koc
Version:
Library to parse data from the online MMORPG Kings of Chaos
1,263 lines (1,242 loc) • 86.4 kB
JavaScript
/*global describe, it, before, beforeEach, after, afterEach */
var chai = require('chai'),
chaiAsPromised = require("chai-as-promised"),
fs = require('fs'),
KoC = require('../lib/koc'),
helpers = require('../lib/helpers'),
koc = new KoC();
chai.use(chaiAsPromised);
chai.should();
describe('Parse Battlefield', function () {
var htmlPaths = [
// htmlPath , loggedIn, # , total, current, max
['test/html/battlefield_full_logged-out.html' , false, 20, 2110, 1, 106],
['test/html/battlefield_xhr_logged-out.html' , false, 20, 2108, 2, 106],
['test/html/battlefield_xhr_logged-in.html' , true, 20, 2088, 103, 105],
['test/html/battlefield_full_first-login.html', true, 20, 2093, 100, 105],
['test/html/battlefield_xhr_02.html' , true, 20, 1877, 83, 94],
['test/html/battlefield_xhr_03.html' , true, 20, 1877, 84, 94],
['test/html/battlefield_xhr_04.html' , true, 20, 1881, 84, 95],
['test/html/battlefield_xhr_05.html' , true, 20, 1882, 76, 95],
['test/html/attack.html' , true, 20, 1406, 68, 71],
];
htmlPaths.forEach(function (currentCase) {
var htmlPath = currentCase[0];
var loggedIn = currentCase[1];
var recordsNb = currentCase[2];
var totalPlayers = currentCase[3];
var currentPage = currentCase[4];
var maxPage = currentCase[5];
describe('#' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseBattlefield(html);
it('should return ' + recordsNb + ' players', function () {
return result.should.have.property('players').that.has.length(recordsNb);
});
var index = 0;
result.players.forEach(function (player) {
index++;
var requiredFields = ['userid', 'alliance', 'username', 'armySize', 'armySizeText', 'race', 'gold', 'goldText', 'rank', 'rankText'];
requiredFields.forEach(function (requiredField) {
it("player #" + index.toString() + " should have '" + requiredField + "'", function () {
return player.should.have.property(requiredField).that.is.not.undefined;
});
});
});
it('loggedIn should be: ' + loggedIn, function () {
return result.should.have.property('loggedIn').that.eql(loggedIn);
});
it('should have ' + totalPlayers + ' total players', function () {
return result.should.have.property('playersTotal').that.eql(totalPlayers);
});
it('should be on page ' + currentPage + ' / ' + maxPage + ' of the battlefield', function () {
result.should.have.property('currentPage').that.eql(currentPage);
result.should.have.property('maxPage').that.eql(maxPage);
});
});
});
});
describe('Login', function () {
describe("#wrong credentials", function () {
var loginPromise = koc.login("wrong username", "wrong password");
it('should be fulfilled', function () {
return loginPromise.should.be.fulfilled;
});
it('should have a session field', function () {
return loginPromise.should.eventually.have.property("session").that.is.not.empty;
});
it('should have success field', function () {
return loginPromise.should.eventually.have.property("success").that.is.false;
});
it('should have error field', function () {
return loginPromise.should.eventually.have.property("error").that.is.not.empty;
});
});
});
describe('ReCaptcha Image', function () {
describe('#get image', function () {
var imagePromise = koc.getReCaptchaChallenge();
it('should be fulfilled', function () {
return imagePromise.should.be.fulfilled;
});
it('should have success field', function () {
return imagePromise.should.eventually.have.property("success").that.is.true;
});
it('should have image field', function () {
return imagePromise.should.eventually.have.property("result").that.has.property("image").that.is.not.empty;
});
it('should have challenge field', function () {
return imagePromise.should.eventually.have.property("result").that.has.property("challenge").that.is.not.empty;
});
});
});
describe('Signup', function () {
describe('#verification wrong username and password', function () {
var verifyPromise = koc.verify("wrong username", "wrong password", "not same password");
it('should be fulfilled', function () {
return verifyPromise.should.be.fulfilled;
});
it('should have success field', function () {
return verifyPromise.should.eventually.have.property("success").that.is.true;
});
it('should have username field', function () {
return verifyPromise.should.eventually.have.property("result").that.has.property("username").that.is.not.empty;
});
it('should have password field', function () {
return verifyPromise.should.eventually.have.property("result").that.has.property("password").that.is.not.empty;
});
});
describe('#verification wrong username correct pass', function () {
var verifyPromise = koc.verify("wrong username", "AcceptedPass", "AcceptedPass");
it('should be fulfilled', function () {
return verifyPromise.should.be.fulfilled;
});
it('should have success field', function () {
return verifyPromise.should.eventually.have.property("success").that.is.true;
});
it('should have username field', function () {
return verifyPromise.should.eventually.have.property("result").that.has.property("username").that.is.not.empty;
});
it('should have password field', function () {
return verifyPromise.should.eventually.have.property("result").that.has.property("password").that.is.empty;
});
});
});
describe('Parse Base', function () {
var htmlPaths = [
'test/html/base_first-login.html',
'test/html/base_01.html',
'test/html/base_02.html',
'test/html/base_commander.html'
];
htmlPaths.forEach(function (htmlPath) {
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseBase(html);
//console.log(result);
it('should be an object', function () {
return result.should.be.an('object');
});
var requiredFields = [
['userInfo',
['userid', 'username', 'race', 'rank', 'highestRank', 'commander']],
['militaryOverview',
['fortification', 'siegeTechnology', 'economy', 'technology',
'conscription', 'availableFunds', 'projectedIncome',
'gameTurns', 'covertLevel']],
['militaryEffectiveness',
['strikeAction', 'strikeActionRank', 'defensiveAction', 'defensiveActionRank',
'spyRating', 'spyRatingRank', 'sentryRating', 'sentryRatingRank']],
['personnel', ['trainedAttackSoldiers', 'trainedAttackMercenaries',
'trainedDefenseSoldiers', 'trainedDefenseMercenaries',
'untrainedSoldiers', 'untrainedMercenaries', 'spies', 'sentries',
'armyMorale', 'totalFightingForce']]
];
requiredFields.forEach(function (requiredField) {
var field = requiredField[0];
var subfields = requiredField[1];
it("Should have '" + field + "' that is an object", function () {
return result.should.have.property(field).that.is.an('object');
});
var fieldValue = result[field];
subfields.forEach(function (subfield) {
it("Field '" + field + "' should have property '" + subfield + "' that is not empty", function () {
return fieldValue.should.have.property(subfield).that.is.not.empty;
});
});
});
it("Should have an array 'previousLogins'", function () {
return result.should.have.property("previousLogins").that.is.an('array');
});
var previousLogins = result.previousLogins;
if (previousLogins !== undefined) {
previousLogins.forEach(function (previousLogin) {
['ip', 'date', 'success'].forEach(function (previousLoginField) {
it("A previous login should have '" + previousLoginField + "' that is not empty", function () {
return previousLogin.should.have.property(previousLoginField).that.is.not.empty;
});
});
});
}
it("Should have the number of changes left", function () {
return result.should.have.property("raceChangesLeft").that.is.a('number').that.is.gte(0);
});
it("Should have an array 'recentAttacksOnYou'", function () {
return result.should.have.property("recentAttacksOnYou").that.is.an('array');
});
var recentAttacks = result.recentAttacksOnYou;
if (recentAttacks !== undefined) {
recentAttacks.forEach(function (recentAttack) {
['date', 'result'].forEach(function (previousLoginField) {
it("A recent attack should have '" + previousLoginField + "' that is not empty", function () {
return recentAttack.should.have.property(previousLoginField).that.is.not.empty;
});
});
it("should have a field 'enemy' that has non-empty property 'username'", function () {
return recentAttack.should.have.property('enemy').that.is.an('object').that.has.property('username').that.is.not.empty;
});
it("should have a field 'enemy' that has non-empty property 'userid'", function () {
return recentAttack.should.have.property('enemy').that.is.an('object').that.has.property('userid').that.is.not.empty;
});
});
}
});
});
describe("#remote failing because no session id", function () {
var localKoC = new KoC();
var basePromise = localKoC.getUserInfo();
it('should be fulfilled', function () {
return basePromise.should.be.fulfilled;
});
it('should have success field', function () {
return basePromise.should.eventually.have.property("success").that.is.false;
});
it('should have error field', function () {
return basePromise.should.eventually.have.property("error").that.is.not.empty;
});
it('should have a user field', function () {
return basePromise.should.eventually.have.property("result").that.has.property("user").that.is.empty;
});
});
describe("#remote failing because not logged in", function () {
var localKoC = new KoC();
localKoC.setSession("invalid session");
var basePromise = localKoC.getUserInfo();
it('should be fulfilled', function () {
return basePromise.should.be.fulfilled;
});
it('should have session field', function () {
return basePromise.should.eventually.have.property("session").that.is.not.empty;
});
it('should have success field', function () {
return basePromise.should.eventually.have.property("success").that.is.false;
});
it('should have error field', function () {
return basePromise.should.eventually.have.property("error").that.is.not.empty;
});
});
});
describe('Parse Left-Side Box', function () {
var htmlPaths = [
// page , has the box, has username/fortification in the title
['test/html/base_first-login.html', true, true],
['test/html/base_01.html', true, true],
['test/html/base_mails_read.html', true, true],
['test/html/battlefield_full_logged-out.html', false, false],
['test/html/battlefield_xhr_logged-out.html', false, false],
['test/html/battlefield_xhr_logged-in.html', false, false],
['test/html/battlefield_full_first-login.html', true, false],
['test/html/home.html', false, false],
['test/html/verify.html', true, false]
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var hasBox = page[1];
var hasUsernameFortification = page[2];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseLeftSideBox(html);
//console.log(result);
it('should be an object', function () {
return result.should.be.an('object');
});
var fields = ['goldText', 'experienceText', 'turns', 'rank',
'lastAttacked', 'mails'];
if (hasUsernameFortification===true){
fields.push('username', 'fortification');
}
fields.forEach(function (field) {
it("should have property '" + field + "'", function () {
return result.should.have.property(field).that.is.not.empty;
});
if (hasBox)
it("property '" + field + "' should not be ???", function () {
return result.should.have.property(field).that.is.not.equal("???");
});
});
it("should have property 'newMails' which is a boolean", function () {
return result.should.have.property("newMails").that.is.a('boolean');
});
if (hasBox) {
it("should have property 'gold' which is a number", function () {
return result.should.have.property("gold").that.is.a('number');
});
it("should have property 'experience' which is a number", function () {
return result.should.have.property("experience").that.is.a('number');
});
}
});
});
});
describe('Parse Races Information', function () {
describe("#remote", function () {
var basePromise = koc.getRacesInformation();
it('should be fulfilled', function () {
return basePromise.should.be.fulfilled;
});
it('should have success field that is true', function () {
return basePromise.should.eventually.have.property("success").that.is.true;
});
it('should have kocHost field that is a string of length > 4', function () {
return basePromise.should.eventually.have.property("kocHost").that.is.a('string').that.has.length.above(4);
});
it('should have races field that is an array of 5 items and features should be an array', function () {
return basePromise.should.eventually.have.property("result").that.has.property("races")
.that.is.an('array')
.that.has.length(5)
.that.has.deep.property('[0]')
.that.contain.keys('race', 'description', 'features', 'image', 'colours')
.that.has.property('features').that.is.an('array');
});
it('should have races field that is an array of 5 items and colours should be an object', function () {
return basePromise.should.eventually.have.property("result").that.has.property("races")
.that.is.an('array')
.that.has.length(5)
.that.has.deep.property('[0]')
.that.contain.keys('race', 'description', 'features', 'image', 'colours')
.that.has.property('colours').that.is.an('object').that.contain.keys('background', 'border', 'text');
});
});
});
describe('Parse New User Advisor', function () {
var htmlPaths = [
// page , has it, expected to contain
['test/html/alliances_first-time.html', true, 'Alliances allow players to work together'],
['test/html/armory_first-time.html', true, 'status of your weapons and tools'],
['test/html/attacklog_first-time.html', true, 'record of all incoming and outgoing attacks'],
['test/html/base_first-login.html', true, 'This is your Command Center'],
['test/html/base_01.html', true, 'This is your Command Center'],
['test/html/base_mails_read.html', true, 'This is your Command Center'],
['test/html/battlefield_full_logged-out.html', false],
['test/html/battlefield_xhr_logged-out.html', false],
['test/html/battlefield_xhr_logged-in.html', false],
['test/html/battlefield_full_first-login.html', true, 'This is the battlefield page'],
['test/html/buddylist_first-time.html', true, 'players of interest for later reference'],
['test/html/conquest_first-time.html', true, 'quickest way to gain Experience'],
['test/html/home.html', false],
['test/html/intel_first-time.html', true, 'results of intercepted incoming Sabotage and Recon missions'],
['test/html/mercs_first-time.html', true, 'increase your Army\'s size for a fee'],
['test/html/recruit_first-time.html', true, 'effective way for you to build your army\'s morale'],
['test/html/stats_first-time.html', true, 'view information about other players'],
['test/html/train_first-time.html', true, 'train your soldiers to be one of four types'],
['test/html/verify.html', false]
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var hasHelp = page[1];
var shouldContain = page[2];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseNewUserAdvisor(html);
//console.log(result);
it('should be a string', function () {
return result.should.be.a('string');
});
if (hasHelp) {
it("should be a string of length > 4", function () {
return result.should.be.a('string').and.has.length.above(4);
});
it("should contain '" + shouldContain + "'", function () {
return result.should.be.a('string').and.contain(shouldContain);
});
}
else {
it("should be empty", function () {
return result.should.be.a('string').and.equal('');
});
}
});
});
});
describe('Parse Error', function () {
var htmlPaths = [
// page , expected to be
['test/html/error_please-login.html', 'Please login to view that page.'],
['test/html/error_cookies.html', 'An unknown error has occurred. Please check to make sure cookies are enabled.'],
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var expected = page[1];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseErrorMessage(html);
//console.log(result);
it('should be a string', function () {
return result.should.be.a('string');
});
it("should be a string of length > 4", function () {
return result.should.be.a('string').and.has.length.above(4);
});
it("should equal '" + expected + "'", function () {
return result.should.be.a('string').and.equal(expected);
});
});
});
});
describe('Parse Banned', function () {
var htmlPaths = [
// page , expected to be
['test/html/bansuspend.html', 'You have been banned for Violating KoC Rules']
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var expected = page[1];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseBannedMessage(html);
//console.log(result);
it('should be a string', function () {
return result.should.be.a('string');
});
it("should be a string of length > 4", function () {
return result.should.be.a('string').and.has.length.above(4);
});
it("should equal '" + expected + "'", function () {
return result.should.be.a('string').and.equal(expected);
});
});
});
});
describe('Parse Age', function () {
var htmlPaths = [
// page
'test/html/alliances_first-time.html',
'test/html/armory_first-time.html',
'test/html/attacklog_first-time.html',
'test/html/base_first-login.html',
'test/html/base_01.html',
'test/html/base_mails_read.html',
'test/html/battlefield_full_logged-out.html',
//'test/html/battlefield_xhr_logged-out.html',
//'test/html/battlefield_xhr_logged-in.html',
'test/html/battlefield_full_first-login.html',
'test/html/buddylist_first-time.html',
'test/html/conquest_first-time.html',
'test/html/home.html',
'test/html/intel_first-time.html',
'test/html/mercs_first-time.html',
'test/html/recruit_first-time.html',
'test/html/stats_first-time.html',
'test/html/train_first-time.html',
'test/html/verify.html'
];
htmlPaths.forEach(function (htmlPath) {
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var age = koc.parser.guessAge(html);
it("age should be 17", function () {
return age.should.equal(17);
});
});
});
});
describe('Parse Commander Change', function () {
var htmlPaths = [
// page , expected to be
['test/html/commander_change.html', {
success: true,
nbTimesCanChangeCommander: 4,
errorMessage: '',
statement: '/images/commchange.gif'
}],
['test/html/commander_change_wrong-pass.html', {
success: true,
nbTimesCanChangeCommander: 4,
errorMessage: 'Your current password is required to make the requested changes.',
statement: '/images/commchange.gif'
}],
['test/html/commander_change_wrong-statement.html', {
success: true,
nbTimesCanChangeCommander: 4,
errorMessage: 'Please copy the text exactly as it appears',
statement: '/images/commchange.gif'
}],
['test/html/base_01.html', { // not found
success: false,
nbTimesCanChangeCommander: -1,
errorMessage: '',
statement: ''
}],
['test/html/commander_change_max.html', { // not found
success: false,
nbTimesCanChangeCommander: -1,
errorMessage: 'You cannot change your commander any more.',
statement: ''
}]
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var expected = page[1];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseCommanderChange(html);
it('should be an object', function () {
return result.should.be.an('object');
});
it("should equal expected value", function () {
return result.should.eql(expected);
});
});
});
});
describe('Parse Menu', function () {
var htmlPaths = [
// page
'test/html/alliances_first-time.html',
'test/html/armory_first-time.html',
'test/html/attacklog_first-time.html',
'test/html/base_first-login.html',
'test/html/base_01.html',
'test/html/base_mails_read.html',
//'test/html/battlefield_full_logged-out.html',
//'test/html/battlefield_xhr_logged-out.html',
//'test/html/battlefield_xhr_logged-in.html',
'test/html/battlefield_full_first-login.html',
'test/html/buddylist_first-time.html',
'test/html/conquest_first-time.html',
//'test/html/home.html',
'test/html/intel_first-time.html',
'test/html/mercs_first-time.html',
'test/html/recruit_first-time.html',
'test/html/stats_first-time.html',
'test/html/train_first-time.html',
//'test/html/verify.html'
];
htmlPaths.forEach(function (htmlPath) {
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseMenu(html);
it("should be a menu", function () {
return result.should.be.an('array').that.has.length.above(3);
});
});
});
});
describe('Test Help', function () {
var help = koc.getHelp();
it("should be an array of 5 items", function () {
return help.should.be.an('array').that.has.length(5);
});
if (help.length > 0) {
var gameplay = help[0];
it("the first item should have title 'Gameplay'", function () {
return gameplay.should.be.an('object').that.has.property('title').that.eql('Gameplay');
});
it("the first item should have 5 sections", function () {
return gameplay.should.be.an('object').that.has.property('sections').that.has.length(6);
});
var i = 0;
help.forEach(function (helpRootItem) {
it("item " + i + " should have 'title', 'help' and 'sections'", function () {
return helpRootItem.should.be.an('object').that.has.keys('sections', 'help', 'title');
});
it("item " + i + " should have non-empty 'title'", function () {
return helpRootItem.should.be.an('object').that.have.property('title').that.is.not.empty;
});
i++;
});
}
});
describe('Parse Forgot Pass', function () {
var htmlPaths = [
// page
['test/html/forgotpass.html', ""],
['test/html/forgotpass_wrong-email.html', "That email address does not exist in our system."],
['test/html/forgotpass_wrong-username.html', "That username does not exist in our system."],
['test/html/forgotpass_invalid-email.html', "Invalid Email"],
['test/html/forgotpass_success.html', "Your login details will be emailed to you in 30 minutes."],
['test/html/forgotpass_success2.html', "Your login details have been emailed to you and will arrive in 30 minutes."]
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var expected = page[1];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseForgotPass(html);
it("should be '" + expected + "'", function () {
return result.should.be.a('string').that.eql(expected);
});
});
});
describe("#remote error because unknown e-mail", function () {
var localKoC = new KoC();
var forgotPassPromise = localKoC.forgotPass("", "warlord@koc.abc");
it('should be fulfilled', function () {
return forgotPassPromise.should.be.fulfilled;
});
it('should have success field that is false', function () {
return forgotPassPromise.should.eventually.have.property("success").that.is.false;
});
it('should have error field == "That email address does not exist in our system."', function () {
return forgotPassPromise.should.eventually.have.property("error").that.eql("That email address does not exist in our system.");
});
});
describe("#remote error because unknown username", function () {
var localKoC = new KoC();
var forgotPassPromise = localKoC.forgotPass("War Lord", "");
it('should be fulfilled', function () {
return forgotPassPromise.should.be.fulfilled;
});
it('should have success field that is false', function () {
return forgotPassPromise.should.eventually.have.property("success").that.is.false;
});
it('should have error field == "That email address does not exist in our system."', function () {
return forgotPassPromise.should.eventually.have.property("error").that.eql("That username does not exist in our system.");
});
});
});
describe('Logout', function () {
describe("#remote logout", function () {
var localKoC = new KoC();
var logoutPromise = localKoC.logout();
it('should be fulfilled', function () {
return logoutPromise.should.be.fulfilled;
});
it('should have success field (true)', function () {
return logoutPromise.should.eventually.have.property("success").that.is.true;
});
it('should have error field (empty)', function () {
return logoutPromise.should.eventually.have.property("error").that.is.empty;
});
});
});
describe('Parse Full User Stats', function () {
var htmlPaths = [
// page , commander, nb officers, total nb officers, number of alliances, primary alliance turing
['test/html/stats_NoOfficer_Alliance.html' , "P0lytech" , 0, 0, 1, 'Forces of Darkness' , "None", "", "vckfb" ],
['test/html/stats_NoOfficer_NoAlliance.html' , "chosen" , 0, 0, 0, null , "None", "", "vckfb" ],
['test/html/stats_Officers_Alliance.html' , "TheGodFather_LaCN", 10, 25, 1, "La Cosa Nostra" , "None", "", "vckfb" ],
['test/html/stats_Officers_NoMainAlliance.html', 'None' , 7, 7, 1, null , "None", "", "vckfb" ],
['test/html/stats_SupremeCommander.html' , "chosen" , 10, 12, 2, "La Cosa Nostra" , "Merchantofdeath_LaCN", "LaCN", "xpn" ],
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var commander = page[1];
var officersNb = page[2];
var totalOfficersNb = page[3];
var alliancesNb = page[4];
var primaryAlliance = page[5];
var supremeCommander = page[6];
var chainName = page[7];
var turing = page[8];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseFullStats(html);
//console.log(result);
it('should be an object', function () {
return result.should.be.an('object');
});
it('should have success==true', function () {
return result.should.have.property('success').that.is.true;
});
it('should have user which is an object', function () {
return result.should.have.property('user').that.is.an('object').that.contain.keys(
'username',
'commander',
'race',
'rank',
'highestRank',
'armyMorale',
'fortification',
'buddyStatus',
'alliances',
'officers',
'supremeCommander',
'chainName'
);
});
it('should have commander ' + commander, function () {
return result.should.have.property('user').that.has.property('commander').that.has.property('username').that.eql(commander);
});
it('should have supreme commander ' + supremeCommander, function () {
return result.should.have.property('user').that.has.property('supremeCommander').that.has.property('username').that.eql(supremeCommander);
});
it('should have chain name ' + chainName, function () {
return result.should.have.property('user').that.has.property('chainName').that.eql(chainName);
});
it('should have ' + officersNb + ' officers', function () {
return result.should.have.property('user').that.has.property('officers').that.is.an('array').that.has.length(officersNb);
});
it('should have ' + totalOfficersNb + ' total officers', function () {
return result.should.have.property('user').that.has.property('totalOfficersNb').that.eql(totalOfficersNb);
});
it('should have ' + alliancesNb + ' alliances', function () {
return result.should.have.property('user').that.has.property('alliances').that.is.an('array').that.has.length(alliancesNb);
});
it('should have turing ' + turing, function () {
return result.should.have.property('turing').that.eql(turing);
});
if (primaryAlliance !== null) {
it('should have primary alliance ' + primaryAlliance, function () {
return result.should.have.property('user').that.has.property('primaryAlliance').that.is.an('object').that.has.property('name').that.eql(primaryAlliance);
});
} else {
it('should have no primary alliance ' + primaryAlliance, function () {
return result.should.have.property('user').that.has.property('primaryAlliance').that.is.an('object').that.has.property('name').that.is.empty;
});
}
});
});
});
describe('Parse Armory', function () {
var htmlPaths = [
// page , expected to be
['test/html/armory_first-time.html', {
nbAttackWeapons: 2,
nbDefenseWeapons: 0,
nbSpyTools: 0,
nbSentryTools: 0,
fortification: "Camp (x 1)",
siegeTechnology: "None (x 1)",
turing: "hruen",
error: "",
}],
['test/html/armory_new-user-advisor.html', {
nbAttackWeapons: 6,
nbDefenseWeapons: 1,
nbSpyTools: 4,
nbSentryTools: 4,
fortification: "Portcullis (x 3.81)",
siegeTechnology: "Catapults (x 4.83)",
turing: "fykdg",
error: "",
}],
['test/html/armory_repair.html', {
nbAttackWeapons: 2,
nbDefenseWeapons: 1,
nbSpyTools: 0,
nbSentryTools: 0,
fortification: "Camp (x 1)",
siegeTechnology: "None (x 1)",
turing: "dbh",
error: "",
}],
['test/html/armory_not-enough-money.html', {
nbAttackWeapons: 2,
nbDefenseWeapons: 1,
nbSpyTools: 0,
nbSentryTools: 0,
fortification: "Camp (x 1)",
siegeTechnology: "None (x 1)",
turing: "udnvm",
error: "Not enough money for those items.",
}],
['test/html/armory_01.html', {
nbAttackWeapons: 3,
nbDefenseWeapons: 3,
nbSpyTools: 5,
nbSentryTools: 2,
fortification: "Trenches (x 5.96)",
siegeTechnology: "Sappers (x 17.92)",
turing: "kvm",
error: "",
currentWeapons: {
"Attack Weapons": [
{
"name": "Blackpowder Missile",
"quantity": 415,
"sell": {
"inputName": "scrapsell[70]",
"price": 700000,
"priceText": "700,000 Gold"
},
"strengthText": "1,000 / 1,000",
strengthCurrent: 1000,
strengthMax: 1000,
"weaponId": 70
},
{
"name": "Chariot",
"quantity": 2,
"repair": {
"defaultValue": 0.67,
"inputName": "repair[72]",
"pricePerPoint": 570
},
"sell": {
"inputName": "scrapsell[72]",
"price": 314649,
"priceText": "314,649 Gold"
},
"strengthText": "599.33 / 600",
strengthCurrent: 599.33,
strengthMax: 600,
"weaponId": 72
},
{
"name": "Excalibur",
"quantity": 1,
"repair": {
"defaultValue": 0.21,
"inputName": "repair[27]",
"pricePerPoint": 297
},
"sell": {
"inputName": "scrapsell[27]",
"price": 139886,
"priceText": "139,886 Gold"
},
"strengthText": "255.79 / 256",
strengthCurrent: 255.79,
strengthMax: 256,
"weaponId": 27
}
],
"Defense Weapons": [
{
"name": "Invisibility Shield",
"quantity": 126,
"sell": {
"inputName": "scrapsell[71]",
"price": 700000,
"priceText": "700,000 Gold"
},
"strengthText": "1,000 / 1,000",
strengthCurrent: 1000,
strengthMax: 1000,
"weaponId": 71
},
{
"name": "Mithril",
"quantity": 1,
"sell": {
"inputName": "scrapsell[46]",
"price": 35000,
"priceText": "35,000 Gold"
},
"strengthText": "64 / 64",
strengthCurrent: 64,
strengthMax: 64,
"weaponId": 46
},
{
"name": "Shield",
"quantity": 15,
"sell": {
"inputName": "scrapsell[38]",
"price": 3500,
"priceText": "3,500 Gold"
},
"strengthText": "5 / 5",
strengthCurrent: 5,
strengthMax: 5,
"weaponId": 38
}
],
"Sentry Tools": [
{
"name": "Lookout Tower",
"quantity": 225,
"sell": {
"inputName": "scrapsell[74]",
"price": 700000,
"priceText": "700,000 Gold"
},
"strengthText": "1,000",
strengthCurrent: 1000,
strengthMax: 1000,
"weaponId": 74
},
{
"name": "Guard Dog",
"quantity": 6,
"sell": {
"inputName": "scrapsell[68]",
"price": 175000,
"priceText": "175,000 Gold"
},
"strengthText": "250",
strengthCurrent: 250,
strengthMax: 250,
"weaponId": 68
}
],
"Spy Tools": [
{
"name": "Nunchaku",
"quantity": 2193,
"sell": {
"inputName": "scrapsell[75]",
"price": 700000,
"priceText": "700,000 Gold"
},
"strengthText": "1,000",
strengthCurrent: 1000,
strengthMax: 1000,
"weaponId": 75
},
{
"name": "Skeleton Key",
"quantity": 2,
"sell": {
"inputName": "scrapsell[73]",
"price": 420000,
"priceText": "420,000 Gold"
},
"strengthText": "600",
strengthCurrent: 600,
strengthMax: 600,
"weaponId": 73
},
{
"name": "Grappling Hook",
"quantity": 1,
"sell": {
"inputName": "scrapsell[67]",
"price": 175000,
"priceText": "175,000 Gold"
},
"strengthText": "250",
strengthCurrent: 250,
strengthMax: 250,
"weaponId": 67
},
{
"name": "Cloak",
"quantity": 1,
"sell": {
"inputName": "scrapsell[65]",
"price": 98000,
"priceText": "98,000 Gold"
},
"strengthText": "140",
strengthCurrent: 140,
strengthMax: 140,
"weaponId": 65
},
{
"name": "Dirk",
"quantity": 1,
"sell": {
"inputName": "scrapsell[63]",
"price": 52500,
"priceText": "52,500 Gold"
},
"strengthText": "75",
strengthCurrent: 75,
strengthMax: 75,
"weaponId": 63
}
]
},
}],
];
htmlPaths.forEach(function (page) {
var htmlPath = page[0];
var expected = page[1];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseArmory(html);
it('should be an object', function () {
return result.should.be.an('object').that.contain.keys('currentWeapons', 'buyWeapons', 'upgrades', 'militaryEffectiveness', 'personnel', 'repairAll', 'turing', 'error');
});
it('turing should be: ' + expected.turing, function () {
return result.should.be.an('object').that.has.property('turing').that.eql(expected.turing);
});
it('error should be: ' + expected.error, function () {
return result.should.be.an('object').that.has.property('error').that.eql(expected.error);
});
if(expected.currentWeapons!==undefined){
it('Current weapons should be as expected (Attack)', function () {
result.should.be.an('object').that.has.property('currentWeapons')
.that.has.property("Attack Weapons").that.eql(expected.currentWeapons['Attack Weapons']);
});
it('Current weapons should be as expected (Defense)', function () {
result.should.be.an('object').that.has.property('currentWeapons')
.that.has.property("Defense Weapons").that.eql(expected.currentWeapons['Defense Weapons']);
});
it('Current weapons should be as expected (Spy)', function () {
result.should.be.an('object').that.has.property('currentWeapons')
.that.has.property("Spy Tools").that.eql(expected.currentWeapons['Spy Tools']);
});
it('Current weapons should be as expected (Sentry)', function () {
result.should.be.an('object').that.has.property('currentWeapons')
.that.has.property("Sentry Tools").that.eql(expected.currentWeapons['Sentry Tools']);
});
}
[{
type: "Attack Weapons",
nbWeapons: expected.nbAttackWeapons
}, {
type: "Defense Weapons",
nbWeapons: expected.nbDefenseWeapons
}, {
type: "Spy Tools",
nbWeapons: expected.nbSpyTools
}, {
type: "Sentry Tools",
nbWeapons: expected.nbSentryTools
}].forEach(function (currentWeapon) {
it('buyWeapons should have more than one ' + currentWeapon.type, function () {
return result.should.be.an('object').that.has.property('buyWeapons').that.has.property(currentWeapon.type).that.is.an('array').that.has.length.gt(1);
});
if (currentWeapon.nbWeapons > 0) {
it('currentWeapons should have ' + currentWeapon.nbWeapons + ' ' + currentWeapon.type, function () {
return result.should.be.an('object').that.has.property('currentWeapons').that.has.property(currentWeapon.type).that.is.an('array').that.has.length(currentWeapon.nbWeapons);
});
}
else {
it('currentWeapons should have no ' + currentWeapon.type, function () {
return result.should.be.an('object').that.has.property('currentWeapons').that.not.has.property(currentWeapon.type);
});
}
});
it('current fortification should be ' + expected.fortification, function () {
return result.should.be.an('object').that.has.property('upgrades').that.has.property('fortification').that.has.property('current').that.eql(expected.fortification);
});
it('current siege technology should be ' + expected.siegeTechnology, function () {
return result.should.be.an('object').that.has.property('upgrades').that.has.property('siegeTechnology').that.has.property('current').that.eql(expected.siegeTechnology);
});
// Personnel
['Trained Attack Soldiers', 'Trained Attack Mercenaries', 'Trained Defense Soldiers', 'Trained Defense Mercenaries',
'Untrained Soldiers', 'Untrained Mercenaries', 'Spies', 'Sentries', 'Army Morale', 'Total Fighting Force'].forEach(function (personnelProperty) {
it('personnel should have ' + personnelProperty, function () {
return result.should.be.an('object').that.has.property('personnel').that.has.property(personnelProperty).that.is.a('number');
});
});
it('militaryEffectiveness should have at least 4 items (SA, DA, Spy, Sentry)', function () {
return result.should.be.an('object').that.has.property('militaryEffectiveness').that.is.an('array').that.has.length.gte(4);
});
});
});
});
describe('Verify E-Mail', function () {
describe('#verification not a valid e-mail address', function () {
var localKoC = new KoC();
localKoC.setSession('abc');
var verifyPromise = localKoC.verifyEmail("not a valid email address");
it('should be fulfilled', function () {
return verifyPromise.should.be.fulfilled;
});
it('should have success field that is false', function () {
return verifyPromise.should.eventually.have.property("success").that.is.false;
});
it('should have error field that is not empty', function () {
return verifyPromise.should.eventually.have.property("error").that.is.not.empty;
});
});
describe('#verification not logged in', function () {
var localKoC = new KoC();
var verifyPromise = localKoC.verifyEmail("valid@email.com");
it('should be fulfilled', function () {
return verifyPromise.should.be.fulfilled;
});
it('should have success field that is false', function () {
return verifyPromise.should.eventually.have.property("success").that.is.false;
});
it('should have error field that is not empty', function () {
return verifyPromise.should.eventually.have.property("error").that.is.not.empty;
});
});
var cases = [
['test/html/verify.html', ''],
['test/html/verify_email-taken.html', 'There is already a user with that e-mail address'],
['test/html/verify_email-sent.html', ''],
];
cases.forEach(function (verifyCase) {
var htmlPath = verifyCase[0];
var expectedErrorMessage = verifyCase[1];
describe('#local ' + htmlPath, function () {
var html = fs.readFileSync(htmlPath, 'utf8');
var result = koc.parser.parseVerifyEmailError(html);
it("should be: '" + expectedErrorMessage + "'", function () {
return result.should.be.a('string').that.eql(expectedErrorMessage);
});
});
});
});
describe('Parse Training', function () {
var htmlPaths = [
// page , expected to be
['test/html/train_first-time.html', {
message: "",
turing: "hruen",
totalFightingForce: 14,
trainingPrograms: 6,
upgrades: [
{
currentTitle: 'Current Covert Skill',
upgradeName: 'Upgrade',
currentLevel: 'Level 0',
cost: '9,600 Gold (+60%)',
inputName: 'upgrade_spy',
},
{
title: 'Increase Conscription',
currentTitle: 'Current Conscription Rate',
upgradeName: 'Upgrade to 5 per day',
currentLevel: '0 soldiers per day',
cost: '3,000 Gold',
inputName: 'upgrade_prod',
},
{
title: 'Economic Development',
currentTitle: 'Current Economy',
upgradeName: 'Research Hunting (100 gold per turn)',
currentLevel: 'None (0 gold per turn)',
cost: '300 Experience',
inputName: 'upgrade_economy',
},
{
title: 'Technological Development',
currentTitle: 'Current Technologies',
upgradeName: 'Research!',
currentLevel: 'You have no technology',
cost: '300 Experience',
inputName: 'upgrade_tech',
}
]
}],
['test/html/train_no-technology.html', {
message: "",
turing: "mbx",
totalFightingForce: 106,
trainingPrograms: 6,
upgrades: [
{
currentTitle: 'Current Covert Skill',
upgradeName: 'Upgrade',
currentLevel: 'Level 3',
cost: '39,300 Gold (+60%)',
inputName: 'upgrade_spy',
},
{
title: 'Increase Conscription',
currentTitle: 'Current Conscription Rate',
upgradeName: 'Upgrade to 5 per day',
currentLevel: '0 soldiers per day',
cost: '3,000 Gold',
inputName: 'upgrade_prod',
},
{
title: 'Economic Development',
currentTitle: 'Current Economy',
upgradeName: 'Research Hunting (100 gold per turn)',
currentLevel: 'None (0 gold per turn)',
cost: '300 Experience',
inputName: 'upgrade_economy',
},
{
title: 'Technological Development',
currentTitle: 'Current Technologies',
upgradeName: 'Research!',
currentLevel: 'You have no technology',
cost: '300 Experience',
inputName: 'upgrade_tech',
}
]
}],
['test/html/train_one-technology.html', {
message: "",
turing: "chy",
totalFightingForce: 109,
trainingPrograms: 6,
upgrades: [
{
currentTitle: 'Current Covert Skill',
upgradeName: 'Upgrade',
currentLevel: 'Level 4',
cost: '62,900 Gold (+60%)',
inputName: 'upgrade_spy',
},
{
title: 'Increase Conscription',
currentTitle: 'Current Conscription Rate',
upgradeName: 'Upgrade to 5 per day',
currentLevel: '0 soldiers per day',
cost: '3,000 Gold',
inputName: 'upgrade_prod',
},
{
title: 'Economic Development',
currentTitle: 'Current Economy',
upgradeName: 'Research Hunting (100 gold per turn)',
currentLevel: 'None (0 gold per turn)',
cost: '300 Experience',
inputName: 'upgrade_economy',
},
{
title: 'Technological Development',
currentTitle: 'Current Technologies',
upgradeName: 'Research!',
currentLevel: 'Spear (x 1.05 strength)',
cost: '350 Experience',
inputName: 'upgrade_tech',
}
]
}],
['test/html/train_two-technologies.html', {
message: "",
turing: "chy",
totalFightingForce: 109,
trainingPrograms: 6,
upgrades: [
{
currentTitle: 'Current Covert Skill',
upgradeName: 'Upgrade',
currentLevel: 'Level 4',
cost: '62,900 Gold (+60%)',
inputName: 'upgrade_spy',
},
{
title: 'Increase Conscription',
currentTitle: 'Current Conscription Rate',
upgradeName: 'Upgrade to 5 per day',
currentLevel: '0 soldiers per day',
cost: '3,000 Gold',
inputName: 'upgrade_prod',
},
{
title: 'Economic Development',
currentTitle: 'Current Economy',
upgradeName: 'Research Hunting (100 gold per turn)',
currentLevel: 'None (0 gold per turn)',
cost: '300 Experience',
inputName: 'upgrade_economy',
},
{
title: 'Technological Development',
currentTitle: 'Current Technologies',
upgradeName: 'Research!',
currentLevel: 'Fire (x 1.1 strength)',
cost: '400 Experience',
inputName: 'upgrade_tech',
}
]
}],
['test/html/train_three-technologies.html', {
message: "You have researched Oven!",
turing: "chy",
totalFightingForce: 109,
trainingPrograms: 6,
upgrades: [
{
currentTitle: 'Current Covert Skill',
upgradeName: 'Upgrade',
currentLevel: 'Level 4',
cost: '62,900 Gold (+60%)',
inputName: 'upgrade_spy',
},
{
title: 'Increase Conscription',
currentTitle: 'Current Conscr