diff --git a/internal/admin/official_gift_snapshot_test.go b/internal/admin/official_gift_snapshot_test.go new file mode 100644 index 00000000..7899fd14 --- /dev/null +++ b/internal/admin/official_gift_snapshot_test.go @@ -0,0 +1,83 @@ +package admin + +import ( + "context" + "os" + "testing" + + stargiftapp "telesrv/internal/app/stargifts" + "telesrv/internal/domain" + "telesrv/internal/officialgifts" + "telesrv/internal/store/memory" +) + +// This opt-in regression uses the exact official snapshot reported by the +// Party Sparkler import issue. It crosses official catalog verification, +// admin mapping, animation materialization and the complete store validator. +func TestConfiguredOfficialPartySparklerImport(t *testing.T) { + root := os.Getenv("TELESRV_TEST_OFFICIAL_GIFTS_DIR") + if root == "" { + t.Skip("TELESRV_TEST_OFFICIAL_GIFTS_DIR is not set") + } + ctx := context.Background() + giftService := stargiftapp.NewService(memory.NewStarGiftStore(), &adminGiftBlob{data: map[string][]byte{}}, 2) + svc := NewService(Dependencies{ + Commands: newMemoryCommandRepo(), + Gifts: giftService, + OfficialGifts: officialgifts.New(root), + Now: fixedNow, + }) + result, err := svc.ImportOfficialStarGift(ctx, ImportOfficialStarGiftRequest{ + CommandMeta: CommandMeta{ + CommandID: "exec-party-sparkler-snapshot-regression", + Actor: "test", + Reason: "verify official collectible import", + }, + SourceGiftID: "6003643167683903930", + Enabled: true, + IncludeCollectible: true, + }) + if err != nil { + t.Fatalf("import Party Sparkler: result=%+v err=%v", result, err) + } + if result.Details["models"] != 100 || result.Details["patterns"] != 136 || result.Details["backdrops"] != 60 { + t.Fatalf("Party Sparkler details = %+v", result.Details) + } + catalog, err := giftService.Catalog(ctx) + if err != nil || len(catalog) != 1 { + t.Fatalf("catalog=%+v err=%v, want one gift", catalog, err) + } + preview, ok, err := giftService.CollectiblePreview(ctx, catalog[0].ID) + if err != nil || !ok || len(preview.Models) != 100 || len(preview.Patterns) != 136 || len(preview.Backdrops) != 60 { + t.Fatalf("preview counts=%d/%d/%d ok=%v err=%v", len(preview.Models), len(preview.Patterns), len(preview.Backdrops), ok, err) + } + for _, model := range preview.Models { + if model.Document == nil || !model.Document.IsSticker() || model.Document.IsCustomEmoji() { + t.Fatalf("model %q document=%+v, want ordinary sticker", model.Name, model.Document) + } + } + for _, pattern := range preview.Patterns { + if pattern.Document == nil || pattern.Document.IsSticker() || !pattern.Document.IsCustomEmoji() || + !hasTextColorCustomEmoji(pattern.Document.Attributes) || !hasInlinePathThumb(pattern.Document.Thumbs) { + t.Fatalf("pattern %q document=%+v, want text-color custom emoji with inline path", pattern.Name, pattern.Document) + } + } +} + +func hasTextColorCustomEmoji(attributes []domain.DocumentAttribute) bool { + for _, attribute := range attributes { + if attribute.Kind == domain.DocAttrCustomEmoji && attribute.TextColor { + return true + } + } + return false +} + +func hasInlinePathThumb(thumbs []domain.PhotoSize) bool { + for _, thumb := range thumbs { + if thumb.Kind == domain.PhotoSizeKindPath && thumb.Type != "" && len(thumb.Bytes) > 0 { + return true + } + } + return false +} diff --git a/internal/admin/service_test.go b/internal/admin/service_test.go index 471ee0e1..f48c4182 100644 --- a/internal/admin/service_test.go +++ b/internal/admin/service_test.go @@ -4,14 +4,17 @@ import ( "bytes" "context" "crypto/sha256" + "encoding/hex" "errors" "reflect" "strings" "testing" "time" + stargiftapp "telesrv/internal/app/stargifts" "telesrv/internal/domain" "telesrv/internal/officialgifts" + "telesrv/internal/store/memory" ) func TestSetAccountFrozenDryRunExecuteAndIdempotency(t *testing.T) { @@ -803,6 +806,79 @@ func TestImportOfficialStarGiftPreservesCraftedRarityAndPublishesBundle(t *testi } } +func TestImportOfficialStarGiftPublishesThroughRealGiftService(t *testing.T) { + const lottie = `{"v":"5.7.4","fr":30,"ip":0,"op":60,"w":512,"h":512,"layers":[{"ty":4}],"assets":[]}` + document := func(id int64, name string) officialgifts.Document { + raw := []byte(lottie) + sum := sha256.Sum256(raw) + return officialgifts.Document{ID: id, FileName: name, SHA256: hex.EncodeToString(sum[:]), Data: raw} + } + permille := 1000 + source := &fakeOfficialGiftsSource{bundle: officialgifts.Bundle{ + ManifestSHA256: bytesOf(0x24, sha256.Size), + SourceJSON: []byte(`{"id":6003643167683903930,"title":"Party Sparkler"}`), + Gift: officialgifts.Gift{ + ID: 6003643167683903930, Title: "Party Sparkler", Stars: 15, ConvertStars: 13, + UpgradeStars: 25, AvailabilityTotal: 400000, DocumentID: 1, + }, + BaseDocument: document(1, "gift.json"), + Collectible: &officialgifts.CollectibleSet{ + Models: []officialgifts.Model{{ + Name: "Model", DocumentID: 2, Rarity: officialgifts.Rarity{Kind: "permille", Permille: &permille}, + Document: document(2, "model.json"), + }}, + Patterns: []officialgifts.Pattern{{ + Name: "Pattern", DocumentID: 3, Rarity: officialgifts.Rarity{Kind: "permille", Permille: &permille}, + Document: document(3, "pattern.json"), + }}, + Backdrops: []officialgifts.Backdrop{{ + Name: "Backdrop", BackdropID: 0, Rarity: officialgifts.Rarity{Kind: "permille", Permille: &permille}, + }}, + }, + }} + ctx := context.Background() + giftService := stargiftapp.NewService(memory.NewStarGiftStore(), &adminGiftBlob{data: map[string][]byte{}}, 2) + svc := NewService(Dependencies{ + Commands: newMemoryCommandRepo(), Gifts: giftService, OfficialGifts: source, Now: fixedNow, + }) + req := ImportOfficialStarGiftRequest{ + SourceGiftID: "6003643167683903930", Enabled: true, IncludeCollectible: true, + CommandMeta: CommandMeta{CommandID: "exec-official-real-service", Actor: "ops", Reason: "regression", DryRun: false}, + } + result, err := svc.ImportOfficialStarGift(ctx, req) + if err != nil { + t.Fatalf("import official collectible through real service: result=%+v err=%v", result, err) + } + catalog, err := giftService.Catalog(ctx) + if err != nil || len(catalog) != 1 { + t.Fatalf("catalog=%+v err=%v, want one imported gift", catalog, err) + } + preview, ok, err := giftService.CollectiblePreview(ctx, catalog[0].ID) + if err != nil || !ok || len(preview.Models) != 1 || len(preview.Patterns) != 1 { + t.Fatalf("preview=%+v ok=%v err=%v", preview, ok, err) + } + model := preview.Models[0].Document + pattern := preview.Patterns[0].Document + if model == nil || !model.IsSticker() || model.IsCustomEmoji() || pattern == nil || + pattern.IsSticker() || !pattern.IsCustomEmoji() || len(pattern.Thumbs) != 1 || + pattern.Thumbs[0].Kind != domain.PhotoSizeKindPath || len(pattern.Thumbs[0].Bytes) == 0 { + t.Fatalf("materialized model=%+v pattern=%+v", model, pattern) + } +} + +type adminGiftBlob struct{ data map[string][]byte } + +func (b *adminGiftBlob) Name() string { return "localfs" } +func (b *adminGiftBlob) Put(_ context.Context, data []byte) (string, error) { + sum := sha256.Sum256(data) + key := hex.EncodeToString(sum[:]) + b.data[key] = append([]byte(nil), data...) + return key, nil +} +func (b *adminGiftBlob) Get(_ context.Context, key string) ([]byte, error) { + return append([]byte(nil), b.data[key]...), nil +} + func bytesOf(value byte, count int) []byte { out := make([]byte, count) for i := range out { diff --git a/internal/app/stargifts/animation_test.go b/internal/app/stargifts/animation_test.go index 1c910396..3e56141a 100644 --- a/internal/app/stargifts/animation_test.go +++ b/internal/app/stargifts/animation_test.go @@ -114,3 +114,56 @@ func TestCreateCatalogBundleRejectsMismatchedOfficialProvenance(t *testing.T) { t.Fatalf("mismatched provenance err=%v, want ErrStarGiftCollectibleInvalid", err) } } + +func TestCreateCatalogBundleMaterializesPublishableCollectibleDocuments(t *testing.T) { + ctx := context.Background() + store := memory.NewStarGiftStore() + svc := NewService(store, &testGiftBlob{data: map[string][]byte{}}, 2) + animation, err := svc.PrepareOfficialAnimation("official.json", []byte(validGiftLottie)) + if err != nil { + t.Fatal(err) + } + manifestSHA := make([]byte, sha256.Size) + result, err := svc.CreateCatalogBundle(ctx, domain.StarGiftCatalogBundleWrite{ + Catalog: domain.StarGiftCatalogWrite{ + Title: "Official", Stars: 50, ConvertStars: 25, Enabled: true, Animation: animation, + Actor: "test", CommandID: "official-catalog", OfficialGiftID: 10, + SourceManifestSHA256: manifestSHA, OfficialSourceJSON: []byte(`{"id":10}`), + }, + Collectible: &domain.StarGiftCollectibleWrite{ + UpgradeStars: 100, SupplyTotal: 1000, SlugPrefix: "official-10", + Models: []domain.StarGiftCollectibleAttribute{{ + Kind: domain.StarGiftCollectibleModel, Name: "Model", RarityKind: domain.StarGiftRarityPermille, + RarityPermille: 1000, Animation: &animation, + }}, + Patterns: []domain.StarGiftCollectibleAttribute{{ + Kind: domain.StarGiftCollectiblePattern, Name: "Pattern", RarityKind: domain.StarGiftRarityPermille, + RarityPermille: 1000, Animation: &animation, + }}, + Backdrops: []domain.StarGiftCollectibleAttribute{{ + Kind: domain.StarGiftCollectibleBackdrop, Name: "Backdrop", RarityKind: domain.StarGiftRarityPermille, + RarityPermille: 1000, + }}, + Actor: "test", CommandID: "official-pool", OfficialGiftID: 10, + SourceManifestSHA256: manifestSHA, + }, + }) + if err != nil { + t.Fatalf("create official collectible bundle: %v", err) + } + if result.Collectible == nil || len(result.Collectible.Models) != 1 || len(result.Collectible.Patterns) != 1 { + t.Fatalf("collectible result = %+v", result.Collectible) + } + model := result.Collectible.Models[0].Document + pattern := result.Collectible.Patterns[0].Document + if model == nil || !model.IsSticker() || model.IsCustomEmoji() { + t.Fatalf("model document = %+v, want ordinary sticker", model) + } + if pattern == nil || pattern.IsSticker() || !pattern.IsCustomEmoji() || len(pattern.Thumbs) != 1 || + pattern.Thumbs[0].Kind != domain.PhotoSizeKindPath || len(pattern.Thumbs[0].Bytes) == 0 { + t.Fatalf("pattern document = %+v, want text-color custom emoji with inline path", pattern) + } + if !pattern.Attributes[1].TextColor { + t.Fatalf("pattern render attribute = %+v, want text_color", pattern.Attributes[1]) + } +} diff --git a/internal/domain/star_gift.go b/internal/domain/star_gift.go index 9d7e44b0..21ea447b 100644 --- a/internal/domain/star_gift.go +++ b/internal/domain/star_gift.go @@ -981,7 +981,8 @@ func validateStarGiftAttributes(attributes []StarGiftCollectibleAttribute, kind len(attribute.Animation.TGS) == 0 || len(attribute.Animation.SHA256) != 32 { return ErrStarGiftCollectibleInvalid } - if requireStoredAsset && (attribute.Document == nil || !attribute.Document.IsSticker() || + if requireStoredAsset && (attribute.Document == nil || + !validStarGiftCollectibleDocument(*attribute.Document, kind) || attribute.Document.MimeType != "application/x-tgsticker" || attribute.Blob == nil) { return ErrStarGiftCollectibleInvalid } @@ -1003,6 +1004,38 @@ func validateStarGiftAttributes(attributes []StarGiftCollectibleAttribute, kind return nil } +// validStarGiftCollectibleDocument enforces the client-visible document roles +// materialized by the Star Gift write boundary. Models are ordinary stickers. +// Patterns are text-color custom emoji with an inline PhotoPathSize so Android +// can classify and tint the TGS before its full first frame is downloaded. +func validStarGiftCollectibleDocument(document Document, kind StarGiftCollectibleAttributeKind) bool { + renderAttributes := 0 + validRenderAttribute := false + for _, attribute := range document.Attributes { + switch attribute.Kind { + case DocAttrSticker: + renderAttributes++ + validRenderAttribute = validRenderAttribute || kind == StarGiftCollectibleModel + case DocAttrCustomEmoji: + renderAttributes++ + validRenderAttribute = validRenderAttribute || + (kind == StarGiftCollectiblePattern && attribute.TextColor) + } + } + if renderAttributes != 1 || !validRenderAttribute { + return false + } + if kind == StarGiftCollectibleModel { + return true + } + for _, thumb := range document.Thumbs { + if thumb.Kind == PhotoSizeKindPath && strings.TrimSpace(thumb.Type) != "" && len(thumb.Bytes) > 0 { + return true + } + } + return false +} + // StarGiftCatalogHash 由客户端可见目录字段折叠出稳定 hash,供 getStarGifts NotModified。 func StarGiftCatalogHash(catalog []StarGift) int { var h uint64 diff --git a/internal/domain/star_gift_collectible_test.go b/internal/domain/star_gift_collectible_test.go index 82798de2..e8c37eb8 100644 --- a/internal/domain/star_gift_collectible_test.go +++ b/internal/domain/star_gift_collectible_test.go @@ -93,3 +93,55 @@ func TestValidateStarGiftCollectibleDraftRejectsImplicitRarity(t *testing.T) { t.Fatalf("err=%v, want ErrStarGiftCollectibleInvalid", err) } } + +func storedCollectibleWrite() StarGiftCollectibleWrite { + write := validCollectibleDraft() + for i := range write.Models { + write.Models[i].Document = &Document{ + ID: int64(100 + i), MimeType: "application/x-tgsticker", + Attributes: []DocumentAttribute{{Kind: DocAttrSticker, Alt: "🎁"}}, + } + write.Models[i].Blob = &FileBlob{LocationKey: "model"} + } + write.Patterns[0].Document = &Document{ + ID: 200, MimeType: "application/x-tgsticker", + Attributes: []DocumentAttribute{{Kind: DocAttrCustomEmoji, Alt: "🎁", TextColor: true}}, + Thumbs: []PhotoSize{{Kind: PhotoSizeKindPath, Type: "j", Bytes: []byte{1}}}, + } + write.Patterns[0].Blob = &FileBlob{LocationKey: "pattern"} + return write +} + +func TestValidateStarGiftCollectibleWriteRequiresExactDocumentRoles(t *testing.T) { + if err := ValidateStarGiftCollectibleWrite(storedCollectibleWrite()); err != nil { + t.Fatalf("valid stored collectible: %v", err) + } + + tests := map[string]func(*StarGiftCollectibleWrite){ + "pattern stored as sticker": func(write *StarGiftCollectibleWrite) { + write.Patterns[0].Document.Attributes = []DocumentAttribute{{Kind: DocAttrSticker, Alt: "🎁"}} + }, + "pattern custom emoji without text color": func(write *StarGiftCollectibleWrite) { + write.Patterns[0].Document.Attributes[0].TextColor = false + }, + "pattern without inline path thumb": func(write *StarGiftCollectibleWrite) { + write.Patterns[0].Document.Thumbs = nil + }, + "model stored as custom emoji": func(write *StarGiftCollectibleWrite) { + write.Models[0].Document.Attributes = []DocumentAttribute{{Kind: DocAttrCustomEmoji, Alt: "🎁", TextColor: true}} + }, + "ambiguous model render attributes": func(write *StarGiftCollectibleWrite) { + write.Models[0].Document.Attributes = append(write.Models[0].Document.Attributes, + DocumentAttribute{Kind: DocAttrCustomEmoji, Alt: "🎁", TextColor: true}) + }, + } + for name, mutate := range tests { + t.Run(name, func(t *testing.T) { + write := storedCollectibleWrite() + mutate(&write) + if err := ValidateStarGiftCollectibleWrite(write); !errors.Is(err, ErrStarGiftCollectibleInvalid) { + t.Fatalf("err=%v, want ErrStarGiftCollectibleInvalid", err) + } + }) + } +} diff --git a/internal/rpc/payments_star_gifts_rpc_test.go b/internal/rpc/payments_star_gifts_rpc_test.go index 80c8b682..7d7da827 100644 --- a/internal/rpc/payments_star_gifts_rpc_test.go +++ b/internal/rpc/payments_star_gifts_rpc_test.go @@ -238,6 +238,10 @@ func collectibleRPCAttribute(kind domain.StarGiftCollectibleAttributeKind, id in MimeType: "application/x-tgsticker", Size: 3, DCID: 2, Attributes: []domain.DocumentAttribute{{Kind: domain.DocAttrSticker}, {Kind: domain.DocAttrFilename, FileName: "gift.tgs"}}, } + if kind == domain.StarGiftCollectiblePattern { + attribute.Document.Attributes[0] = domain.DocumentAttribute{Kind: domain.DocAttrCustomEmoji, TextColor: true} + attribute.Document.Thumbs = []domain.PhotoSize{{Kind: domain.PhotoSizeKindPath, Type: "j", Bytes: []byte{1}}} + } attribute.Animation = &domain.StarGiftAnimation{ SourceName: "gift.tgs", SourceFormat: domain.StarGiftAnimationTGS, JSON: []byte(`{"v":"5.7"}`), TGS: []byte("tgs"), SHA256: make([]byte, 32), Width: 512, Height: 512, diff --git a/internal/store/postgres/star_gift_collectibles_integration_test.go b/internal/store/postgres/star_gift_collectibles_integration_test.go index f5c74418..1a9d6288 100644 --- a/internal/store/postgres/star_gift_collectibles_integration_test.go +++ b/internal/store/postgres/star_gift_collectibles_integration_test.go @@ -46,7 +46,7 @@ func TestStarGiftCollectibleUpgradeAggregatePostgres(t *testing.T) { }}, Patterns: []domain.StarGiftCollectibleAttribute{{ Kind: domain.StarGiftCollectiblePattern, Name: "Orbit", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 989, - Document: collectibleTestDocumentPtr(baseDocumentID+2, "pattern.tgs"), + Document: collectibleTestPatternDocumentPtr(baseDocumentID+2, "pattern.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+2, "pattern"), Animation: collectibleTestAnimationPtr("pattern.tgs"), }}, Backdrops: []domain.StarGiftCollectibleAttribute{{ @@ -341,7 +341,7 @@ func TestStarGiftCollectibleUpgradeAggregatePostgres(t *testing.T) { }}, Patterns: []domain.StarGiftCollectibleAttribute{{ Kind: domain.StarGiftCollectiblePattern, Name: "Ray", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000, - Document: collectibleTestDocumentPtr(baseDocumentID+102, "nova-pattern.tgs"), + Document: collectibleTestPatternDocumentPtr(baseDocumentID+102, "nova-pattern.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+102, "nova-pattern"), Animation: collectibleTestAnimationPtr("nova-pattern.tgs"), }}, Backdrops: []domain.StarGiftCollectibleAttribute{{ @@ -448,7 +448,7 @@ func TestStarGiftUpgradeWithoutCraftedModelDoesNotAdvertiseCraft(t *testing.T) { }}, Patterns: []domain.StarGiftCollectibleAttribute{{ Kind: domain.StarGiftCollectiblePattern, Name: "Pattern", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000, - Document: collectibleTestDocumentPtr(baseDocumentID+2, "no-craft-pattern.tgs"), + Document: collectibleTestPatternDocumentPtr(baseDocumentID+2, "no-craft-pattern.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+2, "no-craft-pattern"), Animation: collectibleTestAnimationPtr("no-craft-pattern.tgs"), }}, Backdrops: []domain.StarGiftCollectibleAttribute{{ @@ -548,6 +548,13 @@ func collectibleTestDocumentPtr(id int64, name string) *domain.Document { return &document } +func collectibleTestPatternDocumentPtr(id int64, name string) *domain.Document { + document := collectibleTestDocument(id, name) + document.Attributes[1] = domain.DocumentAttribute{Kind: domain.DocAttrCustomEmoji, Alt: "🎁", TextColor: true} + document.Thumbs = []domain.PhotoSize{{Kind: domain.PhotoSizeKindPath, Type: "j", Bytes: []byte{1}}} + return &document +} + func collectibleTestBlob(id int64, suffix string) domain.FileBlob { return domain.FileBlob{ LocationKey: fmt.Sprintf("doc:%d", id), Backend: domain.MediaBackendLocalFS, diff --git a/internal/store/postgres/star_gift_lifecycle_integration_test.go b/internal/store/postgres/star_gift_lifecycle_integration_test.go index fdb50782..8bff57f0 100644 --- a/internal/store/postgres/star_gift_lifecycle_integration_test.go +++ b/internal/store/postgres/star_gift_lifecycle_integration_test.go @@ -50,7 +50,7 @@ func TestStarGiftLifecycleAggregatePostgres(t *testing.T) { Document: collectibleTestDocumentPtr(baseDocumentID+2, "crafted.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+2, "crafted"), Animation: collectibleTestAnimationPtr("crafted.tgs")}, }, Patterns: []domain.StarGiftCollectibleAttribute{{Kind: domain.StarGiftCollectiblePattern, Name: "Orbit", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000, - Document: collectibleTestDocumentPtr(baseDocumentID+3, "pattern.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+3, "pattern"), Animation: collectibleTestAnimationPtr("pattern.tgs")}}, + Document: collectibleTestPatternDocumentPtr(baseDocumentID+3, "pattern.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+3, "pattern"), Animation: collectibleTestAnimationPtr("pattern.tgs")}}, Backdrops: []domain.StarGiftCollectibleAttribute{{Kind: domain.StarGiftCollectibleBackdrop, Name: "Night", BackdropID: 77, CenterColor: 0x112233, EdgeColor: 0x223344, PatternColor: 0x334455, TextColor: 0xffffff, RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000}}, @@ -558,7 +558,7 @@ func TestStarGiftChannelLifecycleAtomicPostgres(t *testing.T) { Models: []domain.StarGiftCollectibleAttribute{{Kind: domain.StarGiftCollectibleModel, Name: "Channel Model", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000, Document: collectibleTestDocumentPtr(baseDocumentID+1, "channel-model.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+1, "channel-model"), Animation: collectibleTestAnimationPtr("channel-model.tgs")}}, Patterns: []domain.StarGiftCollectibleAttribute{{Kind: domain.StarGiftCollectiblePattern, Name: "Channel Pattern", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000, - Document: collectibleTestDocumentPtr(baseDocumentID+2, "channel-pattern.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+2, "channel-pattern"), Animation: collectibleTestAnimationPtr("channel-pattern.tgs")}}, + Document: collectibleTestPatternDocumentPtr(baseDocumentID+2, "channel-pattern.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+2, "channel-pattern"), Animation: collectibleTestAnimationPtr("channel-pattern.tgs")}}, Backdrops: []domain.StarGiftCollectibleAttribute{{Kind: domain.StarGiftCollectibleBackdrop, Name: "Channel Backdrop", BackdropID: 88, CenterColor: 0x112233, EdgeColor: 0x223344, PatternColor: 0x334455, TextColor: 0xffffff, RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000}}, diff --git a/internal/store/postgres/star_gift_official_import_integration_test.go b/internal/store/postgres/star_gift_official_import_integration_test.go index d6463580..e4baffc9 100644 --- a/internal/store/postgres/star_gift_official_import_integration_test.go +++ b/internal/store/postgres/star_gift_official_import_integration_test.go @@ -26,7 +26,11 @@ func TestOfficialStarGiftBundleIsAtomicPostgres(t *testing.T) { value.CenterColor, value.EdgeColor, value.PatternColor, value.TextColor = 1, 2, 3, 4 return value } - value.Document = collectibleTestDocumentPtr(id, name+".tgs") + if kind == domain.StarGiftCollectiblePattern { + value.Document = collectibleTestPatternDocumentPtr(id, name+".tgs") + } else { + value.Document = collectibleTestDocumentPtr(id, name+".tgs") + } value.Blob = collectibleTestBlobPtr(id, name) value.Animation = collectibleTestAnimationPtr(name + ".tgs") value.OfficialDocumentID = 5200000000000000000 + id%1000