added pools #14

Merged
SoXX merged 16 commits from dev/pools into main 2024-10-15 09:03:46 +00:00
3 changed files with 362 additions and 0 deletions
Showing only changes of commit 5da2e9e52d - Show all commits

View File

@ -0,0 +1,121 @@
package database
import (
"context"
"errors"
"git.anthrove.art/Anthrove/otter-space-sdk/v4/internal/utils"
otterError "git.anthrove.art/Anthrove/otter-space-sdk/v4/pkg/error"
"git.anthrove.art/Anthrove/otter-space-sdk/v4/pkg/models"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/attribute"
"gorm.io/gorm"
)
func CreatePoolReference(ctx context.Context, poolID models.PoolID, sourceID models.SourceID, url string) (models.PoolReference, error) {
ctx, span, localLogger := utils.SetupTracing(ctx, tracer, "CreatePoolReference")
defer span.End()
localLogger = localLogger.WithFields(log.Fields{
"pool_id": poolID,
"source_id": sourceID,
})
span.SetAttributes(
attribute.String("pool_id", string(poolID)),
attribute.String("source_id", string(sourceID)),
)
utils.HandleEvent(span, localLogger, "Starting poolReference creation")
if client == nil {
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DatabaseIsNotConnected})
}
if poolID == "" {
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.PoolIDIsEmpty})
Alphyron marked this conversation as resolved
Review

Either you use len(poolID) == 0 like in pool.go or you use this method in pool.go. But not both!

Either you use len(poolID) == 0 like in pool.go or you use this method in pool.go. But not both!
}
if len(poolID) != 25 {
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.PoolIDToShort})
}
if sourceID == "" {
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.SourceIDIsEmpty})
Alphyron marked this conversation as resolved
Review

Either you use len(sourceID) == 0 like in pool.go or you use this method in pool.go. But not both!

Either you use len(sourceID) == 0 like in pool.go or you use this method in pool.go. But not both!
}
if len(sourceID) != 25 {
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.SourceIDToShort})
}
if url == "" {
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.PoolURLIsEmpty})
Alphyron marked this conversation as resolved
Review

Either you check for length or for empty string... please be consistent in your variant of checking

Either you check for length or for empty string... please be consistent in your variant of checking
Review

still existing

still existing
}
poolReference := models.PoolReference{
PoolID: poolID,
SourceID: sourceID,
URL: url,
}
result := client.WithContext(ctx).Create(&poolReference)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DuplicateKey})
}
return models.PoolReference{}, utils.HandleError(ctx, span, localLogger, result.Error)
}
utils.HandleEvent(span, localLogger, "poolReference created successfully")
return poolReference, nil
}
func DeletePoolReference(ctx context.Context, poolID models.PoolID, sourceID models.SourceID) error {
ctx, span, localLogger := utils.SetupTracing(ctx, tracer, "DeletePoolReference")
defer span.End()
localLogger = localLogger.WithFields(log.Fields{
"pool_id": poolID,
"source_id": sourceID,
})
span.SetAttributes(
attribute.String("pool_id", string(poolID)),
attribute.String("source_id", string(sourceID)),
)
utils.HandleEvent(span, localLogger, "Starting delete poolReference")
var poolReference models.PoolReference
if client == nil {
return utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DatabaseIsNotConnected})
}
if poolID == "" {
return utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.PoolIDIsEmpty})
Alphyron marked this conversation as resolved
Review

Either you use len(poolID) == 0 like in pool.go or you use this method in pool.go. But not both!

Either you use len(poolID) == 0 like in pool.go or you use this method in pool.go. But not both!
}
if len(poolID) != 25 {
return utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.PostIDToShort})
}
if sourceID == "" {
return utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.SourceIDIsEmpty})
Alphyron marked this conversation as resolved
Review

Either you use len(sourceID) == 0 like in pool.go or you use this method in pool.go. But not both!

Either you use len(sourceID) == 0 like in pool.go or you use this method in pool.go. But not both!
}
if len(sourceID) != 25 {
return utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.SourceIDToShort})
}
result := client.WithContext(ctx).Delete(&poolReference, "pool_id = ? AND source_id = ?", poolID, sourceID)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.NoDataFound})
}
return utils.HandleError(ctx, span, localLogger, result.Error)
}
utils.HandleEvent(span, localLogger, "poolReference deleted successfully")
return nil
}

