def create_test_numeric_goal(self): goal = Goal(setup.get_test_user(), "Test Numeric goal", "How many goals have you created today?", "weekly", 7, "numeric", "daily") goal.persist() return goal
def create_test_binary_goal(self): goal = Goal(setup.get_test_user(), "Test Binary goal", "Have you created a goal today?", "weekly", 7, "binary", "daily") goal.persist() return goal
def create_test_goals(): user = create_test_user() for x in range(ord('a'), ord('a') + 25): x = chr(x) name = "test goal " + str(x) new_goal = Goal(user, name, "Is this a test?", "daily", 10, "numeric", "daily") new_goal.created = new_goal.created - datetime.timedelta(hours=30-(ord(x)-ord('a'))) db.session.add(new_goal) db.session.flush() db.session.commit()
def create_goal(): validate_form(request.form, [ "name", "prompt", "frequency", "target", "input_type", "check_in_frequency" ]) goal = Goal(current_user, request.form['name'], request.form['prompt'], request.form['frequency'], request.form['target'], request.form['input_type'], request.form['check_in_frequency']) goal.persist() return goal.to_json(), 201
def create_goal(): validate_form(request.form, ["name", "prompt", "frequency", "target", "input_type", "check_in_frequency"]) goal = Goal(current_user, request.form['name'], request.form['prompt'], request.form['frequency'], request.form['target'], request.form['input_type'], request.form['check_in_frequency']) goal.persist() return goal.to_json(), 201
def pull_by_goal_start_end(self, goal, start, end): """Return an array of check-ins given a goal ID and start date and an end date""" goal = Goal.pull_by_id(goal) timeframes = Timeframe.get_timeframes(goal.check_in_frequency_name, start, end) timeframes = [x.get_id() for x in timeframes] return self.pull_by_goal_timeframes(goal.get_id(), timeframes)
def get_goal(id): goal = Goal.pull_by_id(id) if (not goal): raise NotFoundError() if (not goal.public and goal.user != current_user.get_id()): raise UnauthorizedError() return goal.to_json(), HTTP_200_OK
def update_goal(): validate_form(request.form, ['id']) goal = Goal.pull_by_id(request.form['id']) if (not goal): raise NotFoundError() if (goal.user != current_user.get_id()): raise UnauthorizedError() goal.update(request.form) return empty_ok()
def get_goals_by_user(id): """Show all public goals for a given user""" user = User.pull_by_id(id) if (not user): raise NotFoundError() validate_sort(request.args, ["id", "created", "name", "frequency"]) goals = Goal.pull_by_user(id, request.args, True) return jsonify({"goals": [x.to_dict() for x in goals]}), HTTP_200_OK
def test_persist( self): ## This sorta also tests pull by ID and exists(), fwiw goal = self.create_test_goal() ## Calls persist self.assertTrue(goal.exists()) check = Goal.pull_by_id(goal.id) self.assertEqual(goal, check) with self.assertRaisesRegexp(goly.errors.ResourceAlreadyExistsError, "Unable to create goal"): goal.persist()
def get_current_check_in(id): """Get the current check-in for a given goal. Returns 404 if the current check-in or goal does not exist""" goal = Goal.pull_by_id(id) if (not goal): raise NotFoundError() if goal.user != current_user.get_id(): raise UnauthorizedError check_in = CheckIn.pull_by_goal_timeframe(id, Timeframe.get_current_timeframe(goal.check_in_frequency_name).get_id()) if (not check_in): raise NotFoundError() return check_in.to_json(), 200
def get_check_in(id, tfid): """Get the check-in for a given timeframe. Returns 404 if there is no check-in for that timeframe""" goal = Goal.pull_by_id(id) if (not goal): raise NotFoundError() if goal.user != current_user.get_id(): raise UnauthorizedError check_in = CheckIn.pull_by_goal_timeframe(id, tfid) if (not check_in): raise NotFoundError() return check_in.to_json(), 200
def check_in(id): validate_form(request.form, ["value"]) goal = Goal.pull_by_id(id) if (not goal): raise NotFoundError() if goal.user != current_user.get_id(): raise UnauthorizedError if ('timeframe' in request.form): timeframe = Timeframe.pull_by_id(request.form['timeframe']) else: timeframe = Timeframe.get_current_timeframe(goal.check_in_frequency_name) check_in = CheckIn(goal, timeframe, request.form['value']) return_code = 200 if check_in.exists() else 201 check_in.persist() return check_in.to_json(), return_code
def get_by_time(id): goal = Goal.pull_by_id(id) if (not goal): raise NotFoundError() if goal.user != current_user.get_id(): raise UnauthorizedError if (not 'start' in request.args or not 'end' in request.args): raise InvalidRequest(["start and end are required parameters"]) try: start = datetime.datetime.strptime(request.args['start'], "%Y-%m-%d %H:%M:%S") end = datetime.datetime.strptime(request.args['end'], "%Y-%m-%d %H:%M:%S") except ValueError as e: raise InvalidRequest([e.message]) check_ins = CheckIn.pull_by_goal_start_end(id, start, end) return jsonify({"check-ins": [check_in.to_dict() for check_in in check_ins]}), 200
def test_create(self): # Requires login: res = self.test_client.post("/goals/create/", data=self.new_goal) setup.assertRequiresLogin(self, res) self.login() ## Test that it rejects bad inputs bad_goal = self.new_goal.copy() bad_goal['name'] = None res = self.test_client.post("/goals/create/", data=bad_goal) setup.assertInvalid(self, res, "name") bad_goal['name'] = self.new_goal['name'] bad_goal['prompt'] = "" res = self.test_client.post("/goals/create/", data=bad_goal) setup.assertBadData(self, res, "Prompt must be between 0 and 255 characters") ## Test that it actually registers at all :-) res = self.test_client.post("/goals/create/", data=self.new_goal) setup.assertOk(self, res, 201) data = json.loads(res.data) self.assertIn('id', data) goal = Goal.pull_by_id(data['id']) self.assertIsNotNone(goal) for key, val in self.new_goal.iteritems(): self.assertEqual(val, data[key]) if (key == 'frequency' or key == 'check_in_frequency'): self.assertEqual(val, Frequency.get_name_by_id(getattr(goal, key))) else: self.assertEqual(val, getattr(goal, key)) ## Shouldn't be able to register something that already exists res = self.test_client.post("/goals/create/", data=self.new_goal) self.assertEqual(res.status_code, 409) data = json.loads(res.data) self.assertIn('detail', data) self.assertIn('Test goal already exists', data['detail'])
def get_my_goals(): """Return all goals (public and private) for the current user""" validate_sort(request.args, ["id", "created", "name", "frequency"]) goals = Goal.pull_by_user(current_user.get_id(), request.args, False) return jsonify({"goals": [x.to_dict() for x in goals]}), HTTP_200_OK
def test_update(self): ## Requires login res = self.test_client.post("/goals/update/", data={'id': 0}) setup.assertRequiresLogin(self, res) ## Validates form self.login() res = self.test_client.post("/goals/update/", data={'favorite_muppet': 'kermit'}) setup.assertInvalid(self, res, 'id') ## 404's res = self.test_client.post("/goals/update/", data={'id': 0, 'name': 'test goal 2.0'}) setup.assert404(self, res) ## Actually works goal = self.create_test_goal() data = {'id': goal['id']} data['name'] = "Test Goal 2.0" data['prompt'] = "Guess how many eggs I had for breakfast today!" data['frequency'] = "monthly" data['target'] = 100 data['input_type'] = "binary" data['active'] = False data['public'] = True data['check_in_frequency'] = "daily" res = self.test_client.post("/goals/update/", data=data) setup.assertOk(self, res, 200) updated_goal = Goal.pull_by_id(goal['id']) for key, val in data.iteritems(): if (key == 'frequency' or key == 'check_in_frequency'): self.assertEqual(Frequency.get_name_by_id(getattr(updated_goal, key)), val) else: self.assertEqual(getattr(updated_goal, key), val) ## If any part is invalid, no part should go through bad_data = {'id': goal['id']} bad_data['name'] = "Test Goal 3.0" bad_data['prompt'] = "How many jars of sand did you collect?" bad_data['frequency'] = "daily" bad_data['target'] = 1000 bad_data['input_type'] = "numeric" bad_data['active'] = True bad_data['public'] = "banana" bad_data['check_in_frequency'] = "daily" res = self.test_client.post("/goals/update/", data=bad_data) setup.assertBadData(self, res, "Public must be a boolean") updated_goal = Goal.pull_by_id(goal['id']) for key, val in data.iteritems(): if (key == 'frequency' or key == 'check_in_frequency'): self.assertEqual(Frequency.get_name_by_id(getattr(updated_goal, key)), val) else: self.assertEqual(getattr(updated_goal, key), val) ## Can't update someone else's goal self.logout() self.login_other_user() res = self.test_client.post("/goals/update/", data=bad_data) ## using bad_data here ensures we don't update setup.assertInvalidCredentials(self, res)
def delete_goal(): validate_form(request.form, ['id']) Goal.delete(current_user.get_id(), request.form['id']) return empty_ok(204)
def test_update(self): goal = self.create_test_goal() with self.assertRaisesRegexp(goly.errors.ResourceAlreadyExistsError, "Unable to create goal"): goal.update({"name": goal.name}) data = { "name": "New test name", "prompt": "New test prompt", "frequency": "yearly", "check_in_frequency": "quarterly", "target": 100, "input_type": "numeric", "active": False, "public": True } goal.update(data) for attr, name in data.iteritems(): if (attr in ['check_in_frequency', 'frequency']): self.assertEqual(Frequency.get_name_by_id(getattr(goal, attr)), data[attr]) else: self.assertEqual(getattr(goal, attr), data[attr]) check = Goal.pull_by_id(goal.get_id()) ## make sure these persisted for attr, name in data.iteritems(): if (attr in ['check_in_frequency', 'frequency']): self.assertEqual(Frequency.get_name_by_id(getattr(goal, attr)), data[attr]) else: self.assertEqual(getattr(goal, attr), data[attr]) with self.assertRaisesRegexp(AssertionError, "Name must be between 0 and 50"): goal.update({"name": " "}) with self.assertRaisesRegexp(AssertionError, "Name must be between 0 and 50"): goal.update({"name": "a" * 51}) with self.assertRaisesRegexp(AssertionError, "Prompt must be between 0 and 255"): goal.update({"prompt": " "}) with self.assertRaisesRegexp(AssertionError, "Prompt must be between 0 and 255"): goal.update({"prompt": "a" * 256}) with self.assertRaisesRegexp(AssertionError, "frequency must be one of "): goal.update({"frequency": "not-an-option"}) with self.assertRaisesRegexp(AssertionError, "Target must be an integer"): goal.update({"target": "banana"}) with self.assertRaisesRegexp(AssertionError, "Input type must be binary or numeric"): goal.update({"input_type": "pineapple"}) with self.assertRaisesRegexp(AssertionError, "Active must be a boolean"): goal.update({'active': "fish"}) with self.assertRaisesRegexp(AssertionError, "Public must be a boolean"): goal.update({"public": "filet"}) with self.assertRaisesRegexp(AssertionError, "check_in_frequency must be one of"): goal.update( {"check_in_frequency": "whenever I feel like it, gosh"}) with self.assertRaisesRegexp(AssertionError, "Check-in frequency must conform"): goal.update({"check_in_frequency": "weekly"})
def reconstruct(self): self.goal_obj = Goal.pull_by_id(self.goal) self.timeframe_obj = Timeframe.pull_by_id(self.timeframe)
def test_update(self): ## Requires login res = self.test_client.post("/goals/update/", data={'id': 0}) setup.assertRequiresLogin(self, res) ## Validates form self.login() res = self.test_client.post("/goals/update/", data={'favorite_muppet': 'kermit'}) setup.assertInvalid(self, res, 'id') ## 404's res = self.test_client.post("/goals/update/", data={ 'id': 0, 'name': 'test goal 2.0' }) setup.assert404(self, res) ## Actually works goal = self.create_test_goal() data = {'id': goal['id']} data['name'] = "Test Goal 2.0" data['prompt'] = "Guess how many eggs I had for breakfast today!" data['frequency'] = "monthly" data['target'] = 100 data['input_type'] = "binary" data['active'] = False data['public'] = True data['check_in_frequency'] = "daily" res = self.test_client.post("/goals/update/", data=data) setup.assertOk(self, res, 200) updated_goal = Goal.pull_by_id(goal['id']) for key, val in data.iteritems(): if (key == 'frequency' or key == 'check_in_frequency'): self.assertEqual( Frequency.get_name_by_id(getattr(updated_goal, key)), val) else: self.assertEqual(getattr(updated_goal, key), val) ## If any part is invalid, no part should go through bad_data = {'id': goal['id']} bad_data['name'] = "Test Goal 3.0" bad_data['prompt'] = "How many jars of sand did you collect?" bad_data['frequency'] = "daily" bad_data['target'] = 1000 bad_data['input_type'] = "numeric" bad_data['active'] = True bad_data['public'] = "banana" bad_data['check_in_frequency'] = "daily" res = self.test_client.post("/goals/update/", data=bad_data) setup.assertBadData(self, res, "Public must be a boolean") updated_goal = Goal.pull_by_id(goal['id']) for key, val in data.iteritems(): if (key == 'frequency' or key == 'check_in_frequency'): self.assertEqual( Frequency.get_name_by_id(getattr(updated_goal, key)), val) else: self.assertEqual(getattr(updated_goal, key), val) ## Can't update someone else's goal self.logout() self.login_other_user() res = self.test_client.post( "/goals/update/", data=bad_data) ## using bad_data here ensures we don't update setup.assertInvalidCredentials(self, res)
def create_test_goal(self): goal = Goal(self.test_user, "test goal", "is this goal a test?", "weekly", 10, "binary", "daily") goal.persist() return goal
class TestCheckIn(unittest.TestCase): test_tf = Timeframe("daily", datetime.datetime(2016, 1, 1)) test_user = setup.create_test_user() test_binary_goal = Goal(test_user, "test binary goal", "is this goal a test?", "weekly", 10, "binary", "daily") test_numeric_goal = Goal(test_user, "test numeric goal", "is this goal a test?", "weekly", 10, "numeric", "daily") test_binary_goal.persist() test_numeric_goal.persist() @classmethod def startUpClass(self): Goal.query.delete() db.session.commit() @classmethod def tearDownClass(self): CheckIn.query.delete() Goal.query.delete() db.session.commit() def startUp(self): CheckIn.query.delete() def tearDown(self): CheckIn.query.delete() def test_init(self): ## Should fail if bogus goal is specified with self.assertRaisesRegexp(AssertionError, "Passed goal must be a goal object"): ci = CheckIn("bogus", self.test_tf, 1) ## Should fail if not a timeframe with self.assertRaisesRegexp(AssertionError, "Passed timeframe must be a timeframe object"): ci = CheckIn(self.test_numeric_goal, "bogus", 1) ## Should fail if timeframe doesn't conform: with self.assertRaisesRegexp(AssertionError, "Passed timeframe frequency must match"): ci = CheckIn(self.test_numeric_goal, Timeframe("weekly", datetime.datetime(2016,2,7)), 1) ## Should fail if numeric and a boolean is passed with self.assertRaisesRegexp(AssertionError, "Value must be numeric"): ci = CheckIn(self.test_numeric_goal, self.test_tf, "orange you glad I didn't say banana?'") ## Should fail if binary and a number is passed with self.assertRaisesRegexp(AssertionError, "Value must be a boolean"): ci = CheckIn(self.test_binary_goal, self.test_tf, 30) ## Should actually work if everything is provided correctly ci = CheckIn(self.test_numeric_goal, self.test_tf, 30) self.assertEqual(ci.goal_obj, self.test_numeric_goal) self.assertEqual(ci.goal, self.test_numeric_goal.get_id()) self.assertEqual(ci.timeframe_obj, self.test_tf) self.assertEqual(ci.timeframe, self.test_tf.get_id()) self.assertEqual(ci.value, 30) ci = CheckIn(self.test_binary_goal, self.test_tf, True) self.assertEqual(ci.goal_obj, self.test_binary_goal) self.assertEqual(ci.goal, self.test_binary_goal.get_id()) self.assertEqual(ci.timeframe_obj, self.test_tf) self.assertEqual(ci.timeframe, self.test_tf.get_id()) self.assertEqual(ci.value, 1) def test_persist(self): ## also tests exists, really -- and pull_by_id ci = self.get_test_check_in() self.assertFalse(ci.exists()) ci.persist() self.assertTrue(ci.exists()) self.assertIsNotNone(ci.get_id()) self.assertEqual(ci.to_dict(), CheckIn.pull_by_id(ci.get_id()).to_dict()) ## now if you overwrite that it should still work. ci = CheckIn(self.test_numeric_goal, self.test_tf, 60) self.assertTrue(ci.exists()) ci.persist() test_ci = CheckIn.pull_by_id(ci.get_id()) self.assertEqual(ci.to_dict(), test_ci.to_dict()) self.assertEqual(test_ci.value, 60) def test_pull_by_goal_timeframe(self): ci = CheckIn.pull_by_goal_timeframe(self.test_numeric_goal.get_id(), self.test_tf.get_id()) self.assertIsNone(ci) ci = self.get_test_check_in() ci.persist() test_ci = CheckIn.pull_by_goal_timeframe(self.test_numeric_goal.get_id(), self.test_tf.get_id()) self.assertEqual(ci.to_dict(), test_ci.to_dict()) def test_destroy(self): ci = self.get_test_check_in() ci.persist() self.assertTrue(ci.exists()) ci.destroy() self.assertFalse(ci.exists()) def test_pull_by_goal_start_end(self): ci = self.get_test_check_in() ci.persist() for x in range(0, 7): tf = ci.timeframe_obj new_tf = Timeframe(tf.frequency_name, tf.start + datetime.timedelta(1)) ci = CheckIn(ci.goal_obj, new_tf, x) ci.persist() cis = CheckIn.pull_by_goal_start_end(ci.goal, datetime.datetime(2016, 1, 1), datetime.datetime(2016, 1, 8)) self.assertEqual(len(cis), 7) def test_pull_by_goal_timeframes(self): ci = self.get_test_check_in() timeframes = [ci.timeframe] ci.persist() for x in range(0, 7): tf = ci.timeframe_obj new_tf = Timeframe(tf.frequency_name, tf.start + datetime.timedelta(1)) timeframes.append(new_tf.get_id()) ci = CheckIn(ci.goal_obj, new_tf, x) ci.persist() cis = CheckIn.pull_by_goal_timeframes(ci.goal, timeframes) self.assertEqual(len(cis), 8) def get_test_check_in(self): return CheckIn(self.test_numeric_goal, self.test_tf, 30)
def test_init(self): ## Test that all of the validators work! fake_user = User("notreal", "notreal", "notreal", "notreal") with self.assertRaisesRegexp(AssertionError, "user does not exist"): goal = Goal(fake_user, "test name", "test prompt", "weekly", 10, "binary", "daily") with self.assertRaisesRegexp(AssertionError, "user must be a User"): goal = Goal("Jimmy", "test", "test prompt", "weekly", 10, "binary", "daily") with self.assertRaisesRegexp(AssertionError, "Name must be between 0 and 50"): goal = Goal(self.test_user, " ", "test prompt", "weekly", 10, "binary", "daily") with self.assertRaisesRegexp(AssertionError, "Name must be between 0 and 50"): goal = Goal(self.test_user, "a" * 51, "test prompt", "weekly", 10, "binary", "daily") with self.assertRaisesRegexp(AssertionError, "Prompt must be between 0 and 255"): goal = Goal(self.test_user, "test", " ", "weekly", 10, "binary", "daily") with self.assertRaisesRegexp(AssertionError, "Prompt must be between 0 and 255"): goal = Goal(self.test_user, "test", "a" * 256, "weekly", 10, "binary", "daily") with self.assertRaisesRegexp(AssertionError, "frequency must be one of "): goal = Goal(self.test_user, "test", "test prompt", "not-an-option", 10, "binary", "daily") with self.assertRaisesRegexp(AssertionError, "Target must be an integer"): goal = Goal(self.test_user, "test", "test prompt", "weekly", "banana", "binary", "daily") with self.assertRaisesRegexp(AssertionError, "Input type must be binary or numeric"): goal = Goal(self.test_user, "test", "test prompt", "weekly", 10, "banana", "daily") with self.assertRaisesRegexp(AssertionError, "check_in_frequency must be one of"): goal = Goal(self.test_user, "test", "test prompt", "weekly", 10, "numeric", "only on fudge sundaes") with self.assertRaisesRegexp( AssertionError, "Check-in frequency must conform to frequency"): goal = Goal(self.test_user, "test", "test prompt", "weekly", 10, "numeric", "monthly") goal = Goal(self.test_user, "test", "test prompt", "weekly", "10", "binary", "daily") self.assertIsInstance(goal, Goal) self.assertTrue(goal.active) self.assertFalse(goal.public) with self.assertRaisesRegexp(AssertionError, "Active must be a boolean"): goal.active = "fish" with self.assertRaisesRegexp(AssertionError, "Public must be a boolean"): goal.public = "filet"