fix: sync collectible document role validation
Sync telesrv d8ad5cc (fix(stargifts): validate collectible document roles). Skipped telesrv docs changes per public sync rules.
This commit is contained in:
parent
2848ff0987
commit
ba82fbccd6
9 changed files with 319 additions and 7 deletions
83
internal/admin/official_gift_snapshot_test.go
Normal file
83
internal/admin/official_gift_snapshot_test.go
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -4,14 +4,17 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
stargiftapp "telesrv/internal/app/stargifts"
|
||||||
"telesrv/internal/domain"
|
"telesrv/internal/domain"
|
||||||
"telesrv/internal/officialgifts"
|
"telesrv/internal/officialgifts"
|
||||||
|
"telesrv/internal/store/memory"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSetAccountFrozenDryRunExecuteAndIdempotency(t *testing.T) {
|
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 {
|
func bytesOf(value byte, count int) []byte {
|
||||||
out := make([]byte, count)
|
out := make([]byte, count)
|
||||||
for i := range out {
|
for i := range out {
|
||||||
|
|
|
||||||
|
|
@ -114,3 +114,56 @@ func TestCreateCatalogBundleRejectsMismatchedOfficialProvenance(t *testing.T) {
|
||||||
t.Fatalf("mismatched provenance err=%v, want ErrStarGiftCollectibleInvalid", err)
|
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])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -981,7 +981,8 @@ func validateStarGiftAttributes(attributes []StarGiftCollectibleAttribute, kind
|
||||||
len(attribute.Animation.TGS) == 0 || len(attribute.Animation.SHA256) != 32 {
|
len(attribute.Animation.TGS) == 0 || len(attribute.Animation.SHA256) != 32 {
|
||||||
return ErrStarGiftCollectibleInvalid
|
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) {
|
attribute.Document.MimeType != "application/x-tgsticker" || attribute.Blob == nil) {
|
||||||
return ErrStarGiftCollectibleInvalid
|
return ErrStarGiftCollectibleInvalid
|
||||||
}
|
}
|
||||||
|
|
@ -1003,6 +1004,38 @@ func validateStarGiftAttributes(attributes []StarGiftCollectibleAttribute, kind
|
||||||
return nil
|
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。
|
// StarGiftCatalogHash 由客户端可见目录字段折叠出稳定 hash,供 getStarGifts NotModified。
|
||||||
func StarGiftCatalogHash(catalog []StarGift) int {
|
func StarGiftCatalogHash(catalog []StarGift) int {
|
||||||
var h uint64
|
var h uint64
|
||||||
|
|
|
||||||
|
|
@ -93,3 +93,55 @@ func TestValidateStarGiftCollectibleDraftRejectsImplicitRarity(t *testing.T) {
|
||||||
t.Fatalf("err=%v, want ErrStarGiftCollectibleInvalid", err)
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,10 @@ func collectibleRPCAttribute(kind domain.StarGiftCollectibleAttributeKind, id in
|
||||||
MimeType: "application/x-tgsticker", Size: 3, DCID: 2,
|
MimeType: "application/x-tgsticker", Size: 3, DCID: 2,
|
||||||
Attributes: []domain.DocumentAttribute{{Kind: domain.DocAttrSticker}, {Kind: domain.DocAttrFilename, FileName: "gift.tgs"}},
|
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{
|
attribute.Animation = &domain.StarGiftAnimation{
|
||||||
SourceName: "gift.tgs", SourceFormat: domain.StarGiftAnimationTGS,
|
SourceName: "gift.tgs", SourceFormat: domain.StarGiftAnimationTGS,
|
||||||
JSON: []byte(`{"v":"5.7"}`), TGS: []byte("tgs"), SHA256: make([]byte, 32), Width: 512, Height: 512,
|
JSON: []byte(`{"v":"5.7"}`), TGS: []byte("tgs"), SHA256: make([]byte, 32), Width: 512, Height: 512,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ func TestStarGiftCollectibleUpgradeAggregatePostgres(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
Patterns: []domain.StarGiftCollectibleAttribute{{
|
Patterns: []domain.StarGiftCollectibleAttribute{{
|
||||||
Kind: domain.StarGiftCollectiblePattern, Name: "Orbit", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 989,
|
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"),
|
Blob: collectibleTestBlobPtr(baseDocumentID+2, "pattern"), Animation: collectibleTestAnimationPtr("pattern.tgs"),
|
||||||
}},
|
}},
|
||||||
Backdrops: []domain.StarGiftCollectibleAttribute{{
|
Backdrops: []domain.StarGiftCollectibleAttribute{{
|
||||||
|
|
@ -341,7 +341,7 @@ func TestStarGiftCollectibleUpgradeAggregatePostgres(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
Patterns: []domain.StarGiftCollectibleAttribute{{
|
Patterns: []domain.StarGiftCollectibleAttribute{{
|
||||||
Kind: domain.StarGiftCollectiblePattern, Name: "Ray", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000,
|
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"),
|
Blob: collectibleTestBlobPtr(baseDocumentID+102, "nova-pattern"), Animation: collectibleTestAnimationPtr("nova-pattern.tgs"),
|
||||||
}},
|
}},
|
||||||
Backdrops: []domain.StarGiftCollectibleAttribute{{
|
Backdrops: []domain.StarGiftCollectibleAttribute{{
|
||||||
|
|
@ -448,7 +448,7 @@ func TestStarGiftUpgradeWithoutCraftedModelDoesNotAdvertiseCraft(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
Patterns: []domain.StarGiftCollectibleAttribute{{
|
Patterns: []domain.StarGiftCollectibleAttribute{{
|
||||||
Kind: domain.StarGiftCollectiblePattern, Name: "Pattern", RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000,
|
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"),
|
Blob: collectibleTestBlobPtr(baseDocumentID+2, "no-craft-pattern"), Animation: collectibleTestAnimationPtr("no-craft-pattern.tgs"),
|
||||||
}},
|
}},
|
||||||
Backdrops: []domain.StarGiftCollectibleAttribute{{
|
Backdrops: []domain.StarGiftCollectibleAttribute{{
|
||||||
|
|
@ -548,6 +548,13 @@ func collectibleTestDocumentPtr(id int64, name string) *domain.Document {
|
||||||
return &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 {
|
func collectibleTestBlob(id int64, suffix string) domain.FileBlob {
|
||||||
return domain.FileBlob{
|
return domain.FileBlob{
|
||||||
LocationKey: fmt.Sprintf("doc:%d", id), Backend: domain.MediaBackendLocalFS,
|
LocationKey: fmt.Sprintf("doc:%d", id), Backend: domain.MediaBackendLocalFS,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ func TestStarGiftLifecycleAggregatePostgres(t *testing.T) {
|
||||||
Document: collectibleTestDocumentPtr(baseDocumentID+2, "crafted.tgs"), Blob: collectibleTestBlobPtr(baseDocumentID+2, "crafted"), Animation: collectibleTestAnimationPtr("crafted.tgs")},
|
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,
|
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,
|
Backdrops: []domain.StarGiftCollectibleAttribute{{Kind: domain.StarGiftCollectibleBackdrop, Name: "Night", BackdropID: 77,
|
||||||
CenterColor: 0x112233, EdgeColor: 0x223344, PatternColor: 0x334455, TextColor: 0xffffff,
|
CenterColor: 0x112233, EdgeColor: 0x223344, PatternColor: 0x334455, TextColor: 0xffffff,
|
||||||
RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000}},
|
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,
|
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")}},
|
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,
|
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,
|
Backdrops: []domain.StarGiftCollectibleAttribute{{Kind: domain.StarGiftCollectibleBackdrop, Name: "Channel Backdrop", BackdropID: 88,
|
||||||
CenterColor: 0x112233, EdgeColor: 0x223344, PatternColor: 0x334455, TextColor: 0xffffff,
|
CenterColor: 0x112233, EdgeColor: 0x223344, PatternColor: 0x334455, TextColor: 0xffffff,
|
||||||
RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000}},
|
RarityKind: domain.StarGiftRarityPermille, RarityPermille: 1000}},
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,11 @@ func TestOfficialStarGiftBundleIsAtomicPostgres(t *testing.T) {
|
||||||
value.CenterColor, value.EdgeColor, value.PatternColor, value.TextColor = 1, 2, 3, 4
|
value.CenterColor, value.EdgeColor, value.PatternColor, value.TextColor = 1, 2, 3, 4
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
if kind == domain.StarGiftCollectiblePattern {
|
||||||
|
value.Document = collectibleTestPatternDocumentPtr(id, name+".tgs")
|
||||||
|
} else {
|
||||||
value.Document = collectibleTestDocumentPtr(id, name+".tgs")
|
value.Document = collectibleTestDocumentPtr(id, name+".tgs")
|
||||||
|
}
|
||||||
value.Blob = collectibleTestBlobPtr(id, name)
|
value.Blob = collectibleTestBlobPtr(id, name)
|
||||||
value.Animation = collectibleTestAnimationPtr(name + ".tgs")
|
value.Animation = collectibleTestAnimationPtr(name + ".tgs")
|
||||||
value.OfficialDocumentID = 5200000000000000000 + id%1000
|
value.OfficialDocumentID = 5200000000000000000 + id%1000
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue