diff --git a/backend/internal/web/embed_test.go b/backend/internal/web/embed_test.go
index f270b624..fd47c4da 100644
--- a/backend/internal/web/embed_test.go
+++ b/backend/internal/web/embed_test.go
@@ -20,6 +20,78 @@ func init() {
gin.SetMode(gin.TestMode)
}
+func TestInjectSiteTitle(t *testing.T) {
+ t.Run("replaces_title_with_site_name", func(t *testing.T) {
+ html := []byte(`
Sub2API - AI API Gateway`)
+ settingsJSON := []byte(`{"site_name":"MyCustomSite"}`)
+
+ result := injectSiteTitle(html, settingsJSON)
+
+ assert.Contains(t, string(result), "MyCustomSite - AI API Gateway")
+ assert.NotContains(t, string(result), "Sub2API")
+ })
+
+ t.Run("returns_unchanged_when_site_name_empty", func(t *testing.T) {
+ html := []byte(`Sub2API - AI API Gateway`)
+ settingsJSON := []byte(`{"site_name":""}`)
+
+ result := injectSiteTitle(html, settingsJSON)
+
+ assert.Equal(t, string(html), string(result))
+ })
+
+ t.Run("returns_unchanged_when_site_name_missing", func(t *testing.T) {
+ html := []byte(`Sub2API - AI API Gateway`)
+ settingsJSON := []byte(`{"other_field":"value"}`)
+
+ result := injectSiteTitle(html, settingsJSON)
+
+ assert.Equal(t, string(html), string(result))
+ })
+
+ t.Run("returns_unchanged_when_invalid_json", func(t *testing.T) {
+ html := []byte(`Sub2API - AI API Gateway`)
+ settingsJSON := []byte(`{invalid json}`)
+
+ result := injectSiteTitle(html, settingsJSON)
+
+ assert.Equal(t, string(html), string(result))
+ })
+
+ t.Run("returns_unchanged_when_no_title_tag", func(t *testing.T) {
+ html := []byte(``)
+ settingsJSON := []byte(`{"site_name":"MyCustomSite"}`)
+
+ result := injectSiteTitle(html, settingsJSON)
+
+ assert.Equal(t, string(html), string(result))
+ })
+
+ t.Run("returns_unchanged_when_title_has_attributes", func(t *testing.T) {
+ // The function looks for "" literally, so attributes are not supported
+ // This is acceptable since index.html uses plain without attributes
+ html := []byte(`Sub2API`)
+ settingsJSON := []byte(`{"site_name":"NewSite"}`)
+
+ result := injectSiteTitle(html, settingsJSON)
+
+ // Should return unchanged since with attributes is not matched
+ assert.Equal(t, string(html), string(result))
+ })
+
+ t.Run("preserves_rest_of_html", func(t *testing.T) {
+ html := []byte(`Sub2API`)
+ settingsJSON := []byte(`{"site_name":"TestSite"}`)
+
+ result := injectSiteTitle(html, settingsJSON)
+
+ assert.Contains(t, string(result), ``)
+ assert.Contains(t, string(result), ``)
+ assert.Contains(t, string(result), ``)
+ assert.Contains(t, string(result), "TestSite - AI API Gateway")
+ })
+}
+
func TestReplaceNoncePlaceholder(t *testing.T) {
t.Run("replaces_single_placeholder", func(t *testing.T) {
html := []byte(``)