mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-10-27 11:12:28 +01:00
Compare commits
328 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b31268fbc2 | ||
|
|
35727228f0 | ||
|
|
f4422b8d6c | ||
|
|
2d4dc9e23c | ||
|
|
c39505d41c | ||
|
|
c24545cae5 | ||
|
|
6bc70ca471 | ||
|
|
b445bc8261 | ||
|
|
31281b43d3 | ||
|
|
a8a915ea8e | ||
|
|
dc3ee25e65 | ||
|
|
54f57445da | ||
|
|
95ef2b1789 | ||
|
|
4d32977e5c | ||
|
|
7fe2504906 | ||
|
|
b74cee3d21 | ||
|
|
5af7733150 | ||
|
|
824bf62e0a | ||
|
|
ac24a5dddd | ||
|
|
9111f59da4 | ||
|
|
6a550b34df | ||
|
|
0c973b1cf0 | ||
|
|
4170ef5e79 | ||
|
|
506275c30e | ||
|
|
6838b7d0a6 | ||
|
|
e987cd52a6 | ||
|
|
1df8668d38 | ||
|
|
1af42aa7fe | ||
|
|
9dc9faa70d | ||
|
|
7fbcc0a263 | ||
|
|
0450e9c3ae | ||
|
|
15626b8ae1 | ||
|
|
444f393f3a | ||
|
|
d711bf4085 | ||
|
|
7b93e326fc | ||
|
|
c62ea522c0 | ||
|
|
810362a404 | ||
|
|
2e429513da | ||
|
|
c8625cb23f | ||
|
|
ad50f90ba0 | ||
|
|
d5305f74e3 | ||
|
|
5ea20e4c8c | ||
|
|
9e4e2d0b34 | ||
|
|
6456e6b8e3 | ||
|
|
af961ff16c | ||
|
|
eb2a6095c2 | ||
|
|
ee82f5a774 | ||
|
|
f1c8c4c54b | ||
|
|
79b15d7ddf | ||
|
|
f2fed7ea39 | ||
|
|
ca81ff5af6 | ||
|
|
e28c214696 | ||
|
|
792f45e9bd | ||
|
|
a69c0999d3 | ||
|
|
37ff35306c | ||
|
|
fd430e95b2 | ||
|
|
0ea472b3af | ||
|
|
6d0496fbd0 | ||
|
|
fac1889776 | ||
|
|
9ca6da0f75 | ||
|
|
99f50f825a | ||
|
|
2308f2397e | ||
|
|
f10d5110e5 | ||
|
|
5ced47f590 | ||
|
|
24b2bc9aa1 | ||
|
|
aea08a971a | ||
|
|
e3452b3ba7 | ||
|
|
3db666eb9e | ||
|
|
cf5985e38c | ||
|
|
d88a8247d1 | ||
|
|
7e1ae6a571 | ||
|
|
d117117885 | ||
|
|
5dd168eee4 | ||
|
|
a7c9355dd5 | ||
|
|
81d3e8a68f | ||
|
|
e0fbfffbf2 | ||
|
|
36b968a74a | ||
|
|
fff249fb00 | ||
|
|
ce5c6b9517 | ||
|
|
702013f9ed | ||
|
|
3503b307b2 | ||
|
|
f1ec8bbf2c | ||
|
|
58b033db9e | ||
|
|
b0dcc2f6ef | ||
|
|
3377f8a916 | ||
|
|
22f83d09c4 | ||
|
|
496534ab4b | ||
|
|
7325d2020e | ||
|
|
1a0d39e566 | ||
|
|
dc62ab7577 | ||
|
|
c4e5633e48 | ||
|
|
d977656e96 | ||
|
|
b0a980d56e | ||
|
|
3d75c99f8d | ||
|
|
0aa16d7021 | ||
|
|
4fa3046104 | ||
|
|
fda4be01b8 | ||
|
|
67436fbef1 | ||
|
|
ffb92a5faa | ||
|
|
4a44d60fac | ||
|
|
122cc510d3 | ||
|
|
29a7a07d14 | ||
|
|
18783aefe3 | ||
|
|
a5e242759c | ||
|
|
e01c6cc9a6 | ||
|
|
8a75383c43 | ||
|
|
47ebee9ae8 | ||
|
|
4e97355110 | ||
|
|
7045b5c214 | ||
|
|
e41dccf6d5 | ||
|
|
d0815ea9ee | ||
|
|
d0bd62bf02 | ||
|
|
39d7581c6c | ||
|
|
fdf146dd01 | ||
|
|
023b3ffd88 | ||
|
|
f01e552637 | ||
|
|
9f11820a02 | ||
|
|
ca6c7b8e5f | ||
|
|
02f8ba1638 | ||
|
|
8eb7c67f12 | ||
|
|
1f895fda44 | ||
|
|
e87c180e9b | ||
|
|
dbf9fd54be | ||
|
|
c9b99d1ecf | ||
|
|
fd8120c80d | ||
|
|
053e75562f | ||
|
|
1d50027f51 | ||
|
|
7fe74fd06a | ||
|
|
173a8561b6 | ||
|
|
f21bef707b | ||
|
|
9cf2ccf7c4 | ||
|
|
77d75c4669 | ||
|
|
1c17b95146 | ||
|
|
d89fc209d1 | ||
|
|
844c8bb3e6 | ||
|
|
569fb11db8 | ||
|
|
7671347d3a | ||
|
|
dc3a02bc2e | ||
|
|
1d8c126687 | ||
|
|
7ee49a43f2 | ||
|
|
900bc8dfc1 | ||
|
|
ec260016d3 | ||
|
|
ec770fb29e | ||
|
|
c1079e4eae | ||
|
|
3cb5637fd5 | ||
|
|
cf3a0118c9 | ||
|
|
895a383089 | ||
|
|
f730e7b345 | ||
|
|
d8f3d99d59 | ||
|
|
99fb1f6116 | ||
|
|
7c6dce2124 | ||
|
|
c757a3f52d | ||
|
|
ffb318fe8d | ||
|
|
19cd15ed62 | ||
|
|
3495662196 | ||
|
|
908a1340a4 | ||
|
|
31f4610b20 | ||
|
|
5eac2a6697 | ||
|
|
4495539e8c | ||
|
|
42e6f10b08 | ||
|
|
66750e77d1 | ||
|
|
1eb31a4fec | ||
|
|
fdf2dd1f1a | ||
|
|
f098fbcc80 | ||
|
|
5c429d0328 | ||
|
|
08a84ce13d | ||
|
|
f4bf2df4a9 | ||
|
|
ee6ceecc35 | ||
|
|
76c3e51660 | ||
|
|
d40543f4ca | ||
|
|
e1ad19c216 | ||
|
|
a03c6184b3 | ||
|
|
526d0b1a23 | ||
|
|
08323f307c | ||
|
|
927a08defd | ||
|
|
356f2c7b7f | ||
|
|
b12bf773f1 | ||
|
|
d70ff4e5a3 | ||
|
|
a68b02d403 | ||
|
|
2db5ab2352 | ||
|
|
2a43df34c0 | ||
|
|
a317b351be | ||
|
|
4759764e61 | ||
|
|
5aea8def3b | ||
|
|
dde63b619f | ||
|
|
cbdb0bc3e3 | ||
|
|
6edd1a1fa5 | ||
|
|
6fcf739c89 | ||
|
|
f128f3d3cd | ||
|
|
744090e652 | ||
|
|
81fc727d41 | ||
|
|
7a74d4c296 | ||
|
|
b6a5efc524 | ||
|
|
1e1220d0f9 | ||
|
|
0a691ffb4f | ||
|
|
cd0222e208 | ||
|
|
7812e14898 | ||
|
|
c0f159a8a5 | ||
|
|
dd0c95f051 | ||
|
|
136947169b | ||
|
|
1379140cf6 | ||
|
|
2cb9228a7c | ||
|
|
b1652ddd97 | ||
|
|
0a69c7a08d | ||
|
|
e784ae21ea | ||
|
|
32fa49191e | ||
|
|
ccc862f82a | ||
|
|
ff92f14a5b | ||
|
|
0b0baf2195 | ||
|
|
8ccec0ed9d | ||
|
|
46b42c8441 | ||
|
|
381f652c08 | ||
|
|
5c5e117da0 | ||
|
|
79b3b26ab2 | ||
|
|
89f8f047ae | ||
|
|
a5dfb499b3 | ||
|
|
5b1530b216 | ||
|
|
c6881c5e30 | ||
|
|
2f913666cd | ||
|
|
5ba3e3ce5b | ||
|
|
e29c393629 | ||
|
|
0c6540e6d8 | ||
|
|
3c2cad43d0 | ||
|
|
de67c130fa | ||
|
|
55e62cdc79 | ||
|
|
eee41142b1 | ||
|
|
d2832b7169 | ||
|
|
daca2c7fff | ||
|
|
861b78ce8a | ||
|
|
1dc1923d7b | ||
|
|
6e70f27bc6 | ||
|
|
ad5decc285 | ||
|
|
3e1c128600 | ||
|
|
d9817be8f3 | ||
|
|
e54dcd2859 | ||
|
|
5ec7815cfe | ||
|
|
adeee244e3 | ||
|
|
fe8a44b8c4 | ||
|
|
2b912b354d | ||
|
|
5f65be98df | ||
|
|
56c32d9691 | ||
|
|
36a933d0c4 | ||
|
|
d051bdf2c9 | ||
|
|
0424d214c5 | ||
|
|
c2aaa9b592 | ||
|
|
e450e52836 | ||
|
|
e2ecec03e8 | ||
|
|
318482d3ff | ||
|
|
2e4f665fa5 | ||
|
|
3d9738ac2f | ||
|
|
666cc855c1 | ||
|
|
3a059f6aca | ||
|
|
cdd3bc3cd6 | ||
|
|
87d57dab13 | ||
|
|
19789eb7ab | ||
|
|
395385f3e2 | ||
|
|
65aabc8333 | ||
|
|
5c16600b25 | ||
|
|
32fd4e33c8 | ||
|
|
560d247c9b | ||
|
|
40567fc8d0 | ||
|
|
9fc7bae13e | ||
|
|
515fd62dd8 | ||
|
|
170f901d86 | ||
|
|
d1fbe98379 | ||
|
|
fb1808d85a | ||
|
|
4094ca99dd | ||
|
|
fd05286e1a | ||
|
|
9436c83919 | ||
|
|
4f636d3d2c | ||
|
|
1a056be637 | ||
|
|
f38e184434 | ||
|
|
d24eb67fa2 | ||
|
|
c35e4f5750 | ||
|
|
0233f7b486 | ||
|
|
c129c38631 | ||
|
|
748ce8a23f | ||
|
|
a86166742f | ||
|
|
82c912237b | ||
|
|
5c89451985 | ||
|
|
2624b06729 | ||
|
|
7b7f5c09fd | ||
|
|
ad621e7208 | ||
|
|
034f18c419 | ||
|
|
7a6bf8b870 | ||
|
|
f529a5c64c | ||
|
|
69662f84df | ||
|
|
7d0ab1ba25 | ||
|
|
bd46e3e195 | ||
|
|
e5a92f64c0 | ||
|
|
798d0ab82b | ||
|
|
acaed1ef0e | ||
|
|
78f94e365c | ||
|
|
11379f150c | ||
|
|
41da55921c | ||
|
|
e9141ff5c9 | ||
|
|
2760de7951 | ||
|
|
203d6d3ac2 | ||
|
|
2a2192e196 | ||
|
|
876552b922 | ||
|
|
2b922508c5 | ||
|
|
cbee0542ad | ||
|
|
bc499bcfbf | ||
|
|
861c85f099 | ||
|
|
de63622cdd | ||
|
|
f5cf27a79e | ||
|
|
88e6cf7d8a | ||
|
|
0d28e663e4 | ||
|
|
716695e11e | ||
|
|
2770650340 | ||
|
|
0bff37b600 | ||
|
|
8614f11a31 | ||
|
|
b27319313d | ||
|
|
1f1c7826a4 | ||
|
|
d8736c17e6 | ||
|
|
00d72fe555 | ||
|
|
9943a94108 | ||
|
|
7a1b7b3291 | ||
|
|
832106dc86 | ||
|
|
24b9bd6ccc | ||
|
|
bd19b83db4 | ||
|
|
eb43f83c71 | ||
|
|
6e89197b3f | ||
|
|
51739a4dfe | ||
|
|
87f39b4273 | ||
|
|
fcea1ecbc2 | ||
|
|
7b9ebc3465 | ||
|
|
40ebaefac9 |
@@ -14,17 +14,13 @@ files:
|
||||
owner: root
|
||||
group: users
|
||||
content: |
|
||||
$(ls -td /opt/elasticbeanstalk/node-install/node-* | head -1)/bin/npm install -g npm@4
|
||||
$(ls -td /opt/elasticbeanstalk/node-install/node-* | head -1)/bin/npm install -g npm@5
|
||||
container_commands:
|
||||
01_makeBabel:
|
||||
command: "touch /tmp/.babel.json"
|
||||
02_ownBabel:
|
||||
command: "chmod a+rw /tmp/.babel.json"
|
||||
03_installBower:
|
||||
command: "$NODE_HOME/bin/npm install -g bower"
|
||||
04_installGulp:
|
||||
03_installGulp:
|
||||
command: "$NODE_HOME/bin/npm install -g gulp"
|
||||
05_runBower:
|
||||
command: "$NODE_HOME/lib/node_modules/bower/bin/bower --config.interactive=false --allow-root install -f"
|
||||
06_runGulp:
|
||||
04_runGulp:
|
||||
command: "$NODE_HOME/lib/node_modules/gulp/bin/gulp.js build"
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,11 +2,14 @@
|
||||
website/client-old/gen
|
||||
website/client-old/common
|
||||
website/client-old/apidoc
|
||||
website/build
|
||||
website/client-old/js/habitrpg-shared.js*
|
||||
website/client-old/css/habitrpg-shared.css
|
||||
website/transpiled-babel/
|
||||
website/common/transpiled-babel/
|
||||
node_modules
|
||||
content_cache
|
||||
apidoc_build
|
||||
*.swp
|
||||
.idea*
|
||||
config.json
|
||||
|
||||
@@ -13,7 +13,7 @@ addons:
|
||||
- g++-4.8
|
||||
before_install:
|
||||
- $CXX --version
|
||||
- npm install -g npm@4
|
||||
- npm install -g npm@5
|
||||
- if [ $REQUIRES_SERVER ]; then sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10; echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list; sudo apt-get update; sudo apt-get install mongodb-org-server; fi
|
||||
install:
|
||||
- npm install &> npm.install.log || (cat npm.install.log; false)
|
||||
@@ -34,6 +34,5 @@ env:
|
||||
- TEST="test:sanity"
|
||||
- TEST="test:content" COVERAGE=true
|
||||
- TEST="test:common" COVERAGE=true
|
||||
- TEST="test:karma" COVERAGE=true
|
||||
- TEST="client:unit" COVERAGE=true
|
||||
- TEST="apidoc"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
FROM node:boron
|
||||
|
||||
# Upgrade NPM to v5 (Yarn is needed because of this bug https://github.com/npm/npm/issues/16807)
|
||||
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
|
||||
RUN yarn global add npm@5
|
||||
# Install global packages
|
||||
RUN npm install -g gulp grunt-cli bower mocha
|
||||
RUN npm install -g gulp mocha
|
||||
|
||||
# Clone Habitica repo and install dependencies
|
||||
RUN mkdir -p /usr/src/habitrpg
|
||||
@@ -9,7 +12,6 @@ WORKDIR /usr/src/habitrpg
|
||||
RUN git clone https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
||||
RUN cp config.json.example config.json
|
||||
RUN npm install
|
||||
RUN bower install --allow-root
|
||||
|
||||
# Create Build dir
|
||||
RUN mkdir -p ./website/build
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
FROM node:boron
|
||||
|
||||
# Upgrade NPM to v5 (Yarn is needed because of this bug https://github.com/npm/npm/issues/16807)
|
||||
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
|
||||
RUN yarn global add npm@5
|
||||
# Install global packages
|
||||
RUN npm install -g gulp grunt-cli bower mocha
|
||||
RUN npm install -g gulp mocha
|
||||
|
||||
# Clone Habitica repo and install dependencies
|
||||
RUN mkdir -p /usr/src/habitrpg
|
||||
WORKDIR /usr/src/habitrpg
|
||||
RUN git clone --branch v3.116.1 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
||||
RUN git clone --branch v4.0.3 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
||||
RUN npm install
|
||||
RUN bower install --allow-root
|
||||
RUN gulp build:prod --force
|
||||
|
||||
# Create Build dir
|
||||
|
||||
142
Gruntfile.js
142
Gruntfile.js
@@ -1,142 +0,0 @@
|
||||
/*global module:false*/
|
||||
require('babel-register');
|
||||
var _ = require('lodash');
|
||||
module.exports = function(grunt) {
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
karma: {
|
||||
unit: {
|
||||
configFile: 'test/client-old/spec/karma.conf.js'
|
||||
},
|
||||
continuous: {
|
||||
configFile: 'test/client-old/spec/karma.conf.js',
|
||||
singleRun: true,
|
||||
autoWatch: false
|
||||
}
|
||||
},
|
||||
|
||||
clean: {
|
||||
build: ['website/build']
|
||||
},
|
||||
|
||||
cssmin: {
|
||||
dist: {
|
||||
options: {
|
||||
report: 'gzip'
|
||||
},
|
||||
files:{
|
||||
"website/client-old/css/habitrpg-shared.css": [
|
||||
"website/assets/sprites/dist/spritesmith*.css",
|
||||
"website/assets/sprites/css/backer.css",
|
||||
"website/assets/sprites/css/Mounts.css",
|
||||
"website/assets/sprites/css/index.css"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
stylus: {
|
||||
build: {
|
||||
options: {
|
||||
compress: false, // AFTER
|
||||
'include css': true,
|
||||
paths: ['website/client-old']
|
||||
},
|
||||
files: {
|
||||
'website/build/app.css': ['website/client-old/css/index.styl'],
|
||||
'website/build/static.css': ['website/client-old/css/static.styl']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
copy: {
|
||||
build: {
|
||||
files: [
|
||||
{expand: true, cwd: 'website/client-old/', src: 'favicon.ico', dest: 'website/build/'},
|
||||
{expand: true, cwd: 'website/client-old/', src: 'favicon_192x192.png', dest: 'website/build/'},
|
||||
{expand: true, cwd: 'website/assets/sprites/dist/', src: 'spritesmith*.png', dest: 'website/build/static/sprites'},
|
||||
{expand: true, cwd: 'website/assets/sprites/', src: 'backer-only/*.gif', dest: 'website/build/'},
|
||||
{expand: true, cwd: 'website/assets/sprites/', src: 'npc_ian.gif', dest: 'website/build/'},
|
||||
{expand: true, cwd: 'website/assets/sprites/', src: 'quest_*.gif', dest: 'website/build/'},
|
||||
{expand: true, cwd: 'website/client-old/', src: 'bower_components/bootstrap/dist/fonts/*', dest: 'website/build/'}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// UPDATE IT WHEN YOU ADD SOME FILES NOT ALREADY MATCHED!
|
||||
hashres: {
|
||||
build: {
|
||||
options: {
|
||||
fileNameFormat: '${name}-${hash}.${ext}'
|
||||
},
|
||||
src: [
|
||||
'website/build/*.js',
|
||||
'website/build/*.css',
|
||||
'website/build/favicon.ico',
|
||||
'website/build/favicon_192x192.png',
|
||||
'website/build/*.png',
|
||||
'website/build/static/sprites/*.png',
|
||||
'website/build/*.gif',
|
||||
'website/build/bower_components/bootstrap/dist/fonts/*'
|
||||
],
|
||||
dest: 'website/build/*.css'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Load build files from client-old/manifest.json
|
||||
grunt.registerTask('loadManifestFiles', 'Load all build files from client-old/manifest.json', function(){
|
||||
var files = grunt.file.readJSON('./website/client-old/manifest.json');
|
||||
var uglify = {};
|
||||
var cssmin = {};
|
||||
|
||||
_.each(files, function(val, key){
|
||||
|
||||
var js = uglify['website/build/' + key + '.js'] = [];
|
||||
|
||||
_.each(files[key].js, function(val){
|
||||
var path = "./";
|
||||
if( val.indexOf('common/') == -1)
|
||||
path = './website/client-old/';
|
||||
js.push(path + val);
|
||||
});
|
||||
|
||||
var css = cssmin['website/build/' + key + '.css'] = [];
|
||||
|
||||
_.each(files[key].css, function(val){
|
||||
var path = "./";
|
||||
if( val.indexOf('common/') == -1) {
|
||||
path = (val == 'app.css' || val == 'static.css') ? './website/build/' : './website/client-old/';
|
||||
}
|
||||
css.push(path + val)
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
grunt.config.set('uglify.build.files', uglify);
|
||||
grunt.config.set('uglify.build.options', {compress: false});
|
||||
|
||||
grunt.config.set('cssmin.build.files', cssmin);
|
||||
// Rewrite urls to relative path
|
||||
grunt.config.set('cssmin.build.options', {'target': 'website/client-old/css/whatever-css.css'});
|
||||
});
|
||||
|
||||
// Register tasks.
|
||||
grunt.registerTask('build:prod', ['loadManifestFiles', 'clean:build', 'uglify', 'stylus', 'cssmin', 'copy:build', 'hashres']);
|
||||
grunt.registerTask('build:dev', ['cssmin', 'stylus']);
|
||||
grunt.registerTask('build:test', ['build:dev']);
|
||||
|
||||
// Load tasks
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-stylus');
|
||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-hashres');
|
||||
if (process.env.NODE_ENV !== 'production') grunt.loadNpmTasks('grunt-karma');
|
||||
|
||||
};
|
||||
56
bower.json
56
bower.json
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"name": "HabitRPG",
|
||||
"version": "0.1.1",
|
||||
"homepage": "https://github.com/lefnire/habitrpg",
|
||||
"authors": [
|
||||
"Tyler Renelle <tylerrenelle@gmail.com>"
|
||||
],
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"website/client-old/bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"Angular-At-Directive": "snicker/Angular-At-Directive#c27bae207aa06d1e",
|
||||
"angular": "1.3.9",
|
||||
"angular-bootstrap": "0.13.0",
|
||||
"angular-filter": "0.5.1",
|
||||
"angular-loading-bar": "0.6.0",
|
||||
"angular-resource": "1.3.9",
|
||||
"angular-sanitize": "1.3.9",
|
||||
"angular-ui": "0.4.0",
|
||||
"angular-ui-router": "0.2.13",
|
||||
"angular-ui-select2": "angular-ui/ui-select2#afa6589a54cb72815f",
|
||||
"angular-ui-utils": "0.1.0",
|
||||
"bootstrap": "3.1.0",
|
||||
"bootstrap-growl": "ifightcrime/bootstrap-growl#162daa41cd1155f",
|
||||
"bootstrap-tour": "0.10.1",
|
||||
"css-social-buttons": "samcollins/css-social-buttons#v1.1.1 ",
|
||||
"github-buttons": "mdo/github-buttons#v3.0.0",
|
||||
"hello": "1.14.1",
|
||||
"jquery": "2.1.0",
|
||||
"jquery-colorbox": "1.4.36",
|
||||
"jquery-ui": "1.10.3",
|
||||
"jquery.cookie": "1.4.0",
|
||||
"js-emoji": "snicker/js-emoji#f25d8a303f",
|
||||
"ngInfiniteScroll": "1.1.0",
|
||||
"pnotify": "1.3.1",
|
||||
"sticky": "1.0.3",
|
||||
"swagger-ui": "wordnik/swagger-ui#v2.0.24",
|
||||
"smart-app-banner": "78ef9c0679723b25be1a0ae04f7b4aef7cbced4f",
|
||||
"habitica-markdown": "1.2.2",
|
||||
"pusher-js-auth": "^2.0.0",
|
||||
"pusher-websocket-iso": "pusher#^3.2.0",
|
||||
"taggle": "^1.11.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular-mocks": "1.3.9"
|
||||
},
|
||||
"resolutions": {
|
||||
"angular": "1.3.9",
|
||||
"jquery": ">=1.9.0"
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import gulp from 'gulp';
|
||||
import clean from 'rimraf';
|
||||
import apidoc from 'apidoc';
|
||||
|
||||
const APIDOC_DEST_PATH = './website/build/apidoc';
|
||||
const APIDOC_DEST_PATH = './apidoc_build';
|
||||
const APIDOC_SRC_PATH = './website/server';
|
||||
gulp.task('apidoc:clean', (done) => {
|
||||
clean(APIDOC_DEST_PATH, done);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import gulp from 'gulp';
|
||||
import browserify from 'browserify';
|
||||
import source from 'vinyl-source-stream';
|
||||
import buffer from 'vinyl-buffer';
|
||||
import uglify from 'gulp-uglify';
|
||||
import sourcemaps from 'gulp-sourcemaps';
|
||||
import babel from 'babelify';
|
||||
|
||||
gulp.task('browserify', function () {
|
||||
let bundler = browserify({
|
||||
entries: './website/common/browserify.js',
|
||||
debug: true,
|
||||
transform: [[babel, { compact: false }]],
|
||||
});
|
||||
|
||||
return bundler.bundle()
|
||||
.pipe(source('habitrpg-shared.js'))
|
||||
.pipe(buffer())
|
||||
.pipe(sourcemaps.init({loadMaps: true}))
|
||||
.pipe(uglify())
|
||||
.on('error', function (err) {
|
||||
console.error(err);
|
||||
this.emit('end');
|
||||
})
|
||||
.pipe(sourcemaps.write('./'))
|
||||
.pipe(gulp.dest('./website/client-old/js/'));
|
||||
});
|
||||
|
||||
gulp.task('browserify:watch', () => {
|
||||
gulp.watch('./website/common/script/**/*.js', ['browserify']);
|
||||
});
|
||||
@@ -1,13 +1,11 @@
|
||||
import gulp from 'gulp';
|
||||
import runSequence from 'run-sequence';
|
||||
import babel from 'gulp-babel';
|
||||
require('gulp-grunt')(gulp);
|
||||
import webpackProductionBuild from '../webpack/build';
|
||||
|
||||
gulp.task('build', () => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
gulp.start('build:prod');
|
||||
} else {
|
||||
gulp.start('build:dev');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,18 +23,16 @@ gulp.task('build:common', () => {
|
||||
|
||||
gulp.task('build:server', ['build:src', 'build:common']);
|
||||
|
||||
gulp.task('build:dev', ['browserify', 'prepare:staticNewStuff'], (done) => {
|
||||
gulp.start('grunt-build:dev', done);
|
||||
// Client Production Build
|
||||
gulp.task('build:client', ['bootstrap'], (done) => {
|
||||
webpackProductionBuild((err, output) => {
|
||||
if (err) return done(err);
|
||||
console.log(output);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('build:dev:watch', ['build:dev'], () => {
|
||||
gulp.watch(['website/client-old/**/*.styl', 'website/common/script/*']);
|
||||
});
|
||||
|
||||
gulp.task('build:prod', ['browserify', 'build:server', 'prepare:staticNewStuff'], (done) => {
|
||||
runSequence(
|
||||
'grunt-build:prod',
|
||||
'apidoc',
|
||||
done
|
||||
);
|
||||
});
|
||||
gulp.task('build:prod', [
|
||||
'build:server',
|
||||
'build:client',
|
||||
'apidoc',
|
||||
]);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import gulp from 'gulp';
|
||||
import jade from 'jade';
|
||||
import {writeFileSync} from 'fs';
|
||||
|
||||
gulp.task('prepare:staticNewStuff', () => {
|
||||
writeFileSync(
|
||||
'./website/client-old/new-stuff.html',
|
||||
jade.compileFile('./website/views/shared/new-stuff.jade')()
|
||||
);
|
||||
});
|
||||
@@ -10,25 +10,24 @@ import {each} from 'lodash';
|
||||
|
||||
// https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248
|
||||
const MAX_SPRITESHEET_SIZE = 1024 * 1024 * 3;
|
||||
const DIST_PATH = 'website/assets/sprites/dist/';
|
||||
|
||||
const IMG_DIST_PATH_NEW_CLIENT = 'website/static/sprites/';
|
||||
const CSS_DIST_PATH_NEW_CLIENT = 'website/client/assets/css/sprites/';
|
||||
const IMG_DIST_PATH = 'website/static/sprites/';
|
||||
const CSS_DIST_PATH = 'website/client/assets/css/sprites/';
|
||||
|
||||
gulp.task('sprites:compile', ['sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions']);
|
||||
|
||||
gulp.task('sprites:main', () => {
|
||||
let mainSrc = sync('website/assets/sprites/spritesmith/**/*.png');
|
||||
let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
|
||||
return createSpritesStream('main', mainSrc);
|
||||
});
|
||||
|
||||
gulp.task('sprites:largeSprites', () => {
|
||||
let largeSrc = sync('website/assets/sprites/spritesmith_large/**/*.png');
|
||||
let largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png');
|
||||
return createSpritesStream('largeSprites', largeSrc);
|
||||
});
|
||||
|
||||
gulp.task('sprites:clean', (done) => {
|
||||
clean(`{${DIST_PATH}spritesmith*,${IMG_DIST_PATH_NEW_CLIENT}spritesmith*,${CSS_DIST_PATH_NEW_CLIENT}spritesmith*}`, done);
|
||||
clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done);
|
||||
});
|
||||
|
||||
gulp.task('sprites:checkCompiledDimensions', ['sprites:main', 'sprites:largeSprites'], () => {
|
||||
@@ -36,7 +35,7 @@ gulp.task('sprites:checkCompiledDimensions', ['sprites:main', 'sprites:largeSpri
|
||||
|
||||
let numberOfSheetsThatAreTooBig = 0;
|
||||
|
||||
let distSpritesheets = sync(`${DIST_PATH}*.png`);
|
||||
let distSpritesheets = sync(`${IMG_DIST_PATH}*.png`);
|
||||
|
||||
each(distSpritesheets, (img, index) => {
|
||||
let spriteSize = calculateImgDimensions(img);
|
||||
@@ -68,18 +67,16 @@ function createSpritesStream (name, src) {
|
||||
cssName: `spritesmith-${name}-${index}.css`,
|
||||
algorithm: 'binary-tree',
|
||||
padding: 1,
|
||||
cssTemplate: 'website/assets/sprites/css/css.template.handlebars',
|
||||
cssTemplate: 'website/raw_sprites/css/css.template.handlebars',
|
||||
cssVarMap: cssVarMap,
|
||||
}));
|
||||
|
||||
let imgStream = spriteData.img
|
||||
.pipe(imagemin())
|
||||
.pipe(gulp.dest(IMG_DIST_PATH_NEW_CLIENT))
|
||||
.pipe(gulp.dest(DIST_PATH));
|
||||
.pipe(gulp.dest(IMG_DIST_PATH));
|
||||
|
||||
let cssStream = spriteData.css
|
||||
.pipe(gulp.dest(CSS_DIST_PATH_NEW_CLIENT))
|
||||
.pipe(gulp.dest(DIST_PATH));
|
||||
.pipe(gulp.dest(CSS_DIST_PATH));
|
||||
|
||||
stream.add(imgStream);
|
||||
stream.add(cssStream);
|
||||
|
||||
@@ -3,8 +3,6 @@ import nodemon from 'gulp-nodemon';
|
||||
|
||||
let pkg = require('../package.json');
|
||||
|
||||
gulp.task('run:dev', ['nodemon', 'build:dev:watch']);
|
||||
|
||||
gulp.task('nodemon', () => {
|
||||
nodemon({
|
||||
script: pkg.main,
|
||||
|
||||
@@ -29,7 +29,6 @@ const SANITY_TEST_COMMAND = 'npm run test:sanity';
|
||||
const COMMON_TEST_COMMAND = 'npm run test:common';
|
||||
const CONTENT_TEST_COMMAND = 'npm run test:content';
|
||||
const CONTENT_OPTIONS = {maxBuffer: 1024 * 500};
|
||||
const KARMA_TEST_COMMAND = 'npm run test:karma';
|
||||
|
||||
/* Helper methods for reporting test summary */
|
||||
let testResults = [];
|
||||
@@ -75,25 +74,11 @@ gulp.task('test:prepare:server', ['test:prepare:mongo'], () => {
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('test:prepare:translations', (cb) => {
|
||||
fs.writeFile(
|
||||
'test/client-old/spec/mocks/translations.js',
|
||||
`if(!window.env) window.env = {};
|
||||
window.env.translations = ${JSON.stringify(i18n.translations['en'])};`, cb);
|
||||
|
||||
});
|
||||
|
||||
gulp.task('test:prepare:build', ['build', 'test:prepare:translations']);
|
||||
// exec(testBin('grunt build:test'), cb);
|
||||
|
||||
gulp.task('test:prepare:webdriver', (cb) => {
|
||||
exec('npm run test:prepare:webdriver', cb);
|
||||
});
|
||||
gulp.task('test:prepare:build', ['build']);
|
||||
|
||||
gulp.task('test:prepare', [
|
||||
'test:prepare:build',
|
||||
'test:prepare:mongo',
|
||||
'test:prepare:webdriver',
|
||||
]);
|
||||
|
||||
gulp.task('test:sanity', (cb) => {
|
||||
@@ -185,99 +170,6 @@ gulp.task('test:content:safe', ['test:prepare:build'], (cb) => {
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:karma', ['test:prepare:build'], (cb) => {
|
||||
let runner = exec(
|
||||
testBin(KARMA_TEST_COMMAND),
|
||||
(err, stdout) => {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
cb();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:karma:watch', ['test:prepare:build'], (cb) => {
|
||||
let runner = exec(
|
||||
testBin(`${KARMA_TEST_COMMAND}:watch`),
|
||||
(err, stdout) => {
|
||||
cb(err);
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:karma:safe', ['test:prepare:build'], (cb) => {
|
||||
let runner = exec(
|
||||
testBin(KARMA_TEST_COMMAND),
|
||||
(err, stdout) => {
|
||||
testResults.push({
|
||||
suite: 'Karma Specs\t',
|
||||
pass: testCount(stdout, /(\d+) tests? completed/),
|
||||
fail: testCount(stdout, /(\d+) tests? failed/),
|
||||
pend: testCount(stdout, /(\d+) tests? skipped/),
|
||||
});
|
||||
cb();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:e2e', ['test:prepare', 'test:prepare:server'], (cb) => {
|
||||
let support = [
|
||||
'Xvfb :99 -screen 0 1024x768x24 -extension RANDR',
|
||||
testBin('npm run test:e2e:webdriver', 'DISPLAY=:99'),
|
||||
].map(exec);
|
||||
support.push(server);
|
||||
|
||||
Bluebird.all([
|
||||
awaitPort(TEST_SERVER_PORT),
|
||||
awaitPort(4444),
|
||||
]).then(() => {
|
||||
let runner = exec(
|
||||
'npm run test:e2e',
|
||||
(err, stdout, stderr) => {
|
||||
support.forEach(kill);
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
cb();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('test:e2e:safe', ['test:prepare', 'test:prepare:server'], (cb) => {
|
||||
let support = [
|
||||
'Xvfb :99 -screen 0 1024x768x24 -extension RANDR',
|
||||
'npm run test:e2e:webdriver',
|
||||
].map(exec);
|
||||
|
||||
Bluebird.all([
|
||||
awaitPort(TEST_SERVER_PORT),
|
||||
awaitPort(4444),
|
||||
]).then(() => {
|
||||
let runner = exec(
|
||||
'npm run test:e2e',
|
||||
(err, stdout, stderr) => {
|
||||
let match = stdout.match(/(\d+) tests?.*(\d) failures?/);
|
||||
|
||||
testResults.push({
|
||||
suite: 'End-to-End Specs\t',
|
||||
pass: testCount(stdout, /(\d+) passing/),
|
||||
fail: testCount(stdout, /(\d+) failing/),
|
||||
pend: testCount(stdout, /(\d+) pending/),
|
||||
});
|
||||
support.forEach(kill);
|
||||
cb();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('test:api-v3:unit', (done) => {
|
||||
let runner = exec(
|
||||
testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-unit --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/unit --recursive --require ./test/helpers/start-server'),
|
||||
@@ -331,7 +223,6 @@ gulp.task('test', (done) => {
|
||||
'test:sanity',
|
||||
'test:content',
|
||||
'test:common',
|
||||
'test:karma',
|
||||
'test:api-v3:unit',
|
||||
'test:api-v3:integration',
|
||||
done
|
||||
|
||||
@@ -10,9 +10,7 @@ require('babel-register');
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
require('./gulp/gulp-apidoc');
|
||||
require('./gulp/gulp-newstuff');
|
||||
require('./gulp/gulp-build');
|
||||
require('./gulp/gulp-babelify');
|
||||
require('./gulp/gulp-bootstrap');
|
||||
} else {
|
||||
require('glob').sync('./gulp/gulp-*').forEach(require);
|
||||
|
||||
97
migrations/20170928_redesign_guilds.js
Normal file
97
migrations/20170928_redesign_guilds.js
Normal file
@@ -0,0 +1,97 @@
|
||||
var migrationName = '20170928_redesign_guilds.js';
|
||||
|
||||
/*
|
||||
* Copy Guild Leader messages to end of Guild descriptions
|
||||
* Copy Guild logos to beginning of Guild descriptions
|
||||
*/
|
||||
|
||||
var monk = require('monk');
|
||||
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
var dbGroups = monk(connectionString).get('groups', { castIds: false });
|
||||
|
||||
function processGroups(lastId) {
|
||||
// specify a query to limit the affected groups (empty for all groups):
|
||||
var query = {
|
||||
};
|
||||
|
||||
var fields = {
|
||||
'description': 1,
|
||||
'logo': 1,
|
||||
'leaderMessage': 1,
|
||||
}
|
||||
|
||||
if (lastId) {
|
||||
query._id = {
|
||||
$gt: lastId
|
||||
}
|
||||
}
|
||||
|
||||
return dbGroups.find(query, {
|
||||
fields: fields,
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
})
|
||||
.then(updateGroups)
|
||||
.catch(function (err) {
|
||||
console.log(err);
|
||||
return exiting(1, 'ERROR! ' + err);
|
||||
});
|
||||
}
|
||||
|
||||
var progressCount = 1000;
|
||||
var count = 0;
|
||||
|
||||
function updateGroups (groups) {
|
||||
if (!groups || groups.length === 0) {
|
||||
console.warn('All appropriate groups found and modified.');
|
||||
displayData();
|
||||
return;
|
||||
}
|
||||
|
||||
var groupPromises = groups.map(updateGroup);
|
||||
var lastGroup = groups[groups.length - 1];
|
||||
|
||||
return Promise.all(groupPromises)
|
||||
.then(function () {
|
||||
processGroups(lastGroup._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateGroup (group) {
|
||||
count++;
|
||||
|
||||
var description = group.description;
|
||||
|
||||
if (group.logo) {
|
||||
description = '\n\n \n\n' + description;
|
||||
}
|
||||
|
||||
if (group.leaderMessage) {
|
||||
description = description + '\n\n \n\n' + group.leaderMessage;
|
||||
}
|
||||
|
||||
var set = {
|
||||
description: description,
|
||||
};
|
||||
|
||||
if (count % progressCount == 0) console.warn(count + ' ' + group._id);
|
||||
|
||||
return dbGroups.update({_id: group._id}, {$set:set});
|
||||
}
|
||||
|
||||
function displayData() {
|
||||
console.warn('\n' + count + ' groups processed\n');
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting(code, msg) {
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) { msg = 'ERROR!'; }
|
||||
if (msg) {
|
||||
if (code) { console.error(msg); }
|
||||
else { console.log( msg); }
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
module.exports = processGroups;
|
||||
128
migrations/20170928_redesign_launch.js
Normal file
128
migrations/20170928_redesign_launch.js
Normal file
@@ -0,0 +1,128 @@
|
||||
import { selectGearToPin } from '../website/common/script/ops/pinnedGearUtils';
|
||||
|
||||
var getItemInfo = require('../website/common/script/libs/getItemInfo');
|
||||
|
||||
var migrationName = '20170928_redesign_launch.js';
|
||||
var authorName = 'paglias'; // in case script author needs to know when their ...
|
||||
var authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; //... own data is done
|
||||
|
||||
/*
|
||||
* Migrate existing in app rewards lists to pinned items
|
||||
* Award Veteran Pets
|
||||
*/
|
||||
|
||||
var monk = require('monk');
|
||||
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
var dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers(lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
var query = {
|
||||
'migration': {$ne:migrationName},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2017-09-21')},
|
||||
};
|
||||
|
||||
var fields = {
|
||||
'items.pets': 1,
|
||||
'items.gear': 1,
|
||||
'stats.class': 1,
|
||||
}
|
||||
|
||||
if (lastId) {
|
||||
query._id = {
|
||||
$gt: lastId
|
||||
}
|
||||
}
|
||||
|
||||
return dbUsers.find(query, {
|
||||
fields: fields,
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(function (err) {
|
||||
console.log(err);
|
||||
return exiting(1, 'ERROR! ' + err);
|
||||
});
|
||||
}
|
||||
|
||||
var progressCount = 1000;
|
||||
var count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return;
|
||||
}
|
||||
|
||||
var userPromises = users.map(updateUser);
|
||||
var lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(function () {
|
||||
processUsers(lastUser._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count++;
|
||||
|
||||
var set = {'migration': migrationName};
|
||||
|
||||
var oldRewardsList = selectGearToPin(user);
|
||||
var newPinnedItems = [
|
||||
{
|
||||
type: 'armoire',
|
||||
path: 'armoire',
|
||||
},
|
||||
{
|
||||
type: 'potion',
|
||||
path: 'potion',
|
||||
},
|
||||
];
|
||||
|
||||
oldRewardsList.forEach(item => {
|
||||
var type = 'marketGear';
|
||||
|
||||
var itemInfo = getItemInfo(user, 'marketGear', item);
|
||||
newPinnedItems.push({
|
||||
type,
|
||||
path: itemInfo.path,
|
||||
})
|
||||
});
|
||||
|
||||
set.pinnedItems = newPinnedItems;
|
||||
|
||||
if (user.items.pets['Lion-Veteran']) {
|
||||
set['items.pets.Bear-Veteran'] = 5;
|
||||
} else if (user.items.pets['Tiger-Veteran']) {
|
||||
set['items.pets.Lion-Veteran'] = 5;
|
||||
} else if (user.items.pets['Wolf-Veteran']) {
|
||||
set['items.pets.Tiger-Veteran'] = 5;
|
||||
} else {
|
||||
set['items.pets.Wolf-Veteran'] = 5;
|
||||
}
|
||||
|
||||
if (count % progressCount == 0) console.warn(count + ' ' + user._id);
|
||||
if (user._id == authorUuid) console.warn(authorName + ' processed');
|
||||
|
||||
return dbUsers.update({_id: user._id}, {$set:set});
|
||||
}
|
||||
|
||||
function displayData() {
|
||||
console.warn('\n' + count + ' users processed\n');
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting(code, msg) {
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) { msg = 'ERROR!'; }
|
||||
if (msg) {
|
||||
if (code) { console.error(msg); }
|
||||
else { console.log( msg); }
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
module.exports = processUsers;
|
||||
@@ -2,7 +2,7 @@ var _id = '';
|
||||
var update = {
|
||||
$addToSet: {
|
||||
'purchased.plan.mysteryItems':{
|
||||
$each:['shield_mystery_201709','back_mystery_201709']
|
||||
$each:['armor_mystery_201710','head_mystery_201710']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
98
migrations/s3-upload.js
Normal file
98
migrations/s3-upload.js
Normal file
@@ -0,0 +1,98 @@
|
||||
let Bluebird = require('bluebird');
|
||||
let request = require('superagent');
|
||||
let last = require('lodash/last');
|
||||
let AWS = require('aws-sdk');
|
||||
|
||||
let config = require('../config');
|
||||
const S3_DIRECTORY = 'mobileApp/images'; //config.S3.SPRITES_DIRECTORY;
|
||||
|
||||
AWS.config.update({
|
||||
accessKeyId: config.S3.accessKeyId,
|
||||
secretAccessKey: config.S3.secretAccessKey,
|
||||
// region: config.get('S3_REGION'),
|
||||
});
|
||||
|
||||
let BUCKET_NAME = config.S3.bucket;
|
||||
let s3 = new AWS.S3();
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/22210077/2601552
|
||||
function uploadFile (buffer, fileName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
s3.putObject({
|
||||
Body: buffer,
|
||||
Key: fileName,
|
||||
Bucket: BUCKET_NAME,
|
||||
}, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
// console.info(`${fileName} uploaded to ${BUCKET_NAME} succesfully.`);
|
||||
resolve(fileName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFileName (file) {
|
||||
let piecesOfPath = file.split('/');
|
||||
let name = last(piecesOfPath);
|
||||
let fullName = S3_DIRECTORY + name;
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
function getFileFromUrl (url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.get(url).end((err, res) => {
|
||||
if (err) return reject(err);
|
||||
let file = res.body;
|
||||
resolve(file);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let commit = '78f94e365c72cc58f66857d5941105638db7d35c';
|
||||
commit = 'df0dbaba636c9ce424cc7040f7bd7fc1aa311015';
|
||||
let gihuburl = `https://api.github.com/repos/HabitRPG/habitica/commits/${commit}`
|
||||
|
||||
|
||||
let currentIndex = 0;
|
||||
|
||||
function uploadToS3(start, end, filesUrls) {
|
||||
let urls = filesUrls.slice(start, end);
|
||||
|
||||
if (urls.length === 0) {
|
||||
console.log("done");
|
||||
return;
|
||||
}
|
||||
|
||||
let promises = urls.map(fullUrl => {
|
||||
return getFileFromUrl(fullUrl)
|
||||
.then((buffer) => {
|
||||
return uploadFile(buffer, getFileName(fullUrl));
|
||||
});
|
||||
});
|
||||
console.log(promises.length)
|
||||
|
||||
return Bluebird.all(promises)
|
||||
.then(() => {
|
||||
currentIndex += 50;
|
||||
uploadToS3(currentIndex, currentIndex + 50, filesUrls);
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
request.get(gihuburl)
|
||||
.end((err, res) => {
|
||||
console.log(err);
|
||||
let files = res.body.files;
|
||||
|
||||
let filesUrls = [''];
|
||||
filesUrls = files.map(file => {
|
||||
return file.raw_url;
|
||||
})
|
||||
|
||||
uploadToS3(currentIndex, currentIndex + 50, filesUrls);
|
||||
});
|
||||
13885
npm-shrinkwrap.json
generated
13885
npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
19050
package-lock.json
generated
Normal file
19050
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
45
package.json
45
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "3.116.1",
|
||||
"version": "4.6.3",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@slack/client": "^3.8.1",
|
||||
@@ -14,6 +14,7 @@
|
||||
"autoprefixer": "^6.4.0",
|
||||
"aws-sdk": "^2.0.25",
|
||||
"axios": "^0.16.0",
|
||||
"axios-progress-bar": "^0.1.7",
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-eslint": "^7.2.3",
|
||||
"babel-loader": "^6.0.0",
|
||||
@@ -30,14 +31,14 @@
|
||||
"bcrypt": "^1.0.2",
|
||||
"bluebird": "^3.3.5",
|
||||
"body-parser": "^1.15.0",
|
||||
"bootstrap": "^4.0.0-alpha.6",
|
||||
"bootstrap-vue": "^0.18.0",
|
||||
"bower": "~1.3.12",
|
||||
"bootstrap": "4.0.0-alpha.6",
|
||||
"bootstrap-vue": "1.0.0-beta.7",
|
||||
"browserify": "~12.0.1",
|
||||
"compression": "^1.6.1",
|
||||
"connect-ratelimit": "0.0.7",
|
||||
"cookie-session": "^1.2.0",
|
||||
"coupon-code": "^0.4.5",
|
||||
"cross-env": "^4.0.0",
|
||||
"css-loader": "^0.28.0",
|
||||
"csv-stringify": "^1.0.2",
|
||||
"cwait": "~1.0.1",
|
||||
@@ -51,18 +52,8 @@
|
||||
"file-loader": "^0.10.0",
|
||||
"glob": "^4.3.5",
|
||||
"got": "^6.1.1",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-contrib-clean": "~0.6.0",
|
||||
"grunt-contrib-copy": "~0.6.0",
|
||||
"grunt-contrib-cssmin": "~0.10.0",
|
||||
"grunt-contrib-stylus": "~0.20.0",
|
||||
"grunt-contrib-uglify": "~0.6.0",
|
||||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-hashres": "habitrpg/grunt-hashres#v0.4.2",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-babel": "^6.1.2",
|
||||
"gulp-grunt": "^0.5.2",
|
||||
"gulp-imagemin": "^2.4.0",
|
||||
"gulp-nodemon": "^2.0.4",
|
||||
"gulp-sourcemaps": "^1.6.0",
|
||||
@@ -75,13 +66,13 @@
|
||||
"in-app-purchase": "^1.1.6",
|
||||
"intro.js": "^2.6.0",
|
||||
"jade": "~1.11.0",
|
||||
"jquery": "^3.1.1",
|
||||
"jquery": ">=3.0.0",
|
||||
"js2xmlparser": "~1.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"merge-stream": "^1.0.0",
|
||||
"method-override": "^2.3.5",
|
||||
"moment": "^2.13.0",
|
||||
"moment-recur": "habitrpg/moment-recur#v1.0.6",
|
||||
"moment-recur": "git://github.com/habitrpg/moment-recur#f147ef27bbc26ca67638385f3db4a44084c76626",
|
||||
"mongoose": "~4.8.6",
|
||||
"mongoose-id-autoinc": "~2013.7.14-4",
|
||||
"morgan": "^1.7.0",
|
||||
@@ -98,11 +89,12 @@
|
||||
"passport-google-oauth20": "1.0.0",
|
||||
"paypal-ipn": "3.0.0",
|
||||
"paypal-rest-sdk": "^1.2.1",
|
||||
"popper.js": "^1.11.0",
|
||||
"postcss-easy-import": "^2.0.0",
|
||||
"pretty-data": "^0.40.0",
|
||||
"ps-tree": "^1.0.0",
|
||||
"pug": "^2.0.0-beta.12",
|
||||
"push-notify": "habitrpg/push-notify#v1.2.0",
|
||||
"push-notify": "git://github.com/habitrpg/push-notify#6bc2b5fdb1bdc9649b9ec1964d79ca50187fc8a9",
|
||||
"pusher": "^1.3.0",
|
||||
"request": "~2.74.0",
|
||||
"rimraf": "^2.4.3",
|
||||
@@ -111,6 +103,7 @@
|
||||
"sass-loader": "^6.0.2",
|
||||
"serve-favicon": "^2.3.0",
|
||||
"shelljs": "^0.7.6",
|
||||
"sortablejs": "^1.6.1",
|
||||
"stripe": "^4.2.0",
|
||||
"superagent": "^3.4.3",
|
||||
"svg-inline-loader": "^0.7.1",
|
||||
@@ -126,11 +119,10 @@
|
||||
"vue": "^2.1.0",
|
||||
"vue-loader": "^11.0.0",
|
||||
"vue-mugen-scroll": "^0.2.1",
|
||||
"vue-notification": "^1.3.2",
|
||||
"vue-router": "^2.0.0-rc.5",
|
||||
"vue-style-loader": "^3.0.0",
|
||||
"vue-template-compiler": "^2.1.10",
|
||||
"vuejs-datepicker": "^0.9.4",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker#45e607a7bccf4e3e089761b3b7b33e3f2c5dc21f",
|
||||
"webpack": "^2.2.1",
|
||||
"webpack-merge": "^4.0.0",
|
||||
"winston": "^2.1.0",
|
||||
@@ -140,7 +132,7 @@
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "^6.9.1",
|
||||
"npm": "^4.0.2"
|
||||
"npm": "^5.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .js,.vue .",
|
||||
@@ -153,22 +145,17 @@
|
||||
"test:sanity": "istanbul cover --dir coverage/sanity --report lcovonly node_modules/mocha/bin/_mocha -- test/sanity --recursive",
|
||||
"test:common": "istanbul cover --dir coverage/common --report lcovonly node_modules/mocha/bin/_mocha -- test/common --recursive",
|
||||
"test:content": "istanbul cover --dir coverage/content --report lcovonly node_modules/mocha/bin/_mocha -- test/content --recursive",
|
||||
"test:karma": "karma start test/client-old/spec/karma.conf.js --single-run",
|
||||
"test:karma:watch": "karma start test/client-old/spec/karma.conf.js",
|
||||
"test:prepare:webdriver": "webdriver-manager update",
|
||||
"test:e2e:webdriver": "webdriver-manager start",
|
||||
"test:e2e": "protractor test/client-old/e2e/protractor.conf.js",
|
||||
"test:nodemon": "gulp test:nodemon",
|
||||
"coverage": "COVERAGE=true mocha --require register-handlers.js --reporter html-cov > coverage.html; open coverage.html",
|
||||
"sprites": "gulp sprites:compile",
|
||||
"client:dev": "gulp bootstrap && node webpack/dev-server.js",
|
||||
"client:build": "gulp bootstrap && node webpack/build.js",
|
||||
"client:build": "gulp build:client",
|
||||
"client:unit": "cross-env NODE_ENV=test karma start test/client/unit/karma.conf.js --single-run",
|
||||
"client:unit:watch": "cross-env NODE_ENV=test karma start test/client/unit/karma.conf.js",
|
||||
"client:e2e": "node test/client/e2e/runner.js",
|
||||
"client:test": "npm run client:unit && npm run client:e2e",
|
||||
"start": "gulp run:dev",
|
||||
"postinstall": "bower --config.interactive=false install -f && gulp build && npm run client:build",
|
||||
"start": "gulp nodemon",
|
||||
"postinstall": "gulp build",
|
||||
"apidoc": "gulp apidoc"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -179,7 +166,6 @@
|
||||
"chromedriver": "^2.27.2",
|
||||
"connect-history-api-fallback": "^1.1.0",
|
||||
"coveralls": "^2.11.2",
|
||||
"cross-env": "^4.0.0",
|
||||
"cross-spawn": "^5.0.1",
|
||||
"csv": "~0.3.6",
|
||||
"deep-diff": "~0.1.4",
|
||||
@@ -192,7 +178,6 @@
|
||||
"event-stream": "^3.2.2",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"expect.js": "~0.2.0",
|
||||
"grunt-karma": "~0.12.1",
|
||||
"http-proxy-middleware": "^0.17.0",
|
||||
"inject-loader": "^3.0.0-beta4",
|
||||
"istanbul": "^1.1.0-alpha.1",
|
||||
|
||||
@@ -48,8 +48,10 @@ describe('GET /challenges/:challengeId', () => {
|
||||
});
|
||||
expect(chal.group).to.eql({
|
||||
_id: group._id,
|
||||
categories: [],
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
summary: group.name,
|
||||
type: group.type,
|
||||
privacy: group.privacy,
|
||||
leader: groupLeader.id,
|
||||
@@ -100,8 +102,10 @@ describe('GET /challenges/:challengeId', () => {
|
||||
});
|
||||
expect(chal.group).to.eql({
|
||||
_id: group._id,
|
||||
categories: [],
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
summary: group.name,
|
||||
type: group.type,
|
||||
privacy: group.privacy,
|
||||
leader: groupLeader.id,
|
||||
@@ -153,7 +157,9 @@ describe('GET /challenges/:challengeId', () => {
|
||||
expect(chal.group).to.eql({
|
||||
_id: group._id,
|
||||
id: group.id,
|
||||
categories: [],
|
||||
name: group.name,
|
||||
summary: group.name,
|
||||
type: group.type,
|
||||
privacy: group.privacy,
|
||||
leader: groupLeader.id,
|
||||
|
||||
@@ -142,4 +142,22 @@ describe('GET /challenges/:challengeId/members', () => {
|
||||
let resIds = res.concat(res2).map(member => member._id);
|
||||
expect(resIds).to.eql(expectedIds.sort());
|
||||
});
|
||||
|
||||
it('supports using req.query.search to get search members', async () => {
|
||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||
let challenge = await generateChallenge(user, group);
|
||||
|
||||
let usersToGenerate = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
usersToGenerate.push(generateUser({challenges: [challenge._id]}));
|
||||
}
|
||||
let generatedUsers = await Promise.all(usersToGenerate);
|
||||
let profileNames = generatedUsers.map(generatedUser => generatedUser.profile.name);
|
||||
|
||||
let firstProfileName = profileNames[0];
|
||||
let nameToSearch = firstProfileName.substring(0, 4);
|
||||
|
||||
let response = await user.get(`/challenges/${challenge._id}/members?search=${nameToSearch}`);
|
||||
expect(response[0].profile.name).to.eql(firstProfileName);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,10 +41,12 @@ describe('GET challenges/user', () => {
|
||||
});
|
||||
expect(foundChallenge.group).to.eql({
|
||||
_id: publicGuild._id,
|
||||
categories: [],
|
||||
id: publicGuild._id,
|
||||
type: publicGuild.type,
|
||||
privacy: publicGuild.privacy,
|
||||
name: publicGuild.name,
|
||||
summary: publicGuild.name,
|
||||
leader: publicGuild.leader._id,
|
||||
});
|
||||
});
|
||||
@@ -61,10 +63,12 @@ describe('GET challenges/user', () => {
|
||||
});
|
||||
expect(foundChallenge1.group).to.eql({
|
||||
_id: publicGuild._id,
|
||||
categories: [],
|
||||
id: publicGuild._id,
|
||||
type: publicGuild.type,
|
||||
privacy: publicGuild.privacy,
|
||||
name: publicGuild.name,
|
||||
summary: publicGuild.name,
|
||||
leader: publicGuild.leader._id,
|
||||
});
|
||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||
@@ -76,10 +80,12 @@ describe('GET challenges/user', () => {
|
||||
});
|
||||
expect(foundChallenge2.group).to.eql({
|
||||
_id: publicGuild._id,
|
||||
categories: [],
|
||||
id: publicGuild._id,
|
||||
type: publicGuild.type,
|
||||
privacy: publicGuild.privacy,
|
||||
name: publicGuild.name,
|
||||
summary: publicGuild.name,
|
||||
leader: publicGuild.leader._id,
|
||||
});
|
||||
});
|
||||
@@ -96,10 +102,12 @@ describe('GET challenges/user', () => {
|
||||
});
|
||||
expect(foundChallenge1.group).to.eql({
|
||||
_id: publicGuild._id,
|
||||
categories: [],
|
||||
id: publicGuild._id,
|
||||
type: publicGuild.type,
|
||||
privacy: publicGuild.privacy,
|
||||
name: publicGuild.name,
|
||||
summary: publicGuild.name,
|
||||
leader: publicGuild.leader._id,
|
||||
});
|
||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||
@@ -111,14 +119,26 @@ describe('GET challenges/user', () => {
|
||||
});
|
||||
expect(foundChallenge2.group).to.eql({
|
||||
_id: publicGuild._id,
|
||||
categories: [],
|
||||
id: publicGuild._id,
|
||||
type: publicGuild.type,
|
||||
privacy: publicGuild.privacy,
|
||||
name: publicGuild.name,
|
||||
summary: publicGuild.name,
|
||||
leader: publicGuild.leader._id,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return not return challenges in user groups if we send member true param', async () => {
|
||||
let challenges = await member.get(`/challenges/user?member=${true}`);
|
||||
|
||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||
expect(foundChallenge1).to.not.exist;
|
||||
|
||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||
expect(foundChallenge2).to.not.exist;
|
||||
});
|
||||
|
||||
it('should return newest challenges first', async () => {
|
||||
let challenges = await user.get('/challenges/user');
|
||||
|
||||
@@ -137,6 +157,7 @@ describe('GET challenges/user', () => {
|
||||
let { group, groupLeader } = await createAndPopulateGroup({
|
||||
groupDetails: {
|
||||
name: 'TestPrivateGuild',
|
||||
summary: 'summary for TestPrivateGuild',
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
},
|
||||
@@ -158,6 +179,7 @@ describe('GET challenges/user', () => {
|
||||
let { group, groupLeader } = await createAndPopulateGroup({
|
||||
groupDetails: {
|
||||
name: 'TestGuild',
|
||||
summary: 'summary for TestGuild',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
|
||||
@@ -224,7 +224,7 @@ describe('POST /chat', () => {
|
||||
color: 'danger',
|
||||
author_name: `${user.profile.name} - ${user.auth.local.email} - ${user._id}`,
|
||||
title: 'Slur in Test Guild',
|
||||
title_link: `${BASE_URL}/#/options/groups/guilds/${groupWithChat.id}`,
|
||||
title_link: `${BASE_URL}/groups/guild/${groupWithChat.id}`,
|
||||
text: testSlurMessage,
|
||||
// footer: sandbox.match(/<.*?groupId=group-id&chatId=chat-id\|Flag this message>/),
|
||||
mrkdwn_in: [
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
} from '../../../../helpers/api-v3-integration.helper';
|
||||
import { v4 as generateUUID } from 'uuid';
|
||||
|
||||
describe('GET /export/avatar-:memberId.html', () => {
|
||||
xdescribe('GET /export/avatar-:memberId.html', () => {
|
||||
let user;
|
||||
|
||||
before(async () => {
|
||||
|
||||
32
test/api/v3/integration/groups/GET-group-plans.test.js
Normal file
32
test/api/v3/integration/groups/GET-group-plans.test.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import {
|
||||
generateUser,
|
||||
generateGroup,
|
||||
} from '../../../../helpers/api-v3-integration.helper';
|
||||
|
||||
describe('GET /group-plans', () => {
|
||||
let user;
|
||||
let groupPlan;
|
||||
|
||||
before(async () => {
|
||||
user = await generateUser({balance: 4});
|
||||
groupPlan = await generateGroup(user,
|
||||
{
|
||||
name: 'public guild - is member',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
{
|
||||
purchased: {
|
||||
plan: {
|
||||
customerId: 'existings',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('returns group plans for the user', async () => {
|
||||
let groupPlans = await user.get('/group-plans');
|
||||
|
||||
expect(groupPlans[0]._id).to.eql(groupPlan._id);
|
||||
});
|
||||
});
|
||||
@@ -6,7 +6,7 @@ import superagent from 'superagent';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const API_TEST_SERVER_PORT = nconf.get('PORT');
|
||||
describe('GET /qr-code/user/:memberId', () => {
|
||||
xdescribe('GET /qr-code/user/:memberId', () => {
|
||||
let user;
|
||||
|
||||
before(async () => {
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('GET /tasks/user', () => {
|
||||
it('returns all user\'s tasks', async () => {
|
||||
let createdTasks = await user.post('/tasks/user', [{text: 'test habit', type: 'habit'}, {text: 'test todo', type: 'todo'}]);
|
||||
let tasks = await user.get('/tasks/user');
|
||||
expect(tasks.length).to.equal(createdTasks.length + 1); // + 1 because 1 is a default task
|
||||
expect(tasks.length).to.equal(createdTasks.length + 1); // Plus one for generated todo
|
||||
});
|
||||
|
||||
it('returns only a type of user\'s tasks if req.query.type is specified', async () => {
|
||||
|
||||
@@ -95,7 +95,7 @@ describe('POST /tasks/unlink-all/:challengeId', () => {
|
||||
// Have the leader delete the challenge and unlink the tasks
|
||||
await user.del(`/challenges/${challenge._id}`);
|
||||
await user.post(`/tasks/unlink-all/${challenge._id}?keep=keep-all`);
|
||||
// Get the second task for the second user
|
||||
// Get the task for the second user
|
||||
const [, anotherUserTask] = await anotherUser.get('/tasks/user');
|
||||
// Expect the second user to still have the task, but unlinked
|
||||
expect(anotherUserTask.challenge).to.eql({
|
||||
@@ -106,4 +106,4 @@ describe('POST /tasks/unlink-all/:challengeId', () => {
|
||||
winner: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -131,7 +131,7 @@ describe('POST /tasks/user', () => {
|
||||
expect(task.updatedAt).not.to.equal('tomorrow');
|
||||
expect(task.challenge).not.to.equal('no');
|
||||
expect(task.completed).to.equal(false);
|
||||
expect(task.streak).not.to.equal('never');
|
||||
expect(task.dateCompleted).not.to.equal('never');
|
||||
expect(task.value).not.to.equal(324);
|
||||
expect(task.yesterDaily).to.equal(true);
|
||||
});
|
||||
|
||||
@@ -86,6 +86,12 @@ describe('DELETE /user', () => {
|
||||
});
|
||||
|
||||
it('deletes the user\'s tasks', async () => {
|
||||
await user.post('/tasks/user', {
|
||||
text: 'test habit',
|
||||
type: 'habit',
|
||||
});
|
||||
await user.sync();
|
||||
|
||||
// gets the user's tasks ids
|
||||
let ids = [];
|
||||
each(user.tasksOrder, (idsForOrder) => {
|
||||
|
||||
@@ -82,7 +82,7 @@ describe('GET /user/anonymized', () => {
|
||||
});
|
||||
// tasks
|
||||
expect(tasks2).to.exist;
|
||||
expect(tasks2.length).to.eql(5); // +1 because generateUser() assigns one todo
|
||||
expect(tasks2.length).to.eql(5);
|
||||
expect(tasks2[0].checklist).to.exist;
|
||||
_.forEach(tasks2, (task) => {
|
||||
expect(task.text).to.eql('task text');
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/* eslint-disable camelcase */
|
||||
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
describe('POST /user/buy/:key', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await generateUser({
|
||||
'stats.gp': 400,
|
||||
});
|
||||
});
|
||||
|
||||
// More tests in common code unit tests
|
||||
|
||||
it('returns an error if the item is not found', async () => {
|
||||
await expect(user.post('/user/buy/notExisting'))
|
||||
.to.eventually.be.rejected.and.eql({
|
||||
code: 404,
|
||||
error: 'NotFound',
|
||||
message: t('itemNotFound', {key: 'notExisting'}),
|
||||
});
|
||||
});
|
||||
|
||||
it('buys a potion', async () => {
|
||||
await user.update({
|
||||
'stats.gp': 400,
|
||||
'stats.hp': 40,
|
||||
});
|
||||
|
||||
let potion = content.potion;
|
||||
let res = await user.post('/user/buy/potion');
|
||||
await user.sync();
|
||||
|
||||
expect(user.stats.hp).to.equal(50);
|
||||
expect(res.data).to.eql(user.stats);
|
||||
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
||||
});
|
||||
|
||||
it('returns an error if user tries to buy a potion with full health', async () => {
|
||||
await user.update({
|
||||
'stats.gp': 40,
|
||||
'stats.hp': 50,
|
||||
});
|
||||
|
||||
await expect(user.post('/user/buy/potion'))
|
||||
.to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('messageHealthAlreadyMax'),
|
||||
});
|
||||
});
|
||||
it('buys a piece of gear', async () => {
|
||||
let key = 'armor_warrior_1';
|
||||
|
||||
await user.post(`/user/buy/${key}`);
|
||||
await user.sync();
|
||||
|
||||
expect(user.items.gear.owned.armor_warrior_1).to.eql(true);
|
||||
});
|
||||
});
|
||||
@@ -98,4 +98,24 @@ describe('POST /user/purchase/:type/:key', () => {
|
||||
await members[0].sync();
|
||||
expect(members[0].balance).to.equal(oldBalance);
|
||||
});
|
||||
|
||||
describe('bulk purchasing', () => {
|
||||
it('purchases a gem item', async () => {
|
||||
await user.post(`/user/purchase/${type}/${key}`, {quantity: 2});
|
||||
await user.sync();
|
||||
|
||||
expect(user.items[type][key]).to.equal(2);
|
||||
});
|
||||
|
||||
it('can convert gold to gems if subscribed', async () => {
|
||||
let oldBalance = user.balance;
|
||||
await user.update({
|
||||
'purchased.plan.customerId': 'group-plan',
|
||||
'stats.gp': 1000,
|
||||
});
|
||||
await user.post('/user/purchase/gems/gem', {quantity: 2});
|
||||
await user.sync();
|
||||
expect(user.balance).to.equal(oldBalance + 0.50);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,43 +10,31 @@ import nconf from 'nconf';
|
||||
|
||||
const API_TEST_SERVER_PORT = nconf.get('PORT');
|
||||
|
||||
describe('GET /user/auth/local/reset-password-set-new-one', () => {
|
||||
// @TODO skipped because on travis the client isn't available and the redirect fails
|
||||
xdescribe('GET /user/auth/local/reset-password-set-new-one', () => {
|
||||
let endpoint = `http://localhost:${API_TEST_SERVER_PORT}/static/user/auth/local/reset-password-set-new-one`;
|
||||
|
||||
// Tests to validate the validatePasswordResetCodeAndFindUser function
|
||||
|
||||
it('renders an error page if the code is missing', async () => {
|
||||
try {
|
||||
await superagent.get(endpoint);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
const res = await superagent.get(endpoint);
|
||||
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders an error page if the code is invalid json', async () => {
|
||||
try {
|
||||
await superagent.get(`${endpoint}?code=invalid`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
const res = await superagent.get(`${endpoint}?code=invalid`);
|
||||
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders an error page if the code cannot be decrypted', async () => {
|
||||
let user = await generateUser();
|
||||
|
||||
try {
|
||||
let code = JSON.stringify({ // not encrypted
|
||||
userId: user._id,
|
||||
expiresAt: new Date(),
|
||||
});
|
||||
await superagent.get(`${endpoint}?code=${code}`);
|
||||
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
let code = JSON.stringify({ // not encrypted
|
||||
userId: user._id,
|
||||
expiresAt: new Date(),
|
||||
});
|
||||
const res = await superagent.get(`${endpoint}?code=${code}`);
|
||||
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders an error page if the code is expired', async () => {
|
||||
@@ -60,12 +48,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': code,
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent.get(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
const res = await superagent.get(`${endpoint}?code=${code}`);
|
||||
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders an error page if the user does not exist', async () => {
|
||||
@@ -74,12 +58,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
|
||||
expiresAt: moment().add({days: 1}),
|
||||
}));
|
||||
|
||||
try {
|
||||
await superagent.get(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
const res = await superagent.get(`${endpoint}?code=${code}`);
|
||||
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders an error page if the user has no local auth', async () => {
|
||||
@@ -93,12 +73,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
|
||||
auth: 'not an object with valid fields',
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent.get(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
const res = await superagent.get(`${endpoint}?code=${code}`);
|
||||
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders an error page if the code doesn\'t match the one saved at user.auth.passwordResetCode', async () => {
|
||||
@@ -112,12 +88,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': 'invalid',
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent.get(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
const res = await superagent.get(`${endpoint}?code=${code}`);
|
||||
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
|
||||
});
|
||||
|
||||
//
|
||||
@@ -134,7 +106,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
|
||||
});
|
||||
|
||||
let res = await superagent.get(`${endpoint}?code=${code}`);
|
||||
expect(res.status).to.equal(200);
|
||||
expect(res.req.path.indexOf('hasError=false') !== -1).to.equal(true);
|
||||
expect(res.req.path.indexOf('code=') !== -1).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -10,49 +10,46 @@ import {
|
||||
import moment from 'moment';
|
||||
import {
|
||||
generateUser,
|
||||
requester,
|
||||
translate as t,
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import superagent from 'superagent';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const API_TEST_SERVER_PORT = nconf.get('PORT');
|
||||
|
||||
describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
let endpoint = `http://localhost:${API_TEST_SERVER_PORT}/static/user/auth/local/reset-password-set-new-one`;
|
||||
describe('POST /user/auth/reset-password-set-new-one', () => {
|
||||
const endpoint = '/user/auth/reset-password-set-new-one';
|
||||
const api = requester();
|
||||
|
||||
// Tests to validate the validatePasswordResetCodeAndFindUser function
|
||||
|
||||
it('renders an error page if the code is missing', async () => {
|
||||
try {
|
||||
await superagent.post(endpoint);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(endpoint)).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('invalidPasswordResetCode'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders an error page if the code is invalid json', async () => {
|
||||
try {
|
||||
await superagent.post(`${endpoint}?code=invalid`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}?code=invalid`)).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('invalidPasswordResetCode'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders an error page if the code cannot be decrypted', async () => {
|
||||
let user = await generateUser();
|
||||
|
||||
try {
|
||||
let code = JSON.stringify({ // not encrypted
|
||||
userId: user._id,
|
||||
expiresAt: new Date(),
|
||||
});
|
||||
await superagent.post(`${endpoint}?code=${code}`);
|
||||
let code = JSON.stringify({ // not encrypted
|
||||
userId: user._id,
|
||||
expiresAt: new Date(),
|
||||
});
|
||||
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('invalidPasswordResetCode'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders an error page if the code is expired', async () => {
|
||||
@@ -66,12 +63,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': code,
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent.post(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('invalidPasswordResetCode'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders an error page if the user does not exist', async () => {
|
||||
@@ -80,12 +78,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
expiresAt: moment().add({days: 1}),
|
||||
}));
|
||||
|
||||
try {
|
||||
await superagent.post(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('invalidPasswordResetCode'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders an error page if the user has no local auth', async () => {
|
||||
@@ -99,12 +98,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
auth: 'not an object with valid fields',
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent.post(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('invalidPasswordResetCode'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders an error page if the code doesn\'t match the one saved at user.auth.passwordResetCode', async () => {
|
||||
@@ -118,12 +118,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': 'invalid',
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent.post(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('invalidPasswordResetCode'),
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
@@ -139,12 +140,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': code,
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent.post(`${endpoint}?code=${code}`);
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 400,
|
||||
error: 'BadRequest',
|
||||
message: t('invalidReqParams'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the error page if the password confirmation is missing', async () => {
|
||||
@@ -158,14 +160,14 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': code,
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent
|
||||
.post(`${endpoint}?code=${code}`)
|
||||
.send({newPassword: 'my new password'});
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
newPassword: 'my new password',
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 400,
|
||||
error: 'BadRequest',
|
||||
message: t('invalidReqParams'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the error page if the password confirmation does not match', async () => {
|
||||
@@ -179,17 +181,15 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': code,
|
||||
});
|
||||
|
||||
try {
|
||||
await superagent
|
||||
.post(`${endpoint}?code=${code}`)
|
||||
.send({
|
||||
newPassword: 'my new password',
|
||||
confirmPassword: 'not matching',
|
||||
});
|
||||
throw new Error('Request should fail.');
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(401);
|
||||
}
|
||||
await expect(api.post(`${endpoint}`, {
|
||||
newPassword: 'my new password',
|
||||
confirmPassword: 'not matching',
|
||||
code,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 400,
|
||||
error: 'BadRequest',
|
||||
message: t('passwordConfirmationMatch'),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the success page and save the user', async () => {
|
||||
@@ -203,14 +203,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': code,
|
||||
});
|
||||
|
||||
let res = await superagent
|
||||
.post(`${endpoint}?code=${code}`)
|
||||
.send({
|
||||
newPassword: 'my new password',
|
||||
confirmPassword: 'my new password',
|
||||
});
|
||||
let res = await api.post(`${endpoint}`, {
|
||||
newPassword: 'my new password',
|
||||
confirmPassword: 'my new password',
|
||||
code,
|
||||
});
|
||||
|
||||
expect(res.status).to.equal(200);
|
||||
expect(res.message).to.equal(t('passwordChangeSuccess'));
|
||||
|
||||
await user.sync();
|
||||
expect(user.auth.local.passwordResetCode).to.equal(undefined);
|
||||
@@ -246,14 +245,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
|
||||
'auth.local.passwordResetCode': code,
|
||||
});
|
||||
|
||||
let res = await superagent
|
||||
.post(`${endpoint}?code=${code}`)
|
||||
.send({
|
||||
newPassword: 'my new password',
|
||||
confirmPassword: 'my new password',
|
||||
});
|
||||
let res = await api.post(`${endpoint}`, {
|
||||
newPassword: 'my new password',
|
||||
confirmPassword: 'my new password',
|
||||
code,
|
||||
});
|
||||
|
||||
expect(res.status).to.equal(200);
|
||||
expect(res.message).to.equal(t('passwordChangeSuccess'));
|
||||
|
||||
await user.sync();
|
||||
expect(user.auth.local.passwordResetCode).to.equal(undefined);
|
||||
|
||||
@@ -59,13 +59,8 @@ describe('POST /user/auth/local/register', () => {
|
||||
let tags = await requests.get('/tags');
|
||||
|
||||
expect(habits).to.have.a.lengthOf(0);
|
||||
|
||||
expect(dailys).to.have.a.lengthOf(0);
|
||||
|
||||
expect(todos).to.have.a.lengthOf(1);
|
||||
expect(todos[0].text).to.eql(t('defaultTodo1Text'));
|
||||
expect(todos[0].notes).to.eql(t('defaultTodoNotes'));
|
||||
|
||||
expect(rewards).to.have.a.lengthOf(0);
|
||||
|
||||
expect(tags).to.have.a.lengthOf(7);
|
||||
@@ -78,7 +73,7 @@ describe('POST /user/auth/local/register', () => {
|
||||
expect(tags[6].name).to.eql(t('defaultTag7'));
|
||||
});
|
||||
|
||||
it('for Web', async () => {
|
||||
xit('for Web', async () => {
|
||||
api = requester(
|
||||
null,
|
||||
{'x-client': 'habitica-web'},
|
||||
@@ -623,10 +618,10 @@ describe('POST /user/auth/local/register', () => {
|
||||
confirmPassword: password,
|
||||
});
|
||||
|
||||
expect(user.tasksOrder.todos).to.not.be.empty;
|
||||
expect(user.tasksOrder.todos).to.be.empty;
|
||||
expect(user.tasksOrder.dailys).to.be.empty;
|
||||
expect(user.tasksOrder.habits).to.not.be.empty;
|
||||
expect(user.tasksOrder.rewards).to.not.be.empty;
|
||||
expect(user.tasksOrder.habits).to.be.empty;
|
||||
expect(user.tasksOrder.rewards).to.be.empty;
|
||||
});
|
||||
|
||||
it('populates user with default tags', async () => {
|
||||
@@ -653,23 +648,8 @@ describe('POST /user/auth/local/register', () => {
|
||||
let habits = await requests.get('/tasks/user?type=habits');
|
||||
let todos = await requests.get('/tasks/user?type=todos');
|
||||
|
||||
function findTag (tagName) {
|
||||
let tag = user.tags.find((userTag) => {
|
||||
return userTag.name === t(tagName);
|
||||
});
|
||||
return tag.id;
|
||||
}
|
||||
|
||||
expect(habits[0].tags).to.have.a.lengthOf(3);
|
||||
expect(habits[0].tags).to.include.members(['defaultTag1', 'defaultTag4', 'defaultTag6'].map(findTag));
|
||||
|
||||
expect(habits[1].tags).to.have.a.lengthOf(1);
|
||||
expect(habits[1].tags).to.include.members(['defaultTag3'].map(findTag));
|
||||
|
||||
expect(habits[2].tags).to.have.a.lengthOf(2);
|
||||
expect(habits[2].tags).to.include.members(['defaultTag2', 'defaultTag3'].map(findTag));
|
||||
|
||||
expect(todos[0].tags).to.have.a.lengthOf(0);
|
||||
expect(habits).to.have.a.lengthOf(0);
|
||||
expect(todos).to.have.a.lengthOf(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
100
test/api/v3/integration/user/buy/POST-user_buy.test.js
Normal file
100
test/api/v3/integration/user/buy/POST-user_buy.test.js
Normal file
@@ -0,0 +1,100 @@
|
||||
/* eslint-disable camelcase */
|
||||
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
describe('POST /user/buy/:key', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await generateUser({
|
||||
'stats.gp': 400,
|
||||
});
|
||||
});
|
||||
|
||||
// More tests in common code unit tests
|
||||
|
||||
it('returns an error if the item is not found', async () => {
|
||||
await expect(user.post('/user/buy/notExisting'))
|
||||
.to.eventually.be.rejected.and.eql({
|
||||
code: 404,
|
||||
error: 'NotFound',
|
||||
message: t('itemNotFound', {key: 'notExisting'}),
|
||||
});
|
||||
});
|
||||
|
||||
it('buys a potion', async () => {
|
||||
await user.update({
|
||||
'stats.gp': 400,
|
||||
'stats.hp': 40,
|
||||
});
|
||||
|
||||
let potion = content.potion;
|
||||
let res = await user.post('/user/buy/potion');
|
||||
await user.sync();
|
||||
|
||||
expect(user.stats.hp).to.equal(50);
|
||||
expect(res.data).to.eql(user.stats);
|
||||
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
||||
});
|
||||
|
||||
it('returns an error if user tries to buy a potion with full health', async () => {
|
||||
await user.update({
|
||||
'stats.gp': 40,
|
||||
'stats.hp': 50,
|
||||
});
|
||||
|
||||
await expect(user.post('/user/buy/potion'))
|
||||
.to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('messageHealthAlreadyMax'),
|
||||
});
|
||||
});
|
||||
|
||||
it('buys a piece of gear', async () => {
|
||||
let key = 'armor_warrior_1';
|
||||
|
||||
await user.post(`/user/buy/${key}`);
|
||||
await user.sync();
|
||||
|
||||
expect(user.items.gear.owned.armor_warrior_1).to.eql(true);
|
||||
});
|
||||
|
||||
it('buys a special spell', async () => {
|
||||
let key = 'spookySparkles';
|
||||
let item = content.special[key];
|
||||
|
||||
await user.update({'stats.gp': 250});
|
||||
let res = await user.post(`/user/buy/${key}`);
|
||||
await user.sync();
|
||||
|
||||
expect(res.data).to.eql({
|
||||
items: JSON.parse(JSON.stringify(user.items)), // otherwise dates can't be compared
|
||||
stats: user.stats,
|
||||
});
|
||||
expect(res.message).to.equal(t('messageBought', {
|
||||
itemText: item.text(),
|
||||
}));
|
||||
});
|
||||
|
||||
it('allows for bulk purchases', async () => {
|
||||
await user.update({
|
||||
'stats.gp': 400,
|
||||
'stats.hp': 20,
|
||||
});
|
||||
|
||||
let potion = content.potion;
|
||||
let res = await user.post('/user/buy/potion', {quantity: 2});
|
||||
await user.sync();
|
||||
|
||||
expect(user.stats.hp).to.equal(50);
|
||||
expect(res.data).to.eql(user.stats);
|
||||
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
|
||||
describe('POST /user/buy-armoire', () => {
|
||||
let user;
|
||||
@@ -3,7 +3,7 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
|
||||
describe('POST /user/buy-gear/:key', () => {
|
||||
let user;
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
|
||||
describe('POST /user/buy-mystery-set/:key', () => {
|
||||
let user;
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import {
|
||||
getManifestFiles,
|
||||
} from '../../../../../website/server/libs/buildManifest';
|
||||
|
||||
describe('Build Manifest', () => {
|
||||
describe('getManifestFiles', () => {
|
||||
it('returns an html string', () => {
|
||||
let htmlCode = getManifestFiles('app');
|
||||
|
||||
expect(htmlCode.startsWith('<script') || htmlCode.startsWith('<link')).to.be.true;
|
||||
});
|
||||
|
||||
it('can return only js files', () => {
|
||||
let htmlCode = getManifestFiles('app', 'js');
|
||||
|
||||
expect(htmlCode.indexOf('<link') === -1).to.be.true;
|
||||
});
|
||||
|
||||
it('can return only css files', () => {
|
||||
let htmlCode = getManifestFiles('app', 'css');
|
||||
|
||||
expect(htmlCode.indexOf('<script') === -1).to.be.true;
|
||||
});
|
||||
|
||||
it('throws an error in case the page does not exist', () => {
|
||||
expect(() => {
|
||||
getManifestFiles('strange name here');
|
||||
}).to.throw(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -142,12 +142,12 @@ describe('emails', () => {
|
||||
describe('getGroupUrl', () => {
|
||||
it('returns correct url if group is the tavern', () => {
|
||||
let getGroupUrl = require(pathToEmailLib).getGroupUrl;
|
||||
expect(getGroupUrl({_id: TAVERN_ID, type: 'guild'})).to.eql('/#/options/groups/tavern');
|
||||
expect(getGroupUrl({_id: TAVERN_ID, type: 'guild'})).to.eql('/groups/tavern');
|
||||
});
|
||||
|
||||
it('returns correct url if group is a guild', () => {
|
||||
let getGroupUrl = require(pathToEmailLib).getGroupUrl;
|
||||
expect(getGroupUrl({_id: 'random _id', type: 'guild'})).to.eql('/#/options/groups/guilds/random _id');
|
||||
expect(getGroupUrl({_id: 'random _id', type: 'guild'})).to.eql('/groups/guild/random _id');
|
||||
});
|
||||
|
||||
it('returns correct url if group is a party', () => {
|
||||
|
||||
@@ -71,7 +71,7 @@ describe('slack', () => {
|
||||
expect(IncomingWebhook.prototype.send).to.be.calledWithMatch({
|
||||
attachments: [sandbox.match({
|
||||
title: 'Flag in Some group',
|
||||
title_link: sandbox.match(/.*\/#\/options\/groups\/guilds\/group-id/),
|
||||
title_link: sandbox.match(/.*\/groups\/guild\/group-id/),
|
||||
})],
|
||||
});
|
||||
});
|
||||
@@ -86,7 +86,7 @@ describe('slack', () => {
|
||||
expect(IncomingWebhook.prototype.send).to.be.calledWithMatch({
|
||||
attachments: [sandbox.match({
|
||||
title: 'Flag in Tavern',
|
||||
title_link: sandbox.match(/.*\/#\/options\/groups\/tavern/),
|
||||
title_link: sandbox.match(/.*\/groups\/tavern/),
|
||||
})],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
generateNext,
|
||||
} from '../../../../helpers/api-unit.helper';
|
||||
import responseMiddleware from '../../../../../website/server/middlewares/response';
|
||||
import packageInfo from '../../../../../package.json';
|
||||
|
||||
describe('response middleware', () => {
|
||||
let res, req, next;
|
||||
@@ -33,6 +34,8 @@ describe('response middleware', () => {
|
||||
success: true,
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,6 +52,8 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
message: 'hello',
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,12 +69,13 @@ describe('response middleware', () => {
|
||||
success: false,
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns userV if a user is authenticated req.query.userV is passed', () => {
|
||||
it('returns userV if a user is authenticated', () => {
|
||||
responseMiddleware(req, res, next);
|
||||
req.query.userV = 3;
|
||||
res.respond(200, {field: 1});
|
||||
|
||||
expect(res.json).to.be.calledOnce;
|
||||
@@ -79,6 +85,7 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: 0,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -101,6 +108,8 @@ describe('response middleware', () => {
|
||||
data: {},
|
||||
},
|
||||
],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -282,7 +282,7 @@ describe('Group Model', () => {
|
||||
expect(finishQuest).to.be.calledWith(quest);
|
||||
});
|
||||
|
||||
context('with Rage', () => {
|
||||
context('with healing Rage', () => {
|
||||
beforeEach(async () => {
|
||||
party.quest.active = false;
|
||||
party.quest.key = 'trex_undead';
|
||||
@@ -327,6 +327,46 @@ describe('Group Model', () => {
|
||||
expect(party.quest.progress.hp).to.eql(500);
|
||||
});
|
||||
});
|
||||
|
||||
context('with Mana drain Rage', () => {
|
||||
beforeEach(async () => {
|
||||
party.quest.active = false;
|
||||
party.quest.key = 'lostMasterclasser4';
|
||||
|
||||
await party.startQuest(questLeader);
|
||||
await party.save();
|
||||
});
|
||||
|
||||
it('applies down progress to boss rage', async () => {
|
||||
progress.down = -2;
|
||||
|
||||
await Group.processQuestProgress(participatingMember, progress);
|
||||
|
||||
party = await Group.findOne({_id: party._id});
|
||||
|
||||
expect(party.quest.progress.rage).to.eql(8);
|
||||
|
||||
let drainedUser = await User.findById(participatingMember._id);
|
||||
expect(drainedUser.stats.mp).to.eql(10);
|
||||
});
|
||||
|
||||
it('activates rage when progress.down triggers rage bar', async () => {
|
||||
let quest = questScrolls[party.quest.key];
|
||||
|
||||
progress.down = -999;
|
||||
|
||||
await party.save();
|
||||
await Group.processQuestProgress(participatingMember, progress);
|
||||
|
||||
party = await Group.findOne({_id: party._id});
|
||||
|
||||
expect(Group.prototype.sendChat).to.be.calledWith(quest.boss.rage.effect('en'));
|
||||
expect(party.quest.progress.rage).to.eql(0);
|
||||
|
||||
let drainedUser = await User.findById(participatingMember._id);
|
||||
expect(drainedUser.stats.mp).to.eql(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Collection Quests', () => {
|
||||
@@ -1342,6 +1382,42 @@ describe('Group Model', () => {
|
||||
expect(updatedParticipatingMember.achievements.quests[quest.key]).to.eql(1);
|
||||
});
|
||||
|
||||
it('gives out super awesome Masterclasser achievement to the deserving', async () => {
|
||||
quest = questScrolls.lostMasterclasser4;
|
||||
party.quest.key = quest.key;
|
||||
|
||||
questLeader.achievements.quests = {
|
||||
mayhemMistiflying1: 1,
|
||||
mayhemMistiflying2: 1,
|
||||
mayhemMistiflying3: 1,
|
||||
stoikalmCalamity1: 1,
|
||||
stoikalmCalamity2: 1,
|
||||
stoikalmCalamity3: 1,
|
||||
taskwoodsTerror1: 1,
|
||||
taskwoodsTerror2: 1,
|
||||
taskwoodsTerror3: 1,
|
||||
dilatoryDistress1: 1,
|
||||
dilatoryDistress2: 1,
|
||||
dilatoryDistress3: 1,
|
||||
lostMasterclasser1: 1,
|
||||
lostMasterclasser2: 1,
|
||||
lostMasterclasser3: 1,
|
||||
};
|
||||
await questLeader.save();
|
||||
await party.finishQuest(quest);
|
||||
|
||||
let [
|
||||
updatedLeader,
|
||||
updatedParticipatingMember,
|
||||
] = await Promise.all([
|
||||
User.findById(questLeader._id),
|
||||
User.findById(participatingMember._id),
|
||||
]);
|
||||
|
||||
expect(updatedLeader.achievements.lostMasterclasser).to.eql(true);
|
||||
expect(updatedParticipatingMember.achievements.lostMasterclasser).to.not.eql(true);
|
||||
});
|
||||
|
||||
it('gives xp and gold', async () => {
|
||||
await party.finishQuest(quest);
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"globals": {
|
||||
"browser": true,
|
||||
"by": true,
|
||||
"element": true
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import fs from 'fs';
|
||||
import { resetHabiticaDB } from '../../helpers/mongo';
|
||||
|
||||
before(async () => {
|
||||
await resetHabiticaDB();
|
||||
});
|
||||
|
||||
// based on https://github.com/angular/protractor/issues/114#issuecomment-29046939
|
||||
afterEach(async function () {
|
||||
let lastTest = this.currentTest;
|
||||
|
||||
if (lastTest.state === 'failed') {
|
||||
let filename = `exception_${lastTest.title}.png`;
|
||||
let png = await browser.takeScreenshot();
|
||||
let buffer = new Buffer(png, 'base64');
|
||||
let stream = fs.createWriteStream(filename);
|
||||
|
||||
stream.write(buffer);
|
||||
stream.end();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
let chai = require('chai');
|
||||
let chaiAsPromised = require('chai-as-promised');
|
||||
|
||||
require('babel-register');
|
||||
require('babel-polyfill');
|
||||
|
||||
exports.config = {
|
||||
specs: ['./helper.js', './**/*.test.js'],
|
||||
baseUrl: 'http://localhost:3003/',
|
||||
capabilities: {
|
||||
browserName: 'firefox',
|
||||
},
|
||||
directConnect: true,
|
||||
seleniumAddress: 'http://localhost:4444/wd/hub',
|
||||
framework: 'mocha',
|
||||
mochaOpts: {
|
||||
reporter: 'spec',
|
||||
slow: 6000,
|
||||
timeout: 10000,
|
||||
compilers: 'js:babel-register',
|
||||
},
|
||||
onPrepare: () => {
|
||||
browser.ignoreSynchronization = true;
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
global.expect = chai.expect;
|
||||
},
|
||||
};
|
||||
@@ -1,64 +0,0 @@
|
||||
import { v4 as generateUniqueId } from 'uuid';
|
||||
|
||||
describe('Static Front Page', () => {
|
||||
beforeEach(() => {
|
||||
browser.get('/');
|
||||
browser.sleep(1000);
|
||||
});
|
||||
|
||||
it('shows the front page', async () => {
|
||||
let button = element(by.id('play-btn'));
|
||||
|
||||
await expect(button.getText()).to.eventually.eql('Join for free');
|
||||
});
|
||||
|
||||
it('does not login when using wrong credentials', async () => {
|
||||
let button = element(by.id('play-btn'));
|
||||
let randomName = generateUniqueId();
|
||||
|
||||
button.click();
|
||||
browser.sleep(1000);
|
||||
|
||||
element(by.model('loginUsername')).sendKeys(randomName);
|
||||
element(by.model('loginPassword')).sendKeys('pass');
|
||||
|
||||
let login = element(by.css('#loginForm input[value="Login"]'));
|
||||
|
||||
login.click();
|
||||
browser.sleep(1000);
|
||||
|
||||
let alertDialog = browser.switchTo().alert();
|
||||
|
||||
await expect(alertDialog.getText()).to.eventually.match(/username or password is incorrect./);
|
||||
|
||||
alertDialog.accept();
|
||||
});
|
||||
|
||||
it('registers a new user', async function () {
|
||||
this.timeout(30000); // TODO: Speed up registration action. Takes way too long and times out unless you extend the timeout
|
||||
|
||||
let button = element(by.id('play-btn'));
|
||||
let randomName = generateUniqueId();
|
||||
|
||||
button.click();
|
||||
browser.sleep(1000);
|
||||
|
||||
let registerTab = element(by.linkText('Register'));
|
||||
registerTab.click();
|
||||
element(by.model('registerVals.username')).sendKeys(randomName);
|
||||
element(by.model('registerVals.email')).sendKeys(`${randomName}@example.com`);
|
||||
element(by.model('registerVals.password')).sendKeys('pass');
|
||||
element(by.model('registerVals.confirmPassword')).sendKeys('pass');
|
||||
|
||||
let register = element(by.css('#registrationForm input[type="submit"]'));
|
||||
|
||||
register.click();
|
||||
browser.sleep(3000);
|
||||
|
||||
let url = await browser.getCurrentUrl();
|
||||
|
||||
expect(url).to.not.match(/static\/front/);
|
||||
});
|
||||
|
||||
it('logs in an existing user');
|
||||
});
|
||||
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('AppJS', function() {
|
||||
describe('Automatic page refresh', function(){
|
||||
var clock;
|
||||
beforeEach(function () {
|
||||
clock = sandbox.useFakeTimers();
|
||||
sandbox.stub(window, "refresher", function(){return true});
|
||||
});
|
||||
|
||||
it('should not call refresher if idle time is less than 6 hours', function() {
|
||||
window.awaitIdle();
|
||||
clock.tick(21599999);
|
||||
expect(window.refresher).to.not.be.called;
|
||||
});
|
||||
|
||||
it('should not call refresher if awaitIdle is called within 6 hours', function() {
|
||||
window.awaitIdle();
|
||||
clock.tick(21500000);
|
||||
window.awaitIdle();
|
||||
clock.tick(21500000);
|
||||
expect(window.refresher).to.not.be.called;
|
||||
});
|
||||
|
||||
it('should call refresher if idle time is 6 hours or greater', function() {
|
||||
window.awaitIdle();
|
||||
clock.tick(21900000);
|
||||
expect(window.refresher).to.be.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,125 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Auth Controller', function() {
|
||||
var scope, ctrl, user, $httpBackend, $window, $modal, alert, Auth;
|
||||
|
||||
beforeEach(function(){
|
||||
module(function($provide) {
|
||||
Auth = {
|
||||
runAuth: sandbox.spy(),
|
||||
};
|
||||
$provide.value('Analytics', analyticsMock);
|
||||
$provide.value('Chat', { seenMessage: function() {} });
|
||||
$provide.value('Auth', Auth);
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, $rootScope, $controller, _$modal_) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
scope = $rootScope.$new();
|
||||
scope.loginUsername = 'user';
|
||||
scope.loginPassword = 'pass';
|
||||
$window = { location: { href: ""}, alert: sandbox.spy() };
|
||||
$modal = _$modal_;
|
||||
user = { user: {}, authenticate: sandbox.spy() };
|
||||
alert = { authErrorAlert: sandbox.spy() };
|
||||
|
||||
ctrl = $controller('AuthCtrl', {$scope: scope, $window: $window, User: user, Alert: alert});
|
||||
})
|
||||
});
|
||||
|
||||
describe('logging in', function() {
|
||||
it('should log in users with correct uname / pass', function() {
|
||||
$httpBackend.expectPOST('/api/v3/user/auth/local/login').respond({data: {id: 'abc', apiToken: 'abc'}});
|
||||
scope.auth();
|
||||
$httpBackend.flush();
|
||||
expect(Auth.runAuth).to.be.calledOnce;
|
||||
expect(alert.authErrorAlert).to.not.be.called;
|
||||
});
|
||||
|
||||
it('should not log in users with incorrect uname / pass', function() {
|
||||
$httpBackend.expectPOST('/api/v3/user/auth/local/login').respond(404, '');
|
||||
scope.auth();
|
||||
$httpBackend.flush();
|
||||
expect(Auth.runAuth).to.not.be.called;
|
||||
expect(alert.authErrorAlert).to.be.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clearLocalStorage', function () {
|
||||
var timer;
|
||||
|
||||
beforeEach(function () {
|
||||
timer = sandbox.useFakeTimers();
|
||||
sandbox.stub($modal, 'open');
|
||||
});
|
||||
|
||||
it('opens modal with message about clearing local storage and logging out', function () {
|
||||
scope.clearLocalStorage();
|
||||
|
||||
expect($modal.open).to.be.calledOnce;
|
||||
expect($modal.open).to.be.calledWith({
|
||||
templateUrl: 'modals/message-modal.html',
|
||||
scope: scope
|
||||
});
|
||||
|
||||
expect(scope.messageModal.title).to.eql(window.env.t('localStorageClearing'));
|
||||
expect(scope.messageModal.body).to.eql(window.env.t('localStorageClearingExplanation'));
|
||||
});
|
||||
|
||||
it('does not call $scope.logout before 3 seconds', function () {
|
||||
sandbox.stub(scope, 'logout');
|
||||
|
||||
scope.clearLocalStorage();
|
||||
|
||||
timer.tick(2999);
|
||||
|
||||
expect(scope.logout).to.not.be.called;
|
||||
});
|
||||
|
||||
it('calls $scope.logout after 3 seconds', function () {
|
||||
sandbox.stub(scope, 'logout');
|
||||
|
||||
scope.clearLocalStorage();
|
||||
|
||||
timer.tick(3000);
|
||||
|
||||
expect(scope.logout).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('does not clear local storage before 3 seconds', function () {
|
||||
sandbox.stub(localStorage, 'clear');
|
||||
|
||||
scope.clearLocalStorage();
|
||||
|
||||
timer.tick(2999);
|
||||
|
||||
expect(localStorage.clear).to.not.be.called;
|
||||
});
|
||||
|
||||
it('clears local storage after 3 seconds', function () {
|
||||
sandbox.stub(localStorage, 'clear');
|
||||
|
||||
scope.clearLocalStorage();
|
||||
|
||||
timer.tick(3000);
|
||||
|
||||
expect(localStorage.clear).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('does not redirect to /logout route before 3 seconds', function () {
|
||||
scope.clearLocalStorage();
|
||||
|
||||
timer.tick(2999);
|
||||
|
||||
expect($window.location.href).to.eql('');
|
||||
});
|
||||
|
||||
it('redirects to /logout after 3 seconds', function () {
|
||||
scope.clearLocalStorage();
|
||||
|
||||
timer.tick(3000);
|
||||
|
||||
expect($window.location.href).to.eql('/logout');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,120 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe("Autocomplete controller", function() {
|
||||
var scope, ctrl, user, $rootScope, $controller;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(function($rootScope, _$controller_){
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
|
||||
scope = $rootScope.$new();
|
||||
scope.group = {}
|
||||
scope.group.chat = [];
|
||||
|
||||
$controller = _$controller_;
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
ctrl = $controller('AutocompleteCtrl', {$scope: scope});
|
||||
});
|
||||
});
|
||||
|
||||
describe("clearUserList", function() {
|
||||
it('calling the function clears the list of usernames and responses', function() {
|
||||
scope.response.push("blah");
|
||||
scope.usernames.push("blub");
|
||||
|
||||
scope.clearUserlist();
|
||||
expect(scope.response).to.be.empty;
|
||||
expect(scope.usernames).to.be.empty;
|
||||
});
|
||||
|
||||
it('the function is called upon initialization of the controller', function() {
|
||||
scope.response.push("blah");
|
||||
scope.response.push("blub");
|
||||
ctrl = $controller('AutocompleteCtrl', {$scope: scope});
|
||||
|
||||
expect(scope.response).to.be.empty;
|
||||
expect(scope.usernames).to.be.empty;
|
||||
});
|
||||
})
|
||||
|
||||
describe("filterUser", function() {
|
||||
it('filters with undefined query (not loaded yet) and returns false (so it will not be rendered)', function() {
|
||||
expect(scope.filterUser({user: "boo"})).to.be.eq(false);
|
||||
});
|
||||
|
||||
it('filters with null query (no typing yet) and returns false (so it will not be rendered)', function() {
|
||||
scope.query = null
|
||||
expect(scope.filterUser({user: "boo"})).to.be.eq(false);
|
||||
});
|
||||
|
||||
it('filters with empty prefix and returns true', function() {
|
||||
scope.query = {text: ""};
|
||||
expect(scope.filterUser({user: "prefix"})).to.be.eq(true);
|
||||
});
|
||||
|
||||
it('filters with prefix element and returns true', function() {
|
||||
scope.query = {text: "pre"}
|
||||
expect(scope.filterUser({user: "prefix"})).to.be.eq(true);
|
||||
});
|
||||
|
||||
it('filters with prefix element of a different case and returns true', function() {
|
||||
scope.query = {text: "pre"}
|
||||
expect(scope.filterUser({user: "Prefix"})).to.be.eq(true);
|
||||
});
|
||||
|
||||
it('filters with nonprefix element and returns false', function() {
|
||||
scope.query = {text: "noprefix"}
|
||||
expect(scope.filterUser({user: "prefix"})).to.be.eq(false);
|
||||
});
|
||||
|
||||
it('filters out system messages (messages without username)', function() {
|
||||
scope.query = {text: "myquery"}
|
||||
expect(scope.filterUser({uuid: "system"})).to.be.eq(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("performCompletion", function() {
|
||||
it('triggers autoComplete', function() {
|
||||
scope.autoComplete = sandbox.spy();
|
||||
|
||||
var msg = {user: "boo"}; // scope.autoComplete only cares about user
|
||||
scope.query = {text: "b"};
|
||||
scope.performCompletion(msg);
|
||||
|
||||
expect(scope.query).to.be.eq(null);
|
||||
expect(scope.autoComplete.callCount).to.be.eq(1);
|
||||
expect(scope.autoComplete).to.have.been.calledWith(msg);
|
||||
});
|
||||
});
|
||||
|
||||
describe("addNewUser", function() {
|
||||
it('a new message from a new user will modify the usernames', function() {
|
||||
expect(scope.response).to.be.empty;
|
||||
expect(scope.usernames).to.be.empty;
|
||||
|
||||
var msg = {user: "boo"};
|
||||
scope.addNewUser(msg);
|
||||
expect(scope.response[0]).to.be.eq(msg);
|
||||
expect(scope.usernames[0]).to.be.eq("boo");
|
||||
});
|
||||
});
|
||||
|
||||
describe("chatChanged", function() {
|
||||
it('if a new chat arrives, the new user name is extracted', function() {
|
||||
var chatChanged = sandbox.spy(scope, 'chatChanged');
|
||||
scope.$watch('group.chat',scope.chatChanged); // reinstantiate watch so spy works
|
||||
|
||||
scope.$digest(); // trigger watch
|
||||
scope.group.chat.push({msg: "new chat", user: "boo"});
|
||||
expect(chatChanged.callCount).to.be.eq(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,774 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Challenges Controller', function() {
|
||||
var rootScope, scope, user, User, ctrl, groups, members, notification, state, challenges, tasks, tavernId;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
user = specHelper.newUser();
|
||||
User = {
|
||||
getBalanceInGems: sandbox.stub(),
|
||||
sync: sandbox.stub(),
|
||||
user: user
|
||||
}
|
||||
$provide.value('User', User);
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, _$state_, _Groups_, _Members_, _Notification_, _Challenges_, _Tasks_, _TAVERN_ID_){
|
||||
scope = $rootScope.$new();
|
||||
rootScope = $rootScope;
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: User});
|
||||
|
||||
ctrl = $controller('ChallengesCtrl', {$scope: scope, User: User});
|
||||
|
||||
challenges = _Challenges_;
|
||||
tasks = _Tasks_;
|
||||
groups = _Groups_;
|
||||
members = _Members_;
|
||||
notification = _Notification_;
|
||||
state = _$state_;
|
||||
tavernId = _TAVERN_ID_;
|
||||
});
|
||||
});
|
||||
|
||||
context('filtering', function() {
|
||||
describe('filterChallenges', function() {
|
||||
var ownMem, ownNotMem, notOwnMem, notOwnNotMem;
|
||||
|
||||
beforeEach(function() {
|
||||
ownMem = specHelper.newChallenge({
|
||||
description: 'You are the owner and member',
|
||||
leader: user._id,
|
||||
members: [user],
|
||||
_isMember: true,
|
||||
_id: 'ownMem-id',
|
||||
});
|
||||
|
||||
ownNotMem = specHelper.newChallenge({
|
||||
description: 'You are the owner, but not a member',
|
||||
leader: user._id,
|
||||
members: [],
|
||||
_isMember: false,
|
||||
_id: 'ownNotMem-id',
|
||||
});
|
||||
|
||||
notOwnMem = specHelper.newChallenge({
|
||||
description: 'Not owner but a member',
|
||||
leader: {_id:"test"},
|
||||
members: [user],
|
||||
_isMember: true,
|
||||
_id: 'notOwnMem-id',
|
||||
});
|
||||
|
||||
notOwnNotMem = specHelper.newChallenge({
|
||||
description: 'Not owner or member',
|
||||
leader: {_id:"test"},
|
||||
members: [],
|
||||
_isMember: false,
|
||||
_id: 'notOwnNotMem-id',
|
||||
});
|
||||
|
||||
user.challenges = [ownMem._id, notOwnMem._id];
|
||||
|
||||
scope.search = {
|
||||
group: _.transform(groups, function(m,g){m[g._id]=true;})
|
||||
};
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: either and owner: either', function() {
|
||||
scope.search._isMember = 'either';
|
||||
scope.search._isOwner = 'either';
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: either and owner: true', function() {
|
||||
scope.search._isMember = 'either';
|
||||
scope.search._isOwner = true;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: either and owner: false', function() {
|
||||
scope.search._isMember = 'either';
|
||||
scope.search._isOwner = false;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: true and owner: either', function() {
|
||||
scope.search._isMember = true;
|
||||
scope.search._isOwner = 'either';
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: true and owner: true', function() {
|
||||
scope.search._isMember = true;
|
||||
scope.search._isOwner = true;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: true and owner: false', function() {
|
||||
scope.search._isMember = true;
|
||||
scope.search._isOwner = false;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: false and owner: either', function() {
|
||||
scope.search._isMember = false;
|
||||
scope.search._isOwner = 'either';
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: false and owner: true', function() {
|
||||
scope.search._isMember = false;
|
||||
scope.search._isOwner = true;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: false and owner: false', function() {
|
||||
scope.search._isMember = false;
|
||||
scope.search._isOwner = false;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
|
||||
it('filters challenges to a single group when group id filter is set', inject(function($controller) {
|
||||
scope.search = { };
|
||||
scope.groupsFilter = {
|
||||
0: specHelper.newGroup({_id: 'group-one'}),
|
||||
1: specHelper.newGroup({_id: 'group-two'}),
|
||||
2: specHelper.newGroup({_id: 'group-three'})
|
||||
};
|
||||
|
||||
scope.groupIdFilter = 'group-one';
|
||||
scope.filterInitialChallenges();
|
||||
expect(scope.search.group).to.eql({'group-one': true});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('selectAll', function() {
|
||||
it('sets all groups in seach.group to true', function() {
|
||||
scope.search = { };
|
||||
scope.groupsFilter = {
|
||||
0: specHelper.newGroup({_id: 'group-one'}),
|
||||
1: specHelper.newGroup({_id: 'group-two'}),
|
||||
2: specHelper.newGroup({_id: 'group-three'})
|
||||
};
|
||||
scope.selectAll();
|
||||
|
||||
expect(scope.search.group).to.eql({
|
||||
'group-one': true,
|
||||
'group-two': true,
|
||||
'group-three': true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectNone', function() {
|
||||
it('sets all groups in seach.group to false', function() {
|
||||
scope.search = { };
|
||||
scope.groupsFilter = {
|
||||
0: specHelper.newGroup({_id: 'group-one'}),
|
||||
1: specHelper.newGroup({_id: 'group-two'}),
|
||||
2: specHelper.newGroup({_id: 'group-three'})
|
||||
};
|
||||
scope.selectNone();
|
||||
|
||||
expect(scope.search.group).to.eql({
|
||||
'group-one': false,
|
||||
'group-two': false,
|
||||
'group-three': false
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('task manipulation', function() {
|
||||
|
||||
describe('shouldShow', function() {
|
||||
it('overrides task controller function by always returning true', function() {
|
||||
expect(scope.shouldShow()).to.eq(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addTask', function() {
|
||||
var challenge;
|
||||
|
||||
beforeEach(function () {
|
||||
challenge = specHelper.newChallenge({
|
||||
description: 'You are the owner and member',
|
||||
leader: user._id,
|
||||
members: [user],
|
||||
_isMember: true
|
||||
});
|
||||
});
|
||||
|
||||
it('adds default task to array', function() {
|
||||
var taskArray = [];
|
||||
var listDef = {
|
||||
newTask: 'new todo text',
|
||||
type: 'todo'
|
||||
}
|
||||
|
||||
scope.addTask(listDef, challenge);
|
||||
|
||||
expect(challenge['todos'].length).to.eql(1);
|
||||
expect(challenge['todos'][0].text).to.eql('new todo text');
|
||||
expect(challenge['todos'][0].type).to.eql('todo');
|
||||
});
|
||||
|
||||
it('adds the task to the front of the array', function() {
|
||||
var previousTask = specHelper.newTodo({ text: 'previous task' });
|
||||
var taskArray = [];
|
||||
challenge['todos'] = [previousTask];
|
||||
var listDef = {
|
||||
newTask: 'new todo',
|
||||
type: 'todo'
|
||||
}
|
||||
|
||||
scope.addTask(listDef, challenge);
|
||||
|
||||
expect(challenge['todos'].length).to.eql(2);
|
||||
expect(challenge['todos'][0].text).to.eql('new todo');
|
||||
expect(challenge['todos'][1].text).to.eql('previous task');
|
||||
});
|
||||
|
||||
it('removes text from new task input box', function() {
|
||||
var taskArray = [];
|
||||
var listDef = {
|
||||
newTask: 'new todo text',
|
||||
type: 'todo'
|
||||
}
|
||||
|
||||
scope.addTask(listDef, challenge);
|
||||
|
||||
expect(listDef.newTask).to.not.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe('editTask', function() {
|
||||
it('is Tasks.editTask', function() {
|
||||
inject(function(Tasks) {
|
||||
// @TODO: Currently we override the task function in the challenge ctrl, but we should abstract it again
|
||||
// expect(scope.editTask).to.eql(Tasks.editTask);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeTask', function() {
|
||||
var task, challenge;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(window, 'confirm');
|
||||
task = specHelper.newTodo();
|
||||
challenge = specHelper.newChallenge({
|
||||
description: 'You are the owner and member',
|
||||
leader: user._id,
|
||||
members: [user],
|
||||
_isMember: true
|
||||
});
|
||||
challenge['todos'] = [task];
|
||||
});
|
||||
|
||||
it('asks user to confirm deletion', function() {
|
||||
scope.removeTask(task, challenge);
|
||||
expect(window.confirm).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('does not remove task from list if not confirmed', function() {
|
||||
window.confirm.returns(false);
|
||||
scope.removeTask(task, challenge);
|
||||
|
||||
expect(challenge['todos']).to.include(task);
|
||||
});
|
||||
|
||||
it('removes task from list', function() {
|
||||
window.confirm.returns(true);
|
||||
scope.removeTask(task, challenge);
|
||||
|
||||
expect(challenge['todos']).to.not.include(task);
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveTask', function() {
|
||||
it('sets task._editing to false', function() {
|
||||
var task = specHelper.newTask({ _editing: true });
|
||||
|
||||
scope.saveTask(task);
|
||||
|
||||
expect(task._editing).to.be.eql(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('challenge owner interactions', function() {
|
||||
describe("save challenge", function() {
|
||||
var alert, createChallengeSpy, challengeResponse, taskChallengeCreateSpy;
|
||||
|
||||
beforeEach(function(){
|
||||
alert = sandbox.stub(window, "alert");
|
||||
createChallengeSpy = sinon.stub(challenges, 'createChallenge');
|
||||
challengeResponse = {data: {data: {_id: 'new-challenge'}}};
|
||||
createChallengeSpy.returns(Promise.resolve(challengeResponse));
|
||||
|
||||
taskChallengeCreateSpy = sinon.stub(tasks, 'createChallengeTasks');
|
||||
var taskResponse = {data: {data: []}};
|
||||
taskChallengeCreateSpy.returns(Promise.resolve(taskResponse));
|
||||
});
|
||||
|
||||
it("opens an alert box if challenge.group is not specified", function() {
|
||||
var challenge = specHelper.newChallenge({
|
||||
name: 'Challenge without a group',
|
||||
shortName: 'chal without group',
|
||||
group: null
|
||||
});
|
||||
|
||||
scope.save(challenge);
|
||||
|
||||
expect(alert).to.be.calledOnce;
|
||||
expect(alert).to.be.calledWith(window.env.t('selectGroup'));
|
||||
});
|
||||
|
||||
it("opens an alert box if isNew and user does not have enough gems", function() {
|
||||
var challenge = specHelper.newChallenge({
|
||||
name: 'Challenge without enough gems',
|
||||
shortName: 'chal without gem',
|
||||
prize: 5
|
||||
});
|
||||
|
||||
scope.maxPrize = 4;
|
||||
scope.save(challenge);
|
||||
|
||||
expect(alert).to.be.calledOnce;
|
||||
expect(alert).to.be.calledWith(window.env.t('challengeNotEnoughGems'));
|
||||
});
|
||||
|
||||
it("saves the challenge if user does not have enough gems, but the challenge is not new", function() {
|
||||
var updateChallengeSpy = sinon.spy(challenges, 'updateChallenge');
|
||||
|
||||
var challenge = specHelper.newChallenge({
|
||||
_id: 'challenge-has-id-so-its-not-new',
|
||||
name: 'Challenge without enough gems',
|
||||
shortName: 'chal without gem',
|
||||
prize: 5,
|
||||
});
|
||||
|
||||
scope.maxPrize = 0;
|
||||
scope.save(challenge);
|
||||
|
||||
expect(updateChallengeSpy).to.be.calledOnce;
|
||||
expect(alert).to.not.be.called;
|
||||
});
|
||||
|
||||
it("saves the challenge if user has enough gems and challenge is new", function() {
|
||||
var challenge = specHelper.newChallenge({
|
||||
name: 'Challenge without enough gems',
|
||||
shortName: 'chal without gem',
|
||||
prize: 5,
|
||||
});
|
||||
|
||||
scope.maxPrize = 5;
|
||||
scope.save(challenge);
|
||||
|
||||
expect(createChallengeSpy).to.be.calledOnce;
|
||||
expect(alert).to.not.be.called;
|
||||
});
|
||||
|
||||
it('saves challenge and then proceeds to detail page', function(done) {
|
||||
sandbox.stub(state, 'transitionTo');
|
||||
|
||||
var challenge = specHelper.newChallenge({
|
||||
name: 'Challenge',
|
||||
shortName: 'chal',
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(createChallengeSpy).to.be.calledOnce;
|
||||
expect(state.transitionTo).to.be.calledWith(
|
||||
'options.social.challenges.detail',
|
||||
{ cid: 'new-challenge' },
|
||||
{
|
||||
reload: true, inherit: false, notify: true
|
||||
}
|
||||
);
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
scope.save(challenge);
|
||||
});
|
||||
|
||||
it('saves new challenge and syncs User', function(done) {
|
||||
var challenge = specHelper.newChallenge();
|
||||
challenge.shortName = 'chal';
|
||||
|
||||
setTimeout(function() {
|
||||
expect(User.sync).to.be.calledOnce;
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
scope.save(challenge);
|
||||
});
|
||||
|
||||
it('saves new challenge and syncs User', function(done) {
|
||||
sinon.stub(notification, 'text');
|
||||
|
||||
var challenge = specHelper.newChallenge();
|
||||
challenge.shortName = 'chal';
|
||||
|
||||
setTimeout(function() {
|
||||
expect(notification.text).to.be.calledOnce;
|
||||
expect(notification.text).to.be.calledWith(window.env.t('challengeCreated'));
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
scope.save(challenge);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create', function() {
|
||||
it('creates new challenge with group that user has selected in filter', function() {
|
||||
var party = specHelper.newGroup({
|
||||
type: 'party',
|
||||
_id: 'user-party'
|
||||
});
|
||||
scope.groupsFilter = [party];
|
||||
scope.search = {
|
||||
group: {
|
||||
'user-party': true
|
||||
}
|
||||
};
|
||||
|
||||
scope.create();
|
||||
|
||||
expect(scope.newChallenge.group).to.eql('user-party');
|
||||
});
|
||||
|
||||
it('uses first group in $scope.groups if more than one exists', function() {
|
||||
var party = specHelper.newGroup({
|
||||
type: 'party',
|
||||
_id: 'user-party'
|
||||
});
|
||||
var guild = specHelper.newGroup({
|
||||
type: 'guild',
|
||||
_id: 'guild'
|
||||
});
|
||||
scope.groups = [party, guild];
|
||||
scope.groupsFilter = [party, guild];
|
||||
scope.search = {
|
||||
group: {
|
||||
'user-party': true,
|
||||
'guild': true
|
||||
}
|
||||
};
|
||||
|
||||
scope.create();
|
||||
|
||||
expect(scope.newChallenge.group).to.eql('user-party');
|
||||
});
|
||||
|
||||
it('defaults to tavern if no group can be set as default', function() {
|
||||
scope.create();
|
||||
|
||||
expect(scope.newChallenge.group).to.eql(tavernId);
|
||||
});
|
||||
|
||||
it('calculates maxPrize', function() {
|
||||
User.getBalanceInGems.returns(20);
|
||||
scope.create();
|
||||
|
||||
expect(scope.maxPrize).to.eql(20);
|
||||
});
|
||||
|
||||
it('sets newChallenge to a blank challenge', function() {
|
||||
scope.create();
|
||||
|
||||
var chal = scope.newChallenge;
|
||||
|
||||
expect(chal.name).to.eql('');
|
||||
expect(chal.description).to.eql('');
|
||||
expect(chal.habits).to.eql([]);
|
||||
expect(chal.dailys).to.eql([]);
|
||||
expect(chal.todos).to.eql([]);
|
||||
expect(chal.rewards).to.eql([]);
|
||||
expect(chal.leader).to.eql('unique-user-id');
|
||||
expect(chal.group).to.eql(tavernId);
|
||||
expect(chal.timestamp).to.be.greaterThan(0);
|
||||
expect(chal.official).to.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insufficientGemsForTavernChallenge', function() {
|
||||
context('tavern challenge', function() {
|
||||
it('returns true if user has no gems', function() {
|
||||
User.user.balance = 0;
|
||||
scope.newChallenge = specHelper.newChallenge({
|
||||
group: tavernId
|
||||
});
|
||||
|
||||
var cannotCreateTavernChallenge = scope.insufficientGemsForTavernChallenge();
|
||||
expect(cannotCreateTavernChallenge).to.eql(true);
|
||||
});
|
||||
|
||||
it('returns false if user has gems', function() {
|
||||
User.user.balance = .25;
|
||||
scope.newChallenge = specHelper.newChallenge({
|
||||
group: tavernId
|
||||
});
|
||||
|
||||
var cannotCreateTavernChallenge = scope.insufficientGemsForTavernChallenge();
|
||||
expect(cannotCreateTavernChallenge).to.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
context('non-tavern challenge', function() {
|
||||
it('returns false', function() {
|
||||
User.user.balance = 0;
|
||||
scope.newChallenge = specHelper.newChallenge({
|
||||
group: 'not-tavern'
|
||||
});
|
||||
|
||||
var cannotCreateTavernChallenge = scope.insufficientGemsForTavernChallenge();
|
||||
expect(cannotCreateTavernChallenge).to.eql(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('edit', function() {
|
||||
it('transitions to edit page', function() {
|
||||
sandbox.stub(state, 'transitionTo');
|
||||
var challenge = specHelper.newChallenge({
|
||||
_id: 'challenge-id'
|
||||
});
|
||||
|
||||
scope.edit(challenge);
|
||||
|
||||
expect(state.transitionTo).to.be.calledOnce;
|
||||
expect(state.transitionTo).to.be.calledWith(
|
||||
'options.social.challenges.edit',
|
||||
{ cid: challenge._id },
|
||||
{ reload: true, inherit: false, notify: true }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('discard', function() {
|
||||
it('sets new challenge to null', function() {
|
||||
scope.newChallenge = specHelper.newChallenge();
|
||||
|
||||
scope.discard();
|
||||
|
||||
expect(scope.newChallenge).to.not.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe('clone', function() {
|
||||
|
||||
var challengeToClone = {
|
||||
name: 'copyChallenge',
|
||||
description: 'copyChallenge',
|
||||
habits: [specHelper.newHabit()],
|
||||
dailys: [specHelper.newDaily()],
|
||||
todos: [specHelper.newTodo()],
|
||||
rewards: [specHelper.newReward()],
|
||||
leader: 'unique-user-id',
|
||||
group: { _id: "copyGroup" },
|
||||
timestamp: new Date("October 13, 2014 11:13:00"),
|
||||
members: ['id', 'another-id'],
|
||||
official: true,
|
||||
_isMember: true,
|
||||
prize: 1
|
||||
};
|
||||
|
||||
it('Clones the basic challenge info', function() {
|
||||
|
||||
scope.clone(challengeToClone);
|
||||
|
||||
expect(scope.newChallenge.name).to.eql(challengeToClone.name);
|
||||
expect(scope.newChallenge.shortName).to.eql(challengeToClone.shortName);
|
||||
expect(scope.newChallenge.description).to.eql(challengeToClone.description);
|
||||
expect(scope.newChallenge.leader).to.eql(user._id);
|
||||
expect(scope.newChallenge.group).to.eql(challengeToClone.group._id);
|
||||
expect(scope.newChallenge.official).to.eql(challengeToClone.official);
|
||||
expect(scope.newChallenge.prize).to.eql(challengeToClone.prize);
|
||||
});
|
||||
|
||||
it('does not clone members', function() {
|
||||
scope.clone(challengeToClone);
|
||||
|
||||
expect(scope.newChallenge.members).to.not.exist;
|
||||
});
|
||||
|
||||
it('does not clone timestamp', function() {
|
||||
scope.clone(challengeToClone);
|
||||
|
||||
expect(scope.newChallenge.timestamp).to.not.exist;
|
||||
});
|
||||
|
||||
it('clones habits', function() {
|
||||
scope.clone(challengeToClone);
|
||||
|
||||
expect(scope.newChallenge.habits.length).to.eql(challengeToClone.habits.length);
|
||||
expect(scope.newChallenge.habits[0].text).to.eql(challengeToClone.habits[0].text);
|
||||
expect(scope.newChallenge.habits[0].notes).to.eql(challengeToClone.habits[0].notes);
|
||||
});
|
||||
|
||||
it('clones dailys', function() {
|
||||
scope.clone(challengeToClone);
|
||||
|
||||
expect(scope.newChallenge.dailys.length).to.eql(challengeToClone.dailys.length);
|
||||
expect(scope.newChallenge.dailys[0].text).to.eql(challengeToClone.dailys[0].text);
|
||||
expect(scope.newChallenge.dailys[0].notes).to.eql(challengeToClone.dailys[0].notes);
|
||||
});
|
||||
|
||||
it('clones todos', function() {
|
||||
scope.clone(challengeToClone);
|
||||
|
||||
expect(scope.newChallenge.todos.length).to.eql(challengeToClone.todos.length);
|
||||
expect(scope.newChallenge.todos[0].text).to.eql(challengeToClone.todos[0].text);
|
||||
expect(scope.newChallenge.todos[0].notes).to.eql(challengeToClone.todos[0].notes);
|
||||
});
|
||||
|
||||
it('clones rewards', function() {
|
||||
scope.clone(challengeToClone);
|
||||
|
||||
expect(scope.newChallenge.rewards.length).to.eql(challengeToClone.rewards.length);
|
||||
expect(scope.newChallenge.rewards[0].text).to.eql(challengeToClone.rewards[0].text);
|
||||
expect(scope.newChallenge.rewards[0].notes).to.eql(challengeToClone.rewards[0].notes);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('User interactions', function() {
|
||||
describe('join', function() {
|
||||
it('calls challenge join', function(){
|
||||
var joinChallengeSpy = sinon.spy(challenges, 'joinChallenge');
|
||||
|
||||
var challenge = specHelper.newChallenge({
|
||||
_id: 'challenge-to-join',
|
||||
});
|
||||
|
||||
scope.join(challenge);
|
||||
|
||||
expect(joinChallengeSpy).to.be.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
describe('clickLeave', function() {
|
||||
var clickEvent = {
|
||||
target: 'button'
|
||||
};
|
||||
|
||||
it('sets selectedChal to passed in challenge', function() {
|
||||
var challenge = specHelper.newChallenge({
|
||||
_id: 'popover-challenge-to-leave'
|
||||
});
|
||||
|
||||
expect(scope.selectedChal).to.not.exist;
|
||||
|
||||
scope.clickLeave(challenge, clickEvent);
|
||||
expect(scope.selectedChal).to.eql(challenge);
|
||||
});
|
||||
|
||||
it('creates popover element', function() {
|
||||
var challenge = specHelper.newChallenge({
|
||||
_id: 'popover-challenge-to-leave'
|
||||
});
|
||||
|
||||
expect(scope.popoverEl).to.not.exist;
|
||||
scope.clickLeave(challenge, clickEvent);
|
||||
expect(scope.popoverEl).to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe('leave', function() {
|
||||
var challenge = specHelper.newChallenge({
|
||||
_id: 'challenge-to-leave',
|
||||
});
|
||||
|
||||
var clickEvent = {
|
||||
target: 'button'
|
||||
};
|
||||
|
||||
it('removes selectedChal when cancel is chosen', function() {
|
||||
scope.clickLeave(challenge, clickEvent);
|
||||
|
||||
expect(scope.selectedChal).to.eql(challenge);
|
||||
|
||||
scope.leave('cancel');
|
||||
expect(scope.selectedChal).to.not.exist;
|
||||
});
|
||||
|
||||
it('calls challenge leave when anything but cancel is chosen', function() {
|
||||
var leaveChallengeSpy = sinon.spy(challenges, 'leaveChallenge');
|
||||
scope.clickLeave(challenge, clickEvent);
|
||||
|
||||
scope.leave('not-cancel', challenge);
|
||||
expect(leaveChallengeSpy).to.be.calledOnce;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('modal actions', function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(members, 'selectMember');
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
members.selectMember.returns(Promise.resolve());
|
||||
});
|
||||
|
||||
describe('sendMessageToChallengeParticipant', function() {
|
||||
it('opens private-message modal', function(done) {
|
||||
scope.sendMessageToChallengeParticipant(user._id);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith(
|
||||
'private-message',
|
||||
{ controller: 'MemberModalCtrl' }
|
||||
);
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendGiftToChallengeParticipant', function() {
|
||||
it('opens send-gift modal', function(done) {
|
||||
scope.sendGiftToChallengeParticipant(user._id);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith(
|
||||
'send-gift',
|
||||
{ controller: 'MemberModalCtrl' }
|
||||
);
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,121 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe("Chat Controller", function() {
|
||||
var scope, ctrl, user, $rootScope, $controller, $httpBackend, html;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(function(_$rootScope_, _$controller_, _$compile_, _$httpBackend_){
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
$rootScope = _$rootScope_;
|
||||
|
||||
scope = _$rootScope_.$new();
|
||||
|
||||
$controller = _$controller_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
html = _$compile_('<div><form ng-submit="postChat(group, message.content)"><textarea submit-on-meta-enter ng-model="message.content" ng-model-options="{debounce: 250}"></textarea></form></div>')(scope);
|
||||
document.body.appendChild(html[0]);
|
||||
ctrl = $controller('ChatCtrl', {$scope: scope, $element: html});
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
html.remove();
|
||||
});
|
||||
|
||||
describe('copyToDo', function() {
|
||||
it('when copying a user message it opens modal with information from message', function() {
|
||||
scope.group = {
|
||||
name: "Princess Bride"
|
||||
};
|
||||
|
||||
var modalSpy = sandbox.spy($rootScope, "openModal");
|
||||
var message = {
|
||||
uuid: 'the-dread-pirate-roberts',
|
||||
user: 'Wesley',
|
||||
text: 'As you wish'
|
||||
};
|
||||
|
||||
scope.copyToDo(message);
|
||||
|
||||
modalSpy.should.have.been.calledOnce;
|
||||
|
||||
modalSpy.should.have.been.calledWith('copyChatToDo', sinon.match(function(callArgToMatch){
|
||||
return callArgToMatch.controller == 'CopyMessageModalCtrl'
|
||||
&& callArgToMatch.scope.text == message.text
|
||||
}));
|
||||
});
|
||||
|
||||
it('when copying a system message it opens modal with information from message', function() {
|
||||
scope.group = {
|
||||
name: "Princess Bride"
|
||||
};
|
||||
|
||||
var modalSpy = sandbox.spy($rootScope, "openModal");
|
||||
var message = {
|
||||
uuid: 'system',
|
||||
text: 'Wesley attacked the ROUS in the Fire Swamp'
|
||||
};
|
||||
|
||||
scope.copyToDo(message);
|
||||
|
||||
modalSpy.should.have.been.calledOnce;
|
||||
|
||||
modalSpy.should.have.been.calledWith('copyChatToDo', sinon.match(function(callArgToMatch){
|
||||
return callArgToMatch.controller == 'CopyMessageModalCtrl'
|
||||
&& callArgToMatch.scope.text == message.text
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it('updates model on enter key press', function() {
|
||||
// Set initial state of the page with some dummy data.
|
||||
scope.group = { name: 'group' };
|
||||
|
||||
// The main controller is going to try to fetch the template right off.
|
||||
// No big deal, just return an empty string.
|
||||
$httpBackend.when('GET', 'partials/main.html').respond('');
|
||||
|
||||
// Let the page settle, and the controllers set their initial state.
|
||||
$rootScope.$digest();
|
||||
|
||||
// Watch for calls to postChat & make sure it doesn't do anything.
|
||||
let postChatSpy = sandbox.stub(scope, 'postChat');
|
||||
|
||||
// Pretend we typed 'aaa' into the textarea.
|
||||
var textarea = html.find('textarea');
|
||||
textarea[0].value = 'aaa';
|
||||
let inputEvent = new Event('input');
|
||||
textarea[0].dispatchEvent(inputEvent);
|
||||
|
||||
// Give a change for the ng-model watchers to notice that the value in the
|
||||
// textarea has changed.
|
||||
$rootScope.$digest();
|
||||
|
||||
// Since no time has elapsed and we debounce the model change, we should
|
||||
// see no model update just yet.
|
||||
expect(scope.message.content).to.equal('');
|
||||
|
||||
// Now, press the enter key in the textarea. We use jquery here to paper
|
||||
// over browser differences with initializing the keyboard event.
|
||||
var keyboardEvent = jQuery.Event('keydown', {keyCode: 13, key: 'Enter', metaKey: true});
|
||||
jQuery(textarea).trigger(keyboardEvent);
|
||||
|
||||
// Now, allow the model to update given the changes to the page still
|
||||
// without letting any time elapse...
|
||||
$rootScope.$digest();
|
||||
|
||||
// ... and nevertheless seeing the desired call to postChat with the right
|
||||
// data. Yay!
|
||||
postChatSpy.should.have.been.calledWith(scope.group, 'aaa');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe("CopyMessageModal controller", function() {
|
||||
var scope, ctrl, user, Notification, $rootScope, $controller;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
var mockWindow = {href: '', alert: sandbox.spy(), location: {search: '', pathname: '', href: ''}};
|
||||
|
||||
$provide.value('$window', mockWindow);
|
||||
});
|
||||
|
||||
inject(function($rootScope, _$controller_, _Notification_, User){
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
user.ops = {
|
||||
addTask: sandbox.spy()
|
||||
};
|
||||
|
||||
scope = $rootScope.$new();
|
||||
scope.$close = sandbox.spy();
|
||||
|
||||
$controller = _$controller_;
|
||||
|
||||
User.setUser(user);
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: User});
|
||||
|
||||
ctrl = $controller('CopyMessageModalCtrl', {$scope: scope, User: User});
|
||||
|
||||
Notification = _Notification_;
|
||||
Notification.text = sandbox.spy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("saveTodo", function() {
|
||||
it('saves todo', function() {
|
||||
|
||||
scope.text = "A Tavern msg";
|
||||
scope.notes = "Some notes";
|
||||
var payload = {
|
||||
body: {
|
||||
text: scope.text,
|
||||
type: 'todo',
|
||||
notes: scope.notes
|
||||
}
|
||||
};
|
||||
|
||||
scope.saveTodo();
|
||||
|
||||
user.ops.addTask.should.have.been.calledOnce;
|
||||
user.ops.addTask.should.have.been.calledWith(payload);
|
||||
Notification.text.should.have.been.calledOnce;
|
||||
Notification.text.should.have.been.calledWith(window.env.t('messageAddedAsToDo'));
|
||||
scope.$close.should.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,51 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Filters Controller', function() {
|
||||
var scope, user, userService;
|
||||
|
||||
beforeEach(function () {
|
||||
module(function($provide) {
|
||||
var mockWindow = {href: '', alert: sandbox.spy(), location: {search: '', pathname: '', href: ''}};
|
||||
|
||||
$provide.value('$window', mockWindow);
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, Shared, User) {
|
||||
user = specHelper.newUser();
|
||||
Shared.wrap(user);
|
||||
scope = $rootScope.$new();
|
||||
// user.filters = {};
|
||||
User.setUser(user);
|
||||
User.user.filters = {};
|
||||
userService = User;
|
||||
$controller('FiltersCtrl', {$scope: scope, User: User});
|
||||
})
|
||||
});
|
||||
|
||||
describe('tags', function(){
|
||||
it('creates a tag', function(){
|
||||
scope._newTag = {name:'tagName'}
|
||||
scope.createTag();
|
||||
expect(user.tags).to.have.length(1);
|
||||
expect(user.tags[0].name).to.eql('tagName');
|
||||
expect(user.tags[0]).to.have.property('id');
|
||||
});
|
||||
|
||||
it('toggles tag filtering', inject(function(Shared){
|
||||
var tag = {id: Shared.uuid(), name: 'myTag'};
|
||||
scope.toggleFilter(tag);
|
||||
expect(userService.user.filters[tag.id]).to.eql(true);
|
||||
scope.toggleFilter(tag);
|
||||
expect(userService.user.filters[tag.id]).to.not.eql(true);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('updateTaskFilter', function(){
|
||||
it('updatest user\'s filter query with the value of filterQuery', function () {
|
||||
scope.filterQuery = 'task';
|
||||
scope.updateTaskFilter();
|
||||
|
||||
expect(userService.user.filterQuery).to.eql(scope.filterQuery);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,86 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Footer Controller', function() {
|
||||
var scope, user, User;
|
||||
|
||||
beforeEach(inject(function($rootScope, $controller) {
|
||||
user = specHelper.newUser();
|
||||
User = {
|
||||
log: sandbox.stub(),
|
||||
set: sandbox.stub(),
|
||||
addTenGems: sandbox.stub(),
|
||||
addHourglass: sandbox.stub(),
|
||||
user: user
|
||||
};
|
||||
scope = $rootScope.$new();
|
||||
$controller('FooterCtrl', {$scope: scope, User: User, Social: {}});
|
||||
}));
|
||||
|
||||
context('Debug mode', function() {
|
||||
before(function() {
|
||||
window.env.NODE_ENV = 'test';
|
||||
});
|
||||
|
||||
after(function() {
|
||||
delete window.env.NODE_ENV;
|
||||
});
|
||||
|
||||
describe('#setHealthLow', function(){
|
||||
it('sets user health to 1');
|
||||
});
|
||||
|
||||
describe('#addMissedDay', function(){
|
||||
beforeEach(function() {
|
||||
sandbox.stub(confirm).returns(true);
|
||||
});
|
||||
|
||||
it('Cancels if confirm box is not confirmed');
|
||||
|
||||
it('allows multiple days');
|
||||
|
||||
it('sets users last cron');
|
||||
|
||||
it('notifies uers');
|
||||
});
|
||||
|
||||
describe('#addTenGems', function() {
|
||||
it('posts to /user/addTenGems', inject(function($httpBackend) {
|
||||
scope.addTenGems();
|
||||
|
||||
expect(User.addTenGems).to.have.been.called;
|
||||
}));
|
||||
});
|
||||
|
||||
describe('#addHourglass', function() {
|
||||
it('posts to /user/addHourglass', inject(function($httpBackend) {
|
||||
scope.addHourglass();
|
||||
|
||||
expect(User.addHourglass).to.have.been.called;
|
||||
}));
|
||||
});
|
||||
|
||||
describe('#addGold', function() {
|
||||
it('adds 500 gold to user');
|
||||
});
|
||||
|
||||
describe('#addMana', function() {
|
||||
it('adds 500 mana to user');
|
||||
});
|
||||
|
||||
describe('#addLevelsAndGold', function() {
|
||||
it('adds 10000 experience to user');
|
||||
|
||||
it('adds 10000 gp to user');
|
||||
|
||||
it('adds 10000 mp to user');
|
||||
});
|
||||
|
||||
describe('#addOneLevel', function() {
|
||||
it('adds one level to user');
|
||||
});
|
||||
|
||||
describe('#addBossQuestProgressUp', function() {
|
||||
it('adds 1000 progress to quest.progress.up');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,279 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Groups Controller', function() {
|
||||
var scope, ctrl, groups, user, guild, $rootScope;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, Groups){
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
|
||||
scope = $rootScope.$new();
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
ctrl = $controller('GroupsCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
groups = Groups;
|
||||
});
|
||||
});
|
||||
|
||||
describe("isMemberOfPendingQuest", function() {
|
||||
var party;
|
||||
var partyStub;
|
||||
|
||||
beforeEach(function () {
|
||||
party = specHelper.newGroup({
|
||||
_id: "unique-party-id",
|
||||
type: 'party',
|
||||
members: ['leader-id'] // Ensure we wouldn't pass automatically.
|
||||
});
|
||||
|
||||
partyStub = sandbox.stub(groups, "party", function() {
|
||||
return party;
|
||||
});
|
||||
});
|
||||
|
||||
it("returns false if group is does not have a quest", function() {
|
||||
expect(scope.isMemberOfPendingQuest(user._id, party)).to.not.be.ok;
|
||||
});
|
||||
|
||||
it("returns false if group quest has not members", function() {
|
||||
party.quest = {
|
||||
'key': 'random-key',
|
||||
};
|
||||
expect(scope.isMemberOfPendingQuest(user._id, party)).to.not.be.ok;
|
||||
});
|
||||
|
||||
it("returns false if group quest is active", function() {
|
||||
party.quest = {
|
||||
'key': 'random-key',
|
||||
'members': {},
|
||||
'active': true,
|
||||
};
|
||||
party.quest.members[user._id] = true;
|
||||
expect(scope.isMemberOfPendingQuest(user._id, party)).to.not.be.ok;
|
||||
});
|
||||
|
||||
it("returns true if user is a member of a pending quest", function() {
|
||||
party.quest = {
|
||||
'key': 'random-key',
|
||||
'members': {},
|
||||
};
|
||||
party.quest.members[user._id] = true;
|
||||
expect(scope.isMemberOfPendingQuest(user._id, party)).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe("isMemberOfGroup", function() {
|
||||
it("returns true if group is the user's party retrieved from groups service", function() {
|
||||
var party = specHelper.newGroup({
|
||||
_id: "unique-party-id",
|
||||
type: 'party',
|
||||
members: ['leader-id'] // Ensure we wouldn't pass automatically.
|
||||
});
|
||||
|
||||
var partyStub = sandbox.stub(groups, "party", function() {
|
||||
return party;
|
||||
});
|
||||
|
||||
expect(scope.isMemberOfGroup(user._id, party)).to.be.ok;
|
||||
});
|
||||
|
||||
it('returns true if guild is included in myGuilds call', function(){
|
||||
|
||||
var guild = specHelper.newGroup({
|
||||
_id: "unique-guild-id",
|
||||
type: 'guild',
|
||||
members: [user._id]
|
||||
});
|
||||
|
||||
user.guilds = [guild._id];
|
||||
|
||||
expect(scope.isMemberOfGroup(user._id, guild)).to.be.ok;
|
||||
});
|
||||
|
||||
it('does not return true if guild is not included in myGuilds call', function(){
|
||||
|
||||
var guild = specHelper.newGroup({
|
||||
_id: "unique-guild-id",
|
||||
type: 'guild',
|
||||
members: ['not-user-id']
|
||||
});
|
||||
|
||||
user.guilds = [];
|
||||
|
||||
expect(scope.isMemberOfGroup(user._id, guild)).to.not.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAbleToEditGroup', () => {
|
||||
var guild;
|
||||
|
||||
beforeEach(() => {
|
||||
user.contributor = {};
|
||||
guild = specHelper.newGroup({
|
||||
_id: 'unique-guild-id',
|
||||
type: 'guild',
|
||||
members: ['not-user-id'],
|
||||
$save: sandbox.spy(),
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true if user is an admin', () => {
|
||||
guild.leader = 'not-user-id';
|
||||
user.contributor.admin = true;
|
||||
expect(scope.isAbleToEditGroup(guild)).to.be.ok;
|
||||
});
|
||||
|
||||
it('returns true if user is group leader', () => {
|
||||
guild.leader = {_id: user._id}
|
||||
expect(scope.isAbleToEditGroup(guild)).to.be.ok;
|
||||
});
|
||||
|
||||
it('returns false is user is not a leader or admin', () => {
|
||||
expect(scope.isAbleToEditGroup(guild)).to.not.be.ok;
|
||||
});
|
||||
|
||||
it('returns false is user is an admin but group is a party', () => {
|
||||
guild.type = 'party';
|
||||
user.contributor.admin = true;
|
||||
expect(scope.isAbleToEditGroup(guild)).to.not.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('editGroup', () => {
|
||||
var guild;
|
||||
|
||||
beforeEach(() => {
|
||||
guild = specHelper.newGroup({
|
||||
_id: 'unique-guild-id',
|
||||
leader: 'old leader',
|
||||
type: 'guild',
|
||||
members: ['not-user-id'],
|
||||
$save: sandbox.spy(),
|
||||
});
|
||||
});
|
||||
|
||||
it('marks group as being in edit mode', () => {
|
||||
scope.editGroup(guild);
|
||||
|
||||
expect(guild._editing).to.eql(true);
|
||||
});
|
||||
|
||||
it('copies group to groupCopy', () => {
|
||||
scope.editGroup(guild);
|
||||
|
||||
for (var key in scope.groupCopy) {
|
||||
expect(scope.groupCopy[key]).to.eql(guild[key]);
|
||||
}
|
||||
});
|
||||
|
||||
it('does not change original group when groupCopy is changed', () => {
|
||||
scope.editGroup(guild);
|
||||
|
||||
scope.groupCopy.leader = 'new leader';
|
||||
expect(scope.groupCopy.leader).to.not.eql(guild.leader);
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveEdit', () => {
|
||||
let guild;
|
||||
|
||||
beforeEach(() => {
|
||||
guild = specHelper.newGroup({
|
||||
_id: 'unique-guild-id',
|
||||
name: 'old name',
|
||||
leader: 'old leader',
|
||||
type: 'guild',
|
||||
members: ['not-user-id'],
|
||||
$save: () => {},
|
||||
});
|
||||
|
||||
scope.editGroup(guild);
|
||||
});
|
||||
|
||||
it('calls group update', () => {
|
||||
let guildUpdate = sandbox.spy(groups.Group, 'update');
|
||||
|
||||
scope.saveEdit(guild);
|
||||
|
||||
expect(guildUpdate).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('calls cancelEdit', () => {
|
||||
sandbox.stub(scope, 'cancelEdit');
|
||||
|
||||
scope.saveEdit(guild);
|
||||
|
||||
expect(scope.cancelEdit).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('applies changes to groupCopy to original group', () => {
|
||||
scope.groupCopy.name = 'new name';
|
||||
|
||||
scope.saveEdit(guild);
|
||||
|
||||
expect(guild.name).to.eql('new name');
|
||||
});
|
||||
|
||||
it('assigns leader id to group if leader has changed', () => {
|
||||
scope.groupCopy._newLeader = { _id: 'some leader id' };
|
||||
|
||||
scope.saveEdit(guild);
|
||||
|
||||
expect(guild.leader).to.eql('some leader id');
|
||||
});
|
||||
|
||||
it('does not assign new leader id if leader object is not passed in', () => {
|
||||
scope.groupCopy._newLeader = 'not an object';
|
||||
|
||||
scope.saveEdit(guild);
|
||||
|
||||
expect(guild.leader).to.eql('old leader');
|
||||
});
|
||||
});
|
||||
|
||||
describe('cancelEdit', () => {
|
||||
beforeEach(() => {
|
||||
guild = specHelper.newGroup({
|
||||
_id: 'unique-guild-id',
|
||||
name: 'old name',
|
||||
leader: 'old leader',
|
||||
type: 'guild',
|
||||
members: ['not-user-id'],
|
||||
$save: () => {},
|
||||
});
|
||||
|
||||
scope.editGroup(guild);
|
||||
});
|
||||
|
||||
it('sets _editing to false on group', () => {
|
||||
expect(guild._editing).to.eql(true);
|
||||
|
||||
scope.cancelEdit(guild);
|
||||
|
||||
expect(guild._editing).to.eql(false);
|
||||
});
|
||||
|
||||
it('reset groupCopy to an empty object', () => {
|
||||
expect(scope.groupCopy).to.not.eql({});
|
||||
|
||||
scope.cancelEdit(guild);
|
||||
|
||||
expect(scope.groupCopy).to.eql({});
|
||||
});
|
||||
});
|
||||
|
||||
/* TODO: Modal testing */
|
||||
describe.skip("deleteAllMessages", function() { });
|
||||
describe.skip("clickMember", function() { });
|
||||
describe.skip("removeMember", function() { });
|
||||
describe.skip("confirmRemoveMember", function() { });
|
||||
describe.skip("quickReply", function() { });
|
||||
});
|
||||
@@ -1,63 +0,0 @@
|
||||
describe('Group Tasks Meta Actions Controller', () => {
|
||||
let rootScope, scope, user, userSerivce;
|
||||
|
||||
beforeEach(() => {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(($rootScope, $controller) => {
|
||||
rootScope = $rootScope;
|
||||
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
userSerivce = {user: user};
|
||||
|
||||
scope = $rootScope.$new();
|
||||
|
||||
scope.task = {
|
||||
group: {
|
||||
assignedUsers: [],
|
||||
approval: {
|
||||
required: false,
|
||||
}
|
||||
},
|
||||
};
|
||||
scope.task._edit = angular.copy(scope.task);
|
||||
|
||||
$controller('GroupTaskActionsCtrl', {$scope: scope, User: userSerivce});
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggleTaskRequiresApproval', function () {
|
||||
it('toggles task approval required field from false to true', function () {
|
||||
scope.toggleTaskRequiresApproval();
|
||||
expect(scope.task._edit.group.approval.required).to.be.true;
|
||||
});
|
||||
|
||||
it('toggles task approval required field from true to false', function () {
|
||||
scope.task._edit.group.approval.required = true;
|
||||
scope.toggleTaskRequiresApproval();
|
||||
expect(scope.task._edit.group.approval.required).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('assign events', function () {
|
||||
it('adds a group member to assigned users on "addedGroupMember" event ', () => {
|
||||
var testId = 'test-id';
|
||||
rootScope.$broadcast('addedGroupMember', testId);
|
||||
expect(scope.task.group.assignedUsers).to.contain(testId);
|
||||
expect(scope.task._edit.group.assignedUsers).to.contain(testId);
|
||||
});
|
||||
|
||||
it('removes a group member to assigned users on "addedGroupMember" event ', () => {
|
||||
var testId = 'test-id';
|
||||
scope.task.group.assignedUsers.push(testId);
|
||||
scope.task._edit.group.assignedUsers.push(testId);
|
||||
rootScope.$broadcast('removedGroupMember', testId);
|
||||
expect(scope.task.group.assignedUsers).to.not.contain(testId);
|
||||
expect(scope.task._edit.group.assignedUsers).to.not.contain(testId);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
describe('Group Task Actions Controller', () => {
|
||||
let scope, user, userSerivce;
|
||||
|
||||
beforeEach(() => {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(($rootScope, $controller) => {
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
userSerivce = {user: user};
|
||||
userSerivce.sync = sandbox.stub();
|
||||
|
||||
scope = $rootScope.$new();
|
||||
|
||||
$controller('GroupTaskMetaActionsCtrl', {$scope: scope, User: userSerivce});
|
||||
|
||||
scope.task = {
|
||||
group: {
|
||||
assignedUsers: [],
|
||||
},
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
describe('claim', () => {
|
||||
beforeEach(() => {
|
||||
sandbox.stub(window, 'confirm').returns(true);
|
||||
});
|
||||
|
||||
it('adds user to assigned users of scope task ', () => {
|
||||
scope.claim();
|
||||
expect(scope.task.group.assignedUsers).to.contain(user._id);
|
||||
});
|
||||
|
||||
it('syncs user tasks ', () => {
|
||||
scope.claim();
|
||||
expect(userSerivce.sync).to.be.calledOnce;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Hall of Heroes Controller', function() {
|
||||
var scope, ctrl, user, $rootScope;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller){
|
||||
user = specHelper.newUser();
|
||||
|
||||
scope = $rootScope.$new();
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
ctrl = $controller('HallHeroesCtrl', {$scope: scope, User: {user: user}});
|
||||
});
|
||||
});
|
||||
|
||||
it('populates contributor input with selected hero id', function(){
|
||||
var loadHero = sandbox.spy(scope, "loadHero");
|
||||
var scrollTo = sandbox.spy(window, "scrollTo");
|
||||
|
||||
scope.populateContributorInput(user._id);
|
||||
expect(scope._heroID).to.eql(user._id);
|
||||
expect(loadHero.callCount).to.eql(1);
|
||||
expect(scrollTo.callCount).to.eql(1);
|
||||
});
|
||||
});
|
||||
@@ -1,50 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Header Controller', function() {
|
||||
var scope, ctrl, user, $location, $rootScope;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id"
|
||||
$provide.value('User', {user: user});
|
||||
});
|
||||
|
||||
inject(function(_$rootScope_, _$controller_, _$location_){
|
||||
scope = _$rootScope_.$new();
|
||||
$rootScope = _$rootScope_;
|
||||
|
||||
$location = _$location_;
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
_$controller_('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
ctrl = _$controller_('HeaderCtrl', {$scope: scope, User: {user: user}});
|
||||
});
|
||||
});
|
||||
|
||||
context('inviteOrStartParty', function(){
|
||||
beforeEach(function(){
|
||||
sandbox.stub($location, 'path');
|
||||
sandbox.stub($rootScope, 'openModal');
|
||||
});
|
||||
|
||||
it('redirects to party page if user does not have a party', function(){
|
||||
var group = {};
|
||||
scope.inviteOrStartParty(group);
|
||||
|
||||
expect($location.path).to.be.calledWith("/options/groups/party");
|
||||
expect($rootScope.openModal).to.not.be.called;
|
||||
});
|
||||
|
||||
it('Opens invite-friends modal if user has a party', function(){
|
||||
var group = {
|
||||
type: 'party'
|
||||
};
|
||||
scope.inviteOrStartParty(group);
|
||||
|
||||
expect($rootScope.openModal).to.be.calledOnce;
|
||||
expect($location.path).to.not.be.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,73 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('inbox Controller', function() {
|
||||
var scope, ctrl, user, $rootScope, $controller;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(function(_$rootScope_, _$controller_){
|
||||
user = specHelper.newUser();
|
||||
user._id = 'unique-user-id';
|
||||
$rootScope = _$rootScope_;
|
||||
|
||||
scope = _$rootScope_.$new();
|
||||
|
||||
$controller = _$controller_;
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
ctrl = $controller('InboxCtrl', {$scope: scope});
|
||||
});
|
||||
});
|
||||
|
||||
describe('copyToDo', function() {
|
||||
it('when copying a user message it opens modal with information from message', function() {
|
||||
scope.group = {
|
||||
name: 'Princess Bride'
|
||||
};
|
||||
|
||||
sandbox.spy($rootScope, 'openModal');
|
||||
var message = {
|
||||
uuid: 'the-dread-pirate-roberts',
|
||||
user: 'Wesley',
|
||||
text: 'As you wish'
|
||||
};
|
||||
|
||||
scope.copyToDo(message);
|
||||
|
||||
expect($rootScope.openModal).to.be.calledOnce;
|
||||
expect($rootScope.openModal).to.be.calledWith('copyChatToDo', sinon.match(function(callArgToMatch){
|
||||
var taskText = env.t('taskTextFromInbox', {
|
||||
from: message.user
|
||||
});
|
||||
return callArgToMatch.controller == 'CopyMessageModalCtrl'
|
||||
&& callArgToMatch.scope.text == taskText
|
||||
}));
|
||||
});
|
||||
|
||||
it('when copying a system message it opens modal with information from message', function() {
|
||||
|
||||
var modalSpy = sandbox.spy($rootScope, 'openModal');
|
||||
var message = {
|
||||
uuid: 'system',
|
||||
text: 'Wesley attacked the ROUS in the Fire Swamp'
|
||||
};
|
||||
|
||||
scope.copyToDo(message);
|
||||
|
||||
modalSpy.should.have.been.calledOnce;
|
||||
|
||||
modalSpy.should.have.been.calledWith('copyChatToDo', sinon.match(function(callArgToMatch){
|
||||
var taskText = env.t('taskTextFromInbox', {
|
||||
from: 'system'
|
||||
});
|
||||
return callArgToMatch.controller == 'CopyMessageModalCtrl'
|
||||
&& callArgToMatch.scope.text == taskText
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,538 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Inventory Controller', function() {
|
||||
var scope, ctrl, user, rootScope, shared, achievement;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
var mockWindow = {
|
||||
confirm: function(msg) {
|
||||
return true;
|
||||
},
|
||||
location: {search: '', pathname: '', href: ''},
|
||||
};
|
||||
|
||||
$provide.value('$window', mockWindow);
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, Shared, User, $location, $window, Achievement) {
|
||||
user = specHelper.newUser({
|
||||
balance: 4,
|
||||
items: {
|
||||
gear: { owned: {} },
|
||||
eggs: { Cactus: 1 },
|
||||
hatchingPotions: { Base: 1 },
|
||||
food: { Meat: 1 },
|
||||
pets: {},
|
||||
mounts: {}
|
||||
},
|
||||
preferences: {
|
||||
suppressModals: {}
|
||||
},
|
||||
purchased: {
|
||||
plan: {
|
||||
mysteryItems: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Shared.wrap(user);
|
||||
shared = Shared;
|
||||
achievement = Achievement;
|
||||
|
||||
scope = $rootScope.$new();
|
||||
rootScope = $rootScope;
|
||||
|
||||
User.user = user;
|
||||
User.setUser(user);
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: User});
|
||||
|
||||
ctrl = $controller('InventoryCtrl', {$scope: scope, User: User});
|
||||
});
|
||||
});
|
||||
|
||||
it('starts without any item selected', function(){
|
||||
expect(scope.selectedEgg).to.eql(null);
|
||||
expect(scope.selectedPotion).to.eql(null);
|
||||
expect(scope.selectedFood).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('chooses an egg', function(){
|
||||
scope.chooseEgg('Cactus');
|
||||
expect(scope.selectedEgg.key).to.eql('Cactus');
|
||||
});
|
||||
|
||||
it('chooses a potion', function(){
|
||||
scope.choosePotion('Base');
|
||||
expect(scope.selectedPotion.key).to.eql('Base');
|
||||
});
|
||||
|
||||
describe('Hatching Pets', function(){
|
||||
beforeEach(function() {
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
});
|
||||
|
||||
it('hatches a pet', function(){
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.choosePotion('Base');
|
||||
expect(user.items.eggs).to.eql({Cactus: 0});
|
||||
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
||||
expect(user.items.pets).to.eql({'Cactus-Base': 5});
|
||||
expect(scope.selectedEgg).to.eql(null);
|
||||
expect(scope.selectedPotion).to.eql(null);
|
||||
});
|
||||
|
||||
it('shows a modal for pet hatching', function(){
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.choosePotion('Base');
|
||||
|
||||
expect(rootScope.openModal).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.calledWith('hatchPet');
|
||||
});
|
||||
|
||||
it('shows modal even if user has raised that pet to a mount', function(){
|
||||
user.items.pets['Cactus-Base'] = -1;
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.choosePotion('Base');
|
||||
|
||||
expect(rootScope.openModal).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.calledWith('hatchPet');
|
||||
});
|
||||
|
||||
//@TODO: Fix Common hatch
|
||||
xit('does not show modal if user tries to hatch a pet they own', function(){
|
||||
user.items.pets['Cactus-Base'] = 5;
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.choosePotion('Base');
|
||||
expect(rootScope.openModal).to.not.have.been.called;
|
||||
});
|
||||
|
||||
//@TODO: Fix Common hatch
|
||||
xit('does not show modal if user tries to hatch a premium quest pet', function(){
|
||||
user.items.eggs = {Snake: 1};
|
||||
user.items.hatchingPotions = {Peppermint: 1};
|
||||
scope.chooseEgg('Snake');
|
||||
scope.choosePotion('Peppermint');
|
||||
expect(rootScope.openModal).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('does not show pet hatching modal if user has opted out', function(){
|
||||
user.preferences.suppressModals.hatchPet = true;
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.choosePotion('Base');
|
||||
|
||||
expect(rootScope.openModal).to.not.be.called;
|
||||
});
|
||||
|
||||
it('shows beastMaster achievement modal if user has all 90 pets', function(){
|
||||
sandbox.stub(achievement, 'displayAchievement');
|
||||
sandbox.stub(shared.count, "beastMasterProgress").returns(90);
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.choosePotion('Base');
|
||||
|
||||
expect(achievement.displayAchievement).to.be.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('beastMaster');
|
||||
});
|
||||
|
||||
it('shows triadBingo achievement modal if user has all pets twice and all mounts', function(){
|
||||
sandbox.stub(achievement, 'displayAchievement');
|
||||
sandbox.stub(shared.count, "mountMasterProgress").returns(90);
|
||||
sandbox.stub(shared.count, "dropPetsCurrentlyOwned").returns(90);
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.choosePotion('Base');
|
||||
|
||||
expect(achievement.displayAchievement).to.be.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('triadBingo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Feeding and Raising Pets', function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
user.items.pets = {'PandaCub-Base':5};
|
||||
user.items.mounts = {'PandaCub-Base':false};
|
||||
});
|
||||
|
||||
it('feeds a pet', function() {
|
||||
scope.chooseFood('Meat');
|
||||
scope.choosePet('PandaCub','Base');
|
||||
|
||||
expect(user.items.pets['PandaCub-Base']).to.eql(10);
|
||||
});
|
||||
|
||||
it('gives weaker benefit when feeding inappropriate food', function() {
|
||||
user.items.food.Honey = 1;
|
||||
|
||||
scope.chooseFood('Honey');
|
||||
scope.choosePet('PandaCub','Base');
|
||||
|
||||
expect(user.items.pets['PandaCub-Base']).to.eql(7);
|
||||
});
|
||||
|
||||
it('raises pet to a mount when feeding gauge maxes out', function() {
|
||||
user.items.pets['PandaCub-Base'] = 45;
|
||||
|
||||
scope.chooseFood('Meat');
|
||||
scope.choosePet('PandaCub','Base');
|
||||
|
||||
expect(user.items.pets['PandaCub-Base']).to.eql(-1);
|
||||
expect(user.items.mounts['PandaCub-Base']).to.exist;
|
||||
});
|
||||
|
||||
it('raises pet to a mount instantly when using a Saddle', function() {
|
||||
user.items.food.Saddle = 1;
|
||||
|
||||
scope.chooseFood('Saddle');
|
||||
scope.choosePet('PandaCub','Base');
|
||||
|
||||
expect(user.items.pets['PandaCub-Base']).to.eql(-1);
|
||||
expect(user.items.mounts['PandaCub-Base']).to.exist;
|
||||
});
|
||||
|
||||
it('displays mount raising modal for drop pets', function() {
|
||||
user.items.food.Saddle = 1;
|
||||
|
||||
scope.chooseFood('Saddle');
|
||||
scope.choosePet('PandaCub','Base');
|
||||
|
||||
expect(rootScope.openModal).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.calledWith('raisePet');
|
||||
});
|
||||
|
||||
it('displays mount raising modal for quest pets', function() {
|
||||
user.items.food.Saddle = 1;
|
||||
user.items.pets['Snake-Base'] = 1;
|
||||
|
||||
scope.chooseFood('Saddle');
|
||||
scope.choosePet('Snake','Base');
|
||||
|
||||
expect(rootScope.openModal).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.calledWith('raisePet');
|
||||
});
|
||||
|
||||
it('displays mount raising modal for premium pets', function() {
|
||||
user.items.food.Saddle = 1;
|
||||
user.items.pets['TigerCub-Spooky'] = 1;
|
||||
|
||||
scope.chooseFood('Saddle');
|
||||
scope.choosePet('TigerCub','Spooky');
|
||||
|
||||
expect(rootScope.openModal).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.calledWith('raisePet');
|
||||
});
|
||||
|
||||
it('shows mountMaster achievement modal if user has all 90 mounts', function(){
|
||||
sandbox.stub(achievement, 'displayAchievement');
|
||||
sandbox.stub(shared.count, "mountMasterProgress").returns(90);
|
||||
scope.chooseFood('Meat');
|
||||
scope.choosePet('PandaCub','Base');
|
||||
|
||||
expect(achievement.displayAchievement).to.be.calledOnce;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('mountMaster');
|
||||
});
|
||||
});
|
||||
|
||||
it('sells an egg', function(){
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.sellInventory();
|
||||
expect(user.items.eggs).to.eql({Cactus: 0});
|
||||
expect(user.stats.gp).to.eql(3);
|
||||
});
|
||||
|
||||
it('sells a potion', function(){
|
||||
scope.choosePotion('Base');
|
||||
scope.sellInventory();
|
||||
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
||||
expect(user.stats.gp).to.eql(2);
|
||||
});
|
||||
|
||||
it('sells food', function(){
|
||||
scope.chooseFood('Meat');
|
||||
scope.sellInventory();
|
||||
expect(user.items.food).to.eql({Meat: 0});
|
||||
expect(user.stats.gp).to.eql(1);
|
||||
});
|
||||
|
||||
it('chooses a pet', function(){
|
||||
user.items.pets['Cactus-Base'] = 5;
|
||||
scope.choosePet('Cactus', 'Base');
|
||||
expect(user.items.currentPet).to.eql('Cactus-Base');
|
||||
});
|
||||
|
||||
it('purchases an egg', inject(function(Content){
|
||||
scope.purchase('eggs', Content.eggs['Wolf']);
|
||||
expect(user.balance).to.eql(3.25);
|
||||
expect(user.items.eggs).to.eql({Cactus: 1, Wolf: 1})
|
||||
}));
|
||||
|
||||
describe('Deselecting Items', function() {
|
||||
it('deselects a food', function(){
|
||||
scope.chooseFood('Meat');
|
||||
scope.deselectItem();
|
||||
expect(scope.selectedFood).to.eql(null);
|
||||
});
|
||||
|
||||
it('deselects a potion', function(){
|
||||
scope.choosePotion('Base');
|
||||
scope.deselectItem();
|
||||
expect(scope.selectedPotion).to.eql(null);
|
||||
});
|
||||
|
||||
it('deselects a egg', function(){
|
||||
scope.chooseEgg('Cactus');
|
||||
scope.deselectItem();
|
||||
expect(scope.selectedEgg).to.eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('openCardsModal', function(type, numberOfVariations) {
|
||||
var cardsModalScope;
|
||||
|
||||
beforeEach(function() {
|
||||
cardsModalScope = {};
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
sandbox.stub(rootScope, '$new').returns(cardsModalScope);
|
||||
});
|
||||
|
||||
it('opens cards modal', function() {
|
||||
scope.openCardsModal('valentine', 4);
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith(
|
||||
'cards'
|
||||
);
|
||||
});
|
||||
|
||||
it('instantiates a new scope for the modal', function() {
|
||||
scope.openCardsModal('valentine', 4);
|
||||
|
||||
expect(rootScope.$new).to.be.calledOnce;
|
||||
expect(cardsModalScope.cardType).to.eql('valentine');
|
||||
expect(cardsModalScope.cardMessage).to.exist;
|
||||
});
|
||||
|
||||
it('provides a card message', function() {
|
||||
scope.openCardsModal('valentine', 1);
|
||||
|
||||
expect(cardsModalScope.cardMessage).to.eql(env.t('valentine0'));
|
||||
});
|
||||
|
||||
it('randomly generates message from x number of messages', function() {
|
||||
var possibleValues = [env.t('valentine0'), env.t('valentine1')];
|
||||
|
||||
scope.openCardsModal('valentine', 2);
|
||||
|
||||
expect(possibleValues).to.contain(cardsModalScope.cardMessage);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#buyQuest', function() {
|
||||
var quests, questObject;
|
||||
|
||||
beforeEach(inject(function(Quests) {
|
||||
quests = Quests;
|
||||
questObject = { key: 'whale' };
|
||||
|
||||
sandbox.stub(quests, 'buyQuest').returns({ then: function(res) { res(questObject); } });
|
||||
}));
|
||||
|
||||
it('calls Quests.buyQuest', function() {
|
||||
scope.buyQuest('foo');
|
||||
|
||||
expect(quests.buyQuest).to.be.calledOnce;
|
||||
expect(quests.buyQuest).to.be.calledWith('foo');
|
||||
});
|
||||
|
||||
it('sets selectedQuest to resolved quest object', function() {
|
||||
scope.buyQuest('whale');
|
||||
|
||||
expect(rootScope.selectedQuest).to.eql(questObject);
|
||||
});
|
||||
|
||||
it('opens buyQuest modal', function() {
|
||||
sandbox.spy(rootScope, 'openModal');
|
||||
|
||||
scope.buyQuest('whale');
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith('buyQuest', {controller: 'InventoryCtrl'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#showQuest', function() {
|
||||
var quests, questObject;
|
||||
|
||||
beforeEach(inject(function(Quests) {
|
||||
quests = Quests;
|
||||
questObject = { key: 'whale' };
|
||||
|
||||
sandbox.stub(quests, 'showQuest').returns({ then: function(res) { res(questObject); } });
|
||||
}));
|
||||
|
||||
it('calls Quests.showQuest', function() {
|
||||
scope.showQuest('foo');
|
||||
|
||||
expect(quests.showQuest).to.be.calledOnce;
|
||||
expect(quests.showQuest).to.be.calledWith('foo');
|
||||
});
|
||||
|
||||
it('sets selectedQuest to resolved quest object', function() {
|
||||
scope.showQuest('whale');
|
||||
|
||||
expect(rootScope.selectedQuest).to.eql(questObject);
|
||||
});
|
||||
|
||||
it('opens showQuest modal', function() {
|
||||
sandbox.spy(rootScope, 'openModal');
|
||||
|
||||
scope.showQuest('whale');
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith('showQuest', {controller: 'InventoryCtrl'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#hasAllTimeTravelerItems', function() {
|
||||
it('returns false if items remain for purchase with Mystic Hourglasses', function() {
|
||||
expect(scope.hasAllTimeTravelerItems()).to.eql(false);
|
||||
});
|
||||
|
||||
it('returns true if there are no items left to purchase', inject(function(Content) {
|
||||
_.forEach(Content.gear.flat, function(v,item) {
|
||||
if (item.indexOf('mystery') > -1) {
|
||||
user.items.gear.owned[item] = true;
|
||||
}
|
||||
});
|
||||
_.forEach(Content.timeTravelStable.pets, function(v,pet) {
|
||||
user.items.pets[pet] = 5;
|
||||
});
|
||||
_.forEach(Content.timeTravelStable.mounts, function(v,mount) {
|
||||
user.items.mounts[mount] = true;
|
||||
});
|
||||
|
||||
expect(scope.hasAllTimeTravelerItems()).to.eql(true);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('#hasAllTimeTravelerItemsOfType', function() {
|
||||
it('returns false for Mystery Sets if there are sets left in the time traveler store', function() {
|
||||
expect(scope.hasAllTimeTravelerItemsOfType('mystery')).to.eql(false);
|
||||
});
|
||||
|
||||
it('returns true for Mystery Sets if there are no sets left to purchase', inject(function(Content) {
|
||||
_.forEach(Content.gear.flat, function(v,item) {
|
||||
if (item.indexOf('mystery') > -1) {
|
||||
user.items.gear.owned[item] = true;
|
||||
}
|
||||
});
|
||||
|
||||
expect(scope.hasAllTimeTravelerItemsOfType('mystery')).to.eql(true);
|
||||
}));
|
||||
|
||||
it('returns false for pets if user does not own all pets in the Time Travel Stable', function() {
|
||||
expect(scope.hasAllTimeTravelerItemsOfType('pets')).to.eql(false);
|
||||
});
|
||||
|
||||
it('returns true for pets if user owns all pets in the Time Travel Stable', inject(function(Content) {
|
||||
_.forEach(Content.timeTravelStable.pets, function(v,pet) {
|
||||
user.items.pets[pet] = 5;
|
||||
});
|
||||
|
||||
expect(scope.hasAllTimeTravelerItemsOfType('pets')).to.eql(true);
|
||||
}));
|
||||
|
||||
it('returns false for mounts if user does not own all mounts in the Time Travel Stable', function() {
|
||||
expect(scope.hasAllTimeTravelerItemsOfType('mounts')).to.eql(false);
|
||||
});
|
||||
|
||||
it('returns true for mounts if user owns all mounts in the Time Travel Stable', inject(function(Content) {
|
||||
_.forEach(Content.timeTravelStable.mounts, function(v,mount) {
|
||||
user.items.mounts[mount] = true;
|
||||
});
|
||||
|
||||
expect(scope.hasAllTimeTravelerItemsOfType('mounts')).to.eql(true);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('Gear search filter', function() {
|
||||
var wrap = function(text) {
|
||||
return {'text': function() {return text;}};
|
||||
}
|
||||
|
||||
var toText = function(list) {
|
||||
return _.map(list, function(ele) { return ele.text(); });
|
||||
}
|
||||
|
||||
var gearByClass, gearByType;
|
||||
|
||||
beforeEach(function() {
|
||||
scope.$digest();
|
||||
gearByClass = {'raw': [wrap('kale'), wrap('sashimi')],
|
||||
'cooked': [wrap('chicken'), wrap('potato')]};
|
||||
|
||||
gearByType = {'veg': [wrap('kale'), wrap('potato')],
|
||||
'not': [wrap('chicken'), wrap('sashimi')]};
|
||||
scope.gearByClass = gearByClass;
|
||||
scope.gearByType = gearByType;
|
||||
scope.equipmentQuery.query = 'a';
|
||||
});
|
||||
|
||||
it('filters nothing if equipmentQuery is nothing', function() {
|
||||
scope.equipmentQuery.query = '';
|
||||
scope.$digest();
|
||||
expect(toText(scope.filteredGearByClass['raw'])).to.eql(['kale', 'sashimi']);
|
||||
expect(toText(scope.filteredGearByClass['cooked'])).to.eql(['chicken', 'potato']);
|
||||
expect(toText(scope.filteredGearByType['veg'])).to.eql(['kale', 'potato']);
|
||||
expect(toText(scope.filteredGearByType['not'])).to.eql(['chicken', 'sashimi']);
|
||||
});
|
||||
|
||||
it('filters out gear if class gear changes', function() {
|
||||
scope.$digest();
|
||||
expect(toText(scope.filteredGearByClass['raw'])).to.eql(['kale', 'sashimi']);
|
||||
expect(toText(scope.filteredGearByClass['cooked'])).to.eql(['potato']);
|
||||
|
||||
scope.gearByClass['raw'].push(wrap('zucchini'));
|
||||
scope.gearByClass['cooked'].push(wrap('pizza'));
|
||||
scope.$digest();
|
||||
expect(toText(scope.filteredGearByClass['raw'])).to.eql(['kale', 'sashimi']);
|
||||
expect(toText(scope.filteredGearByClass['cooked'])).to.eql(['potato', 'pizza']);
|
||||
});
|
||||
|
||||
it('filters out gear if typed gear changes', function() {
|
||||
scope.$digest();
|
||||
expect(toText(scope.filteredGearByType['veg'])).to.eql(['kale', 'potato']);
|
||||
expect(toText(scope.filteredGearByType['not'])).to.eql(['sashimi']);
|
||||
|
||||
scope.gearByType['veg'].push(wrap('zucchini'));
|
||||
scope.gearByType['not'].push(wrap('pizza'));
|
||||
|
||||
scope.$digest();
|
||||
expect(toText(scope.filteredGearByType['veg'])).to.eql(['kale', 'potato']);
|
||||
expect(toText(scope.filteredGearByType['not'])).to.eql(['sashimi', 'pizza']);
|
||||
});
|
||||
|
||||
it('filters out gear if filter query changes', function() {
|
||||
scope.equipmentQuery.query = 'c';
|
||||
scope.$digest();
|
||||
|
||||
expect(toText(scope.filteredGearByClass['raw'])).to.eql([]);
|
||||
expect(toText(scope.filteredGearByClass['cooked'])).to.eql(['chicken']);
|
||||
expect(toText(scope.filteredGearByType['veg'])).to.eql([]);
|
||||
expect(toText(scope.filteredGearByType['not'])).to.eql(['chicken']);
|
||||
});
|
||||
|
||||
it('returns the right filtered gear', function() {
|
||||
var equipment = [wrap('spicy tuna'), wrap('dragon'), wrap('rainbow'), wrap('caterpillar')];
|
||||
expect(toText(scope.equipmentSearch(equipment, 'ra'))).to.eql(['dragon', 'rainbow']);
|
||||
});
|
||||
|
||||
it('returns the right filtered gear if the source gear has unicode', function() {
|
||||
// blue hat, red hat, red shield
|
||||
var equipment = [wrap('藍色軟帽'), wrap('紅色軟帽'), wrap('紅色盾牌')];
|
||||
// searching for 'red' gives red hat, red shield
|
||||
expect(toText(scope.equipmentSearch(equipment, '紅色'))).to.eql(['紅色軟帽', '紅色盾牌']);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,257 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Invite to Group Controller', function() {
|
||||
var scope, ctrl, groups, user, guild, rootScope, $controller;
|
||||
|
||||
beforeEach(function() {
|
||||
user = specHelper.newUser({
|
||||
profile: { name: 'Mario' }
|
||||
});
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
$provide.value('injectedGroup', { user: user });
|
||||
});
|
||||
|
||||
inject(function(_$rootScope_, _$controller_, Groups) {
|
||||
rootScope = _$rootScope_;
|
||||
|
||||
scope = _$rootScope_.$new();
|
||||
|
||||
$controller = _$controller_;
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
ctrl = $controller('InviteToGroupCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
groups = Groups;
|
||||
});
|
||||
});
|
||||
|
||||
describe('addEmail', function() {
|
||||
it('adds blank email to email list', function() {
|
||||
scope.emails = [{name: 'Mario', email: 'mario@mushroomkingdom.com'}];
|
||||
scope.addEmail();
|
||||
|
||||
expect(scope.emails).to.eql([{name: 'Mario', email: 'mario@mushroomkingdom.com'}, {name: '', email: ''}]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addUuid', function() {
|
||||
it('adds blank uuid to invitees list', function() {
|
||||
scope.invitees = [{uuid: 'user1'}];
|
||||
scope.addUuid();
|
||||
|
||||
expect(scope.invitees).to.eql([{uuid: 'user1'}, {uuid: ''}]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('inviteNewUsers', function() {
|
||||
var groupInvite, groupCreate;
|
||||
|
||||
beforeEach(function() {
|
||||
scope.group = specHelper.newGroup({
|
||||
type: 'party',
|
||||
});
|
||||
|
||||
groupCreate = sandbox.stub(groups.Group, 'create');
|
||||
groupInvite = sandbox.stub(groups.Group, 'invite');
|
||||
});
|
||||
|
||||
context('if the party does not already exist', function() {
|
||||
var groupResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
delete scope.group._id;
|
||||
groupResponse = {data: {data: scope.group}}
|
||||
});
|
||||
|
||||
it('saves the group if a new group is being created', function() {
|
||||
groupCreate.returns(Promise.resolve(groupResponse));
|
||||
scope.inviteNewUsers('uuid');
|
||||
expect(groupCreate).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('uses provided name', function() {
|
||||
scope.group.name = 'test party';
|
||||
|
||||
groupCreate.returns(Promise.resolve(groupResponse));
|
||||
|
||||
scope.inviteNewUsers('uuid');
|
||||
|
||||
expect(groupCreate).to.be.calledWith(scope.group);
|
||||
expect(scope.group.name).to.eql('test party');
|
||||
});
|
||||
|
||||
it('names the group if no name is provided', function() {
|
||||
scope.group.name = '';
|
||||
|
||||
groupCreate.returns(Promise.resolve(groupResponse));
|
||||
|
||||
scope.inviteNewUsers('uuid');
|
||||
|
||||
expect(groupCreate).to.be.calledWith(scope.group);
|
||||
expect(scope.group.name).to.eql(env.t('possessiveParty', {name: user.profile.name}));
|
||||
});
|
||||
});
|
||||
|
||||
context('email', function() {
|
||||
beforeEach(function () {
|
||||
sandbox.stub(rootScope, 'hardRedirect');
|
||||
});
|
||||
|
||||
it('invites user with emails', function(done) {
|
||||
scope.emails = [
|
||||
{name: 'Luigi', email: 'mario_bro@themushroomkingdom.com'},
|
||||
{name: 'Mario', email: 'mario@tmk.com'}
|
||||
];
|
||||
|
||||
var inviteDetails = {
|
||||
inviter: user.profile.name,
|
||||
emails: [
|
||||
{name: 'Luigi', email: 'mario_bro@themushroomkingdom.com'},
|
||||
{name: 'Mario', email: 'mario@tmk.com'}
|
||||
]
|
||||
};
|
||||
|
||||
groupInvite.returns(
|
||||
Promise.resolve()
|
||||
.then(function () {
|
||||
expect(groupInvite).to.be.calledOnce;
|
||||
expect(groupInvite).to.be.calledWith(scope.group._id, inviteDetails);
|
||||
done();
|
||||
})
|
||||
);
|
||||
|
||||
scope.inviteNewUsers('email');
|
||||
});
|
||||
|
||||
it('resets email list after sending', function(done) {
|
||||
scope.emails[0].name = 'Luigi';
|
||||
scope.emails[0].email = 'mario_bro@themushroomkingdom.com';
|
||||
|
||||
groupInvite.returns(
|
||||
Promise.resolve()
|
||||
.then(function () {
|
||||
//We use a timeout to test items that happen after the promise is resolved
|
||||
setTimeout(function(){
|
||||
expect(scope.emails).to.eql([{name:'', email: ''},{name:'', email: ''}]);
|
||||
done();
|
||||
}, 1000);
|
||||
})
|
||||
);
|
||||
|
||||
scope.inviteNewUsers('email');
|
||||
});
|
||||
|
||||
it('filters out blank email inputs', function() {
|
||||
scope.emails = [
|
||||
{name: 'Luigi', email: 'mario_bro@themushroomkingdom.com'},
|
||||
{name: 'Toad', email: ''},
|
||||
{name: 'Mario', email: 'mario@tmk.com'}
|
||||
];
|
||||
|
||||
var inviteDetails = {
|
||||
inviter: user.profile.name,
|
||||
emails: [
|
||||
{name: 'Luigi', email: 'mario_bro@themushroomkingdom.com'},
|
||||
{name: 'Mario', email: 'mario@tmk.com'}
|
||||
]
|
||||
};
|
||||
|
||||
groupInvite.returns(
|
||||
Promise.resolve()
|
||||
.then(function () {
|
||||
expect(groupInvite).to.be.calledOnce;
|
||||
expect(groupInvite).to.be.calledWith(scope.group._id, inviteDetails);
|
||||
done();
|
||||
})
|
||||
);
|
||||
|
||||
scope.inviteNewUsers('email');
|
||||
});
|
||||
});
|
||||
|
||||
context('uuid', function() {
|
||||
beforeEach(function () {
|
||||
sandbox.stub(rootScope, 'hardRedirect');
|
||||
});
|
||||
|
||||
it('invites user with uuid', function(done) {
|
||||
scope.invitees = [{uuid: '1234'}];
|
||||
|
||||
groupInvite.returns(
|
||||
Promise.resolve()
|
||||
.then(function () {
|
||||
expect(groupInvite).to.be.calledOnce;
|
||||
expect(groupInvite).to.be.calledWith(scope.group._id, { uuids: ['1234'] });
|
||||
done();
|
||||
})
|
||||
);
|
||||
|
||||
scope.inviteNewUsers('uuid');
|
||||
});
|
||||
|
||||
it('invites users with uuids', function(done) {
|
||||
scope.invitees = [{uuid: 'user1'}, {uuid: 'user2'}, {uuid: 'user3'}];
|
||||
|
||||
groupInvite.returns(
|
||||
Promise.resolve()
|
||||
.then(function () {
|
||||
expect(groupInvite).to.be.calledOnce;
|
||||
expect(groupInvite).to.be.calledWith(scope.group._id, { uuids: ['user1', 'user2', 'user3'] });
|
||||
done();
|
||||
})
|
||||
);
|
||||
|
||||
scope.inviteNewUsers('uuid');
|
||||
});
|
||||
|
||||
it('resets invitee list after sending', function(done) {
|
||||
scope.invitees = [{uuid: 'user1'}, {uuid: 'user2'}, {uuid: 'user3'}];
|
||||
|
||||
groupInvite.returns(
|
||||
Promise.resolve()
|
||||
.then(function () {
|
||||
//We use a timeout to test items that happen after the promise is resolved
|
||||
setTimeout(function(){
|
||||
expect(scope.invitees).to.eql([{uuid: ''}]);
|
||||
done();
|
||||
}, 1000);
|
||||
done();
|
||||
})
|
||||
);
|
||||
|
||||
scope.inviteNewUsers('uuid');
|
||||
});
|
||||
|
||||
it('removes blank fields from being sent', function() {
|
||||
scope.invitees = [{uuid: 'user1'}, {uuid: ''}, {uuid: 'user3'}];
|
||||
|
||||
groupInvite.returns(
|
||||
Promise.resolve()
|
||||
.then(function () {
|
||||
expect(groupInvite).to.be.calledOnce;
|
||||
expect(groupInvite).to.be.calledWith(scope.group._id, { uuids: ['user1', 'user3'] });
|
||||
done();
|
||||
})
|
||||
);
|
||||
|
||||
scope.inviteNewUsers('uuid');
|
||||
});
|
||||
});
|
||||
|
||||
context('invalid invite method', function() {
|
||||
it('logs error', function() {
|
||||
sandbox.stub(console, 'log');
|
||||
|
||||
scope.inviteNewUsers();
|
||||
expect(groups.Group.invite).to.not.be.called;
|
||||
expect(console.log).to.be.calledOnce;
|
||||
expect(console.log).to.be.calledWith('Invalid invite method.');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Menu Controller', function() {
|
||||
|
||||
describe('MenuCtrl', function(){
|
||||
var scope, ctrl, user, $httpBackend, $window;
|
||||
|
||||
beforeEach(function(){
|
||||
module(function($provide) {
|
||||
$provide.value('Chat', { seenMessage: function() {} });
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, $rootScope, $controller) {
|
||||
scope = $rootScope.$new();
|
||||
|
||||
ctrl = $controller('MenuCtrl', {$scope: scope, $window: $window, User: user});
|
||||
})
|
||||
});
|
||||
|
||||
describe('clearMessage', function() {
|
||||
it('is Chat.seenMessage', inject(function(Chat) {
|
||||
expect(scope.clearMessages).to.eql(Chat.markChatSeen);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,191 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Notification Controller', function() {
|
||||
var user, scope, rootScope, fakeBackend, achievement, ctrl;
|
||||
|
||||
beforeEach(function() {
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
user.needsCron = false;
|
||||
|
||||
var userSync = sinon.stub().returns({
|
||||
then: function then (f) { f(); }
|
||||
});
|
||||
|
||||
let User = {
|
||||
user,
|
||||
readNotification: function noop () {},
|
||||
readNotifications: function noop () {},
|
||||
sync: userSync
|
||||
};
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('User', User);
|
||||
$provide.value('Guide', {});
|
||||
});
|
||||
|
||||
inject(function(_$rootScope_, $httpBackend, _$controller_, Achievement, Shared) {
|
||||
scope = _$rootScope_.$new();
|
||||
rootScope = _$rootScope_;
|
||||
|
||||
fakeBackend = $httpBackend;
|
||||
fakeBackend.when('GET', 'partials/main.html').respond({});
|
||||
|
||||
achievement = Achievement;
|
||||
|
||||
Shared.wrap(user);
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
_$controller_('RootCtrl', {$scope: scope, User});
|
||||
|
||||
ctrl = _$controller_('NotificationCtrl', {$scope: scope, User});
|
||||
});
|
||||
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
sandbox.stub(achievement, 'displayAchievement');
|
||||
});
|
||||
|
||||
describe('Quest Invitation modal watch', function() {
|
||||
it('opens quest invitation modal', function() {
|
||||
user.party.quest.RSVPNeeded = true;
|
||||
delete user.party.quest.completed;
|
||||
scope.$digest();
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith('questInvitation', {controller:'PartyCtrl'});
|
||||
});
|
||||
|
||||
it('does not open quest invitation modal if RSVPNeeded is not true', function() {
|
||||
user.party.quest.RSVPNeeded = false;
|
||||
delete user.party.quest.completed;
|
||||
scope.$digest();
|
||||
|
||||
expect(rootScope.openModal).to.not.be.called;
|
||||
});
|
||||
|
||||
it('does not open quest invitation modal if quest.completed contains a quest key', function() {
|
||||
user.party.quest.RSVPNeeded = true;
|
||||
user.party.quest.completed = "hedgebeast";
|
||||
scope.$digest();
|
||||
|
||||
expect(rootScope.openModal).to.not.be.calledWith('questInvitation', {controller:'PartyCtrl'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Quest Completion modal watch', function() {
|
||||
it('opens quest completion modal', function() {
|
||||
user.party.quest.completed = "hedgebeast";
|
||||
scope.$digest();
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith('questCompleted', {controller:'InventoryCtrl'});
|
||||
});
|
||||
|
||||
// Ensures that the completion modal opens before the invitation modal
|
||||
it('opens quest completion modal if RSVPNeeded is true', function() {
|
||||
user.party.quest.RSVPNeeded = true;
|
||||
user.party.quest.completed = "hedgebeast";
|
||||
scope.$digest();
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith('questCompleted', {controller:'InventoryCtrl'});
|
||||
});
|
||||
|
||||
it('does not open quest completion modal if quest.completed is null', function() {
|
||||
user.party.quest.completed = null;
|
||||
scope.$digest();
|
||||
|
||||
expect(rootScope.openModal).to.not.be.called;
|
||||
});
|
||||
});
|
||||
|
||||
describe('User challenge won notification watch', function() {
|
||||
it('opens challenge won modal when a challenge-won notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.userNotifications.push({type: 'WON_CHALLENGE'});
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.be.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('wonChallenge');
|
||||
});
|
||||
|
||||
it('does not open challenge won modal if no new challenge-won notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.not.be.calledWith('wonChallenge');
|
||||
});
|
||||
});
|
||||
|
||||
describe('User streak achievement notification watch', function() {
|
||||
it('opens streak achievement modal when a streak-achievement notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.userNotifications.push({type: 'STREAK_ACHIEVEMENT'});
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.be.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('streak', {size: 'md'});
|
||||
});
|
||||
|
||||
it('does not open streak achievement modal if no new streak-achievement notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.not.be.calledWith('streak', {size: 'md'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('User ultimate gear set achievement notification watch', function() {
|
||||
it('opens ultimate gear set achievement modal when an ultimate-gear-achievement notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.userNotifications.push({type: 'ULTIMATE_GEAR_ACHIEVEMENT'});
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.be.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('ultimateGear', {size: 'md'});
|
||||
});
|
||||
|
||||
it('does not open ultimate gear set achievement modal if no new ultimate-gear-achievement notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.not.be.calledWith('ultimateGear', {size: 'md'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('User rebirth achievement notification watch', function() {
|
||||
it('opens rebirth achievement modal when a rebirth-achievement notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.userNotifications.push({type: 'REBIRTH_ACHIEVEMENT'});
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.be.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('rebirth');
|
||||
});
|
||||
|
||||
it('does not open rebirth achievement modal if no new rebirth-achievement notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.not.be.calledWith('rebirth');
|
||||
});
|
||||
});
|
||||
|
||||
describe('User contributor achievement notification watch', function() {
|
||||
it('opens contributor achievement modal when a new-contributor-level notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.userNotifications.push({type: 'NEW_CONTRIBUTOR_LEVEL'});
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.be.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('contributor', {size: 'md'});
|
||||
});
|
||||
|
||||
it('does not open contributor achievement modal if no new new-contributor-level notification is recieved', function() {
|
||||
rootScope.$digest();
|
||||
rootScope.$digest();
|
||||
|
||||
expect(achievement.displayAchievement).to.not.be.calledWith('contributor', {size: 'md'});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,489 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe("Party Controller", function() {
|
||||
var scope, ctrl, user, User, questsService, groups, achievement, rootScope, $controller, deferred, party;
|
||||
|
||||
beforeEach(function() {
|
||||
user = specHelper.newUser(),
|
||||
user._id = "unique-user-id";
|
||||
User = {
|
||||
user: user,
|
||||
sync: sandbox.spy(),
|
||||
set: sandbox.spy()
|
||||
};
|
||||
|
||||
party = specHelper.newGroup({
|
||||
_id: "unique-party-id",
|
||||
type: 'party',
|
||||
members: ['leader-id'] // Ensure we wouldn't pass automatically.
|
||||
});
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('User', User);
|
||||
});
|
||||
|
||||
inject(function(_$rootScope_, _$controller_, Groups, Quests, _$q_, Achievement){
|
||||
|
||||
rootScope = _$rootScope_;
|
||||
|
||||
scope = _$rootScope_.$new();
|
||||
|
||||
$controller = _$controller_;
|
||||
|
||||
groups = Groups;
|
||||
questsService = Quests;
|
||||
achievement = Achievement;
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: User});
|
||||
|
||||
ctrl = $controller('PartyCtrl', {$scope: scope, User: User});
|
||||
});
|
||||
});
|
||||
|
||||
describe('initialization', function() {
|
||||
var groupResponse;
|
||||
|
||||
function initializeControllerWithStubbedState() {
|
||||
inject(function(_$state_) {
|
||||
var state = _$state_;
|
||||
sandbox.stub(state, 'is').returns(true);
|
||||
|
||||
var syncParty = sinon.stub(groups.Group, 'syncParty')
|
||||
syncParty.returns(Promise.resolve(groupResponse));
|
||||
|
||||
var froceSyncParty = sinon.stub(groups, 'party')
|
||||
froceSyncParty.returns(Promise.resolve(groupResponse));
|
||||
|
||||
$controller('PartyCtrl', { $scope: scope, $state: state, User: User });
|
||||
expect(state.is).to.be.calledOnce;
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(achievement, 'displayAchievement');
|
||||
});
|
||||
|
||||
context('party has 1 member', function() {
|
||||
it('awards no new achievements', function() {
|
||||
groupResponse = {_id: "test", type: "party", memberCount: 1};
|
||||
|
||||
initializeControllerWithStubbedState();
|
||||
|
||||
expect(User.set).to.not.be.called;
|
||||
expect(achievement.displayAchievement).to.not.be.called;
|
||||
});
|
||||
});
|
||||
|
||||
context('party has 2 members', function() {
|
||||
context('user does not have "Party Up" achievement', function() {
|
||||
it('awards "Party Up" achievement', function(done) {
|
||||
groupResponse = {_id: "test", type: "party", memberCount: 2};
|
||||
|
||||
initializeControllerWithStubbedState();
|
||||
|
||||
setTimeout(function() {
|
||||
expect(User.set).to.be.calledOnce;
|
||||
expect(User.set).to.be.calledWith(
|
||||
{ 'achievements.partyUp': true }
|
||||
);
|
||||
expect(achievement.displayAchievement).to.be.calledOnce;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('partyUp');
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('party has 4 members', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
groupResponse = {_id: "test", type: "party", memberCount: 4};
|
||||
});
|
||||
|
||||
context('user has "Party Up" but not "Party On" achievement', function() {
|
||||
it('awards "Party On" achievement', function(done) {
|
||||
user.achievements.partyUp = true;
|
||||
|
||||
initializeControllerWithStubbedState();
|
||||
|
||||
setTimeout(function(){
|
||||
expect(User.set).to.be.calledOnce;
|
||||
expect(User.set).to.be.calledWith(
|
||||
{ 'achievements.partyOn': true }
|
||||
);
|
||||
expect(achievement.displayAchievement).to.be.calledOnce;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('partyOn');
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
context('user has neither "Party Up" nor "Party On" achievements', function() {
|
||||
it('awards "Party Up" and "Party On" achievements', function(done) {
|
||||
initializeControllerWithStubbedState();
|
||||
|
||||
setTimeout(function(){
|
||||
expect(User.set).to.have.been.called;
|
||||
expect(User.set).to.be.calledWith(
|
||||
{ 'achievements.partyUp': true}
|
||||
);
|
||||
expect(User.set).to.be.calledWith(
|
||||
{ 'achievements.partyOn': true}
|
||||
);
|
||||
expect(achievement.displayAchievement).to.have.been.called;
|
||||
expect(achievement.displayAchievement).to.be.calledWith('partyUp');
|
||||
expect(achievement.displayAchievement).to.be.calledWith('partyOn');
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
context('user has both "Party Up" and "Party On" achievements', function() {
|
||||
it('awards no new achievements', function() {
|
||||
user.achievements.partyUp = true;
|
||||
user.achievements.partyOn = true;
|
||||
|
||||
initializeControllerWithStubbedState();
|
||||
|
||||
expect(User.set).to.not.be.called;
|
||||
expect(achievement.displayAchievement).to.not.be.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("create", function() {
|
||||
var partyStub;
|
||||
|
||||
beforeEach(function () {
|
||||
partyStub = sinon.stub(groups.Group, "create");
|
||||
partyStub.returns(Promise.resolve(party));
|
||||
sinon.stub(rootScope, 'hardRedirect');
|
||||
});
|
||||
|
||||
it("creates a new party", function() {
|
||||
var group = {
|
||||
type: 'party',
|
||||
};
|
||||
scope.create(group);
|
||||
expect(partyStub).to.be.calledOnce;
|
||||
//@TODO: Check user party console.log(User.user.party.id)
|
||||
});
|
||||
});
|
||||
|
||||
describe('questAccept', function() {
|
||||
var sendAction;
|
||||
var memberResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
scope.group = {
|
||||
quest: { members: { 'user-id': true } }
|
||||
};
|
||||
|
||||
memberResponse = {members: {another: true}};
|
||||
sinon.stub(questsService, 'sendAction')
|
||||
questsService.sendAction.returns(Promise.resolve(memberResponse));
|
||||
});
|
||||
|
||||
it('calls Quests.sendAction', function() {
|
||||
scope.questAccept();
|
||||
|
||||
expect(questsService.sendAction).to.be.calledOnce;
|
||||
expect(questsService.sendAction).to.be.calledWith('quests/accept');
|
||||
});
|
||||
|
||||
|
||||
it('updates quest object with new participants list', function(done) {
|
||||
scope.group.quest = {
|
||||
members: { user: true, another: true }
|
||||
};
|
||||
|
||||
setTimeout(function(){
|
||||
expect(scope.group.quest).to.eql(memberResponse);
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
scope.questAccept();
|
||||
});
|
||||
});
|
||||
|
||||
describe('questReject', function() {
|
||||
var memberResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
scope.group = {
|
||||
quest: { members: { 'user-id': true } }
|
||||
};
|
||||
|
||||
memberResponse = {members: {another: true}};
|
||||
var sendAction = sinon.stub(questsService, 'sendAction')
|
||||
sendAction.returns(Promise.resolve(memberResponse));
|
||||
});
|
||||
|
||||
it('calls Quests.sendAction', function() {
|
||||
scope.questReject();
|
||||
|
||||
expect(questsService.sendAction).to.be.calledOnce;
|
||||
expect(questsService.sendAction).to.be.calledWith('quests/reject');
|
||||
});
|
||||
|
||||
|
||||
it('updates quest object with new participants list', function(done) {
|
||||
scope.group.quest = {
|
||||
members: { user: true, another: true }
|
||||
};
|
||||
|
||||
setTimeout(function(){
|
||||
expect(scope.group.quest).to.eql(memberResponse);
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
scope.questReject();
|
||||
});
|
||||
});
|
||||
|
||||
describe('questCancel', function() {
|
||||
var party, cancelSpy, windowSpy, memberResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
scope.group = {
|
||||
quest: { members: { 'user-id': true } }
|
||||
};
|
||||
|
||||
memberResponse = {members: {another: true}};
|
||||
sinon.stub(questsService, 'sendAction')
|
||||
questsService.sendAction.returns(Promise.resolve(memberResponse));
|
||||
});
|
||||
|
||||
it('calls Quests.sendAction when alert box is confirmed', function() {
|
||||
sandbox.stub(window, "confirm").returns(true);
|
||||
|
||||
scope.questCancel();
|
||||
|
||||
expect(window.confirm).to.be.calledOnce;
|
||||
expect(window.confirm).to.be.calledWith(window.env.t('sureCancel'));
|
||||
expect(questsService.sendAction).to.be.calledOnce;
|
||||
expect(questsService.sendAction).to.be.calledWith('quests/cancel');
|
||||
});
|
||||
|
||||
it('does not call Quests.sendAction when alert box is not confirmed', function() {
|
||||
sandbox.stub(window, "confirm").returns(false);
|
||||
|
||||
scope.questCancel();
|
||||
|
||||
expect(window.confirm).to.be.calledOnce;
|
||||
expect(questsService.sendAction).to.not.be.called;
|
||||
});
|
||||
});
|
||||
|
||||
describe('questAbort', function() {
|
||||
var memberResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
scope.group = {
|
||||
quest: { members: { 'user-id': true } }
|
||||
};
|
||||
|
||||
memberResponse = {members: {another: true}};
|
||||
sinon.stub(questsService, 'sendAction')
|
||||
questsService.sendAction.returns(Promise.resolve(memberResponse));
|
||||
});
|
||||
|
||||
it('calls Quests.sendAction when two alert boxes are confirmed', function() {
|
||||
sandbox.stub(window, "confirm", function(){return true});
|
||||
|
||||
scope.questAbort();
|
||||
expect(window.confirm).to.be.calledTwice;
|
||||
expect(window.confirm).to.be.calledWith(window.env.t('sureAbort'));
|
||||
expect(window.confirm).to.be.calledWith(window.env.t('doubleSureAbort'));
|
||||
|
||||
expect(questsService.sendAction).to.be.calledOnce;
|
||||
expect(questsService.sendAction).to.be.calledWith('quests/abort');
|
||||
});
|
||||
|
||||
it('does not call Quests.sendAction when first alert box is not confirmed', function() {
|
||||
sandbox.stub(window, "confirm", function(){return false});
|
||||
|
||||
scope.questAbort();
|
||||
|
||||
expect(window.confirm).to.be.calledOnce;
|
||||
expect(window.confirm).to.be.calledWith(window.env.t('sureAbort'));
|
||||
expect(window.confirm).to.not.be.calledWith(window.env.t('doubleSureAbort'));
|
||||
|
||||
expect(questsService.sendAction).to.not.be.called;
|
||||
});
|
||||
|
||||
it('does not call Quests.sendAction when first alert box is confirmed but second one is not', function() {
|
||||
// Hack to confirm first window, but not second
|
||||
// Should not be necessary when we upgrade sinon
|
||||
var shouldReturn = false;
|
||||
sandbox.stub(window, 'confirm', function(){
|
||||
shouldReturn = !shouldReturn;
|
||||
return shouldReturn;
|
||||
});
|
||||
|
||||
scope.questAbort();
|
||||
|
||||
expect(window.confirm).to.be.calledTwice;
|
||||
expect(window.confirm).to.be.calledWith(window.env.t('sureAbort'));
|
||||
expect(window.confirm).to.be.calledWith(window.env.t('doubleSureAbort'));
|
||||
expect(questsService.sendAction).to.not.be.called;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#questLeave', function() {
|
||||
var memberResponse;
|
||||
|
||||
beforeEach(function() {
|
||||
scope.group = {
|
||||
quest: { members: { 'user-id': true } }
|
||||
};
|
||||
|
||||
memberResponse = {members: {another: true}};
|
||||
sinon.stub(questsService, 'sendAction')
|
||||
questsService.sendAction.returns(Promise.resolve(memberResponse));
|
||||
});
|
||||
|
||||
it('calls Quests.sendAction when alert box is confirmed', function() {
|
||||
sandbox.stub(window, "confirm").returns(true);
|
||||
|
||||
scope.questLeave();
|
||||
|
||||
expect(window.confirm).to.be.calledOnce;
|
||||
expect(window.confirm).to.be.calledWith(window.env.t('sureLeave'));
|
||||
expect(questsService.sendAction).to.be.calledOnce;
|
||||
expect(questsService.sendAction).to.be.calledWith('quests/leave');
|
||||
});
|
||||
|
||||
it('does not call Quests.sendAction when alert box is not confirmed', function() {
|
||||
sandbox.stub(window, "confirm").returns(false);
|
||||
|
||||
scope.questLeave();
|
||||
|
||||
expect(window.confirm).to.be.calledOnce;
|
||||
questsService.sendAction.should.not.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('updates quest object with new participants list', function(done) {
|
||||
scope.group.quest = {
|
||||
members: { user: true, another: true }
|
||||
};
|
||||
sandbox.stub(window, "confirm").returns(true);
|
||||
|
||||
setTimeout(function(){
|
||||
expect(scope.group.quest).to.eql(memberResponse);
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
scope.questLeave();
|
||||
});
|
||||
});
|
||||
|
||||
describe('clickStartQuest', function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
sandbox.stub(rootScope.$state, 'go');
|
||||
});
|
||||
|
||||
it('opens quest modal if user has a quest', function() {
|
||||
user.items.quests = {
|
||||
whale: 1
|
||||
};
|
||||
|
||||
scope.clickStartQuest();
|
||||
|
||||
expect(rootScope.$state.go).to.not.be.called;
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith(
|
||||
'ownedQuests',
|
||||
{ controller: 'InventoryCtrl' }
|
||||
);
|
||||
});
|
||||
|
||||
it('does not open modal if user has no quests', function() {
|
||||
user.items.quests = { };
|
||||
|
||||
scope.clickStartQuest();
|
||||
|
||||
expect(rootScope.openModal).to.not.be.called;
|
||||
expect(rootScope.$state.go).to.be.calledOnce;
|
||||
expect(rootScope.$state.go).to.be.calledWith('options.inventory.quests');
|
||||
});
|
||||
|
||||
it('does not open modal if user had quests previously, but does not now', function() {
|
||||
user.items.quests = {
|
||||
whale: 0,
|
||||
atom1: 0
|
||||
};
|
||||
|
||||
scope.clickStartQuest();
|
||||
|
||||
expect(rootScope.openModal).to.not.be.called;
|
||||
expect(rootScope.$state.go).to.be.calledOnce;
|
||||
expect(rootScope.$state.go).to.be.calledWith('options.inventory.quests');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#leaveOldPartyAndJoinNewParty', function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(scope, 'join');
|
||||
groups.data.party = { _id: 'old-party' };
|
||||
var groupLeave = sandbox.stub(groups.Group, 'leave');
|
||||
groupLeave.returns(Promise.resolve({}));
|
||||
sandbox.stub(groups, 'party').returns({
|
||||
_id: 'old-party'
|
||||
});
|
||||
sandbox.stub(window, 'confirm').returns(true);
|
||||
});
|
||||
|
||||
it('does nothing if user declines confirmation', function() {
|
||||
window.confirm.returns(false);
|
||||
scope.leaveOldPartyAndJoinNewParty('some-id', 'some-name');
|
||||
|
||||
expect(groups.Group.leave).to.not.be.called;
|
||||
})
|
||||
|
||||
it('leaves user\'s current party', function() {
|
||||
scope.leaveOldPartyAndJoinNewParty('some-id', 'some-name');
|
||||
|
||||
expect(groups.Group.leave).to.be.calledOnce;
|
||||
expect(groups.Group.leave).to.be.calledWith('old-party', false);
|
||||
});
|
||||
|
||||
it('joins the new party', function(done) {
|
||||
scope.leaveOldPartyAndJoinNewParty('some-id', 'some-name');
|
||||
|
||||
setTimeout(function() {
|
||||
expect(scope.join).to.be.calledOnce;
|
||||
expect(scope.join).to.be.calledWith({id: 'some-id', name: 'some-name'});
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#canEditQuest', function() {
|
||||
var party;
|
||||
|
||||
beforeEach(function() {
|
||||
party = specHelper.newGroup({
|
||||
type: 'party',
|
||||
leader: {},
|
||||
quest: {}
|
||||
});
|
||||
scope.group = party;
|
||||
});
|
||||
|
||||
it('returns false if user is not the quest leader', function() {
|
||||
party.quest.leader = 'another-user';
|
||||
|
||||
expect(scope.canEditQuest(party)).to.eql(false);
|
||||
});
|
||||
|
||||
it('returns true if user is quest leader', function() {
|
||||
party.quest.leader = 'unique-user-id';
|
||||
|
||||
expect(scope.canEditQuest(party)).to.eql(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,187 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Root Controller', function() {
|
||||
var scope, rootscope, user, User, notification, ctrl, $httpBackend;
|
||||
|
||||
beforeEach(function () {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
$provide.service('$templateCache', function () {
|
||||
return {
|
||||
get: function () {},
|
||||
put: function () {}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, _$httpBackend_, Notification) {
|
||||
scope = $rootScope.$new();
|
||||
scope.loginUsername = 'user';
|
||||
scope.loginPassword = 'pass';
|
||||
|
||||
rootscope = $rootScope;
|
||||
|
||||
$httpBackend = _$httpBackend_;
|
||||
|
||||
notification = Notification;
|
||||
sandbox.stub(notification, 'text');
|
||||
sandbox.stub(notification, 'markdown');
|
||||
|
||||
user = specHelper.newUser();
|
||||
User = {user: user};
|
||||
User.save = sandbox.spy();
|
||||
User.sync = sandbox.spy();
|
||||
|
||||
$httpBackend.whenGET(/partials/).respond();
|
||||
|
||||
ctrl = $controller('RootCtrl', {$scope: scope, User: User});
|
||||
});
|
||||
});
|
||||
|
||||
describe('contribText', function(){
|
||||
it('shows contributor level text', function(){
|
||||
expect(scope.contribText()).to.eql(undefined);
|
||||
expect(scope.contribText(null, {npc: 'NPC'})).to.eql('NPC');
|
||||
expect(scope.contribText({level: 0, text: 'Blacksmith'})).to.eql(undefined);
|
||||
expect(scope.contribText({level: 1, text: 'Blacksmith'})).to.eql('Friend Blacksmith');
|
||||
expect(scope.contribText({level: 2, text: 'Blacksmith'})).to.eql('Friend Blacksmith');
|
||||
expect(scope.contribText({level: 3, text: 'Blacksmith'})).to.eql('Elite Blacksmith');
|
||||
expect(scope.contribText({level: 4, text: 'Blacksmith'})).to.eql('Elite Blacksmith');
|
||||
expect(scope.contribText({level: 5, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
|
||||
expect(scope.contribText({level: 6, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
|
||||
expect(scope.contribText({level: 7, text: 'Blacksmith'})).to.eql('Legendary Blacksmith');
|
||||
expect(scope.contribText({level: 8, text: 'Blacksmith'})).to.eql('Guardian Blacksmith');
|
||||
expect(scope.contribText({level: 9, text: 'Blacksmith'})).to.eql('Heroic Blacksmith');
|
||||
expect(scope.contribText({level: 9, text: 'Blacksmith'}, {npc: 'NPC'})).to.eql('NPC');
|
||||
});
|
||||
});
|
||||
|
||||
describe('castEnd', function(){
|
||||
var task_target, type;
|
||||
|
||||
beforeEach(function(){
|
||||
task_target = {
|
||||
id: 'task-id',
|
||||
text: 'task'
|
||||
};
|
||||
type = 'task';
|
||||
scope.spell = {
|
||||
target: 'task',
|
||||
key: 'fireball',
|
||||
mana: 10,
|
||||
text: function() { return env.t('spellWizardFireballText') },
|
||||
cast: function(){}
|
||||
};
|
||||
rootscope.applyingAction = true;
|
||||
});
|
||||
|
||||
context('fails', function(){
|
||||
it('exits early if there is no applying action', function(){
|
||||
rootscope.applyingAction = null;
|
||||
expect(scope.castEnd(task_target, type)).to.be.eql('No applying action');
|
||||
});
|
||||
|
||||
it('sends notification if target is invalid', function(){
|
||||
scope.spell.target = 'not_the_same_target';
|
||||
|
||||
scope.castEnd(task_target, type);
|
||||
|
||||
notification.text.should.have.been.calledWith(window.env.t('invalidTarget'));
|
||||
});
|
||||
});
|
||||
|
||||
context('succeeds', function(){
|
||||
it('sets scope.spell and rootScope.applyingAction to falsy values', function(){
|
||||
|
||||
scope.castEnd(task_target, type);
|
||||
|
||||
expect(rootscope.applyingAction).to.eql(false);
|
||||
expect(scope.spell).to.eql(null);
|
||||
});
|
||||
|
||||
it('calls $scope.spell.cast', function(){
|
||||
// Kind of a hack, would prefer to use sinon.spy,
|
||||
// but scope.spell gets turned to null in scope.castEnd
|
||||
var spellWasCast = false;
|
||||
scope.spell.cast = function(){ spellWasCast = true };
|
||||
|
||||
scope.castEnd(task_target, type);
|
||||
|
||||
expect(spellWasCast).to.eql(true);
|
||||
});
|
||||
|
||||
it('calls cast endpoint', function() {
|
||||
$httpBackend.expectPOST(/cast/).respond(201);
|
||||
scope.castEnd(task_target, type);
|
||||
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('sends notification that spell was cast on task', function() {
|
||||
$httpBackend.expectPOST(/cast/).respond(201);
|
||||
scope.castEnd(task_target, type);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(notification.markdown).to.be.calledOnce;
|
||||
expect(notification.markdown).to.be.calledWith('You cast Burst of Flames on task.');
|
||||
expect(User.sync).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('sends notification that spell was cast on user', function() {
|
||||
var user_target = {
|
||||
profile: { name: 'Lefnire' }
|
||||
};
|
||||
scope.spell = {
|
||||
target: 'user',
|
||||
key: 'snowball',
|
||||
mana: 0,
|
||||
text: function() { return env.t('spellSpecialSnowballAuraText') },
|
||||
cast: function(){}
|
||||
};
|
||||
$httpBackend.expectPOST(/cast/).respond(201);
|
||||
scope.castEnd(user_target, 'user');
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(notification.markdown).to.be.calledOnce;
|
||||
expect(notification.markdown).to.be.calledWith('You cast Snowball on Lefnire.');
|
||||
expect(User.sync).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('sends notification that spell was cast on party', function() {
|
||||
var party_target = {};
|
||||
scope.spell = {
|
||||
target: 'party',
|
||||
key: 'healAll',
|
||||
mana: 25,
|
||||
text: function() { return env.t('spellHealerHealAllText') },
|
||||
cast: function(){}
|
||||
};
|
||||
$httpBackend.expectPOST(/cast/).respond(201);
|
||||
scope.castEnd(party_target, 'party');
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(notification.markdown).to.be.calledOnce;
|
||||
expect(notification.markdown).to.be.calledWith('You cast Blessing for the party.');
|
||||
expect(User.sync).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('sends notification that spell was cast on self', function() {
|
||||
var self_target = {};
|
||||
scope.spell = {
|
||||
target: 'self',
|
||||
key: 'stealth',
|
||||
mana: 45,
|
||||
text: function() { return env.t('spellRogueStealthText') },
|
||||
cast: function(){}
|
||||
};
|
||||
$httpBackend.expectPOST(/cast/).respond(201);
|
||||
scope.castEnd(self_target, 'self');
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(notification.markdown).to.be.calledOnce;
|
||||
expect(notification.markdown).to.be.calledWith('You cast Stealth.');
|
||||
expect(User.sync).to.be.calledOnce;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,367 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Settings Controller', function () {
|
||||
var rootScope, scope, $httpBackend, user, User, ctrl, Notification;
|
||||
|
||||
const actionClickEvent = {
|
||||
target: document.createElement('button'),
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
module(function($provide) {
|
||||
user = specHelper.newUser();
|
||||
User = {
|
||||
set: sandbox.stub(),
|
||||
reroll: sandbox.stub(),
|
||||
rebirth: sandbox.stub(),
|
||||
releasePets: sandbox.stub(),
|
||||
releaseMounts: sandbox.stub(),
|
||||
releaseBoth: sandbox.stub(),
|
||||
setCustomDayStart: sandbox.stub(),
|
||||
user: user
|
||||
};
|
||||
|
||||
User.user.ops = {
|
||||
reroll: sandbox.stub(),
|
||||
rebirth: sandbox.stub(),
|
||||
releasePets: sandbox.stub(),
|
||||
releaseMounts: sandbox.stub(),
|
||||
releaseBoth: sandbox.stub(),
|
||||
};
|
||||
|
||||
Notification = {
|
||||
error: sandbox.stub(),
|
||||
text: sandbox.stub()
|
||||
};
|
||||
|
||||
$provide.value('Notification', Notification);
|
||||
$provide.value('User', User);
|
||||
$provide.value('Guide', sandbox.stub());
|
||||
});
|
||||
|
||||
inject(function(_$rootScope_, _$controller_, _$httpBackend_) {
|
||||
scope = _$rootScope_.$new();
|
||||
rootScope = _$rootScope_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
|
||||
$httpBackend.whenGET(/partials/).respond();
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
_$controller_('RootCtrl', {$scope: scope, User: User, Notification: Notification});
|
||||
|
||||
ctrl = _$controller_('SettingsCtrl', {$scope: scope, User: User, Notification: Notification});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#openDayStartModal', function () {
|
||||
beforeEach(function () {
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
sandbox.stub(window, 'alert');
|
||||
});
|
||||
|
||||
it('opens the day start modal', function () {
|
||||
scope.openDayStartModal(5);
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith('change-day-start', {scope: scope});
|
||||
});
|
||||
|
||||
it('sets nextCron variable', function () {
|
||||
expect(scope.nextCron).to.not.exist;
|
||||
|
||||
scope.openDayStartModal(5);
|
||||
|
||||
expect(scope.nextCron).to.exist;
|
||||
});
|
||||
|
||||
it('calculates the next time cron will run', function () {
|
||||
var fakeCurrentTime = new Date(2013, 3, 1, 3, 12).getTime();
|
||||
var expectedTime = new Date(2013, 3, 1, 5, 0, 0).getTime();
|
||||
sandbox.useFakeTimers(fakeCurrentTime);
|
||||
|
||||
scope.openDayStartModal(5);
|
||||
|
||||
expect(scope.nextCron).to.eq(expectedTime);
|
||||
});
|
||||
|
||||
it('calculates the next time cron will run and adds a day if cron would have already passed', function () {
|
||||
var fakeCurrentTime = new Date(2013, 3, 1, 8, 12).getTime();
|
||||
var expectedTime = new Date(2013, 3, 2, 5, 0, 0).getTime();
|
||||
sandbox.useFakeTimers(fakeCurrentTime);
|
||||
|
||||
scope.openDayStartModal(5);
|
||||
|
||||
expect(scope.nextCron).to.eq(expectedTime);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#saveDayStart', function () {
|
||||
it('updates user\'s custom day start', function () {
|
||||
scope.dayStart = 5;
|
||||
scope.saveDayStart();
|
||||
|
||||
expect(User.setCustomDayStart).to.be.calledWith(5);
|
||||
});
|
||||
});
|
||||
|
||||
context('Player Reroll', function () {
|
||||
describe('#reroll', function () {
|
||||
beforeEach(function () {
|
||||
scope.clickReroll(actionClickEvent);
|
||||
});
|
||||
|
||||
it('destroys the previous popover if it exists', function () {
|
||||
sandbox.spy($.fn, 'popover');
|
||||
|
||||
scope.reroll(false);
|
||||
|
||||
expect(scope.popoverEl).to.exist;
|
||||
expect($.fn.popover).to.be.calledWith('destroy');
|
||||
});
|
||||
|
||||
it('doesn\'t call reroll when not confirmed', function () {
|
||||
scope.reroll(false);
|
||||
|
||||
expect(user.ops.reroll).to.not.be.calledOnce;
|
||||
});
|
||||
|
||||
it('calls reroll on the user when confirmed', function () {
|
||||
sandbox.stub(rootScope.$state, 'go');
|
||||
|
||||
scope.reroll(true);
|
||||
|
||||
expect(User.reroll).to.be.calledWith({});
|
||||
});
|
||||
|
||||
it('navigates to the tasks page when confirmed', function () {
|
||||
sandbox.stub(rootScope.$state, 'go');
|
||||
|
||||
scope.reroll(true);
|
||||
|
||||
expect(rootScope.$state.go).to.be.calledWith('tasks');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clickReroll', function () {
|
||||
it('displays a confirmation popover for the user', function () {
|
||||
sandbox.spy($.fn, 'popover');
|
||||
|
||||
scope.clickReroll(actionClickEvent);
|
||||
|
||||
expect($.fn.popover).to.be.calledWith('destroy');
|
||||
expect($.fn.popover).to.be.calledWith('show');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Player Rebirth', function () {
|
||||
describe('#rebirth', function () {
|
||||
beforeEach(function () {
|
||||
scope.clickRebirth(actionClickEvent);
|
||||
});
|
||||
|
||||
it('destroys the previous popover if it exists', function () {
|
||||
sandbox.spy($.fn, 'popover');
|
||||
|
||||
scope.rebirth(false);
|
||||
|
||||
expect(scope.popoverEl).to.exist;
|
||||
expect($.fn.popover).to.be.calledWith('destroy');
|
||||
});
|
||||
|
||||
it('doesn\'t call rebirth when not confirmed', function () {
|
||||
scope.rebirth(false);
|
||||
|
||||
expect(user.ops.rebirth).to.not.be.calledOnce;
|
||||
});
|
||||
|
||||
it('calls rebirth on the user when confirmed', function () {
|
||||
sandbox.stub(rootScope.$state, 'go');
|
||||
|
||||
scope.rebirth(true);
|
||||
|
||||
expect(User.rebirth).to.be.calledWith({});
|
||||
});
|
||||
|
||||
it('navigates to tasks page when confirmed', function () {
|
||||
sandbox.stub(rootScope.$state, 'go');
|
||||
|
||||
scope.rebirth(true);
|
||||
|
||||
expect(rootScope.$state.go).to.be.calledWith('tasks');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clickRebirth', function () {
|
||||
it('displays a confirmation popover for the user', function () {
|
||||
sandbox.spy($.fn, 'popover');
|
||||
|
||||
scope.clickRebirth(actionClickEvent);
|
||||
|
||||
expect($.fn.popover).to.be.calledWith('destroy');
|
||||
expect($.fn.popover).to.be.calledWith('show');
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
context('Releasing pets and mounts', function () {
|
||||
describe('#release', function () {
|
||||
beforeEach(function () {
|
||||
scope.clickRelease('dummy', actionClickEvent);
|
||||
|
||||
sandbox.stub(rootScope.$state, 'go');
|
||||
});
|
||||
|
||||
it('destroys the previous popover if it exists', function () {
|
||||
sandbox.spy($.fn, 'popover');
|
||||
|
||||
scope.releaseAnimals('', false);
|
||||
|
||||
expect($.fn.popover).to.be.calledWith('destroy');
|
||||
});
|
||||
|
||||
it('doesn\'t call any release method if type is not provided', function () {
|
||||
scope.releaseAnimals();
|
||||
|
||||
expect(User.releasePets).to.not.be.called;
|
||||
expect(User.releaseMounts).to.not.be.called;
|
||||
expect(User.releaseBoth).to.not.be.called;
|
||||
});
|
||||
|
||||
it('doesn\'t redirect to tasks page if type is not provided', function () {
|
||||
scope.releaseAnimals();
|
||||
|
||||
expect(rootScope.$state.go).to.not.be.called;
|
||||
})
|
||||
|
||||
it('calls releasePets when "pets" is provided', function () {
|
||||
scope.releaseAnimals('pets');
|
||||
|
||||
expect(User.releasePets).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('navigates to the tasks page when "pets" is provided', function () {
|
||||
scope.releaseAnimals('pets');
|
||||
|
||||
expect(rootScope.$state.go).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('calls releaseMounts when "mounts" is provided', function () {
|
||||
scope.releaseAnimals('mounts');
|
||||
|
||||
expect(User.releaseMounts).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('navigates to the tasks page when "mounts" is provided', function () {
|
||||
scope.releaseAnimals('mounts');
|
||||
|
||||
expect(rootScope.$state.go).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('calls releaseBoth when "both" is provided', function () {
|
||||
scope.releaseAnimals('both');
|
||||
|
||||
expect(User.releaseBoth).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('navigates to the tasks page when "both" is provided', function () {
|
||||
scope.releaseAnimals('both');
|
||||
|
||||
expect(rootScope.$state.go).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('does not call release functions when non-applicable argument is passed in', function () {
|
||||
scope.releaseAnimals('dummy');
|
||||
|
||||
expect(User.releasePets).to.not.be.called;
|
||||
expect(User.releaseMounts).to.not.be.called;
|
||||
expect(User.releaseBoth).to.not.be.called;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clickRelease', function () {
|
||||
it('displays a confirmation popover for the user', function () {
|
||||
sandbox.spy($.fn, 'popover');
|
||||
scope.clickRelease('dummy', actionClickEvent);
|
||||
|
||||
expect($.fn.popover).to.be.calledWith('destroy');
|
||||
expect($.fn.popover).to.be.called;
|
||||
expect($.fn.popover).to.be.calledWith('show');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Validating coupons', function () {
|
||||
describe('#applyCoupon', function () {
|
||||
it('displays an error when an invalid coupon is applied', function () {
|
||||
$httpBackend
|
||||
.whenPOST('/api/v3/coupons/validate/INVALID_COUPON?userV=undefined')
|
||||
.respond(200, {
|
||||
success: true,
|
||||
data: {
|
||||
valid: false
|
||||
},
|
||||
notifications: [],
|
||||
userV: 'undefined'
|
||||
});
|
||||
|
||||
scope.applyCoupon('INVALID_COUPON');
|
||||
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(Notification.error).to.be.called;
|
||||
expect(Notification.error).to.be.calledWith(env.t('invalidCoupon'), true);
|
||||
});
|
||||
|
||||
it('displays an confirmation when a valid coupon is applied', function () {
|
||||
$httpBackend
|
||||
.whenPOST('/api/v3/coupons/validate/VALID_COUPON?userV=undefined')
|
||||
.respond(200, {
|
||||
success: true,
|
||||
data: {
|
||||
valid: true
|
||||
},
|
||||
notifications: [],
|
||||
userV: 'undefined'
|
||||
});
|
||||
|
||||
scope.applyCoupon('VALID_COUPON');
|
||||
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(Notification.error).to.not.be.called;
|
||||
expect(Notification.text).to.be.calledWith('Coupon applied!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Fixing character values', function () {
|
||||
describe('#restore', function () {
|
||||
var blankRestoreValues = {
|
||||
stats: {
|
||||
hp: 0,
|
||||
exp: 0,
|
||||
gp: 0,
|
||||
lvl: 0,
|
||||
mp: 0,
|
||||
},
|
||||
achievements: {
|
||||
streak: 0,
|
||||
},
|
||||
};
|
||||
|
||||
it('doesn\'t update character values when level is less than 1', function () {
|
||||
scope.restoreValues = blankRestoreValues;
|
||||
scope.restore();
|
||||
expect(User.set).to.not.be.called;
|
||||
});
|
||||
|
||||
it('updates character values when level is at least 1', function () {
|
||||
scope.restoreValues = blankRestoreValues;
|
||||
scope.restoreValues.stats.lvl = 1;
|
||||
scope.restore();
|
||||
expect(User.set).to.be.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
describe('Sortable Inventory Controller', () => {
|
||||
let scope;
|
||||
|
||||
beforeEach(inject(($rootScope, $controller) => {
|
||||
scope = $rootScope.$new();
|
||||
$controller('SortableInventoryController', {$scope: scope});
|
||||
}));
|
||||
|
||||
it('defaults scope.order to set', () => {
|
||||
expect(scope.order).to.eql('set')
|
||||
});
|
||||
|
||||
describe('#setOrder', () => {
|
||||
it('sets sort criteria for all standard attributes', () =>{
|
||||
let oldOrder = scope.order;
|
||||
|
||||
let attrs = [
|
||||
'constitution',
|
||||
'intelligence',
|
||||
'perception',
|
||||
'strength',
|
||||
'set'
|
||||
];
|
||||
|
||||
attrs.forEach((attribute) => {
|
||||
scope.setOrder(attribute);
|
||||
expect(scope.order).to.exist;
|
||||
expect(scope.order).to.not.eql(oldOrder);
|
||||
oldOrder = scope.order;
|
||||
});
|
||||
});
|
||||
|
||||
it('does nothing when missing sort criteria', () =>{
|
||||
scope.order = null;
|
||||
|
||||
scope.setOrder('foooo');
|
||||
|
||||
expect(scope.order).to.not.exist;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,76 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Tasks Controller', function() {
|
||||
var $rootScope, shared, scope, user, User, ctrl;
|
||||
|
||||
beforeEach(function() {
|
||||
user = specHelper.newUser();
|
||||
User = {
|
||||
user: user
|
||||
};
|
||||
|
||||
User.deleteTask = sandbox.stub();
|
||||
User.user.ops = {
|
||||
deleteTask: sandbox.stub(),
|
||||
};
|
||||
module(function($provide) {
|
||||
$provide.value('User', User);
|
||||
$provide.value('Guide', {});
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, Shared){
|
||||
|
||||
scope = $rootScope.$new();
|
||||
shared = Shared;
|
||||
$controller('RootCtrl', {$scope: scope, User: User});
|
||||
|
||||
ctrl = $controller('TasksCtrl', {$scope: scope, User: User});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('editTask', function() {
|
||||
it('is Tasks.editTask', function() {
|
||||
inject(function(Tasks) {
|
||||
// @TODO: Currently we override the task function in the challenge ctrl, but we should abstract it again
|
||||
// expect(scope.editTask).to.eql(Tasks.editTask);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeTask', function() {
|
||||
var task;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(window, 'confirm');
|
||||
task = specHelper.newTodo();
|
||||
});
|
||||
|
||||
it('asks user to confirm deletion', function() {
|
||||
scope.removeTask(task);
|
||||
expect(window.confirm).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('does not remove task if not confirmed', function() {
|
||||
window.confirm.returns(false);
|
||||
scope.removeTask(task);
|
||||
expect(User.deleteTask).to.not.be.called;
|
||||
});
|
||||
|
||||
it('removes task', function() {
|
||||
window.confirm.returns(true);
|
||||
scope.removeTask(task);
|
||||
expect(User.deleteTask).to.be.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
describe('watch to updateStore', function() {
|
||||
it('updates itemStore when user gear changes', function() {
|
||||
sinon.stub(shared, 'updateStore').returns({item: true});
|
||||
user.items.gear.owned.foo = true;
|
||||
|
||||
scope.$digest();
|
||||
expect(scope.itemStore).to.eql({item: true});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('User Controller', function() {
|
||||
var $rootScope, $window, User, shared, scope, ctrl, content;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function ($provide) {
|
||||
var user = specHelper.newUser();
|
||||
User = {user: user}
|
||||
$provide.value('Guide', sandbox.stub());
|
||||
$provide.value('User', User);
|
||||
$provide.value('Achievement', sandbox.stub());
|
||||
$provide.value('Social', sandbox.stub());
|
||||
$provide.value('Shared', {
|
||||
achievements: {
|
||||
getAchievementsForProfile: sandbox.stub()
|
||||
},
|
||||
shops: {
|
||||
getBackgroundShopSets: sandbox.stub()
|
||||
}
|
||||
});
|
||||
$provide.value('Content', {
|
||||
loginIncentives: sandbox.stub()
|
||||
})
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, User, Content) {
|
||||
scope = $rootScope.$new();
|
||||
content = Content;
|
||||
$controller('RootCtrl', { $scope: scope, User: User});
|
||||
ctrl = $controller('UserCtrl', { $scope: scope, User: User, $window: $window});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getProgressDisplay', function() {
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox.stub(window.env, 't');
|
||||
window.env.t.onFirstCall().returns('Progress until next');
|
||||
});
|
||||
|
||||
it('should return initial progress', function() {
|
||||
scope.profile.loginIncentives = 0;
|
||||
content.loginIncentives = [{
|
||||
nextRewardAt: 1,
|
||||
reward: true
|
||||
}];
|
||||
var actual = scope.getProgressDisplay();
|
||||
expect(actual.trim()).to.eql('Progress until next 0/1');
|
||||
});
|
||||
|
||||
it('should return progress between next reward and current reward', function() {
|
||||
scope.profile.loginIncentives = 1;
|
||||
content.loginIncentives = [{
|
||||
nextRewardAt: 1,
|
||||
reward: true
|
||||
}, {
|
||||
prevRewardAt: 0,
|
||||
nextRewardAt: 2,
|
||||
reward: true
|
||||
}, {
|
||||
prevRewardAt: 1,
|
||||
nextRewardAt: 3
|
||||
}];
|
||||
var actual = scope.getProgressDisplay();
|
||||
expect(actual.trim()).to.eql('Progress until next 0/1');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,30 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('focusElement Directive', function() {
|
||||
var elementToFocus, scope;
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
scope = $rootScope.$new();
|
||||
|
||||
scope.focusThisLink = false;
|
||||
var element = '<input data-focus-element="focusThisLink" />';
|
||||
|
||||
elementToFocus = $compile(element)(scope);
|
||||
scope.$digest();
|
||||
}));
|
||||
|
||||
it('places focus on the element it is applied to when the expression it binds to evaluates to true', inject(function($timeout) {
|
||||
var focusSpy = sandbox.spy();
|
||||
|
||||
elementToFocus.appendTo(document.body);
|
||||
elementToFocus.on('focus', focusSpy);
|
||||
scope.focusThisLink = true;
|
||||
scope.$digest();
|
||||
|
||||
$timeout.flush();
|
||||
expect(document.activeElement.dataset.focusElement).to.eql("focusThisLink");
|
||||
expect(focusSpy).to.have.been.called;
|
||||
}));
|
||||
});
|
||||
@@ -1,89 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('fromNow Directive', function() {
|
||||
var element, scope;
|
||||
var fromNow = 'recently';
|
||||
var diff = 0;
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
scope = $rootScope.$new();
|
||||
scope.message = {};
|
||||
|
||||
sandbox.stub(window, 'moment').returns({
|
||||
fromNow: function() { return fromNow },
|
||||
diff: function() { return diff }
|
||||
});
|
||||
|
||||
element = "<p from-now></p>";
|
||||
|
||||
element = $compile(element)(scope);
|
||||
scope.$digest();
|
||||
}));
|
||||
|
||||
afterEach(function() {
|
||||
window.moment.restore();
|
||||
});
|
||||
|
||||
it('sets the element text to the elapsed time', function() {
|
||||
expect(element.text()).to.eql('recently');
|
||||
});
|
||||
|
||||
describe('when the elapsed time is less than an hour', function() {
|
||||
beforeEach(inject(function($compile) {
|
||||
fromNow = 'recently';
|
||||
diff = 0;
|
||||
|
||||
element = $compile('<p from-now></p>')(scope);
|
||||
scope.$digest();
|
||||
}));
|
||||
|
||||
it('updates the elapsed time every minute', inject(function($interval) {
|
||||
fromNow = 'later';
|
||||
|
||||
expect(element.text()).to.eql('recently');
|
||||
$interval.flush(60001);
|
||||
|
||||
expect(element.text()).to.eql('later');
|
||||
}));
|
||||
|
||||
it('moves to hourly updates after an hour', inject(function($timeout, $interval) {
|
||||
diff = 61;
|
||||
|
||||
$timeout.flush();
|
||||
$interval.flush(60001);
|
||||
|
||||
fromNow = 'later';
|
||||
|
||||
$interval.flush(60001);
|
||||
expect(element.text()).to.eql('recently');
|
||||
|
||||
$interval.flush(3600000);
|
||||
expect(element.text()).to.eql('later');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('when the elapsed time is more than an hour', function() {
|
||||
beforeEach(inject(function($compile) {
|
||||
fromNow = 'recently';
|
||||
diff = 65;
|
||||
|
||||
element = $compile('<p from-now></p>')(scope);
|
||||
scope.$digest();
|
||||
}));
|
||||
|
||||
it('updates the elapsed time every hour', inject(function($interval) {
|
||||
fromNow = 'later';
|
||||
|
||||
expect(element.text()).to.eql('recently');
|
||||
|
||||
$interval.flush(60001);
|
||||
expect(element.text()).to.eql('recently');
|
||||
|
||||
$interval.flush(3600000);
|
||||
expect(element.text()).to.eql('later');
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
describe('task Directive', () => {
|
||||
var compile, scope, directiveElem, $modal;
|
||||
|
||||
beforeEach(function(){
|
||||
module(function($provide) {
|
||||
$modal = {
|
||||
open: sandbox.spy(),
|
||||
};
|
||||
$provide.value('$modal', $modal);
|
||||
});
|
||||
|
||||
inject(function($compile, $rootScope, $templateCache) {
|
||||
compile = $compile;
|
||||
scope = $rootScope.$new();
|
||||
|
||||
$templateCache.put('templates/task.html', '<div>Task</div>');
|
||||
});
|
||||
|
||||
|
||||
directiveElem = getCompiledElement();
|
||||
});
|
||||
|
||||
function getCompiledElement(){
|
||||
var element = angular.element('<task></task>');
|
||||
var compiledElement = compile(element)(scope);
|
||||
scope.$digest();
|
||||
return compiledElement;
|
||||
}
|
||||
|
||||
xit('opens task note modal', () => {
|
||||
scope.showNoteDetails();
|
||||
|
||||
expect($modal.open).to.be.calledOnce;
|
||||
});
|
||||
})
|
||||
@@ -1,33 +0,0 @@
|
||||
describe('roundLargeNumbers', function() {
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
it('returns same number if less than 1000', inject(function(roundLargeNumbersFilter) {
|
||||
for(var num = 0; num < 1000; num++) {
|
||||
expect(roundLargeNumbersFilter(num)).to.eql(num);
|
||||
};
|
||||
}));
|
||||
|
||||
it('truncates number and appends "k" if number is 1000-999999', inject(function(roundLargeNumbersFilter) {
|
||||
expect(roundLargeNumbersFilter(999.01)).to.eql("1.0k");
|
||||
expect(roundLargeNumbersFilter(1000)).to.eql("1.0k");
|
||||
expect(roundLargeNumbersFilter(3284.12)).to.eql("3.3k");
|
||||
expect(roundLargeNumbersFilter(52983.99)).to.eql("53.0k");
|
||||
expect(roundLargeNumbersFilter(452983.99)).to.eql("453.0k");
|
||||
expect(roundLargeNumbersFilter(999999)).to.eql("1000.0k");
|
||||
}));
|
||||
|
||||
it('truncates number and appends "m" if number is 1000000-999999999', inject(function(roundLargeNumbersFilter) {
|
||||
expect(roundLargeNumbersFilter(999999.01)).to.eql("1.0m");
|
||||
expect(roundLargeNumbersFilter(1000000)).to.eql("1.0m");
|
||||
expect(roundLargeNumbersFilter(3284124.12)).to.eql("3.3m");
|
||||
expect(roundLargeNumbersFilter(52983105.99)).to.eql("53.0m");
|
||||
expect(roundLargeNumbersFilter(452983410.99)).to.eql("453.0m");
|
||||
expect(roundLargeNumbersFilter(999999999)).to.eql("1000.0m");
|
||||
}));
|
||||
|
||||
it('truncates number and appends b" if number is greater than 999999999', inject(function(roundLargeNumbersFilter) {
|
||||
expect(roundLargeNumbersFilter(999999999.01)).to.eql("1.0b");
|
||||
expect(roundLargeNumbersFilter(1423985738.54)).to.eql("1.4b");
|
||||
}));
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
describe('filter', function() {
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
describe('gold', function() {
|
||||
it('rounds down decimal values', inject(function(goldFilter) {
|
||||
expect(goldFilter(10)).to.eql(10);
|
||||
expect(goldFilter(10.0)).to.eql(10);
|
||||
expect(goldFilter(10.1)).to.eql(10);
|
||||
expect(goldFilter(10.2)).to.eql(10);
|
||||
expect(goldFilter(10.3)).to.eql(10);
|
||||
expect(goldFilter(10.4)).to.eql(10);
|
||||
expect(goldFilter(10.5)).to.eql(10);
|
||||
expect(goldFilter(10.6)).to.eql(10);
|
||||
expect(goldFilter(10.7)).to.eql(10);
|
||||
expect(goldFilter(10.8)).to.eql(10);
|
||||
expect(goldFilter(10.9)).to.eql(10);
|
||||
expect(goldFilter(11)).to.eql(11);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('silver', function() {
|
||||
it('converts decimal value of gold to silver', inject(function(silverFilter) {
|
||||
expect(silverFilter(10)).to.be.closeTo(0, 1);
|
||||
expect(silverFilter(10.01)).to.be.closeTo(1, 1);
|
||||
expect(silverFilter(10.05)).to.be.closeTo(5, 1);
|
||||
expect(silverFilter(10.17)).to.be.closeTo(17, 1);
|
||||
expect(silverFilter(10.23)).to.be.closeTo(23, 1);
|
||||
expect(silverFilter(10.25)).to.be.closeTo(25, 1);
|
||||
expect(silverFilter(10.53)).to.be.closeTo(53, 1);
|
||||
expect(silverFilter(10.75)).to.be.closeTo(75, 1);
|
||||
expect(silverFilter(10.99)).to.be.closeTo(99, 1);
|
||||
}));
|
||||
});
|
||||
});
|
||||
@@ -1,94 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Task Ordering Filters', function() {
|
||||
var filter, orderBySpy;
|
||||
|
||||
beforeEach(function() {
|
||||
orderBySpy = sandbox.spy();
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('orderByFilter', orderBySpy);
|
||||
});
|
||||
inject(function($rootScope, $filter) {
|
||||
filter = $filter;
|
||||
});
|
||||
});
|
||||
|
||||
describe('conditionalOrderBy', function() {
|
||||
describe('when the predicate is true', function() {
|
||||
it('delegates the arguments to the orderBy filter', function() {
|
||||
filter('conditionalOrderBy')('array', true, 'sortPredicate', 'reverseOrder');
|
||||
expect(orderBySpy).to.have.been.calledWith('array','sortPredicate','reverseOrder');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the predicate is false', function() {
|
||||
it('returns the initial array', function() {
|
||||
expect(filter('conditionalOrderBy')([1,2,3], false)).to.eql([1,2,3]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterByTaskInfo', function () {
|
||||
it('returns undefined when no input given', function () {
|
||||
expect(filter('filterByTaskInfo')()).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('returns all tasks if term is not a string', function () {
|
||||
var tasks = [1, 2, 3];
|
||||
expect(filter('filterByTaskInfo')(tasks, undefined)).to.eql(tasks);
|
||||
expect(filter('filterByTaskInfo')(tasks, [])).to.eql(tasks);
|
||||
expect(filter('filterByTaskInfo')(tasks, new Date())).to.eql(tasks);
|
||||
});
|
||||
|
||||
it('returns tasks if term is an empty string', function () {
|
||||
var tasks = [1, 2, 3];
|
||||
expect(filter('filterByTaskInfo')(tasks, '')).to.eql(tasks);
|
||||
});
|
||||
|
||||
it('filters items by text', function () {
|
||||
var tasks = [
|
||||
{ text: 'foo' },
|
||||
{ text: 'some text that contains foo' },
|
||||
{ text: 'some text that should not be matched' }
|
||||
];
|
||||
|
||||
expect(filter('filterByTaskInfo')(tasks, 'foo')).to.eql([tasks[0], tasks[1]]);
|
||||
});
|
||||
|
||||
it('filters items by notes', function () {
|
||||
var tasks = [
|
||||
{ text: 'some text', notes: 'foo' },
|
||||
{ text: 'some text', notes: 'a note that contains foo' },
|
||||
{ text: 'some text', notes: 'some text' },
|
||||
{ text: 'some text' }
|
||||
];
|
||||
|
||||
expect(filter('filterByTaskInfo')(tasks, 'foo')).to.eql([tasks[0], tasks[1]]);
|
||||
});
|
||||
|
||||
it('filters items by checklists', function () {
|
||||
var tasks = [
|
||||
{ text: 'foo' },
|
||||
{ text: 'foo', notes: 'bar', checklist: [ {text: "checkListToFind"} ] },
|
||||
{ text: 'foo', notes: 'bar', checklist: [ {text: "checkListToNotFind"} ] }
|
||||
];
|
||||
|
||||
expect(filter('filterByTaskInfo')(tasks, 'checkListToFind')).to.eql([tasks[1]]);
|
||||
});
|
||||
|
||||
it('only includes task once, even with multiple matches in checklist', function() {
|
||||
var tasks = [
|
||||
{
|
||||
text: 'foo', notes: 'bar', checklist: [
|
||||
{text: "checkListToFind"},
|
||||
{text: "checkListToFind"},
|
||||
{text: "checkListToFind"}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
expect(filter('filterByTaskInfo')(tasks, 'checkListToFind')).to.eql([tasks[0]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
describe('timezoneOffsetToUtc', function() {
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
it('formats the timezone offset with a - sign if the offset is positive', inject(function(timezoneOffsetToUtcFilter) {
|
||||
expect(timezoneOffsetToUtcFilter(90)).to.eql('UTC-1:30');
|
||||
}));
|
||||
|
||||
it('formats the timezone offset with a + sign if the offset is negative', inject(function(timezoneOffsetToUtcFilter) {
|
||||
expect(timezoneOffsetToUtcFilter(-525)).to.eql('UTC+8:45');
|
||||
}));
|
||||
|
||||
it('prepends the minutes with a 0 if the minute the offset is less than 10', inject(function(timezoneOffsetToUtcFilter) {
|
||||
expect(timezoneOffsetToUtcFilter(60)).to.eql('UTC-1:00');
|
||||
}));
|
||||
|
||||
it('returns the string UTC+0:00 if the offset is 0', inject(function(timezoneOffsetToUtcFilter) {
|
||||
expect(timezoneOffsetToUtcFilter(0)).to.eql('UTC+0:00');
|
||||
}));
|
||||
});
|
||||
@@ -1,98 +0,0 @@
|
||||
// Karma configuration
|
||||
// http://karma-runner.github.io/0.10/config/configuration-file.html
|
||||
|
||||
module.exports = function karmaConfig (config) {
|
||||
config.set({
|
||||
// base path, that will be used to resolve files and exclude
|
||||
basePath: '',
|
||||
|
||||
// testing framework to use (jasmine/mocha/qunit/...)
|
||||
frameworks: ['mocha', 'chai', 'chai-as-promised', 'sinon-chai'],
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'../../../website/client-old/bower_components/jquery/dist/jquery.js',
|
||||
'../../../website/client-old/bower_components/pnotify/jquery.pnotify.js',
|
||||
'../../../website/client-old/bower_components/angular/angular.js',
|
||||
'../../../website/client-old/bower_components/angular-loading-bar/build/loading-bar.min.js',
|
||||
'../../../website/client-old/bower_components/angular-resource/angular-resource.min.js',
|
||||
'../../../website/client-old/bower_components/hello/dist/hello.all.min.js',
|
||||
'../../../website/client-old/bower_components/angular-sanitize/angular-sanitize.js',
|
||||
'../../../website/client-old/bower_components/bootstrap/dist/js/bootstrap.js',
|
||||
'../../../website/client-old/bower_components/angular-bootstrap/ui-bootstrap.js',
|
||||
'../../../website/client-old/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
|
||||
'../../../website/client-old/bower_components/angular-ui-router/release/angular-ui-router.js',
|
||||
'../../../website/client-old/bower_components/angular-filter/dist/angular-filter.js',
|
||||
'../../../website/client-old/bower_components/angular-ui/build/angular-ui.js',
|
||||
'../../../website/client-old/bower_components/angular-ui-utils/ui-utils.min.js',
|
||||
'../../../website/client-old/bower_components/Angular-At-Directive/src/at.js',
|
||||
'../../../website/client-old/bower_components/Angular-At-Directive/src/caret.js',
|
||||
'../../../website/client-old/bower_components/angular-mocks/angular-mocks.js',
|
||||
'../../../website/client-old/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js',
|
||||
'../../../website/client-old/bower_components/select2/select2.js',
|
||||
'../../../website/client-old/bower_components/angular-ui-select2/src/select2.js',
|
||||
'../../../website/client-old/bower_components/habitica-markdown/dist/habitica-markdown.min.js',
|
||||
'../../../website/client-old/js/habitrpg-shared.js',
|
||||
|
||||
'../../../test/client-old/spec/mocks/**/*.js',
|
||||
|
||||
'../../../website/client-old/js/env.js',
|
||||
'../../../website/client-old/js/app.js',
|
||||
'../../../website/client-old/js/config.js',
|
||||
|
||||
'../../../website/client-old/js/services/**/*.js',
|
||||
'../../../website/client-old/js/filters/**/*.js',
|
||||
'../../../website/client-old/js/directives/**/*.js',
|
||||
'../../../website/client-old/js/controllers/**/*.js',
|
||||
'../../../website/client-old/js/components/**/*.js',
|
||||
|
||||
'../../../test/client-old/spec/specHelper.js',
|
||||
'../../../test/client-old/spec/**/*.js',
|
||||
],
|
||||
|
||||
// list of files / patterns to exclude
|
||||
exclude: [],
|
||||
|
||||
// web server port
|
||||
port: 8080,
|
||||
|
||||
// level of logging
|
||||
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
|
||||
// Start these browsers, currently available:
|
||||
// - Chrome
|
||||
// - ChromeCanary
|
||||
// - Firefox
|
||||
// - Opera
|
||||
// - Safari (only Mac)
|
||||
// - PhantomJS
|
||||
// - IE (only Windows)
|
||||
browsers: ['PhantomJS'],
|
||||
|
||||
preprocessors: {
|
||||
'../../../website/client-old/js/**/*.js': ['coverage'],
|
||||
'../../../test/**/*.js': ['babel'],
|
||||
},
|
||||
|
||||
coverageReporter: {
|
||||
reporters: [
|
||||
{ type: 'lcov', subdir: '.' },
|
||||
{ type: 'text-summary' },
|
||||
],
|
||||
dir: '../../../coverage/karma',
|
||||
},
|
||||
|
||||
// Enable mocha-style reporting, for better test visibility
|
||||
reporters: ['mocha', 'coverage'],
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, it capture browsers, run tests and exit
|
||||
singleRun: false,
|
||||
});
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
var sandbox = sinon.sandbox.create();
|
||||
|
||||
afterEach(function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
var analyticsMock = {
|
||||
login: sandbox.spy(),
|
||||
register: sandbox.spy(),
|
||||
updateUser: sandbox.spy(),
|
||||
track: sandbox.spy()
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('achievementServices', function() {
|
||||
var achievementService, rootScope;
|
||||
|
||||
beforeEach(function() {
|
||||
rootScope = { 'openModal': sandbox.stub() };
|
||||
module(function($provide) {
|
||||
$provide.value('$rootScope', rootScope);
|
||||
});
|
||||
|
||||
inject(function(Achievement) {
|
||||
achievementService = Achievement;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#displayAchievement', function() {
|
||||
it('passes given achievement name to openModal', function() {
|
||||
achievementService.displayAchievement('beastMaster');
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith('achievements/beastMaster');
|
||||
});
|
||||
|
||||
it('calls openModal with UserCtrl and small modal size if no other size is given', function() {
|
||||
achievementService.displayAchievement('test');
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith(
|
||||
'achievements/test',
|
||||
{ controller: 'UserCtrl', size: 'sm' }
|
||||
);
|
||||
});
|
||||
|
||||
it('calls openModal with UserCtrl and specified modal size if one is given', function() {
|
||||
achievementService.displayAchievement('test', {size: 'md'});
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith(
|
||||
'achievements/test',
|
||||
{ controller: 'UserCtrl', size: 'md' }
|
||||
);
|
||||
});
|
||||
|
||||
it('calls openModal with UserCtrl and default \'sm\' size if invalid size is given', function() {
|
||||
achievementService.displayAchievement('test', {size: 'INVALID_SIZE'});
|
||||
|
||||
expect(rootScope.openModal).to.be.calledOnce;
|
||||
expect(rootScope.openModal).to.be.calledWith(
|
||||
'achievements/test',
|
||||
{ controller: 'UserCtrl', size: 'sm' }
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,282 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Analytics Service', function () {
|
||||
var analytics, user, clock;
|
||||
|
||||
beforeEach(function() {
|
||||
clock = sandbox.useFakeTimers();
|
||||
sandbox.stub(window, 'refresher', function(){return true});
|
||||
user = specHelper.newUser({
|
||||
contributor: {},
|
||||
purchased: { plan: {} },
|
||||
});
|
||||
user.flags.tour = { intro: null };
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('User', {user: user});
|
||||
});
|
||||
|
||||
inject(function(Analytics) {
|
||||
analytics = Analytics;
|
||||
});
|
||||
});
|
||||
|
||||
context('functions', function() {
|
||||
|
||||
describe('register', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(amplitude, 'setUserId');
|
||||
sandbox.stub(window, 'ga');
|
||||
});
|
||||
|
||||
it('sets up user with Amplitude', function() {
|
||||
analytics.register();
|
||||
clock.tick();
|
||||
expect(amplitude.setUserId).to.have.been.calledOnce;
|
||||
expect(amplitude.setUserId).to.have.been.calledWith(user._id);
|
||||
});
|
||||
|
||||
it('sets up user with Google Analytics', function() {
|
||||
analytics.register();
|
||||
clock.tick();
|
||||
expect(ga).to.have.been.calledOnce;
|
||||
expect(ga).to.have.been.calledWith('set', {userId: user._id});
|
||||
});
|
||||
});
|
||||
|
||||
describe('login', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(amplitude, 'setUserId');
|
||||
sandbox.stub(window, 'ga');
|
||||
});
|
||||
|
||||
it('sets up tracking for amplitude', function() {
|
||||
analytics.login();
|
||||
clock.tick();
|
||||
|
||||
expect(amplitude.setUserId).to.have.been.calledOnce;
|
||||
expect(amplitude.setUserId).to.have.been.calledWith(user._id);
|
||||
});
|
||||
|
||||
it('sets up tracking for google analytics', function() {
|
||||
analytics.login();
|
||||
clock.tick();
|
||||
|
||||
expect(ga).to.have.been.calledOnce;
|
||||
expect(ga).to.have.been.calledWith('set', {userId: user._id});
|
||||
});
|
||||
});
|
||||
|
||||
describe('track', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(amplitude, 'logEvent');
|
||||
sandbox.stub(window, 'ga');
|
||||
});
|
||||
|
||||
context('successful tracking', function() {
|
||||
|
||||
it('tracks a simple user action with Amplitude', function() {
|
||||
var properties = {'hitType':'event','eventCategory':'behavior','eventAction':'cron'};
|
||||
analytics.track(properties);
|
||||
clock.tick();
|
||||
|
||||
expect(amplitude.logEvent).to.have.been.calledOnce;
|
||||
expect(amplitude.logEvent).to.have.been.calledWith('cron', properties);
|
||||
});
|
||||
|
||||
it('tracks a simple user action with Google Analytics', function() {
|
||||
var properties = {'hitType':'event','eventCategory':'behavior','eventAction':'cron'};
|
||||
analytics.track(properties);
|
||||
clock.tick();
|
||||
|
||||
expect(ga).to.have.been.calledOnce;
|
||||
expect(ga).to.have.been.calledWith('send', properties);
|
||||
});
|
||||
|
||||
it('tracks a user action with additional properties in Amplitude', function() {
|
||||
var properties = {'hitType':'event','eventCategory':'behavior','eventAction':'cron','booleanProperty':true,'numericProperty':17,'stringProperty':'bagel'};
|
||||
analytics.track(properties);
|
||||
clock.tick();
|
||||
|
||||
expect(amplitude.logEvent).to.have.been.calledOnce;
|
||||
expect(amplitude.logEvent).to.have.been.calledWith('cron', properties);
|
||||
});
|
||||
|
||||
it('tracks a user action with additional properties in google analytics', function() {
|
||||
var properties = {'hitType':'event','eventCategory':'behavior','eventAction':'cron','booleanProperty':true,'numericProperty':17,'stringProperty':'bagel'};
|
||||
analytics.track(properties);
|
||||
clock.tick();
|
||||
|
||||
expect(ga).to.have.been.calledOnce;
|
||||
expect(ga).to.have.been.calledWith('send', properties);
|
||||
});
|
||||
});
|
||||
|
||||
context('unsuccessful tracking', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(console, 'log');
|
||||
});
|
||||
|
||||
context('events without required properties', function() {
|
||||
beforeEach(function(){
|
||||
analytics.track('action');
|
||||
analytics.track({'hitType':'pageview','eventCategory':'green'});
|
||||
analytics.track({'hitType':'pageview','eventAction':'eat'});
|
||||
analytics.track({'eventCategory':'green','eventAction':'eat'});
|
||||
analytics.track({'hitType':'pageview'});
|
||||
analytics.track({'eventCategory':'green'});
|
||||
analytics.track({'eventAction':'eat'});
|
||||
clock.tick();
|
||||
});
|
||||
|
||||
it('logs errors to console', function() {
|
||||
expect(console.log.callCount).to.eql(7);
|
||||
});
|
||||
|
||||
it('does not call out to Amplitude', function() {
|
||||
expect(amplitude.logEvent).to.not.be.called;
|
||||
});
|
||||
|
||||
it('does not call out to Google Analytics', function() {
|
||||
expect(ga).to.not.be.called;
|
||||
});
|
||||
});
|
||||
|
||||
context('incorrect hit type', function() {
|
||||
beforeEach(function() {
|
||||
analytics.track({'hitType':'moogly','eventCategory':'green','eventAction':'eat'});
|
||||
clock.tick();
|
||||
});
|
||||
|
||||
it('logs error to console', function () {
|
||||
expect(console.log).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('does not call out to Amplitude', function() {
|
||||
expect(amplitude.logEvent).to.not.be.called;
|
||||
});
|
||||
|
||||
it('does not call out to Google Analytics', function() {
|
||||
expect(ga).to.not.be.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateUser', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(amplitude, 'setUserProperties');
|
||||
sandbox.stub(window, 'ga');
|
||||
});
|
||||
|
||||
context('properties argument provided', function(){
|
||||
var properties = {'userBoolean': false, 'userNumber': -8, 'userString': 'Enlightened'};
|
||||
var expectedProperties = _.cloneDeep(properties);
|
||||
expectedProperties.UUID = 'unique-user-id';
|
||||
expectedProperties.Class = 'wizard';
|
||||
expectedProperties.Experience = 35;
|
||||
expectedProperties.Gold = 43;
|
||||
expectedProperties.Health = 48;
|
||||
expectedProperties.Level = 24;
|
||||
expectedProperties.Mana = 41;
|
||||
expectedProperties.tutorialComplete = false;
|
||||
expectedProperties["Number Of Tasks"] = {
|
||||
habits: 1,
|
||||
dailys: 1,
|
||||
todos: 1,
|
||||
rewards: 1
|
||||
};
|
||||
expectedProperties.balance = 12;
|
||||
expectedProperties.balanceGemAmount = 48;
|
||||
|
||||
beforeEach(function() {
|
||||
user._id = 'unique-user-id';
|
||||
user.stats.class = 'wizard';
|
||||
user.stats.exp = 35.7;
|
||||
user.stats.gp = 43.2;
|
||||
user.stats.hp = 47.8;
|
||||
user.stats.lvl = 24;
|
||||
user.stats.mp = 41;
|
||||
user.flags.tour.intro = 3;
|
||||
user.habits = [{_id: 'habit'}];
|
||||
user.dailys = [{_id: 'daily'}];
|
||||
user.todos = [{_id: 'todo'}];
|
||||
user.rewards = [{_id: 'reward'}];
|
||||
user.balance = 12;
|
||||
|
||||
analytics.updateUser(properties);
|
||||
clock.tick();
|
||||
});
|
||||
|
||||
it('calls Amplitude with provided properties and select user info', function() {
|
||||
expect(amplitude.setUserProperties).to.have.been.calledOnce;
|
||||
expect(amplitude.setUserProperties).to.have.been.calledWith(expectedProperties);
|
||||
});
|
||||
|
||||
it('calls Google Analytics with provided properties and select user info', function() {
|
||||
expect(ga).to.have.been.calledOnce;
|
||||
expect(ga).to.have.been.calledWith('set', expectedProperties);
|
||||
});
|
||||
});
|
||||
|
||||
context('no properties argument provided', function() {
|
||||
var expectedProperties = {
|
||||
UUID: 'unique-user-id',
|
||||
Class: 'wizard',
|
||||
Experience: 35,
|
||||
Gold: 43,
|
||||
Health: 48,
|
||||
Level: 24,
|
||||
Mana: 41,
|
||||
contributorLevel: 1,
|
||||
subscription: 'unique-plan-id',
|
||||
tutorialComplete: true,
|
||||
"Number Of Tasks": {
|
||||
todos: 1,
|
||||
dailys: 1,
|
||||
habits: 1,
|
||||
rewards: 1
|
||||
},
|
||||
balance: 12,
|
||||
balanceGemAmount: 48
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
user._id = 'unique-user-id';
|
||||
user.stats.class = 'wizard';
|
||||
user.stats.exp = 35.7;
|
||||
user.stats.gp = 43.2;
|
||||
user.stats.hp = 47.8;
|
||||
user.stats.lvl = 24;
|
||||
user.stats.mp = 41;
|
||||
user.contributor.level = 1;
|
||||
user.purchased.plan.planId = 'unique-plan-id';
|
||||
user.flags.tour.intro = -2;
|
||||
user.habits = [{_id: 'habit'}];
|
||||
user.dailys = [{_id: 'daily'}];
|
||||
user.todos = [{_id: 'todo'}];
|
||||
user.rewards = [{_id: 'reward'}];
|
||||
user.balance = 12;
|
||||
|
||||
analytics.updateUser();
|
||||
clock.tick();
|
||||
});
|
||||
|
||||
it('calls Amplitude with select user info', function() {
|
||||
expect(amplitude.setUserProperties).to.have.been.calledOnce;
|
||||
expect(amplitude.setUserProperties).to.have.been.calledWith(expectedProperties);
|
||||
});
|
||||
|
||||
it('calls Google Analytics with select user info', function() {
|
||||
expect(ga).to.have.been.calledOnce;
|
||||
expect(ga).to.have.been.calledWith('set', expectedProperties);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,88 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('challengeServices', function() {
|
||||
var $httpBackend, $http, challenges, user;
|
||||
var apiV3Prefix = '/api/v3';
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {user:user});
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, Challenges, User) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
challenges = Challenges;
|
||||
user = User;
|
||||
user.sync = function(){};
|
||||
});
|
||||
});
|
||||
|
||||
it('calls create challenge endpoint', function() {
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/challenges').respond({});
|
||||
challenges.createChallenge();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls join challenge endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/challenges/' + challengeId + '/join').respond({});
|
||||
challenges.joinChallenge(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls leave challenge endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/challenges/' + challengeId + '/leave').respond({});
|
||||
challenges.leaveChallenge(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get user challenges endpoint', function() {
|
||||
$httpBackend.expectGET(apiV3Prefix + '/challenges/user').respond({});
|
||||
challenges.getUserChallenges();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get group challenges endpoint', function() {
|
||||
var groupId = 1;
|
||||
$httpBackend.expectGET(apiV3Prefix + '/challenges/groups/' + groupId).respond({});
|
||||
challenges.getGroupChallenges(groupId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get challenge endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectGET(apiV3Prefix + '/challenges/' + challengeId).respond({});
|
||||
challenges.getChallenge(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls export challenge to csv endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectGET(apiV3Prefix + '/challenges/' + challengeId + '/export/csv').respond({});
|
||||
challenges.exportChallengeCsv(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls update challenge endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectPUT(apiV3Prefix + '/challenges/' + challengeId).respond({});
|
||||
challenges.updateChallenge(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls delete challenge endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectDELETE(apiV3Prefix + '/challenges/' + challengeId).respond({});
|
||||
challenges.deleteChallenge(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls select challenge winner endpoint', function() {
|
||||
var challengeId = 1;
|
||||
var winnerId = 2;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/challenges/' + challengeId + '/selectWinner/' + winnerId).respond({});
|
||||
challenges.selectChallengeWinner(challengeId, winnerId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
@@ -1,73 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('chatServices', function() {
|
||||
var $httpBackend, $http, chat, user;
|
||||
var apiV3Prefix = '/api/v3';
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {user:user});
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, Chat, User) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
chat = Chat;
|
||||
user = User;
|
||||
user.sync = function(){};
|
||||
});
|
||||
});
|
||||
|
||||
it('calls get chat endpoint', function() {
|
||||
var groupId = 1;
|
||||
$httpBackend.expectGET(apiV3Prefix + '/groups/' + groupId + '/chat').respond({});
|
||||
chat.getChat(groupId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get chat endpoint', function() {
|
||||
var groupId = 1;
|
||||
var message = "test message";
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/groups/' + groupId + '/chat').respond({});
|
||||
chat.postChat(groupId, message);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls delete chat endpoint', function() {
|
||||
var groupId = 1;
|
||||
var chatId = 2;
|
||||
$httpBackend.expectDELETE(apiV3Prefix + '/groups/' + groupId + '/chat/' + chatId).respond({});
|
||||
chat.deleteChat(groupId, chatId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls like chat endpoint', function() {
|
||||
var groupId = 1;
|
||||
var chatId = 2;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/groups/' + groupId + '/chat/' + chatId + '/like').respond({});
|
||||
chat.like(groupId, chatId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls flag chat endpoint', function() {
|
||||
var groupId = 1;
|
||||
var chatId = 2;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/groups/' + groupId + '/chat/' + chatId + '/flag').respond({});
|
||||
chat.flagChatMessage(groupId, chatId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls clearflags chat endpoint', function() {
|
||||
var groupId = 1;
|
||||
var chatId = 2;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/groups/' + groupId + '/chat/' + chatId + '/clearflags').respond({});
|
||||
chat.clearFlagCount(groupId, chatId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls chat seen endpoint', function() {
|
||||
var groupId = 1;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/groups/' + groupId + '/chat/seen').respond({});
|
||||
chat.markChatSeen(groupId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
@@ -1,200 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('groupServices', function() {
|
||||
var $httpBackend, $http, groups, user, $rootScope;
|
||||
var groupApiUrlPrefix = '/api/v3/groups';
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id"
|
||||
user.party._id = 'unique-party-id';
|
||||
user.sync = function(){};
|
||||
$provide.value('User', {user: user});
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, _$rootScope_, Groups, User) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$rootScope = _$rootScope_;
|
||||
$rootScope.openModal = function() {}
|
||||
groups = Groups;
|
||||
});
|
||||
});
|
||||
|
||||
it('calls get groups', function() {
|
||||
$httpBackend.expectGET(groupApiUrlPrefix).respond({});
|
||||
groups.Group.getGroups();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get group', function() {
|
||||
var gid = 1;
|
||||
$httpBackend.expectGET(groupApiUrlPrefix + '/' + gid).respond({});
|
||||
groups.Group.get(gid);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls party endpoint', function() {
|
||||
var groupId = '1234';
|
||||
var groupResponse = {data: {_id: groupId}};
|
||||
$httpBackend.expectGET(groupApiUrlPrefix + '/party').respond(groupResponse);
|
||||
$httpBackend.expectGET('/api/v3/groups/' + groupId + '/members?includeAllPublicFields=true').respond({});
|
||||
$httpBackend.expectGET('/api/v3/groups/' + groupId + '/invites').respond({});
|
||||
$httpBackend.expectGET('/api/v3/challenges/groups/' + groupId).respond({});
|
||||
groups.Group.syncParty();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls create endpoint', function() {
|
||||
$httpBackend.expectPOST(groupApiUrlPrefix).respond({});
|
||||
groups.Group.create({});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls update group', function() {
|
||||
var gid = 1;
|
||||
var groupDetails = { _id: gid };
|
||||
$httpBackend.expectPUT(groupApiUrlPrefix + '/' + gid).respond({});
|
||||
groups.Group.update(groupDetails);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls join group', function() {
|
||||
var gid = 1;
|
||||
$httpBackend.expectPOST(groupApiUrlPrefix + '/' + gid + '/join').respond({});
|
||||
groups.Group.join(gid);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls reject invite group', function() {
|
||||
var gid = 1;
|
||||
$httpBackend.expectPOST(groupApiUrlPrefix + '/' + gid + '/reject-invite').respond({});
|
||||
groups.Group.rejectInvite(gid);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls invite group', function() {
|
||||
var gid = 1;
|
||||
$httpBackend.expectPOST(groupApiUrlPrefix + '/' + gid + '/invite').respond({});
|
||||
groups.Group.invite(gid, [], []);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls party endpoint when party is not cached', function() {
|
||||
var groupId = '1234';
|
||||
var groupResponse = {data: {_id: groupId}};
|
||||
$httpBackend.expectGET(groupApiUrlPrefix + '/party').respond(groupResponse);
|
||||
$httpBackend.expectGET('/api/v3/groups/' + groupId + '/members?includeAllPublicFields=true').respond({});
|
||||
$httpBackend.expectGET('/api/v3/groups/' + groupId + '/invites').respond({});
|
||||
$httpBackend.expectGET('/api/v3/challenges/groups/' + groupId).respond({});
|
||||
groups.party();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('returns party if cached', function (done) {
|
||||
var uid = 'abc';
|
||||
var party = {
|
||||
_id: uid,
|
||||
};
|
||||
groups.data.party = party;
|
||||
groups.party()
|
||||
.then(function (result) {
|
||||
expect(result).to.eql(party);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls tavern endpoint when tavern is not cached', function() {
|
||||
$httpBackend.expectGET(groupApiUrlPrefix + '/habitrpg').respond({});
|
||||
groups.tavern();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('returns tavern if cached', function (done) {
|
||||
var uid = 'abc';
|
||||
var tavern = {
|
||||
_id: uid,
|
||||
};
|
||||
groups.data.tavern = tavern;
|
||||
groups.tavern()
|
||||
.then(function (result) {
|
||||
expect(result).to.eql(tavern);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls public guilds endpoint', function() {
|
||||
$httpBackend.expectGET(groupApiUrlPrefix + '?type=publicGuilds').respond([]);
|
||||
groups.publicGuilds();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('returns public guilds if cached', function (done) {
|
||||
var uid = 'abc';
|
||||
var publicGuilds = [
|
||||
{_id: uid},
|
||||
];
|
||||
groups.data.publicGuilds = publicGuilds;
|
||||
|
||||
groups.publicGuilds()
|
||||
.then(function (result) {
|
||||
expect(result).to.eql(publicGuilds);
|
||||
done();
|
||||
});
|
||||
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls my guilds endpoint', function() {
|
||||
$httpBackend.expectGET(groupApiUrlPrefix + '?type=guilds').respond([]);
|
||||
groups.myGuilds();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('returns my guilds if cached', function (done) {
|
||||
var uid = 'abc';
|
||||
var myGuilds = [
|
||||
{_id: uid},
|
||||
];
|
||||
groups.data.myGuilds = myGuilds;
|
||||
|
||||
groups.myGuilds()
|
||||
.then(function (myGuilds) {
|
||||
expect(myGuilds).to.eql(myGuilds);
|
||||
done();
|
||||
});
|
||||
|
||||
$httpBackend.flush()
|
||||
});
|
||||
|
||||
it('sets a "sendInviteText" property on a party to "Send Invitations"', function() {
|
||||
var sendInviteText = window.env.t('sendInvitations');
|
||||
var party = {
|
||||
type: 'party',
|
||||
data: {
|
||||
_id: '1234',
|
||||
},
|
||||
};
|
||||
groups.inviteOrStartParty(party);
|
||||
expect(party.sendInviteText).to.eql(sendInviteText);
|
||||
});
|
||||
|
||||
it('sets a "sendInviteText" proptery on a guild to "Send Invitations +$3.00/month/user"', function() {
|
||||
var sendInviteText = window.env.t('sendInvitations');
|
||||
var guild = {
|
||||
type: 'guild',
|
||||
data: {
|
||||
_id: '12345',
|
||||
},
|
||||
purchased: {
|
||||
plan: {
|
||||
customerId: '123',
|
||||
},
|
||||
},
|
||||
};
|
||||
groups.inviteOrStartParty(guild);
|
||||
expect(guild.sendInviteText).to.eql(sendInviteText + window.env.t('groupAdditionalUserCost'));
|
||||
});
|
||||
});
|
||||
@@ -1,118 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('memberServices', function() {
|
||||
var $httpBackend, members;
|
||||
var apiV3Prefix = '/api/v3';
|
||||
|
||||
beforeEach(inject(function (_$httpBackend_, Members) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
members = Members;
|
||||
}));
|
||||
|
||||
afterEach(function() {
|
||||
$httpBackend.verifyNoOutstandingExpectation();
|
||||
$httpBackend.verifyNoOutstandingRequest();
|
||||
});
|
||||
|
||||
|
||||
it('has no members at the beginning', function() {
|
||||
expect(members.members).to.be.an('object');
|
||||
expect(members.members).to.eql({});
|
||||
expect(members.selectedMember).to.be.undefined;
|
||||
});
|
||||
|
||||
it('calls fetch member', function() {
|
||||
var memberId = 1;
|
||||
var memberUrl = apiV3Prefix + '/members/' + memberId;
|
||||
$httpBackend.expectGET(memberUrl).respond({});
|
||||
members.fetchMember(memberId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get group members', function() {
|
||||
var groupId = 1;
|
||||
var memberUrl = apiV3Prefix + '/groups/' + groupId + '/members';
|
||||
$httpBackend.expectGET(memberUrl).respond({});
|
||||
members.getGroupMembers(groupId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get group invites', function() {
|
||||
var groupId = 1;
|
||||
var memberUrl = apiV3Prefix + '/groups/' + groupId + '/invites';
|
||||
$httpBackend.expectGET(memberUrl).respond({});
|
||||
members.getGroupInvites(groupId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get challenge members', function() {
|
||||
var challengeId = 1;
|
||||
var memberUrl = apiV3Prefix + '/challenges/' + challengeId + '/members';
|
||||
$httpBackend.expectGET(memberUrl).respond({});
|
||||
members.getChallengeMembers(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get challenge members progress', function() {
|
||||
var challengeId = 1;
|
||||
var memberId = 2;
|
||||
var memberUrl = apiV3Prefix + '/challenges/' + challengeId + '/members/' + memberId;
|
||||
$httpBackend.expectGET(memberUrl).respond({});
|
||||
members.getChallengeMemberProgress(challengeId, memberId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
describe('addToMembersList', function() {
|
||||
it('adds member to members object', function() {
|
||||
var member = { _id: 'user_id' };
|
||||
members.addToMembersList(member, members);
|
||||
expect(members.members).to.eql({
|
||||
user_id: { _id: 'user_id' }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectMember', function() {
|
||||
it('fetches member if not already in cache', function(done) {
|
||||
var uid = 'abc';
|
||||
var memberResponse = {
|
||||
data: {_id: uid},
|
||||
}
|
||||
$httpBackend.expectGET(apiV3Prefix + '/members/' + uid).respond(memberResponse);
|
||||
members.selectMember(uid)
|
||||
.then(function () {
|
||||
expect(members.selectedMember._id).to.eql(uid);
|
||||
expect(members.members).to.have.property(uid);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('fetches member if member data in cache is incomplete', function(done) {
|
||||
var uid = 'abc';
|
||||
members.members = {
|
||||
abc: { _id: 'abc', items: {} }
|
||||
}
|
||||
var memberResponse = {
|
||||
data: {_id: uid},
|
||||
}
|
||||
$httpBackend.expectGET(apiV3Prefix + '/members/' + uid).respond(memberResponse);
|
||||
members.selectMember(uid)
|
||||
.then(function () {
|
||||
expect(members.selectedMember._id).to.eql(uid);
|
||||
expect(members.members).to.have.property(uid);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('gets member from cache if member has a weapons object', function() {
|
||||
var uid = 'abc';
|
||||
members.members[uid] = { _id: uid, items: { weapon: {} } };
|
||||
members.selectMember(uid, function(){
|
||||
expect(members.selectedMember._id).to.eql(uid);
|
||||
expect(members.members).to.have.property(uid);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,202 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('notificationServices', function() {
|
||||
var notification;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub($, 'pnotify', function(){
|
||||
return { click: function(){}}
|
||||
});
|
||||
|
||||
module(function($provide){
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(function(Notification) {
|
||||
notification = Notification;
|
||||
});
|
||||
});
|
||||
|
||||
it('notifies coins amount', function() {
|
||||
var SILVER_COIN = "<span class='notification-icon shop_silver'></span>";
|
||||
var GOLD_COIN = "<span class='notification-icon shop_gold'></span>";
|
||||
|
||||
expect(notification.coins(0)).to.not.exist;
|
||||
expect(notification.coins(0.01)).to.eql("1 " + SILVER_COIN);
|
||||
expect(notification.coins(0.1)).to.eql("10 " + SILVER_COIN);
|
||||
expect(notification.coins(1)).to.eql("1 " + GOLD_COIN);
|
||||
expect(notification.coins(12.34)).to.eql("12 " + GOLD_COIN +" 33 " + SILVER_COIN);
|
||||
});
|
||||
|
||||
it('sends crit notification', function() {
|
||||
notification.crit(5);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('crit');
|
||||
expect(arg.text).to.eql('Critical Hit! Bonus: 5%');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-certificate');
|
||||
});
|
||||
|
||||
it('sends drop notification for unspecified item', function() {
|
||||
notification.drop('msg');
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('drop');
|
||||
expect(arg.text).to.eql('msg');
|
||||
expect(arg.icon).to.eql(false);
|
||||
});
|
||||
|
||||
it('sends drop notification for Egg', function() {
|
||||
var item = { type: 'Egg', key: 'wolf' };
|
||||
notification.drop('msg', item);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('drop');
|
||||
expect(arg.text).to.eql('msg');
|
||||
expect(arg.icon).to.eql('Pet_Egg_wolf');
|
||||
});
|
||||
|
||||
it('sends drop notification for Hatching Potion', function() {
|
||||
var item = { type: 'HatchingPotion', key: 'red' };
|
||||
notification.drop('msg', item);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('drop');
|
||||
expect(arg.text).to.eql('msg');
|
||||
expect(arg.icon).to.eql('Pet_HatchingPotion_red');
|
||||
});
|
||||
|
||||
it('sends drop notification for Food', function() {
|
||||
var item = { type: 'Food', key: 'meat' };
|
||||
notification.drop('msg', item);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('drop');
|
||||
expect(arg.text).to.eql('msg');
|
||||
expect(arg.icon).to.eql('Pet_Food_meat');
|
||||
});
|
||||
|
||||
it('does not send exp notification if val < -50', function() {
|
||||
notification.exp(-51);
|
||||
expect($.pnotify).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('sends exp notification if val >= -50', function() {
|
||||
notification.exp(50);
|
||||
notification.exp(0);
|
||||
notification.exp(-50);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledThrice;
|
||||
expect(arg.type).to.eql('xp');
|
||||
expect(arg.text).to.eql('+ 50 Experience');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-star');
|
||||
});
|
||||
|
||||
it('sends exp notification with rounded value', function() {
|
||||
notification.exp(50.23333);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('xp');
|
||||
expect(arg.text).to.eql('+ 50.2 Experience');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-star');
|
||||
});
|
||||
|
||||
it('sends error notification', function() {
|
||||
notification.error('there was an error');
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('danger');
|
||||
expect(arg.text).to.eql('there was an error');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-exclamation-sign');
|
||||
});
|
||||
|
||||
it('sends gp gained notification', function() {
|
||||
notification.gp(50, 4);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('gp');
|
||||
expect(arg.text).to.eql('+ 46 <span class=\'notification-icon shop_gold\'></span>');
|
||||
expect(arg.icon).to.eql(false);
|
||||
});
|
||||
|
||||
it('sends hp notification', function() {
|
||||
notification.hp(10);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('hp');
|
||||
expect(arg.text).to.eql('+ 10 Health');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-heart');
|
||||
});
|
||||
|
||||
it('sends level up notification', function() {
|
||||
notification.lvl(10);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('lvl');
|
||||
expect(arg.text).to.eql('Level Up!');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-chevron-up');
|
||||
});
|
||||
|
||||
it('sends markdown parsed notification', function() {
|
||||
notification.markdown(":smile: - task name");
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('info');
|
||||
expect(arg.text).to.eql('<p><img class="habitica-emoji" style="height: 1.5em; width: 1.5em" src="https://s3.amazonaws.com/habitica-assets/cdn/emoji/smile.png" alt="smile"> - task name</p>\n');
|
||||
expect(arg.icon).to.eql(false);
|
||||
});
|
||||
|
||||
it('does not send markdown notification if no text is given', function() {
|
||||
notification.markdown();
|
||||
|
||||
expect($.pnotify).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('sends mp notification', function() {
|
||||
notification.mp(10);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('mp');
|
||||
expect(arg.text).to.eql('+ 10 Mana');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-fire');
|
||||
});
|
||||
|
||||
it('sends streak notification', function() {
|
||||
notification.streak(10);
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('streak');
|
||||
expect(arg.text).to.eql('Streak Achievements: 10');
|
||||
expect(arg.icon).to.eql('glyphicon glyphicon-repeat');
|
||||
});
|
||||
|
||||
it('sends text notification', function() {
|
||||
notification.text('task name');
|
||||
var arg = $.pnotify.args[0][0];
|
||||
|
||||
expect($.pnotify).to.have.been.calledOnce;
|
||||
expect(arg.type).to.eql('info');
|
||||
expect(arg.text).to.eql('task name');
|
||||
expect(arg.icon).to.eql(false);
|
||||
});
|
||||
|
||||
it('does not send text notification if no text is given', function() {
|
||||
notification.text();
|
||||
|
||||
expect($.pnotify).to.not.have.been.called;
|
||||
});
|
||||
});
|
||||
@@ -1,435 +0,0 @@
|
||||
'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();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,258 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Stats Service', function() {
|
||||
var scope, statCalc, user;
|
||||
|
||||
beforeEach(function() {
|
||||
user = specHelper.newUser();
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('User', {user: user});
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, Stats) {
|
||||
statCalc = Stats;
|
||||
});
|
||||
});
|
||||
|
||||
describe('beastMasterProgress', function() {
|
||||
it('counts drop pets that user has', function() {
|
||||
user.items.pets = {
|
||||
"BearCub-Base" : 5,
|
||||
"BearCub-CottonCandyBlue" : 5,
|
||||
"Cactus-Zombie" : 5,
|
||||
"Deer-Golden" : 5,
|
||||
"Deer-Red" : 5,
|
||||
"Egg-Desert" : 5,
|
||||
"MantisShrimp-Base" : 5,
|
||||
"Wolf-Spooky": 5
|
||||
}
|
||||
|
||||
var beastMasterDisplay = statCalc.beastMasterProgress(user.items.pets);
|
||||
|
||||
expect(beastMasterDisplay).to.eql('3/90');
|
||||
});
|
||||
|
||||
it('counts drop pets with a value of -1', function() {
|
||||
user.items.pets = {
|
||||
"BearCub-Base" : -1,
|
||||
"BearCub-CottonCandyBlue" : -1,
|
||||
"Cactus-Zombie" : 5,
|
||||
"Deer-Golden" : 5,
|
||||
"Deer-Red" : -1,
|
||||
"Egg-Desert" : 5,
|
||||
"MantisShrimp-Base" : 5,
|
||||
"Wolf-Spooky": -1
|
||||
}
|
||||
|
||||
var beastMasterDisplay = statCalc.beastMasterProgress(user.items.pets);
|
||||
|
||||
expect(beastMasterDisplay).to.eql('3/90');
|
||||
});
|
||||
|
||||
it('does not count drop pets with a value of 0', function() {
|
||||
user.items.pets = {
|
||||
"BearCub-Base" : 0,
|
||||
"BearCub-CottonCandyBlue" : 0,
|
||||
"Cactus-Zombie" : 5,
|
||||
"Deer-Golden" : 5,
|
||||
"Deer-Red" : 5,
|
||||
"Egg-Desert" : 5,
|
||||
"MantisShrimp-Base" : 5
|
||||
}
|
||||
|
||||
var beastMasterDisplay = statCalc.beastMasterProgress(user.items.pets);
|
||||
|
||||
expect(beastMasterDisplay).to.eql('1/90');
|
||||
});
|
||||
});
|
||||
|
||||
describe('expDisplay', function() {
|
||||
it('displays exp as "exp / toNextLevelExp"', function() {
|
||||
user.stats.exp = 10;
|
||||
user.stats.lvl = 29;
|
||||
var expDisplay = statCalc.expDisplay(user);
|
||||
|
||||
expect(expDisplay).to.eql('10/640');
|
||||
});
|
||||
|
||||
it('Rounds exp down when given a decimal', function() {
|
||||
user.stats.exp = 10.999;
|
||||
user.stats.lvl = 29;
|
||||
var expDisplay = statCalc.expDisplay(user);
|
||||
|
||||
expect(expDisplay).to.eql('10/640');
|
||||
});
|
||||
});
|
||||
|
||||
describe('goldDisplay', function() {
|
||||
it('displays gold', function() {
|
||||
var gold = 30;
|
||||
var goldDisplay = statCalc.goldDisplay(gold);
|
||||
|
||||
expect(goldDisplay).to.eql(30);
|
||||
});
|
||||
|
||||
it('Rounds gold down when given a decimal', function() {
|
||||
var gold = 30.999;
|
||||
var goldDisplay = statCalc.goldDisplay(gold);
|
||||
|
||||
expect(goldDisplay).to.eql(30);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hpDisplay', function() {
|
||||
it('displays hp as "hp / totalHP"', function() {
|
||||
var hp = 34;
|
||||
var hpDisplay = statCalc.hpDisplay(hp);
|
||||
|
||||
expect(hpDisplay).to.eql('34/50');
|
||||
});
|
||||
|
||||
it('Rounds hp up when given a decimal', function() {
|
||||
|
||||
var hp = 34.4;
|
||||
var hpDisplay = statCalc.hpDisplay(hp);
|
||||
|
||||
expect(hpDisplay).to.eql('35/50');
|
||||
});
|
||||
});
|
||||
|
||||
describe('mountMasterProgress', function() {
|
||||
it('counts drop mounts that user has', function() {
|
||||
user.items.mounts = {
|
||||
"Hedgehog-Desert" : true,
|
||||
"Octopus-CottonCandyPink" : true,
|
||||
"TigerCub-White" : true,
|
||||
"Wolf-Golden" : true,
|
||||
"Owl-CottonCandyBlue" : true,
|
||||
"Mammoth-Base" : true,
|
||||
"Bunny-Skeleton" : true,
|
||||
"Tiger-Spooky": true
|
||||
}
|
||||
|
||||
var mountMasterDisplay = statCalc.mountMasterProgress(user.items.mounts);
|
||||
|
||||
expect(mountMasterDisplay).to.eql('2/90');
|
||||
});
|
||||
|
||||
it('does not count drop mounts with a value of false', function() {
|
||||
user.items.mounts = {
|
||||
"Hedgehog-Desert" : true,
|
||||
"Octopus-CottonCandyPink" : true,
|
||||
"TigerCub-White" : false,
|
||||
"Wolf-Golden" : false,
|
||||
"Owl-CottonCandyBlue" : true,
|
||||
"Mammoth-Base" : true,
|
||||
"Bunny-Skeleton" : true,
|
||||
"Tiger-Spooky": true
|
||||
}
|
||||
|
||||
var mountMasterDisplay = statCalc.mountMasterProgress(user.items.mounts);
|
||||
|
||||
expect(mountMasterDisplay).to.eql('0/90');
|
||||
});
|
||||
});
|
||||
|
||||
describe('mpDisplay', function() {
|
||||
it('displays mp as "mp / totalMP"', function() {
|
||||
user.fns = {};
|
||||
user.fns.statsComputed = function () { return { maxMP: 100 } };
|
||||
user.stats.mp = 30;
|
||||
var mpDisplay = statCalc.mpDisplay(user);
|
||||
|
||||
expect(mpDisplay).to.eql('30/100');
|
||||
});
|
||||
|
||||
it('Rounds mp down when given a decimal', function() {
|
||||
user.fns = {};
|
||||
user.fns.statsComputed = function () { return { maxMP: 100 } };
|
||||
user.stats.mp = 30.99;
|
||||
var mpDisplay = statCalc.mpDisplay(user);
|
||||
|
||||
expect(mpDisplay).to.eql('30/100');
|
||||
});
|
||||
});
|
||||
|
||||
describe('totalCount', function() {
|
||||
it('counts all pets that user has', function() {
|
||||
user.items.pets = {
|
||||
"BearCub-Base" : 5,
|
||||
"BearCub-CottonCandyBlue" : 5,
|
||||
"Cactus-Zombie" : 5,
|
||||
"Deer-Golden" : 5,
|
||||
"Deer-Red" : 5,
|
||||
"Egg-Desert" : 5,
|
||||
"MantisShrimp-Base" : 5
|
||||
}
|
||||
|
||||
var petsFound = statCalc.totalCount(user.items.pets);
|
||||
|
||||
expect(petsFound).to.eql(7);
|
||||
});
|
||||
|
||||
it('includes pets that have a value of 0', function() {
|
||||
user.items.pets = {
|
||||
"BearCub-Base" : 0,
|
||||
"BearCub-CottonCandyBlue" : 5,
|
||||
"Cactus-Zombie" : 0,
|
||||
"Deer-Golden" : 0,
|
||||
"Deer-Red" : 0,
|
||||
"Egg-Desert" : 0,
|
||||
"MantisShrimp-Base" : 5
|
||||
}
|
||||
|
||||
var petsFound = statCalc.totalCount(user.items.pets);
|
||||
|
||||
expect(petsFound).to.eql(7);
|
||||
});
|
||||
|
||||
it('includes pets that have a value of -1', function() {
|
||||
user.items.pets = {
|
||||
"BearCub-Base" : -1,
|
||||
"BearCub-CottonCandyBlue" : 5,
|
||||
"Cactus-Zombie" : -1,
|
||||
"Deer-Golden" : -1,
|
||||
"Deer-Red" : -1,
|
||||
"Egg-Desert" : -1,
|
||||
"MantisShrimp-Base" : 5
|
||||
}
|
||||
|
||||
var petsFound = statCalc.totalCount(user.items.pets);
|
||||
|
||||
expect(petsFound).to.eql(7);
|
||||
});
|
||||
|
||||
it('counts all mounts that user has', function() {
|
||||
user.items.mounts = {
|
||||
"Hedgehog-Desert" : true,
|
||||
"Octopus-CottonCandyPink" : true,
|
||||
"TigerCub-White" : true,
|
||||
"Wolf-Golden" : true,
|
||||
"Owl-CottonCandyBlue" : true,
|
||||
"Mammoth-Base" : true,
|
||||
"Bunny-Skeleton" : true
|
||||
}
|
||||
|
||||
var mountsFound = statCalc.totalCount(user.items.mounts);
|
||||
|
||||
expect(mountsFound).to.eql(7);
|
||||
});
|
||||
|
||||
it('inlcudes mounts with a value of false', function() {
|
||||
user.items.mounts = {
|
||||
"Hedgehog-Desert" : false,
|
||||
"Octopus-CottonCandyPink" : true,
|
||||
"TigerCub-White" : false,
|
||||
"Wolf-Golden" : false,
|
||||
"Owl-CottonCandyBlue" : false,
|
||||
"Mammoth-Base" : true,
|
||||
"Bunny-Skeleton" : false
|
||||
}
|
||||
|
||||
var mountsFound = statCalc.totalCount(user.items.mounts);
|
||||
|
||||
expect(mountsFound).to.eql(7);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Tags Service', function() {
|
||||
var rootScope, tags, user, $httpBackend;
|
||||
var apiV3Prefix = 'api/v3/tags';
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
user = specHelper.newUser();
|
||||
$provide.value('User', {user: user});
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, _$rootScope_, Tags, User) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
rootScope = _$rootScope_;
|
||||
tags = Tags;
|
||||
});
|
||||
});
|
||||
|
||||
it('calls get tags endpoint', function() {
|
||||
$httpBackend.expectGET(apiV3Prefix).respond({});
|
||||
tags.getTags();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls post tags endpoint', function() {
|
||||
$httpBackend.expectPOST(apiV3Prefix).respond({});
|
||||
tags.createTag();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get tag endpoint', function() {
|
||||
var tagId = 1;
|
||||
$httpBackend.expectGET(apiV3Prefix + '/' + tagId).respond({});
|
||||
tags.getTag(tagId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls update tag endpoint', function() {
|
||||
var tagId = 1;
|
||||
$httpBackend.expectPUT(apiV3Prefix + '/' + tagId).respond({});
|
||||
tags.updateTag(tagId, {});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls delete tag endpoint', function() {
|
||||
var tagId = 1;
|
||||
$httpBackend.expectDELETE(apiV3Prefix + '/' + tagId).respond({});
|
||||
tags.deleteTag(tagId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user