Organize backend into product executable and shared Go modules
This commit is contained in:
1 parent
981e84a4b4
commit
f0720ec66b
382 files changed
+1944
-6989
No files matched your search
@@ -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")
|
||||
}
|
||||
Reference in new issue
Block a user