Merge branch 'next' into develop

This commit is contained in:
nocobase[bot] 2024-12-21 09:02:38 +00:00
commit fccf733fdf
3 changed files with 80 additions and 9 deletions

View File

@ -0,0 +1,67 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Database, Repository } from '@nocobase/database';
import { MockServer, createMockServer } from '@nocobase/test';
import compose from 'koa-compose';
import { parseFieldAndAssociations, queryData } from '../actions/query';
import { createQueryParser } from '../query-parser';
describe('api', () => {
let app: MockServer;
let db: Database;
beforeAll(async () => {
app = await createMockServer({
plugins: ['users', 'auth', 'data-visualization', 'data-source-manager', 'acl', 'error-handler'],
});
db = app.db;
});
afterAll(async () => {
await app.destroy();
});
test('query with nested m2m filter', async () => {
const ctx = {
app,
db,
action: {
params: {
values: {
collection: 'users',
measures: [
{
field: ['id'],
aggregation: 'count',
alias: 'id',
},
],
filter: {
$and: [
{
createdBy: {
roles: {
name: {
$includes: 'member',
},
},
},
},
],
},
},
},
},
} as any;
const queryParser = createQueryParser(db);
await compose([parseFieldAndAssociations, queryParser.parse(), queryData])(ctx, async () => {});
expect(ctx.action.params.values.data).toBeDefined();
});
});

View File

@ -18,9 +18,7 @@ import {
postProcess,
} from '../actions/query';
import { Database } from '@nocobase/database';
import * as formatter from '../formatter';
import { createQueryParser } from '../query-parser';
import { QueryParser } from '../query-parser/query-parser';
describe('query', () => {
describe('parseBuilder', () => {

View File

@ -149,20 +149,26 @@ export const parseFieldAndAssociations = async (ctx: Context, next: Next) => {
collection,
});
const { where, include: filterInclude } = filterParser.toSequelizeParams();
const parsedFilterInclude = filterInclude?.map((item) => {
if (fields.get(item.association)?.type === 'belongsToMany') {
item.through = { attributes: [] };
if (filterInclude) {
// Remove attributes from through table
const stack = [...filterInclude];
while (stack.length) {
const item = stack.pop();
if (fields.get(item.association)?.type === 'belongsToMany') {
item.through = { attributes: [] };
}
if (item.include) {
stack.push(...item.include);
}
}
return item;
});
}
ctx.action.params.values = {
...ctx.action.params.values,
where,
measures: parsedMeasures,
dimensions: parsedDimensions,
orders: parsedOrders,
include: [...include, ...(parsedFilterInclude || [])],
include: [...include, ...(filterInclude || [])],
};
await next();
};