不要怂,就是干,撸起袖子干!

Commit 8c82d694 by turbofoxwave Committed by Sushant

add tests for postgres query-interface functions createSchema, databa… (#6775)

* add tests for postgres query-interface functions createSchema, databaseVersion, renameFunction
refactored file to address eslint warnings and errors

* Improve code style
1 parent c88bc257
'use strict'; 'use strict';
/* jshint -W030 */ /* jshint -W030 */
var chai = require('chai') const chai = require('chai');
, expect = chai.expect const expect = chai.expect;
, Support = require(__dirname + '/../../support') const Support = require(__dirname + '/../../support');
, dialect = Support.getTestDialect() const dialect = Support.getTestDialect();
, DataTypes = require(__dirname + '/../../../../lib/data-types') const DataTypes = require(__dirname + '/../../../../lib/data-types');
, Sequelize = require('../../../../index') const _ = require('lodash');
, Promise = Sequelize.Promise
, _ = require('lodash');
if (dialect.match(/^postgres/)) { if (dialect.match(/^postgres/)) {
describe('[POSTGRES Specific] QueryInterface', function () { describe('[POSTGRES Specific] QueryInterface', () => {
beforeEach(function () { beforeEach(function() {
this.sequelize.options.quoteIdenifiers = true; this.sequelize.options.quoteIdenifiers = true;
this.queryInterface = this.sequelize.getQueryInterface(); this.queryInterface = this.sequelize.getQueryInterface();
}); });
describe('createFunction', function () { describe('createSchema', () => {
beforeEach(function() {
// make sure we don't have a pre-existing schema called testSchema.
return this.queryInterface.dropSchema('testschema').reflect();
});
beforeEach( function () { it('creates a schema', function() {
//make sure we don't have a pre-existing function called create_job return this.queryInterface.createSchema('testschema')
//this is needed to cover the edge case of afterEach not getting called because of an unexpected issue or stopage with the .then(() => this.sequelize.query(`
//test suite causing a failure of afterEach's cleanup to be called. SELECT schema_name
return this.queryInterface.dropFunction('create_job',[{type:'varchar',name:'test'}]) FROM information_schema.schemata
//suppress errors here. if create_job doesn't exist thats ok. WHERE schema_name = 'testschema';
.catch( err => {}); `, { type: this.sequelize.QueryTypes.SELECT }))
.then(res => {
expect(res, 'query results').to.not.be.empty;
expect(res[0].schema_name).to.be.equal('testschema');
});
});
it('errors if the schema exists', function() {
return this.queryInterface.createSchema('testschema')
.catch(err => {
expect(err.message).to.be.equal('schema "testschema" already exists');
});
});
}); });
after( function () { describe('databaseVersion', () => {
//cleanup it('reports version', function() {
return this.queryInterface.dropFunction('create_job',[{type:'varchar',name:'test'}]) return this.queryInterface.databaseVersion()
//suppress errors here. if create_job doesn't exist thats ok. .then(res => {
.catch( err => {}); // check that result matches expected version number format. example 9.5.4
expect(res).to.match(/[0-9\.[0-9]\.[0-9]/);
});
});
}); });
it('creates a stored procedure', function () { describe('renameFunction', () => {
var body = 'return test;'; beforeEach(function() {
var options = {}; // ensure the function names we'll use don't exist before we start.
// then setup our function to rename
return this.queryInterface.dropFunction('rftest1', [])
.reflect()
.then(() => this.queryInterface.dropFunction('rftest2', []))
.reflect()
.then(() => this.queryInterface.createFunction('rftest1', [], 'varchar', 'plpgsql', 'return \'testreturn\';', {}));
});
//make our call to create a function it('renames a function', function() {
return this.queryInterface.createFunction('create_job', [{type:'varchar',name:'test'}], 'varchar', 'plpgsql', body, options) return this.queryInterface.renameFunction('rftest1', [], 'rftest2')
//validate .then(() => this.sequelize.query('select rftest2();', { type: this.sequelize.QueryTypes.SELECT }))
.then( () => { .then(res => {
return this.sequelize.query('select create_job(\'test\');', { type: this.sequelize.QueryTypes.SELECT }); expect(res[0].rftest2).to.be.eql('testreturn');
}) });
.then( res => {
return expect(res[0].create_job).to.be.eql('test');
}); });
}); });
it('treats options as optional', function () { describe('createFunction', () => {
var body = 'return test;';
//run with null options parameter beforeEach(function() {
return this.queryInterface.createFunction('create_job', [{type:'varchar',name:'test'}], 'varchar', 'plpgsql', body, null) // make sure we don't have a pre-existing function called create_job
//validate // this is needed to cover the edge case of afterEach not getting called because of an unexpected issue or stopage with the
.then( () => { // test suite causing a failure of afterEach's cleanup to be called.
return this.sequelize.query('select create_job(\'test\');', { type: this.sequelize.QueryTypes.SELECT }); return this.queryInterface.dropFunction('create_job', [{type:'varchar', name:'test'}])
}) // suppress errors here. if create_job doesn't exist thats ok.
.then( res => { .reflect();
return expect(res[0].create_job).to.be.eql('test'); });
after(function() {
// cleanup
return this.queryInterface.dropFunction('create_job', [{type:'varchar', name:'test'}])
// suppress errors here. if create_job doesn't exist thats ok.
.reflect();
});
it('creates a stored procedure', function() {
const body = 'return test;';
const options = {};
// make our call to create a function
return this.queryInterface.createFunction('create_job', [{type:'varchar', name:'test'}], 'varchar', 'plpgsql', body, options)
// validate
.then(() => this.sequelize.query('select create_job(\'test\');', { type: this.sequelize.QueryTypes.SELECT }))
.then(res => {
expect(res[0].create_job).to.be.eql('test');
});
});
it('treats options as optional', function() {
const body = 'return test;';
// run with null options parameter
return this.queryInterface.createFunction('create_job', [{type:'varchar', name:'test'}], 'varchar', 'plpgsql', body, null)
// validate
.then(() => this.sequelize.query('select create_job(\'test\');', { type: this.sequelize.QueryTypes.SELECT }))
.then(res => {
expect(res[0].create_job).to.be.eql('test');
}); });
}); });
it('produces an error when missing expected parameters', function () { it('produces an error when missing expected parameters', function() {
var body = 'return 1;'; const body = 'return 1;';
var options = {}; const options = {};
return Promise.all([ return Promise.all([
//requires functionName // requires functionName
expect( () => { expect(() => {
return this.queryInterface.createFunction(null, [{name:'test'}], 'integer', 'plpgsql', body, options); return this.queryInterface.createFunction(null, [{name:'test'}], 'integer', 'plpgsql', body, options);
}).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/) }).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/),
//requires Parameters array // requires Parameters array
,expect( () => { expect(() => {
return this.queryInterface.createFunction('create_job',null, 'integer', 'plpgsql', body, options); return this.queryInterface.createFunction('create_job', null, 'integer', 'plpgsql', body, options);
}).to.throw(/function parameters array required/) }).to.throw(/function parameters array required/),
//requires returnType // requires returnType
,expect( () => { expect(() => {
return this.queryInterface.createFunction('create_job', [{type:'varchar',name:'test'}], null, 'plpgsql', body, options); return this.queryInterface.createFunction('create_job', [{type:'varchar', name:'test'}], null, 'plpgsql', body, options);
}).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/) }).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/),
//requires type in parameter array // requires type in parameter array
,expect( () => { expect(() => {
return this.queryInterface.createFunction('create_job', [{name:'test'}], 'integer', 'plpgsql', body, options); return this.queryInterface.createFunction('create_job', [{name:'test'}], 'integer', 'plpgsql', body, options);
}).to.throw(/function or trigger used with a parameter without any type/) }).to.throw(/function or trigger used with a parameter without any type/),
//requires language // requires language
,expect( () => { expect(() => {
return this.queryInterface.createFunction('create_job', [{type:'varchar',name:'test'}], 'varchar', null, body, options); return this.queryInterface.createFunction('create_job', [{type:'varchar', name:'test'}], 'varchar', null, body, options);
}).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/) }).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/),
//requires body // requires body
,expect( () => { expect(() => {
return this.queryInterface.createFunction('create_job', [{type:'varchar',name:'test'}], 'varchar', 'plpgsql', null, options); return this.queryInterface.createFunction('create_job', [{type:'varchar', name:'test'}], 'varchar', 'plpgsql', null, options);
}).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/) }).to.throw(/createFunction missing some parameters. Did you pass functionName, returnType, language and body/)
]); ]);
}); });
}); });
describe('dropFunction',function () { describe('dropFunction', () => {
beforeEach( function () { beforeEach(function() {
var body = 'return test;'; const body = 'return test;';
var options = {}; const options = {};
//make sure we have a droptest function in place. // make sure we have a droptest function in place.
return this.queryInterface.createFunction('droptest', [{type:'varchar',name:'test'}], 'varchar', 'plpgsql', body, options) return this.queryInterface.createFunction('droptest', [{type:'varchar', name:'test'}], 'varchar', 'plpgsql', body, options)
//suppress errors.. this could fail if the function is already there.. thats ok. // suppress errors.. this could fail if the function is already there.. thats ok.
.catch( function (err) { }); .reflect();
}); });
it('can drop a function', function () { it('can drop a function', function() {
//call drop function return expect(
return expect(this.queryInterface.dropFunction('droptest',[{type:'varchar',name:'test'}]) // call drop function
//now call the function we attempted to drop.. if dropFunction worked as expect it should produce an error. this.queryInterface.dropFunction('droptest', [{type:'varchar', name:'test'}])
.then( () => { // now call the function we attempted to drop.. if dropFunction worked as expect it should produce an error.
.then(() => {
// call the function we attempted to drop.. if it is still there then throw an error informing that the expected behavior is not met. // call the function we attempted to drop.. if it is still there then throw an error informing that the expected behavior is not met.
return this.sequelize.query('select droptest(\'test\');', { type: this.sequelize.QueryTypes.SELECT }); return this.sequelize.query('select droptest(\'test\');', { type: this.sequelize.QueryTypes.SELECT });
})) })
//test that we did get the expected error indicating that droptest was properly removed. // test that we did get the expected error indicating that droptest was properly removed.
.to.be.rejectedWith(/.*function droptest.* does not exist/); ).to.be.rejectedWith(/.*function droptest.* does not exist/);
}); });
it('produces an error when missing expected parameters', function () { it('produces an error when missing expected parameters', function() {
return Promise.all([ return Promise.all([
expect( () => { expect(() => {
return this.queryInterface.dropFunction(); return this.queryInterface.dropFunction();
}).to.throw(/.*requires functionName/) }).to.throw(/.*requires functionName/),
,
expect( () => { expect(() => {
return this.queryInterface.dropFunction('droptest'); return this.queryInterface.dropFunction('droptest');
}).to.throw(/.*function parameters array required/) }).to.throw(/.*function parameters array required/),
,
expect( () => { expect(() => {
return this.queryInterface.dropFunction('droptest', [{name:'test'}]); return this.queryInterface.dropFunction('droptest', [{name:'test'}]);
}).to.be.throw(/.*function or trigger used with a parameter without any type/) }).to.be.throw(/.*function or trigger used with a parameter without any type/)
]); ]);
}); });
}); });
describe('indexes', function () { describe('indexes', () => {
beforeEach(function () { beforeEach(function() {
var self = this; return this.queryInterface.dropTable('Group')
return this.queryInterface.dropTable('Group').then(function () { .then(() => this.queryInterface.createTable('Group', {
return self.queryInterface.createTable('Group', {
username: DataTypes.STRING, username: DataTypes.STRING,
isAdmin: DataTypes.BOOLEAN, isAdmin: DataTypes.BOOLEAN,
from: DataTypes.STRING from: DataTypes.STRING
}); }));
});
}); });
it('adds, reads and removes a named functional index to the table', function () { it('adds, reads and removes a named functional index to the table', function() {
var self = this;
return this.queryInterface.addIndex('Group', [this.sequelize.fn('lower', this.sequelize.col('username'))], { return this.queryInterface.addIndex('Group', [this.sequelize.fn('lower', this.sequelize.col('username'))], {
name: 'group_username_lower' name: 'group_username_lower'
}).then(function () { })
return self.queryInterface.showIndex('Group').then(function (indexes) { .then(() => this.queryInterface.showIndex('Group'))
var indexColumns = _.uniq(indexes.map(function (index) { .then(indexes => {
return index.name; const indexColumns = _.uniq(indexes.map(index => index.name));
}));
expect(indexColumns).to.include('group_username_lower'); expect(indexColumns).to.include('group_username_lower');
return self.queryInterface.removeIndex('Group', 'group_username_lower').then(function () { })
return self.queryInterface.showIndex('Group').then(function (indexes) { .then(() => this.queryInterface.removeIndex('Group', 'group_username_lower'))
indexColumns = _.uniq(indexes.map(function (index) { .then(() => this.queryInterface.showIndex('Group'))
return index.name; .then(indexes => {
})); const indexColumns = _.uniq(indexes.map(index => index.name));
expect(indexColumns).to.be.empty; expect(indexColumns).to.be.empty;
}); });
}); });
}); });
}); });
});
});
});
} }
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!