Fix all tests broken by compose/namespace change

This commit is contained in:
Denis Arh
2019-04-29 18:51:18 +02:00
parent 4af79a5f35
commit 19f6168506
16 changed files with 348 additions and 186 deletions
+6
View File
@@ -93,6 +93,10 @@ steps:
CI: circleci
AUTH_OIDC_ENABLED: 0
AUTH_JWT_SECRET: bRxJ37sJ6Qu4
DB_DSN: crust:crust@tcp(crust-db:3306)/crust?collation=utf8mb4_general_ci
SYSTEM_DB_DSN: crust:crust@tcp(crust-db:3306)/crust?collation=utf8mb4_general_ci
COMPOSE_DB_DSN: crust:crust@tcp(crust-db:3306)/crust?collation=utf8mb4_general_ci
MESSAGING_DB_DSN: crust:crust@tcp(crust-db:3306)/crust?collation=utf8mb4_general_ci
commands:
- make mocks
- make codegen
@@ -103,11 +107,13 @@ steps:
- go build -ldflags "-X github.com/crusttech/crust/internal/version.BuildTime=`date +%FT%T%z` -X github.com/crusttech/crust/internal/version.Version=`git describe --always --tags`" -o build/system-cli-$GOOS-$GOARCH cmd/system-cli/*.go
# check all tests are able to build
- wait-for-it.sh -t 60 --strict crust-db:3306 -- echo "Crust DB1 is up"
- ./build/system-cli-$GOOS-$GOARCH roles reset
- gotest -v --tags="migrations" ./system/db/...
- gotest -v --tags="migrations" ./compose/db/...
- gotest -v --tags="migrations" ./messaging/db/...
- go test -run=^$ --tags="unit integration external" ./cmd/... ./internal/... ./compose/... ./messaging/... ./system/...
- gotest -failfast --coverprofile=coverage.txt -v --tags="unit integration" ./internal/... ./system/... ./compose/... ./messaging/...
- name: coverage
image: plugins/codecov
settings:
+2 -2
View File
@@ -116,7 +116,7 @@ func (r *namespace) Update(mod *types.Namespace) (*types.Namespace, error) {
return mod, r.db().Replace(r.table(), mod)
}
func (r *namespace) DeleteByID(id uint64) error {
_, err := r.db().Exec("DELETE FROM "+r.table()+" WHERE id=?", id)
func (r *namespace) DeleteByID(namespaceID uint64) error {
_, err := r.db().Exec("UPDATE "+r.table()+" SET deleted_at = NOW() WHERE id = ?", namespaceID)
return err
}
+4 -1
View File
@@ -15,7 +15,7 @@ type (
With(ctx context.Context, db *factory.DB) PageRepository
FindByID(namespaceID, pageID uint64) (*types.Page, error)
FindByModuleID(namespaceID, pageID uint64) (*types.Page, error)
FindByModuleID(namespaceID, moduleID uint64) (*types.Page, error)
Find(filter types.PageFilter) (set types.PageSet, f types.PageFilter, err error)
Create(mod *types.Page) (*types.Page, error)
@@ -107,6 +107,8 @@ func (r page) Find(filter types.PageFilter) (set types.PageSet, f types.PageFilt
if filter.ParentID > 0 {
query = query.Where("self_id = ?", filter.ParentID)
} else if filter.Root {
query = query.Where("self_id = 0")
}
if f.Query != "" {
@@ -171,6 +173,7 @@ func (r page) Create(mod *types.Page) (*types.Page, error) {
func (r page) Update(mod *types.Page) (*types.Page, error) {
now := time.Now()
mod.UpdatedAt = &now
return mod, r.db().Replace(r.table(), mod)
}
+79 -3
View File
@@ -1,11 +1,87 @@
// +build unit
// +build integration
package service
import (
"context"
"testing"
"github.com/pkg/errors"
"github.com/crusttech/crust/compose/types"
"github.com/crusttech/crust/internal/auth"
"github.com/crusttech/crust/internal/test"
systemTypes "github.com/crusttech/crust/system/types"
)
func TestModuleGraph(t *testing.T) {
// repository := Module().With(context.Background())
func TestChart(t *testing.T) {
ctx := context.WithValue(context.Background(), "testing", true)
user := &systemTypes.User{
ID: 1337,
Name: "John Crm Doe",
Username: "johndoe",
}
// Set Identity (required for permission checks).
ctx = auth.SetIdentityToContext(ctx, user)
ns1, _ := createTestNamespaces(ctx, t)
svc := Chart().With(ctx)
// the chart object we're working with
chart := &types.Chart{
NamespaceID: ns1.ID,
Name: "Test",
}
{
{
m, err := svc.Update(chart)
test.Assert(t, m == nil, "Expected empty return for invalid update, got %#v", m)
test.Assert(t, err != nil, "Expected error when updating invalid content")
}
// create chart
m, err := svc.Create(chart)
test.Assert(t, err == nil, "Error when creating chart: %+v", err)
test.Assert(t, m.ID > 0, "Expected auto generated ID")
{
_, err := svc.Create(chart)
test.Assert(t, err == nil, "Unexpected error when creating chart, %+v", err)
}
// fetch created chart
{
ms, err := svc.FindByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when retrieving chart by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "Expected ID from database to match, %+v", errors.Errorf("%d != %d", m.ID, ms.ID))
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %+v", errors.Errorf("%s != %s", m.Name, ms.Name))
}
// update created chart
{
m.UpdatedAt = nil
m.Name = "Updated test"
_, err := svc.Update(m)
test.Assert(t, err == nil, "Error when updating chart, %+v", err)
}
// re-fetch chart
{
ms, err := svc.FindByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when retrieving chart by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "re-fetch: Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %s != %s", m.Name, ms.Name)
}
// delete chart
{
err := svc.DeleteByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when deleting chart by id: %+v", err)
}
}
}
+15
View File
@@ -3,6 +3,7 @@
package service
import (
"context"
"log"
"os"
"testing"
@@ -11,6 +12,8 @@ import (
"github.com/titpetric/factory"
composeMigrate "github.com/crusttech/crust/compose/db"
"github.com/crusttech/crust/compose/types"
"github.com/crusttech/crust/internal/test"
systemMigrate "github.com/crusttech/crust/system/db"
systemService "github.com/crusttech/crust/system/service"
)
@@ -56,3 +59,15 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
func createTestNamespaces(ctx context.Context, t *testing.T) (ns1 *types.Namespace, ns2 *types.Namespace) {
var err error
ns1, err = Namespace().With(ctx).Create(&types.Namespace{Enabled: true, Name: "TestNamespace"})
test.Assert(t, err == nil, "Error when creating namespace: %+v", err)
ns2, err = Namespace().With(ctx).Create(&types.Namespace{Enabled: true, Name: "TestNamespace"})
test.Assert(t, err == nil, "Error when creating namespace: %+v", err)
return ns1, ns2
}
+5
View File
@@ -100,6 +100,11 @@ func (svc *module) Find(filter types.ModuleFilter) (set types.ModuleSet, f types
}
func (svc *module) Create(mod *types.Module) (*types.Module, error) {
if mod.NamespaceID == 0 {
return nil, ErrNamespaceRequired.withStack()
}
if !svc.prmSvc.CanCreateModule(crmNamespace()) {
return nil, ErrNoCreatePermissions.withStack()
}
+10 -6
View File
@@ -24,11 +24,14 @@ func TestModule(t *testing.T) {
// Set Identity (required for permission checks).
ctx = auth.SetIdentityToContext(ctx, user)
ns1, _ := createTestNamespaces(ctx, t)
svc := Module().With(ctx)
// the module object we're working with
module := &types.Module{
Name: "Test",
NamespaceID: ns1.ID,
Name: "Test",
Fields: types.ModuleFieldSet{
&types.ModuleField{
Name: "name",
@@ -65,7 +68,7 @@ func TestModule(t *testing.T) {
// fetch created module
{
ms, err := svc.FindByID(m.ID)
ms, err := svc.FindByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when retrieving module by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %s != %s", m.Name, ms.Name)
@@ -75,6 +78,7 @@ func TestModule(t *testing.T) {
// update created module
{
m.Name = "Updated test"
m.UpdatedAt = nil
_, err := svc.Update(m)
test.Assert(t, err == nil, "Error when updating module, %+v", err)
}
@@ -88,7 +92,7 @@ func TestModule(t *testing.T) {
// re-fetch module
{
ms, err := svc.FindByID(m.ID)
ms, err := svc.FindByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when retrieving module by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %s != %s", m.Name, ms.Name)
@@ -96,7 +100,7 @@ func TestModule(t *testing.T) {
// fetch all modules
{
ms, err := svc.Find()
ms, _, err := svc.Find(types.ModuleFilter{})
test.Assert(t, err == nil, "Error when retrieving modules: %+v", err)
test.Assert(t, len(ms) >= 1, "Expected at least one module, got %d", len(ms))
prevModuleCount = len(ms)
@@ -104,13 +108,13 @@ func TestModule(t *testing.T) {
// re-fetch module
{
err := svc.DeleteByID(m.ID)
err := svc.DeleteByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when deleting module by id: %+v", err)
}
// fetch all modules
{
ms, err := svc.Find()
ms, _, err := svc.Find(types.ModuleFilter{})
test.Assert(t, err == nil, "Error when retrieving modules: %+v", err)
test.Assert(t, len(ms) < prevModuleCount, "Expected modules count to decrease after deletion, %d < %d", len(ms), prevModuleCount)
}
@@ -0,0 +1,93 @@
// +build integration
package service
import (
"context"
"testing"
"github.com/crusttech/crust/compose/types"
"github.com/crusttech/crust/internal/auth"
"github.com/crusttech/crust/internal/test"
systemTypes "github.com/crusttech/crust/system/types"
)
func TestNamespace(t *testing.T) {
ctx := context.WithValue(context.Background(), "testing", true)
user := &systemTypes.User{
ID: 1337,
Name: "John Crm Doe",
Username: "johndoe",
}
// Set Identity (required for permission checks).
ctx = auth.SetIdentityToContext(ctx, user)
svc := Namespace().With(ctx)
// the namespace object we're working with
namespace := &types.Namespace{
Name: "Test",
}
prevNamespaceCount := uint(0)
{
{
m, err := svc.Update(namespace)
test.Assert(t, m == nil, "Expected empty return for invalid update, got %#v", m)
test.Assert(t, err != nil, "Expected error when updating invalid content")
}
// create namespace
m, err := svc.Create(namespace)
test.Assert(t, err == nil, "Error when creating namespace: %+v", err)
test.Assert(t, m.ID > 0, "Expected auto generated ID")
// fetch created namespace
{
ms, err := svc.FindByID(m.ID)
test.Assert(t, err == nil, "Error when retrieving namespace by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %s != %s", m.Name, ms.Name)
}
// update created namespace
{
m.Name = "Updated test"
m.UpdatedAt = nil
_, err := svc.Update(m)
test.Assert(t, err == nil, "Error when updating namespace, %+v", err)
}
// re-fetch namespace
{
ms, err := svc.FindByID(m.ID)
test.Assert(t, err == nil, "Error when retrieving namespace by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %s != %s", m.Name, ms.Name)
}
// fetch all namespaces
{
_, f, err := svc.Find(types.NamespaceFilter{})
test.Assert(t, err == nil, "Error when retrieving namespaces: %+v", err)
test.Assert(t, f.Count > 0, "Expected at least one namespace, got %d", f.Count)
prevNamespaceCount = f.Count
}
// re-fetch namespace
{
err := svc.DeleteByID(m.ID)
test.Assert(t, err == nil, "Error when deleting namespace by id: %+v", err)
}
// fetch all namespaces
{
_, f, err := svc.Find(types.NamespaceFilter{})
test.Assert(t, err == nil, "Error when retrieving namespaces: %+v", err)
test.Assert(t, f.Count < prevNamespaceCount, "Expected namespaces count to decrease after deletion, %d < %d", f.Count, prevNamespaceCount)
}
}
}
+75 -44
View File
@@ -38,6 +38,10 @@ type (
}
)
const (
ErrModulePageExists serviceError = "ModulePageExists"
)
func Page() PageService {
return (&page{
prmSvc: DefaultPermissions,
@@ -76,17 +80,32 @@ func (svc *page) checkPermissions(p *types.Page, err error) (*types.Page, error)
}
func (svc *page) FindBySelfID(namespaceID, parentID uint64) (pp types.PageSet, f types.PageFilter, err error) {
if namespaceID == 0 {
return nil, f, ErrNamespaceRequired.withStack()
}
return svc.filterPageSetByPermission(svc.pageRepo.Find(types.PageFilter{
NamespaceID: namespaceID,
ParentID: parentID,
// This will enable parentID=0 query
Root: true,
}))
}
func (svc *page) Find(filter types.PageFilter) (set types.PageSet, f types.PageFilter, err error) {
if filter.NamespaceID == 0 {
return nil, f, ErrNamespaceRequired.withStack()
}
return svc.filterPageSetByPermission(svc.pageRepo.Find(filter))
}
func (svc *page) Tree(namespaceID uint64) (pages types.PageSet, err error) {
if namespaceID == 0 {
return nil, ErrNamespaceRequired.withStack()
}
var (
tree types.PageSet
filter = types.PageFilter{
@@ -140,58 +159,70 @@ func (svc *page) Reorder(namespaceID, selfID uint64, pageIDs []uint64) error {
return svc.pageRepo.Reorder(namespaceID, selfID, pageIDs)
}
func (svc *page) Create(page *types.Page) (p *types.Page, err error) {
validate := func() error {
if !svc.prmSvc.CanCreatePage(crmNamespace()) {
return errors.New("not allowed to create this page")
}
func (svc *page) Create(mod *types.Page) (p *types.Page, err error) {
mod.ID = 0
if page.ModuleID > 0 {
if p, err = svc.pageRepo.FindByModuleID(page.NamespaceID, page.ModuleID); err != nil {
return err
} else if p.ID > 0 {
return errors.New("Page for module already exists")
}
}
return nil
if mod.NamespaceID == 0 {
return nil, ErrNamespaceRequired.withStack()
}
if err := validate(); err != nil {
return nil, err
if !svc.prmSvc.CanCreatePage(crmNamespace()) {
return nil, ErrNoCreatePermissions.withStack()
}
return p, svc.db.Transaction(func() (err error) {
p, err = svc.pageRepo.Create(page)
if err = svc.checkModulePage(mod); err != nil {
return
})
}
p, err = svc.pageRepo.Create(mod)
return
}
func (svc *page) Update(page *types.Page) (p *types.Page, err error) {
validate := func() error {
if page.ID == 0 {
return errors.New("Error when saving page, invalid ID")
} else if p, err = svc.pageRepo.FindByID(page.NamespaceID, page.ID); err != nil {
return errors.Wrap(err, "Error while loading page for update")
} else {
if !svc.prmSvc.CanUpdatePage(p) {
return errors.New("not allowed to update this page")
}
}
func (svc *page) Update(mod *types.Page) (p *types.Page, err error) {
if mod.ID == 0 {
return nil, ErrInvalidID.withStack()
}
if page.ModuleID > 0 {
if p, err = svc.pageRepo.FindByModuleID(page.NamespaceID, page.ModuleID); err != nil {
return err
} else if p.ID > 0 && page.ID != p.ID {
return errors.New("Page for module already exists")
}
}
return nil
}
if err := validate(); err != nil {
return nil, err
}
return p, svc.db.Transaction(func() (err error) {
p, err = svc.pageRepo.Update(page)
if p, err = svc.pageRepo.FindByID(mod.NamespaceID, mod.ID); err != nil {
return
})
}
if isStale(mod.UpdatedAt, p.UpdatedAt, p.CreatedAt) {
return nil, ErrStaleData.withStack()
}
if !svc.prmSvc.CanUpdatePage(p) {
return nil, ErrNoUpdatePermissions.withStack()
}
if err = svc.checkModulePage(mod); err != nil {
return
}
p.ModuleID = mod.ModuleID
p.SelfID = mod.SelfID
p.Blocks = mod.Blocks
p.Title = mod.Title
p.Description = mod.Description
p.Visible = mod.Visible
p.Weight = mod.Weight
p, err = svc.pageRepo.Update(p)
return
}
func (svc page) checkModulePage(mod *types.Page) error {
if mod.ModuleID > 0 {
if p, err := svc.pageRepo.FindByModuleID(mod.NamespaceID, mod.ModuleID); err != nil {
if err.Error() != repository.ErrPageNotFound.Error() {
return err
}
} else if p.ID > 0 && mod.ID != p.ID {
return ErrModulePageExists
}
}
return nil
}
func (svc *page) DeleteByID(namespaceID, pageID uint64) error {
+41 -42
View File
@@ -27,12 +27,16 @@ func TestPage(t *testing.T) {
// Set Identity (required for permission checks).
ctx = auth.SetIdentityToContext(ctx, user)
repository := Page().With(ctx)
ns1, _ := createTestNamespaces(ctx, t)
svc := Page().With(ctx)
// the page object we're working with
var err error
page := &types.Page{
Title: "Test",
ModuleID: 123,
NamespaceID: ns1.ID,
Title: "Test",
ModuleID: 123,
}
(&page.Blocks).Scan([]byte("[]"))
@@ -40,104 +44,99 @@ func TestPage(t *testing.T) {
{
{
m, err := repository.Update(page)
m, err := svc.Update(page)
test.Assert(t, m == nil, "Expected empty return for invalid update, got %#v", m)
test.Assert(t, err != nil, "Expected error when updating invalid content")
}
// create page
m, err := repository.Create(page)
page, err = svc.Create(page)
test.Assert(t, err == nil, "Error when creating page: %+v", err)
test.Assert(t, m.ID > 0, "Expected auto generated ID")
test.Assert(t, page.ID > 0, "Expected auto generated ID")
page.SelfID = m.ID
var firstPageID = page.ID
page.SelfID = page.ID
{
_, err := repository.Create(page)
_, err = svc.Create(page)
test.Assert(t, err != nil, "%+v", errors.Errorf("Expected error when creating duplicate moduleID page"))
}
page.ModuleID = 0
{
page.ModuleID = 0
_, err := repository.Create(page)
_, err = svc.Create(page)
test.Assert(t, err == nil, "Unexpected error when creating page, %+v", err)
}
{
_, err := repository.Create(page)
_, err = svc.Create(page)
test.Assert(t, err == nil, "Unexpected error when creating page, %+v", err)
}
// fetch created page
{
ms, err := repository.FindByID(m.ID)
p, err := svc.FindByID(page.NamespaceID, page.ID)
test.Assert(t, err == nil, "Error when retrieving page by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "Expected ID from database to match, %+v", errors.Errorf("%d != %d", m.ID, ms.ID))
test.Assert(t, ms.Title == m.Title, "Expected Title from database to match, %+v", errors.Errorf("%s != %s", m.Title, ms.Title))
test.Assert(t, p.ID == page.ID, "Expected ID from database to match, %+v", errors.Errorf("%d != %d", page.ID, p.ID))
test.Assert(t, p.Title == page.Title, "Expected Title from database to match, %+v", errors.Errorf("%s != %s", page.Title, p.Title))
}
// update created page
{
m.Title = "Updated test"
_, err := repository.Update(m)
page.Title = "Updated test"
page.UpdatedAt = nil
_, err := svc.Update(page)
test.Assert(t, err == nil, "Error when updating page, %+v", err)
}
// re-fetch page
{
ms, err := repository.FindByID(m.ID)
p, err := svc.FindByID(page.NamespaceID, page.ID)
test.Assert(t, err == nil, "Error when retrieving page by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "re-fetch: Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Title == m.Title, "Expected Title from database to match, %s != %s", m.Title, ms.Title)
}
// re-fetch page with moduleID
{
ms, err := repository.FindByModuleID(m.ModuleID)
test.Assert(t, err == nil, "Error when retrieving page by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "fetch-module: Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Title == m.Title, "Expected Title from database to match, %s != %s", m.Title, ms.Title)
test.Assert(t, p.ID == page.ID, "re-fetch: Expected ID from database to match, %d != %d", page.ID, p.ID)
test.Assert(t, p.Title == page.Title, "Expected Title from database to match, %s != %s", page.Title, p.Title)
}
// fetch all pages
{
ms, err := repository.FindBySelfID(0)
p, _, err := svc.FindBySelfID(page.NamespaceID, 0)
test.Assert(t, err == nil, "Error when retrieving pages: %+v", err)
test.Assert(t, len(ms) >= 1, "Expected at least one page, got %d", len(ms))
prevPageCount = len(ms)
test.Assert(t, len(p) >= 1, "Expected at least one page, got %d", len(p))
prevPageCount = len(p)
}
// fetch all pages
{
ms, err := repository.FindBySelfID(m.ID)
p, _, err := svc.FindBySelfID(page.NamespaceID, firstPageID)
test.Assert(t, err == nil, "Error when retrieving pages: %+v", err)
test.Assert(t, len(ms) == 2, "Expected two pages with selfID=%d, got %v", m.ID, spew.Sdump(ms))
prevPageCount = len(ms)
test.Assert(t, len(p) == 2, "Expected 2 pages with selfID=%d, got %v", page.ID, spew.Sdump(p))
prevPageCount = len(p)
parent := m.ID
ids := []uint64{ms[0].ID, ms[1].ID}
ids := []uint64{p[0].ID, p[1].ID}
{
err := repository.Reorder(parent, ids)
err := svc.Reorder(page.NamespaceID, firstPageID, ids)
test.Assert(t, err == nil, "Error when reordering pages: %+v", err)
ms, err = repository.FindBySelfID(m.ID)
p, _, err = svc.FindBySelfID(page.NamespaceID, firstPageID)
test.Assert(t, err == nil, "Error when retrieving pages: %+v", err)
test.Assert(t, len(ms) == 2, "Expected two pages with selfID=%d, got %v", m.ID, spew.Sdump(ms))
test.Assert(t, ms[0].Weight < ms[1].Weight, "Expected ascending order, %+v", errors.Errorf("%d < %d", ms[0].Weight, ms[1].Weight))
test.Assert(t, len(p) == 2, "Expected 2 pages with selfID=%d, got %v", page.ID, spew.Sdump(p))
test.Assert(t, p[0].Weight < p[1].Weight, "Expected ascending order, %+v", errors.Errorf("%d < %d", p[0].Weight, p[1].Weight))
}
}
// re-fetch page
{
err := repository.DeleteByID(m.ID)
err := svc.DeleteByID(page.NamespaceID, page.ID)
test.Assert(t, err == nil, "Error when deleting page by id: %+v", err)
}
// fetch all pages
{
ms, err := repository.FindBySelfID(0)
p, _, err := svc.FindBySelfID(page.NamespaceID, 0)
test.Assert(t, err == nil, "Error when retrieving pages: %+v", err)
test.Assert(t, len(ms) < prevPageCount, "Expected pages count to decrease after deletion, %d < %d", len(ms), prevPageCount)
test.Assert(t, len(p) < prevPageCount, "Expected pages count to decrease after deletion, %d < %d", len(p), prevPageCount)
}
}
+1
View File
@@ -27,6 +27,7 @@ type (
Effective() (ee []effectivePermission, err error)
CanAccess() bool
CanGrant() bool
CanCreateNamespace() bool
CanReadNamespace(r permissionResource) bool
CanUpdateNamespace(r permissionResource) bool
@@ -1,80 +0,0 @@
// +build integration
package service
import (
"context"
"testing"
"github.com/crusttech/crust/compose/internal/repository"
"github.com/crusttech/crust/compose/types"
"github.com/crusttech/crust/internal/auth"
"github.com/crusttech/crust/internal/rules"
. "github.com/crusttech/crust/internal/test"
systemService "github.com/crusttech/crust/system/service"
systemTypes "github.com/crusttech/crust/system/types"
)
func TestPermissions(t *testing.T) {
var err error
ctx := context.WithValue(context.Background(), "testing", true)
{
user := &systemTypes.User{ID: 1337}
ctx = auth.SetIdentityToContext(ctx, auth.NewIdentity(user.Identity()))
}
// Create user with role and add it to context.
userSvc := systemService.TestUser(t, ctx)
user := &systemTypes.User{
Name: "John Crm Doe",
Username: "johndoe",
}
_, err = userSvc.Create(user)
NoError(t, err, "expected no error creating user, got %+v", err)
ctx = auth.SetIdentityToContext(ctx, user)
roleSvc := systemService.TestRole(t, ctx)
role := &systemTypes.Role{
Name: "Test role v1",
}
role, err = roleSvc.Create(role)
NoError(t, err, "expected no error creating role, got %+v", err)
err = roleSvc.MemberAdd(role.ID, user.ID)
NoError(t, err, "expected no error adding user to role, got %+v", err)
// Insert `grant` permission for `compose`.
{
db := repository.DB(ctx)
resources := rules.NewResources(ctx, db)
list := []rules.Rule{
rules.Rule{Resource: types.PermissionResource, Operation: "grant", Value: rules.Allow},
}
err := resources.Grant(role.ID, list)
NoError(t, err, "expected no error, got %+v", err)
}
// Generate services.
cleanContext := auth.SetIdentityToContext(context.Background(), user)
permissionsSvc := Permissions().With(cleanContext)
systemRulesSvc := systemService.TestRules(t, ctx)
// Test `access` to compose service.
ret := permissionsSvc.CanAccess()
Assert(t, ret == false, "expected CanAccess == false, got %+v", ret)
// Add `access` to compose service.
list := []rules.Rule{
rules.Rule{Resource: types.PermissionResource, Operation: "access", Value: rules.Allow},
}
_, err = systemRulesSvc.Update(role.ID, list)
NoError(t, err, "expected no error, got %+v", err)
// Test `access` to compose service.
ret = permissionsSvc.CanAccess()
Assert(t, ret == true, "expected CanAccess == true, got %+v", ret)
}
+2 -2
View File
@@ -46,8 +46,8 @@ func Init() error {
// Data is stale when new date does not match updatedAt or createdAt (before first update)
func isStale(new *time.Time, updatedAt *time.Time, createdAt time.Time) bool {
if new == nil {
// Change to true to require stale-data-check.
return true
// Change to true for stale-data-check
return false
}
if updatedAt != nil {
+4
View File
@@ -77,6 +77,10 @@ func (svc trigger) Find(filter types.TriggerFilter) (set types.TriggerSet, f typ
}
func (svc trigger) Create(mod *types.Trigger) (c *types.Trigger, err error) {
if mod.NamespaceID == 0 {
return nil, ErrNamespaceRequired.withStack()
}
if !svc.prmSvc.CanCreateTrigger(crmNamespace()) {
return nil, ErrNoCreatePermissions.withStack()
}
+9 -5
View File
@@ -26,12 +26,15 @@ func TestTrigger(t *testing.T) {
// Set Identity (required for permission checks).
ctx = auth.SetIdentityToContext(ctx, user)
ns1, _ := createTestNamespaces(ctx, t)
svc := Trigger().With(ctx)
// the trigger object we're working with
trigger := &types.Trigger{
Name: "Test",
ModuleID: 123,
NamespaceID: ns1.ID,
Name: "Test",
ModuleID: 123,
}
{
@@ -53,7 +56,7 @@ func TestTrigger(t *testing.T) {
// fetch created trigger
{
ms, err := svc.FindByID(m.ID)
ms, err := svc.FindByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when retrieving trigger by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "Expected ID from database to match, %+v", errors.Errorf("%d != %d", m.ID, ms.ID))
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %+v", errors.Errorf("%s != %s", m.Name, ms.Name))
@@ -61,6 +64,7 @@ func TestTrigger(t *testing.T) {
// update created trigger
{
m.UpdatedAt = nil
m.Name = "Updated test"
_, err := svc.Update(m)
test.Assert(t, err == nil, "Error when updating trigger, %+v", err)
@@ -68,7 +72,7 @@ func TestTrigger(t *testing.T) {
// re-fetch trigger
{
ms, err := svc.FindByID(m.ID)
ms, err := svc.FindByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when retrieving trigger by id: %+v", err)
test.Assert(t, ms.ID == m.ID, "re-fetch: Expected ID from database to match, %d != %d", m.ID, ms.ID)
test.Assert(t, ms.Name == m.Name, "Expected Name from database to match, %s != %s", m.Name, ms.Name)
@@ -76,7 +80,7 @@ func TestTrigger(t *testing.T) {
// delete trigger
{
err := svc.DeleteByID(m.ID)
err := svc.DeleteByID(m.NamespaceID, m.ID)
test.Assert(t, err == nil, "Error when deleting trigger by id: %+v", err)
}
}
+2 -1
View File
@@ -47,7 +47,8 @@ type (
PageFilter struct {
NamespaceID uint64 `json:"namespaceID,string"`
ParentID uint64 `json:"paentID,string"`
ParentID uint64 `json:"parentID,string,omitempty"`
Root bool `json:"root,omitempty"`
Query string `json:"query"`
Page uint `json:"page"`
PerPage uint `json:"perPage"`