Files
sub2api/backend/internal/handler/dto/public_settings_injection_schema_test.go
T
Randark 7e45634df9 chore: remove leftover Sora references after platform removal
PR #1463 removed the Sora platform, but some references survived:

- README/README_CN/README_JA kept the 'Sora status (temporarily
  unavailable)' sections and gateway.sora_* docs that the removal PR
  never touched.
- deploy/config.example.yaml still documented ~130 lines of sora_*
  gateway keys, the top-level sora: direct-client/storage block, and
  token_refresh.sync_linked_sora_accounts - none of which map to any
  field in the config structs anymore.
- The OIDC login PR (02a66a01c, branched off pre-removal main and
  merged 4 days after #1463) re-added the dead
  PublicSettings.SoraClientEnabled field, which no code ever sets.
- A release sync (748a84d87) re-introduced sora i18n keys that the
  later i18n split (d9e514f98) faithfully carried into
  locales/{zh,en}/admin/{overview,settings}.ts. No component references
  any of these keys.

This drops all of the above. Pure deletions, no behavior change.
2026-08-18 00:51:30 +00:00

69 lines
2.3 KiB
Go

package dto
import (
"reflect"
"strings"
"testing"
"github.com/Wei-Shaw/sub2api/internal/service"
)
// TestPublicSettingsInjectionPayload_SchemaDoesNotDrift guarantees the SSR
// injection struct exposes every JSON field consumed by the frontend.
//
// Why this test exists: before we extracted a named PublicSettingsInjectionPayload
// type, the inline struct was manually kept in sync with dto.PublicSettings and
// drifted — ChannelMonitorEnabled / AvailableChannelsEnabled were missing, which
// made the frontend read `undefined` on refresh and hide the "可用渠道" menu
// until the async /api/v1/settings/public round-trip finished.
//
// This test compares the two JSON-tag sets and fails if injection is missing
// any field that dto.PublicSettings exposes. Adding a new feature flag with
// only a DTO entry will fail this test until the injection struct is updated.
//
// Intentional exclusions (fields present on dto.PublicSettings that SSR does
// not need to inject) are listed in `dtoOnlyFields` below with a reason.
func TestPublicSettingsInjectionPayload_SchemaDoesNotDrift(t *testing.T) {
injection := jsonTags(reflect.TypeOf(service.PublicSettingsInjectionPayload{}))
dtoKeys := jsonTags(reflect.TypeOf(PublicSettings{}))
// Fields that legitimately live only on the DTO. Keep tiny; document each.
dtoOnlyFields := map[string]string{
// force_email_on_third_party_signup lives on the DTO but is not injected via SSR.
"force_email_on_third_party_signup": "auth-source default, not a feature flag",
}
var missing []string
for key := range dtoKeys {
if _, ok := injection[key]; ok {
continue
}
if _, allowed := dtoOnlyFields[key]; allowed {
continue
}
missing = append(missing, key)
}
if len(missing) > 0 {
t.Fatalf("service.PublicSettingsInjectionPayload is missing JSON fields present on dto.PublicSettings: %s\n"+
"add the field to PublicSettingsInjectionPayload (and GetPublicSettingsForInjection), or "+
"document the exclusion in dtoOnlyFields with a reason.", strings.Join(missing, ", "))
}
}
func jsonTags(t reflect.Type) map[string]struct{} {
out := make(map[string]struct{})
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
tag := f.Tag.Get("json")
if tag == "" || tag == "-" {
continue
}
name := strings.SplitN(tag, ",", 2)[0]
if name == "" {
continue
}
out[name] = struct{}{}
}
return out
}