109 lines
3.8 KiB
Go
109 lines
3.8 KiB
Go
//go:build integration
|
|
// +build integration
|
|
|
|
package invitationdb
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.sendico.io/tech/sxchnge/bff/pkg/db/repository"
|
|
"git.sendico.io/tech/sxchnge/bff/pkg/merrors"
|
|
"git.sendico.io/tech/sxchnge/bff/pkg/model"
|
|
"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/v2/bson"
|
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
)
|
|
|
|
func TestPendingInvitationEmailIndexBehavior(t *testing.T) {
|
|
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.ForListeningPort("27017/tcp").WithStartupTimeout(2*time.Minute)),
|
|
)
|
|
require.NoError(t, err)
|
|
defer func() {
|
|
termCtx, termCancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer termCancel()
|
|
_ = mongoContainer.Terminate(termCtx)
|
|
}()
|
|
|
|
mongoURI, err := mongoContainer.ConnectionString(ctx)
|
|
require.NoError(t, err)
|
|
|
|
client, err := mongo.Connect(options.Client().ApplyURI(mongoURI))
|
|
require.NoError(t, err)
|
|
defer func() { _ = client.Disconnect(context.Background()) }()
|
|
|
|
database := client.Database("test_invitation_pending_email_index")
|
|
defer func() { _ = database.Drop(context.Background()) }()
|
|
|
|
repo := repository.CreateMongoRepository(database, "invitations")
|
|
require.NoError(t, repo.CreateIndex(pendingInvitationEmailIndexDefinition()))
|
|
assertPendingEmailIndexDefinition(t, ctx, database.Collection("invitations"))
|
|
|
|
orgRef := bson.NewObjectID()
|
|
email := "invitee@example.com"
|
|
require.NoError(t, repo.Insert(ctx, testInvitation(orgRef, email, model.InvitationCreated), nil))
|
|
err = repo.Insert(ctx, testInvitation(orgRef, email, model.InvitationSent), nil)
|
|
require.ErrorIs(t, err, merrors.ErrDataConflict, "duplicate pending invitation must conflict")
|
|
|
|
for _, status := range []model.InvitationStatus{model.InvitationRevoked, model.InvitationDeclined, model.InvitationAccepted} {
|
|
statusEmail := string(status) + "@example.com"
|
|
require.NoError(t, repo.Insert(ctx, testInvitation(orgRef, statusEmail, status), nil))
|
|
require.NoError(t, repo.Insert(ctx, testInvitation(orgRef, statusEmail, model.InvitationCreated), nil))
|
|
}
|
|
|
|
otherOrgRef := bson.NewObjectID()
|
|
require.NoError(t, repo.Insert(ctx, testInvitation(otherOrgRef, email, model.InvitationCreated), nil))
|
|
}
|
|
|
|
func testInvitation(orgRef bson.ObjectID, email string, status model.InvitationStatus) *model.Invitation {
|
|
inv := &model.Invitation{
|
|
OrganizationRef: orgRef,
|
|
Status: status,
|
|
ExpiresAt: time.Now().UTC().Add(time.Hour),
|
|
}
|
|
inv.SetID(bson.NewObjectID())
|
|
inv.SetOrganizationRef(orgRef)
|
|
inv.Content.Email = email
|
|
return inv
|
|
}
|
|
|
|
func assertPendingEmailIndexDefinition(t *testing.T, ctx context.Context, collection *mongo.Collection) {
|
|
t.Helper()
|
|
cursor, err := collection.Indexes().List(ctx)
|
|
require.NoError(t, err)
|
|
defer func() { _ = cursor.Close(ctx) }()
|
|
|
|
for cursor.Next(ctx) {
|
|
var index bson.M
|
|
require.NoError(t, cursor.Decode(&index))
|
|
if index["name"] != uniquePendingInvitationEmailIndexName {
|
|
continue
|
|
}
|
|
|
|
require.Equal(t, true, index["unique"])
|
|
require.Equal(t, bson.D{
|
|
{Key: "organizationRef", Value: int32(1)},
|
|
{Key: "description.email", Value: int32(1)},
|
|
}, index["key"])
|
|
require.Equal(t, bson.D{
|
|
{Key: "status", Value: bson.D{{Key: "$in", Value: bson.A{"created", "sent"}}}},
|
|
{Key: "description.email", Value: bson.D{{Key: "$type", Value: "string"}}},
|
|
}, index["partialFilterExpression"])
|
|
return
|
|
}
|
|
require.NoError(t, cursor.Err())
|
|
t.Fatalf("index %q was not created", uniquePendingInvitationEmailIndexName)
|
|
}
|