fx build fix
This commit is contained in:
@@ -1,69 +0,0 @@
|
||||
package indexable
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tech/sendico/pkg/db/repository"
|
||||
"github.com/tech/sendico/pkg/db/repository/builder"
|
||||
"github.com/tech/sendico/pkg/mlogger"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// Example usage of the generic IndexableDB with different types
|
||||
|
||||
// Example 1: Using with Project
|
||||
func ExampleProjectIndexableDB(repo repository.Repository, logger mlogger.Logger, organizationRef primitive.ObjectID) {
|
||||
// Define helper functions for Project
|
||||
createEmpty := func() *model.Project {
|
||||
return &model.Project{}
|
||||
}
|
||||
|
||||
getIndexable := func(p *model.Project) *model.Indexable {
|
||||
return &p.Indexable
|
||||
}
|
||||
|
||||
// Create generic IndexableDB for Project
|
||||
projectDB := NewIndexableDB(repo, logger, createEmpty, getIndexable)
|
||||
|
||||
// Use with organization filter
|
||||
orgFilter := repository.OrgFilter(organizationRef)
|
||||
projectDB.Reorder(context.Background(), primitive.NewObjectID(), 2, orgFilter)
|
||||
}
|
||||
|
||||
// Example 3: Using with Task
|
||||
func ExampleTaskIndexableDB(repo repository.Repository, logger mlogger.Logger, statusRef primitive.ObjectID) {
|
||||
// Define helper functions for Task
|
||||
createEmpty := func() *model.Task {
|
||||
return &model.Task{}
|
||||
}
|
||||
|
||||
getIndexable := func(t *model.Task) *model.Indexable {
|
||||
return &t.Indexable
|
||||
}
|
||||
|
||||
// Create generic IndexableDB for Task
|
||||
taskDB := NewIndexableDB(repo, logger, createEmpty, getIndexable)
|
||||
|
||||
// Use with status filter
|
||||
statusFilter := repository.Query().Comparison(repository.Field("statusRef"), builder.Eq, statusRef)
|
||||
taskDB.Reorder(context.Background(), primitive.NewObjectID(), 3, statusFilter)
|
||||
}
|
||||
|
||||
// Example 5: Using without any filter (global reordering)
|
||||
func ExampleGlobalIndexableDB(repo repository.Repository, logger mlogger.Logger) {
|
||||
// Define helper functions for any Indexable type
|
||||
createEmpty := func() *model.Project {
|
||||
return &model.Project{}
|
||||
}
|
||||
|
||||
getIndexable := func(p *model.Project) *model.Indexable {
|
||||
return &p.Indexable
|
||||
}
|
||||
|
||||
// Create generic IndexableDB without filters
|
||||
globalDB := NewIndexableDB(repo, logger, createEmpty, getIndexable)
|
||||
|
||||
// Use without any filter - reorders all items globally
|
||||
globalDB.Reorder(context.Background(), primitive.NewObjectID(), 5, repository.Query())
|
||||
}
|
||||
@@ -1,314 +0,0 @@
|
||||
//go:build integration
|
||||
// +build integration
|
||||
|
||||
package indexable
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tech/sendico/pkg/db/repository"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/modules/mongodb"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func setupTestDB(t *testing.T) (repository.Repository, func()) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
mongoContainer, err := mongodb.Run(ctx,
|
||||
"mongo:latest",
|
||||
mongodb.WithUsername("root"),
|
||||
mongodb.WithPassword("password"),
|
||||
testcontainers.WithWaitStrategy(wait.ForLog("Waiting for connections")),
|
||||
)
|
||||
require.NoError(t, err, "failed to start MongoDB container")
|
||||
|
||||
mongoURI, err := mongoContainer.ConnectionString(ctx)
|
||||
require.NoError(t, err, "failed to get MongoDB connection string")
|
||||
|
||||
clientOptions := options.Client().ApplyURI(mongoURI)
|
||||
client, err := mongo.Connect(ctx, clientOptions)
|
||||
require.NoError(t, err, "failed to connect to MongoDB")
|
||||
|
||||
db := client.Database("testdb")
|
||||
repo := repository.CreateMongoRepository(db, "projects")
|
||||
|
||||
cleanup := func() {
|
||||
disconnect(ctx, t, client)
|
||||
terminate(ctx, t, mongoContainer)
|
||||
}
|
||||
|
||||
return repo, cleanup
|
||||
}
|
||||
|
||||
func disconnect(ctx context.Context, t *testing.T, client *mongo.Client) {
|
||||
if err := client.Disconnect(ctx); err != nil {
|
||||
t.Logf("failed to disconnect from MongoDB: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func terminate(ctx context.Context, t *testing.T, container testcontainers.Container) {
|
||||
if err := container.Terminate(ctx); err != nil {
|
||||
t.Logf("failed to terminate MongoDB container: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexableDB_Reorder(t *testing.T) {
|
||||
repo, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
ctx := context.Background()
|
||||
organizationRef := primitive.NewObjectID()
|
||||
logger := zap.NewNop()
|
||||
|
||||
// Create test projects with different indices
|
||||
projects := []*model.Project{
|
||||
{
|
||||
ProjectBase: model.ProjectBase{
|
||||
PermissionBound: model.PermissionBound{
|
||||
OrganizationBoundBase: model.OrganizationBoundBase{
|
||||
OrganizationRef: organizationRef,
|
||||
},
|
||||
},
|
||||
Describable: model.Describable{Name: "Project A"},
|
||||
Indexable: model.Indexable{Index: 0},
|
||||
Mnemonic: "A",
|
||||
State: model.ProjectStateActive,
|
||||
},
|
||||
},
|
||||
{
|
||||
ProjectBase: model.ProjectBase{
|
||||
PermissionBound: model.PermissionBound{
|
||||
OrganizationBoundBase: model.OrganizationBoundBase{
|
||||
OrganizationRef: organizationRef,
|
||||
},
|
||||
},
|
||||
Describable: model.Describable{Name: "Project B"},
|
||||
Indexable: model.Indexable{Index: 1},
|
||||
Mnemonic: "B",
|
||||
State: model.ProjectStateActive,
|
||||
},
|
||||
},
|
||||
{
|
||||
ProjectBase: model.ProjectBase{
|
||||
PermissionBound: model.PermissionBound{
|
||||
OrganizationBoundBase: model.OrganizationBoundBase{
|
||||
OrganizationRef: organizationRef,
|
||||
},
|
||||
},
|
||||
Describable: model.Describable{Name: "Project C"},
|
||||
Indexable: model.Indexable{Index: 2},
|
||||
Mnemonic: "C",
|
||||
State: model.ProjectStateActive,
|
||||
},
|
||||
},
|
||||
{
|
||||
ProjectBase: model.ProjectBase{
|
||||
PermissionBound: model.PermissionBound{
|
||||
OrganizationBoundBase: model.OrganizationBoundBase{
|
||||
OrganizationRef: organizationRef,
|
||||
},
|
||||
},
|
||||
Describable: model.Describable{Name: "Project D"},
|
||||
Indexable: model.Indexable{Index: 3},
|
||||
Mnemonic: "D",
|
||||
State: model.ProjectStateActive,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Insert projects into database
|
||||
for _, project := range projects {
|
||||
project.ID = primitive.NewObjectID()
|
||||
err := repo.Insert(ctx, project, nil)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Create helper functions for Project type
|
||||
createEmpty := func() *model.Project {
|
||||
return &model.Project{}
|
||||
}
|
||||
|
||||
getIndexable := func(p *model.Project) *model.Indexable {
|
||||
return &p.Indexable
|
||||
}
|
||||
|
||||
indexableDB := NewIndexableDB(repo, logger, createEmpty, getIndexable)
|
||||
|
||||
t.Run("Reorder_NoChange", func(t *testing.T) {
|
||||
// Test reordering to the same position (should be no-op)
|
||||
err := indexableDB.Reorder(ctx, projects[1].ID, 1, repository.Query())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify indices haven't changed
|
||||
var result model.Project
|
||||
err = repo.Get(ctx, projects[0].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, result.Index)
|
||||
|
||||
err = repo.Get(ctx, projects[1].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, result.Index)
|
||||
})
|
||||
|
||||
t.Run("Reorder_MoveDown", func(t *testing.T) {
|
||||
// Move Project A (index 0) to index 2
|
||||
err := indexableDB.Reorder(ctx, projects[0].ID, 2, repository.Query())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify the reordering:
|
||||
// Project A should now be at index 2
|
||||
// Project B should be at index 0
|
||||
// Project C should be at index 1
|
||||
// Project D should remain at index 3
|
||||
|
||||
var result model.Project
|
||||
|
||||
// Check Project A (moved to index 2)
|
||||
err = repo.Get(ctx, projects[0].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, result.Index)
|
||||
|
||||
// Check Project B (shifted to index 0)
|
||||
err = repo.Get(ctx, projects[1].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, result.Index)
|
||||
|
||||
// Check Project C (shifted to index 1)
|
||||
err = repo.Get(ctx, projects[2].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, result.Index)
|
||||
|
||||
// Check Project D (unchanged)
|
||||
err = repo.Get(ctx, projects[3].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 3, result.Index)
|
||||
})
|
||||
|
||||
t.Run("Reorder_MoveUp", func(t *testing.T) {
|
||||
// Reset indices for this test
|
||||
for i, project := range projects {
|
||||
project.Index = i
|
||||
err := repo.Update(ctx, project)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Move Project C (index 2) to index 0
|
||||
err := indexableDB.Reorder(ctx, projects[2].ID, 0, repository.Query())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify the reordering:
|
||||
// Project C should now be at index 0
|
||||
// Project A should be at index 1
|
||||
// Project B should be at index 2
|
||||
// Project D should remain at index 3
|
||||
|
||||
var result model.Project
|
||||
|
||||
// Check Project C (moved to index 0)
|
||||
err = repo.Get(ctx, projects[2].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, result.Index)
|
||||
|
||||
// Check Project A (shifted to index 1)
|
||||
err = repo.Get(ctx, projects[0].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, result.Index)
|
||||
|
||||
// Check Project B (shifted to index 2)
|
||||
err = repo.Get(ctx, projects[1].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, result.Index)
|
||||
|
||||
// Check Project D (unchanged)
|
||||
err = repo.Get(ctx, projects[3].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 3, result.Index)
|
||||
})
|
||||
|
||||
t.Run("Reorder_WithFilter", func(t *testing.T) {
|
||||
// Reset indices for this test
|
||||
for i, project := range projects {
|
||||
project.Index = i
|
||||
err := repo.Update(ctx, project)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Test reordering with organization filter
|
||||
orgFilter := repository.OrgFilter(organizationRef)
|
||||
err := indexableDB.Reorder(ctx, projects[0].ID, 2, orgFilter)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify the reordering worked with filter
|
||||
var result model.Project
|
||||
err = repo.Get(ctx, projects[0].ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, result.Index)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIndexableDB_EdgeCases(t *testing.T) {
|
||||
repo, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
ctx := context.Background()
|
||||
organizationRef := primitive.NewObjectID()
|
||||
logger := zap.NewNop()
|
||||
|
||||
// Create a single project for edge case testing
|
||||
project := &model.Project{
|
||||
ProjectBase: model.ProjectBase{
|
||||
PermissionBound: model.PermissionBound{
|
||||
OrganizationBoundBase: model.OrganizationBoundBase{
|
||||
OrganizationRef: organizationRef,
|
||||
},
|
||||
},
|
||||
Describable: model.Describable{Name: "Test Project"},
|
||||
Indexable: model.Indexable{Index: 0},
|
||||
Mnemonic: "TEST",
|
||||
State: model.ProjectStateActive,
|
||||
},
|
||||
}
|
||||
project.ID = primitive.NewObjectID()
|
||||
err := repo.Insert(ctx, project, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create helper functions for Project type
|
||||
createEmpty := func() *model.Project {
|
||||
return &model.Project{}
|
||||
}
|
||||
|
||||
getIndexable := func(p *model.Project) *model.Indexable {
|
||||
return &p.Indexable
|
||||
}
|
||||
|
||||
indexableDB := NewIndexableDB(repo, logger, createEmpty, getIndexable)
|
||||
|
||||
t.Run("Reorder_SingleItem", func(t *testing.T) {
|
||||
// Test reordering a single item (should work but have no effect)
|
||||
err := indexableDB.Reorder(ctx, project.ID, 0, repository.Query())
|
||||
require.NoError(t, err)
|
||||
|
||||
var result model.Project
|
||||
err = repo.Get(ctx, project.ID, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, result.Index)
|
||||
})
|
||||
|
||||
t.Run("Reorder_InvalidObjectID", func(t *testing.T) {
|
||||
// Test reordering with an invalid object ID
|
||||
invalidID := primitive.NewObjectID()
|
||||
err := indexableDB.Reorder(ctx, invalidID, 1, repository.Query())
|
||||
require.Error(t, err) // Should fail because object doesn't exist
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user