Compare commits

..

3 Commits

Author SHA1 Message Date
2d4102be6a refactor: added getting of tag by specific type
Some checks failed
Gitea Build Check / Build (push) Has been cancelled
Gitea Build Check / Build (pull_request) Successful in 11m44s
Signed-off-by: SoXX <soxx@fenpa.ws>
2024-07-01 22:29:37 +02:00
a842d64f1c refactor: added deletion of tags
Signed-off-by: SoXX <soxx@fenpa.ws>
2024-07-01 22:15:43 +02:00
1b40c6145a refactor: changed CreateTag to align with other functions
Signed-off-by: SoXX <soxx@fenpa.ws>
2024-07-01 22:06:36 +02:00
7 changed files with 440 additions and 37 deletions

View File

@ -10,13 +10,17 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { func CreateTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName, tagType models.TagType) error {
if tag == nil { if tagName == "" {
return &otterError.EntityValidationFailed{Reason: "Tag is nil"} return &otterError.EntityValidationFailed{Reason: "tagName cannot be empty"}
} }
result := db.WithContext(ctx).Create(tag) if tagType == "" {
return &otterError.EntityValidationFailed{Reason: "tagType cannot be empty"}
}
result := db.WithContext(ctx).Create(&models.Tag{Name: string(tagName), Type: tagType})
if result.Error != nil { if result.Error != nil {
if errors.Is(result.Error, gorm.ErrDuplicatedKey) { if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
return &otterError.EntityAlreadyExists{} return &otterError.EntityAlreadyExists{}
@ -29,13 +33,58 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error {
} }
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"tag_name": tag.Name, "tag_name": tagName,
"tag_type": tag.Type, "tag_type": tagType,
}).Trace("database: created tag node") }).Trace("database: created tag node")
return nil return nil
} }
func DeleteTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName) error {
if tagName == "" {
return &otterError.EntityValidationFailed{Reason: "tagName cannot be empty"}
}
result := db.WithContext(ctx).Delete(&models.Tag{Name: string(tagName)})
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return &otterError.NoDataFound{}
}
return result.Error
}
log.WithFields(log.Fields{
"tag_name": tagName,
}).Trace("database: deleted tag")
return nil
}
func GetAllTagByTagsType(ctx context.Context, db *gorm.DB, tagType models.TagType) ([]models.Tag, error) {
var tags []models.Tag
if tagType == "" {
return nil, &otterError.EntityValidationFailed{Reason: "tagType cannot be empty"}
}
result := db.WithContext(ctx).Find(&tags).Where("tag_type = ?", tagType)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, &otterError.NoDataFound{}
}
return nil, result.Error
}
log.WithFields(log.Fields{
"tags_length": len(tags),
}).Trace("database: got tag")
return tags, nil
}
func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, tag *models.Tag) error { func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, tag *models.Tag) error {
if anthrovePostID == "" { if anthrovePostID == "" {

View File

@ -128,7 +128,7 @@ func TestGetTags(t *testing.T) {
} }
for _, tag := range tags { for _, tag := range tags {
err = CreateTag(ctx, gormDB, &tag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -204,7 +204,8 @@ func TestCreateTag(t *testing.T) {
type args struct { type args struct {
ctx context.Context ctx context.Context
db *gorm.DB db *gorm.DB
tag *models.Tag tagName models.AnthroveTagName
tagType models.TagType
} }
tests := []struct { tests := []struct {
name string name string
@ -216,7 +217,8 @@ func TestCreateTag(t *testing.T) {
args: args{ args: args{
ctx: ctx, ctx: ctx,
db: gormDB, db: gormDB,
tag: &validTag, tagName: models.AnthroveTagName(validTag.Name),
tagType: validTag.Type,
}, },
wantErr: false, wantErr: false,
}, },
@ -225,7 +227,8 @@ func TestCreateTag(t *testing.T) {
args: args{ args: args{
ctx: ctx, ctx: ctx,
db: gormDB, db: gormDB,
tag: &validTag, tagName: models.AnthroveTagName(validTag.Name),
tagType: validTag.Type,
}, },
wantErr: true, wantErr: true,
}, },
@ -234,14 +237,15 @@ func TestCreateTag(t *testing.T) {
args: args{ args: args{
ctx: ctx, ctx: ctx,
db: gormDB, db: gormDB,
tag: &invalidTag, tagName: models.AnthroveTagName(invalidTag.Name),
tagType: invalidTag.Type,
}, },
wantErr: true, wantErr: true,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if err := CreateTag(tt.args.ctx, tt.args.db, tt.args.tag); (err != nil) != tt.wantErr { if err := CreateTag(tt.args.ctx, tt.args.db, tt.args.tagName, tt.args.tagType); (err != nil) != tt.wantErr {
t.Errorf("CreateTag() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("CreateTag() error = %v, wantErr %v", err, tt.wantErr)
} }
}) })
@ -269,7 +273,7 @@ func TestCreateTagAlias(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -379,7 +383,7 @@ func TestGetAllTagAlias(t *testing.T) {
}, },
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -456,7 +460,7 @@ func TestGetAllTagAliasByTag(t *testing.T) {
}, },
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -540,7 +544,7 @@ func TestDeleteTagAlias(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -618,7 +622,7 @@ func TestCreateTagGroup(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -728,7 +732,7 @@ func TestGetAllTagGroup(t *testing.T) {
}, },
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -805,7 +809,7 @@ func TestGetAllTagGroupByTag(t *testing.T) {
}, },
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -889,7 +893,7 @@ func TestDeleteTagGroup(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = CreateTag(ctx, gormDB, validTag) err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -945,3 +949,167 @@ func TestDeleteTagGroup(t *testing.T) {
}) })
} }
} }
func TestDeleteTag(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
validTagID := models.AnthroveTagID("toothless")
validTag := &models.Tag{
Name: string(validTagID),
Type: models.Character,
}
err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil {
t.Fatal(err)
}
// Test
type args struct {
ctx context.Context
db *gorm.DB
tagName models.AnthroveTagName
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Test 1: Valid TagName",
args: args{
ctx: ctx,
db: gormDB,
tagName: models.AnthroveTagName(validTagID),
},
wantErr: false,
},
{
name: "Test 2: Invalid TagName",
args: args{
ctx: ctx,
db: gormDB,
tagName: models.AnthroveTagName("aaa"),
},
wantErr: false,
},
{
name: "Test 3: No TagName",
args: args{
ctx: ctx,
db: gormDB,
tagName: "",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := DeleteTag(tt.args.ctx, tt.args.db, tt.args.tagName); (err != nil) != tt.wantErr {
t.Errorf("DeleteTag() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestGetAllTagByTagType(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
validTags := []models.Tag{
{
Name: "JayTheFerret",
Type: models.Character,
},
{
Name: "SoXX",
Type: models.Character,
},
{
Name: "Alphyron",
Type: models.Character,
},
{
Name: "Dragon",
Type: models.Species,
},
}
for _, tag := range validTags {
err = CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type)
if err != nil {
t.Fatal(err)
}
}
// Test
type args struct {
ctx context.Context
db *gorm.DB
tagType models.TagType
}
tests := []struct {
name string
args args
want []models.Tag
wantErr bool
}{
{
name: "Test 1: Get Data",
args: args{
ctx: ctx,
db: gormDB,
tagType: models.Character,
},
want: validTags,
wantErr: false,
},
{
name: "Test 2: invalid Tag Type",
args: args{
ctx: ctx,
db: gormDB,
tagType: "aa",
},
want: validTags,
wantErr: false,
},
{
name: "Test 3: No Tag Type",
args: args{
ctx: ctx,
db: gormDB,
tagType: "",
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GetAllTagByTagsType(tt.args.ctx, tt.args.db, tt.args.tagType)
if (err != nil) != tt.wantErr {
t.Errorf("GetAllTagByTagsType() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !checkTag(got, tt.want) {
t.Errorf("GetAllTagByTagsType() got = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -19,6 +19,9 @@ type OtterSpace interface {
// Source contains all function that are needed to manage the Source // Source contains all function that are needed to manage the Source
Source Source
// Tag contains all functions that are used to manage Tag
Tag
// TagAlias contains all function that are needed to manage the TagAlias // TagAlias contains all function that are needed to manage the TagAlias
TagAlias TagAlias

View File

@ -202,6 +202,18 @@ func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName
return postgres.DeleteTagGroup(ctx, p.db, tagGroupName) return postgres.DeleteTagGroup(ctx, p.db, tagGroupName)
} }
func (p *postgresqlConnection) CreateTag(ctx context.Context, tagName models.AnthroveTagName, tagType models.TagType) error {
return postgres.CreateTag(ctx, p.db, tagName, tagType)
}
func (p *postgresqlConnection) GetAllTagsByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error) {
return postgres.GetAllTagByTagsType(ctx, p.db, tagType)
}
func (p *postgresqlConnection) DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error {
return postgres.DeleteTag(ctx, p.db, tagName)
}
// HELPER // HELPER
func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error { func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error {

View File

@ -1704,7 +1704,7 @@ func Test_postgresqlConnection_GetAllTags(t *testing.T) {
} }
for _, tag := range tags { for _, tag := range tags {
err = postgres.CreateTag(ctx, gormDB, &tag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2043,7 +2043,7 @@ func Test_postgresqlConnection_CreateTagAlias(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2151,7 +2151,7 @@ func Test_postgresqlConnection_GetAllTagAlias(t *testing.T) {
}, },
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2228,7 +2228,7 @@ func Test_postgresqlConnection_GetAllTagAliasByTag(t *testing.T) {
}, },
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2312,7 +2312,7 @@ func Test_postgresqlConnection_DeleteTagAlias(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2392,7 +2392,7 @@ func Test_postgresqlConnection_CreateTagGroup(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2500,7 +2500,7 @@ func Test_postgresqlConnection_GetAllTagGroup(t *testing.T) {
}, },
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2577,7 +2577,7 @@ func Test_postgresqlConnection_GetAllTagGroupByTag(t *testing.T) {
}, },
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2661,7 +2661,7 @@ func Test_postgresqlConnection_DeleteTagGroup(t *testing.T) {
Type: models.Character, Type: models.Character,
} }
err = postgres.CreateTag(ctx, gormDB, validTag) err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -3073,3 +3073,167 @@ func Test_postgresqlConnection_UpdateUserSourceValidation(t *testing.T) {
}) })
} }
} }
func Test_postgresqlConnection_DeleteTag(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
validTagID := models.AnthroveTagID("toothless")
validTag := &models.Tag{
Name: string(validTagID),
Type: models.Character,
}
err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type)
if err != nil {
t.Fatal(err)
}
// Test
type args struct {
ctx context.Context
tagName models.AnthroveTagName
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Test 1: Valid TagName",
args: args{
ctx: ctx,
tagName: models.AnthroveTagName(validTagID),
},
wantErr: false,
},
{
name: "Test 2: Invalid TagName",
args: args{
ctx: ctx,
tagName: models.AnthroveTagName("aaa"),
},
wantErr: false,
},
{
name: "Test 3: No TagName",
args: args{
ctx: ctx,
tagName: "",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &postgresqlConnection{
db: gormDB,
debug: true,
}
if err := p.DeleteTag(tt.args.ctx, tt.args.tagName); (err != nil) != tt.wantErr {
t.Errorf("DeleteTag() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_postgresqlConnection_GetAllTagsByTagType(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
validTags := []models.Tag{
{
Name: "JayTheFerret",
Type: models.Character,
},
{
Name: "SoXX",
Type: models.Character,
},
{
Name: "Alphyron",
Type: models.Character,
},
{
Name: "Dragon",
Type: models.Species,
},
}
for _, tag := range validTags {
err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type)
if err != nil {
t.Fatal(err)
}
}
// Test
type args struct {
ctx context.Context
tagType models.TagType
}
tests := []struct {
name string
args args
want []models.Tag
wantErr bool
}{
{
name: "Test 1: Get Data",
args: args{
ctx: ctx,
tagType: models.Character,
},
want: validTags,
wantErr: false,
},
{
name: "Test 2: invalid Tag Type",
args: args{
ctx: ctx,
tagType: "aa",
},
want: validTags,
wantErr: false,
},
{
name: "Test 3: No Tag Type",
args: args{
ctx: ctx,
tagType: "",
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &postgresqlConnection{
db: gormDB,
debug: true,
}
got, err := p.GetAllTagsByTagType(tt.args.ctx, tt.args.tagType)
if (err != nil) != tt.wantErr {
t.Errorf("GetAllTagsByTagType() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetAllTagsByTagType() got = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -7,6 +7,12 @@ import (
) )
type Tag interface { type Tag interface {
CreateTag(ctx context.Context, tagName models.AnthroveTagName, tagType models.TagType) error
// GetAllTags retrieves all tags. // GetAllTags retrieves all tags.
GetAllTags(ctx context.Context) ([]models.Tag, error) GetAllTags(ctx context.Context) ([]models.Tag, error)
GetAllTagsByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error)
DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error
} }

View File

@ -12,6 +12,7 @@ type AnthroveTagAliasName string
type AnthroveTagID string type AnthroveTagID string
type AnthroveScrapeTimeInterval int type AnthroveScrapeTimeInterval int
type AnthroveUserLastScrapeTime time.Time type AnthroveUserLastScrapeTime time.Time
type AnthroveTagName string
type Rating string type Rating string
type TagType string type TagType string