From c0c4e5af4a268fa6d1333b9825de7d5c1ab4d60a Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Thu, 16 Apr 2020 20:17:46 +0200 Subject: [PATCH] feat: edit details, roles and columns of custom view. --- server/src/http/controllers/Views.js | 169 +++++++- server/src/models/ViewColumn.js | 23 + server/tests/routes/views.test.js | 458 ++++++++++++++++---- server/tests/services/JournalPoster.test.js | 2 +- 4 files changed, 555 insertions(+), 97 deletions(-) diff --git a/server/src/http/controllers/Views.js b/server/src/http/controllers/Views.js index a0f145ba0..c10b90bf1 100644 --- a/server/src/http/controllers/Views.js +++ b/server/src/http/controllers/Views.js @@ -1,4 +1,4 @@ -import { difference, pick } from 'lodash'; +import { difference, intersection, pick } from 'lodash'; import express from 'express'; import { check, @@ -14,7 +14,7 @@ import View from '@/models/View'; import ViewRole from '@/models/ViewRole'; import ViewColumn from '@/models/ViewColumn'; import { - validateViewLogicExpression, + validateViewRoles, } from '@/lib/ViewRolesBuilder'; export default { @@ -161,7 +161,7 @@ export default { code: 'validation_error', ...validationErrors, }); } - const form = { ...req.body }; + const form = { roles: [], ...req.body }; const resource = await Resource.query().where('name', form.resource_name).first(); if (!resource) { @@ -190,7 +190,7 @@ export default { errorReasons.push({ type: 'COLUMNS_NOT_EXIST', code: 200, columns: notFoundColumns }); } // Validates the view conditional logic expression. - if (!validateViewLogicExpression(form.logic_expression, form.roles.map((r) => r.index))) { + if (!validateViewRoles(form.roles, form.logic_expression)) { errorReasons.push({ type: 'VIEW.ROLES.LOGIC.EXPRESSION.INVALID', code: 400 }); } if (errorReasons.length > 0) { @@ -234,13 +234,24 @@ export default { }, }, + /** + * Edit the given custom view metadata. + */ editView: { validation: [ param('view_id').exists().isNumeric().toInt(), - check('label').exists().escape().trim(), - check('columns').isArray({ min: 3 }), + check('name').exists().escape().trim(), + check('logic_expression').exists().trim().escape(), + + check('columns').exists().isArray({ min: 1 }), + + check('columns.*.id').optional().isNumeric().toInt(), + check('columns.*.key').exists().escape().trim(), + check('columns.*.index').exists().isNumeric().toInt(), + check('roles').isArray(), - check('roles.*.field').exists().escape().trim(), + check('roles.*.id').optional().isNumeric().toInt(), + check('roles.*.field_key').exists().escape().trim(), check('roles.*.comparator').exists(), check('roles.*.value').exists(), check('roles.*.index').exists().isNumeric().toInt(), @@ -254,13 +265,155 @@ export default { code: 'validation_error', ...validationErrors, }); } - const view = await View.where('id', viewId).fetch(); + const view = await View.query().where('id', viewId) + .withGraphFetched('roles.field') + .withGraphFetched('columns') + .first(); if (!view) { return res.boom.notFound(null, { errors: [{ type: 'ROLE_NOT_FOUND', code: 100 }], }); } + const form = { ...req.body }; + const resource = await Resource.query() + .where('id', view.resourceId) + .withGraphFetched('fields') + .withGraphFetched('views') + .first(); + + const errorReasons = []; + const fieldsSlugs = form.roles.map((role) => role.field_key); + const resourceFieldsKeys = resource.fields.map((f) => f.key); + const resourceFieldsKeysMap = new Map(resource.fields.map((field) => [field.key, field])); + const columnsKeys = form.columns.map((c) => c.key); + + // The difference between the stored resource fields and submit fields keys. + const notFoundFields = difference(fieldsSlugs, resourceFieldsKeys); + + // Validate not found resource fields keys. + if (notFoundFields.length > 0) { + errorReasons.push({ + type: 'RESOURCE_FIELDS_NOT_EXIST', code: 100, fields: notFoundFields, + }); + } + // The difference between the stored resource fields and the submit columns keys. + const notFoundColumns = difference(columnsKeys, resourceFieldsKeys); + + // Validate not found view columns. + if (notFoundColumns.length > 0) { + errorReasons.push({ type: 'RESOURCE_COLUMNS_NOT_EXIST', code: 200, columns: notFoundColumns }); + } + // Validates the view conditional logic expression. + if (!validateViewRoles(form.roles, form.logic_expression)) { + errorReasons.push({ type: 'VIEW.ROLES.LOGIC.EXPRESSION.INVALID', code: 400 }); + } + + const viewRolesIds = view.roles.map((r) => r.id); + const viewColumnsIds = view.columns.map((c) => c.id); + + const formUpdatedRoles = form.roles.filter((r) => r.id); + const formInsertRoles = form.roles.filter((r) => !r.id); + + const formRolesIds = formUpdatedRoles.map((r) => r.id); + + const formUpdatedColumns = form.columns.filter((r) => r.id); + const formInsertedColumns = form.columns.filter((r) => !r.id); + const formColumnsIds = formUpdatedColumns.map((r) => r.id); + + const rolesIdsShouldDeleted = difference(viewRolesIds, formRolesIds); + const columnsIdsShouldDelete = difference(viewColumnsIds, formColumnsIds); + + const notFoundViewRolesIds = difference(formRolesIds, viewRolesIds); + const notFoundViewColumnsIds = difference(viewColumnsIds, viewColumnsIds); + + // Validate the not found view roles ids. + if (notFoundViewRolesIds.length) { + errorReasons.push({ type: 'VIEW.ROLES.IDS.NOT.FOUND', code: 500, ids: notFoundViewRolesIds }); + } + // Validate the not found view columns ids. + if (notFoundViewColumnsIds.length) { + errorReasons.push({ type: 'VIEW.COLUMNS.IDS.NOT.FOUND', code: 600, ids: notFoundViewColumnsIds }); + } + if (errorReasons.length > 0) { + return res.status(400).send({ errors: errorReasons }); + } + const asyncOpers = []; + + // Save view details. + await View.query() + .where('id', view.id) + .patch({ + name: form.name, + roles_logic_expression: form.logic_expression, + }); + + // Update view roles. + if (formUpdatedRoles.length > 0) { + formUpdatedRoles.forEach((role) => { + const fieldModel = resourceFieldsKeysMap.get(role.field_key); + const updateOper = ViewRole.query() + .where('id', role.id) + .update({ + ...pick(role, ['comparator', 'value', 'index']), + field_id: fieldModel.id, + }); + asyncOpers.push(updateOper); + }); + } + // Insert a new view roles. + if (formInsertRoles.length > 0) { + formInsertRoles.forEach((role) => { + const fieldModel = resourceFieldsKeysMap.get(role.field_key); + const insertOper = ViewRole.query() + .insert({ + ...pick(role, ['comparator', 'value', 'index']), + field_id: fieldModel.id, + view_id: view.id, + }); + asyncOpers.push(insertOper); + }); + } + // Delete view roles. + if (rolesIdsShouldDeleted.length > 0) { + const deleteOper = ViewRole.query() + .where('id', rolesIdsShouldDeleted) + .delete(); + asyncOpers.push(deleteOper); + } + // Insert a new view columns to the storage. + if (formInsertedColumns.length > 0) { + formInsertedColumns.forEach((column) => { + const fieldModel = resourceFieldsKeysMap.get(column.key); + const insertOper = ViewColumn.query() + .insert({ + field_id: fieldModel.id, + index: column.index, + view_id: view.id, + }); + asyncOpers.push(insertOper); + }); + } + // Update the view columns on the storage. + if (formUpdatedColumns.length > 0) { + formUpdatedColumns.forEach((column) => { + const updateOper = ViewColumn.query() + .where('id', column.id) + .update({ + index: column.index, + }); + asyncOpers.push(updateOper); + }); + } + // Delete the view columns from the storage. + if (columnsIdsShouldDelete.length > 0) { + const deleteOper = ViewColumn.query() + .whereIn('id', columnsIdsShouldDelete) + .delete(); + asyncOpers.push(deleteOper); + } + await Promise.all(asyncOpers); + return res.status(200).send(); }, }, diff --git a/server/src/models/ViewColumn.js b/server/src/models/ViewColumn.js index 2364e7150..d5db7efd3 100644 --- a/server/src/models/ViewColumn.js +++ b/server/src/models/ViewColumn.js @@ -1,3 +1,4 @@ +import { Model } from 'objection'; import BaseModel from '@/models/Model'; export default class ViewColumn extends BaseModel { @@ -14,4 +15,26 @@ export default class ViewColumn extends BaseModel { static get hasTimestamps() { return false; } + + + /** + * Relationship mapping. + */ + static get relationMappings() { + const ResourceField = require('@/models/ResourceField'); + + return { + /** + * View role model may belongs to resource field model. + */ + field: { + relation: Model.BelongsToOneRelation, + modelClass: ResourceField.default, + join: { + from: 'view_columns.fieldId', + to: 'resource_fields.id', + }, + }, + }; + } } diff --git a/server/tests/routes/views.test.js b/server/tests/routes/views.test.js index e82ede2b7..9fa1b1910 100644 --- a/server/tests/routes/views.test.js +++ b/server/tests/routes/views.test.js @@ -11,7 +11,7 @@ import ViewColumn from '../../src/models/ViewColumn'; let loginRes; -describe('routes: `/views`', () => { +describe.only('routes: `/views`', () => { beforeEach(async () => { loginRes = await login(); }); @@ -41,8 +41,6 @@ describe('routes: `/views`', () => { .query({ resource_name: 'resource_name' }) .send(); - // console.log(res.body); - expect(res.status).equals(200); expect(res.body.views.length).equals(1); }); @@ -116,11 +114,11 @@ describe('routes: `/views`', () => { expect(res.status).equals(200); expect(res.body.view.name).equals(resourceView.name); - expect(res.body.view.resourceId).equals(resourceView.resourceId); - expect(res.body.view.rolesLogicExpression).equals(resourceView.rolesLogicExpression); + expect(res.body.view.resource_id).equals(resourceView.resourceId); + expect(res.body.view.roles_logic_expression).equals(resourceView.rolesLogicExpression); - expect(res.body.view.viewRoles.length).equals(1); - expect(res.body.view.viewRoles[0].viewId).equals(viewRole.viewId); + expect(res.body.view.roles.length).equals(1); + expect(res.body.view.roles[0].view_id).equals(viewRole.viewId); }); }); @@ -132,7 +130,7 @@ describe('routes: `/views`', () => { expect(res.body.message).equals('unauthorized'); }); - it('Should `label` be required.', async () => { + it('Should `name` be required.', async () => { await create('resource'); const res = await request() .post('/api/views') @@ -141,7 +139,7 @@ describe('routes: `/views`', () => { expect(res.status).equals(422); expect(res.body.code).equals('validation_error'); expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'label', location: 'body', + msg: 'Invalid value', param: 'name', location: 'body', }); }); @@ -255,7 +253,7 @@ describe('routes: `/views`', () => { .set('x-access-token', loginRes.body.token) .send({ resource_name: 'not_found', - label: 'View Label', + name: 'View Label', columns: [ { key: 'amount', index: 1 }, { key: 'thumbnail', index: 1 }, @@ -267,6 +265,7 @@ describe('routes: `/views`', () => { comparator: 'equals', value: '100', }], + logic_expression: '1', }); expect(res.status).equals(404); @@ -288,7 +287,7 @@ describe('routes: `/views`', () => { .send({ resource_name: resource.name, logic_expression: '100 && 100', - label: 'View Label', + name: 'View Label', columns: [ { key: 'amount', index: 1 }, ], @@ -303,7 +302,7 @@ describe('routes: `/views`', () => { expect(res.body.errors).include.something.that.deep.equals({ type: 'VIEW.ROLES.LOGIC.EXPRESSION.INVALID', code: 400, }); - }) + }); it('Should response the roles fields not exist in case role field was not exist.', async () => { const resource = await create('resource'); @@ -314,7 +313,8 @@ describe('routes: `/views`', () => { .set('x-access-token', loginRes.body.token) .send({ resource_name: resource.name, - label: 'View Label', + name: 'View Label', + logic_expression: '1', columns: [ { key: 'amount', index: 1 }, { key: 'thumbnail', index: 1 }, @@ -345,7 +345,8 @@ describe('routes: `/views`', () => { .set('x-access-token', loginRes.body.token) .send({ resource_name: resource.name, - label: 'View Label', + name: 'View Label', + logic_expression: '1', columns: [ { key: 'amount', index: 1 }, { key: 'thumbnail', index: 2 }, @@ -376,7 +377,8 @@ describe('routes: `/views`', () => { .set('x-access-token', loginRes.body.token) .send({ resource_name: resource.name, - label: 'View Label', + name: 'View Label', + logic_expression: '1', columns: [ { key: 'amount', index: 1 }, ], @@ -405,19 +407,20 @@ describe('routes: `/views`', () => { const res = await request() .post('/api/views') + .set('x-access-token', loginRes.body.token) .send({ resource_name: resource.name, - label: 'View Label', + name: 'View Label', columns: [{ key: 'amount', index: 1 }], + logic_expression: '1', roles: [{ index: 1, field_key: 'amount', comparator: 'equals', value: '100', }], - }) - .set('x-access-token', loginRes.body.token); - + }); + const viewRoles = await ViewRole.query().where('view_id', res.body.id); expect(viewRoles.length).equals(1); @@ -440,7 +443,8 @@ describe('routes: `/views`', () => { .set('x-access-token', loginRes.body.token) .send({ resource_name: resource.name, - label: 'View Label', + name: 'View Label', + logic_expression: '1', columns: [ { key: 'amount', index: 1 }, ], @@ -455,103 +459,111 @@ describe('routes: `/views`', () => { const viewColumns = await ViewColumn.query().where('view_id', res.body.id); expect(viewColumns.length).equals(1); }); + + }); - describe('POST: `/views/:view_id`', () => { - it('Should `label` be required.', async () => { + describe.only('POST: `/views/:view_id`', () => { + it('Should `name` be required.', async () => { const view = await create('view'); - const res = await request().post(`/api/views/${view.id}`); + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send(); expect(res.status).equals(422); expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('label'); + expect(res.body.errors).include.something.deep.equals({ + msg: 'Invalid value', param: 'name', location: 'body', + }); }); it('Should columns be minimum limited', async () => { const view = await create('view'); - const res = await request().post(`/api/views/${view.id}`, { - label: 'View Label', - columns: [], - }); + const res = await request() + .post(`/api/views/${view.id}`, { + label: 'View Label', + columns: [], + }) + .set('x-access-token', loginRes.body.token) + .send(); expect(res.status).equals(422); expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('columns'); + expect(res.body.errors).include.something.deep.equals({ + msg: 'Invalid value', param: 'columns', location: 'body', + }); }); it('Should columns be array.', async () => { const view = await create('view'); - const res = await request().post(`/api/views/${view.id}`, { - label: 'View Label', - columns: 'not_array', - }); + const res = await request() + .post(`/api/views/${view.id}`, { + label: 'View Label', + columns: 'not_array', + }) + .set('x-access-token', loginRes.body.token) + .send(); expect(res.status).equals(422); expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('columns'); + expect(res.body.errors).include.something.deep.equals({ + msg: 'Invalid value', param: 'code', location: 'body', + }); }); - it('Should `roles.*.field` be required.', async () => { + it('Should `roles.*.field_key` be required.', async () => { const view = await create('view'); - const res = await request().post(`/api/views/${view.id}`).send({ - label: 'View Label', - roles: [{}], - }); + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + label: 'View Label', + roles: [{}], + }); expect(res.status).equals(422); expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('roles[0].field'); + expect(res.body.errors).include.something.deep.equals({ + msg: 'Invalid value', param: 'roles', location: 'body', + }); }); - it('Should `roles.*.comparator` be valid.', async () => { + it('Should `roles.*.comparator` be required.', async () => { const view = await create('view'); - const res = await request().post(`/api/views/${view.id}`).send({ - label: 'View Label', - roles: [{}], - }); + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + label: 'View Label', + roles: [{}], + }); expect(res.status).equals(422); expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('roles[0].comparator'); + expect(res.body.errors).include.something.deep.equals({ + msg: 'Invalid value', param: 'roles[0].comparator', location: 'body', + }); }); it('Should `roles.*.index` be number as integer.', async () => { const view = await create('view'); - const res = await request().post(`/api/views/${view.id}`).send({ - label: 'View Label', - roles: [{ index: 'not_numeric' }], - }); + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + label: 'View Label', + roles: [{ index: 'not_numeric' }], + }); expect(res.status).equals(422); expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('roles[0].index'); - }); - - it('Should response not found in case resource was not exist.', async () => { - const res = await request().post('/api/views/100').send({ - label: 'View Label', - columns: ['amount', 'thumbnail', 'status'], - roles: [{ - index: 1, - field: 'amount', - comparator: 'equals', - value: '100', - }], + expect(res.body.errors).include.something.deep.equals({ + msg: 'Invalid value', + param: 'roles[0].index', + location: 'body', + value: 'not_numeric', }); - - expect(res.status).equals(404); }); it('Should response the roles fields not exist in case role field was not exist.', async () => { @@ -560,21 +572,291 @@ describe('routes: `/views`', () => { resource_id: view.resource_id, label_name: 'Amount', }); - const res = await request().post(`/api/views/${view.id}`).send({ - label: 'View Label', - columns: ['amount', 'thumbnail', 'status'], - roles: [{ - index: 1, - field: 'price', - comparator: 'equals', - value: '100', - }], - }); - + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + key: 'amount', + index: 1, + }, { + key: 'thumbnail', + index: 2, + }, { + key: 'status', + index: 3, + }], + roles: [{ + index: 1, + field_key: 'price', + comparator: 'equals', + value: '100', + }], + }); expect(res.body.errors).include.something.that.deep.equals({ type: 'RESOURCE_FIELDS_NOT_EXIST', code: 100, fields: ['price'], }); }); + + it('Should response the resource columns not exists in case the column keys was not exist.', async () => { + const view = await create('view'); + await create('resource_field', { + resource_id: view.resource_id, + label_name: 'Amount', + }); + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + key: 'amount', + index: 1, + }, { + key: 'thumbnail', + index: 2, + }, { + key: 'status', + index: 3, + }], + roles: [{ + index: 1, + field_key: 'price', + comparator: 'equals', + value: '100', + }], + }); + expect(res.body.errors).include.something.that.deep.equals({ + type: 'RESOURCE_COLUMNS_NOT_EXIST', + code: 200, + columns: ['amount', 'thumbnail', 'status'], + }); + }); + + it('Should validate the logic expressions with the given conditions.', () => { + + }); + + it('Should delete the view roles that not presented the post data.', async () => { + const resource = await create('resource'); + const resourceField = await create('resource_field', { + resource_id: resource.id, + label_name: 'Amount', + key: 'amount', + }); + + const view = await create('view', { resource_id: resource.id }); + const viewRole = await create('view_role', { + view_id: view.id, + field_id: resourceField.id, + }); + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + key: resourceField.key, + index: 1, + }], + roles: [{ + index: 1, + field_key: resourceField.key, + comparator: 'equals', + value: '100', + }], + }); + + const foundViewRole = await ViewRole.query().where('id', viewRole.id); + expect(foundViewRole.length).equals(0); + }); + + it('Should update the view roles that presented in the given data.', async () => { + const resource = await create('resource'); + const resourceField = await create('resource_field', { + resource_id: resource.id, + label_name: 'Amount', + key: 'amount', + }); + + const view = await create('view', { resource_id: resource.id }); + const viewRole = await create('view_role', { + view_id: view.id, + field_id: resourceField.id, + }); + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + key: resourceField.key, + index: 1, + }], + roles: [{ + id: viewRole.id, + index: 1, + field_key: resourceField.key, + comparator: 'equals', + value: '100', + }], + }); + + const foundViewRole = await ViewRole.query().where('id', viewRole.id); + + expect(foundViewRole.length).equals(1); + expect(foundViewRole[0].id).equals(1); + expect(foundViewRole[0].index).equals(1); + expect(foundViewRole[0].value).equals('100'); + expect(foundViewRole[0].comparator).equals('equals'); + }); + + it('Should response not found roles ids in case not exists in the storage.', async () => { + const resource = await create('resource'); + const resourceField = await create('resource_field', { + resource_id: resource.id, + label_name: 'Amount', + key: 'amount', + }); + const view = await create('view', { resource_id: resource.id }); + + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + key: resourceField.key, + index: 1, + }], + roles: [{ + id: 1, + index: 1, + field_key: resourceField.key, + comparator: 'equals', + value: '100', + }], + }); + + expect(res.body.errors).include.something.that.deep.equals({ + type: 'VIEW.ROLES.IDS.NOT.FOUND', code: 500, ids: [1], + }); + }); + + it('Should delete columns from storage in case view columns ids not presented.', async () => { + const resource = await create('resource'); + const resourceField = await create('resource_field', { + resource_id: resource.id, + label_name: 'Amount', + key: 'amount', + }); + const view = await create('view', { resource_id: resource.id }); + const viewColumn = await create('view_column', { view_id: view.id }); + + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + key: resourceField.key, + index: 1, + }], + roles: [{ + index: 1, + field_key: resourceField.key, + comparator: 'equals', + value: '100', + }], + }); + + // console.log(res.status, res.body); + const foundViewColumns = await ViewColumn.query().where('id', viewColumn.id); + expect(foundViewColumns.length).equals(0); + }); + + it('Should insert columns to the storage if where new columns', async () => { + const resource = await create('resource'); + const resourceField = await create('resource_field', { + resource_id: resource.id, + label_name: 'Amount', + key: 'amount', + }); + const view = await create('view', { resource_id: resource.id }); + + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + key: resourceField.key, + index: 1, + }], + roles: [{ + index: 1, + field_key: resourceField.key, + comparator: 'equals', + value: '100', + }], + }); + + const foundViewColumns = await ViewColumn.query().where('view_id', view.id); + + expect(foundViewColumns.length).equals(1); + expect(foundViewColumns[0].viewId).equals(view.id); + expect(foundViewColumns[0].index).equals(1); + expect(foundViewColumns[0].fieldId).equals(resourceField.id); + }); + + + it('Should update columns on the storage.', async () => { + const resource = await create('resource'); + const resourceField = await create('resource_field', { + resource_id: resource.id, + label_name: 'Amount', + key: 'amount', + }); + const view = await create('view', { resource_id: resource.id }); + const viewColumn = await create('view_column', { view_id: view.id }); + + const res = await request() + .post(`/api/views/${view.id}`) + .set('x-access-token', loginRes.body.token) + .send({ + name: 'View Label', + logic_expression: '1', + columns: [{ + id: viewColumn.id, + key: resourceField.key, + index: 10, + }], + roles: [{ + index: 1, + field_key: resourceField.key, + comparator: 'equals', + value: '100', + }], + }); + + console.log(res.body) + + const foundViewColumns = await ViewColumn.query().where('id', viewColumn.id); + + expect(foundViewColumns.length).equals(1); + expect(foundViewColumns[0].id).equals(viewColumn.id); + expect(foundViewColumns[0].viewId).equals(view.id); + expect(foundViewColumns[0].index).equals(10); + // expect(foundViewColumns[0].fieldId).equals(); + }) }); describe('DELETE: `/views/:resource_id`', () => { diff --git a/server/tests/services/JournalPoster.test.js b/server/tests/services/JournalPoster.test.js index 63df39a37..16c137135 100644 --- a/server/tests/services/JournalPoster.test.js +++ b/server/tests/services/JournalPoster.test.js @@ -220,7 +220,7 @@ describe('JournalPoster', () => { }); - describe.only('removeEntries', () => { + describe('removeEntries', () => { it('Should remove all entries in the collection.', () => { const journalPoster = new JournalPoster(); const journalEntry1 = new JournalEntry({