326 lines
10 KiB
Go
326 lines
10 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
)
|
|
|
|
// Helper: create prerequisite Account + PlatformApp for Permissible tests.
|
|
func createPermissiblePrereqs(t *testing.T, db *gorm.DB) (*model.Account, *model.PlatformApp) {
|
|
t.Helper()
|
|
|
|
account := &model.Account{Name: "PermTestOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(account).Error)
|
|
|
|
active := true
|
|
app := &model.PlatformApp{
|
|
Name: "PermTestApp",
|
|
AccountID: &account.ID,
|
|
Description: "Test platform app for permissible",
|
|
Type: "api",
|
|
Status: "active",
|
|
Active: &active,
|
|
}
|
|
require.NoError(t, db.Create(app).Error)
|
|
|
|
return account, app
|
|
}
|
|
|
|
// Helper: create a second PlatformApp for multi-app tests.
|
|
func createSecondPlatformApp(t *testing.T, db *gorm.DB, accountID uint) *model.PlatformApp {
|
|
t.Helper()
|
|
|
|
active := true
|
|
app := &model.PlatformApp{
|
|
Name: "PermTestApp2",
|
|
AccountID: &accountID,
|
|
Description: "Second test platform app",
|
|
Type: "api",
|
|
Status: "active",
|
|
Active: &active,
|
|
}
|
|
require.NoError(t, db.Create(app).Error)
|
|
return app
|
|
}
|
|
|
|
// ========== 1. Create + GetByID roundtrip ==========
|
|
|
|
func TestPermissibleRepo_CreateAndGetByID(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
|
|
perm := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}
|
|
err := repo.Create(context.Background(), perm)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, perm.ID, "ID should be set after Create")
|
|
assert.Equal(t, app.ID, perm.PlatformAppID)
|
|
assert.Equal(t, model.PermissibleTypeAccount, perm.PermissibleType)
|
|
assert.Equal(t, account.ID, perm.PermissibleID)
|
|
|
|
// GetByID roundtrip
|
|
found, err := repo.GetByID(context.Background(), perm.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, perm.ID, found.ID)
|
|
assert.Equal(t, app.ID, found.PlatformAppID)
|
|
assert.Equal(t, model.PermissibleTypeAccount, found.PermissibleType)
|
|
assert.Equal(t, account.ID, found.PermissibleID)
|
|
}
|
|
|
|
// ========== 2. FindByPlatformAppID ==========
|
|
|
|
func TestPermissibleRepo_FindByPlatformAppID(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
|
|
// Create multiple permissibles for the same app (different resource types)
|
|
perm1 := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}
|
|
perm2 := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeUser,
|
|
PermissibleID: account.ID,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), perm1))
|
|
require.NoError(t, repo.Create(context.Background(), perm2))
|
|
|
|
results, err := repo.FindByPlatformAppID(context.Background(), app.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, results, 2)
|
|
|
|
// Verify both types are present
|
|
types := map[string]bool{}
|
|
for _, p := range results {
|
|
types[p.PermissibleType] = true
|
|
assert.Equal(t, app.ID, p.PlatformAppID)
|
|
}
|
|
assert.True(t, types[model.PermissibleTypeAccount])
|
|
assert.True(t, types[model.PermissibleTypeUser])
|
|
}
|
|
|
|
func TestPermissibleRepo_FindByPlatformAppID_Empty(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
_, app := createPermissiblePrereqs(t, db)
|
|
|
|
results, err := repo.FindByPlatformAppID(context.Background(), app.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, results, 0)
|
|
}
|
|
|
|
// ========== 3. FindByResource (which apps can access Account X) ==========
|
|
|
|
func TestPermissibleRepo_FindByResource(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app1 := createPermissiblePrereqs(t, db)
|
|
app2 := createSecondPlatformApp(t, db, account.ID)
|
|
|
|
// Both apps get access to the same Account resource
|
|
require.NoError(t, repo.Create(context.Background(), &model.Permissible{
|
|
PlatformAppID: app1.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}))
|
|
require.NoError(t, repo.Create(context.Background(), &model.Permissible{
|
|
PlatformAppID: app2.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}))
|
|
|
|
// FindByResource should return both permissibles
|
|
results, err := repo.FindByResource(context.Background(), model.PermissibleTypeAccount, account.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, results, 2)
|
|
|
|
// Verify both apps are represented
|
|
appIDs := map[uint]bool{}
|
|
for _, p := range results {
|
|
appIDs[p.PlatformAppID] = true
|
|
assert.Equal(t, model.PermissibleTypeAccount, p.PermissibleType)
|
|
assert.Equal(t, account.ID, p.PermissibleID)
|
|
}
|
|
assert.True(t, appIDs[app1.ID])
|
|
assert.True(t, appIDs[app2.ID])
|
|
}
|
|
|
|
// ========== 4. FindByPlatformAppAndResource (check if app has permission on specific resource) ==========
|
|
|
|
func TestPermissibleRepo_FindByPlatformAppAndResource(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
|
|
perm := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), perm))
|
|
|
|
// Found: app has permission on this resource
|
|
found, err := repo.FindByPlatformAppAndResource(context.Background(), app.ID, model.PermissibleTypeAccount, account.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, perm.ID, found.ID)
|
|
assert.Equal(t, app.ID, found.PlatformAppID)
|
|
assert.Equal(t, model.PermissibleTypeAccount, found.PermissibleType)
|
|
assert.Equal(t, account.ID, found.PermissibleID)
|
|
}
|
|
|
|
func TestPermissibleRepo_FindByPlatformAppAndResource_NotFound(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
|
|
// No permissible created — should return gorm.ErrRecordNotFound
|
|
_, err := repo.FindByPlatformAppAndResource(context.Background(), app.ID, model.PermissibleTypeAccount, account.ID)
|
|
assert.Error(t, err)
|
|
assert.Equal(t, gorm.ErrRecordNotFound, err)
|
|
}
|
|
|
|
// ========== 5. Delete single Permissible ==========
|
|
|
|
func TestPermissibleRepo_Delete(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
|
|
perm := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), perm))
|
|
|
|
err := repo.Delete(context.Background(), perm.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Verify it's gone
|
|
_, err = repo.GetByID(context.Background(), perm.ID)
|
|
assert.Error(t, err)
|
|
assert.Equal(t, gorm.ErrRecordNotFound, err)
|
|
}
|
|
|
|
// ========== 6. DeleteByPlatformAppAndResource ==========
|
|
|
|
func TestPermissibleRepo_DeleteByPlatformAppAndResource(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
|
|
// Create two permissibles: one for Account, one for User
|
|
permAccount := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}
|
|
permUser := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeUser,
|
|
PermissibleID: account.ID,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), permAccount))
|
|
require.NoError(t, repo.Create(context.Background(), permUser))
|
|
|
|
// Delete only the Account permission
|
|
err := repo.DeleteByPlatformAppAndResource(context.Background(), app.ID, model.PermissibleTypeAccount, account.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Account permission should be gone
|
|
_, err = repo.FindByPlatformAppAndResource(context.Background(), app.ID, model.PermissibleTypeAccount, account.ID)
|
|
assert.Equal(t, gorm.ErrRecordNotFound, err)
|
|
|
|
// User permission should still exist
|
|
found, err := repo.FindByPlatformAppAndResource(context.Background(), app.ID, model.PermissibleTypeUser, account.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, permUser.ID, found.ID)
|
|
}
|
|
|
|
// ========== 7. DeleteByPlatformAppID (cleanup when app is deleted) ==========
|
|
|
|
func TestPermissibleRepo_DeleteByPlatformAppID(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
app2 := createSecondPlatformApp(t, db, account.ID)
|
|
|
|
// Create permissibles for both apps
|
|
require.NoError(t, repo.Create(context.Background(), &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}))
|
|
require.NoError(t, repo.Create(context.Background(), &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeUser,
|
|
PermissibleID: account.ID,
|
|
}))
|
|
require.NoError(t, repo.Create(context.Background(), &model.Permissible{
|
|
PlatformAppID: app2.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}))
|
|
|
|
// Delete all permissibles for app1
|
|
err := repo.DeleteByPlatformAppID(context.Background(), app.ID)
|
|
require.NoError(t, err)
|
|
|
|
// App1's permissibles should all be gone
|
|
results, err := repo.FindByPlatformAppID(context.Background(), app.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, results, 0)
|
|
|
|
// App2's permissible should still exist
|
|
results, err = repo.FindByPlatformAppID(context.Background(), app2.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, results, 1)
|
|
assert.Equal(t, model.PermissibleTypeAccount, results[0].PermissibleType)
|
|
}
|
|
|
|
// ========== 8. Duplicate permission should error (unique constraint) ==========
|
|
|
|
func TestPermissibleRepo_DuplicatePermissionError(t *testing.T) {
|
|
db := setupTestDB(t, &model.Permissible{}, &model.PlatformApp{})
|
|
repo := NewPermissibleRepo(db)
|
|
|
|
account, app := createPermissiblePrereqs(t, db)
|
|
|
|
perm := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), perm))
|
|
|
|
// Attempt to create duplicate (same platform_app_id + permissible_type + permissible_id)
|
|
dup := &model.Permissible{
|
|
PlatformAppID: app.ID,
|
|
PermissibleType: model.PermissibleTypeAccount,
|
|
PermissibleID: account.ID,
|
|
}
|
|
err := repo.Create(context.Background(), dup)
|
|
assert.Error(t, err, "duplicate permissible should return an error")
|
|
} |