hapiest-mysql
Version:
A wrapper around mysql that provides a very descriptive way of running queries.
403 lines (335 loc) • 16.9 kB
JavaScript
;
const Should = require('should');
const MysqlServiceFactory = require('../../lib/mysqlServiceFactory');
const MysqlDatabaseSetupFactory = require('../../lib/testing-helper/mysqlDatabaseSetupFactory');
const sourceDbConnection = {
host: 'localhost',
database: 'hapiestmysql',
user: 'hapiestmysql',
password: 'hapiestmysql',
connectionLimit: 1
};
const mysqlServiceForSourceDb = MysqlServiceFactory.createFromObjWithOnePool(sourceDbConnection);
const testDbConnection = {
host: 'localhost',
database: 'hapiestmysql_test',
user: 'hapiestmysql',
password: 'hapiestmysql',
connectionLimit: 1,
multipleStatements: true
};
const mysqlServiceForTestDb = MysqlServiceFactory.createFromObjWithOnePool(testDbConnection);
const mysqlDatabaseSetup = MysqlDatabaseSetupFactory.create(mysqlServiceForTestDb, 'hapiestmysql');
describe('MysqlDatabaseSetup', function() {
describe('replicateAllTables', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should copy over three tables from the source database', function() {
return mysqlDatabaseSetup.replicateAllTables()
.then(() => {
const sql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${testDbConnection.database}'ORDER BY TABLE_NAME ASC`;
return mysqlServiceForTestDb.selectAll(sql)
.then(tableNameRows => tableNameRows.map(tableNameRow => tableNameRow.TABLE_NAME))
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(3);
tables[0].should.eql('users');
tables[1].should.eql('user_downloads');
tables[2].should.eql('videos');
});
});
});
it('Should copy over three tables from the source database and reset AUTO_INCREMENT values to 1', function() {
const resetAutoIncrement = true;
return mysqlDatabaseSetup.replicateAllTables(resetAutoIncrement)
.then(() => {
const sql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${testDbConnection.database}'ORDER BY TABLE_NAME ASC`;
return mysqlServiceForTestDb.selectAll(sql)
.then(tableNameRows => tableNameRows.map(tableNameRow => tableNameRow.TABLE_NAME))
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(3);
tables[0].should.eql('users');
tables[1].should.eql('user_downloads');
tables[2].should.eql('videos');
})
.then(() => {
const sql = `INSERT INTO users (first_name, last_name, email) VALUES ('John', 'Doe', 'john.doe@gmail.com');`;
return mysqlServiceForTestDb.insert(sql);
})
.then(result => {
Should.exist(result);
Should.exist(result.insertId);
result.insertId.should.eql(1);
})
.then(() => {
const sql = `INSERT INTO videos (title, url) VALUES ('video 1', 'http://www.youtube.com/video1')`;
return mysqlServiceForTestDb.insert(sql);
})
.then(result => {
Should.exist(result);
Should.exist(result.insertId);
result.insertId.should.eql(1);
});
});
});
});
describe('replicateTables', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should copy over three tables from the source database', function() {
return mysqlDatabaseSetup.replicateTables(['users', 'videos'])
.then(() => {
const sql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${testDbConnection.database}'ORDER BY TABLE_NAME ASC`;
return mysqlServiceForTestDb.selectAll(sql)
.then(tableNameRows => tableNameRows.map(tableNameRow => tableNameRow.TABLE_NAME))
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(2);
tables[0].should.eql('users');
tables[1].should.eql('videos');
});
});
});
it('Should copy over three tables from the source database and reset AUTO_INCREMENT values to 1', function() {
const resetAutoIncrement = true;
return mysqlDatabaseSetup.replicateTables(['users', 'videos'], resetAutoIncrement)
.then(() => {
const sql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${testDbConnection.database}'ORDER BY TABLE_NAME ASC`;
return mysqlServiceForTestDb.selectAll(sql)
.then(tableNameRows => tableNameRows.map(tableNameRow => tableNameRow.TABLE_NAME))
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(2);
tables[0].should.eql('users');
tables[1].should.eql('videos');
})
.then(() => {
const sql = `INSERT INTO users (first_name, last_name, email) VALUES ('John', 'Doe', 'john.doe@gmail.com');`;
return mysqlServiceForTestDb.insert(sql);
})
.then(result => {
Should.exist(result);
Should.exist(result.insertId);
result.insertId.should.eql(1);
})
.then(() => {
const sql = `INSERT INTO videos (title, url) VALUES ('video 1', 'http://www.youtube.com/video1')`;
return mysqlServiceForTestDb.insert(sql);
})
.then(result => {
Should.exist(result);
Should.exist(result.insertId);
result.insertId.should.eql(1);
});
});
});
});
describe('copyDataForAllTables', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should copy data for three tables from the source database', function() {
return mysqlDatabaseSetup.replicateAllTables()
.then(() => mysqlDatabaseSetup.copyDataForAllTables())
.then(() => {
const sqlQueries = [`SELECT * FROM users`, `SELECT * FROM videos`, `SELECT * FROM user_downloads`];
return mysqlServiceForTestDb.executeQueries(sqlQueries)
.then(results => {
Should.exist(results);
results.should.be.an.Array();
results.length.should.eql(3);
Should.exist(results[0][0]);
Should.not.exist(results[0][1]);
const userInfo = results[0][0];
userInfo.should.have.properties(['id', 'first_name', 'last_name', 'email', 'date_created']);
userInfo.id.should.eql(1);
userInfo.first_name.should.eql('John');
userInfo.last_name.should.eql('Doe');
userInfo.email.should.eql('john.doe@gmail.com');
Should.exist(results[1][0]);
Should.exist(results[1][1]);
Should.not.exist(results[1][2]);
const video1 = results[1][0];
video1.id.should.eql(1);
video1.title.should.eql('video 1');
video1.url.should.eql('http://www.youtube.com/video1');
const video2 = results[1][1];
video2.id.should.eql(2);
video2.title.should.eql('video 2');
video2.url.should.eql('http://www.youtube.com/video2');
Should.exist(results[2][0]);
Should.exist(results[2][1]);
Should.not.exist(results[2][2]);
const download1 = results[2][0];
download1.id.should.eql(1);
download1.user_id.should.eql(1);
download1.video_id.should.eql(1);
const download2 = results[2][1];
download2.id.should.eql(2);
download2.user_id.should.eql(1);
download2.video_id.should.eql(2);
});
});
});
});
describe('copyDataForTables', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should copy data for only the user table', function() {
return mysqlDatabaseSetup.replicateAllTables()
.then(() => {
return Promise.all([mysqlDatabaseSetup.copyDataForTables(['users'])])
})
.then(() => {
const sqlQueries = [`SELECT * FROM users`, `SELECT * FROM videos`, `SELECT * FROM user_downloads`];
return mysqlServiceForTestDb.executeQueries(sqlQueries)
.then(results => {
Should.exist(results);
results.should.be.an.Array();
results.length.should.eql(3);
Should.exist(results[0][0]);
Should.not.exist(results[0][1]);
const userInfo = results[0][0];
userInfo.should.have.properties(['id', 'first_name', 'last_name', 'email', 'date_created']);
userInfo.id.should.eql(1);
userInfo.first_name.should.eql('John');
userInfo.last_name.should.eql('Doe');
userInfo.email.should.eql('john.doe@gmail.com');
Should.exist(results[1]); // No videos copied over
Should.not.exist(results[1][0]);
Should.exist(results[2]); // No downloads copied over
Should.not.exist(results[2][0]);
});
});
});
});
describe('dropAllTables', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should drop all tables', function() {
return mysqlDatabaseSetup.replicateAllTables()
.then(() => mysqlDatabaseSetup.getAllTablesFromCurrentDatabase())
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(3);
})
.then(() => mysqlDatabaseSetup.dropAllTables())
.then(() => mysqlDatabaseSetup.getAllTablesFromCurrentDatabase())
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(0);
})
});
});
describe('dropTables', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should drop the users table', function() {
return mysqlDatabaseSetup.replicateAllTables()
.then(() => mysqlDatabaseSetup.getAllTablesFromCurrentDatabase())
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(3);
})
.then(() => mysqlDatabaseSetup.dropTables(['users']))
.then(() => mysqlDatabaseSetup.getAllTablesFromCurrentDatabase())
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(2);
})
});
});
describe('getAllTablesFromSourceDatabase', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should return all tables in the source database', function() {
return mysqlDatabaseSetup.getAllTablesFromSourceDatabase()
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(3);
})
});
});
describe('getAllTablesFromSourceDatabase', function() {
beforeEach(setupSourceDatabase);
afterEach(cleanupDatabases);
it('Should get all tables in current database', function() {
return mysqlDatabaseSetup.getAllTablesFromCurrentDatabase()
.then(tables => {
tables.should.be.an.Array();
tables.length.should.eql(0);
})
.then(() => mysqlDatabaseSetup.replicateAllTables())
.then(() => mysqlDatabaseSetup.getAllTablesFromCurrentDatabase())
.then(tables => {
Should.exist(tables);
tables.should.be.an.Array();
tables.length.should.eql(3);
})
});
});
});
function setupSourceDatabase() {
return _dropTables(mysqlServiceForSourceDb)
.then(() => _createTables(mysqlServiceForSourceDb));
}
function cleanupDatabases() {
return _dropTables(mysqlServiceForSourceDb)
.then(() => _dropTables(mysqlServiceForTestDb));
}
/**
* @param {MysqlService} mysqlService
* @private
*/
function _dropTables(mysqlService) {
const dropTableQueries = [
`SET foreign_key_checks = 0;`,
'DROP TABLE IF EXISTS __testing;', // Necessary due to table pollution from other tests...@TODO: fix this
'DROP TABLE IF EXISTS users;',
`DROP TABLE IF EXISTS videos;`,
`DROP TABLE IF EXISTS user_downloads;`,
`SET foreign_key_checks = 1;`
];
return mysqlService.executeQueries(dropTableQueries);
}
/**
* @param {MysqlService} mysqlService
* @private
*/
function _createTables(mysqlService) {
const createQueries = [
`CREATE TABLE IF NOT EXISTS users (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(255) NOT NULL,
date_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX (email)
);`,
`INSERT INTO users (first_name, last_name, email) VALUES ('John', 'Doe', 'john.doe@gmail.com');`,
`CREATE TABLE IF NOT EXISTS videos (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(50) NOT NULL,
url VARCHAR(255) NOT NULL
);`,
`INSERT INTO videos (title, url) VALUES ('video 1', 'http://www.youtube.com/video1'), ('video 2', 'http://www.youtube.com/video2');`,
`CREATE TABLE IF NOT EXISTS user_downloads (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
video_id INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users (id),
FOREIGN KEY (video_id) REFERENCES videos (id)
);`,
`INSERT INTO user_downloads (user_id, video_id) SELECT u.id as user_id, v.id as video_id FROM users u CROSS JOIN videos v;`
];
return mysqlService.executeQueries(createQueries);
}