From bb456583103ae1de98cfca78a765d25d0b95c58b Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 15:13:40 +0200 Subject: [PATCH] feat(TagAlias): added function and tests Signed-off-by: SoXX --- internal/postgres/tag.go | 94 ++++++++++++++++ internal/postgres/tag_test.go | 98 +++++++++++++++++ pkg/database/postgres.go | 86 ++++++++------- pkg/database/postgres_test.go | 194 +++++++++++++++++++++++++--------- 4 files changed, 379 insertions(+), 93 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 23e23ef..729d57a 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -90,3 +90,97 @@ func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { return tags, nil } + +func CreateTagAlias(ctx context.Context, db *gorm.DB, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { + + if tagAliasName == "" { + return &otterError.EntityValidationFailed{Reason: "tagAliasName cannot be empty"} + } + if tagID == "" { + return &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + } + + result := db.WithContext(ctx).Create(&models.TagAlias{ + Name: string(tagAliasName), + TagID: string(tagID), + }) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &otterError.EntityAlreadyExists{} + } + return result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_name": tagAliasName, + "tag_alias_tag_id": tagID, + }).Trace("database: created tagAlias") + + return nil +} + +func GetAllTagAlias(ctx context.Context, db *gorm.DB) ([]models.TagAlias, error) { + var tagAliases []models.TagAlias + + result := db.WithContext(ctx).Find(&tagAliases) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &otterError.NoDataFound{} + } + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_length": len(tagAliases), + }).Trace("database: created tagAlias") + + return tagAliases, nil +} + +func GetAllTagAliasByTag(ctx context.Context, db *gorm.DB, tagID models.AnthroveTagID) ([]models.TagAlias, error) { + var tagAliases []models.TagAlias + + if tagID == "" { + return nil, &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + } + + result := db.WithContext(ctx).Where("tag_id = ?", tagID).Find(&tagAliases) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &otterError.NoDataFound{} + } + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_length": len(tagAliases), + "tag_alias_tag_id": tagID, + }).Trace("database: get specific tagAlias") + + return tagAliases, nil +} + +func DeleteTagAlias(ctx context.Context, db *gorm.DB, tagAliasName models.AnthroveTagAliasName) error { + + if tagAliasName == "" { + return &otterError.EntityValidationFailed{Reason: "tagAliasName cannot be empty"} + } + + result := db.WithContext(ctx).Delete(&models.TagAlias{Name: string(tagAliasName)}) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return &otterError.NoDataFound{} + } + return result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_name": tagAliasName, + }).Trace("database: deleted tagAlias") + + return nil +} diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 3f22c76..c18712a 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -246,3 +246,101 @@ func TestCreateTag(t *testing.T) { }) } } + +func TestCreateTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTagAliasName01 := models.AnthroveTagAliasName("httyd") + validTagAliasName02 := models.AnthroveTagAliasName("dragon") + + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagAliasName models.AnthroveTagAliasName + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: false, + }, + { + name: "Test 2: No TagAliasName", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: "", + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 4: No tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName01, + tagID: "", + }, + wantErr: true, + }, + { + name: "Test 5: Duplicate tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 6: Invalide tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName02, + tagID: "aaa", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateTagAlias(tt.args.ctx, tt.args.db, tt.args.tagAliasName, tt.args.tagID); (err != nil) != tt.wantErr { + t.Errorf("CreateTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index b63ca0b..d511a84 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -148,50 +148,7 @@ func (p *postgresqlConnection) GetSourceByDomain(ctx context.Context, sourceDoma return postgres.GetSourceByDomain(ctx, p.db, sourceDomain) } -func (p *postgresqlConnection) GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) UpdateUserWithScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { - //TODO implement me - panic("implement me") -} +// NEW FUNCTIONS func (p *postgresqlConnection) UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { //TODO implement me @@ -208,6 +165,47 @@ func (p *postgresqlConnection) UpdateUserSourceValidation(ctx context.Context, a panic("implement me") } +func (p *postgresqlConnection) CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { + return postgres.CreateTagAlias(ctx, p.db, tagAliasName, tagID) +} + +func (p *postgresqlConnection) GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error { + //TODO implement me + panic("implement me") +} + +// HELPER + func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error { dialect := "postgres" migrations := &migrate.EmbedFileSystemMigrationSource{FileSystem: embedMigrations, Root: "migrations"} diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 26a46fb..6950118 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -1898,55 +1898,6 @@ func Test_postgresqlConnection_GetSourceByDomain(t *testing.T) { } } -func checkSource(got *models.Source, want *models.Source) bool { - - if want == nil && got == nil { - return true - } - - if got.Domain != want.Domain { - return false - } - - return true - -} - -func checkPost(got *models.Post, want *models.Post) bool { - - if got == nil && want == nil { - return true - } else if got == nil || want == nil { - return false - } - - if got.ID != want.ID { - return false - } - - if got.Rating != want.Rating { - return false - } - - return true -} - -func checkSources(got []models.Source, want []models.Source) bool { - for i, source := range want { - if source.DisplayName != got[i].DisplayName { - return false - } - if source.Domain != got[i].Domain { - return false - } - if source.Icon != got[i].Icon { - return false - } - } - - return true -} - func Test_postgresqlConnection_migrateDatabase(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -1986,6 +1937,53 @@ func Test_postgresqlConnection_migrateDatabase(t *testing.T) { } } +// Helper functions for validation purposes +func checkSource(got *models.Source, want *models.Source) bool { + + if want == nil && got == nil { + return true + } + + if got.Domain != want.Domain { + return false + } + + return true + +} +func checkPost(got *models.Post, want *models.Post) bool { + + if got == nil && want == nil { + return true + } else if got == nil || want == nil { + return false + } + + if got.ID != want.ID { + return false + } + + if got.Rating != want.Rating { + return false + } + + return true +} +func checkSources(got []models.Source, want []models.Source) bool { + for i, source := range want { + if source.DisplayName != got[i].DisplayName { + return false + } + if source.Domain != got[i].Domain { + return false + } + if source.Icon != got[i].Icon { + return false + } + } + + return true +} func checkUser(got []models.User, want []models.User) bool { for i, user := range want { if user.ID != got[i].ID { @@ -2020,3 +2018,101 @@ func checkUserSource(got *models.UserSource, want *models.UserSource) bool { return true } + +//------------------------- + +func Test_postgresqlConnection_CreateTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTagAliasName01 := models.AnthroveTagAliasName("httyd") + validTagAliasName02 := models.AnthroveTagAliasName("dragon") + + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + tagAliasName models.AnthroveTagAliasName + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: false, + }, + { + name: "Test 2: No TagAliasName", + args: args{ + ctx: ctx, + tagAliasName: "", + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 4: No tagID", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName01, + tagID: "", + }, + wantErr: true, + }, + { + name: "Test 5: Duplicate tagID", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 6: Invalide tagID", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName02, + tagID: "aaa", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateTagAlias(tt.args.ctx, tt.args.tagAliasName, tt.args.tagID); (err != nil) != tt.wantErr { + t.Errorf("CreateTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +}