diff --git a/pkg/database/source_test.go b/pkg/database/source_test.go new file mode 100644 index 0000000..0006052 --- /dev/null +++ b/pkg/database/source_test.go @@ -0,0 +1,546 @@ +package database + +import ( + "context" + "fmt" + "reflect" + "testing" + "time" + + "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models" + "git.anthrove.art/Anthrove/otter-space-sdk/v2/test" + "go.opentelemetry.io/contrib/bridges/otellogrus" + "go.opentelemetry.io/otel" + "gorm.io/gorm" +) + +func TestCreateSource(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 Source to test with + validSource := models.Source{ + BaseModel: models.BaseModel[models.SourceID]{ + ID: models.SourceID(fmt.Sprintf("%025s", "Source1")), + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: gorm.DeletedAt{}, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "e621.net/icon.png", + } + // -- + + // -- -- Tests + type args struct { + ctx context.Context + source models.Source + } + tests := []struct { + name string + args args + want models.Source + wantErr bool + }{ + { + name: "Test 01: Valid Source", + args: args{ + ctx: ctx, + source: validSource, + }, + want: validSource, + wantErr: false, + }, + { + name: "Test 02: Duplicate Source", + args: args{ + ctx: ctx, + source: validSource, + }, + want: models.Source{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := CreateSource(tt.args.ctx, tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("CreateSource() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("CreateSource() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCreateSourceInBatch(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 Sources to test with + validSources := test.GenerateRandomSources(5) + // -- + + // -- -- Tests + type args struct { + ctx context.Context + source []models.Source + batchSize int + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 01: Valid Sources", + args: args{ + ctx: ctx, + source: validSources, + batchSize: len(validSources), + }, + wantErr: false, + }, + { + name: "Test 02: Duplicate Sources", + args: args{ + ctx: ctx, + source: validSources, + batchSize: len(validSources), + }, + wantErr: true, + }, + { + name: "Test 03: Nil Sources", + args: args{ + ctx: ctx, + source: nil, + batchSize: len(validSources), + }, + wantErr: true, + }, + { + name: "Test 04: Empty Sources", + args: args{ + ctx: ctx, + source: []models.Source{}, + batchSize: len(validSources), + }, + wantErr: true, + }, + { + name: "Test 08: Empty Batch Size", + args: args{ + ctx: ctx, + source: []models.Source{}, + batchSize: 0, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateSourceInBatch(tt.args.ctx, tt.args.source, tt.args.batchSize); (err != nil) != tt.wantErr { + t.Errorf("CreateSourceInBatch() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestUpdateSource(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 Source to test with + validSource := models.Source{ + BaseModel: models.BaseModel[models.SourceID]{ + ID: models.SourceID(fmt.Sprintf("%025s", "Source1")), + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: gorm.DeletedAt{}, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "e621.net/icon.png", + } + + validSource, err = CreateSource(ctx, validSource) + if err != nil { + t.Fatalf("CreateSource err: %v", err) + } + // -- + + // -- Create Updates models for UserSource + validUpdateSource := validSource + validUpdateSource.DisplayName = "eeeee" + validUpdateSource.Domain = "aaaaa" + validUpdateSource.Icon = "nnnn" + + invalidUpdateSource := models.Source{} + // -- + + // -- -- Tests + type args struct { + ctx context.Context + source models.Source + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 01: Valid Update for Source", + args: args{ + ctx: ctx, + source: validUpdateSource, + }, + wantErr: false, + }, + { + name: "Test 02: Invalid Update for Source", + args: args{ + ctx: ctx, + source: invalidUpdateSource, + }, + wantErr: true, + }, + { + name: "Test 03: Empty ID for Update for Source", + args: args{ + ctx: ctx, + source: models.Source{BaseModel: models.BaseModel[models.SourceID]{ID: ""}}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := UpdateSource(tt.args.ctx, tt.args.source); (err != nil) != tt.wantErr { + t.Errorf("UpdateSource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestGetSourceByID(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 Source to test with + validSource := models.Source{ + BaseModel: models.BaseModel[models.SourceID]{ + ID: models.SourceID(fmt.Sprintf("%025s", "Source1")), + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: gorm.DeletedAt{}, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "e621.net/icon.png", + } + + validSource, err = CreateSource(ctx, validSource) + if err != nil { + t.Fatalf("CreateSource err: %v", err) + } + // -- + + // -- -- Tests + type args struct { + ctx context.Context + id models.SourceID + } + tests := []struct { + name string + args args + want models.Source + wantErr bool + }{ + { + name: "Test 01: Valid Source ID", + args: args{ + ctx: ctx, + id: validSource.ID, + }, + want: validSource, + wantErr: false, + }, + { + name: "Test 03: Empty SourceID", + args: args{ + ctx: ctx, + id: "", + }, + wantErr: true, + }, + { + name: "Test 04: Short SourceID", + args: args{ + ctx: ctx, + id: "111", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetSourceByID(tt.args.ctx, tt.args.id) + if (err != nil) != tt.wantErr { + t.Errorf("GetSourceByID() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkSourceID(got, tt.want) { + t.Errorf("GetSourceByID() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetSourceByDomain(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 Source to test with + validSource := models.Source{ + BaseModel: models.BaseModel[models.SourceID]{ + ID: models.SourceID(fmt.Sprintf("%025s", "Source1")), + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: gorm.DeletedAt{}, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "e621.net/icon.png", + } + + validSource, err = CreateSource(ctx, validSource) + if err != nil { + t.Fatalf("CreateSource err: %v", err) + } + // -- + + // -- -- Tests + type args struct { + ctx context.Context + sourceDomain models.SourceDomain + } + tests := []struct { + name string + args args + want models.Source + wantErr bool + }{ + { + name: "Test 01: Valid SourceURL", + args: args{ + ctx: ctx, + sourceDomain: validSource.Domain, + }, + want: validSource, + wantErr: false, + }, + { + name: "Test 02: Empty SourceURL", + args: args{ + ctx: ctx, + sourceDomain: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetSourceByDomain(tt.args.ctx, tt.args.sourceDomain) + if (err != nil) != tt.wantErr { + t.Errorf("GetSourceByDomain() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkSourceID(got, tt.want) { + t.Errorf("GetSourceByDomain() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDeleteSource(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 Source to test with + validSource := models.Source{ + BaseModel: models.BaseModel[models.SourceID]{ + ID: models.SourceID(fmt.Sprintf("%025s", "Source1")), + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: gorm.DeletedAt{}, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "e621.net/icon.png", + } + + validSource, err = CreateSource(ctx, validSource) + if err != nil { + t.Fatalf("CreateSource err: %v", err) + } + // -- + + // -- -- Tests + type args struct { + ctx context.Context + id models.SourceID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 01: Delete Valid Source", + args: args{ + ctx: ctx, + id: validSource.ID, + }, + wantErr: false, + }, + { + name: "Test 02: Delete not existed Source", + args: args{ + ctx: ctx, + id: validSource.ID, + }, + wantErr: false, + }, + { + name: "Test 03: Empty SourceID", + args: args{ + ctx: ctx, + id: "", + }, + wantErr: true, + }, + { + name: "Test 04: Short SourceID", + args: args{ + ctx: ctx, + id: "111", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DeleteSource(tt.args.ctx, tt.args.id); (err != nil) != tt.wantErr { + t.Errorf("DeleteSource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func checkSourceID(got models.Source, want models.Source) bool { + if got.ID != want.ID { + return false + } + + return true +}