Organize backend into product executable and shared Go modules

This commit is contained in:
Stephan D committed 2026-09-12 14:14:08 +02:00
1 parent 981e84a4b4
commit f0720ec66b
382 files changed
+1944 -6989

No files matched your search

+162
View File
@@ -0,0 +1,162 @@
package refreshtokens
import (
"context"
"errors"
sessionmodel "git.sendico.io/tech/sxchnge/product/sessions/model"
"testing"
"time"
"git.sendico.io/tech/sxchnge/shared/database/record"
"git.sendico.io/tech/sxchnge/shared/database/repository"
"git.sendico.io/tech/sxchnge/shared/database/repository/builder"
"git.sendico.io/tech/sxchnge/shared/database/template"
"git.sendico.io/tech/sxchnge/shared/errors"
"github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/zap"
)
type createRepository struct {
repository.Repository
filters []bson.D
patches []bson.D
patchMatches []bool
patchErr error
insertCalls int
insertErr error
storedID bson.ObjectID
}
func (r *createRepository) PatchOneByFilter(
_ context.Context,
filter builder.Query,
patch builder.Patch,
result storable.Storable,
) (bool, error) {
r.filters = append(r.filters, filter.BuildQuery())
r.patches = append(r.patches, patch.Build())
if r.patchErr != nil {
return false, r.patchErr
}
call := len(r.filters) - 1
matched := call < len(r.patchMatches) && r.patchMatches[call]
if matched {
result.SetID(r.storedID)
}
return matched, nil
}
func (r *createRepository) Insert(_ context.Context, object storable.Storable, _ builder.Query) error {
r.insertCalls++
if object.GetID() == nil || object.GetID().IsZero() {
object.SetID(bson.NewObjectID())
}
return r.insertErr
}
func newCreateDB(repo repository.Repository) *RefreshTokenDB {
return &RefreshTokenDB{
DBImp: template.DBImp[*sessionmodel.RefreshToken]{
Logger: zap.NewNop(),
Repository: repo,
},
}
}
func versionedToken(accountRef bson.ObjectID, version, value string) *sessionmodel.RefreshToken {
return &sessionmodel.RefreshToken{
ClientRefreshToken: sessionmodel.ClientRefreshToken{
SessionIdentifier: sessionmodel.SessionIdentifier{
ClientID: "web-app",
DeviceID: "browser",
SessionVersion: version,
},
RefreshToken: value,
},
AccountRef: &accountRef,
ExpiresAt: time.Now().Add(24 * time.Hour),
UserAgent: "test-agent",
IPAddress: "192.0.2.1",
}
}
func extendedJSON(t *testing.T, document bson.D) string {
t.Helper()
raw, err := bson.MarshalExtJSON(document, true, false)
require.NoError(t, err)
return string(raw)
}
func TestCreateReplacesSlotWithoutMatchingNewSessionVersion(t *testing.T) {
storedID := bson.NewObjectID()
repo := &createRepository{
patchMatches: []bool{true},
storedID: storedID,
}
db := newCreateDB(repo)
token := versionedToken(bson.NewObjectID(), "version-2", "replacement-token")
err := db.Create(context.Background(), token)
require.NoError(t, err)
require.Equal(t, storedID, *token.GetID())
require.Zero(t, repo.insertCalls)
require.Len(t, repo.filters, 1)
filterJSON := extendedJSON(t, repo.filters[0])
require.Contains(t, filterJSON, "accountRef")
require.Contains(t, filterJSON, "clientId")
require.Contains(t, filterJSON, "deviceId")
require.Contains(t, filterJSON, "isRevoked")
require.NotContains(t, filterJSON, "sessionVersion")
patchJSON := extendedJSON(t, repo.patches[0])
require.Contains(t, patchJSON, "sessionVersion")
require.Contains(t, patchJSON, "version-2")
}
func TestCreateReconcilesConcurrentSlotInsert(t *testing.T) {
storedID := bson.NewObjectID()
repo := &createRepository{
patchMatches: []bool{false, true},
insertErr: merrors.DataConflict("duplicate_key"),
storedID: storedID,
}
db := newCreateDB(repo)
token := versionedToken(bson.NewObjectID(), "version-2", "replacement-token")
err := db.Create(context.Background(), token)
require.NoError(t, err)
require.Equal(t, storedID, *token.GetID())
require.Equal(t, 1, repo.insertCalls)
require.Len(t, repo.filters, 2)
}
func TestCreatePreservesUnrelatedInsertConflict(t *testing.T) {
repo := &createRepository{
patchMatches: []bool{false, false},
insertErr: merrors.DataConflict("duplicate_key"),
storedID: bson.NewObjectID(),
}
db := newCreateDB(repo)
token := versionedToken(bson.NewObjectID(), "version-2", "replacement-token")
err := db.Create(context.Background(), token)
require.Error(t, err)
require.True(t, errors.Is(err, merrors.ErrDataConflict))
require.Equal(t, 1, repo.insertCalls)
require.Len(t, repo.filters, 2)
}
func TestCredentialFilterKeepsSessionVersion(t *testing.T) {
query := filterByAccount(bson.NewObjectID(), &sessionmodel.SessionIdentifier{
ClientID: "web-app",
DeviceID: "browser",
SessionVersion: "version-2",
})
filterJSON := extendedJSON(t, query.BuildQuery())
require.Contains(t, filterJSON, "sessionVersion")
require.Contains(t, filterJSON, "version-2")
}