229 lines
7.2 KiB
Go
229 lines
7.2 KiB
Go
package sections
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
func TestResolve_NoOverrides(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "Recently Added", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
{ID: "2", Position: 1, SectionType: SectionFavorites, Title: "Favorites", ItemLimit: 10, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
result := Resolve(admin, nil)
|
|
if len(result) != 2 {
|
|
t.Fatalf("expected 2 sections, got %d", len(result))
|
|
}
|
|
if result[0].Title != "Recently Added" {
|
|
t.Errorf("first section title = %q", result[0].Title)
|
|
}
|
|
}
|
|
|
|
func TestResolve_HiddenOverride(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "Recently Added", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
{ID: "2", Position: 1, SectionType: SectionFavorites, Title: "Favorites", ItemLimit: 10, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
overrides := []ProfileSectionOverride{
|
|
{SectionID: "1", Hidden: true},
|
|
}
|
|
|
|
result := Resolve(admin, overrides)
|
|
if len(result) != 1 {
|
|
t.Fatalf("expected 1 section (1 hidden), got %d", len(result))
|
|
}
|
|
if result[0].ID != "2" {
|
|
t.Errorf("remaining section ID = %q, want %q", result[0].ID, "2")
|
|
}
|
|
}
|
|
|
|
func TestResolve_RemovedOverrideSkipsAdminSection(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "Recently Added", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
{ID: "2", Position: 1, SectionType: SectionFavorites, Title: "Favorites", ItemLimit: 10, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
overrides := []ProfileSectionOverride{
|
|
{SectionID: "1", Removed: true},
|
|
}
|
|
|
|
result := Resolve(admin, overrides)
|
|
if len(result) != 1 || result[0].ID != "2" {
|
|
t.Fatalf("resolved IDs = %#v, want only section 2", result)
|
|
}
|
|
}
|
|
|
|
func TestResolve_PositionOverride(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "A", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
{ID: "2", Position: 1, SectionType: SectionFavorites, Title: "B", ItemLimit: 10, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
posB := 0
|
|
posA := 1
|
|
overrides := []ProfileSectionOverride{
|
|
{SectionID: "2", Position: &posB}, // Move B to position 0
|
|
{SectionID: "1", Position: &posA}, // Move A to position 1
|
|
}
|
|
|
|
result := Resolve(admin, overrides)
|
|
if result[0].ID != "2" {
|
|
t.Errorf("first section should be B (id=2), got id=%s", result[0].ID)
|
|
}
|
|
if result[1].ID != "1" {
|
|
t.Errorf("second section should be A (id=1), got id=%s", result[1].ID)
|
|
}
|
|
}
|
|
|
|
func TestResolve_UserAddedSection(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "A", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
pos := 1
|
|
overrides := []ProfileSectionOverride{
|
|
{ID: "custom-1", SectionID: "", SectionType: "genre", Title: "My Action", Position: &pos, ItemLimit: new(15), Config: json.RawMessage(`{"genres":["Action"]}`)},
|
|
}
|
|
|
|
result := Resolve(admin, overrides)
|
|
if len(result) != 2 {
|
|
t.Fatalf("expected 2 sections, got %d", len(result))
|
|
}
|
|
if result[1].Title != "My Action" {
|
|
t.Errorf("second section title = %q, want %q", result[1].Title, "My Action")
|
|
}
|
|
if !result[1].IsCustom {
|
|
t.Error("user-added section should be marked IsCustom")
|
|
}
|
|
}
|
|
|
|
func TestResolve_RemovedCustomSection(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "A", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
overrides := []ProfileSectionOverride{
|
|
{ID: "custom-1", SectionType: "genre", Title: "My Action", Removed: true},
|
|
}
|
|
|
|
result := Resolve(admin, overrides)
|
|
if len(result) != 1 {
|
|
t.Fatalf("expected removed custom section to be skipped, got %d sections", len(result))
|
|
}
|
|
if result[0].ID != "1" {
|
|
t.Fatalf("remaining section ID = %q, want %q", result[0].ID, "1")
|
|
}
|
|
}
|
|
|
|
func TestResolveForSettings_IncludesHidden(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "Recently Added", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
{ID: "2", Position: 1, SectionType: SectionFavorites, Title: "Favorites", ItemLimit: 10, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
overrides := []ProfileSectionOverride{
|
|
{SectionID: "1", Hidden: true},
|
|
}
|
|
|
|
result := ResolveForSettings(admin, overrides)
|
|
if len(result) != 2 {
|
|
t.Fatalf("expected 2 sections (including hidden), got %d", len(result))
|
|
}
|
|
if !result[0].Hidden {
|
|
t.Error("section 1 should be marked Hidden")
|
|
}
|
|
if result[0].Customized != true {
|
|
t.Error("hidden section should be marked Customized")
|
|
}
|
|
if result[1].Hidden {
|
|
t.Error("section 2 should not be hidden")
|
|
}
|
|
}
|
|
|
|
func TestResolveForSettings_SkipsRemovedSection(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "Recently Added", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
overrides := []ProfileSectionOverride{
|
|
{SectionID: "1", Removed: true},
|
|
}
|
|
|
|
result := ResolveForSettings(admin, overrides)
|
|
if len(result) != 0 {
|
|
t.Fatalf("expected removed section to be omitted from settings, got %d entries", len(result))
|
|
}
|
|
}
|
|
|
|
func TestResolveForSettings_SkipsRemovedCustomSection(t *testing.T) {
|
|
admin := []*PageSection{
|
|
{ID: "1", Position: 0, SectionType: SectionRecentlyAdded, Title: "Recently Added", ItemLimit: 20, Config: json.RawMessage(`{}`)},
|
|
}
|
|
|
|
overrides := []ProfileSectionOverride{
|
|
{ID: "custom-1", SectionType: "genre", Title: "My Action", Removed: true},
|
|
}
|
|
|
|
result := ResolveForSettings(admin, overrides)
|
|
if len(result) != 1 {
|
|
t.Fatalf("expected removed custom section to be omitted from settings, got %d entries", len(result))
|
|
}
|
|
if result[0].ID != "1" {
|
|
t.Fatalf("remaining section ID = %q, want %q", result[0].ID, "1")
|
|
}
|
|
}
|
|
|
|
func TestResolveIncludesUserAddedRecipeFromOverride(t *testing.T) {
|
|
admin := []*PageSection{}
|
|
overrides := []ProfileSectionOverride{
|
|
{
|
|
ID: "u1",
|
|
ProfileID: "p1",
|
|
Scope: "home",
|
|
SectionID: "",
|
|
IsUserAdded: true,
|
|
UserSectionType: "hidden_gems",
|
|
UserConfig: json.RawMessage(`{"min_rating":7.5}`),
|
|
UserTitle: "Hidden Gems",
|
|
},
|
|
}
|
|
resolved := Resolve(admin, overrides)
|
|
if len(resolved) != 1 {
|
|
t.Fatalf("got %d sections", len(resolved))
|
|
}
|
|
if resolved[0].SectionType != "hidden_gems" {
|
|
t.Errorf("section_type = %s want hidden_gems", resolved[0].SectionType)
|
|
}
|
|
if resolved[0].Title != "Hidden Gems" {
|
|
t.Errorf("title = %s want Hidden Gems", resolved[0].Title)
|
|
}
|
|
if string(resolved[0].Config) != `{"min_rating":7.5}` {
|
|
t.Errorf("config = %s want {\"min_rating\":7.5}", resolved[0].Config)
|
|
}
|
|
if !resolved[0].IsCustom {
|
|
t.Error("expected IsCustom true")
|
|
}
|
|
}
|
|
|
|
func TestResolveBackwardCompatLegacyUserAdded(t *testing.T) {
|
|
// An override with the OLD shape (no IsUserAdded flag, but SectionID empty)
|
|
// should still resolve correctly using the legacy fields.
|
|
admin := []*PageSection{}
|
|
overrides := []ProfileSectionOverride{
|
|
{
|
|
ID: "u2",
|
|
ProfileID: "p1",
|
|
Scope: "home",
|
|
SectionID: "",
|
|
SectionType: "recently_added",
|
|
Title: "My recents",
|
|
},
|
|
}
|
|
resolved := Resolve(admin, overrides)
|
|
if len(resolved) != 1 || resolved[0].SectionType != "recently_added" || resolved[0].Title != "My recents" {
|
|
t.Fatalf("legacy user-added not resolved correctly: %+v", resolved)
|
|
}
|
|
}
|