diff --git a/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/index.ts b/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/index.ts index 8cd8450ded..3a8a1150b9 100644 --- a/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/index.ts +++ b/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/index.ts @@ -13,7 +13,7 @@ export async function createApp(options: any = {}) { const app = await createMockServer({ acl: false, ...options, - plugins: ['error-handler', 'field-sort', 'data-source-main', 'ui-schema-storage'], + plugins: (options.plugins || []).concat(['error-handler', 'field-sort', 'data-source-main', 'ui-schema-storage']), }); return app; } diff --git a/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts b/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts index ac45d9077b..6d8fb1efd3 100644 --- a/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts +++ b/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts @@ -11,10 +11,11 @@ import Database, { Repository, ViewCollection, ViewFieldInference } from '@nocob import Application from '@nocobase/server'; import { uid } from '@nocobase/utils'; import { createApp } from '../index'; +import { MockServer } from '@nocobase/test'; describe('view collection', function () { let db: Database; - let app: Application; + let app: MockServer; let collectionRepository: Repository; @@ -25,6 +26,7 @@ describe('view collection', function () { database: { tablePrefix: '', }, + plugins: ['users'], }); db = app.db; @@ -48,7 +50,7 @@ describe('view collection', function () { await collectionRepository.create({ values: { - name: 'users', + name: 'users_1', fields: [ { name: 'name', type: 'string' }, { type: 'belongsTo', name: 'group', foreignKey: 'group_id' }, @@ -57,7 +59,7 @@ describe('view collection', function () { context: {}, }); - const User = db.getCollection('users'); + const User = db.getCollection('users_1'); const assoc = User.model.associations.group; const foreignKey = assoc.foreignKey; @@ -67,7 +69,7 @@ describe('view collection', function () { await db.sequelize.query(`DROP VIEW IF EXISTS ${viewName}`); const createSQL = `CREATE VIEW ${viewName} AS SELECT id, ${foreignField}, name FROM ${db - .getCollection('users') + .getCollection('users_1') .quotedTableName()}`; await db.sequelize.query(createSQL); @@ -107,7 +109,7 @@ describe('view collection', function () { await collectionRepository.create({ values: { - name: 'users', + name: 'users_1', fields: [ { name: 'name', type: 'string' }, { type: 'belongsTo', name: 'group', foreignKey: 'group_id' }, @@ -116,7 +118,7 @@ describe('view collection', function () { context: {}, }); - const User = db.getCollection('users'); + const User = db.getCollection('users_1'); const assoc = User.model.associations.group; const foreignKey = assoc.foreignKey; @@ -126,7 +128,7 @@ describe('view collection', function () { await db.sequelize.query(`DROP VIEW IF EXISTS ${viewName}`); const createSQL = `CREATE VIEW ${viewName} AS SELECT id, ${foreignField}, name FROM ${db - .getCollection('users') + .getCollection('users_1') .quotedTableName()}`; await db.sequelize.query(createSQL); @@ -161,7 +163,7 @@ describe('view collection', function () { it('should load view collection belongs to field', async () => { await collectionRepository.create({ values: { - name: 'users', + name: 'users_1', fields: [ { type: 'string', @@ -190,14 +192,14 @@ describe('view collection', function () { type: 'belongsTo', name: 'user', foreignKey: 'userId', - target: 'users', + target: 'users_1', }, ], }, context: {}, }); - await db.getRepository('users').create({ + await db.getRepository('users_1').create({ values: [ { name: 'u1', @@ -216,7 +218,7 @@ describe('view collection', function () { await db.sequelize.query(`DROP VIEW IF EXISTS ${viewName}`); const viewSQL = ` - CREATE VIEW ${viewName} as SELECT users.* FROM ${Post.quotedTableName()} as users + CREATE VIEW ${viewName} as SELECT users_1.* FROM ${Post.quotedTableName()} as users_1 `; await db.sequelize.query(viewSQL); @@ -256,7 +258,7 @@ describe('view collection', function () { it('should use view collection as through collection', async () => { const User = await collectionRepository.create({ values: { - name: 'users', + name: 'users_1', fields: [{ name: 'name', type: 'string' }], }, context: {}, @@ -270,9 +272,9 @@ describe('view collection', function () { context: {}, }); - const UserCollection = db.getCollection('users'); + const UserCollection = db.getCollection('users_1'); - await db.getRepository('users').create({ + await db.getRepository('users_1').create({ values: [{ name: 'u1' }, { name: 'u2' }], }); @@ -324,7 +326,7 @@ describe('view collection', function () { await fieldsRepository.create({ values: { - collectionName: 'users', + collectionName: 'users_1', name: 'roles', type: 'belongsToMany', target: 'my_roles', @@ -335,14 +337,14 @@ describe('view collection', function () { context: {}, }); - const users = await db.getRepository('users').find({ + const users_1 = await db.getRepository('users_1').find({ appends: ['roles'], filter: { name: 'u1', }, }); - const roles = users[0].get('roles'); + const roles = users_1[0].get('roles'); expect(roles).toHaveLength(2); await collectionRepository.destroy({ @@ -355,7 +357,7 @@ describe('view collection', function () { expect( await fieldsRepository.count({ filter: { - collectionName: 'users', + collectionName: 'users_1', name: 'roles', }, }), @@ -541,4 +543,130 @@ describe('view collection', function () { expect(db.getCollection('view_collection')).toBeUndefined(); }); + + it('should create view collection successfully when underscored env and DB_DIALECT=mysql', async () => { + if (!db.options.underscored) { + return; + } + + await app + .agent() + .resource('collections') + .create({ + values: { + logging: true, + name: 'users_1', + template: 'general', + view: false, + fields: [ + { + name: 'id', + type: 'bigInt', + autoIncrement: true, + primaryKey: true, + allowNull: false, + uiSchema: { + type: 'number', + title: '{{t("ID")}}', + 'x-component': 'InputNumber', + 'x-read-pretty': true, + }, + interface: 'integer', + }, + { + name: 'createdBy', + interface: 'createdBy', + type: 'belongsTo', + target: 'users_1', + foreignKey: 'createdById', + uiSchema: { + type: 'object', + title: '{{t("Created by")}}', + 'x-component': 'AssociationField', + 'x-component-props': { fieldNames: { value: 'id', label: 'nickname' } }, + 'x-read-pretty': true, + }, + }, + { + type: 'belongsTo', + target: 'users_1', + foreignKey: 'updatedById', + name: 'updatedBy', + interface: 'updatedBy', + uiSchema: { + type: 'object', + title: '{{t("Last updated by")}}', + 'x-component': 'AssociationField', + 'x-component-props': { fieldNames: { value: 'id', label: 'nickname' } }, + 'x-read-pretty': true, + }, + }, + ], + autoGenId: false, + title: 'users_1', + }, + }); + + const dropViewSQL = `DROP VIEW IF EXISTS test_view`; + await db.sequelize.query(dropViewSQL); + const viewSQL = `CREATE VIEW test_view AS select * from users_1`; + await db.sequelize.query(viewSQL); + + const response = await app + .agent() + .resource('collections') + .create({ + values: { + name: 'fff1', + template: 'view', + view: true, + fields: [ + { + name: 'id', + rawType: 'BIGINT', + field: 'id', + type: 'bigInt', + source: 'users_1.id', + uiSchema: { title: 'id' }, + }, + { + name: 'createdBy', + type: 'belongsTo', + source: 'users_1.createdBy', + uiSchema: { title: 'createdBy' }, + }, + { + name: 'created_by_id', + rawType: 'BIGINT', + field: 'created_by_id', + type: 'bigInt', + possibleTypes: ['bigInt', 'unixTimestamp', 'sort'], + uiSchema: { title: 'created_by_id' }, + }, + { + name: 'updatedBy', + type: 'belongsTo', + source: 'users_1.updatedBy', + uiSchema: { title: 'updatedBy' }, + }, + { + name: 'updated_by_id', + rawType: 'BIGINT', + field: 'updated_by_id', + type: 'bigInt', + possibleTypes: ['bigInt', 'unixTimestamp', 'sort'], + uiSchema: { title: 'updated_by_id' }, + }, + ], + schema: null, + writableView: false, + sources: ['users_1'], + title: 'view_collection_display_name', + databaseView: 'test_view', + viewName: 'test_view', + }, + }); + + expect(response.status).toBe(200); + }); });