def test_update_tree_returns_400_on_invalid_species_id(self): test_plot = mkPlot(self.user) mkTree(self.user, plot=test_plot) invalid_species_id = -1 self.assertRaises(Exception, Species.objects.get, pk=invalid_species_id) updated_values = {'tree': {'species': invalid_species_id}} response = put_json( "%s/plots/%d" % (API_PFX, test_plot.id), updated_values, self.client, self.sign) self.assertEqual(400, response.status_code) response_json = loads(response.content) self.assertTrue("error" in response_json.keys(), "Expected an 'error' key in the JSON response")
def test_get_current_tree(self): plot = mkPlot(self.user) plot_id = plot.pk tree = mkTree(self.user, plot=plot) response = self.client.get("%s/plots/%d/tree" % (API_PFX, plot_id), **self.sign) self.assertEqual(200, response.status_code, "Expected 200 status code after delete") response_dict = loads(response.content) self.assertTrue('species' in response_dict, 'Expected "species" to be a top level key in the response object') self.assertEqual(tree.species.pk, response_dict['species'])
def test_update_tree_species(self): test_plot = mkPlot(self.user) test_tree = mkTree(self.user, plot=test_plot) test_tree_id = test_tree.id first_species = Species.objects.all()[0] updated_values = {'tree': {'species': first_species.id}} response = put_json( "%s/plots/%d" % (API_PFX, test_plot.id), updated_values, self.client, self.sign) self.assertEqual(200, response.status_code) tree = Tree.objects.get(pk=test_tree_id) self.assertIsNotNone(tree) self.assertEqual(first_species, tree.species)
def test_update_tree(self): test_plot = mkPlot(self.user) test_tree = mkTree(self.user, plot=test_plot) test_tree_id = test_tree.id test_tree.dbh = 2.3 test_tree.save() updated_values = {'tree': {'dbh': 3.9}} response = put_json( "%s/plots/%d" % (API_PFX, test_plot.id), updated_values, self.client, self.sign) self.assertEqual(200, response.status_code) tree = Tree.objects.get(pk=test_tree_id) self.assertIsNotNone(tree) self.assertEqual(3.9, tree.dbh)
def test_approve_plot_pending_with_mutiple_pending_edits(self): settings.PENDING_ON = True test_plot = mkPlot(self.user) test_plot.width = 100 test_plot.length = 50 test_plot.save() test_tree = mkTree(self.user, plot=test_plot) test_tree.dbh = 2.3 test_tree.save() updated_values = { "plot_width": 125, "plot_length": 25, "tree": { "dbh": 3.9 } } response = put_json( "%s/plots/%d" % (API_PFX, test_plot.id), updated_values, self.client, self.public_user_sign) self.assertEqual(response.status_code, 200, "Non 200 response when updating plot") updated_values = { "plot_width": 175, } response = put_json( "%s/plots/%d" % (API_PFX, test_plot.id), updated_values, self.client, self.public_user_sign) self.assertEqual(response.status_code, 200, "Non 200 response when updating plot") test_plot = Plot.objects.get(pk=test_plot.pk) pending_edit_count = len(list(test_plot.get_active_pends_with_tree_pends())) self.assertEqual(4, pending_edit_count, "Expected three pending edits but got %d" % pending_edit_count) pend = test_plot.get_active_pends()[0] approved_pend_id = pend.id response = post_json("%s/pending-edits/%d/approve/" % (API_PFX, approved_pend_id), None, self.client, self.sign) self.assertEqual(response.status_code, 200, "Non 200 response when approving the pend") self.assertEqual(2, len(list(test_plot.get_active_pends_with_tree_pends())), "Expected there to be 2 pending edits after approval") for plot_pending in PlotPending.objects.all(): if plot_pending.id == approved_pend_id: self.assertEqual('approved', plot_pending.status, 'The status of the approved pend should be "approved"') elif plot_pending.field == 'width': self.assertEqual('rejected', plot_pending.status, 'The status of the non-approved width pends should be "rejected"') else: # plot_pending.id != approved_pend_id and plot_pending.field != 'width' self.assertEqual('pending', plot_pending.status, 'The status of plot pends not on the width field should still be "pending"') for tree_pending in TreePending.objects.all(): self.assertEqual('pending', tree_pending.status, 'The status of tree pends should still be "pending"')
def test_change_reputation_for_action_with_sub_actions(self): plot = mkPlot(self.jim) tree = mkTree(self.jim, plot=plot) reputation_count = UserReputationAction.objects.count() self.assertEqual(0, reputation_count) change_reputation_for_user(self.amy, 'edit verified', tree, sub_action='down', change_initiated_by_user=self.jim) self.assertEqual(1, UserReputationAction.objects.count()) reputation_action = UserReputationAction.objects.all()[0] self.assertEqual(self.amy.id, reputation_action.user.id) self.assertEqual(self.jim.id, reputation_action.originating_user.id) self.assertEqual(-10, reputation_action.value)
def test_change_reputation_for_action(self): plot = mkPlot(self.jim) tree = mkTree(self.jim, plot=plot) reputation_count = UserReputationAction.objects.count() self.assertEqual(0, reputation_count) change_reputation_for_user(self.jim, 'add tree', tree) self.assertEqual(1, UserReputationAction.objects.count()) reputation_action = UserReputationAction.objects.all()[0] self.assertEqual(self.jim.id, reputation_action.user.id) self.assertEqual(self.jim.id, reputation_action.originating_user.id) self.assertEqual(25, reputation_action.value)
def assert_pending_edit_operation(self, action, original_dbh=2.3, edited_dbh=3.9): settings.PENDING_ON = True test_plot = mkPlot(self.user) test_tree = mkTree(self.user, plot=test_plot) test_tree_id = test_tree.id test_tree.dbh = original_dbh test_tree.save() if action == 'approve': status_after_action = 'approved' elif action == 'reject': status_after_action = 'rejected' else: raise Exception('Action must be "approve" or "reject"') self.assertEqual(0, len(Pending.objects.all()), "Expected the test to start with no pending records") updated_values = {'tree': {'dbh': edited_dbh}} response = put_json( "%s/plots/%d" % (API_PFX, test_plot.id), updated_values, self.client, self.public_user_sign) self.assertEqual(200, response.status_code) tree = Tree.objects.get(pk=test_tree_id) self.assertIsNotNone(tree) self.assertEqual(original_dbh, tree.dbh, "A pend should have been created instead of editing the tree value.") self.assertEqual(1, len(TreePending.objects.all()), "Expected 1 pend record for the edited field.") pending_edit = TreePending.objects.all()[0] self.assertEqual('pending', pending_edit.status, "Expected the status of the Pending to be 'pending'") response = post_json("%s/pending-edits/%d/%s/" % (API_PFX, pending_edit.id, action), None, self.client, self.sign) self.assertEqual(200, response.status_code) pending_edit = TreePending.objects.get(pk=pending_edit.id) self.assertEqual(status_after_action, pending_edit.status, "Expected the status of the Pending to be '%s'" % status_after_action) test_tree = Tree.objects.get(pk=test_tree_id) if action == 'approve': self.assertEqual(edited_dbh, test_tree.dbh, "Expected dbh to have been updated on the Tree") elif action == 'reject': self.assertEqual(original_dbh, test_tree.dbh, "Expected dbh to NOT have been updated on the Tree") response_json = loads(response.content) self.assertTrue('tree' in response_json) self.assertTrue('dbh' in response_json['tree']) if action == 'approve': self.assertEqual(edited_dbh, response_json['tree']['dbh'], "Expected dbh to have been updated in the JSON response") elif action == 'reject': self.assertEqual(original_dbh, response_json['tree']['dbh'], "Expected dbh to NOT have been updated in the JSON response")
def test_update_tree_with_pending(self): settings.PENDING_ON = True test_plot = mkPlot(self.user) test_tree = mkTree(self.user, plot=test_plot) test_tree_id = test_tree.id test_tree.dbh = 2.3 test_tree.save() self.assertEqual(0, len(Pending.objects.all()), "Expected the test to start with no pending records") updated_values = {'tree': {'dbh': 3.9}} response = put_json( "%s/plots/%d" % (API_PFX, test_plot.id), updated_values, self.client, self.public_user_sign) self.assertEqual(200, response.status_code) tree = Tree.objects.get(pk=test_tree_id) self.assertIsNotNone(tree) self.assertEqual(2.3, tree.dbh, "A pend should have been created instead of editing the tree value.") self.assertEqual(1, len(TreePending.objects.all()), "Expected 1 pend record for the edited field.") response_json = loads(response.content) self.assertEqual(1, len(response_json['pending_edits'].keys()), "Expected the json response to have a pending_edits dict with 1 keys")
def test_remove_tree(self): plot = mkPlot(self.user) plot_id = plot.pk tree = mkTree(self.user, plot=plot) tree_id = tree.pk response = self.client.delete("%s/plots/%d/tree" % (API_PFX, plot_id), **self.sign) self.assertEqual(200, response.status_code, "Expected 200 status code after delete") response_dict = loads(response.content) self.assertIsNone(response_dict['tree'], 'Expected a json object response to a None value for "tree" key after the tree is deleted') plot = Plot.objects.get(pk=plot_id) tree = Tree.objects.get(pk=tree_id) self.assertTrue(plot.present, 'Expected "present" to be True after tree is deleted from plot') for audit_trail_record in plot.history.all(): self.assertTrue(audit_trail_record.present, 'Expected "present" to be True for all audit trail records for plot with a deleted tree') self.assertFalse(tree.present, 'Expected "present" to be False on tree associated with a deleted plot') for audit_trail_record in tree.history.all(): self.assertFalse(audit_trail_record.present, 'Expected "present" to be False for all audit trail records for tree associated with a deleted plot')
def test_remove_plot(self): plot = mkPlot(self.user) plot_id = plot.pk tree = mkTree(self.user, plot=plot) tree_id = tree.pk response = self.client.delete("%s/plots/%d" % (API_PFX, plot_id), **self.sign) self.assertEqual(200, response.status_code, "Expected 200 status code after delete") response_dict = loads(response.content) self.assertTrue('ok' in response_dict, 'Expected a json object response with a "ok" key') self.assertTrue(response_dict['ok'], 'Expected a json object response with a "ok" key set to True') plot = Plot.objects.get(pk=plot_id) tree = Tree.objects.get(pk=tree_id) self.assertFalse(plot.present, 'Expected "present" to be False on a deleted plot') for audit_trail_record in plot.history.all(): self.assertFalse(audit_trail_record.present, 'Expected "present" to be False for all audit trail records for a deleted plot') self.assertFalse(tree.present, 'Expected "present" to be False on tree associated with a deleted plot') for audit_trail_record in tree.history.all(): self.assertFalse(audit_trail_record.present, 'Expected "present" to be False for all audit trail records for tree associated with a deleted plot')
def test_tree_data(self): p = mkPlot(self.u) t = mkTree(self.u, plot=p) t.species = None t.dbh = None t.present = True t.save() info = self.client.get("%s/plots" % API_PFX, **self.sign) self.assertEqual(info.status_code, 200) json = loads(info.content) self.assertEqual(len(json), 1) record = json[0] self.assertEqual(record["tree"]["id"], t.pk) t.species = Species.objects.all()[0] t.dbh = 11.2 t.save() info = self.client.get("%s/plots" % API_PFX, **self.sign) self.assertEqual(info.status_code, 200) json = loads(info.content) self.assertEqual(len(json), 1) record = json[0] self.assertEqual(record["tree"]["species"], t.species.pk) self.assertEqual(record["tree"]["dbh"], t.dbh) self.assertEqual(record["tree"]["id"], t.pk)
def test_edit_flags(self): content_type_p = ContentType(app_label='auth', model='Plot') content_type_p.save() content_type_t = ContentType(app_label='auth', model='Tree') content_type_t.save() p = P(codename="change_user",name="change_user",content_type=content_type_p) p.save() t = P(codename="change_user",name="change_user",content_type=content_type_t) t.save() ghost = AnonymousUser() peon = User(username="******") peon.save() peon.reputation = Reputation(user=peon) peon.reputation.save() duke = User(username="******") duke.save() duke.reputation = Reputation(user=duke) duke.reputation.save() leroi = User(username="******") leroi.active = True leroi.save() # double save required for m2m... leroi.reputation = Reputation(user=leroi) leroi.user_permissions.add(p) leroi.user_permissions.add(t) leroi.save() leroi.reputation.save() p_peon_0 = mkPlot(peon) p_peon_1 = mkPlot(peon) p_duke_2 = mkPlot(duke) t_duke_0 = mkTree(duke, plot=p_peon_0) t_peon_1 = mkTree(peon, plot=p_peon_1) t_duke_2 = mkTree(duke, plot=p_duke_2) p_roi_3 = mkPlot(leroi) t_roi_3 = mkTree(leroi, plot=p_roi_3) plots = [p_peon_0, p_peon_1, p_duke_2, p_roi_3] trees = [t_duke_0, t_peon_1, t_duke_2, t_roi_3] users = [ghost, peon, duke, leroi] def mkd(e, d): return { "can_delete": d, "can_edit": e } def mkdp(pe, pd, te=None, td=None): d = { "plot": mkd(pe,pd) } if td != None and te != None: d["tree"] = mkd(te, td) return d ################################# # A None or Anonymous user can't # do anything for p in plots: self.assertEqual(mkd(False,False), plot_or_tree_permissions(p, ghost)) self.assertEqual(mkdp(False,False,False,False), plot_permissions(p, ghost)) self.assertEqual(mkd(False,False), plot_or_tree_permissions(p, None)) self.assertEqual(mkdp(False,False,False,False), plot_permissions(p, None)) for t in trees: self.assertEqual(mkd(False,False), plot_or_tree_permissions(t, ghost)) self.assertEqual(mkd(False,False), plot_or_tree_permissions(t, None)) ################################# # A user can always delete or edit their own trees and plots # self.assertEqual(mkd(True,True), plot_or_tree_permissions(p_peon_0, peon)) self.assertEqual(mkd(True,True), plot_or_tree_permissions(p_peon_1, peon)) self.assertEqual(mkd(True,True), plot_or_tree_permissions(p_duke_2, duke)) self.assertEqual(mkd(True,True), plot_or_tree_permissions(t_duke_0, duke)) self.assertEqual(mkd(True,True), plot_or_tree_permissions(t_peon_1, peon)) self.assertEqual(mkd(True,True), plot_or_tree_permissions(t_duke_2, duke)) self.assertEqual(mkd(True,True), plot_or_tree_permissions(p_roi_3, leroi)) self.assertEqual(mkd(True,True), plot_or_tree_permissions(t_roi_3, leroi)) ################################# # An admin user can always do anything # for p in plots: self.assertEqual(mkd(True,True), plot_or_tree_permissions(p, leroi)) self.assertEqual(mkdp(True,True,True,True), plot_permissions(p, leroi)) for t in trees: self.assertEqual(mkd(True,True), plot_or_tree_permissions(t, leroi)) ################################# # A user can edit other trees but can't delete # self.assertEqual(mkdp(True,False,True,False), plot_permissions(p_roi_3, duke)) ################################# # No one can edit readonly trees # for p in plots: p.readonly = True p.save() for t in trees: t.readonly = True t.save() for p in plots: for u in users: self.assertEqual(mkd(False,False), plot_or_tree_permissions(p, u)) self.assertEqual(mkdp(False,False,False,False), plot_permissions(p, u)) for t in trees: for u in users: self.assertEqual(mkd(False,False), plot_or_tree_permissions(t, u))
def test_recent_edits(self): user = self.u p = mkPlot(user) p2 = mkPlot(user) t3 = mkTree(user) acts = ReputationAction.objects.all() content_type_p = ContentType(app_label='auth', model='Plot') content_type_p.save() reputation1 = UserReputationAction(action=acts[0], user=user, originating_user=user, content_type=content_type_p, object_id=p.pk, content_object=p, value=20) reputation1.save() auth = base64.b64encode("%s:%s" % (user.username,user.username)) withauth = dict(create_signer_dict(user).items() + [("HTTP_AUTHORIZATION", "Basic %s" % auth)]) ret = self.client.get("%s/user/%s/edits" % (API_PFX, user.pk), **withauth) json = loads(ret.content) self.assertEqual(len(json), 1) # Just on reputation item self.assertEqual(json[0]['plot_id'], p.pk) self.assertEqual(json[0]['id'], reputation1.pk) reputation2 = UserReputationAction(action=acts[1 % len(acts)], user=user, originating_user=user, content_type=content_type_p, object_id=p2.pk, content_object=p2, value=20) reputation2.save() ret = self.client.get("%s/user/%s/edits" % (API_PFX, user.pk), **withauth) json = loads(ret.content) self.assertEqual(len(json), 2) # Just on reputation item self.assertEqual(json[0]['plot_id'], p2.pk) self.assertEqual(json[0]['id'], reputation2.pk) self.assertEqual(json[1]['plot_id'], p.pk) self.assertEqual(json[1]['id'], reputation1.pk) reputation3 = UserReputationAction(action=acts[2 % len(acts)], user=user, originating_user=user, content_type=content_type_p, object_id=t3.pk, content_object=t3, value=20) reputation3.save() ret = self.client.get("%s/user/%s/edits" % (API_PFX, user.pk), **withauth) json = loads(ret.content) self.assertEqual(len(json), 3) # Just on reputation item self.assertEqual(json[0]['plot_id'], t3.plot.pk) self.assertEqual(json[0]['id'], reputation3.pk) self.assertEqual(json[1]['plot_id'], p2.pk) self.assertEqual(json[1]['id'], reputation2.pk) self.assertEqual(json[2]['plot_id'], p.pk) self.assertEqual(json[2]['id'], reputation1.pk) ret = self.client.get("%s/user/%s/edits?offset=1" % (API_PFX, user.pk), **withauth) json = loads(ret.content) self.assertEqual(len(json), 2) # Just on reputation item self.assertEqual(json[0]['plot_id'], p2.pk) self.assertEqual(json[0]['id'], reputation2.pk) self.assertEqual(json[1]['plot_id'], p.pk) self.assertEqual(json[1]['id'], reputation1.pk) ret = self.client.get("%s/user/%s/edits?offset=2&length=1" % (API_PFX, user.pk), **withauth) json = loads(ret.content) self.assertEqual(len(json), 1) # Just on reputation item self.assertEqual(json[0]['plot_id'], p.pk) self.assertEqual(json[0]['id'], reputation1.pk) ret = self.client.get("%s/user/%s/edits?length=1" % (API_PFX, user.pk), **withauth) json = loads(ret.content) self.assertEqual(len(json), 1) # Just on reputation item self.assertEqual(json[0]['plot_id'], t3.plot.pk) self.assertEqual(json[0]['id'], reputation3.pk) reputation1.delete() reputation2.delete() reputation3.delete() content_type_p.delete() p.delete() p2.delete() t3.delete()