package cardmaster import ( "encoding/json" "errors" "testing" ) func TestService_GetAllPaginated_Success(t *testing.T) { repo := &mockRepository{ findAllPaginatedFunc: func(page, limit int, query ListCardMasterQuery) ([]CardMaster, int64, error) { return []CardMaster{ {ID: 1, Name: "Pikachu"}, {ID: 2, Name: "Charizard"}, }, 2, nil }, } svc := NewService(repo) list, total, err := svc.GetAllPaginated(ListCardMasterQuery{Page: 1, Limit: 20}) if err != nil { t.Fatalf("expected no error, got: %v", err) } if total != 2 { t.Errorf("expected total 2, got: %d", total) } if len(list) != 2 { t.Errorf("expected list length 2, got: %d", len(list)) } } func TestService_GetAllPaginated_DefaultNormalization(t *testing.T) { var capturedPage, capturedLimit int repo := &mockRepository{ findAllPaginatedFunc: func(page, limit int, query ListCardMasterQuery) ([]CardMaster, int64, error) { capturedPage, capturedLimit = page, limit return []CardMaster{{ID: 1, Name: "Bulbasaur"}}, 1, nil }, } svc := NewService(repo) _, total, err := svc.GetAllPaginated(ListCardMasterQuery{Page: 0, Limit: 0}) if err != nil { t.Fatalf("expected no error, got: %v", err) } if total != 1 { t.Errorf("expected total 1, got: %d", total) } if capturedPage != 1 { t.Errorf("expected page normalized to 1, got: %d", capturedPage) } if capturedLimit != 20 { t.Errorf("expected limit normalized to 20, got: %d", capturedLimit) } } func TestService_GetByID_Success(t *testing.T) { repo := &mockRepository{ findByIDFunc: func(id uint) (*CardMaster, error) { return &CardMaster{ID: id, Name: "Bulbasaur"}, nil }, } svc := NewService(repo) c, err := svc.GetByID(1) if err != nil { t.Fatalf("expected no error, got: %v", err) } if c.ID != 1 { t.Errorf("expected ID 1, got: %d", c.ID) } if c.Name != "Bulbasaur" { t.Errorf("expected Name 'Bulbasaur', got: '%s'", c.Name) } } func TestService_GetByID_NotFound(t *testing.T) { repo := &mockRepository{ findByIDFunc: func(id uint) (*CardMaster, error) { return nil, errors.New("record not found") }, } svc := NewService(repo) _, err := svc.GetByID(999) if !errors.Is(err, ErrCardNotFound) { t.Fatalf("expected ErrCardNotFound, got: %v", err) } } func TestService_Update_Success(t *testing.T) { repo := &mockRepository{ findByIDFunc: func(id uint) (*CardMaster, error) { return &CardMaster{ID: id, Name: "Old Name", Element: "Daun"}, nil }, updateFunc: func(c *CardMaster, oldIDSet uint) error { return nil }, } svc := NewService(repo) req := UpdateCardMasterRequest{ Name: "Bulbasaur Mega", Element: "Daun", } updated, err := svc.Update(1, req) if err != nil { t.Fatalf("expected no error, got: %v", err) } if updated.Name != "Bulbasaur Mega" { t.Errorf("expected Name 'Bulbasaur Mega', got: '%s'", updated.Name) } if updated.ElementImage != "/images/elements/Grass.png" { t.Errorf("expected ElementImage '/images/elements/Grass.png', got: '%s'", updated.ElementImage) } } func TestService_Update_NotFound(t *testing.T) { repo := &mockRepository{ findByIDFunc: func(id uint) (*CardMaster, error) { return nil, errors.New("record not found") }, } svc := NewService(repo) _, err := svc.Update(999, UpdateCardMasterRequest{Name: "New Name"}) if !errors.Is(err, ErrCardNotFound) { t.Fatalf("expected ErrCardNotFound, got: %v", err) } } func TestService_Update_EnrichElementImage(t *testing.T) { repo := &mockRepository{ findByIDFunc: func(id uint) (*CardMaster, error) { return &CardMaster{ID: id, Name: "Charmander"}, nil }, updateFunc: func(c *CardMaster, oldIDSet uint) error { return nil }, } svc := NewService(repo) req := UpdateCardMasterRequest{ HP: &HP{Value: "70", Element: "Api"}, Attacks: []Attack{ { Name: "Flame Burst", Cost: []AttackCost{ {Element: "Api"}, }, Damage: "30", }, }, } updated, err := svc.Update(1, req) if err != nil { t.Fatalf("expected no error, got: %v", err) } var parsedHP HP if err := json.Unmarshal(updated.HP, &parsedHP); err != nil { t.Fatalf("failed to unmarshal HP: %v", err) } if parsedHP.ElementImage != "/images/elements/Fire.png" { t.Errorf("expected HP ElementImage '/images/elements/Fire.png', got: '%s'", parsedHP.ElementImage) } var parsedAttacks []Attack if err := json.Unmarshal(updated.Attacks, &parsedAttacks); err != nil { t.Fatalf("failed to unmarshal Attacks: %v", err) } if len(parsedAttacks) != 1 || parsedAttacks[0].Cost[0].Image != "/images/elements/Fire.png" { t.Errorf("expected Attack Cost Image '/images/elements/Fire.png', got: '%s'", parsedAttacks[0].Cost[0].Image) } }