mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-10-27 19:22:55 +01:00
Compare commits
157 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 |
@@ -20,11 +20,7 @@ container_commands:
|
||||
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
|
||||
|
||||
@@ -4,7 +4,7 @@ FROM node:boron
|
||||
# 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
|
||||
@@ -12,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
|
||||
|
||||
@@ -4,14 +4,13 @@ FROM node:boron
|
||||
# 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 release 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']);
|
||||
});
|
||||
@@ -2,13 +2,10 @@ import gulp from 'gulp';
|
||||
import runSequence from 'run-sequence';
|
||||
import babel from 'gulp-babel';
|
||||
import webpackProductionBuild from '../webpack/build';
|
||||
require('gulp-grunt')(gulp);
|
||||
|
||||
gulp.task('build', () => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
gulp.start('build:prod');
|
||||
} else {
|
||||
gulp.start('build:dev');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -34,23 +31,8 @@ gulp.task('build:client', ['bootstrap'], (done) => {
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('build:dev', ['browserify', 'prepare:staticNewStuff'], (done) => {
|
||||
gulp.start('grunt-build:dev', done);
|
||||
});
|
||||
|
||||
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',
|
||||
'build:client',
|
||||
], (done) => {
|
||||
runSequence(
|
||||
'grunt-build:prod',
|
||||
'apidoc',
|
||||
done
|
||||
);
|
||||
});
|
||||
'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);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var updateStore = require('../website/common/script/libs/updateStore');
|
||||
import { selectGearToPin } from '../website/common/script/ops/pinnedGearUtils';
|
||||
|
||||
var getItemInfo = require('../website/common/script/libs/getItemInfo');
|
||||
|
||||
var migrationName = '20170928_redesign_launch.js';
|
||||
@@ -69,7 +70,7 @@ function updateUser (user) {
|
||||
|
||||
var set = {'migration': migrationName};
|
||||
|
||||
var oldRewardsList = updateStore(user);
|
||||
var oldRewardsList = selectGearToPin(user);
|
||||
var newPinnedItems = [
|
||||
{
|
||||
type: 'armoire',
|
||||
|
||||
@@ -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']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
6179
package-lock.json
generated
6179
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.0.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",
|
||||
@@ -31,8 +32,7 @@
|
||||
"bluebird": "^3.3.5",
|
||||
"body-parser": "^1.15.0",
|
||||
"bootstrap": "4.0.0-alpha.6",
|
||||
"bootstrap-vue": "^1.0.0-beta.6",
|
||||
"bower": "~1.3.12",
|
||||
"bootstrap-vue": "1.0.0-beta.7",
|
||||
"browserify": "~12.0.1",
|
||||
"compression": "^1.6.1",
|
||||
"connect-ratelimit": "0.0.7",
|
||||
@@ -52,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": "git://github.com/habitrpg/grunt-hashres#dc85db6d3002e29e1b7c5ee186b80d708d2f0e0b",
|
||||
"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",
|
||||
@@ -155,11 +145,6 @@
|
||||
"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",
|
||||
@@ -169,7 +154,7 @@
|
||||
"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",
|
||||
"start": "gulp nodemon",
|
||||
"postinstall": "gulp build",
|
||||
"apidoc": "gulp apidoc"
|
||||
},
|
||||
@@ -193,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",
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,8 +3,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;
|
||||
|
||||
@@ -56,6 +56,7 @@ describe('POST /user/buy/:key', () => {
|
||||
message: t('messageHealthAlreadyMax'),
|
||||
});
|
||||
});
|
||||
|
||||
it('buys a piece of gear', async () => {
|
||||
let key = 'armor_warrior_1';
|
||||
|
||||
@@ -64,4 +65,36 @@ describe('POST /user/buy/:key', () => {
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
@@ -34,6 +35,7 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,6 +53,7 @@ describe('response middleware', () => {
|
||||
message: 'hello',
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -67,6 +70,7 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -81,6 +85,7 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: 0,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -104,6 +109,7 @@ describe('response middleware', () => {
|
||||
},
|
||||
],
|
||||
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 received', 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 received', 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 received', 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 received', 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 received', 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 received', 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 received', 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 received', 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 received', 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 received', 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();
|
||||
});
|
||||
});
|
||||
@@ -1,440 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('Tasks Service', function() {
|
||||
var rootScope, tasks, user, $httpBackend;
|
||||
var apiV3Prefix = '/api/v3/tasks';
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
user = specHelper.newUser();
|
||||
$provide.value('User', {user: user});
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, _$rootScope_, Tasks, User) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
rootScope = _$rootScope_;
|
||||
rootScope.charts = {};
|
||||
tasks = Tasks;
|
||||
});
|
||||
|
||||
rootScope.openModal = function() {
|
||||
return {
|
||||
result: {
|
||||
then: function() {},
|
||||
catch: function() {},
|
||||
},
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it('calls get user tasks endpoint', function() {
|
||||
$httpBackend.expectGET(apiV3Prefix + '/user').respond({});
|
||||
tasks.getUserTasks();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls post user tasks endpoint', function() {
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/user').respond({});
|
||||
tasks.createUserTasks();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get challenge tasks endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectGET(apiV3Prefix + '/challenge/' + challengeId).respond({});
|
||||
tasks.getChallengeTasks(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls create challenge tasks endpoint', function() {
|
||||
var challengeId = 1;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/challenge/' + challengeId).respond({});
|
||||
tasks.createChallengeTasks(challengeId, {});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls get task endpoint', function() {
|
||||
var taskId = 1;
|
||||
$httpBackend.expectGET(apiV3Prefix + '/' + taskId).respond({});
|
||||
tasks.getTask(taskId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls update task endpoint', function() {
|
||||
var taskId = 1;
|
||||
$httpBackend.expectPUT(apiV3Prefix + '/' + taskId).respond({});
|
||||
tasks.updateTask(taskId, {});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls delete task endpoint', function() {
|
||||
var taskId = 1;
|
||||
$httpBackend.expectDELETE(apiV3Prefix + '/' + taskId).respond({});
|
||||
tasks.deleteTask(taskId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls score task endpoint', function() {
|
||||
var taskId = 1;
|
||||
var direction = "down";
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/' + taskId + '/score/' + direction).respond({});
|
||||
tasks.scoreTask(taskId, direction);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls move task endpoint', function() {
|
||||
var taskId = 1;
|
||||
var position = 0;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/' + taskId + '/move/to/' + position).respond({});
|
||||
tasks.moveTask(taskId, position);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls group move task endpoint', function() {
|
||||
var taskId = 1;
|
||||
var position = 0;
|
||||
$httpBackend.expectPOST('/api/v3/group-tasks/' + taskId + '/move/to/' + position).respond({});
|
||||
tasks.moveGroupTask(taskId, position);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls add check list item endpoint', function() {
|
||||
var taskId = 1;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/' + taskId + '/checklist').respond({});
|
||||
tasks.addChecklistItem(taskId, {});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls score check list item endpoint', function() {
|
||||
var taskId = 1;
|
||||
var itemId = 2;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/' + taskId + '/checklist/' + itemId + '/score').respond({});
|
||||
tasks.scoreCheckListItem(taskId, itemId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls update check list item endpoint', function() {
|
||||
var taskId = 1;
|
||||
var itemId = 2;
|
||||
$httpBackend.expectPUT(apiV3Prefix + '/' + taskId + '/checklist/' + itemId).respond({});
|
||||
tasks.updateChecklistItem(taskId, itemId, {});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls remove check list item endpoint', function() {
|
||||
var taskId = 1;
|
||||
var itemId = 2;
|
||||
$httpBackend.expectDELETE(apiV3Prefix + '/' + taskId + '/checklist/' + itemId).respond({});
|
||||
tasks.removeChecklistItem(taskId, itemId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls add tag to list item endpoint', function() {
|
||||
var taskId = 1;
|
||||
var tagId = 2;
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/' + taskId + '/tags/' + tagId).respond({});
|
||||
tasks.addTagToTask(taskId, tagId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls remove tag to list item endpoint', function() {
|
||||
var taskId = 1;
|
||||
var tagId = 2;
|
||||
$httpBackend.expectDELETE(apiV3Prefix + '/' + taskId + '/tags/' + tagId).respond({});
|
||||
tasks.removeTagFromTask(taskId, tagId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls unlinkOneTask endpoint', function() {
|
||||
var taskId = 1;
|
||||
var keep = "keep";
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/unlink-one/' + taskId + '?keep=' + keep).respond({});
|
||||
tasks.unlinkOneTask(taskId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls unlinkAllTasks endpoint', function() {
|
||||
var challengeId = 1;
|
||||
var keep = "keep-all";
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/unlink-all/' + challengeId + '?keep=' + keep).respond({});
|
||||
tasks.unlinkAllTasks(challengeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('calls clear completed todo task endpoint', function() {
|
||||
$httpBackend.expectPOST(apiV3Prefix + '/clearCompletedTodos').respond({});
|
||||
tasks.clearCompletedTodos();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
describe('editTask', function() {
|
||||
var task;
|
||||
|
||||
beforeEach(function(){
|
||||
task = specHelper.newTask();
|
||||
});
|
||||
|
||||
it('sets _editing to true', function() {
|
||||
tasks.editTask(task, user);
|
||||
expect(task._editing).to.eql(true);
|
||||
});
|
||||
|
||||
it('sets _tags to true by default', function() {
|
||||
tasks.editTask(task, user);
|
||||
|
||||
expect(task._tags).to.eql(true);
|
||||
});
|
||||
|
||||
it('sets _tags to false if preference for collapsed tags is turned on', function() {
|
||||
user.preferences.tagsCollapsed = true;
|
||||
tasks.editTask(task, user);
|
||||
|
||||
expect(task._tags).to.eql(false);
|
||||
});
|
||||
|
||||
it('sets _advanced to true by default', function(){
|
||||
user.preferences.advancedCollapsed = true;
|
||||
tasks.editTask(task, user);
|
||||
|
||||
expect(task._advanced).to.eql(false);
|
||||
});
|
||||
|
||||
it('sets _advanced to false if preference for collapsed advance menu is turned on', function() {
|
||||
user.preferences.advancedCollapsed = false;
|
||||
tasks.editTask(task, user);
|
||||
|
||||
expect(task._advanced).to.eql(true);
|
||||
});
|
||||
|
||||
it('closes task chart if it exists', function() {
|
||||
rootScope.charts[task.id] = true;
|
||||
|
||||
tasks.editTask(task, user);
|
||||
expect(rootScope.charts[task.id]).to.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cancelTaskEdit', function() {
|
||||
var task;
|
||||
|
||||
beforeEach(function(){
|
||||
task = specHelper.newTask();
|
||||
});
|
||||
|
||||
it('sets _editing to false', function() {
|
||||
task._editing = true;
|
||||
tasks.cancelTaskEdit(task);
|
||||
expect(task._editing).to.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cloneTask', function() {
|
||||
|
||||
context('generic tasks', function() {
|
||||
it('clones the data from a task', function() {
|
||||
var task = specHelper.newTask();
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
|
||||
expect(clonedTask.text).to.eql(task.text);
|
||||
expect(clonedTask.notes).to.eql(task.notes);
|
||||
expect(clonedTask.tags.includedTag).to.eql(task.tags.includedTag);
|
||||
expect(clonedTask.tags.notIncludedTag).to.eql(task.tags.notIncludedTag);
|
||||
expect(clonedTask.priority).to.eql(task.priority);
|
||||
expect(clonedTask.attribute).to.eql(task.attribute);
|
||||
});
|
||||
|
||||
it('does not clone original task\'s _id', function() {
|
||||
var task = specHelper.newTask();
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
|
||||
expect(clonedTask._id).to.exist;
|
||||
expect(clonedTask._id).to.not.eql(task._id);
|
||||
});
|
||||
|
||||
it('does not clone original task\'s dateCreated attribute', function() {
|
||||
var task = specHelper.newTask({
|
||||
createdAt: new Date(2014, 5, 1, 1, 1, 1, 1),
|
||||
});
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
|
||||
expect(clonedTask.createdAt).to.exist;
|
||||
expect(clonedTask.createdAt).to.not.eql(task.createdAt);
|
||||
});
|
||||
|
||||
it('does not clone original task\'s value', function() {
|
||||
var task = specHelper.newTask({
|
||||
value: 130
|
||||
});
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
|
||||
expect(clonedTask.value).to.exist;
|
||||
expect(clonedTask.value).to.not.eql(task.value);
|
||||
});
|
||||
});
|
||||
|
||||
context('Habits', function() {
|
||||
|
||||
it('clones a habit', function() {
|
||||
var habit = specHelper.newHabit({
|
||||
up: true,
|
||||
down: false
|
||||
});
|
||||
var clonedHabit = tasks.cloneTask(habit);
|
||||
|
||||
expect(clonedHabit.type).to.eql('habit');
|
||||
expect(clonedHabit.up).to.eql(habit.up);
|
||||
expect(clonedHabit.down).to.eql(habit.down);
|
||||
});
|
||||
});
|
||||
|
||||
context('Dailys', function() {
|
||||
|
||||
it('clones a daily', function() {
|
||||
var daily = specHelper.newDaily({
|
||||
frequency: 'daily',
|
||||
everyX: 3,
|
||||
startDate: new Date(2014, 5, 1, 1, 1, 1, 1),
|
||||
});
|
||||
|
||||
var clonedDaily = tasks.cloneTask(daily);
|
||||
|
||||
expect(clonedDaily.type).to.eql('daily');
|
||||
expect(clonedDaily.frequency).to.eql(daily.frequency);
|
||||
expect(clonedDaily.everyX).to.eql(daily.everyX);
|
||||
expect(clonedDaily.startDate).to.eql(daily.startDate);
|
||||
});
|
||||
|
||||
it('does not clone streak', function() {
|
||||
var daily = specHelper.newDaily({
|
||||
streak: 11
|
||||
});
|
||||
|
||||
var clonedDaily = tasks.cloneTask(daily);
|
||||
|
||||
expect(clonedDaily.streak).to.eql(0);
|
||||
});
|
||||
});
|
||||
|
||||
context('Todos', function() {
|
||||
|
||||
it('clones a todo', function() {
|
||||
var todo = specHelper.newTodo();
|
||||
var clonedTodo = tasks.cloneTask(todo);
|
||||
|
||||
expect(clonedTodo.type).to.eql('todo');
|
||||
});
|
||||
|
||||
it('does not clone due date', function() {
|
||||
var todo = specHelper.newTodo({
|
||||
date: '2015-06-20'
|
||||
});
|
||||
|
||||
var clonedTodo = tasks.cloneTask(todo);
|
||||
|
||||
expect(clonedTodo.date).to.not.exist;
|
||||
});
|
||||
|
||||
it('does not clone date completed', function() {
|
||||
var todo = specHelper.newTodo({
|
||||
dateCompleted: new Date()
|
||||
});
|
||||
|
||||
var clonedTodo = tasks.cloneTask(todo);
|
||||
|
||||
expect(clonedTodo.dateCompleted).to.not.exist;
|
||||
});
|
||||
});
|
||||
|
||||
context('Rewards', function() {
|
||||
|
||||
it('clones a reward', function() {
|
||||
var reward = specHelper.newReward();
|
||||
var clonedReward = tasks.cloneTask(reward);
|
||||
|
||||
expect(clonedReward.type).to.eql('reward');
|
||||
});
|
||||
|
||||
it('does clone a reward\'s vaue', function() {
|
||||
var reward = specHelper.newReward({
|
||||
value: 20
|
||||
});
|
||||
var clonedReward = tasks.cloneTask(reward);
|
||||
|
||||
expect(clonedReward.value).to.eql(reward.value);
|
||||
});
|
||||
});
|
||||
|
||||
context('complete', function() {
|
||||
it('does not clone completed status', function() {
|
||||
var todo = specHelper.newTodo({
|
||||
completed: true
|
||||
});
|
||||
|
||||
var clonedTodo = tasks.cloneTask(todo);
|
||||
|
||||
expect(clonedTodo.completed).to.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
context('history', function() {
|
||||
|
||||
it('does not clone history', function() {
|
||||
var habit = specHelper.newHabit({
|
||||
history: [
|
||||
{ date: Date.now, value: 3.1 },
|
||||
{ date: Date.now, value: 2.7 }
|
||||
]
|
||||
});
|
||||
var clonedHabit = tasks.cloneTask(habit);
|
||||
|
||||
expect(clonedHabit.history).to.be.an.array;
|
||||
expect(clonedHabit.history).to.be.empty;
|
||||
});
|
||||
});
|
||||
|
||||
context('checklists', function() {
|
||||
|
||||
it('clones checklist text', function() {
|
||||
var todo = specHelper.newTodo({
|
||||
checklist: [{
|
||||
completed: true,
|
||||
text: 'checklist 1',
|
||||
id: 'cl-1'
|
||||
}, {
|
||||
completed: false,
|
||||
text: 'checklist 2',
|
||||
id: 'cl-2'
|
||||
}]
|
||||
});
|
||||
|
||||
var clonedTodo = tasks.cloneTask(todo);
|
||||
|
||||
expect(clonedTodo.checklist[0].text).to.eql(todo.checklist[0].text);
|
||||
expect(clonedTodo.checklist[1].text).to.eql(todo.checklist[1].text);
|
||||
});
|
||||
|
||||
it('does not clone complete or id attribute of checklist', function() {
|
||||
var todo = specHelper.newTodo({
|
||||
checklist: [{
|
||||
completed: true,
|
||||
text: 'checklist 1',
|
||||
id: 'cl-1'
|
||||
}, {
|
||||
completed: false,
|
||||
text: 'checklist 2',
|
||||
id: 'cl-2'
|
||||
}]
|
||||
});
|
||||
|
||||
var clonedTodo = tasks.cloneTask(todo);
|
||||
|
||||
expect(clonedTodo.checklist[0].completed).to.eql(false);
|
||||
expect(clonedTodo.checklist[0].id).to.not.eql(todo.checklist[0].id);
|
||||
expect(clonedTodo.checklist[0].id).to.exist;
|
||||
expect(clonedTodo.checklist[1].completed).to.eql(false);
|
||||
expect(clonedTodo.checklist[1].id).to.not.eql(todo.checklist[1].id);
|
||||
expect(clonedTodo.checklist[1].id).to.exist;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,64 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('userServices', function() {
|
||||
var $httpBackend, $window, user, STORAGE_USER_ID, STORAGE_SETTINGS_ID;
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
beforeEach(function(){
|
||||
module(function($provide){
|
||||
$window = {href: '', alert: sandbox.spy(), location: {search: '', pathname: '', href: ''}};
|
||||
$provide.value('$window', $window);
|
||||
});
|
||||
|
||||
inject(function(_$httpBackend_, User, _STORAGE_USER_ID_, _STORAGE_SETTINGS_ID_) {
|
||||
$httpBackend = _$httpBackend_;
|
||||
user = User;
|
||||
STORAGE_USER_ID = _STORAGE_USER_ID_;
|
||||
STORAGE_SETTINGS_ID = _STORAGE_SETTINGS_ID_;
|
||||
});
|
||||
localStorage.removeItem(STORAGE_SETTINGS_ID);
|
||||
localStorage.removeItem(STORAGE_USER_ID);
|
||||
});
|
||||
|
||||
it('checks online status', function(){
|
||||
user.online(true);
|
||||
expect(user.settings.online).to.be.true;
|
||||
user.online(false);
|
||||
expect(user.settings.online).to.be.false;
|
||||
})
|
||||
|
||||
it('saves user data to local storage', function(){
|
||||
user.save();
|
||||
var settings = JSON.parse(localStorage[STORAGE_SETTINGS_ID]);
|
||||
expect(settings).to.eql(user.settings);
|
||||
});
|
||||
|
||||
xit('alerts when not authenticated', function(){
|
||||
user.log();
|
||||
expect($window.alert).to.have.been.calledWith("Not authenticated, can't sync, go to settings first.");
|
||||
});
|
||||
|
||||
xit('puts items in que queue', function(){
|
||||
user.log({});
|
||||
//TODO where does that null comes from?
|
||||
expect(user.settings.sync.queue).to.eql([null, {}]);
|
||||
});
|
||||
|
||||
describe('getBalanceInGems', function() {
|
||||
|
||||
it('multiplies balance by 4', function() {
|
||||
user.user.balance = 5;
|
||||
var balanceInGems = user.getBalanceInGems();
|
||||
|
||||
expect(balanceInGems).to.eql(20);
|
||||
});
|
||||
|
||||
it('returns zero if balance is not defined', function() {
|
||||
var balanceInGems = user.getBalanceInGems();
|
||||
|
||||
expect(user.user.balance).to.not.exist;
|
||||
expect(balanceInGems).to.eql(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,179 +0,0 @@
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
var specHelper = {};
|
||||
|
||||
(function(){
|
||||
|
||||
specHelper.newUser = newUser;
|
||||
specHelper.newGroup = newGroup;
|
||||
specHelper.newTask = newTask;
|
||||
specHelper.newHabit = newHabit;
|
||||
specHelper.newDaily = newDaily;
|
||||
specHelper.newTodo = newTodo;
|
||||
specHelper.newReward = newReward;
|
||||
specHelper.newChallenge = newChallenge;
|
||||
|
||||
function newUser(overrides) {
|
||||
var buffs = { per:0, int:0, con:0, str:0, stealth: 0, streaks: false };
|
||||
var stats = { str:1, con:1, per:1, int:1, mp: 32, class: 'warrior', buffs: buffs, gp: 0 };
|
||||
var items = {
|
||||
lastDrop: { count: 0 },
|
||||
hatchingPotions: {},
|
||||
eggs: {},
|
||||
food: {},
|
||||
pets: {},
|
||||
mounts: {},
|
||||
gear: { equipped: {}, costume: {}, owned: {} }
|
||||
};
|
||||
|
||||
var user = {
|
||||
_id: 'unique-user-id',
|
||||
profile: {
|
||||
name: 'dummy-name',
|
||||
},
|
||||
auth: { timestamps: {} },
|
||||
stats: stats,
|
||||
items: items,
|
||||
party: {
|
||||
quest: {
|
||||
progress: {down: 0}
|
||||
}
|
||||
},
|
||||
preferences: { suppressModals: {} },
|
||||
habits: [],
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
flags: {},
|
||||
filters: {},
|
||||
achievements: {}
|
||||
};
|
||||
|
||||
_setOverrides(user, overrides);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
function newGroup(overrides) {
|
||||
var quest = { progress: { }, active: false };
|
||||
var group = {
|
||||
_id: 'group-id',
|
||||
leader : 'leader-id',
|
||||
memberCount : 1,
|
||||
chat : [],
|
||||
privacy : "public",
|
||||
invites : [],
|
||||
members : [
|
||||
'leader-id'
|
||||
]
|
||||
};
|
||||
|
||||
_setOverrides(group, overrides);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function newTask(overrides) {
|
||||
var task = {
|
||||
id: 'task-id',
|
||||
_id: 'task-id',
|
||||
dateCreated: Date.now,
|
||||
text: 'task text',
|
||||
notes: 'task notes',
|
||||
tags: { },
|
||||
value: 0,
|
||||
priority: 1,
|
||||
attribute: 'str',
|
||||
challenge: { }
|
||||
};
|
||||
|
||||
_setOverrides(task, overrides);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
function newHabit(overrides) {
|
||||
var habit = newTask();
|
||||
habit.type = 'habit';
|
||||
habit.history = [];
|
||||
habit.up = true;
|
||||
habit.down = true;
|
||||
|
||||
_setOverrides(habit, overrides);
|
||||
|
||||
return habit;
|
||||
}
|
||||
|
||||
function newDaily(overrides) {
|
||||
var daily = newTask();
|
||||
daily.type = 'daily';
|
||||
daily.frequency = 'weekly';
|
||||
daily.repeat = {
|
||||
m: true,
|
||||
t: true,
|
||||
w: true,
|
||||
th: true,
|
||||
f: true,
|
||||
s: true,
|
||||
su: true
|
||||
};
|
||||
daily.startDate = Date.now;
|
||||
daily.history = [];
|
||||
daily.completed = false;
|
||||
daily.collapseChecklist = false;
|
||||
daily.checklist = [];
|
||||
daily.streak = 0;
|
||||
|
||||
_setOverrides(daily, overrides);
|
||||
|
||||
return daily;
|
||||
}
|
||||
|
||||
function newTodo(overrides) {
|
||||
var todo = newTask();
|
||||
todo.type = 'todo';
|
||||
todo.completed = false;
|
||||
todo.collapseChecklist = false;
|
||||
todo.checklist = [];
|
||||
|
||||
_setOverrides(todo, overrides);
|
||||
|
||||
return todo;
|
||||
}
|
||||
|
||||
function newReward(overrides) {
|
||||
var reward = newTask();
|
||||
reward.type = 'reward';
|
||||
|
||||
_setOverrides(reward, overrides);
|
||||
|
||||
return reward;
|
||||
}
|
||||
|
||||
function newChallenge(overrides) {
|
||||
var challenge = {
|
||||
name: 'challenge name',
|
||||
description: 'challeng description',
|
||||
habits: [],
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
leader: 'leader-id',
|
||||
group: 'group-id',
|
||||
prize: 0,
|
||||
timestamp: +(new Date),
|
||||
members: ['leader-id'],
|
||||
official: false
|
||||
};
|
||||
|
||||
_setOverrides(challenge, overrides);
|
||||
|
||||
return challenge;
|
||||
}
|
||||
|
||||
function _setOverrides(factory, overrides) {
|
||||
for(var key in overrides) {
|
||||
factory[key] = overrides[key];
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -25,6 +25,15 @@ describe('shared.ops.blockUser', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('validates user can\'t block himself', (done) => {
|
||||
try {
|
||||
blockUser(user, { params: { uuid: user._id } });
|
||||
} catch (error) {
|
||||
expect(error.message).to.eql(i18n.t('blockYourself'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('blocks user', () => {
|
||||
let [result] = blockUser(user, { params: { uuid: blockedUser._id } });
|
||||
expect(user.inbox.blocks).to.eql([blockedUser._id]);
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/* eslint-disable camelcase */
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buy from '../../../website/common/script/ops/buy';
|
||||
import {
|
||||
BadRequest,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buy', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(() => {
|
||||
user = generateUser({
|
||||
items: {
|
||||
gear: {
|
||||
owned: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
equipped: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
stats: { gp: 200 },
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error when key is not provided', (done) => {
|
||||
try {
|
||||
buy(user);
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('recovers 15 hp', () => {
|
||||
user.stats.hp = 30;
|
||||
buy(user, {params: {key: 'potion'}});
|
||||
expect(user.stats.hp).to.eql(45);
|
||||
});
|
||||
|
||||
it('adds equipment to inventory', () => {
|
||||
user.stats.gp = 31;
|
||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
||||
expect(user.items.gear.owned).to.eql({
|
||||
weapon_warrior_0: true,
|
||||
armor_warrior_1: true,
|
||||
eyewear_special_blackTopFrame: true,
|
||||
eyewear_special_blueTopFrame: true,
|
||||
eyewear_special_greenTopFrame: true,
|
||||
eyewear_special_pinkTopFrame: true,
|
||||
eyewear_special_redTopFrame: true,
|
||||
eyewear_special_whiteTopFrame: true,
|
||||
eyewear_special_yellowTopFrame: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
124
test/common/ops/buy/buy.js
Normal file
124
test/common/ops/buy/buy.js
Normal file
@@ -0,0 +1,124 @@
|
||||
/* eslint-disable camelcase */
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../../helpers/common.helper';
|
||||
import buy from '../../../../website/common/script/ops/buy';
|
||||
import {
|
||||
BadRequest,
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
import content from '../../../../website/common/script/content/index';
|
||||
|
||||
describe('shared.ops.buy', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(() => {
|
||||
user = generateUser({
|
||||
items: {
|
||||
gear: {
|
||||
owned: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
equipped: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
stats: { gp: 200 },
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error when key is not provided', (done) => {
|
||||
try {
|
||||
buy(user);
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('recovers 15 hp', () => {
|
||||
user.stats.hp = 30;
|
||||
buy(user, {params: {key: 'potion'}});
|
||||
expect(user.stats.hp).to.eql(45);
|
||||
});
|
||||
|
||||
it('adds equipment to inventory', () => {
|
||||
user.stats.gp = 31;
|
||||
|
||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
||||
|
||||
expect(user.items.gear.owned).to.eql({
|
||||
weapon_warrior_0: true,
|
||||
armor_warrior_1: true,
|
||||
eyewear_special_blackTopFrame: true,
|
||||
eyewear_special_blueTopFrame: true,
|
||||
eyewear_special_greenTopFrame: true,
|
||||
eyewear_special_pinkTopFrame: true,
|
||||
eyewear_special_redTopFrame: true,
|
||||
eyewear_special_whiteTopFrame: true,
|
||||
eyewear_special_yellowTopFrame: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('buys Steampunk Accessories Set', () => {
|
||||
user.purchased.plan.consecutive.trinkets = 1;
|
||||
|
||||
buy(user, {
|
||||
params: {
|
||||
key: '301404',
|
||||
},
|
||||
type: 'mystery',
|
||||
});
|
||||
|
||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||
expect(user.items.gear.owned).to.have.property('weapon_warrior_0', true);
|
||||
expect(user.items.gear.owned).to.have.property('weapon_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('armor_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('head_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('eyewear_mystery_301404', true);
|
||||
});
|
||||
|
||||
it('buys a Quest scroll', () => {
|
||||
user.stats.gp = 205;
|
||||
|
||||
buy(user, {
|
||||
params: {
|
||||
key: 'dilatoryDistress1',
|
||||
},
|
||||
type: 'quest',
|
||||
});
|
||||
|
||||
expect(user.items.quests).to.eql({dilatoryDistress1: 1});
|
||||
expect(user.stats.gp).to.equal(5);
|
||||
});
|
||||
|
||||
it('buys a special item', () => {
|
||||
user.stats.gp = 11;
|
||||
let item = content.special.thankyou;
|
||||
|
||||
let [data, message] = buy(user, {
|
||||
params: {
|
||||
key: 'thankyou',
|
||||
},
|
||||
type: 'special',
|
||||
});
|
||||
|
||||
expect(user.stats.gp).to.equal(1);
|
||||
expect(user.items.special.thankyou).to.equal(1);
|
||||
expect(data).to.eql({
|
||||
items: user.items,
|
||||
stats: user.stats,
|
||||
});
|
||||
expect(message).to.equal(i18n.t('messageBought', {
|
||||
itemText: item.text(),
|
||||
}));
|
||||
});
|
||||
|
||||
it('allows for bulk purchases', () => {
|
||||
user.stats.hp = 30;
|
||||
buy(user, {params: {key: 'potion'}, quantity: 2});
|
||||
expect(user.stats.hp).to.eql(50);
|
||||
});
|
||||
});
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import count from '../../../website/common/script/count';
|
||||
import buyArmoire from '../../../website/common/script/ops/buyArmoire';
|
||||
import randomVal from '../../../website/common/script/libs/randomVal';
|
||||
import content from '../../../website/common/script/content/index';
|
||||
} from '../../../helpers/common.helper';
|
||||
import count from '../../../../website/common/script/count';
|
||||
import buyArmoire from '../../../../website/common/script/ops/buyArmoire';
|
||||
import randomVal from '../../../../website/common/script/libs/randomVal';
|
||||
import content from '../../../../website/common/script/content/index';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
function getFullArmoire () {
|
||||
let fullArmoire = {};
|
||||
@@ -3,13 +3,13 @@
|
||||
import sinon from 'sinon'; // eslint-disable-line no-shadow
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyGear from '../../../website/common/script/ops/buyGear';
|
||||
import shared from '../../../website/common/script';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyGear from '../../../../website/common/script/ops/buyGear';
|
||||
import shared from '../../../../website/common/script';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyGear', () => {
|
||||
let user;
|
||||
@@ -1,12 +1,12 @@
|
||||
/* eslint-disable camelcase */
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyHealthPotion from '../../../website/common/script/ops/buyHealthPotion';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyHealthPotion from '../../../../website/common/script/ops/buyHealthPotion';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyHealthPotion', () => {
|
||||
let user;
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyMysterySet from '../../../website/common/script/ops/buyMysterySet';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyMysterySet from '../../../../website/common/script/ops/buyMysterySet';
|
||||
import {
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyMysterySet', () => {
|
||||
let user;
|
||||
@@ -1,12 +1,12 @@
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyQuest from '../../../website/common/script/ops/buyQuest';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyQuest from '../../../../website/common/script/ops/buyQuest';
|
||||
import {
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyQuest', () => {
|
||||
let user;
|
||||
@@ -1,14 +1,14 @@
|
||||
import buySpecialSpell from '../../../website/common/script/ops/buySpecialSpell';
|
||||
import buySpecialSpell from '../../../../website/common/script/ops/buySpecialSpell';
|
||||
import {
|
||||
BadRequest,
|
||||
NotFound,
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import content from '../../../website/common/script/content/index';
|
||||
} from '../../../helpers/common.helper';
|
||||
import content from '../../../../website/common/script/content/index';
|
||||
|
||||
describe('shared.ops.buySpecialSpell', () => {
|
||||
let user;
|
||||
@@ -138,6 +138,7 @@ describe('shared.ops.purchase', () => {
|
||||
user.balance = userGemAmount;
|
||||
user.stats.gp = goldPoints;
|
||||
user.purchased.plan.gemsBought = 0;
|
||||
user.purchased.plan.customerId = 'customer-id';
|
||||
});
|
||||
|
||||
it('purchases gems', () => {
|
||||
@@ -226,4 +227,39 @@ describe('shared.ops.purchase', () => {
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
context('bulk purchase', () => {
|
||||
let userGemAmount = 10;
|
||||
|
||||
before(() => {
|
||||
user.balance = userGemAmount;
|
||||
user.stats.gp = goldPoints;
|
||||
user.purchased.plan.gemsBought = 0;
|
||||
user.purchased.plan.customerId = 'customer-id';
|
||||
});
|
||||
|
||||
it('makes bulk purchases of gems', () => {
|
||||
let [, message] = purchase(user, {
|
||||
params: {type: 'gems', key: 'gem'},
|
||||
quantity: 2,
|
||||
});
|
||||
|
||||
expect(message).to.equal(i18n.t('plusOneGem'));
|
||||
expect(user.balance).to.equal(userGemAmount + 0.50);
|
||||
expect(user.purchased.plan.gemsBought).to.equal(2);
|
||||
expect(user.stats.gp).to.equal(goldPoints - planGemLimits.convRate * 2);
|
||||
});
|
||||
|
||||
it('makes bulk purchases of eggs', () => {
|
||||
let type = 'eggs';
|
||||
let key = 'TigerCub';
|
||||
|
||||
purchase(user, {
|
||||
params: {type, key},
|
||||
quantity: 2,
|
||||
});
|
||||
|
||||
expect(user.items[type][key]).to.equal(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -172,13 +172,13 @@ describe('shared.ops.rebirth', () => {
|
||||
expect(user.flags.levelDrops).to.be.empty;
|
||||
});
|
||||
|
||||
it('does not reset rebirthEnabled if user has beastMaster', () => {
|
||||
it('reset rebirthEnabled even if user has beastMaster', () => {
|
||||
user.achievements.beastMaster = 1;
|
||||
user.flags.rebirthEnabled = true;
|
||||
|
||||
rebirth(user);
|
||||
|
||||
expect(user.flags.rebirthEnabled).to.be.true;
|
||||
expect(user.flags.rebirthEnabled).to.be.false;
|
||||
});
|
||||
|
||||
it('sets rebirth achievement', () => {
|
||||
|
||||
@@ -19,4 +19,4 @@ echo Update npm...
|
||||
npm install -g npm@4
|
||||
|
||||
echo Installing global modules...
|
||||
npm install -g gulp bower grunt-cli mocha node-pre-gyp
|
||||
npm install -g gulp mocha node-pre-gyp
|
||||
|
||||
@@ -4,5 +4,5 @@ apt-get install -qq graphicsmagick
|
||||
echo Installing phantomjs and dependency...
|
||||
apt-get install -qq libicu48
|
||||
|
||||
echo Installing requirements for grunt-spritesmith...
|
||||
echo Installing requirements for gulp.spritesmith...
|
||||
apt-get install -qq pkg-config libcairo2-dev libjpeg-dev
|
||||
|
||||
@@ -105,7 +105,12 @@ const baseConfig = {
|
||||
{
|
||||
test: /\.svg$/,
|
||||
use: [
|
||||
{ loader: 'svg-url-loader' },
|
||||
{
|
||||
loader: 'svg-url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
},
|
||||
},
|
||||
{ loader: 'svgo-loader' },
|
||||
],
|
||||
include: [path.resolve(projectRoot, 'website/client/assets/svg/for-css')],
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user