Restructured Tests

- removed previous testfiles
- added test.js where all tests are stored
- added tests for lib/utils
- added standard test config
- added test config to devDependencies in package.json
- reconfigured circleci configuration
pull/26/head
Trivernis 6 years ago
parent a712f41a55
commit d5d5c12126

@ -30,6 +30,10 @@ jobs:
name: Installing dependencies name: Installing dependencies
command: npm install command: npm install
- run:
name: Installing dependencies
command: npm install --save-dev
- run: - run:
name: installing additional dependencies name: installing additional dependencies
command: npm install sqlite3 command: npm install sqlite3
@ -41,17 +45,9 @@ jobs:
- run: - run:
name: Creating config file name: Creating config file
command: echo {} >> config.json command: echo {api:{}} >> config.json
# run tests! # run tests!
- run: - run:
name: Testing ./lib/music name: Unit testing
command: node ./testscripts/musicTest.js command: npm test
- run:
name: Testing ./lib/cmd
command: node ./testscripts/cmdTest.js
- run:
name: Testing ./lib/guilding
command: node ./testscripts/guildingTest.js

1
.gitignore vendored

@ -1,5 +1,6 @@
.log .log
.idea .idea
.nyc_output
data data
package-lock.json package-lock.json
node_modules node_modules

@ -36,7 +36,7 @@ exports.objectDeepFind = function (object, attributePath) {
let current = object, let current = object,
paths = attributePath.split('.'); paths = attributePath.split('.');
for (let path of paths) { for (let path of paths) {
if (current[path]) if (current[path] !== undefined && current[path] !== null)
current = current[path]; current = current[path];
else else
return undefined; return undefined;
@ -100,8 +100,8 @@ exports.YouTube = class {
* @returns {boolean} * @returns {boolean}
*/ */
static isValidUrl(url) { static isValidUrl(url) {
return /https?:\/\/www.youtube.com\/(watch\?v=|playlist\?list=)/g.test(url) || return /https?:\/\/(www\.)?youtube\.com\/(watch\?v=|playlist\?list=)/g.test(url) ||
/https?:\/\/youtu.be\//g.test(url); /https?:\/\/youtu\.be\//g.test(url);
} }
/** /**
@ -110,8 +110,8 @@ exports.YouTube = class {
* @returns {boolean} * @returns {boolean}
*/ */
static isValidEntityUrl(url) { static isValidEntityUrl(url) {
return /https?:\/\/www.youtube.com\/(watch\?v=.+?|playlist\?list=.+?)/g.test(url) || return /https?:\/\/(www\.)?youtube\.com\/(watch\?v=.+?|playlist\?list=.+?)/g.test(url) ||
/https?:\/\/youtu.be\/.+?/g.test(url); /https?:\/\/youtu\.be\/.+?/g.test(url);
} }
/** /**
@ -120,7 +120,7 @@ exports.YouTube = class {
* @returns {boolean} * @returns {boolean}
*/ */
static isValidPlaylistUrl(url) { static isValidPlaylistUrl(url) {
return /https?:\/\/www.youtube.com\/playlist\?list=.+?/g.test(url); return /https?:\/\/(www\.)?youtube\.com\/playlist\?list=.+?/g.test(url);
} }
/** /**
@ -129,15 +129,17 @@ exports.YouTube = class {
* @returns {boolean} * @returns {boolean}
*/ */
static isValidVideoUrl(url) { static isValidVideoUrl(url) {
return /https?:\/\/www.youtube.com\/watch\?v=.+?/g.test(url) || /https?:\/\/youtu.be\/.+?/g.test(url); return /https?:\/\/(www\.)?youtube\.com\/watch\?v=.+?/g.test(url) || /https?:\/\/youtu\.be\/.+?/g.test(url);
} }
/** /**
* Returns the id for a youtube video stripped from the url * Returns the id for a youtube video stripped from the url
* @param url * @param url
* @returns {RegExpMatchArray} * @returns {String}
*/ */
static getPlaylistIdFromUrl(url) { static getPlaylistIdFromUrl(url) {
if (!exports.YouTube.isValidPlaylistUrl(url))
return null;
let matches = url.match(/(?<=\?list=)[\w\-]+/); let matches = url.match(/(?<=\?list=)[\w\-]+/);
if (matches) if (matches)
return matches[0]; return matches[0];
@ -148,13 +150,21 @@ exports.YouTube = class {
/** /**
* Returns the id for a youtube video stripped from the url * Returns the id for a youtube video stripped from the url
* @param url * @param url
* @return {String}
*/ */
static getVideoIdFromUrl(url) { static getVideoIdFromUrl(url) {
let matches = url.match(/(?<=\?v=)[\w\-]+/); if (!exports.YouTube.isValidVideoUrl(url))
if (matches)
return matches[0];
else
return null; return null;
let matches1 = url.match(/(?<=\?v=)[\w\-]+/);
if (matches1)
return matches1[0];
else {
let matches2 = url.match(/(?<=youtu\.be\/)[\w\-]+/);
if (matches2)
return matches2[0];
else
return null;
}
} }
/** /**
@ -177,9 +187,8 @@ exports.YouTube = class {
exports.ConfigVerifyer = class { exports.ConfigVerifyer = class {
/** /**
* @param confFile {String} the file that needs to be verified * @param confObj
* @param required {Array} the attributes that are required for the bot to work * @param required {Array} the attributes that are required for the bot to work
* @param optional {Array} the attributes that are optional (and may provide extra features)
*/ */
constructor(confObj, required) { constructor(confObj, required) {
this.config = confObj; this.config = confObj;
@ -192,12 +201,12 @@ exports.ConfigVerifyer = class {
verifyConfig(logger) { verifyConfig(logger) {
let missing = []; let missing = [];
for (let reqAttr of this.requiredAttributes) { for (let reqAttr of this.requiredAttributes) {
if (!exports.objectDeepFind(this.config, reqAttr)) if (exports.objectDeepFind(this.config, reqAttr) === undefined)
missing.push(reqAttr); missing.push(reqAttr);
} }
this.missingAttributes = missing; this.missingAttributes = missing;
this.logMissing(logger); this.logMissing(logger);
return this.missingAttributes.length > 0; return this.missingAttributes.length === 0;
} }
/** /**
@ -206,10 +215,7 @@ exports.ConfigVerifyer = class {
*/ */
logMissing(logger) { logMissing(logger) {
if (this.missingAttributes.length > 0) { if (this.missingAttributes.length > 0) {
logger.error("Missing required Attributes"); logger.error(`Missing required Attributes ${this.missingAttributes.join(', ')}`);
for (let misAttr of this.missingAttributes) {
logger.warn(`Missing Attribute ${misAttr} in config.json`);
}
} }
} }
}; };

@ -2,7 +2,9 @@
"name": "discordbot", "name": "discordbot",
"version": "1.0.0", "version": "1.0.0",
"scripts": { "scripts": {
"start": "node bot.js" "start": "node bot.js",
"test": "mocha",
"test-unit": "NODE_ENV=test mocha '/**/*.spec.js'"
}, },
"dependencies": { "dependencies": {
"args-parser": "1.1.0", "args-parser": "1.1.0",
@ -15,5 +17,12 @@
"winston-daily-rotate-file": "3.6.0", "winston-daily-rotate-file": "3.6.0",
"youtube-playlist-info": "1.1.2", "youtube-playlist-info": "1.1.2",
"ytdl-core": "0.29.1" "ytdl-core": "0.29.1"
},
"devDependencies": {
"assert": "^1.4.1",
"chai": "^4.2.0",
"mocha": "^5.2.0",
"nyc": "^13.1.0",
"sinon": "^7.2.3"
} }
} }

@ -1,7 +1,8 @@
exports.mockLogger = { exports.mockLogger = {
error: msg => raise(msg), error: msg => {
throw new Error(msg);
},
warn: msg => console.error("warn: ", msg), warn: msg => console.error("warn: ", msg),
warning: msg => console.error("warn: ", msg),
info: msg => console.log("info: ", msg), info: msg => console.log("info: ", msg),
verbose: msg => console.log("verbose: ", msg), verbose: msg => console.log("verbose: ", msg),
debug: msg => console.log("debug: ", msg) debug: msg => console.log("debug: ", msg)
@ -48,4 +49,4 @@ exports.mockVoicechannel = {
exports.mockChannel = { exports.mockChannel = {
send: (msg) => console.log('Send: ', msg) send: (msg) => console.log('Send: ', msg)
} };

@ -0,0 +1,10 @@
const sinon = require('sinon'),
chai = require('chai');
beforeEach(() => {
this.sandbox = sinon.createSandbox();
});
afterEach(() => {
this.sandbox.restore();
});

@ -0,0 +1,190 @@
const mockobjects = require('./mockobjects.js'),
sinon = require('sinon');
let Discord = require("discord.js"),
assert = require('assert'),
config = require('../config.json');
describe('lib/utils', function() {
const utils = require('../lib/utils.js');
describe('#YouTube', function() {
it('returns if an url is valid', function(done) {
assert(utils.YouTube.isValidUrl('https://www.youtube.com/watch?v=VID-ID'));
assert(utils.YouTube.isValidUrl('https://youtube.com/playlist?list=PL-ID'));
assert(utils.YouTube.isValidUrl('https://youtube.com/watch?v='));
assert(utils.YouTube.isValidUrl('https://www.youtube.com/playlist?list='));
assert(utils.YouTube.isValidUrl('https://youtu.be/VIDID'));
assert(utils.YouTube.isValidUrl('https://youtu.be/'));
assert(utils.YouTube.isValidUrl('http://youtube.com/watch?v=VID-ID'));
assert(utils.YouTube.isValidUrl('http://youtube.com/playlist?list=PL-ID'));
assert(utils.YouTube.isValidUrl('http://youtube.com/watch?v='));
assert(utils.YouTube.isValidUrl('http://youtube.com/playlist?list='));
assert(!utils.YouTube.isValidUrl('https://github.com'));
assert(!utils.YouTube.isValidUrl('notevenanurl'));
done();
});
it('returns if an url is a valid entity url', function(done) {
assert(utils.YouTube.isValidEntityUrl('https://youtube.com/watch?v=VID-ID'));
assert(utils.YouTube.isValidEntityUrl('https://youtube.com/playlist?list=PL-ID'));
assert(utils.YouTube.isValidEntityUrl('https://youtu.be/VIDID'));
assert(utils.YouTube.isValidEntityUrl('http://www.youtube.com/watch?v=VID-ID'));
assert(utils.YouTube.isValidEntityUrl('http://youtube.com/playlist?list=PL-ID'));
assert(!utils.YouTube.isValidEntityUrl('https://youtube.com/watch?v='));
assert(!utils.YouTube.isValidEntityUrl('https://youtube.com/playlist?list='));
assert(!utils.YouTube.isValidEntityUrl('https://youtu.be/'));
assert(!utils.YouTube.isValidEntityUrl('https://github.com'));
assert(!utils.YouTube.isValidEntityUrl('notevenanurl'));
done();
});
it('returns if an url is a valid playlist url', function(done) {
assert(!utils.YouTube.isValidPlaylistUrl('https://youtube.com/watch?v=VID-ID'));
assert(utils.YouTube.isValidPlaylistUrl('https://youtube.com/playlist?list=PL-ID'));
assert(!utils.YouTube.isValidPlaylistUrl('https://youtu.be/VIDID'));
assert(!utils.YouTube.isValidPlaylistUrl('http://www.youtube.com/watch?v=VID-ID'));
assert(utils.YouTube.isValidPlaylistUrl('http://youtube.com/playlist?list=PL-ID'));
assert(!utils.YouTube.isValidPlaylistUrl('http://youtube.com/playlist?list='));
assert(!utils.YouTube.isValidPlaylistUrl('https://github.com'));
assert(!utils.YouTube.isValidPlaylistUrl('notevenanurl'));
done();
});
it('returns if an url is a valid video url', function(done) {
assert(utils.YouTube.isValidVideoUrl('https://youtube.com/watch?v=VID-ID'));
assert(!utils.YouTube.isValidVideoUrl('https://youtube.com/playlist?list=PL-ID'));
assert(utils.YouTube.isValidVideoUrl('https://youtu.be/VIDID'));
assert(utils.YouTube.isValidVideoUrl('http://www.youtube.com/watch?v=VID-ID'));
assert(!utils.YouTube.isValidVideoUrl('http://youtube.com/playlist?list=PL-ID'));
assert(!utils.YouTube.isValidVideoUrl('https://youtube.com/watch?v='));
assert(!utils.YouTube.isValidVideoUrl('https://youtu.be/'));
assert(!utils.YouTube.isValidVideoUrl('https://github.com'));
assert(!utils.YouTube.isValidVideoUrl('notevenanurl'));
done();
});
it('returns the id for a playlist url', function(done) {
let getPlId = utils.YouTube.getPlaylistIdFromUrl;
assert('PL-ID' === getPlId('https://youtube.com/playlist?list=PL-ID'));
assert('PL-ID' === getPlId('http://youtube.com/playlist?list=PL-ID'));
assert('PL-ID' === getPlId('https://www.youtube.com/playlist?list=PL-ID'));
assert('PL-ID' === getPlId('https://www.youtube.com/playlist?list=PL-ID'));
assert(null === getPlId('https://www.youtube.com/playlist?list='));
done();
});
it('returns the id for a video url', function(done) {
let getVidId = utils.YouTube.getVideoIdFromUrl;
assert('VID-ID' === getVidId('https://youtube.com/watch?v=VID-ID'));
assert('VID-ID' === getVidId('http://youtube.com/watch?v=VID-ID'));
assert('VID-ID' === getVidId('https://www.youtube.com/watch?v=VID-ID'));
assert('VID-ID' === getVidId('https://youtu.be/VID-ID'));
assert(null === getVidId('https://www.faketube.com/watch?v=VID-ID'));
assert(null === getVidId('tu.be/VID-ID'));
assert(null === getVidId('https://youtube.com/watch?v='));
assert(null === getVidId('https://youtu.be/'));
done();
});
it('returns the video url for an id', function(done) {
let getVid4Id = utils.YouTube.getVideoUrlFromId;
assert('https://www.youtube.com/watch?v=VID-ID', getVid4Id('VID-ID'));
assert('https://www.youtube.com/watch?v=12345567885432', getVid4Id('12345567885432'));
done();
});
it('returns the thumbnail url for a video url', function(done) {
let getVid4Id = utils.YouTube.getVideoUrlFromId;
let getTh4Id = utils.YouTube.getVideoThumbnailUrlFromUrl;
assert('https://i3.ytimg.com/vi/VIDID/maxresdefault.jpg', getTh4Id(getVid4Id('VIDID')));
assert('https://i3.ytimg.com/vi/1234/maxresdefault.jpg', getTh4Id(getVid4Id('1234')));
done();
})
});
describe('#ConfigVerifyer', function() {
it('verifies correct configs', function(done) {
const testObj = {
'key1': {
'key2': 'value2',
'key3': 'value3'
},
'key4': [],
'key5': false,
'key6': 'a longer string',
'key7': {
'key8': [{
'key9': 'okay...'
}]
}
};
let confVer = new utils.ConfigVerifyer(testObj, ['key1', 'key1.key3']);
assert(confVer.verifyConfig(mockobjects.mockLogger));
confVer = new utils.ConfigVerifyer(testObj, ['key1', 'key1.key2', 'key7.key8.0.key9']);
assert(confVer.verifyConfig(mockobjects.mockLogger));
confVer = new utils.ConfigVerifyer(testObj, ['key4', 'key1.key2', 'key5', 'key7']);
assert(confVer.verifyConfig(mockobjects.mockLogger));
done();
});
it('rejects invalid configs', function(done) {
const testObj = {
};
let modifiedMockLogger = mockobjects.mockLogger;
modifiedMockLogger.error = (msg) => {};
let confVer = new utils.ConfigVerifyer(testObj, ['key1', 'key1.key3']);
assert(!confVer.verifyConfig(mockobjects.mockLogger));
confVer = new utils.ConfigVerifyer(testObj, ['key1', 'key1.key2', 'key7.key8.0.key9']);
assert(!confVer.verifyConfig(mockobjects.mockLogger));
done();
})
});
});
// TODO: Repair and activate later
describe('The dj class', function *() {
const music = require('../lib/music');
let ytdl = require("ytdl-core");
let yttl = require('get-youtube-title');
let ypi = require('youtube-playlist-info');
let ytdlMock = sinon.mock(ytdl);
let yttlMock = sinon.mock(yttl);
let ypiMock = sinon.mock(ypi);
it('connects to a VoiceChannel', function () {
let dj = new music.DJ(mockobjects.mockVoicechannel);
dj.connect();
console.log(dj.connected);
assert(dj.connected);
});
it('listens on Repeat', function() {
let dj = new music.DJ(mockobjects.mockVoicechannel);
dj.current = {'url': '', 'title': ''};
dj.listenOnRepeat = true;
assert(dj.repeat);
assert(dj.queue.length > 0);
});
it('plays Files', function () {
let dj = new music.DJ(mockobjects.mockVoicechannel);
dj.connect();
dj.playFile();
assert(dj.playing);
});
it('plays YouTube urls', function () {
let dj = new music.DJ(mockobjects.mockVoicechannel);
dj.playYouTube('http://www.youtube.com/watch?v=abc');
assert(dj.playing);
});
});

@ -1,33 +0,0 @@
const music = require('../lib/music.js'),
mockobjects = require('./mockobjects.js');
function main() {
let dj = new music.DJ(mockobjects.mockVoicechannel)
music.setLogger(mockobjects.mockLogger);
dj.connect().then(() => {
console.log('connected', dj.connected);
dj.playFile('test');
dj.playYouTube('https://www.youtube.com/watch?v=TEST');
dj.setVolume(1);
dj.pause();
dj.resume();
dj.skip();
dj.stop();
dj.shuffle();
console.log('dj.playlist: ', dj.playlist);
console.log('dj.song: ', dj.song);
dj.clear();
process.exit(0);
});
}
// Executing the main function
if (typeof require !== 'undefined' && require.main === module) {
process.on('unhandledRejection', (reason, p) => {
console.error('Unhandled Rejection at: Promise', p, 'reason:', reason);
throw Error('Promise rejection');
});
setTimeout(() => process.exit(1), 60000);
main();
}
Loading…
Cancel
Save