mirror of https://github.com/nocodb/nocodb
15 changed files with 365 additions and 34 deletions
@ -0,0 +1,13 @@ |
|||||||
|
import { Request, Router } from 'express'; |
||||||
|
import { TestResetService } from '../../services/test/TestResetService'; |
||||||
|
|
||||||
|
export async function reset(_: Request<any, any>, res) { |
||||||
|
const service = new TestResetService(); |
||||||
|
|
||||||
|
res.json(await service.process()); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.get('/api/v1/meta/test/reset', reset); |
||||||
|
export default router; |
@ -0,0 +1,65 @@ |
|||||||
|
import axios from 'axios'; |
||||||
|
|
||||||
|
const extPgProject = { |
||||||
|
title: 'pgExtREST', |
||||||
|
bases: [ |
||||||
|
{ |
||||||
|
type: 'pg', |
||||||
|
config: { |
||||||
|
client: 'pg', |
||||||
|
connection: { |
||||||
|
host: 'localhost', |
||||||
|
port: '5432', |
||||||
|
user: 'postgres', |
||||||
|
password: 'password', |
||||||
|
database: 'postgres', |
||||||
|
}, |
||||||
|
searchPath: ['public'], |
||||||
|
}, |
||||||
|
inflection_column: 'camelize', |
||||||
|
inflection_table: 'camelize', |
||||||
|
}, |
||||||
|
], |
||||||
|
external: true, |
||||||
|
}; |
||||||
|
|
||||||
|
// const extMysqlProject = {
|
||||||
|
// title: 'externalREST',
|
||||||
|
// bases: [
|
||||||
|
// {
|
||||||
|
// type: 'mysql2',
|
||||||
|
// config: {
|
||||||
|
// client: 'mysql2',
|
||||||
|
// connection: {
|
||||||
|
// host: 'localhost',
|
||||||
|
// port: '5432',
|
||||||
|
// user: 'root',
|
||||||
|
// password: 'password',
|
||||||
|
// database: 'sakila',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// inflection_column: 'camelize',
|
||||||
|
// inflection_table: 'camelize',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// external: true,
|
||||||
|
// };
|
||||||
|
|
||||||
|
const createProjects = async (token) => { |
||||||
|
return await Promise.all( |
||||||
|
[extPgProject].map(async (projectAttr) => { |
||||||
|
const response = await axios.post( |
||||||
|
'http://localhost:8080/api/v1/db/meta/projects/', |
||||||
|
projectAttr, |
||||||
|
{ |
||||||
|
headers: { |
||||||
|
'xc-auth': token, |
||||||
|
}, |
||||||
|
} |
||||||
|
); |
||||||
|
return response.data; |
||||||
|
}) |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default createProjects; |
@ -0,0 +1,17 @@ |
|||||||
|
import axios from 'axios'; |
||||||
|
|
||||||
|
const defaultUserArgs = { |
||||||
|
email: 'user@nocodb.com', |
||||||
|
password: 'Password123.', |
||||||
|
}; |
||||||
|
|
||||||
|
const createUser = async () => { |
||||||
|
const response = await axios.post( |
||||||
|
'http://localhost:8080/api/v1/auth/user/signup', |
||||||
|
defaultUserArgs |
||||||
|
); |
||||||
|
|
||||||
|
return { token: response.data.token }; |
||||||
|
}; |
||||||
|
|
||||||
|
export default createUser; |
@ -0,0 +1,39 @@ |
|||||||
|
import Noco from '../../../Noco'; |
||||||
|
|
||||||
|
import Knex from 'knex'; |
||||||
|
import NocoCache from '../../../cache/NocoCache'; |
||||||
|
import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2'; |
||||||
|
import createProjects from './createProjects'; |
||||||
|
import { isPgSakilaToBeReset, resetPgSakila } from './resetPgSakila'; |
||||||
|
import createUser from './createUser'; |
||||||
|
import resetMeta from './resetMeta'; |
||||||
|
|
||||||
|
export class TestResetService { |
||||||
|
private knex: Knex | null = null; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.knex = Noco.ncMeta.knex; |
||||||
|
} |
||||||
|
|
||||||
|
async process() { |
||||||
|
try { |
||||||
|
await NcConnectionMgrv2.destroyAll(); |
||||||
|
|
||||||
|
if (await isPgSakilaToBeReset()) { |
||||||
|
await resetPgSakila(); |
||||||
|
} |
||||||
|
|
||||||
|
await resetMeta(this.knex); |
||||||
|
|
||||||
|
await NocoCache.destroy(); |
||||||
|
|
||||||
|
const { token } = await createUser(); |
||||||
|
const projects = await createProjects(token); |
||||||
|
|
||||||
|
return { token, projects }; |
||||||
|
} catch (e) { |
||||||
|
console.error('cleanupMeta', e); |
||||||
|
return { error: e }; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
import Model from '../../../models/Model'; |
||||||
|
import Project from '../../../models/Project'; |
||||||
|
import { orderedMetaTables } from '../../../utils/globals'; |
||||||
|
|
||||||
|
const disableForeignKeyChecks = async (knex) => { |
||||||
|
await knex.raw('PRAGMA foreign_keys = OFF'); |
||||||
|
// await this.knex.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
||||||
|
}; |
||||||
|
|
||||||
|
const enableForeignKeyChecks = async (knex) => { |
||||||
|
await knex.raw(`PRAGMA foreign_keys = ON;`); |
||||||
|
// await this.knex.raw(`SET FOREIGN_KEY_CHECKS = 1`);
|
||||||
|
}; |
||||||
|
|
||||||
|
const dropTablesAllNonExternalProjects = async (knex) => { |
||||||
|
const projects = await Project.list({}); |
||||||
|
const userCreatedTableNames: string[] = []; |
||||||
|
await Promise.all( |
||||||
|
projects |
||||||
|
.filter((project) => project.is_meta) |
||||||
|
.map(async (project) => { |
||||||
|
await project.getBases(); |
||||||
|
const base = project.bases && project.bases[0]; |
||||||
|
if (!base) return; |
||||||
|
|
||||||
|
const models = await Model.list({ |
||||||
|
project_id: project.id, |
||||||
|
base_id: base.id!, |
||||||
|
}); |
||||||
|
models.forEach((model) => { |
||||||
|
userCreatedTableNames.push(model.table_name); |
||||||
|
}); |
||||||
|
}) |
||||||
|
); |
||||||
|
|
||||||
|
await disableForeignKeyChecks(knex); |
||||||
|
|
||||||
|
for (const tableName of userCreatedTableNames) { |
||||||
|
await knex.raw(`DROP TABLE ${tableName}`); |
||||||
|
} |
||||||
|
|
||||||
|
await enableForeignKeyChecks(knex); |
||||||
|
}; |
||||||
|
|
||||||
|
const resetMeta = async (knex) => { |
||||||
|
await dropTablesAllNonExternalProjects(knex); |
||||||
|
|
||||||
|
await disableForeignKeyChecks(knex); |
||||||
|
for (const tableName of orderedMetaTables) { |
||||||
|
try { |
||||||
|
await knex.raw(`DELETE FROM ${tableName}`); |
||||||
|
} catch (e) { |
||||||
|
console.error('cleanupMetaTables', e); |
||||||
|
} |
||||||
|
} |
||||||
|
await enableForeignKeyChecks(knex); |
||||||
|
}; |
||||||
|
|
||||||
|
export default resetMeta; |
@ -0,0 +1,56 @@ |
|||||||
|
import knex from 'knex'; |
||||||
|
import fs from 'fs'; |
||||||
|
import Project from '../../../models/Project'; |
||||||
|
import Audit from '../../../models/Audit'; |
||||||
|
|
||||||
|
const config = { |
||||||
|
client: 'pg', |
||||||
|
connection: { |
||||||
|
host: 'localhost', |
||||||
|
port: 5432, |
||||||
|
user: 'postgres', |
||||||
|
password: 'password', |
||||||
|
database: 'postgres', |
||||||
|
}, |
||||||
|
searchPath: ['public'], |
||||||
|
meta: { dbtype: '' }, |
||||||
|
pool: { min: 0, max: 5 }, |
||||||
|
}; |
||||||
|
|
||||||
|
const isPgSakilaToBeReset = async () => { |
||||||
|
const sakilaProject = await Project.getByTitle('pgExtREST'); |
||||||
|
|
||||||
|
const audits = |
||||||
|
sakilaProject && (await Audit.projectAuditList(sakilaProject.id, {})); |
||||||
|
|
||||||
|
return audits.length > 0; |
||||||
|
}; |
||||||
|
|
||||||
|
const resetPgSakila = async () => { |
||||||
|
const knexClient = knex(config); |
||||||
|
|
||||||
|
try { |
||||||
|
await knexClient.raw(`DROP SCHEMA public CASCADE`); |
||||||
|
} catch (e) { |
||||||
|
console.log('Error dropping pg schema', e); |
||||||
|
} |
||||||
|
await knexClient.raw(`CREATE SCHEMA public`); |
||||||
|
|
||||||
|
const testsDir = __dirname.replace( |
||||||
|
'/src/lib/services/test/TestResetService', |
||||||
|
'/tests' |
||||||
|
); |
||||||
|
|
||||||
|
const schemaFile = fs |
||||||
|
.readFileSync(`${testsDir}/pg-sakila-db/01-postgres-sakila-schema.sql`) |
||||||
|
.toString(); |
||||||
|
const dataFile = fs |
||||||
|
.readFileSync(`${testsDir}/pg-sakila-db/02-postgres-sakila-insert-data.sql`) |
||||||
|
.toString(); |
||||||
|
await knexClient.raw(schemaFile); |
||||||
|
await knexClient.raw(dataFile); |
||||||
|
|
||||||
|
await knexClient.destroy(); |
||||||
|
}; |
||||||
|
|
||||||
|
export { resetPgSakila, isPgSakilaToBeReset }; |
@ -0,0 +1,51 @@ |
|||||||
|
// let t0 = require("./explicitLogin");
|
||||||
|
// let t01 = require("../common/00_pre_configurations");
|
||||||
|
let t6b = require("../common/6b_downloadCsv"); |
||||||
|
// let t6c = require("../common/6c_swagger_api");
|
||||||
|
// let t6d = require("../common/6d_language_validation");
|
||||||
|
// let t6e = require("../common/6e_project_operations");
|
||||||
|
let t6f = require("../common/6f_attachments"); |
||||||
|
// let t6g = require("../common/6g_base_share");
|
||||||
|
// let t7a = require("../common/7a_create_project_from_excel");
|
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
// const t8a = require("../common/8a_webhook");
|
||||||
|
const t9b = require("../common/9b_ERD"); |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
|
||||||
|
// Download CSV
|
||||||
|
t6b.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// Attachment cell
|
||||||
|
t6f.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// ERD:
|
||||||
|
t9b.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "postgres"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
Loading…
Reference in new issue