snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
267
server/system/service/user_test.go
Normal file
267
server/system/service/user_test.go
Normal file
@@ -0,0 +1,267 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
a "github.com/cortezaproject/corteza/server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza/server/pkg/eventbus"
|
||||
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/store/adapters/rdbms/drivers/sqlite"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
u struct {
|
||||
store.Users
|
||||
L func(ctx context.Context, handle string) (*types.User, error)
|
||||
}
|
||||
)
|
||||
|
||||
func TestUser_ProtectedSearch(t *testing.T) {
|
||||
const testRoleID = 123
|
||||
|
||||
var (
|
||||
req = require.New(t)
|
||||
ctx = context.Background()
|
||||
|
||||
masked = &types.User{Email: "email.masked@us.er", Name: "Name MSKD", ID: nextID(), CreatedAt: *now()}
|
||||
unmasked = &types.User{Email: "email.unmasked@us.er", Name: "Name UNMSKD", ID: nextID(), CreatedAt: *now()}
|
||||
|
||||
set types.UserSet
|
||||
err error
|
||||
|
||||
testUser = &types.User{ID: 42}
|
||||
|
||||
acRBAC = rbac.NewService(zap.NewNop(), nil)
|
||||
|
||||
s store.Storer
|
||||
)
|
||||
|
||||
if s, err = sqlite.ConnectInMemory(ctx); err != nil {
|
||||
req.NoError(err)
|
||||
} else if err = store.Upgrade(ctx, zap.NewNop(), s); err != nil {
|
||||
req.NoError(err)
|
||||
}
|
||||
|
||||
acRBAC.UpdateRoles(rbac.CommonRole.Make(testRoleID, "test-role"))
|
||||
req.NoError(acRBAC.Grant(ctx,
|
||||
rbac.AllowRule(testRoleID, types.ComponentRbacResource(), "users.search"),
|
||||
rbac.AllowRule(testRoleID, types.UserRbacResource(0), "read"),
|
||||
rbac.DenyRule(testRoleID, masked.RbacResource(), "email.unmask"),
|
||||
rbac.AllowRule(testRoleID, unmasked.RbacResource(), "email.unmask"),
|
||||
rbac.DenyRule(testRoleID, masked.RbacResource(), "name.unmask"),
|
||||
rbac.AllowRule(testRoleID, unmasked.RbacResource(), "name.unmask"),
|
||||
))
|
||||
|
||||
testUser.SetRoles(testRoleID)
|
||||
ctx = a.SetIdentityToContext(ctx, testUser)
|
||||
|
||||
svc := &user{
|
||||
settings: &types.AppSettings{},
|
||||
ac: &accessControl{rbac: acRBAC},
|
||||
eventbus: eventbus.New(),
|
||||
store: s,
|
||||
}
|
||||
|
||||
req.NoError(store.CreateUser(ctx, svc.store, masked, unmasked))
|
||||
|
||||
t.Run("with disabled masking", func(t *testing.T) {
|
||||
// Masking disabled, expecting to fetch both users
|
||||
svc.settings.Privacy.Mask.Email = false
|
||||
svc.settings.Privacy.Mask.Name = false
|
||||
set, _, err = svc.Find(ctx, types.UserFilter{Query: "email"})
|
||||
req.NoError(err)
|
||||
req.Len(set, 2)
|
||||
req.NotEqual(set[0].Email, maskPrivateDataEmail)
|
||||
req.NotEqual(set[1].Email, maskPrivateDataEmail)
|
||||
})
|
||||
|
||||
t.Run("with enabled privacy", func(t *testing.T) {
|
||||
// Masking enabled, expecting to fetch only unmasked
|
||||
svc.settings.Privacy.Mask.Email = true
|
||||
svc.settings.Privacy.Mask.Name = true
|
||||
|
||||
set, _, err = svc.Find(ctx, types.UserFilter{Query: "email"})
|
||||
req.NoError(err)
|
||||
req.Len(set, 1)
|
||||
})
|
||||
|
||||
t.Run("email search with enabled privacy", func(t *testing.T) {
|
||||
// Masking enabled, expecting to fetch only unmasked
|
||||
svc.settings.Privacy.Mask.Email = true
|
||||
svc.settings.Privacy.Mask.Name = true
|
||||
|
||||
set, _, err = svc.Find(ctx, types.UserFilter{Email: "email.masked@us.er"})
|
||||
req.NoError(err)
|
||||
req.Len(set, 0)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_createUserHandle(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
// Define test cases
|
||||
tests := []struct {
|
||||
name string
|
||||
user *types.User
|
||||
expected string
|
||||
s u
|
||||
}{
|
||||
{
|
||||
name: "Test with valid name",
|
||||
user: &types.User{
|
||||
Name: "John Doe",
|
||||
},
|
||||
expected: "JohnDoe_1",
|
||||
s: u{
|
||||
L: func(ctx context.Context, handle string) (*types.User, error) {
|
||||
return nil, store.ErrNotFound
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test with valid name and username",
|
||||
user: &types.User{
|
||||
Name: "John",
|
||||
Username: "username_provided_here123",
|
||||
},
|
||||
expected: "John_username_provided_here123",
|
||||
s: u{
|
||||
L: func(ctx context.Context, handle string) (*types.User, error) {
|
||||
if handle == "John1" {
|
||||
return nil, store.ErrNotUnique
|
||||
}
|
||||
return nil, store.ErrNotFound
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test with valid name and email",
|
||||
user: &types.User{
|
||||
Name: "John John",
|
||||
Email: "jj+test@example.ltd",
|
||||
},
|
||||
expected: "jjTest",
|
||||
s: u{
|
||||
L: func(ctx context.Context, handle string) (*types.User, error) {
|
||||
return nil, store.ErrNotFound
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test with valid name, not unique handle",
|
||||
user: &types.User{
|
||||
Name: "John Gardener",
|
||||
Email: "johng@example.ltd",
|
||||
},
|
||||
expected: "JohnGardener_1",
|
||||
s: u{
|
||||
L: func(ctx context.Context, handle string) (*types.User, error) {
|
||||
if handle == "johng" {
|
||||
return nil, store.ErrNotUnique
|
||||
}
|
||||
return nil, store.ErrNotFound
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Run test cases
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
createUserHandle(ctx, tc.s, tc.user)
|
||||
assert.Equal(t, tc.expected, tc.user.Handle)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_processAvatarInitials(t *testing.T) {
|
||||
// Define test cases
|
||||
tests := []struct {
|
||||
name string
|
||||
user *types.User
|
||||
expectedInitial string
|
||||
}{
|
||||
{
|
||||
name: "Test with valid name",
|
||||
user: &types.User{
|
||||
Name: "John Doe",
|
||||
},
|
||||
expectedInitial: "JD",
|
||||
},
|
||||
{
|
||||
name: "Test with valid handle",
|
||||
user: &types.User{
|
||||
Handle: "johndoe",
|
||||
},
|
||||
expectedInitial: "J",
|
||||
},
|
||||
{
|
||||
name: "Test handle with a delimiter",
|
||||
user: &types.User{
|
||||
Handle: "john_doe",
|
||||
},
|
||||
expectedInitial: "JD",
|
||||
},
|
||||
{
|
||||
name: "Test with valid handle",
|
||||
user: &types.User{
|
||||
Email: "johndoe@example.com",
|
||||
},
|
||||
expectedInitial: "J",
|
||||
},
|
||||
{
|
||||
name: "Test email with a delimiter",
|
||||
user: &types.User{
|
||||
Email: "john-doe@example.com",
|
||||
},
|
||||
expectedInitial: "JD",
|
||||
},
|
||||
{
|
||||
name: "Test with one letter name",
|
||||
user: &types.User{
|
||||
Name: "K",
|
||||
},
|
||||
expectedInitial: "K",
|
||||
},
|
||||
{
|
||||
name: "Test with one name",
|
||||
user: &types.User{
|
||||
Name: "Doe",
|
||||
},
|
||||
expectedInitial: "DO",
|
||||
},
|
||||
{
|
||||
name: "Test with three names",
|
||||
user: &types.User{
|
||||
Name: "John David Doe",
|
||||
},
|
||||
expectedInitial: "JDD",
|
||||
},
|
||||
{
|
||||
name: "Test with a name that has a valid and invalid letter",
|
||||
user: &types.User{
|
||||
Name: "k-",
|
||||
},
|
||||
expectedInitial: "K",
|
||||
},
|
||||
}
|
||||
|
||||
// Run test cases
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
initial := processAvatarInitials(tc.user)
|
||||
assert.Equal(t, tc.expectedInitial, initial)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (uu u) LookupUserByHandle(ctx context.Context, handle string) (*types.User, error) {
|
||||
return uu.L(ctx, handle)
|
||||
}
|
||||
Reference in New Issue
Block a user