From c2614c0447fa0417cf65facae057de28b4ddf3db Mon Sep 17 00:00:00 2001 From: TheHollidayInn Date: Tue, 7 Apr 2015 19:40:54 -0500 Subject: [PATCH 01/13] Moved if statement to assign task completion before saving task to user --- website/src/controllers/user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/src/controllers/user.js b/website/src/controllers/user.js index 0fb27aef1b..df14373818 100644 --- a/website/src/controllers/user.js +++ b/website/src/controllers/user.js @@ -99,9 +99,11 @@ api.score = function(req, res, next) { text: req.body && req.body.text, notes: (req.body && req.body.notes) || "This task was created by a third-party service. Feel free to edit, it won't harm the connection to that service. Additionally, multiple services may piggy-back off this task." }; - task = user.ops.addTask({body:task}); + if (task.type === 'daily' || task.type === 'todo') task.completed = direction === 'up'; + + task = user.ops.addTask({body:task}); } var delta = user.ops.score({params:{id:task.id, direction:direction}, language: req.language}); From 31f61c05f4797933d4eb2bde1ed753436ce862ab Mon Sep 17 00:00:00 2001 From: TheHollidayInn Date: Wed, 10 Jun 2015 23:10:37 -0500 Subject: [PATCH 02/13] Added tests for using directional tasks endpoints --- test/api/todos.coffee | 63 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/test/api/todos.coffee b/test/api/todos.coffee index b5f8d7fe3e..86eff59bd2 100644 --- a/test/api/todos.coffee +++ b/test/api/todos.coffee @@ -97,6 +97,36 @@ describe "Todos", -> expect(todo.value).to.equal 0 done() + it "Creates a completed a todo when using up url", (done) -> + upTodo = undefined + request.post(baseURL + "/user/tasks/withUp/up").send( + type: "todo" + text: "testTitle" + complete: true + description: "testDesc" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withUp") + .send().end (res) -> + upTodo = res.body + expect(upTodo.completed).to.equal true + done() + + it "Creates an uncompleted todo when using down url", (done) -> + downTodo = undefined + request.post(baseURL + "/user/tasks/withDown/down").send( + type: "todo" + text: "testTitle" + complete: true + description: "testDesc" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withDown") + .send().end (res) -> + downTodo = res.body + expect(downTodo.completed).to.equal false + done() + it "Does not create a todo with an id that already exists", (done) -> original_todo = { type: "todo" @@ -160,7 +190,7 @@ describe "Todos", -> ).end (res) -> expectCode res, 200 body = res.body - expect(body).to.be.empty + expect(body).to.be.empty done() it "Does not delete already deleted todo", (done) -> @@ -184,3 +214,34 @@ describe "Todos", -> expect(body.err).to.equal "Task not found." done() +describe "habits", -> + + it "Creates a completed a habit when using up url", (done) -> + upHabit = undefined + request.post(baseURL + "/user/tasks/withUp/up").send( + type: "habit" + text: "testTitle" + complete: true + description: "testDesc" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withUp") + .send().end (res) -> + upHabit = res.body + expect(upHabit.completed).to.equal true + done() + + it "Creates an uncompleted todo when using down url", (done) -> + downHabit = undefined + request.post(baseURL + "/user/tasks/withDown/down").send( + type: "habit" + text: "testTitle" + complete: true + description: "testDesc" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withDown") + .send().end (res) -> + downHabit = res.body + expect(downHabit.completed).to.equal false + done() From 8d20168b6b76b7268d0a969f8a9296d9e7a39efe Mon Sep 17 00:00:00 2001 From: TheHollidayInn Date: Thu, 11 Jun 2015 23:38:44 -0500 Subject: [PATCH 03/13] Added up and down test to complete and uncomplete a todo respectively. --- test/api/todos.coffee | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/api/todos.coffee b/test/api/todos.coffee index 86eff59bd2..ae95814a80 100644 --- a/test/api/todos.coffee +++ b/test/api/todos.coffee @@ -184,6 +184,43 @@ describe "Todos", -> expect(todo.notes).to.equal "Some notes" done() + it "It completes a todo when using up url", (done) -> + unCompletedTodo = undefined + request.post(baseURL + "/user/tasks").send( + type: "todo" + text: "Sample Todo" + ).end (res) -> + expectCode res, 200 + unCompletedTodo = res.body + expect(unCompletedTodo.completed).to.equal false + request.post(baseURL + "/user/tasks/"+unCompletedTodo._id+"/up").send( + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/"+unCompletedTodo._id) + .send().end (res) -> + unCompletedTodo = res.body + expect(unCompletedTodo.completed).to.equal true + done() + + it "It uncompletes a todo when using down url", (done) -> + completedTodo = undefined + request.post(baseURL + "/user/tasks").send( + type: "todo" + text: "Sample Todo" + completed: true + ).end (res) -> + expectCode res, 200 + completedTodo = res.body + expect(completedTodo.completed).to.equal true + request.post(baseURL + "/user/tasks/"+completedTodo._id+"/down").send( + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/"+completedTodo._id) + .send().end (res) -> + completedTodo = res.body + expect(completedTodo.completed).to.equal false + done() + describe "Deleting todos", -> it "Does delete todo", (done) -> request.del(baseURL + "/user/tasks/" + todo.id).send( From 3dc3891ec6e093f205bff7758ea759a53db1d84f Mon Sep 17 00:00:00 2001 From: TheHollidayInn Date: Tue, 16 Jun 2015 20:19:02 -0500 Subject: [PATCH 04/13] Fixed habit tests to create habits and check scoring --- test/api/todos.coffee | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/api/todos.coffee b/test/api/todos.coffee index ae95814a80..3de65e9aa6 100644 --- a/test/api/todos.coffee +++ b/test/api/todos.coffee @@ -253,32 +253,34 @@ describe "Todos", -> describe "habits", -> - it "Creates a completed a habit when using up url", (done) -> + it "Creates and scores up a habit when using up url", (done) -> upHabit = undefined - request.post(baseURL + "/user/tasks/withUp/up").send( + request.post(baseURL + "/user/tasks/habitWithUp/up").send( type: "habit" text: "testTitle" complete: true description: "testDesc" ).end (res) -> expectCode res, 200 - request.get(baseURL + "/user/tasks/withUp") + request.get(baseURL + "/user/tasks/habitWithUp") .send().end (res) -> upHabit = res.body - expect(upHabit.completed).to.equal true + expect(upHabit.value).to.be.at.least(1); + expect(upHabit.type).to.equal("habit"); done() - it "Creates an uncompleted todo when using down url", (done) -> + it "Creates and scores down a habit when using down url", (done) -> downHabit = undefined - request.post(baseURL + "/user/tasks/withDown/down").send( + request.post(baseURL + "/user/tasks/habitWithDown/down").send( type: "habit" text: "testTitle" complete: true description: "testDesc" ).end (res) -> expectCode res, 200 - request.get(baseURL + "/user/tasks/withDown") + request.get(baseURL + "/user/tasks/habitWithDown") .send().end (res) -> downHabit = res.body - expect(downHabit.completed).to.equal false + expect(downHabit.value).to.have.at.most(-1); + expect(downHabit.type).to.equal("habit"); done() From 925cc81425806d3d668401bee2830ad5e592132a Mon Sep 17 00:00:00 2001 From: TheHollidayInn Date: Thu, 18 Jun 2015 23:10:50 -0500 Subject: [PATCH 05/13] Removed complete param from creating todos with up and down url and added test for overriding complete parameter --- test/api/todos.coffee | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/test/api/todos.coffee b/test/api/todos.coffee index 3de65e9aa6..9157bc3187 100644 --- a/test/api/todos.coffee +++ b/test/api/todos.coffee @@ -101,8 +101,7 @@ describe "Todos", -> upTodo = undefined request.post(baseURL + "/user/tasks/withUp/up").send( type: "todo" - text: "testTitle" - complete: true + text: "withUp" description: "testDesc" ).end (res) -> expectCode res, 200 @@ -116,8 +115,7 @@ describe "Todos", -> downTodo = undefined request.post(baseURL + "/user/tasks/withDown/down").send( type: "todo" - text: "testTitle" - complete: true + text: "withDown" description: "testDesc" ).end (res) -> expectCode res, 200 @@ -127,6 +125,36 @@ describe "Todos", -> expect(downTodo.completed).to.equal false done() + it "Creates a completed a todo overriding the complete parameter when using up url", (done) -> + upTodo = undefined + request.post(baseURL + "/user/tasks/withUpWithComplete/up").send( + type: "todo" + text: "withUpWithComplete" + complete: false + description: "testDesc" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withUpWithComplete") + .send().end (res) -> + upTodo = res.body + expect(upTodo.completed).to.equal true + done() + + it "Creates an uncompleted todo verriding the complete when using down url", (done) -> + downTodo = undefined + request.post(baseURL + "/user/tasks/withDownWithUncomplete/down").send( + type: "todo" + text: "withDownWithUncomplete" + complete: true + description: "testDesc" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withDownWithUncomplete") + .send().end (res) -> + downTodo = res.body + expect(downTodo.completed).to.equal false + done() + it "Does not create a todo with an id that already exists", (done) -> original_todo = { type: "todo" From 83089720c8e69a2186b9249238483929ba96c3be Mon Sep 17 00:00:00 2001 From: Alys Date: Sat, 20 Jun 2015 09:17:32 +1000 Subject: [PATCH 06/13] Update migration script that sets Ultimate Gear object in user accounts to ensure true OR false values for all classes. Ref https://github.com/HabitRPG/habitrpg/issues/5427 --- migrations/20150604_ultimateGearSets.js | 70 +++++++++++++++---------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/migrations/20150604_ultimateGearSets.js b/migrations/20150604_ultimateGearSets.js index 2a060dcb68..3e3c53997b 100644 --- a/migrations/20150604_ultimateGearSets.js +++ b/migrations/20150604_ultimateGearSets.js @@ -1,13 +1,22 @@ -/** - * Created by Sabe on 6/3/2015. - */ +// var migrationName = '20150604_ultimateGearSets'; +// var authorName = 'Sabe'; // in case script author needs to know when their ... +// var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done -var migrationName = '20150604_ultimateGearSets'; -var authorName = process.env.AUTHOR_NAME || 'Sabe'; // in case script author needs to know when their ... -var authorUuid = process.env.AUTHOR_UUID || '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done +var migrationName = '20150620_ultimateGearSets'; +var authorName = 'Alys'; // in case script author needs to know when their ... +var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done /* * grant the new ultimateGearSets achievement for existing users' collected equipment + * + * + * Changed by Alys on 20150620 to assign false values to + * 'achievements.ultimateGearSets' when true values are not appropriate, + * because of https://github.com/HabitRPG/habitrpg/issues/5427 + * + * Minimal changes were made so the code isn't as efficient or clean + * as it could be, but it's (hopefully) one-use-only and minimal changes + * means minimal new testing. */ var dbserver = 'localhost:27017' // FOR TEST DATABASE @@ -24,25 +33,10 @@ var fields = { 'items.gear.owned':1 }; + +// Changes 20150620: All users have to be processed now (non-achievers need +// false values). var query = { - // 'auth.timestamps.loggedin':{$lte:new Date('2015-05-22')}, - $or: [ - {'items.gear.owned.weapon_wizard_6': {$exists: true}}, - {'items.gear.owned.armor_wizard_5': {$exists: true}}, - {'items.gear.owned.head_wizard_5': {$exists: true}}, - {'items.gear.owned.weapon_warrior_6': {$exists: true}}, - {'items.gear.owned.armor_warrior_5': {$exists: true}}, - {'items.gear.owned.head_warrior_5': {$exists: true}}, - {'items.gear.owned.shield_warrior_5': {$exists: true}}, - {'items.gear.owned.weapon_healer_6': {$exists: true}}, - {'items.gear.owned.armor_healer_5': {$exists: true}}, - {'items.gear.owned.head_healer_5': {$exists: true}}, - {'items.gear.owned.shield_healer_5': {$exists: true}}, - {'items.gear.owned.weapon_rogue_6': {$exists: true}}, - {'items.gear.owned.armor_rogue_5': {$exists: true}}, - {'items.gear.owned.head_rogue_5': {$exists: true}}, - {'items.gear.owned.shield_rogue_6': {$exists: true}} - ] }; console.warn('Updating users...'); @@ -58,6 +52,8 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) { var achievements = {}; var changeUser = false; + // Changes 20150620: 'changeUser' now indicates that the user must have the + // Enchanted Armoire unlocked. if ( (typeof user.items.gear.owned.weapon_wizard_6 !== 'undefined') && (typeof user.items.gear.owned.armor_wizard_5 !== 'undefined') && (typeof user.items.gear.owned.head_wizard_5 !== 'undefined') @@ -65,6 +61,11 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) { achievements['wizard'] = true; changeUser = true; } + else { + // Changes 20150620: false added for all classes (here and below) + achievements['wizard'] = false; + } + if ( (typeof user.items.gear.owned.weapon_warrior_6 !== 'undefined') && (typeof user.items.gear.owned.armor_warrior_5 !== 'undefined') && (typeof user.items.gear.owned.head_warrior_5 !== 'undefined') @@ -73,6 +74,10 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) { achievements['warrior'] = true; changeUser = true; } + else { + achievements['warrior'] = false; + } + if ( (typeof user.items.gear.owned.weapon_healer_6 !== 'undefined') && (typeof user.items.gear.owned.armor_healer_5 !== 'undefined') && (typeof user.items.gear.owned.head_healer_5 !== 'undefined') @@ -81,6 +86,10 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) { achievements['healer'] = true; changeUser = true; } + else { + achievements['healer'] = false; + } + if ( (typeof user.items.gear.owned.weapon_rogue_6 !== 'undefined') && (typeof user.items.gear.owned.armor_rogue_5 !== 'undefined') && (typeof user.items.gear.owned.head_rogue_5 !== 'undefined') @@ -89,12 +98,17 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) { achievements['rogue'] = true; changeUser = true; } - - if (changeUser) { - var set = {'migration':migrationName, 'achievements.ultimateGearSets':achievements, 'flags.armoireEnabled':true}; - dbUsers.update({_id:user._id}, {$set:set}); + else { + achievements['rogue'] = false; } + // Changes 20150620: $set is now run for all users. + var set = {'migration':migrationName, 'achievements.ultimateGearSets':achievements}; + if (changeUser) { // user has at least one Ultimate Gear achievement + set['flags.armoireEnabled'] = true; + } + dbUsers.update({_id:user._id}, {$set:set}); + if (count%progressCount == 0) console.warn(count + ' ' + user._id); if (user._id == authorUuid) console.warn(authorName + ' processed'); if (user._id == '9' ) console.warn('lefnire' + ' processed'); From 2acf7eb71e7cfa54d2e34f0a9738ffd140add40d Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Fri, 19 Jun 2015 23:50:46 -0500 Subject: [PATCH 07/13] Move score tests to separate file --- test/api/score.coffee | 114 +++++++++++++++++++++++++++++++++++++ test/api/todos.coffee | 129 ------------------------------------------ 2 files changed, 114 insertions(+), 129 deletions(-) create mode 100644 test/api/score.coffee diff --git a/test/api/score.coffee b/test/api/score.coffee new file mode 100644 index 0000000000..a3b1b41826 --- /dev/null +++ b/test/api/score.coffee @@ -0,0 +1,114 @@ +'use strict' + +require("../../website/src/server") + +describe "Score", -> + before (done) -> + registerNewUser done, true + + context "Todos that did not previously exist", -> + it "creates a completed a todo when using up url", (done) -> + request.post(baseURL + "/user/tasks/withUp/up").send( + type: "todo" + text: "withUp" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withUp").end (res) -> + upTodo = res.body + expect(upTodo.completed).to.equal true + done() + + it "creates an uncompleted todo when using down url", (done) -> + request.post(baseURL + "/user/tasks/withDown/down").send( + type: "todo" + text: "withDown" + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withDown").end (res) -> + downTodo = res.body + expect(downTodo.completed).to.equal false + done() + + it "creates a completed a todo overriding the complete parameter when using up url", (done) -> + request.post(baseURL + "/user/tasks/withUpWithComplete/up").send( + type: "todo" + text: "withUpWithComplete" + completed: false + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withUpWithComplete").end (res) -> + upTodo = res.body + expect(upTodo.completed).to.equal true + done() + + it "Creates an uncompleted todo overriding the completed parameter when using down url", (done) -> + request.post(baseURL + "/user/tasks/withDownWithUncomplete/down").send( + type: "todo" + text: "withDownWithUncomplete" + completed: true + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/withDownWithUncomplete").end (res) -> + downTodo = res.body + expect(downTodo.completed).to.equal false + done() + + context "Todo that already exists", -> + it "It completes a todo when using up url", (done) -> + request.post(baseURL + "/user/tasks").send( + type: "todo" + text: "Sample Todo" + ).end (res) -> + expectCode res, 200 + unCompletedTodo = res.body + expect(unCompletedTodo.completed).to.equal false + request.post(baseURL + "/user/tasks/"+unCompletedTodo._id+"/up").end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/"+unCompletedTodo._id).end (res) -> + unCompletedTodo = res.body + expect(unCompletedTodo.completed).to.equal true + done() + + it "It uncompletes a todo when using down url", (done) -> + request.post(baseURL + "/user/tasks").send( + type: "todo" + text: "Sample Todo" + completed: true + ).end (res) -> + expectCode res, 200 + completedTodo = res.body + expect(completedTodo.completed).to.equal true + request.post(baseURL + "/user/tasks/"+completedTodo._id+"/down").end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/"+completedTodo._id).end (res) -> + completedTodo = res.body + expect(completedTodo.completed).to.equal false + done() + + it "Creates and scores up a habit when using up url", (done) -> + upHabit = undefined + request.post(baseURL + "/user/tasks/habitWithUp/up").send( + type: "habit" + text: "testTitle" + completed: true + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/habitWithUp").end (res) -> + upHabit = res.body + expect(upHabit.value).to.be.at.least(1) + expect(upHabit.type).to.equal("habit") + done() + + it "Creates and scores down a habit when using down url", (done) -> + downHabit = undefined + request.post(baseURL + "/user/tasks/habitWithDown/down").send( + type: "habit" + text: "testTitle" + completed: true + ).end (res) -> + expectCode res, 200 + request.get(baseURL + "/user/tasks/habitWithDown").end (res) -> + downHabit = res.body + expect(downHabit.value).to.have.at.most(-1) + expect(downHabit.type).to.equal("habit") + done() diff --git a/test/api/todos.coffee b/test/api/todos.coffee index 9157bc3187..7b57378bf4 100644 --- a/test/api/todos.coffee +++ b/test/api/todos.coffee @@ -97,64 +97,6 @@ describe "Todos", -> expect(todo.value).to.equal 0 done() - it "Creates a completed a todo when using up url", (done) -> - upTodo = undefined - request.post(baseURL + "/user/tasks/withUp/up").send( - type: "todo" - text: "withUp" - description: "testDesc" - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/withUp") - .send().end (res) -> - upTodo = res.body - expect(upTodo.completed).to.equal true - done() - - it "Creates an uncompleted todo when using down url", (done) -> - downTodo = undefined - request.post(baseURL + "/user/tasks/withDown/down").send( - type: "todo" - text: "withDown" - description: "testDesc" - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/withDown") - .send().end (res) -> - downTodo = res.body - expect(downTodo.completed).to.equal false - done() - - it "Creates a completed a todo overriding the complete parameter when using up url", (done) -> - upTodo = undefined - request.post(baseURL + "/user/tasks/withUpWithComplete/up").send( - type: "todo" - text: "withUpWithComplete" - complete: false - description: "testDesc" - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/withUpWithComplete") - .send().end (res) -> - upTodo = res.body - expect(upTodo.completed).to.equal true - done() - - it "Creates an uncompleted todo verriding the complete when using down url", (done) -> - downTodo = undefined - request.post(baseURL + "/user/tasks/withDownWithUncomplete/down").send( - type: "todo" - text: "withDownWithUncomplete" - complete: true - description: "testDesc" - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/withDownWithUncomplete") - .send().end (res) -> - downTodo = res.body - expect(downTodo.completed).to.equal false - done() - it "Does not create a todo with an id that already exists", (done) -> original_todo = { type: "todo" @@ -212,43 +154,6 @@ describe "Todos", -> expect(todo.notes).to.equal "Some notes" done() - it "It completes a todo when using up url", (done) -> - unCompletedTodo = undefined - request.post(baseURL + "/user/tasks").send( - type: "todo" - text: "Sample Todo" - ).end (res) -> - expectCode res, 200 - unCompletedTodo = res.body - expect(unCompletedTodo.completed).to.equal false - request.post(baseURL + "/user/tasks/"+unCompletedTodo._id+"/up").send( - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/"+unCompletedTodo._id) - .send().end (res) -> - unCompletedTodo = res.body - expect(unCompletedTodo.completed).to.equal true - done() - - it "It uncompletes a todo when using down url", (done) -> - completedTodo = undefined - request.post(baseURL + "/user/tasks").send( - type: "todo" - text: "Sample Todo" - completed: true - ).end (res) -> - expectCode res, 200 - completedTodo = res.body - expect(completedTodo.completed).to.equal true - request.post(baseURL + "/user/tasks/"+completedTodo._id+"/down").send( - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/"+completedTodo._id) - .send().end (res) -> - completedTodo = res.body - expect(completedTodo.completed).to.equal false - done() - describe "Deleting todos", -> it "Does delete todo", (done) -> request.del(baseURL + "/user/tasks/" + todo.id).send( @@ -278,37 +183,3 @@ describe "Todos", -> body = res.body expect(body.err).to.equal "Task not found." done() - -describe "habits", -> - - it "Creates and scores up a habit when using up url", (done) -> - upHabit = undefined - request.post(baseURL + "/user/tasks/habitWithUp/up").send( - type: "habit" - text: "testTitle" - complete: true - description: "testDesc" - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/habitWithUp") - .send().end (res) -> - upHabit = res.body - expect(upHabit.value).to.be.at.least(1); - expect(upHabit.type).to.equal("habit"); - done() - - it "Creates and scores down a habit when using down url", (done) -> - downHabit = undefined - request.post(baseURL + "/user/tasks/habitWithDown/down").send( - type: "habit" - text: "testTitle" - complete: true - description: "testDesc" - ).end (res) -> - expectCode res, 200 - request.get(baseURL + "/user/tasks/habitWithDown") - .send().end (res) -> - downHabit = res.body - expect(downHabit.value).to.have.at.most(-1); - expect(downHabit.type).to.equal("habit"); - done() From 02acad9dfc1a443eb33b4794e3a8519af5fd7b8e Mon Sep 17 00:00:00 2001 From: hairlessbear Date: Sat, 20 Jun 2015 01:38:47 -0400 Subject: [PATCH 08/13] Removed unused 'armorSet' attribute in user model --- website/src/models/user.js | 1 - 1 file changed, 1 deletion(-) diff --git a/website/src/models/user.js b/website/src/models/user.js index 7a45250308..c77df6ab56 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -296,7 +296,6 @@ var UserSchema = new Schema({ } }, preferences: { - armorSet: String, dayStart: {type:Number, 'default': 0, min: 0, max: 23}, size: {type:String, enum: ['broad','slim'], 'default': 'slim'}, hair: { From 6eac1174a2c2fb73808b8f5f8388e3c73b763520 Mon Sep 17 00:00:00 2001 From: Alys Date: Sat, 20 Jun 2015 20:22:27 +1000 Subject: [PATCH 09/13] sort eligibleEquipment before choosing random item from Enchaned Armoire - possible partial fix for https://github.com/HabitRPG/habitrpg/issues/5376#issuecomment-111799217 --- common/script/index.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/common/script/index.coffee b/common/script/index.coffee index cc055a0b8d..1b04cd98ac 100644 --- a/common/script/index.coffee +++ b/common/script/index.coffee @@ -882,6 +882,7 @@ api.wrap = (user, main=true) -> # the same seed would give one of the first five foods only. eligibleEquipment = _.filter(content.gear.flat, ((i)->i.klass is 'armoire' and !user.items.gear.owned[i.key])) if !_.isEmpty(eligibleEquipment) and (armoireResult < .6 or !user.flags.armoireOpened) + eligibleEquipment.sort() # https://github.com/HabitRPG/habitrpg/issues/5376#issuecomment-111799217 drop = user.fns.randomVal(eligibleEquipment) user.items.gear.owned[drop.key] = true user.flags.armoireOpened = true From 837c26415d14feeb9bec039e3544fc373c3242be Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sat, 20 Jun 2015 10:02:46 -0500 Subject: [PATCH 10/13] Update node version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8ba1ff5cb2..e6a638ab72 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "www.habitrpg.com" ], "engines": { - "node": "0.10.x" + "node": "0.12.4" }, "scripts": { "test": "./node_modules/.bin/gulp test", From 944cef4d44d75897c54ba084d431d0d7c2c7cc58 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sat, 20 Jun 2015 14:48:38 -0500 Subject: [PATCH 11/13] Switch over to using sinon.sandbox in karma specs --- test/spec/app.js | 9 ++------- test/spec/controllers/authCtrlSpec.js | 12 +++++------ test/spec/controllers/groupCtrlSpec.js | 20 +++++++++---------- test/spec/controllers/hallCtrlSpec.js | 7 ++----- test/spec/controllers/headerCtrlSpec.js | 9 ++------- test/spec/controllers/rootCtrlSpec.js | 15 ++++---------- .../directives/focus-me.directive.spec.js | 2 +- .../directives/from-now.directive.spec.js | 2 +- test/spec/filters/taskOrderingSpec.js | 5 +++-- .../spec/services/notificationServicesSpec.js | 10 ++-------- test/spec/services/userServicesSpec.js | 2 +- test/spec/specHelper.js | 10 ++++++++++ 12 files changed, 44 insertions(+), 59 deletions(-) diff --git a/test/spec/app.js b/test/spec/app.js index 6567bf9ef6..8a80b435be 100644 --- a/test/spec/app.js +++ b/test/spec/app.js @@ -4,13 +4,8 @@ describe('AppJS', function() { describe('Automatic page refresh', function(){ var clock; beforeEach(function () { - clock = sinon.useFakeTimers(); - sinon.stub(window, "refresher", function(){return true}); - }); - - afterEach(function () { - clock.restore(); - window.refresher.restore(); + clock = sandbox.useFakeTimers(); + sandbox.stub(window, "refresher", function(){return true}); }); it('should not call refresher if idle time is less than 6 hours', function() { diff --git a/test/spec/controllers/authCtrlSpec.js b/test/spec/controllers/authCtrlSpec.js index 598fe0dee4..70e985d76d 100644 --- a/test/spec/controllers/authCtrlSpec.js +++ b/test/spec/controllers/authCtrlSpec.js @@ -10,8 +10,8 @@ describe('Auth Controller', function() { scope = $rootScope.$new(); scope.loginUsername = 'user'; scope.loginPassword = 'pass'; - $window = { location: { href: ""}, alert: sinon.spy() }; - user = { user: {}, authenticate: sinon.spy() }; + $window = { location: { href: ""}, alert: sandbox.spy() }; + user = { user: {}, authenticate: sandbox.spy() }; ctrl = $controller('AuthCtrl', {$scope: scope, $window: $window, User: user}); })); @@ -20,16 +20,16 @@ describe('Auth Controller', function() { $httpBackend.expectPOST('/api/v2/user/auth/local').respond({id: 'abc', token: 'abc'}); scope.auth(); $httpBackend.flush(); - sinon.assert.calledOnce(user.authenticate); - sinon.assert.notCalled($window.alert); + expect(user.authenticate).to.be.calledOnce; + expect($window.alert).to.not.be.called; }); it('should not log in users with incorrect uname / pass', function() { $httpBackend.expectPOST('/api/v2/user/auth/local').respond(404, ''); scope.auth(); $httpBackend.flush(); - sinon.assert.notCalled(user.authenticate); - sinon.assert.calledOnce($window.alert); + expect(user.authenticate).to.not.be.called; + expect($window.alert).to.be.calledOnce; }); }); diff --git a/test/spec/controllers/groupCtrlSpec.js b/test/spec/controllers/groupCtrlSpec.js index a85cb7b810..58f0e197c3 100644 --- a/test/spec/controllers/groupCtrlSpec.js +++ b/test/spec/controllers/groupCtrlSpec.js @@ -30,7 +30,7 @@ describe('Groups Controller', function() { party.type = 'party'; party.members = []; // Ensure we wouldn't pass automatically. - var partyStub = sinon.stub(groups,"party", function() { + var partyStub = sandbox.stub(groups,"party", function() { return party; }); @@ -44,7 +44,7 @@ describe('Groups Controller', function() { guild.type = 'guild'; guild.members.push(user._id); - var myGuilds = sinon.stub(groups,"myGuilds", function() { + var myGuilds = sandbox.stub(groups,"myGuilds", function() { return [guild]; }); @@ -58,7 +58,7 @@ describe('Groups Controller', function() { guild._id = "unique-guild-id"; guild.type = 'guild'; - var myGuilds = sinon.stub(groups,"myGuilds", function() { + var myGuilds = sandbox.stub(groups,"myGuilds", function() { return []; }); @@ -98,7 +98,7 @@ describe("Chat Controller", function() { name: "Princess Bride" }; - var modalSpy = sinon.spy($rootScope, "openModal"); + var modalSpy = sandbox.spy($rootScope, "openModal"); var message = { uuid: 'the-dread-pirate-roberts', user: 'Wesley', @@ -120,7 +120,7 @@ describe("Chat Controller", function() { name: "Princess Bride" }; - var modalSpy = sinon.spy($rootScope, "openModal"); + var modalSpy = sandbox.spy($rootScope, "openModal"); var message = { uuid: 'system', text: 'Wesley attacked the ROUS in the Fire Swamp' @@ -221,7 +221,7 @@ describe("Autocomplete controller", function() { describe("performCompletion", function() { it('triggers autoComplete', function() { - scope.autoComplete = sinon.spy(); + scope.autoComplete = sandbox.spy(); var msg = {user: "boo"}; // scope.autoComplete only cares about user scope.query = {text: "b"}; @@ -247,7 +247,7 @@ describe("Autocomplete controller", function() { describe("chatChanged", function() { it('if a new chat arrives, the new user name is extracted', function() { - var chatChanged = sinon.spy(scope, 'chatChanged'); + var chatChanged = sandbox.spy(scope, 'chatChanged'); scope.$watch('group.chat',scope.chatChanged); // reinstantiate watch so spy works scope.$digest(); // trigger watch @@ -269,11 +269,11 @@ describe("CopyMessageModal controller", function() { user = specHelper.newUser(); user._id = "unique-user-id"; user.ops = { - addTask: sinon.spy() + addTask: sandbox.spy() }; scope = $rootScope.$new(); - scope.$close = sinon.spy(); + scope.$close = sandbox.spy(); $controller = _$controller_; @@ -283,7 +283,7 @@ describe("CopyMessageModal controller", function() { ctrl = $controller('CopyMessageModalCtrl', {$scope: scope, User: {user: user}}); Notification = _Notification_; - Notification.text = sinon.spy(); + Notification.text = sandbox.spy(); }); }); diff --git a/test/spec/controllers/hallCtrlSpec.js b/test/spec/controllers/hallCtrlSpec.js index 15367b5728..5ad0e32c98 100644 --- a/test/spec/controllers/hallCtrlSpec.js +++ b/test/spec/controllers/hallCtrlSpec.js @@ -22,15 +22,12 @@ describe('Hall of Heroes Controller', function() { }); it('populates contributor input with selected hero id', function(){ - var loadHero = sinon.spy(scope, "loadHero"); - var scrollTo = sinon.spy(window, "scrollTo"); + 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); - - scope.loadHero.restore(); - window.scrollTo.restore(); }); }); diff --git a/test/spec/controllers/headerCtrlSpec.js b/test/spec/controllers/headerCtrlSpec.js index 4060519fde..ab37d11205 100644 --- a/test/spec/controllers/headerCtrlSpec.js +++ b/test/spec/controllers/headerCtrlSpec.js @@ -26,13 +26,8 @@ describe('Header Controller', function() { context('inviteOrStartParty', function(){ beforeEach(function(){ - sinon.stub($location, 'path'); - sinon.stub($rootScope, 'openModal'); - }); - - afterEach(function(){ - $location.path.restore(); - $rootScope.openModal.restore(); + sandbox.stub($location, 'path'); + sandbox.stub($rootScope, 'openModal'); }); it('redirects to party page if user does not have a party', function(){ diff --git a/test/spec/controllers/rootCtrlSpec.js b/test/spec/controllers/rootCtrlSpec.js index 15ee64e1cf..648de78d9f 100644 --- a/test/spec/controllers/rootCtrlSpec.js +++ b/test/spec/controllers/rootCtrlSpec.js @@ -24,13 +24,13 @@ describe('Root Controller', function() { $httpBackend = _$httpBackend_; notification = Notification; - sinon.stub(notification, 'text'); - sinon.stub(notification, 'markdown'); + sandbox.stub(notification, 'text'); + sandbox.stub(notification, 'markdown'); user = specHelper.newUser(); User = {user: user}; - User.save = sinon.spy(); - User.sync = sinon.spy(); + User.save = sandbox.spy(); + User.sync = sandbox.spy(); $httpBackend.whenGET(/partials/).respond(); @@ -38,13 +38,6 @@ describe('Root Controller', function() { }); }); - afterEach(function() { - notification.text.reset(); - notification.markdown.reset(); - User.save.reset(); - User.sync.reset(); - }); - describe('contribText', function(){ it('shows contributor level text', function(){ expect(scope.contribText()).to.eql(undefined); diff --git a/test/spec/directives/focus-me.directive.spec.js b/test/spec/directives/focus-me.directive.spec.js index ed016949c3..c91b36a2f3 100644 --- a/test/spec/directives/focus-me.directive.spec.js +++ b/test/spec/directives/focus-me.directive.spec.js @@ -16,7 +16,7 @@ describe('focusMe Directive', function() { it('focuses the element when appended to the DOM', function() { inject(function($timeout) { - var focusSpy = sinon.spy(); + var focusSpy = sandbox.spy(); element.appendTo(document.body); element.on('focus', focusSpy); diff --git a/test/spec/directives/from-now.directive.spec.js b/test/spec/directives/from-now.directive.spec.js index a197f2c331..d39fd4e5ad 100644 --- a/test/spec/directives/from-now.directive.spec.js +++ b/test/spec/directives/from-now.directive.spec.js @@ -11,7 +11,7 @@ describe('fromNow Directive', function() { scope = $rootScope.$new(); scope.message = {}; - sinon.stub(window, 'moment').returns({ + sandbox.stub(window, 'moment').returns({ fromNow: function() { return fromNow }, diff: function() { return diff } }); diff --git a/test/spec/filters/taskOrderingSpec.js b/test/spec/filters/taskOrderingSpec.js index 989a56c7e8..46a9162c49 100644 --- a/test/spec/filters/taskOrderingSpec.js +++ b/test/spec/filters/taskOrderingSpec.js @@ -1,10 +1,11 @@ 'use strict'; describe('Task Ordering Filters', function() { - var filter - , orderBySpy = sinon.spy(); + var filter, orderBySpy; beforeEach(function() { + orderBySpy = sandbox.spy(); + module(function($provide) { $provide.value('orderByFilter', orderBySpy); }); diff --git a/test/spec/services/notificationServicesSpec.js b/test/spec/services/notificationServicesSpec.js index a55cf513cc..277e4431b2 100644 --- a/test/spec/services/notificationServicesSpec.js +++ b/test/spec/services/notificationServicesSpec.js @@ -3,13 +3,11 @@ describe('notificationServices', function() { var notification; - before(function(){ - sinon.stub($, 'pnotify', function(){ + beforeEach(function() { + sandbox.stub($, 'pnotify', function(){ return { click: function(){}} }); - }); - beforeEach(function() { module(function($provide){ $provide.value('User', {}); }); @@ -19,10 +17,6 @@ describe('notificationServices', function() { }); }); - afterEach(function() { - $.pnotify.reset(); - }); - it('notifies coins amount', function() { var SILVER_COIN = ""; var GOLD_COIN = ""; diff --git a/test/spec/services/userServicesSpec.js b/test/spec/services/userServicesSpec.js index 4a361e0b1a..5861f76d8b 100644 --- a/test/spec/services/userServicesSpec.js +++ b/test/spec/services/userServicesSpec.js @@ -7,7 +7,7 @@ describe('userServices', function() { beforeEach(function(){ module(function($provide){ - $window = {href: '', alert: sinon.spy(), location: {search: '', pathname: ''}}; + $window = {href: '', alert: sandbox.spy(), location: {search: '', pathname: ''}}; $provide.value('$window', $window); }); diff --git a/test/spec/specHelper.js b/test/spec/specHelper.js index 80f5858fe8..9ddacdac52 100644 --- a/test/spec/specHelper.js +++ b/test/spec/specHelper.js @@ -1,5 +1,15 @@ beforeEach(module('habitrpg')); +var sandbox; + +beforeEach(function() { + sandbox = sinon.sandbox.create(); +}); + +afterEach(function() { + sandbox.restore(); +}); + specHelper = { newUser: function(){ var buffs = {per:0, int:0, con:0, str:0, stealth: 0, streaks: false}; From ab53391feed0f9a58dda96bf8de3185e030296d0 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sat, 20 Jun 2015 15:00:30 -0500 Subject: [PATCH 12/13] Convert analytics service to use sinon.sandbox --- test/spec/services/analyticsServicesSpec.js | 39 +++++---------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/test/spec/services/analyticsServicesSpec.js b/test/spec/services/analyticsServicesSpec.js index ee1fa936a1..a03b962694 100644 --- a/test/spec/services/analyticsServicesSpec.js +++ b/test/spec/services/analyticsServicesSpec.js @@ -15,11 +15,7 @@ describe('Analytics Service', function () { context('error handling', function() { beforeEach(function() { - sinon.stub(console, 'log'); - }); - - afterEach(function() { - console.log.restore(); + sandbox.stub(console, 'log'); }); it('does not accept tracking events without required properties', function() { @@ -42,15 +38,9 @@ describe('Analytics Service', function () { context('Amplitude', function() { beforeEach(function() { - sinon.stub(amplitude, 'setUserId'); - sinon.stub(amplitude, 'logEvent'); - sinon.stub(amplitude, 'setUserProperties'); - }); - - afterEach(function() { - amplitude.setUserId.restore(); - amplitude.logEvent.restore(); - amplitude.setUserProperties.restore(); + sandbox.stub(amplitude, 'setUserId'); + sandbox.stub(amplitude, 'logEvent'); + sandbox.stub(amplitude, 'setUserProperties'); }); it('sets up tracking when user registers', function() { @@ -85,11 +75,7 @@ describe('Analytics Service', function () { context('Google Analytics', function() { beforeEach(function() { - sinon.stub(window, 'ga'); - }); - - afterEach(function() { - window.ga.restore(); + sandbox.stub(window, 'ga'); }); it('sets up tracking when user registers', function() { @@ -126,17 +112,10 @@ describe('Analytics Service', function () { context.skip('Mixpanel', function() { // Mixpanel not currently in use beforeEach(function() { - sinon.stub(mixpanel, 'alias'); - sinon.stub(mixpanel, 'identify'); - sinon.stub(mixpanel, 'track'); - sinon.stub(mixpanel, 'register'); - }); - - afterEach(function() { - mixpanel.alias.restore(); - mixpanel.identify.restore(); - mixpanel.track.restore(); - mixpanel.register.restore(); + sandbox.stub(mixpanel, 'alias'); + sandbox.stub(mixpanel, 'identify'); + sandbox.stub(mixpanel, 'track'); + sandbox.stub(mixpanel, 'register'); }); it('sets up tracking when user registers', function() { From 71fad8ca978cc0e95648b833f416fcc1262299fb Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sat, 20 Jun 2015 15:50:06 -0500 Subject: [PATCH 13/13] Provide user for anaylitcs service test --- test/spec/services/analyticsServicesSpec.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/spec/services/analyticsServicesSpec.js b/test/spec/services/analyticsServicesSpec.js index a03b962694..026ec77664 100644 --- a/test/spec/services/analyticsServicesSpec.js +++ b/test/spec/services/analyticsServicesSpec.js @@ -4,9 +4,17 @@ 'use strict'; describe('Analytics Service', function () { - var analytics; + var analytics, user; beforeEach(function() { + user = specHelper.newUser(); + user.contributor = { level: 1 }; + user.purchased = { plan: true }; + + module(function($provide) { + $provide.value('User', {user: user}); + }); + inject(function(Analytics) { analytics = Analytics; });