View File

@ -0,0 +1,239 @@
package database
import (
"context"
"fmt"
"reflect"
"testing"
"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"
)
func TestCreatePoolReference(t *testing.T) {
// Setup throwaway 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 Pool to test with
pool := models.Pool{
BaseModel: models.BaseModel[models.PoolID]{
ID: models.PoolID(fmt.Sprintf("%025s", "Pool1")),
},
Name: "Test Pool 01",
Category: models.Collection,
}
pool, err = CreatePool(ctx, pool)
if err != nil {
logger.Error(err)
}
// -- Create Source to test with
source := models.Source{
BaseModel: models.BaseModel[models.SourceID]{
ID: models.SourceID(fmt.Sprintf("%025s", "Source1")),
},
DisplayName: "test",
Domain: "aaa",
Icon: "bbb",
}
source, err = CreateSource(ctx, source)
if err != nil {
logger.Fatal(err)
}
// --
// -- -- Tests
type args struct {
ctx context.Context
poolID models.PoolID
sourceID models.SourceID
url string
}
tests := []struct {
name string
args args
want models.PoolReference
wantErr bool
}{
{
name: "Test 01: Valid pool & source ID",
args: args{
ctx: ctx,
poolID: pool.ID,
sourceID: source.ID,
url: "http://example.com",
},
want: models.PoolReference{
PoolID: pool.ID,
SourceID: source.ID,
URL: "http://example.com",
},
wantErr: false,
},
{
name: "Test 02: Duplicate",
args: args{
ctx: ctx,
poolID: pool.ID,
sourceID: source.ID,
url: "http://example.com",
},
want: models.PoolReference{},
wantErr: true,
},
{
name: "Test 03: poolID is empty",
args: args{
ctx: ctx,
poolID: "",
sourceID: source.ID,
url: "http://example.com",
},
want: models.PoolReference{},
wantErr: true,
},
{
name: "Test 04: sourceID is empty",
args: args{
ctx: ctx,
poolID: pool.ID,
sourceID: "",
url: "http://example.com",
},
want: models.PoolReference{},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := CreatePoolReference(tt.args.ctx, tt.args.poolID, tt.args.sourceID, tt.args.url)
if (err != nil) != tt.wantErr {
t.Errorf("CreatePoolReference() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("CreatePoolReference() got = %v, want %v", got, tt.want)
}
})
}
}
func TestDeletePoolReference(t *testing.T) {
// Setup throwaway 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 Pool to test with
pool := models.Pool{
BaseModel: models.BaseModel[models.PoolID]{
ID: models.PoolID(fmt.Sprintf("%025s", "Pool1")),
},
Name: "Test Pool 01",
Category: models.Collection,
}
pool, err = CreatePool(ctx, pool)
if err != nil {
logger.Error(err)
}
// -- Create Source to test with
source := models.Source{
BaseModel: models.BaseModel[models.SourceID]{
ID: models.SourceID(fmt.Sprintf("%025s", "Source1")),
},
DisplayName: "test",
Domain: "aaa",
Icon: "bbb",
}
source, err = CreateSource(ctx, source)
if err != nil {
logger.Fatal(err)
}
// --
// -- -- Tests
type args struct {
ctx context.Context
poolID models.PoolID
sourceID models.SourceID
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Test 01: Valid Reference & pool id",
args: args{
ctx: ctx,
poolID: pool.ID,
sourceID: source.ID,
},
wantErr: false,
},
{
name: "Test 02: Not existing sourceID",
args: args{
ctx: ctx,
poolID: pool.ID,
sourceID: "",
},
wantErr: true,
},
{
name: "Test 03: Not existing poolID",
args: args{
ctx: ctx,
poolID: "",
sourceID: source.ID,
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := DeletePoolReference(tt.args.ctx, tt.args.poolID, tt.args.sourceID); (err != nil) != tt.wantErr {
t.Errorf("DeletePoolReference() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View File

@ -33,6 +33,8 @@ const (
PoolIDIsEmpty = "PoolID cannot be empty"
PoolIDToShort = "PoolID needs to be 25 characters long"
PoolURLIsEmpty = "PoolURL cannot be empty"
)
type EntityValidationFailed struct {