package database import ( "context" "fmt" "reflect" "testing" "time" "git.anthrove.art/Anthrove/otter-space-sdk/v4/pkg/models" "git.anthrove.art/Anthrove/otter-space-sdk/v4/test" "go.opentelemetry.io/contrib/bridges/otellogrus" "go.opentelemetry.io/otel" "gorm.io/gorm" ) func TestCreatePost(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) if err != nil { logger.Fatalf("Could not start PostgreSQL container: %v", err) } client = gormDB // Setup open telemetry tracer = otel.Tracer(tracingName) hook := otellogrus.NewHook(tracingName) logger.AddHook(hook) defer container.Terminate(ctx) // -- -- Setup Tests // -- Create Post to test with validPost := models.Post{ BaseModel: models.BaseModel[models.PostID]{ ID: models.PostID(fmt.Sprintf("%025s", "Post1")), CreatedAt: time.Now(), UpdatedAt: time.Now(), DeletedAt: gorm.DeletedAt{}, }, Rating: models.SFW, } // -- // -- -- Tests type args struct { ctx context.Context post models.Post } tests := []struct { name string args args want models.Post wantErr bool }{ { name: "Test 01: Valid Post", args: args{ ctx: ctx, post: validPost, }, want: validPost, wantErr: false, }, { name: "Test 02: Duplicate Post", args: args{ ctx: ctx, post: validPost, }, want: models.Post{}, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := CreatePost(tt.args.ctx, tt.args.post) if (err != nil) != tt.wantErr { t.Errorf("CreatePost() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { t.Errorf("CreatePost() got = %v, want %v", got, tt.want) } }) } } func TestCreatePostInBatch(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) if err != nil { logger.Fatalf("Could not start PostgreSQL container: %v", err) } client = gormDB // Setup open telemetry tracer = otel.Tracer(tracingName) hook := otellogrus.NewHook(tracingName) logger.AddHook(hook) defer container.Terminate(ctx) // -- -- Setup Tests // -- Create Posts to test with validPosts := test.GenerateRandomPosts(20) // -- // -- -- Tests type args struct { ctx context.Context post []models.Post batchSize int } tests := []struct { name string args args wantErr bool }{ { name: "Test 01: Valid Posts", args: args{ ctx: ctx, post: validPosts, batchSize: len(validPosts), }, wantErr: false, }, { name: "Test 02: Duplicate Posts", args: args{ ctx: ctx, post: validPosts, batchSize: len(validPosts), }, wantErr: true, }, { name: "Test 03: Nil Posts", args: args{ ctx: ctx, post: nil, batchSize: len(validPosts), }, wantErr: true, }, { name: "Test 04: Empty Posts", args: args{ ctx: ctx, post: []models.Post{}, batchSize: len(validPosts), }, wantErr: true, }, { name: "Test 08: Empty Batch Size", args: args{ ctx: ctx, post: []models.Post{}, batchSize: 0, }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := CreatePostInBatch(tt.args.ctx, tt.args.post, tt.args.batchSize); (err != nil) != tt.wantErr { t.Errorf("CreatePostInBatch() error = %v, wantErr %v", err, tt.wantErr) } }) } } func TestGetPostByID(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) if err != nil { logger.Fatalf("Could not start PostgreSQL container: %v", err) } client = gormDB // Setup open telemetry tracer = otel.Tracer(tracingName) hook := otellogrus.NewHook(tracingName) logger.AddHook(hook) defer container.Terminate(ctx) // -- -- Setup Tests // -- Create Post to test with validPost := models.Post{ BaseModel: models.BaseModel[models.PostID]{ ID: models.PostID(fmt.Sprintf("%025s", "Post1")), CreatedAt: time.Now(), UpdatedAt: time.Now(), DeletedAt: gorm.DeletedAt{}, }, Rating: models.SFW, } validPost, err = CreatePost(ctx, validPost) if err != nil { logger.Fatal(err) } // -- // -- -- Tests type args struct { ctx context.Context id models.PostID } tests := []struct { name string args args want models.Post wantErr bool }{ { name: "Test 01: Valid PostID", args: args{ ctx: ctx, id: validPost.ID, }, want: validPost, wantErr: false, }, { name: "Test 03: Empty PostID", args: args{ ctx: ctx, id: "", }, wantErr: true, }, { name: "Test 04: Short PostID", args: args{ ctx: ctx, id: "111", }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := GetPostByID(tt.args.ctx, tt.args.id) if (err != nil) != tt.wantErr { t.Errorf("GetPostByID() error = %v, wantErr %v", err, tt.wantErr) return } if !checkPostID(got, tt.want) { t.Errorf("GetPostByID() got = %v, want %v", got, tt.want) } }) } } func TestUpdatePost(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) if err != nil { logger.Fatalf("Could not start PostgreSQL container: %v", err) } client = gormDB // Setup open telemetry tracer = otel.Tracer(tracingName) hook := otellogrus.NewHook(tracingName) logger.AddHook(hook) defer container.Terminate(ctx) // -- -- Setup Tests // -- Create Post to test with validPost := models.Post{ BaseModel: models.BaseModel[models.PostID]{ ID: models.PostID(fmt.Sprintf("%025s", "Post1")), CreatedAt: time.Now(), UpdatedAt: time.Now(), DeletedAt: gorm.DeletedAt{}, }, Rating: models.SFW, } validPost, err = CreatePost(ctx, validPost) if err != nil { logger.Fatal(err) } // -- // -- Create Updates models for Post validUpdatePost := validPost validUpdatePost.Rating = models.NSFW invalidUpdatePost := models.Post{} // -- // -- -- Tests type args struct { ctx context.Context anthrovePost models.Post } tests := []struct { name string args args wantErr bool }{ { name: "Test 01: Valid Update for Post", args: args{ ctx: ctx, anthrovePost: validUpdatePost, }, wantErr: false, }, { name: "Test 02: Invalid Update for Post", args: args{ ctx: ctx, anthrovePost: invalidUpdatePost, }, wantErr: true, }, { name: "Test 03: Empty ID for Update for Post", args: args{ ctx: ctx, anthrovePost: models.Post{BaseModel: models.BaseModel[models.PostID]{ID: ""}}, }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := UpdatePost(tt.args.ctx, tt.args.anthrovePost); (err != nil) != tt.wantErr { t.Errorf("UpdatePost() error = %v, wantErr %v", err, tt.wantErr) } }) } } func TestDeletePost(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) if err != nil { logger.Fatalf("Could not start PostgreSQL container: %v", err) } client = gormDB // Setup open telemetry tracer = otel.Tracer(tracingName) hook := otellogrus.NewHook(tracingName) logger.AddHook(hook) defer container.Terminate(ctx) // -- -- Setup Tests // -- Create Post to test with validPost := models.Post{ BaseModel: models.BaseModel[models.PostID]{ ID: models.PostID(fmt.Sprintf("%025s", "Post1")), CreatedAt: time.Now(), UpdatedAt: time.Now(), DeletedAt: gorm.DeletedAt{}, }, Rating: models.SFW, } validPost, err = CreatePost(ctx, validPost) if err != nil { logger.Fatal(err) } // -- // -- -- Tests type args struct { ctx context.Context id models.PostID } tests := []struct { name string args args wantErr bool }{ { name: "Test 01: Delete Valid Post", args: args{ ctx: ctx, id: validPost.ID, }, wantErr: false, }, { name: "Test 02: Delete not existed Post", args: args{ ctx: ctx, id: validPost.ID, }, wantErr: false, }, { name: "Test 03: Empty PostID", args: args{ ctx: ctx, id: "", }, wantErr: true, }, { name: "Test 04: Short PostID", args: args{ ctx: ctx, id: "111", }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := DeletePost(tt.args.ctx, tt.args.id); (err != nil) != tt.wantErr { t.Errorf("DeletePost() error = %v, wantErr %v", err, tt.wantErr) } }) } } func checkPostID(got models.Post, want models.Post) bool { if got.ID != want.ID { return false } return true }