package bundb_test import ( "context" "testing" "time" "gitea.dwysokinski.me/twhelp/dcbot/internal/bundb" "gitea.dwysokinski.me/twhelp/dcbot/internal/bundb/internal/model" "gitea.dwysokinski.me/twhelp/dcbot/internal/domain" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/uptrace/bun/dbfixture" ) func TestGroup_Create(t *testing.T) { t.Parallel() repo := bundb.NewGroup(newDB(t)) t.Run("OK", func(t *testing.T) { t.Parallel() params, err := domain.NewCreateGroupParams( "592292203234328587", "en", "en113", "1234", "1235", ) require.NoError(t, err) group, err := repo.Create(context.Background(), params) assert.NoError(t, err) _, err = uuid.Parse(group.ID) assert.NoError(t, err) assert.Equal(t, params.ServerID(), group.ServerID) assert.Equal(t, params.ServerKey(), group.ServerKey) assert.Equal(t, params.VersionCode(), group.VersionCode) assert.Equal(t, params.ChannelGains(), group.ChannelGains) assert.Equal(t, params.ChannelLosses(), group.ChannelLosses) assert.WithinDuration(t, time.Now(), group.CreatedAt, 1*time.Second) }) } func TestGroup_Update(t *testing.T) { t.Parallel() db := newDB(t) fixture := loadFixtures(t, db) repo := bundb.NewGroup(db) group := getGroupFromFixture(t, fixture, "group-1-server-1") t.Run("OK", func(t *testing.T) { t.Parallel() params := domain.UpdateGroupParams{ ChannelGains: domain.NullString{ String: group.ChannelGains + "update", Valid: true, }, ChannelLosses: domain.NullString{ String: group.ChannelLosses + "update", Valid: true, }, } updatedGroup, err := repo.Update(context.Background(), group.ID.String(), group.ServerID, params) assert.NoError(t, err) assert.Equal(t, params.ChannelGains.String, updatedGroup.ChannelGains) assert.Equal(t, params.ChannelLosses.String, updatedGroup.ChannelLosses) }) t.Run("ERR: nothing to update", func(t *testing.T) { t.Parallel() updatedGroup, err := repo.Update(context.Background(), "", "", domain.UpdateGroupParams{}) assert.ErrorIs(t, err, domain.ErrNothingToUpdate) assert.Zero(t, updatedGroup) }) t.Run("ERR: group not found", func(t *testing.T) { t.Parallel() tests := []struct { name string id string serverID string }{ { name: "ID - not UUID", id: "test", serverID: group.ServerID, }, { name: "ID - random UUID", id: uuid.NewString(), serverID: group.ServerID, }, { name: "ServerID - random UUID", id: group.ID.String(), serverID: uuid.NewString(), }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() updatedGroup, err := repo.Update(context.Background(), tt.id, tt.serverID, domain.UpdateGroupParams{ ChannelGains: domain.NullString{ String: "update", Valid: true, }, }) assert.ErrorIs(t, err, domain.GroupNotFoundError{ID: tt.id}) assert.Zero(t, updatedGroup) }) } }) } func TestGroup_List(t *testing.T) { t.Parallel() db := newDB(t) fixture := loadFixtures(t, db) repo := bundb.NewGroup(db) groups := getAllGroupsFromFixture(t, fixture) allGroups := make([]string, 0, len(groups)) for _, g := range groups { allGroups = append(allGroups, g.ID.String()) } tests := []struct { name string params domain.ListGroupsParams expectedGroups []string }{ { name: "no params", params: domain.ListGroupsParams{}, expectedGroups: allGroups, }, { name: "ServerIDs=[server-1]", params: domain.ListGroupsParams{ ServerIDs: []string{"server-1"}, }, expectedGroups: []string{ "d56ad37f-2637-48ea-98f8-79627f3fcc96", "429b790e-7186-4106-b531-4cc4931ce2ba", }, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() res, err := repo.List(context.Background(), tt.params) assert.NoError(t, err) assert.Len(t, res, len(tt.expectedGroups)) for _, id := range tt.expectedGroups { found := false for _, grp := range res { if grp.ID == id { found = true break } } assert.True(t, found, "group (id=%s) not found", id) } }) } } func TestGroup_Get(t *testing.T) { t.Parallel() db := newDB(t) fixture := loadFixtures(t, db) repo := bundb.NewGroup(db) group := getGroupFromFixture(t, fixture, "group-1-server-1") t.Run("OK", func(t *testing.T) { t.Parallel() g, err := repo.Get(context.Background(), group.ID.String(), group.ServerID) assert.NoError(t, err) assert.Equal(t, group.ToDomain(), g) }) t.Run("ERR: group not found (unknown ID)", func(t *testing.T) { t.Parallel() tests := []struct { name string id string serverID string }{ { name: "ID - not UUID", id: "test", serverID: group.ServerID, }, { name: "ID - random UUID", id: uuid.NewString(), serverID: group.ServerID, }, { name: "ServerID - random UUID", id: group.ID.String(), serverID: uuid.NewString(), }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() g, err := repo.Get(context.Background(), tt.id, tt.serverID) assert.ErrorIs(t, err, domain.GroupNotFoundError{ID: tt.id}) assert.Zero(t, g) }) } }) } func TestGroup_Delete(t *testing.T) { t.Parallel() db := newDB(t) fixture := loadFixtures(t, db) groupRepo := bundb.NewGroup(db) monitorRepo := bundb.NewMonitor(db) group := getGroupFromFixture(t, fixture, "group-1-server-1") t.Run("OK", func(t *testing.T) { t.Parallel() beforeDelete, err := groupRepo.List(context.Background(), domain.ListGroupsParams{ ServerIDs: []string{group.ServerID}, }) assert.NoError(t, err) assert.NoError(t, groupRepo.Delete(context.Background(), group.ID.String(), group.ServerID)) afterDelete, err := groupRepo.List(context.Background(), domain.ListGroupsParams{ ServerIDs: []string{group.ServerID}, }) assert.NoError(t, err) assert.Len(t, afterDelete, len(beforeDelete)-1) // monitors should also be deleted monitors, err := monitorRepo.List(context.Background(), group.ID.String()) assert.NoError(t, err) assert.Len(t, monitors, 0) }) t.Run("ERR: group not found", func(t *testing.T) { t.Parallel() tests := []struct { name string id string serverID string }{ { name: "ID - not UUID", id: "test", serverID: group.ServerID, }, { name: "ID - random UUID", id: uuid.NewString(), serverID: group.ServerID, }, { name: "ServerID - random UUID", id: group.ID.String(), serverID: uuid.NewString(), }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() assert.ErrorIs( t, groupRepo.Delete(context.Background(), tt.id, tt.serverID), domain.GroupNotFoundError{ID: tt.id}, ) }) } }) } func getAllGroupsFromFixture(tb testing.TB, fixture *dbfixture.Fixture) []model.Group { tb.Helper() //nolint:lll ids := []string{"group-1-server-1", "group-2-server-1", "group-1-server-2", "group-2-server-2"} groups := make([]model.Group, 0, len(ids)) for _, id := range ids { groups = append(groups, getGroupFromFixture(tb, fixture, id)) } return groups } func getGroupFromFixture(tb testing.TB, fixture *dbfixture.Fixture, id string) model.Group { tb.Helper() row, err := fixture.Row("Group." + id) require.NoError(tb, err) g, ok := row.(*model.Group) require.True(tb, ok) return *g }