fix Collection rest api (#205)
* test: collections rest api * test: add more test cases * fix: test case * fix: Error: src/schema-component/antd/array-table/TableRecordActionDesigner.tsx(3,38): error TS2307: Cannot find module '@nocobase/client' or its corresponding type declarations. * fix: belongsToMany create with empty value * fix: relation query test * test: appends + sort * fix: belongsToMany find error * fix: add cleanDb to fix database test * fix: mysql test Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
2caec7a271
commit
9dd590c459
@ -7,8 +7,11 @@ describe('belongs to many with target key', function () {
|
||||
let db: Database;
|
||||
let Tag: Collection;
|
||||
let Post: Collection;
|
||||
let Color: Collection;
|
||||
|
||||
beforeEach(async () => {
|
||||
db = mockDatabase();
|
||||
|
||||
Post = db.collection({
|
||||
name: 'posts',
|
||||
filterTargetKey: 'title',
|
||||
@ -114,6 +117,7 @@ describe('belongs to many', () => {
|
||||
let Post;
|
||||
let Tag;
|
||||
let PostTag;
|
||||
let Color;
|
||||
|
||||
beforeEach(async () => {
|
||||
db = mockDatabase();
|
||||
@ -154,6 +158,15 @@ describe('belongs to many', () => {
|
||||
{ type: 'belongsToMany', name: 'posts', through: 'posts_tags' },
|
||||
{ type: 'string', name: 'name' },
|
||||
{ type: 'string', name: 'status' },
|
||||
{ type: 'hasMany', name: 'colors' },
|
||||
],
|
||||
});
|
||||
|
||||
Color = db.collection({
|
||||
name: 'colors',
|
||||
fields: [
|
||||
{ type: 'string', name: 'name' },
|
||||
{ type: 'belongsTo', name: 'tag' },
|
||||
],
|
||||
});
|
||||
|
||||
@ -269,6 +282,35 @@ describe('belongs to many', () => {
|
||||
expect(t1).toBeNull();
|
||||
});
|
||||
|
||||
test('find with sort & appends', async () => {
|
||||
const p1 = await Post.repository.create({
|
||||
values: {
|
||||
title: 'p1',
|
||||
tags: [
|
||||
{
|
||||
name: 't1',
|
||||
colors: [
|
||||
{
|
||||
name: 'red',
|
||||
},
|
||||
],
|
||||
},
|
||||
{ name: 't2', colors: [{ name: 'green' }] },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const PostTagsRepository = new BelongsToManyRepository(Post, 'tags', p1.id);
|
||||
const tags = await PostTagsRepository.find({
|
||||
appends: ['colors'],
|
||||
sort: ['name'],
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
});
|
||||
|
||||
console.log(tags);
|
||||
});
|
||||
|
||||
test('update raw attribute', async () => {
|
||||
const otherTag = await Tag.repository.create({
|
||||
values: { name: 'other_tag' },
|
||||
|
@ -33,7 +33,8 @@ export class BelongsToManyRepository extends MultipleRelationRepository implemen
|
||||
const transaction = await this.getTransaction(options);
|
||||
|
||||
const createAccessor = this.accessors().create;
|
||||
const values = options.values;
|
||||
|
||||
const values = options.values || {};
|
||||
|
||||
const sourceModel = await this.getSourceModel(transaction);
|
||||
|
||||
|
@ -32,11 +32,14 @@ export abstract class MultipleRelationRepository extends RelationRepository {
|
||||
async find(options?: FindOptions): Promise<any> {
|
||||
const transaction = await this.getTransaction(options);
|
||||
|
||||
const findOptions = this.extendFindOptions(
|
||||
const findOptions = {
|
||||
...this.extendFindOptions(
|
||||
this.buildQueryOptions({
|
||||
...options,
|
||||
}),
|
||||
);
|
||||
),
|
||||
subQuery: false,
|
||||
};
|
||||
|
||||
const getAccessor = this.accessors().get;
|
||||
const sourceModel = await this.getSourceModel(transaction);
|
||||
@ -44,7 +47,7 @@ export abstract class MultipleRelationRepository extends RelationRepository {
|
||||
if (findOptions.include && findOptions.include.length > 0) {
|
||||
const ids = (
|
||||
await sourceModel[getAccessor]({
|
||||
...omit(findOptions, 'order'),
|
||||
...findOptions,
|
||||
includeIgnoreAttributes: false,
|
||||
attributes: [this.targetKey()],
|
||||
group: `${this.targetModel.name}.${this.targetKey()}`,
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { flatten } from 'flat';
|
||||
import lodash, { keys } from 'lodash';
|
||||
|
||||
import { Collection } from './collection';
|
||||
import { BelongsTo, HasOne, Model, ModelCtor } from 'sequelize';
|
||||
import lodash from 'lodash';
|
||||
import { Model, ModelCtor } from 'sequelize';
|
||||
import { AssociationKeysToBeUpdate, BlackList, WhiteList } from './repository';
|
||||
|
||||
|
||||
type UpdateValueItem = string | number | UpdateValues;
|
||||
|
||||
type UpdateValues = {
|
||||
@ -130,7 +128,7 @@ export class UpdateGuard {
|
||||
return values;
|
||||
}
|
||||
|
||||
let valuesKeys = Object.keys(values);
|
||||
let valuesKeys = Object.keys(values || {});
|
||||
|
||||
// handle whitelist
|
||||
if (this.whiteList) {
|
||||
|
@ -19,6 +19,8 @@ export async function prepareApp() {
|
||||
registerActions: true,
|
||||
});
|
||||
|
||||
await app.cleanDb();
|
||||
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginCollectionManager);
|
||||
|
||||
|
@ -0,0 +1,462 @@
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { createApp } from '..';
|
||||
|
||||
describe('collections repository', () => {
|
||||
let app: MockServer;
|
||||
|
||||
beforeEach(async () => {
|
||||
app = await createApp();
|
||||
await app.install({ clean: true });
|
||||
await app.start();
|
||||
await app
|
||||
.agent()
|
||||
.resource('collections')
|
||||
.create({
|
||||
values: {
|
||||
name: 'tags',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('collections')
|
||||
.create({
|
||||
values: {
|
||||
name: 'foos',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('collections.fields', 'tags')
|
||||
.create({
|
||||
values: {
|
||||
name: 'foos',
|
||||
target: 'foos',
|
||||
type: 'belongsToMany',
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('collections')
|
||||
.create({
|
||||
values: {
|
||||
name: 'comments',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('collections')
|
||||
.create({
|
||||
values: {
|
||||
name: 'posts',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
name: 'comments',
|
||||
target: 'comments',
|
||||
type: 'hasMany',
|
||||
},
|
||||
{
|
||||
name: 'tags',
|
||||
target: 'tags',
|
||||
type: 'belongsToMany',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.destroy();
|
||||
});
|
||||
|
||||
it('case 1', async () => {
|
||||
const response1 = await app.agent().resource('posts').create();
|
||||
const postId = response1.body.data.id;
|
||||
const response2 = await app.agent().resource('posts.comments', postId).create();
|
||||
expect(response2.statusCode).toBe(200);
|
||||
});
|
||||
|
||||
it('case 2', async () => {
|
||||
const response = await app.agent().resource('posts').create();
|
||||
const postId = response.body.data.id;
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 1',
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 2',
|
||||
},
|
||||
});
|
||||
const response2 = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.list({
|
||||
filter: {
|
||||
'comments.title': 'comment 1',
|
||||
},
|
||||
});
|
||||
expect(response2.body.data[0].id).toBe(1);
|
||||
});
|
||||
|
||||
it('case 3', async () => {
|
||||
const response = await app.agent().resource('posts').create();
|
||||
const postId = response.body.data.id;
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 1',
|
||||
},
|
||||
});
|
||||
const response2 = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.list({
|
||||
filter: {
|
||||
'comments.id': 3,
|
||||
},
|
||||
});
|
||||
expect(response2.body.data.length).toBe(0);
|
||||
});
|
||||
|
||||
it('case 4', async () => {
|
||||
const response = await app.agent().resource('posts').create();
|
||||
const postId = response.body.data.id;
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 1',
|
||||
},
|
||||
});
|
||||
const response2 = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.list({
|
||||
filter: {
|
||||
$and: [
|
||||
{
|
||||
'comments.title': 'comment 1',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(response2.body.data[0].id).toBe(1);
|
||||
});
|
||||
|
||||
it('case 5', async () => {
|
||||
const response = await app.agent().resource('posts').create();
|
||||
const postId = response.body.data.id;
|
||||
await app.agent().resource('posts.tags', postId).create({
|
||||
values: {},
|
||||
});
|
||||
|
||||
expect(await app.db.getRepository('tags').count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('case 6', async () => {
|
||||
const response = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [
|
||||
{},
|
||||
{
|
||||
title: 'Tag1',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const postId = response.body.data.id;
|
||||
const response1 = await app.agent().resource('posts.tags', postId).list();
|
||||
expect(response1.body.data.length).toBe(2);
|
||||
});
|
||||
|
||||
it('case 7', async () => {
|
||||
const response = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [
|
||||
{},
|
||||
{
|
||||
title: 'Tag1',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const postId = response.body.data.id;
|
||||
const response1 = await app
|
||||
.agent()
|
||||
.resource('posts.tags', postId)
|
||||
.list({
|
||||
filter: {
|
||||
title: 'Tag1',
|
||||
},
|
||||
});
|
||||
expect(response1.body.data.length).toBe(1);
|
||||
});
|
||||
|
||||
it('case 8', async () => {
|
||||
const response = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [
|
||||
{},
|
||||
{
|
||||
title: 'Tag1',
|
||||
},
|
||||
{
|
||||
title: 'Tag2',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const postId = response.body.data.id;
|
||||
const response1 = await app
|
||||
.agent()
|
||||
.resource('posts.tags', postId)
|
||||
.list({
|
||||
filter: {
|
||||
$or: [{ title: 'Tag1' }, { title: 'Tag2' }],
|
||||
},
|
||||
});
|
||||
expect(response1.body.data.length).toBe(2);
|
||||
});
|
||||
|
||||
it('case 9', async () => {
|
||||
const response = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [
|
||||
{},
|
||||
{
|
||||
title: 'Tag1',
|
||||
},
|
||||
{
|
||||
title: 'Tag2',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const postId = response.body.data.id;
|
||||
const response1 = await app
|
||||
.agent()
|
||||
.resource('posts.tags', postId)
|
||||
.list({
|
||||
filter: {
|
||||
$or: [{ title: 'Tag1' }, { title: 'Tag2' }],
|
||||
},
|
||||
});
|
||||
expect(response1.body.data.length).toBe(2);
|
||||
});
|
||||
|
||||
it('case 10', async () => {
|
||||
const response = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [
|
||||
{},
|
||||
{
|
||||
title: 'Tag1',
|
||||
},
|
||||
{
|
||||
title: 'Tag2',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const postId = response.body.data.id;
|
||||
const response1 = await app
|
||||
.agent()
|
||||
.resource('posts.tags', postId)
|
||||
.list({
|
||||
appends: ['foos'],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
sort: ['-createdAt', '-id'],
|
||||
});
|
||||
|
||||
expect(response1.body.data[0]['id']).toEqual(3);
|
||||
});
|
||||
|
||||
it('case 11', async () => {
|
||||
const response = await app.agent().resource('posts').create();
|
||||
const postId = response.body.data.id;
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 1',
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 2',
|
||||
},
|
||||
});
|
||||
const response2 = await app.agent().resource('posts').create();
|
||||
const postId2 = response2.body.data.id;
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId2)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 2',
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId2)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 2',
|
||||
},
|
||||
});
|
||||
const response3 = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.list({
|
||||
filter: {
|
||||
$or: [
|
||||
{
|
||||
'comments.title': 'comment 1',
|
||||
},
|
||||
{
|
||||
'comments.title': 'comment 2',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(response3.body.data.length).toBe(2);
|
||||
});
|
||||
|
||||
it('case 12', async () => {
|
||||
const response = await app.agent().resource('posts').create();
|
||||
const postId = response.body.data.id;
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 1',
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 2',
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.create({
|
||||
values: {
|
||||
title: 'comment 3',
|
||||
},
|
||||
});
|
||||
const response2 = await app
|
||||
.agent()
|
||||
.resource('posts.comments', postId)
|
||||
.list({
|
||||
filter: {
|
||||
$or: [
|
||||
{
|
||||
title: 'comment 1',
|
||||
},
|
||||
{
|
||||
title: 'comment 2',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(response2.body.data.length).toBe(2);
|
||||
});
|
||||
|
||||
it('case 13', async () => {
|
||||
const tagRepository = app.db.getRepository('tags');
|
||||
const tag1 = await tagRepository.create({ values: { title: 'tag1' } });
|
||||
const tag2 = await tagRepository.create({ values: { title: 'tag2' } });
|
||||
const tag3 = await tagRepository.create({ values: { title: 'tag3' } });
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [tag1.get('id'), tag3.get('id')],
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [tag2.get('id')],
|
||||
},
|
||||
});
|
||||
await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.create({
|
||||
values: {
|
||||
tags: [tag2.get('id'), tag3.get('id')],
|
||||
},
|
||||
});
|
||||
|
||||
const response1 = await app
|
||||
.agent()
|
||||
.resource('posts')
|
||||
.list({
|
||||
filter: {
|
||||
$or: [{ 'tags.title': 'tag1' }, { 'tags.title': 'tag3' }],
|
||||
},
|
||||
});
|
||||
expect(response1.body.data.length).toBe(2);
|
||||
});
|
||||
});
|
@ -3,6 +3,7 @@ import CollectionManagerPlugin from '..';
|
||||
|
||||
export async function createApp() {
|
||||
const app = mockServer();
|
||||
await app.cleanDb();
|
||||
app.plugin(CollectionManagerPlugin);
|
||||
await app.load();
|
||||
return app;
|
||||
|
@ -19,6 +19,7 @@ describe('server hooks', () => {
|
||||
registerActions: true,
|
||||
});
|
||||
|
||||
await app.cleanDb();
|
||||
db = app.db;
|
||||
|
||||
app.plugin(UiSchemaStoragePlugin);
|
||||
|
@ -58,6 +58,7 @@ describe('server hooks', () => {
|
||||
registerActions: true,
|
||||
});
|
||||
|
||||
await app.cleanDb();
|
||||
db = app.db;
|
||||
|
||||
app.plugin(UiSchemaStoragePlugin);
|
||||
|
Loading…
Reference in New Issue
Block a user