From 6077d0d8a3a6cf4b9fc5f9a7498e45e2c18036ed Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Fri, 9 Nov 2018 14:54:38 +0100 Subject: [PATCH] upd(crm): - ownership of content records from identity - return user structure with content rows - add migrations for crm and system to tests - empty users table for tests - extend tests with user info checks - fix tests in short mode (no testing.M.Skip()) --- crm/repository/content.go | 45 ++++++++++++++++++++++++++++------ crm/repository/content_test.go | 23 ++++++++++++++++- crm/repository/main_test.go | 23 ++++++++++++++--- crm/types/types.go | 8 +++++- 4 files changed, 85 insertions(+), 14 deletions(-) diff --git a/crm/repository/content.go b/crm/repository/content.go index b811e5984..486ecd1e4 100644 --- a/crm/repository/content.go +++ b/crm/repository/content.go @@ -12,6 +12,7 @@ import ( "github.com/titpetric/factory" "github.com/crusttech/crust/crm/types" + systemRepository "github.com/crusttech/crust/system/repository" ) type ( @@ -51,10 +52,7 @@ func (r *content) FindByID(id uint64) (*types.Content, error) { if err := r.db().Get(mod, "SELECT * FROM crm_content WHERE id=? and deleted_at IS NULL", id); err != nil { return nil, err } - if err := r.fillPage(mod); err != nil { - return nil, err - } - return mod, nil + return mod, r.prepare(mod, "page", "user") } func (r *content) Find(moduleID uint64, page int, perPage int) ([]*types.Content, error) { @@ -71,12 +69,16 @@ func (r *content) Find(moduleID uint64, page int, perPage int) ([]*types.Content if perPage < 10 { perPage = 10 } - return mod, r.db().Select(&mod, fmt.Sprintf("SELECT * FROM crm_content WHERE module_id=? and deleted_at IS NULL ORDER BY id DESC LIMIT %d, %d", page, perPage), moduleID) + if err := r.db().Select(&mod, fmt.Sprintf("SELECT * FROM crm_content WHERE module_id=? and deleted_at IS NULL ORDER BY id DESC LIMIT %d, %d", page, perPage), moduleID); err != nil { + return nil, err + } + return mod, r.prepareAll(mod, "user") } func (r *content) Create(mod *types.Content) (*types.Content, error) { mod.ID = factory.Sonyflake.NextID() mod.CreatedAt = time.Now() + mod.UserID = Identity(r.Context()) fields := make([]types.ContentColumn, 0) if err := json.Unmarshal(mod.Fields, &fields); err != nil { @@ -90,7 +92,11 @@ func (r *content) Create(mod *types.Content) (*types.Content, error) { } } - return mod, r.db().Insert("crm_content", mod) + if err := r.db().Insert("crm_content", mod); err != nil { + return nil, err + } + + return mod, r.prepare(mod, "user") } func (r *content) Update(mod *types.Content) (*types.Content, error) { @@ -144,8 +150,31 @@ func (r *content) Fields(content *types.Content) ([]*types.ContentColumn, error) return result, r.db().Select(&result, "select * from crm_content_column where content_id=? order by "+order, args...) } -func (r *content) fillPage(content *types.Content) (err error) { +func (r *content) prepareAll(contents []*types.Content, fields ...string) error { + for _, content := range contents { + if err := r.prepare(content, fields...); err != nil { + return err + } + } + return nil +} + +func (r *content) prepare(content *types.Content, fields ...string) (err error) { api := Page(r.Context(), r.db()) - content.Page, err = api.FindByModuleID(content.ModuleID) + usersAPI := systemRepository.User(r.Context(), r.db()) + for _, field := range fields { + switch field { + case "page": + if content.Page, err = api.FindByModuleID(content.ModuleID); err != nil { + return + } + case "user": + if content.UserID > 0 { + if content.User, err = usersAPI.FindByID(content.UserID); err != nil { + return + } + } + } + } return } diff --git a/crm/repository/content_test.go b/crm/repository/content_test.go index f86306a72..8760c015a 100644 --- a/crm/repository/content_test.go +++ b/crm/repository/content_test.go @@ -8,10 +8,29 @@ import ( "github.com/pkg/errors" "github.com/crusttech/crust/crm/types" + "github.com/crusttech/crust/internal/auth" + systemRepository "github.com/crusttech/crust/system/repository" + systemTypes "github.com/crusttech/crust/system/types" ) func TestContent(t *testing.T) { - repository := Content(context.TODO(), nil).With(context.Background(), nil) + user := &systemTypes.User{ + ID: 1337, + Username: "TestUser", + } + { + err := user.GeneratePassword("Mary had a little lamb, little lamb, little lamb") + assert(t, err == nil, "Error generating password: %+v", err) + } + + { + userAPI := systemRepository.User(context.Background(), nil) + _, err := userAPI.Create(user) + assert(t, err == nil, "Error when inserting user: %+v", err) + } + + ctx := auth.SetIdentityToContext(context.Background(), auth.NewIdentity(user.Identity())) + repository := Content(context.TODO(), nil).With(ctx, nil) fields, err := json.Marshal([]types.Field{ types.Field{ @@ -60,6 +79,8 @@ func TestContent(t *testing.T) { m, err := repository.Create(content) assert(t, err == nil, "Error when creating content: %+v", err) assert(t, m.ID > 0, "Expected auto generated ID") + assert(t, m.User != nil, "Expected non-nil user when creating content") + assert(t, m.User.Username == "TestUser", "Expected 'TestUser' as username, got '%s'", m.User.Username) // fetch created content { diff --git a/crm/repository/main_test.go b/crm/repository/main_test.go index 911da3859..6a5175a83 100644 --- a/crm/repository/main_test.go +++ b/crm/repository/main_test.go @@ -1,16 +1,21 @@ package repository import ( + "log" + "os" + "testing" + "github.com/joho/godotenv" "github.com/namsral/flag" "github.com/titpetric/factory" - "os" - "testing" + + crmMigrate "github.com/crusttech/crust/crm/db" + systemMigrate "github.com/crusttech/crust/system/db" ) func TestMain(m *testing.M) { if testing.Short() { - t.Skip("skipping test in short mode.") + log.Println("skipping test in short mode.") return } @@ -32,9 +37,19 @@ func TestMain(m *testing.M) { db := factory.Database.MustGet() db.Profiler = &factory.Database.ProfilerStdout + // migrate database schema + if err := systemMigrate.Migrate(db); err != nil { + log.Printf("Error running migrations: %+v\n", err) + return + } + if err := crmMigrate.Migrate(db); err != nil { + log.Printf("Error running migrations: %+v\n", err) + return + } + // clean up tables { - for _, name := range []string{"crm_module", "crm_module_form", "crm_content", "crm_content_column", "crm_page"} { + for _, name := range []string{"crm_module", "crm_module_form", "crm_content", "crm_content_column", "crm_page", "users"} { _, err := db.Exec("truncate " + name) if err != nil { panic("Error when clearing " + name + ": " + err.Error()) diff --git a/crm/types/types.go b/crm/types/types.go index b1fb66044..316671b68 100644 --- a/crm/types/types.go +++ b/crm/types/types.go @@ -4,6 +4,8 @@ import ( "time" "github.com/jmoiron/sqlx/types" + + systemTypes "github.com/crusttech/crust/system/types" ) type ( @@ -11,7 +13,11 @@ type ( Content struct { ID uint64 `json:"id,string" db:"id"` ModuleID uint64 `json:"moduleID,string" db:"module_id"` - Page *Page `json:"page,omitempty"` + + User *systemTypes.User `json:"user,omitempty" db:"-"` + UserID uint64 `json:"userID,string" db:"user_id"` + + Page *Page `json:"page,omitempty"` Fields types.JSONText `json:"fields,omitempty" db:"-"`