|
|
@@ -334,3 +334,27 @@ TEST_F(ApiFixture, SettingsPutChangesField) {
|
|
|
admin().Put("/api/v1/settings",
|
|
|
nlohmann::json{{"default_embedding_model", "text-embedding-3-small"}}.dump(), "application/json");
|
|
|
}
|
|
|
+
|
|
|
+TEST_F(ApiFixture, SpaFallbackServesIndexForClientRoutes) {
|
|
|
+ for (const char* route : {"/login", "/settings", "/collections", "/documents"}) {
|
|
|
+ auto r = noAuth().Get(route);
|
|
|
+ ASSERT_TRUE(r) << route;
|
|
|
+ EXPECT_EQ(r->status, 200) << route;
|
|
|
+ EXPECT_NE(r->body.find("SVAPI_SPA_OK"), std::string::npos) << route;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+TEST_F(ApiFixture, SpaFallbackDoesNotClobberApiMetaOrAssets) {
|
|
|
+ // /api stays a real 401 JSON (not the SPA html)
|
|
|
+ auto a = noAuth().Get("/api/v1/projects");
|
|
|
+ ASSERT_TRUE(a); EXPECT_EQ(a->status, 401);
|
|
|
+ EXPECT_EQ(a->body.find("SVAPI_SPA_OK"), std::string::npos);
|
|
|
+ // a missing asset (path with an extension) keeps its 404
|
|
|
+ auto j = noAuth().Get("/assets/missing.js");
|
|
|
+ ASSERT_TRUE(j); EXPECT_EQ(j->status, 404);
|
|
|
+ EXPECT_EQ(j->body.find("SVAPI_SPA_OK"), std::string::npos);
|
|
|
+ // meta is still the real thing
|
|
|
+ auto o = noAuth().Get("/openapi.json");
|
|
|
+ ASSERT_TRUE(o); EXPECT_EQ(o->status, 200);
|
|
|
+ EXPECT_EQ(o->body.find("SVAPI_SPA_OK"), std::string::npos);
|
|
|
+}
|