added pools #14
121
pkg/database/pool_reference.go
Normal file
121
pkg/database/pool_reference.go
Normal 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
|
||||
}
|
||||
|
||||
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
Alphyron
commented
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
Alphyron
commented
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
Alphyron
commented
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
Alphyron
commented
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
Alphyron
commented
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
|
||||
}
|
239
pkg/database/pool_reference_test.go
Normal file
239
pkg/database/pool_reference_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user
Either you use len(poolID) == 0 like in pool.go or you use this method in pool.go. But not both!