diff --git a/packages/nocodb/src/lib/services/test/TestResetService/index.ts b/packages/nocodb/src/lib/services/test/TestResetService/index.ts index d8277e60b9..c75661426a 100644 --- a/packages/nocodb/src/lib/services/test/TestResetService/index.ts +++ b/packages/nocodb/src/lib/services/test/TestResetService/index.ts @@ -5,6 +5,7 @@ import axios from 'axios'; import Project from '../../../models/Project'; import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2'; import resetMetaSakilaSqliteProject from './resetMetaSakilaSqliteProject'; +import resetMysqlSakilaProject from './resetMysqlSakilaProject'; const loginRootUser = async () => { const response = await axios.post( @@ -17,6 +18,7 @@ const loginRootUser = async () => { const projectTitleByType = { sqlite3: 'sampleREST', + mysql: 'externalREST', }; export class TestResetService { @@ -34,7 +36,7 @@ export class TestResetService { const { project } = await this.resetProject({ metaKnex: this.knex, token, - type: 'sqlite3', + type: 'mysql', parallelId: this.parallelId, }); @@ -57,7 +59,7 @@ export class TestResetService { parallelId: string; }) { const title = `${projectTitleByType[type]}${parallelId}`; - const project = await Project.getByTitle(title); + const project: Project | undefined = await Project.getByTitle(title); if (project) { const bases = await project.getBases(); @@ -68,6 +70,8 @@ export class TestResetService { if (type == 'sqlite3') { await resetMetaSakilaSqliteProject({ token, metaKnex, title }); + } else if (type == 'mysql') { + await resetMysqlSakilaProject({ token, title, parallelId, oldProject: project }); } return { diff --git a/packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakila.ts b/packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakila.ts deleted file mode 100644 index 5051eb0e08..0000000000 --- a/packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakila.ts +++ /dev/null @@ -1,55 +0,0 @@ -import knex from 'knex'; -import fs from 'fs'; -import Project from '../../../models/Project'; -import Audit from '../../../models/Audit'; - -const config = { - client: 'mysql2', - connection: { - host: 'localhost', - port: 3306, - user: 'root', - password: 'password', - database: 'test_sakila', - multipleStatements: true, - dateStrings: true, - }, -}; - -const isMysqlSakilaToBeReset = async () => { - const sakilaProject = await Project.getByTitle('externalREST'); - - const audits = - sakilaProject && (await Audit.projectAuditList(sakilaProject.id, {})); - - return audits?.length > 0; -}; - -const resetMysqlSakila = async () => { - const knexClient = knex(config); - - try { - await knexClient.raw(`DROP DATABASE test_sakila`); - } catch (e) { - console.log('Error dropping db', e); - } - await knexClient.raw(`CREATE DATABASE test_sakila`); - - const testsDir = __dirname.replace( - '/src/lib/services/test/TestResetService', - '/tests' - ); - - const schemaFile = fs - .readFileSync(`${testsDir}/mysql-sakila-db/03-test-sakila-schema.sql`) - .toString(); - const dataFile = fs - .readFileSync(`${testsDir}/mysql-sakila-db/04-test-sakila-data.sql`) - .toString(); - await knexClient.raw(schemaFile); - await knexClient.raw(dataFile); - - await knexClient.destroy(); -}; - -export { resetMysqlSakila, isMysqlSakilaToBeReset }; diff --git a/packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakilaProject.ts b/packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakilaProject.ts new file mode 100644 index 0000000000..a35466c3a0 --- /dev/null +++ b/packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakilaProject.ts @@ -0,0 +1,165 @@ +import axios from 'axios'; +import Knex from 'knex'; + +import fs from 'fs'; +import Audit from '../../../models/Audit'; +import { sakilaTableNames } from '../../../utils/globals'; +import Project from '../../../models/Project'; + +const config = { + client: 'mysql2', + connection: { + host: 'localhost', + port: 3306, + user: 'root', + password: 'password', + database: 'sakila', + multipleStatements: true, + dateStrings: true, + }, +}; + +const extMysqlProject = (title, parallelId) => ({ + title, + bases: [ + { + type: 'mysql2', + config: { + client: 'mysql2', + connection: { + host: 'localhost', + port: '3306', + user: 'root', + password: 'password', + database: `test_sakila_${parallelId}`, + }, + }, + inflection_column: 'camelize', + inflection_table: 'camelize', + }, + ], + external: true, +}); + +const mysqlSakilaSqlViews = [ + 'actor_info', 'customer_list', 'film_list', 'nicer_but_slower_film_list', 'sales_by_film_category', 'sales_by_store', 'staff_list' +] + +const dropTablesAndViews = async (knex: Knex) => { + for (const view of mysqlSakilaSqlViews) { + try { + await knex.raw(`DROP VIEW ${view}`); + } catch (e) { + } + } + + for (const table of sakilaTableNames) { + try { + await knex.raw(`DROP TABLE ${table}`); + } catch (e) { + } + } +}; + +const isSakilaMysqlToBeReset = async (knex: Knex, parallelId: string, project?: Project, ) => { + const tablesInDb: Array = await knex.raw( + `SELECT table_name FROM information_schema.tables WHERE table_schema = 'test_sakila_${parallelId}'` + ) + + if ( + tablesInDb.length === 0 || + (tablesInDb.length > 0 && !tablesInDb.includes(`actor`)) + ) { + return true; + } + + if(!project) return false; + + const audits = await Audit.projectAuditList(project.id, {}); + + return audits?.length > 0; +}; + +const resetSakilaMysql = async (knex:Knex, parallelId: string) => { + await dropTablesAndViews(knex); + + const testsDir = __dirname.replace( + '/src/lib/services/test/TestResetService', + '/tests' + ); + + try { + await knex.raw(`DROP DATABASE test_sakila_${parallelId}`); + } catch (e) { + console.log('Error dropping db', e); + } + await knex.raw(`CREATE DATABASE test_sakila_${parallelId}`); + + const trx = await knex.transaction(); + + try { + const schemaFile = fs + .readFileSync( + `${testsDir}/mysql-sakila-db/03-test-sakila-schema.sql` + ) + .toString() + .replace(/test_sakila/g, `test_sakila_${parallelId}`); + + const dataFile = fs + .readFileSync( + `${testsDir}/mysql-sakila-db/04-test-sakila-data.sql` + ) + .toString() + .replace(/test_sakila/g, `test_sakila_${parallelId}`); + + await trx.raw(schemaFile); + await trx.raw(dataFile); + + await trx.commit(); + } catch (e) { + console.log('Error resetting mysql db', e); + await trx.rollback(e); + } +}; + +const resetMysqlSakilaProject = async ({ + token, + title, + parallelId, + oldProject, +}: { + token: string; + title: string; + parallelId: string; + oldProject?: Project | undefined; +}) => { + const knex = Knex(config); + + try{ + await knex.raw(`USE test_sakila_${parallelId}`); + } catch (e) { + await knex.raw(`CREATE DATABASE test_sakila_${parallelId}`); + await knex.raw(`USE test_sakila_${parallelId}`); + } + + if (await isSakilaMysqlToBeReset(knex, parallelId, oldProject)) { + await resetSakilaMysql(knex, parallelId); + } + + const response = await axios.post( + 'http://localhost:8080/api/v1/db/meta/projects/', + extMysqlProject(title, parallelId), + { + headers: { + 'xc-auth': token, + }, + } + ); + if (response.status !== 200) { + console.error('Error creating project', response.data); + } + + await knex.destroy(); +}; + +export default resetMysqlSakilaProject; diff --git a/scripts/playwright/tests/singleSelect.spec.ts b/scripts/playwright/tests/singleSelect.spec.ts index 1f55ea6b4a..568245ec41 100644 --- a/scripts/playwright/tests/singleSelect.spec.ts +++ b/scripts/playwright/tests/singleSelect.spec.ts @@ -42,7 +42,7 @@ test.describe('Single select', () => { await grid.verifyRowDoesNotExist({index: 0}); }); - test.skip('Remove a option, reorder option and delete the column', async () => { + test('Remove a option, reorder option and delete the column', async () => { await grid.cell.selectOption.select({index: 0, columnHeader: 'SingleSelect', option: 'Option 1'}); await grid.column.selectOption.addOption({index: 2, option: 'Option 3', columnTitle: 'SingleSelect'});