fix: use wrapped and logic for merging filters (#42)

This commit is contained in:
Junyi 2020-12-14 22:07:23 +08:00 committed by GitHub
parent a687e1e1e3
commit 7fcce0943a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 11 deletions

View File

@ -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;

View File

@ -11,6 +11,7 @@ import Resourcer from '@nocobase/resourcer';
import associated from '../middlewares/associated'; import associated from '../middlewares/associated';
import actions from '..'; import actions from '..';
import list1 from './actions/list1';
import create1 from './actions/create1'; import create1 from './actions/create1';
import create2 from './actions/create2'; import create2 from './actions/create2';
import update1 from './actions/update1'; import update1 from './actions/update1';
@ -61,6 +62,7 @@ resourcer.define({
name: 'posts', name: 'posts',
actions: { actions: {
...actions.common, ...actions.common,
list1,
create1, create1,
create2, create2,
update1, update1,

View File

@ -4,13 +4,17 @@ import { initDatabase, agent } from './index';
describe('list', () => { describe('list', () => {
let db; let db;
let now: string; let now: Date;
let timestamps: { created_at: string; updated_at: string; }; let nowString: string;
let timestamps: { created_at: Date; updated_at: Date; };
let timestampsStrings;
beforeEach(async () => { beforeEach(async () => {
db = await initDatabase(); db = await initDatabase();
now = (new Date()).toISOString(); now = new Date();
nowString = now.toISOString()
timestamps = { created_at: now, updated_at: now }; timestamps = { created_at: now, updated_at: now };
timestampsStrings = { created_at: nowString, updated_at: nowString };
}); });
afterAll(() => db.close()); afterAll(() => db.close());
@ -29,7 +33,7 @@ describe('list', () => {
await Post.bulkCreate(Array(25).fill(null).map((_, index) => ({ await Post.bulkCreate(Array(25).fill(null).map((_, index) => ({
title: `title${index}`, title: `title${index}`,
status: index % 2 ? 'published' : 'draft', 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, user_id: users[index % users.length].id,
...timestamps ...timestamps
}))); })));
@ -122,6 +126,21 @@ describe('list', () => {
expect(response.body.count).toBe(expected.length); 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', () => { describe('page', () => {
@ -258,7 +277,7 @@ describe('list', () => {
it('appends fields', async () => { it('appends fields', async () => {
const response = await agent.get('/posts?fields[only]=title&fields[appends]=user.name&filter[title]=title0'); 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[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, page: 2,
per_page: 2 per_page: 2
}); });
}); });
}); });
}); });

View File

@ -227,7 +227,10 @@ describe('koa middleware', () => {
}); });
expect(response.body).toEqual({ expect(response.body).toEqual({
sort: '-id', sort: '-id',
filter: { col1: 'val1', col2: 'val2', col3: 'val3' }, filter: { and: [
{ col1: 'val1', col2: 'val2' },
{ col2: '&val2', col3: 'val3' }
]},
fields: { only: [ 'id' ], appends: [] }, fields: { only: [ 'id' ], appends: [] },
other: 'other1', other: 'other1',
actionName: 'list', actionName: 'list',

View File

@ -284,7 +284,9 @@ export class Action {
// optionsFilter = await optionsFilter(this.context); // optionsFilter = await optionsFilter(this.context);
// } // }
if (!_.isEmpty(optionsFilter) || !_.isEmpty(filter)) { 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') { // if (typeof optionsFields === 'function') {
// this.parameters = _.cloneDeep(data); // this.parameters = _.cloneDeep(data);