3
0

add(crm): implement page reorder api, list pages by selfID

This commit is contained in:
Tit Petric
2018-10-25 11:52:11 +02:00
parent 31c38f683c
commit 068af15e40
9 changed files with 133 additions and 23 deletions
+1
View File
@@ -48,6 +48,7 @@ CRM module pages
| Parameter | Type | Method | Description | Default | Required? |
| --------- | ---- | ------ | ----------- | ------- | --------- |
| selfID | uint64 | GET | Parent page ID | N/A | NO |
## Create page
+6 -1
View File
@@ -49,7 +49,12 @@
"name": "list",
"method": "GET",
"path": "/",
"title": "List available pages"
"title": "List available pages",
"parameters": {
"get": [
{ "type": "uint64", "name": "selfID", "required": false, "title": "Parent page ID" }
]
}
},
{
"name": "create",
+10 -1
View File
@@ -14,7 +14,16 @@
"Method": "GET",
"Title": "List available pages",
"Path": "/",
"Parameters": null
"Parameters": {
"get": [
{
"name": "selfID",
"required": false,
"title": "Parent page ID",
"type": "uint64"
}
]
}
},
{
"Name": "create",
+1 -1
View File
@@ -33,7 +33,7 @@ func TestMain(m *testing.M) {
// clean up tables
{
for _, name := range []string{"crm_module", "crm_content", "crm_content_column"} {
for _, name := range []string{"crm_module", "crm_module_form", "crm_content", "crm_content_column", "crm_page"} {
_, err := db.Exec("truncate " + name)
if err != nil {
panic("Error when clearing " + name + ": " + err.Error())
+46 -9
View File
@@ -13,13 +13,15 @@ type (
PageRepository interface {
With(ctx context.Context, db *factory.DB) PageRepository
Find() ([]*types.Page, error)
Find(selfID uint64) ([]*types.Page, error)
FindByID(id uint64) (*types.Page, error)
FindByModuleID(id uint64) (*types.Page, error)
Create(mod *types.Page) (*types.Page, error)
Update(mod *types.Page) (*types.Page, error)
DeleteByID(id uint64) error
Reorder(selfID uint64, pageIDs []uint64) error
}
page struct {
@@ -56,9 +58,9 @@ func (r *page) FindByModuleID(id uint64) (*types.Page, error) {
return page, nil
}
func (r *page) Find() ([]*types.Page, error) {
func (r *page) Find(selfID uint64) ([]*types.Page, error) {
pages := make([]*types.Page, 0)
if err := r.db().Select(&pages, "SELECT * FROM crm_page ORDER BY id ASC"); err != nil {
if err := r.db().Select(&pages, "SELECT * FROM crm_page where self_id=? ORDER BY weight ASC", selfID); err != nil {
return pages, err
}
for _, page := range pages {
@@ -69,15 +71,50 @@ func (r *page) Find() ([]*types.Page, error) {
return pages, nil
}
func (r *page) Create(page *types.Page) (*types.Page, error) {
func (r *page) Reorder(selfID uint64, pageIDs []uint64) error {
pageMap := map[uint64]bool{}
if pages, err := r.Find(selfID); err != nil {
return nil
} else {
for _, page := range pages {
pageMap[page.ID] = true
}
}
weight := 1
db := r.db()
// honor parameter first
for _, pageID := range pageIDs {
if pageMap[pageID] {
pageMap[pageID] = false
if _, err := db.Exec("UPDATE crm_page set weight=? where id=? and self_id=?", weight, pageID, selfID); err != nil {
return err
}
weight++
}
}
for pageID, update := range pageMap {
if update {
if _, err := db.Exec("UPDATE crm_page set weight=? where id=? and self_id=?", weight, pageID, selfID); err != nil {
return err
}
weight++
}
}
return nil
}
func (r *page) Create(item *types.Page) (*types.Page, error) {
page := &types.Page{}
*page = *item
page.ID = factory.Sonyflake.NextID()
if page.ModuleID > 0 {
check, err := r.FindByModuleID(page.ModuleID)
if err != nil {
if check, err := r.FindByModuleID(page.ModuleID); err != nil {
return nil, err
}
if check.ID > 0 {
return nil, errors.New("Page for module already exists")
} else {
if check.ID > 0 {
return nil, errors.New("Page for module already exists")
}
}
}
return page, r.db().Insert("crm_page", page)
+49 -7
View File
@@ -2,8 +2,12 @@ package repository
import (
"context"
"github.com/crusttech/crust/crm/types"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/pkg/errors"
"github.com/crusttech/crust/crm/types"
)
func TestPage(t *testing.T) {
@@ -24,12 +28,29 @@ func TestPage(t *testing.T) {
assert(t, err == nil, "Error when creating page: %+v", err)
assert(t, m.ID > 0, "Expected auto generated ID")
page.SelfID = m.ID
{
_, err := repository.Create(page)
assert(t, err != nil, "%+v", errors.Errorf("Expected error when creating duplicate moduleID page"))
}
{
page.ModuleID = 0
_, err := repository.Create(page)
assert(t, err == nil, "Unexpected error when creating page, %+v", err)
}
{
_, err := repository.Create(page)
assert(t, err == nil, "Unexpected error when creating page, %+v", err)
}
// fetch created page
{
ms, err := repository.FindByID(m.ID)
assert(t, err == nil, "Error when retrieving page by id: %+v", err)
assert(t, ms.ID == m.ID, "Expected ID from database to match, %d != %d", m.ID, ms.ID)
assert(t, ms.Title == m.Title, "Expected Title from database to match, %s != %s", m.Title, ms.Title)
assert(t, ms.ID == m.ID, "Expected ID from database to match, %+v", errors.Errorf("%d != %d", m.ID, ms.ID))
assert(t, ms.Title == m.Title, "Expected Title from database to match, %+v", errors.Errorf("%s != %s", m.Title, ms.Title))
}
// update created page
@@ -43,7 +64,7 @@ func TestPage(t *testing.T) {
{
ms, err := repository.FindByID(m.ID)
assert(t, err == nil, "Error when retrieving page by id: %+v", err)
assert(t, ms.ID == m.ID, "Expected ID from database to match, %d != %d", m.ID, ms.ID)
assert(t, ms.ID == m.ID, "re-fetch: Expected ID from database to match, %d != %d", m.ID, ms.ID)
assert(t, ms.Title == m.Title, "Expected Title from database to match, %s != %s", m.Title, ms.Title)
}
@@ -51,18 +72,39 @@ func TestPage(t *testing.T) {
{
ms, err := repository.FindByModuleID(m.ModuleID)
assert(t, err == nil, "Error when retrieving page by id: %+v", err)
assert(t, ms.ID == m.ID, "Expected ID from database to match, %d != %d", m.ID, ms.ID)
assert(t, ms.ID == m.ID, "fetch-module: Expected ID from database to match, %d != %d", m.ID, ms.ID)
assert(t, ms.Title == m.Title, "Expected Title from database to match, %s != %s", m.Title, ms.Title)
}
// fetch all pages
{
ms, err := repository.Find()
ms, err := repository.Find(0)
assert(t, err == nil, "Error when retrieving pages: %+v", err)
assert(t, len(ms) >= 1, "Expected at least one page, got %d", len(ms))
prevPageCount = len(ms)
}
// fetch all pages
{
ms, err := repository.Find(m.ID)
assert(t, err == nil, "Error when retrieving pages: %+v", err)
assert(t, len(ms) == 2, "Expected two pages with selfID=%d, got %v", m.ID, spew.Sdump(ms))
prevPageCount = len(ms)
parent := m.ID
ids := []uint64{ms[0].ID, ms[1].ID}
{
err := repository.Reorder(parent, ids)
assert(t, err == nil, "Error when reordering pages: %+v", err)
ms, err = repository.Find(m.ID)
assert(t, err == nil, "Error when retrieving pages: %+v", err)
assert(t, len(ms) == 2, "Expected two pages with selfID=%d, got %v", m.ID, spew.Sdump(ms))
assert(t, ms[0].Weight < ms[1].Weight, "Expected ascending order, %+v", errors.Errorf("%d < %d", ms[0].Weight, ms[1].Weight))
}
}
// re-fetch page
{
err := repository.DeleteByID(m.ID)
@@ -71,7 +113,7 @@ func TestPage(t *testing.T) {
// fetch all pages
{
ms, err := repository.Find()
ms, err := repository.Find(0)
assert(t, err == nil, "Error when retrieving pages: %+v", err)
assert(t, len(ms) < prevPageCount, "Expected pages count to decrease after deletion, %d < %d", len(ms), prevPageCount)
}
+5 -1
View File
@@ -21,7 +21,7 @@ func (Page) New(pageSvc service.PageService) *Page {
}
func (ctrl *Page) List(ctx context.Context, r *request.PageList) (interface{}, error) {
return ctrl.page.With(ctx).Find()
return ctrl.page.With(ctx).Find(r.SelfID)
}
func (ctrl *Page) Create(ctx context.Context, r *request.PageCreate) (interface{}, error) {
@@ -40,6 +40,10 @@ func (ctrl *Page) Read(ctx context.Context, r *request.PageRead) (interface{}, e
return ctrl.page.With(ctx).FindByID(r.ID)
}
func (ctrl *Page) Reorder(ctx context.Context, r *request.PageReorder) (interface{}, error) {
return resputil.OK(), ctrl.page.With(ctx).Reorder(r.SelfID, r.PageIDs)
}
func (ctrl *Page) Edit(ctx context.Context, r *request.PageEdit) (interface{}, error) {
p := &types.Page{
ID: r.ID,
+6
View File
@@ -32,6 +32,7 @@ var _ = multipart.FileHeader{}
// Page list request parameters
type PageList struct {
SelfID uint64 `json:",string"`
}
func NewPageList() *PageList {
@@ -65,6 +66,11 @@ func (p *PageList) Fill(r *http.Request) (err error) {
post[name] = string(param[0])
}
if val, ok := get["selfID"]; ok {
p.SelfID = parseUInt64(val)
}
return err
}
+9 -3
View File
@@ -20,11 +20,13 @@ type (
With(ctx context.Context) PageService
FindByID(pageID uint64) (*types.Page, error)
Find() ([]*types.Page, error)
Find(selfID uint64) ([]*types.Page, error)
Create(page *types.Page) (*types.Page, error)
Update(page *types.Page) (*types.Page, error)
DeleteByID(pageID uint64) error
Reorder(selfID uint64, pageIDs []uint64) error
}
)
@@ -45,8 +47,12 @@ func (s *page) FindByID(id uint64) (*types.Page, error) {
return s.repository.FindByID(id)
}
func (s *page) Find() ([]*types.Page, error) {
return s.repository.Find()
func (s *page) Find(selfID uint64) ([]*types.Page, error) {
return s.repository.Find(selfID)
}
func (s *page) Reorder(selfID uint64, pageIDs []uint64) error {
return s.repository.Reorder(selfID, pageIDs)
}
func (s *page) Create(mod *types.Page) (*types.Page, error) {