Files
habitica/test/client-old/spec/services/questServicesSpec.js
Sabe Jones e6f605f23a Discount Bundled Quests (#8731)
* refactor(content): split quests file

* feat(purchases): sell bundled quests

* fix(style): address linting errors

* test(bundles): shop and purchase tests

* fix(test): remove only

* test(bundles): check balance deduction

* docs(content): comment bundle structure

* fix(test): account for cumulative balance
2017-05-17 20:36:34 -05:00

436 lines
13 KiB
JavaScript

'use strict';
describe('Quests Service', function() {
var groupsService, quest, questsService, user, content, resolveSpy, rejectSpy, state;
beforeEach(function() {
user = specHelper.newUser();
user.ops = {
buyQuest: sandbox.spy()
};
user.party._id = 'unique-party-id';
user.achievements.quests = {};
quest = {lvl:20};
module(function($provide) {
$provide.value('User', {sync: sinon.stub(), user: user});
});
inject(function(Quests, Groups, Content, _$state_) {
questsService = Quests;
groupsService = Groups;
content = Content;
state = _$state_;
});
sandbox.stub(groupsService, 'inviteOrStartParty');
sandbox.stub(window,'confirm');
sandbox.stub(window,'alert');
resolveSpy = sandbox.spy();
rejectSpy = sandbox.spy();
});
describe('#lockQuest', function() {
it('locks quest when user does not meet level requirement', function() {
user.stats.lvl = 15;
expect(questsService.lockQuest(quest)).to.be.ok;
});
it('does not lock quest if we ignore level requirement', function() {
user.stats.lvl = 15;
expect(questsService.lockQuest(quest,true)).to.not.be.ok;
});
it('does not lock quest if user meets level requirement', function() {
user.stats.lvl = 20;
expect(questsService.lockQuest(quest)).to.not.be.ok;
});
it('locks quest if user has not completed previous quest in series', function() {
quest.previous = 'priorQuest';
user.stats.lvl = 25;
expect(questsService.lockQuest(quest)).to.be.ok;
});
it('does not lock quest if user has completed previous quest in series', function() {
quest.previous = 'priorQuest';
user.stats.lvl = 25;
user.achievements.quests.priorQuest = 1;
expect(questsService.lockQuest(quest)).to.not.be.ok;
});
});
describe('#buyQuest', function() {
var scope;
beforeEach(inject(function($rootScope) {
scope = $rootScope.$new();
}));
//@TODO: This is fixed in a Quest Service PR port
xit('returns a promise', function() {
var promise = questsService.buyQuest('whale');
expect(promise).to.respondTo('then');
});
context('Quest key does not exist', function() {
it('rejects with message that quest is not found', function(done) {
questsService.buyQuest('foo')
.then(resolveSpy, function(rej) {
expect(rej).to.eql('No quest with that key found');
expect(resolveSpy).to.not.be.called;
done();
});
scope.$apply();
});
});
context('invite friends', function() {
it('prompts user to invite friends to party for invite reward quests', function() {
questsService.buyQuest('basilist');
expect(window.confirm).to.be.calledOnce;
expect(window.confirm).to.be.calledWith(env.t('mustInviteFriend'));
});
it('rejects promise if confirm is cancelled', function(done) {
window.confirm.returns(false);
questsService.buyQuest('basilist')
.then(resolveSpy, function(rej) {
expect(rej).to.eql('Did not want to invite friends');
expect(window.confirm).to.be.calledOnce;
expect(groupsService.inviteOrStartParty).to.not.be.called;
done();
});
scope.$apply();
});
it('rejects promise if confirm is cofirmed and calls groups service', function(done) {
window.confirm.returns(true);
questsService.buyQuest('basilist')
.then(resolveSpy, function(rej) {
expect(rej).to.eql('Invite or start party');
expect(window.confirm).to.be.calledOnce;
expect(groupsService.inviteOrStartParty).to.be.calledOnce;
done();
});
scope.$apply();
});
});
context('quests in a series', function() {
it('does not allow user to buy subsquent quests in a series if user has no quest achievements', function(done) {
user.stats.lvl = 100;
user.achievements.quests = undefined;
questsService.buyQuest('goldenknight2')
.then(resolveSpy, function(res) {
expect(window.alert).to.have.been.calledOnce;
expect(res).to.eql('unlockByQuesting');
expect(resolveSpy).to.not.be.called;
done();
});
scope.$apply();
});
it('does not allow user to buy quests whose previous quests are incomplete', function(done) {
user.stats.lvl = 100;
user.achievements.quests = {
'atom1': 1
};
questsService.buyQuest('goldenknight2')
.then(resolveSpy, function(res) {
expect(window.alert).to.have.been.calledOnce;
expect(resolveSpy).to.not.be.called;
done();
});
scope.$apply();
});
});
context('quests with level requirement', function() {
it('does not allow user to buy quests beyond their level', function(done) {
user.stats.lvl = 1;
questsService.buyQuest('vice1')
.then(resolveSpy, function(res) {
expect(window.alert).to.have.been.calledOnce;
expect(res).to.eql('mustLvlQuest');
done();
});
scope.$apply();
});
it('allows user to buy quest if they meet level requirement', function(done) {
user.stats.lvl = 30;
questsService.buyQuest('vice1')
.then(function(res) {
expect(res).to.eql(content.quests.vice1);
expect(window.alert).to.not.be.called;
expect(rejectSpy).to.not.be.called;
done();
}, rejectSpy);
scope.$apply();
});
});
context('gold purchasable quests', function() {
it('sends quest object', function(done) {
questsService.buyQuest('dilatoryDistress1')
.then(function(res) {
expect(res).to.eql(content.quests.dilatoryDistress1);
expect(window.alert).to.not.be.called;
expect(rejectSpy).to.not.be.called;
done();
}, rejectSpy);
scope.$apply();
});
});
context('quest bundles', function() {
it('sends bundle object', function(done) {
questsService.buyQuest('featheredFriends')
.then(function(res) {
expect(res).to.eql(content.bundles.featheredFriends);
expect(window.alert).to.not.be.called;
expect(rejectSpy).to.not.be.called;
done();
}, rejectSpy);
scope.$apply();
});
});
context('all other quests', function() {
it('sends quest object', function(done) {
questsService.buyQuest('whale')
.then(function(res) {
expect(res).to.eql(content.quests.whale);
expect(window.alert).to.not.be.called;
expect(rejectSpy).to.not.be.called;
done();
}, rejectSpy);
scope.$apply();
});
});
});
describe('#showQuest', function() {
var scope;
beforeEach(inject(function($rootScope) {
scope = $rootScope.$new();
}));
xit('returns a promise', function() {
var promise = questsService.showQuest('whale');
expect(promise).to.respondTo('then');
});
context('Quest key does not exist', function() {
it('rejects with message that quest is not found', function(done) {
questsService.showQuest('foo')
.then(resolveSpy, function(rej) {
expect(rej).to.eql('No quest with that key found');
expect(resolveSpy).to.not.be.called;
done();
});
scope.$apply();
});
});
context('quests in a series', function() {
it('does not allow user to buy subsquent quests in a series if user has no quest achievements', function(done) {
user.stats.lvl = 100;
user.achievements.quests = undefined;
questsService.showQuest('goldenknight2')
.then(resolveSpy, function(res) {
expect(window.alert).to.have.been.calledOnce;
expect(res).to.eql('unlockByQuesting');
expect(resolveSpy).to.not.be.called;
done();
});
scope.$apply();
});
it('does not allow user to buy quests whose previous quests are incomplete', function(done) {
user.stats.lvl = 100;
user.achievements.quests = {
'atom1': 1
};
questsService.showQuest('goldenknight2')
.then(resolveSpy, function(res) {
expect(window.alert).to.have.been.calledOnce;
expect(resolveSpy).to.not.be.called;
done();
});
scope.$apply();
});
});
context('quests with level requirement', function() {
it('does not allow user to buy quests beyond their level', function(done) {
user.stats.lvl = 1;
questsService.showQuest('vice1')
.then(resolveSpy, function(res) {
expect(window.alert).to.have.been.calledOnce;
expect(res).to.eql('mustLvlQuest');
done();
});
scope.$apply();
});
it('allows user to buy quest if they meet level requirement', function(done) {
user.stats.lvl = 30;
questsService.showQuest('vice1')
.then(function(res) {
expect(res).to.eql(content.quests.vice1);
expect(window.alert).to.not.be.called;
expect(rejectSpy).to.not.be.called;
done();
}, rejectSpy);
scope.$apply();
});
});
context('gold purchasable quests', function() {
it('sends quest object', function(done) {
questsService.showQuest('dilatoryDistress1')
.then(function(res) {
expect(res).to.eql(content.quests.dilatoryDistress1);
expect(window.alert).to.not.be.called;
expect(rejectSpy).to.not.be.called;
done();
}, rejectSpy);
scope.$apply();
});
});
context('all other quests', function() {
it('sends quest object', function(done) {
questsService.showQuest('whale')
.then(function(res) {
expect(res).to.eql(content.quests.whale);
expect(window.alert).to.not.be.called;
expect(rejectSpy).to.not.be.called;
done();
}, rejectSpy);
scope.$apply();
});
});
});
describe('#initQuest', function() {
var fakeBackend, scope, key = 'whale';
beforeEach(inject(function($httpBackend, $rootScope) {
scope = $rootScope.$new();
fakeBackend = $httpBackend;
var partyResponse = {data:{_id: 'party-id'}};
fakeBackend.when('GET', 'partials/main.html').respond({});
fakeBackend.when('GET', 'partials/main.html').respond({});
fakeBackend.when('GET', '/api/v3/groups/party').respond(partyResponse);
fakeBackend.when('GET', '/api/v3/groups/party-id/members?includeAllPublicFields=true').respond({});
fakeBackend.when('GET', '/api/v3/groups/party-id/invites').respond({});
fakeBackend.when('GET', '/api/v3/challenges/groups/party-id').respond({});
fakeBackend.when('POST', '/api/v3/groups/party-id/quests/invite/' + key).respond({quest: { key: 'whale' } });
fakeBackend.flush();
}));
it('returns a promise', function() {
var promise = questsService.initQuest(key);
expect(promise).to.respondTo('then');
});
it('starts a quest', function(done) {
fakeBackend.expectPOST( '/api/v3/groups/party-id/quests/invite/' + key);
questsService.initQuest(key)
.then(function(res) {
done();
});
fakeBackend.flush();
scope.$apply();
});
it('brings user to party page');
});
//@TODO: This is fixed in a Quest Service PR port
xdescribe('#sendAction', function() {
var fakeBackend, scope;
beforeEach(inject(function($httpBackend, $rootScope) {
scope = $rootScope.$new();
fakeBackend = $httpBackend;
var partyResponse = {data:{_id: 'party-id'}};
fakeBackend.when('GET', 'partials/main.html').respond({});
fakeBackend.when('GET', '/api/v3/groups/party').respond(partyResponse);
fakeBackend.when('POST', '/api/v3/groups/party-id/quests/reject').respond({quest: { key: 'whale' } });
fakeBackend.flush();
}));
it('returns a promise', function() {
var promise = questsService.sendAction('quests/reject');
expect(promise).to.respondTo('then');
});
it('calls specified quest endpoint', function(done) {
fakeBackend.expectPOST('/api/v3/groups/party-id/quests/reject');
questsService.sendAction('quests/reject')
.then(function(res) {
expect(res.key).to.eql('whale');
done();
});
fakeBackend.flush();
scope.$apply();
});
it('syncs User', function() {
questsService.sendAction('quests/reject')
.then(function(res) {
expect(User.sync).to.be.calledOnce;
done();
});
scope.$apply();
});
});
});