This repository has been archived on 2024-04-06. You can view files and clone it, but cannot push or open issues or pull requests.
core-old/internal/adapter/player_snapshot_bun_repository_test.go
Dawid Wysokiński 9c1b580adb
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
refactor: adapters - rename structs/files
2023-07-22 08:22:28 +02:00

466 lines
13 KiB
Go

package adapter_test
import (
"context"
"testing"
"time"
"gitea.dwysokinski.me/twhelp/core/internal/adapter"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/jackc/pgerrcode"
"github.com/stretchr/testify/assert"
"github.com/uptrace/bun/driver/pgdriver"
)
func TestPlayerSnapshotBunRepository_Create(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("skipping long-running test")
}
db := newBunDB(t)
fixture := loadFixtures(t, db)
repo := adapter.NewPlayerSnapshotBunRepository(db)
t.Run("OK", func(t *testing.T) {
t.Parallel()
playerGSus := fixture.Player(t, "de188-g-sus")
playerRIP := fixture.Player(t, "de188-rest-in-peace")
params := []domain.CreatePlayerSnapshotParams{
{
OpponentsDefeated: playerGSus.OpponentsDefeated,
PlayerID: playerGSus.ID,
NumVillages: playerGSus.NumVillages,
Points: playerGSus.Points,
Rank: playerGSus.Rank,
TribeID: playerGSus.TribeID,
ServerKey: playerGSus.ServerKey,
Date: time.Now().Add(-15 * time.Hour),
},
{
OpponentsDefeated: playerGSus.OpponentsDefeated,
PlayerID: playerGSus.ID,
NumVillages: playerGSus.NumVillages,
Points: playerGSus.Points,
Rank: playerGSus.Rank,
TribeID: playerGSus.TribeID,
ServerKey: playerGSus.ServerKey,
Date: time.Now().Add(-48 * time.Hour),
},
{
OpponentsDefeated: playerRIP.OpponentsDefeated,
PlayerID: playerRIP.ID,
NumVillages: playerRIP.NumVillages,
Points: playerRIP.Points,
Rank: playerRIP.Rank,
TribeID: playerRIP.TribeID,
ServerKey: playerRIP.ServerKey,
Date: time.Now().Add(-14 * time.Hour),
},
}
assert.NoError(t, repo.Create(context.Background(), params...))
snapshots, err := repo.List(context.Background(), domain.ListPlayerSnapshotsParams{
ServerKeys: []string{playerGSus.ServerKey},
})
assert.NoError(t, err)
for _, p := range params {
var found bool
for _, s := range snapshots {
if cmp.Equal(p, domain.CreatePlayerSnapshotParams{
OpponentsDefeated: s.OpponentsDefeated,
PlayerID: s.PlayerID,
NumVillages: s.NumVillages,
Points: s.Points,
Rank: s.Rank,
TribeID: s.TribeID,
ServerKey: s.ServerKey,
Date: s.Date,
}, cmpopts.EquateApproxTime(24*time.Hour)) && s.ID > 0 && !s.CreatedAt.IsZero() {
found = true
break
}
}
assert.True(t, found)
}
})
t.Run("OK: len(params) == 0", func(t *testing.T) {
t.Parallel()
assert.NoError(t, repo.Create(context.Background()))
})
t.Run("ERR: snapshot already exists", func(t *testing.T) {
t.Parallel()
playerRiou89 := fixture.Player(t, "de188-riou89")
params := []domain.CreatePlayerSnapshotParams{
{
OpponentsDefeated: playerRiou89.OpponentsDefeated,
PlayerID: playerRiou89.ID,
NumVillages: playerRiou89.NumVillages,
Points: playerRiou89.Points,
Rank: playerRiou89.Rank,
TribeID: playerRiou89.TribeID,
ServerKey: playerRiou89.ServerKey,
Date: time.Now().Add(-48 * time.Hour),
},
{
OpponentsDefeated: playerRiou89.OpponentsDefeated,
PlayerID: playerRiou89.ID,
NumVillages: playerRiou89.NumVillages,
Points: playerRiou89.Points,
Rank: playerRiou89.Rank,
TribeID: playerRiou89.TribeID,
ServerKey: playerRiou89.ServerKey,
Date: time.Now().Add(-48 * time.Hour),
},
}
err := repo.Create(context.Background(), params...)
var pgErr pgdriver.Error
assert.ErrorAs(t, err, &pgErr)
assert.Equal(t, pgerrcode.UniqueViolation, pgErr.Field('C'))
assert.Equal(t, "player_snapshots_player_id_server_key_date_key", pgErr.Field('n'))
})
t.Run("ERR: server doesn't exist", func(t *testing.T) {
t.Parallel()
playerRiou89 := fixture.Player(t, "de188-riou89")
params := []domain.CreatePlayerSnapshotParams{
{
OpponentsDefeated: playerRiou89.OpponentsDefeated,
PlayerID: playerRiou89.ID,
NumVillages: playerRiou89.NumVillages,
Points: playerRiou89.Points,
Rank: playerRiou89.Rank,
TribeID: playerRiou89.TribeID,
ServerKey: "random",
Date: time.Now().Add(-48 * time.Hour),
},
}
err := repo.Create(context.Background(), params...)
var pgErr pgdriver.Error
assert.ErrorAs(t, err, &pgErr)
assert.Equal(t, pgerrcode.ForeignKeyViolation, pgErr.Field('C'))
assert.Equal(t, "player_snapshots_server_key_fkey", pgErr.Field('n'))
})
t.Run("ERR: player must exist", func(t *testing.T) {
t.Parallel()
playerRiou89 := fixture.Player(t, "de188-riou89")
params := []domain.CreatePlayerSnapshotParams{
{
OpponentsDefeated: playerRiou89.OpponentsDefeated,
PlayerID: playerRiou89.ID + 11112221,
NumVillages: playerRiou89.NumVillages,
Points: playerRiou89.Points,
Rank: playerRiou89.Rank,
TribeID: playerRiou89.TribeID,
ServerKey: playerRiou89.ServerKey,
Date: time.Now().Add(-48 * time.Hour),
},
}
err := repo.Create(context.Background(), params...)
var pgErr pgdriver.Error
assert.ErrorAs(t, err, &pgErr)
assert.Equal(t, pgerrcode.ForeignKeyViolation, pgErr.Field('C'))
assert.Equal(t, "player_snapshots_player_id_server_key_fkey", pgErr.Field('n'))
})
}
func TestPlayerSnapshotBunRepository_List(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("skipping long-running test")
}
db := newBunDB(t)
fixture := loadFixtures(t, db)
repo := adapter.NewPlayerSnapshotBunRepository(db)
snapshots := fixture.PlayerSnapshots(t)
type expectedSnapshots struct {
id int64
serverKey string
}
allSnapshots := make([]expectedSnapshots, 0, len(snapshots))
for _, s := range snapshots {
allSnapshots = append(allSnapshots, expectedSnapshots{
id: s.ID,
serverKey: s.ServerKey,
})
}
//nolint:prealloc
var snapshotsDE188 []expectedSnapshots
for _, s := range snapshots {
if s.ServerKey != "de188" {
continue
}
snapshotsDE188 = append(snapshotsDE188, expectedSnapshots{
id: s.ID,
serverKey: s.ServerKey,
})
}
tests := []struct {
name string
params domain.ListPlayerSnapshotsParams
expectedSnapshots []expectedSnapshots
expectedCount int64
expectedErr error
}{
{
name: "Sort=[{By=Date,Direction=ASC},{By=ID,Direction=ASC}]",
params: domain.ListPlayerSnapshotsParams{
Sort: []domain.PlayerSnapshotSort{
{
By: domain.PlayerSnapshotSortByDate,
Direction: domain.SortDirectionASC,
},
{
By: domain.PlayerSnapshotSortByID,
Direction: domain.SortDirectionASC,
},
},
},
expectedSnapshots: allSnapshots,
expectedCount: int64(len(allSnapshots)),
},
{
name: "ServerKey=[de188],Sort=[{By=Date,Direction=ASC},{By=ID,Direction=ASC}]",
params: domain.ListPlayerSnapshotsParams{
ServerKeys: []string{"de188"},
Sort: []domain.PlayerSnapshotSort{
{
By: domain.PlayerSnapshotSortByDate,
Direction: domain.SortDirectionASC,
},
{
By: domain.PlayerSnapshotSortByID,
Direction: domain.SortDirectionASC,
},
},
},
expectedSnapshots: snapshotsDE188,
expectedCount: int64(len(snapshotsDE188)),
},
{
name: "ServerKey=[pl169],Sort=[{By=Date,Direction=ASC},{By=ID,Direction=ASC}],Limit=2",
params: domain.ListPlayerSnapshotsParams{
ServerKeys: []string{"pl169"},
Pagination: domain.Pagination{
Limit: 2,
},
Sort: []domain.PlayerSnapshotSort{
{
By: domain.PlayerSnapshotSortByDate,
Direction: domain.SortDirectionASC,
},
{
By: domain.PlayerSnapshotSortByID,
Direction: domain.SortDirectionASC,
},
},
},
expectedSnapshots: []expectedSnapshots{
{
id: 100000,
serverKey: "pl169",
},
{
id: 100001,
serverKey: "pl169",
},
},
expectedCount: 3,
},
{
name: "ServerKey=[pl169],Sort=[{By=Date,Direction=ASC},{By=ID,Direction=ASC}],Offset=1",
params: domain.ListPlayerSnapshotsParams{
ServerKeys: []string{"pl169"},
Pagination: domain.Pagination{
Offset: 1,
},
Sort: []domain.PlayerSnapshotSort{
{
By: domain.PlayerSnapshotSortByDate,
Direction: domain.SortDirectionASC,
},
{
By: domain.PlayerSnapshotSortByID,
Direction: domain.SortDirectionASC,
},
},
},
expectedSnapshots: []expectedSnapshots{
{
id: 100001,
serverKey: "pl169",
},
{
id: 100050,
serverKey: "pl169",
},
},
expectedCount: 3,
},
{
name: "ServerKey=[pl169],Sort=[{By=Date,Direction=DESC},{By=ID,Direction=ASC}],Offset=2,Limit=1",
params: domain.ListPlayerSnapshotsParams{
ServerKeys: []string{"pl169"},
Pagination: domain.Pagination{
Limit: 1,
Offset: 2,
},
Sort: []domain.PlayerSnapshotSort{
{
By: domain.PlayerSnapshotSortByDate,
Direction: domain.SortDirectionDESC,
},
{
By: domain.PlayerSnapshotSortByID,
Direction: domain.SortDirectionASC,
},
},
},
expectedSnapshots: []expectedSnapshots{
{
id: 100000,
serverKey: "pl169",
},
},
expectedCount: 3,
},
{
name: "ServerKey=[pl169],PlayerIDs=[6180190],Sort=[{By=ID,Direction=DESC}],Limit=1",
params: domain.ListPlayerSnapshotsParams{
ServerKeys: []string{"pl169"},
PlayerIDs: []int64{6180190},
Pagination: domain.Pagination{
Limit: 1,
},
Sort: []domain.PlayerSnapshotSort{
{
By: domain.PlayerSnapshotSortByID,
Direction: domain.SortDirectionDESC,
},
},
},
expectedSnapshots: []expectedSnapshots{
{
id: 100001,
serverKey: "pl169",
},
},
expectedCount: 2,
},
{
name: "ERR: unsupported sort by",
params: domain.ListPlayerSnapshotsParams{
Sort: []domain.PlayerSnapshotSort{
{By: 100, Direction: domain.SortDirectionDESC},
},
},
expectedSnapshots: nil,
expectedCount: 0,
expectedErr: domain.ErrUnsupportedSortBy,
},
{
name: "ERR: unsupported sort direction",
params: domain.ListPlayerSnapshotsParams{
Sort: []domain.PlayerSnapshotSort{
{By: domain.PlayerSnapshotSortByDate, Direction: 100},
},
},
expectedSnapshots: nil,
expectedCount: 0,
expectedErr: domain.ErrUnsupportedSortDirection,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
resListCountWithRelations, count, err := repo.ListCountWithRelations(context.Background(), tt.params)
assert.ErrorIs(t, err, tt.expectedErr)
assert.Equal(t, tt.expectedCount, count)
assert.Len(t, resListCountWithRelations, len(tt.expectedSnapshots))
for _, expSnapshot := range tt.expectedSnapshots {
found := false
for _, snapshot := range resListCountWithRelations {
if snapshot.ID != expSnapshot.id {
continue
}
if snapshot.ServerKey != expSnapshot.serverKey {
continue
}
if snapshot.TribeID != 0 && (!snapshot.Tribe.Valid || snapshot.Tribe.Tribe.ID != snapshot.TribeID) {
continue
}
if snapshot.TribeID == 0 && snapshot.Tribe.Valid {
continue
}
found = true
break
}
assert.True(t, found, "snapshot (id=%d,serverkey=%s) not found", expSnapshot.id, expSnapshot.serverKey)
}
resList, err := repo.List(context.Background(), tt.params)
assert.ErrorIs(t, err, tt.expectedErr)
assert.Len(t, resList, len(resListCountWithRelations))
for i, snapshot := range resList {
assert.Equal(t, resListCountWithRelations[i].PlayerSnapshot, snapshot)
}
})
}
}
func TestPlayerSnapshotBunRepository_Delete(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("skipping long-running test")
}
db := newBunDB(t)
fixture := loadFixtures(t, db)
repo := adapter.NewPlayerSnapshotBunRepository(db)
snapshotsBeforeDelete, err := repo.List(context.Background(), domain.ListPlayerSnapshotsParams{})
assert.NoError(t, err)
assert.Greater(t, len(snapshotsBeforeDelete), 0)
assert.NoError(t, repo.Delete(context.Background(), fixture.Server(t, "pl169").Key, time.Date(2021, time.September, 3, 23, 0, 0, 0, time.UTC)))
snapshotsAfterDelete, err := repo.List(context.Background(), domain.ListPlayerSnapshotsParams{})
assert.NoError(t, err)
assert.Equal(t, len(snapshotsBeforeDelete)-2, len(snapshotsAfterDelete))
}