@@ -18,6 +18,7 @@ package dataplane
1818
1919import (
2020 "context"
21+ "errors"
2122 "io"
2223 "net/http"
2324 "net/http/httptest"
@@ -77,6 +78,19 @@ func (f *fakeRuntime) ControlToken(_ context.Context, namespace, name string) (s
7778 return f .token , nil
7879}
7980
81+ type fakePreviewRouteManager struct {
82+ err error
83+
84+ calls int
85+ got * unstructured.Unstructured
86+ }
87+
88+ func (f * fakePreviewRouteManager ) Ensure (_ context.Context , instance * unstructured.Unstructured ) error {
89+ f .calls ++
90+ f .got = instance
91+ return f .err
92+ }
93+
8094func newTestHandler (t * testing.T , ig * fakeInstanceGetter , rt * fakeRuntime ) * Handler {
8195 t .Helper ()
8296 return NewHandler (ig , & fakeContractGetter {contract : sandboxRunnerContract ()}, rt )
@@ -154,6 +168,61 @@ func TestHandlerProxyVerbAppendsCallerPath(t *testing.T) {
154168 }
155169}
156170
171+ func TestHandlerEnsuresPreviewRouteBeforeProxyingSandboxPreview (t * testing.T ) {
172+ var gotPath string
173+ upstream := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
174+ gotPath = r .URL .Path
175+ }))
176+ defer upstream .Close ()
177+
178+ manager := & fakePreviewRouteManager {}
179+ h := NewHandler (
180+ & fakeInstanceGetter {instance : runnerInstance (testNamespace )},
181+ & fakeContractGetter {contract : sandboxRunnerContract ()},
182+ & fakeRuntime {host : upstream .URL },
183+ WithPreviewRouteManager (manager ),
184+ )
185+ rec := doRequest (h , http .MethodGet , dataplaneURL ("proxy" )+ "/assets/app.js" )
186+ if rec .Code != http .StatusOK {
187+ t .Fatalf ("status = %d, want 200" , rec .Code )
188+ }
189+ if manager .calls != 1 {
190+ t .Fatalf ("preview route ensure calls = %d, want 1" , manager .calls )
191+ }
192+ if manager .got == nil || manager .got .GetName () != "kedge-sandbox-a1c31ddaaaa007d4" {
193+ t .Fatalf ("preview route manager got instance %#v" , manager .got )
194+ }
195+ if gotPath == "" {
196+ t .Fatal ("request was not proxied after preview route ensure" )
197+ }
198+ }
199+
200+ func TestHandlerReportsPreviewRouteNotReady (t * testing.T ) {
201+ h := NewHandler (
202+ & fakeInstanceGetter {instance : runnerInstance (testNamespace )},
203+ & fakeContractGetter {contract : sandboxRunnerContract ()},
204+ & fakeRuntime {host : "http://unused" },
205+ WithPreviewRouteManager (& fakePreviewRouteManager {err : previewRouteNotReady ("waiting for ResolvedRefs" )}),
206+ )
207+ rec := doRequest (h , http .MethodGet , dataplaneURL ("proxy" ))
208+ if rec .Code != http .StatusServiceUnavailable {
209+ t .Fatalf ("status = %d, want 503" , rec .Code )
210+ }
211+ }
212+
213+ func TestHandlerFailsClosedWhenPreviewRouteValidationFails (t * testing.T ) {
214+ h := NewHandler (
215+ & fakeInstanceGetter {instance : runnerInstance (testNamespace )},
216+ & fakeContractGetter {contract : sandboxRunnerContract ()},
217+ & fakeRuntime {host : "http://unused" },
218+ WithPreviewRouteManager (& fakePreviewRouteManager {err : errors .New ("unexpected backend" )}),
219+ )
220+ rec := doRequest (h , http .MethodGet , dataplaneURL ("proxy" ))
221+ if rec .Code != http .StatusServiceUnavailable {
222+ t .Fatalf ("status = %d, want 503" , rec .Code )
223+ }
224+ }
225+
157226func TestHandlerStatusVerbServedFromCR (t * testing.T ) {
158227 h := newTestHandler (t , & fakeInstanceGetter {instance : runnerInstance (testNamespace )}, & fakeRuntime {host : "http://unused" })
159228 rec := doRequest (h , http .MethodGet , dataplaneURL ("status" ))
0 commit comments