diff --git a/packages/actions/src/__tests__/actions/list1.ts b/packages/actions/src/__tests__/actions/list1.ts new file mode 100644 index 000000000..a38e75d9d --- /dev/null +++ b/packages/actions/src/__tests__/actions/list1.ts @@ -0,0 +1,17 @@ +import { ActionOptions } from '@nocobase/resourcer'; +import { list } from '../../actions/common'; + +const now = new Date(); +const before7Days = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7); + +export default { + filter: { + status: 'published', + published_at: { + gte: before7Days.toISOString(), + lt: now.toISOString() + } + }, + + handler: list +} as ActionOptions; diff --git a/packages/actions/src/__tests__/index.ts b/packages/actions/src/__tests__/index.ts index 696141bc1..3f0582e99 100644 --- a/packages/actions/src/__tests__/index.ts +++ b/packages/actions/src/__tests__/index.ts @@ -11,6 +11,7 @@ import Resourcer from '@nocobase/resourcer'; import associated from '../middlewares/associated'; import actions from '..'; +import list1 from './actions/list1'; import create1 from './actions/create1'; import create2 from './actions/create2'; import update1 from './actions/update1'; @@ -61,6 +62,7 @@ resourcer.define({ name: 'posts', actions: { ...actions.common, + list1, create1, create2, update1, diff --git a/packages/actions/src/__tests__/list.test.ts b/packages/actions/src/__tests__/list.test.ts index f204da686..3faedbfe4 100644 --- a/packages/actions/src/__tests__/list.test.ts +++ b/packages/actions/src/__tests__/list.test.ts @@ -4,13 +4,17 @@ import { initDatabase, agent } from './index'; describe('list', () => { let db; - let now: string; - let timestamps: { created_at: string; updated_at: string; }; + let now: Date; + let nowString: string; + let timestamps: { created_at: Date; updated_at: Date; }; + let timestampsStrings; beforeEach(async () => { db = await initDatabase(); - now = (new Date()).toISOString(); + now = new Date(); + nowString = now.toISOString() timestamps = { created_at: now, updated_at: now }; + timestampsStrings = { created_at: nowString, updated_at: nowString }; }); afterAll(() => db.close()); @@ -29,7 +33,7 @@ describe('list', () => { await Post.bulkCreate(Array(25).fill(null).map((_, index) => ({ title: `title${index}`, status: index % 2 ? 'published' : 'draft', - published_at: index % 2 ? new Date(2020, 10, 30 - index, 0, 0, 0) : null, + published_at: index % 2 ? new Date(now.getFullYear(), now.getMonth(), now.getDate() - index, 0, 0, 0) : null, user_id: users[index % users.length].id, ...timestamps }))); @@ -122,6 +126,21 @@ describe('list', () => { expect(response.body.count).toBe(expected.length); }); }); + + describe('merge params with action options', () => { + it('plain key-value filter', async () => { + const response = await agent.get('/posts:list1?filter[status]=draft'); + expect(response.body.count).toBe(0); + }); + + it('date filter', async () => { + // const before1Days = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1); + const before3Days = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 3); + const response = await agent.get(`/posts:list1?filter[published_at.gt]=${before3Days.toISOString()}`); + expect(response.body.count).toBe(1); + expect(response.body.rows[0].id).toBe(2); + }); + }) }); describe('page', () => { @@ -258,7 +277,7 @@ describe('list', () => { it('appends fields', async () => { const response = await agent.get('/posts?fields[only]=title&fields[appends]=user.name&filter[title]=title0'); expect(response.body.rows[0].user.name).toEqual('a'); - expect(response.body.rows).toEqual([{ title: 'title0', user: { id: 1, name: 'a', ...timestamps } }]); + expect(response.body.rows).toEqual([{ title: 'title0', user: { id: 1, name: 'a', ...timestampsStrings } }]); }); }); }); @@ -377,9 +396,6 @@ describe('list', () => { page: 2, per_page: 2 }); - }); - - + }); }); - }); diff --git a/packages/resourcer/src/__tests__/koa.test.ts b/packages/resourcer/src/__tests__/koa.test.ts index e26e58680..382b0ea8f 100644 --- a/packages/resourcer/src/__tests__/koa.test.ts +++ b/packages/resourcer/src/__tests__/koa.test.ts @@ -227,7 +227,10 @@ describe('koa middleware', () => { }); expect(response.body).toEqual({ sort: '-id', - filter: { col1: 'val1', col2: 'val2', col3: 'val3' }, + filter: { and: [ + { col1: 'val1', col2: 'val2' }, + { col2: '&val2', col3: 'val3' } + ]}, fields: { only: [ 'id' ], appends: [] }, other: 'other1', actionName: 'list', diff --git a/packages/resourcer/src/action.ts b/packages/resourcer/src/action.ts index 536d27a84..d908223eb 100644 --- a/packages/resourcer/src/action.ts +++ b/packages/resourcer/src/action.ts @@ -284,7 +284,9 @@ export class Action { // optionsFilter = await optionsFilter(this.context); // } if (!_.isEmpty(optionsFilter) || !_.isEmpty(filter)) { - data.filter = _.merge(filter, _.cloneDeep(optionsFilter)); + const filterOptions = [_.cloneDeep(optionsFilter), filter].filter(Boolean); + // TODO(feature): change 'and' to symbol + data.filter = filterOptions.length > 1 ? { and: filterOptions } : filterOptions[0]; } // if (typeof optionsFields === 'function') { // this.parameters = _.cloneDeep(data);