def test_record_is_created_when_nullables_are_still_pending(self): new_plot = Plot(geom=self.p1, instance=self.instance) new_plot.save_with_user(self.pending_user) new_tree = Tree(plot=new_plot, instance=self.instance, diameter=10, height=10, readonly=False) new_tree.save_with_user(self.pending_user) approve_or_reject_audits_and_apply( new_plot.audits(), self.commander_user, True) insert_audit = Audit.objects.filter(model='Tree')\ .get(field='id') field_audits = Audit.objects.filter(model='Tree')\ .filter(field__in=['readonly', 'diameter', 'plot']) for audit in field_audits: approve_or_reject_audit_and_apply( audit, self.commander_user, approved=True) approve_or_reject_audit_and_apply(insert_audit, self.commander_user, True) real_tree = Tree.objects.get(pk=new_tree.pk) self.assertEqual(real_tree.plot_id, new_plot.pk) self.assertEqual(real_tree.diameter, 10) self.assertEqual(real_tree.height, None) self.assertNotEqual(real_tree.readonly, True)
def test_approve_insert_without_required_raises_integrity_error(self): new_plot = Plot(geom=self.p1, instance=self.instance) new_plot.save_with_user(self.pending_user) new_tree = Tree(plot=new_plot, instance=self.instance, diameter=10, height=10, readonly=False) new_tree.save_with_user(self.pending_user) approve_or_reject_audits_and_apply(new_plot.audits(), self.commander_user, True) diameter_audit = Audit.objects.get(model='Tree', field='diameter', model_id=new_tree.pk) insert_audit = Audit.objects.get(model='Tree', model_id=new_tree.pk, field='id') approve_or_reject_audit_and_apply(diameter_audit, self.commander_user, approved=True) self.assertRaises(IntegrityError, approve_or_reject_audit_and_apply, insert_audit, self.commander_user, True)
class AuditDetailTagTest(OTMTestCase): def setUp(self): self.p1 = Point(-8515222.0, 4953200.0) self.instance = make_instance(point=self.p1) self.user = make_commander_user(self.instance) self.plot = Plot(geom=self.p1, instance=self.instance) self.plot.save_with_user(self.user) self.tree = Tree( plot=self.plot, instance=self.instance, readonly=False) self.tree.save_with_user(self.user) def test_tree_link(self): audit = self.tree.audits()[0] link = audit_detail_link(audit) target = reverse('tree_detail', kwargs={'instance_url_name': self.instance.url_name, 'feature_id': self.tree.plot.pk, 'tree_id': self.tree.pk}) self.assertEqual(link, target) def test_plot_link(self): audit = self.plot.audits()[0] link = audit_detail_link(audit) target = reverse('map_feature_detail', kwargs={'instance_url_name': self.instance.url_name, 'feature_id': self.plot.pk}) self.assertEqual(link, target) def test_bad_model_returns_none(self): audit = self.plot.audits()[0] audit.model = 'invaild' self.assertIsNone(audit_detail_link(audit)) def test_bad_id_returns_none(self): audit = self.plot.audits()[0] audit.model_id = -1000 self.assertIsNone(audit_detail_link(audit))
def test_basic_audit(self): p = Point(-8515222.0, 4953200.0) plot = Plot(geom=p, instance=self.instance) plot.save_with_user(self.user1) self.assertAuditsEqual([ self.make_audit(plot.pk, 'id', None, str(plot.pk), model='Plot'), self.make_audit(plot.pk, 'readonly', None, 'False', model='Plot'), self.make_audit( plot.pk, 'geom', None, str(plot.geom), model='Plot') ], plot.audits()) t = Tree(plot=plot, instance=self.instance, readonly=True) t.save_with_user(self.user1) expected_audits = [ self.make_audit(t.pk, 'id', None, str(t.pk)), self.make_audit(t.pk, 'readonly', None, True), self.make_audit(t.pk, 'plot', None, plot.pk) ] self.assertAuditsEqual(expected_audits, t.audits()) t.readonly = False t.save_with_user(self.user2) expected_audits.insert( 0, self.make_audit(t.pk, 'readonly', 'True', 'False', action=Audit.Type.Update, user=self.user2)) self.assertAuditsEqual(expected_audits, t.audits()) old_pk = t.pk t.delete_with_user(self.user1) expected_audits.insert( 0, self.make_audit(old_pk, None, None, None, action=Audit.Type.Delete, user=self.user1)) self.assertAuditsEqual( expected_audits, Audit.audits_for_model('Tree', self.instance, old_pk))
def test_lots_of_trees_and_plots(self): """ Make 3 plots: 2 pending and 1 approved Make 4 trees: 1 on each pending plot, 2 on approved plot Approve one pending plot. Approve all trees. The one on the (Still) pending plot should fail. all else should pass. """ p1 = Point(0, 0) p2 = Point(1, 1) p3 = Point(2, 2) plot1 = Plot(geom=p1, instance=self.instance) plot2 = Plot(geom=p2, instance=self.instance) plot3 = Plot(geom=p3, instance=self.instance) plot1.save_with_user(self.commander_user) plot2.save_with_user(self.pending_user) plot3.save_with_user(self.pending_user) tree1 = Tree(plot=plot1, instance=self.instance) tree1.save_with_user(self.pending_user) tree2 = Tree(plot=plot1, instance=self.instance) tree2.save_with_user(self.pending_user) tree3 = Tree(plot=plot2, instance=self.instance) tree3.save_with_user(self.pending_user) tree4 = Tree(plot=plot3, instance=self.instance) tree4.save_with_user(self.pending_user) approve_or_reject_audits_and_apply( plot2.audits(), self.commander_user, True) approve_or_reject_audits_and_apply( tree1.audits(), self.commander_user, True) approve_or_reject_audits_and_apply( tree2.audits(), self.commander_user, True) approve_or_reject_audits_and_apply( tree3.audits(), self.commander_user, True) self.assertRaises(ObjectDoesNotExist, Plot.objects.get, pk=plot3.pk) self.assertRaises(ObjectDoesNotExist, approve_or_reject_audits_and_apply, tree4.audits(), self.commander_user, True)
def test_insert_writes_when_approved(self): new_plot = Plot(geom=self.p1, instance=self.instance) new_plot.save_with_user(self.pending_user) new_tree = Tree(plot=new_plot, instance=self.instance) new_tree.save_with_user(self.pending_user) self.assertEquals(Plot.objects.count(), 0) self.assertEquals(Tree.objects.count(), 0) approve_or_reject_audits_and_apply( list(new_tree.audits()) + list(new_plot.audits()), self.commander_user, True) self.assertEqual(Plot.objects.all().count(), 1) self.assertEqual(Tree.objects.all().count(), 1)
def test_lots_of_trees_and_plots(self): """ Make 3 plots: 2 pending and 1 approved Make 4 trees: 1 on each pending plot, 2 on approved plot Approve one pending plot. Approve all trees. The one on the (Still) pending plot should fail. all else should pass. """ plot1 = Plot(geom=self.instance.center, instance=self.instance) plot2 = Plot(geom=self.instance.center, instance=self.instance) plot3 = Plot(geom=self.instance.center, instance=self.instance) plot1.save_with_user(self.commander_user) plot2.save_with_user(self.pending_user) plot3.save_with_user(self.pending_user) tree1 = Tree(plot=plot1, instance=self.instance) tree1.save_with_user(self.pending_user) tree2 = Tree(plot=plot1, instance=self.instance) tree2.save_with_user(self.pending_user) tree3 = Tree(plot=plot2, instance=self.instance) tree3.save_with_user(self.pending_user) tree4 = Tree(plot=plot3, instance=self.instance) tree4.save_with_user(self.pending_user) approve_or_reject_audits_and_apply( plot2.audits(), self.commander_user, True) approve_or_reject_audits_and_apply( tree1.audits(), self.commander_user, True) approve_or_reject_audits_and_apply( tree2.audits(), self.commander_user, True) approve_or_reject_audits_and_apply( tree3.audits(), self.commander_user, True) self.assertRaises(ObjectDoesNotExist, Plot.objects.get, pk=plot3.pk) self.assertRaises(ObjectDoesNotExist, approve_or_reject_audits_and_apply, tree4.audits(), self.commander_user, True)
def test_basic_audit(self): p = Point(-8515222.0, 4953200.0) plot = Plot(geom=p, instance=self.instance) plot.save_with_user(self.user1) self.assertAuditsEqual([ self.make_audit(plot.pk, 'id', None, str(plot.pk), model='Plot'), self.make_audit(plot.pk, 'readonly', None, 'False', model='Plot'), self.make_audit(plot.pk, 'geom', None, str(plot.geom), model='Plot')], plot.audits()) t = Tree(plot=plot, instance=self.instance, readonly=True) t.save_with_user(self.user1) expected_audits = [ self.make_audit(t.pk, 'id', None, str(t.pk)), self.make_audit(t.pk, 'readonly', None, True), self.make_audit(t.pk, 'plot', None, plot.pk)] self.assertAuditsEqual(expected_audits, t.audits()) t.readonly = False t.save_with_user(self.user2) expected_audits.insert( 0, self.make_audit(t.pk, 'readonly', 'True', 'False', action=Audit.Type.Update, user=self.user2)) self.assertAuditsEqual(expected_audits, t.audits()) old_pk = t.pk t.delete_with_user(self.user1) expected_audits.insert( 0, self.make_audit(old_pk, None, None, None, action=Audit.Type.Delete, user=self.user1)) self.assertAuditsEqual( expected_audits, Audit.audits_for_model('Tree', self.instance, old_pk))
def test_approve_insert_without_required_raises_integrity_error(self): new_plot = Plot(geom=self.p1, instance=self.instance) new_plot.save_with_user(self.pending_user) new_tree = Tree(plot=new_plot, instance=self.instance, diameter=10, height=10, readonly=False) new_tree.save_with_user(self.pending_user) approve_or_reject_audits_and_apply( new_plot.audits(), self.commander_user, True) diameter_audit = Audit.objects.get(model='Tree', field='diameter', model_id=new_tree.pk) insert_audit = Audit.objects.get(model='Tree', model_id=new_tree.pk, field='id') approve_or_reject_audit_and_apply( diameter_audit, self.commander_user, approved=True) self.assertRaises(IntegrityError, approve_or_reject_audit_and_apply, insert_audit, self.commander_user, True)
class UDFAuditTest(TestCase): def setUp(self): self.instance = make_instance() self.commander_user = make_commander_user(self.instance) set_write_permissions(self.instance, self.commander_user, 'Plot', ['udf:Test choice']) self.p = Point(-8515941.0, 4953519.0) UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type='Plot', datatype=json.dumps({'type': 'choice', 'choices': ['a', 'b', 'c']}), iscollection=False, name='Test choice') UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type='Plot', datatype=json.dumps({'type': 'string'}), iscollection=False, name='Test unauth') UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type='Plot', datatype=json.dumps([{'type': 'choice', 'name': 'a choice', 'choices': ['a', 'b', 'c']}, {'type': 'string', 'name': 'a string'}]), iscollection=True, name='Test collection') self.plot = Plot(geom=self.p, instance=self.instance) self.plot.save_with_user(self.commander_user) psycopg2.extras.register_hstore(connection.cursor(), globally=True) def test_mask_unauthorized_with_udfs(self): officer_user = make_officer_user(self.instance) self.plot.udfs['Test choice'] = 'b' self.plot.save_with_user(self.commander_user) self.plot.udfs['Test unauth'] = 'foo' self.plot.save_base() newplot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(newplot.udfs['Test choice'], 'b') self.assertEqual(newplot.udfs['Test unauth'], 'foo') newplot = Plot.objects.get(pk=self.plot.pk) newplot.mask_unauthorized_fields(self.commander_user) self.assertEqual(newplot.udfs['Test choice'], 'b') self.assertEqual(newplot.udfs['Test unauth'], None) newplot = Plot.objects.get(pk=self.plot.pk) newplot.mask_unauthorized_fields(officer_user) self.assertEqual(newplot.udfs['Test choice'], None) self.assertEqual(newplot.udfs['Test unauth'], None) def test_update_field_creates_audit(self): self.plot.udfs['Test choice'] = 'b' self.plot.save_with_user(self.commander_user) last_audit = list(self.plot.audits())[-1] self.assertEqual(last_audit.model, 'Plot') self.assertEqual(last_audit.model_id, self.plot.pk) self.assertEqual(last_audit.field, 'udf:Test choice') self.assertEqual(last_audit.previous_value, None) self.assertEqual(last_audit.current_value, 'b') self.plot.udfs['Test choice'] = 'c' self.plot.save_with_user(self.commander_user) last_audit = list(self.plot.audits())[-1] self.assertEqual(last_audit.model, 'Plot') self.assertEqual(last_audit.model_id, self.plot.pk) self.assertEqual(last_audit.field, 'udf:Test choice') self.assertEqual(last_audit.previous_value, 'b') self.assertEqual(last_audit.current_value, 'c') def test_cant_edit_unauthorized_collection(self): self.plot.udfs['Test collection'] = [ {'a choice': 'a', 'a string': 's'}] self.assertRaises(AuthorizeException, self.plot.save_with_user, self.commander_user) def test_cant_edit_unauthorized_field(self): self.plot.udfs['Test unauth'] = 'c' self.assertRaises(AuthorizeException, self.plot.save_with_user, self.commander_user) def test_create_and_apply_pending(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, _ = FieldPermission.objects.get_or_create( model_name='Plot', field_name='udf:Test unauth', permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance) self.plot.udfs['Test unauth'] = 'c' self.plot.save_with_user(self.commander_user) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual( reloaded_plot.udfs['Test unauth'], None) pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 1) fp.permission_level = FieldPermission.WRITE_DIRECTLY fp.save() approve_or_reject_audit_and_apply(pending[0], self.commander_user, True) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual( reloaded_plot.udfs['Test unauth'], 'c') def test_create_invalid_pending_collection(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, _ = FieldPermission.objects.get_or_create( model_name='Plot', field_name='udf:Test collection', permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance) self.plot.udfs['Test collection'] = [ {'a choice': 'invalid choice', 'a string': 's'}] self.assertRaises(ValidationError, self.plot.save_with_user, self.commander_user) def test_create_and_apply_pending_collection(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, _ = FieldPermission.objects.get_or_create( model_name='Plot', field_name='udf:Test collection', permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance) self.plot.udfs['Test collection'] = [ {'a choice': 'a', 'a string': 's'}] self.plot.save_with_user(self.commander_user) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual( reloaded_plot.udfs['Test collection'], []) pending = self.plot.audits().filter(requires_auth=True) # Expecting 'model_id', 'id', 'field def id' # and two udf fields ('a string' and 'a choice') self.assertEqual(len(pending), 5) fp.permission_level = FieldPermission.WRITE_DIRECTLY fp.save() approve_or_reject_audits_and_apply(pending, self.commander_user, True) reloaded_plot = Plot.objects.get(pk=self.plot.pk) col = reloaded_plot.udfs['Test collection'] self.assertEqual(len(col), 1) self.assertEqual(col[0]['a choice'], 'a') self.assertEqual(col[0]['a string'], 's')
class UDFAuditTest(OTMTestCase): def setUp(self): self.p = Point(-8515941.0, 4953519.0) self.instance = make_instance(point=self.p) self.commander_user = make_commander_user(self.instance) set_write_permissions(self.instance, self.commander_user, "Plot", ["udf:Test choice"]) UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type="Plot", datatype=json.dumps({"type": "choice", "choices": ["a", "b", "c"]}), iscollection=False, name="Test choice", ) UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type="Plot", datatype=json.dumps({"type": "string"}), iscollection=False, name="Test unauth", ) UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type="Plot", datatype=json.dumps( [ {"type": "choice", "name": "a choice", "choices": ["a", "b", "c"]}, {"type": "string", "name": "a string"}, ] ), iscollection=True, name="Test collection", ) self.plot = Plot(geom=self.p, instance=self.instance) self.plot.save_with_user(self.commander_user) psycopg2.extras.register_hstore(connection.cursor(), globally=True) def test_mask_unauthorized_with_udfs(self): officer_user = make_officer_user(self.instance) self.plot.udfs["Test choice"] = "b" self.plot.save_with_user(self.commander_user) self.plot.udfs["Test unauth"] = "foo" self.plot.save_base() newplot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(newplot.udfs["Test choice"], "b") self.assertEqual(newplot.udfs["Test unauth"], "foo") newplot = Plot.objects.get(pk=self.plot.pk) newplot.mask_unauthorized_fields(self.commander_user) self.assertEqual(newplot.udfs["Test choice"], "b") self.assertEqual(newplot.udfs["Test unauth"], None) newplot = Plot.objects.get(pk=self.plot.pk) newplot.mask_unauthorized_fields(officer_user) self.assertEqual(newplot.udfs["Test choice"], None) self.assertEqual(newplot.udfs["Test unauth"], None) def test_update_field_creates_audit(self): self.plot.udfs["Test choice"] = "b" self.plot.save_with_user(self.commander_user) last_audit = list(self.plot.audits())[-1] self.assertEqual(last_audit.model, "Plot") self.assertEqual(last_audit.model_id, self.plot.pk) self.assertEqual(last_audit.field, "udf:Test choice") self.assertEqual(last_audit.previous_value, None) self.assertEqual(last_audit.current_value, "b") self.plot.udfs["Test choice"] = "c" self.plot.save_with_user(self.commander_user) last_audit = list(self.plot.audits())[-1] self.assertEqual(last_audit.model, "Plot") self.assertEqual(last_audit.model_id, self.plot.pk) self.assertEqual(last_audit.field, "udf:Test choice") self.assertEqual(last_audit.previous_value, "b") self.assertEqual(last_audit.current_value, "c") def test_cant_edit_unauthorized_collection(self): self.plot.udfs["Test collection"] = [{"a choice": "a", "a string": "s"}] self.assertRaises(AuthorizeException, self.plot.save_with_user, self.commander_user) def test_cant_edit_unauthorized_field(self): self.plot.udfs["Test unauth"] = "c" self.assertRaises(AuthorizeException, self.plot.save_with_user, self.commander_user) def test_create_and_apply_pending(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, __ = FieldPermission.objects.get_or_create( model_name="Plot", field_name="udf:Test unauth", permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance, ) self.plot.udfs["Test unauth"] = "c" self.plot.save_with_user(self.commander_user) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(reloaded_plot.udfs["Test unauth"], None) pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 1) fp.permission_level = FieldPermission.WRITE_DIRECTLY fp.save() approve_or_reject_audit_and_apply(pending[0], self.commander_user, True) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(reloaded_plot.udfs["Test unauth"], "c") def test_create_invalid_pending_collection(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, __ = FieldPermission.objects.get_or_create( model_name="Plot", field_name="udf:Test collection", permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance, ) self.plot.udfs["Test collection"] = [{"a choice": "invalid choice", "a string": "s"}] self.assertRaises(ValidationError, self.plot.save_with_user, self.commander_user) def test_create_and_apply_pending_collection(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, __ = FieldPermission.objects.get_or_create( model_name="Plot", field_name="udf:Test collection", permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance, ) self.plot.udfs["Test collection"] = [{"a choice": "a", "a string": "s"}] self.plot.save_with_user(self.commander_user) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(reloaded_plot.udfs["Test collection"], []) pending = self.plot.audits().filter(requires_auth=True) # Expecting 'model_id', 'id', 'field def id' # and two udf fields ('a string' and 'a choice') self.assertEqual(len(pending), 5) fp.permission_level = FieldPermission.WRITE_DIRECTLY fp.save() approve_or_reject_audits_and_apply(pending, self.commander_user, True) reloaded_plot = Plot.objects.get(pk=self.plot.pk) col = reloaded_plot.udfs["Test collection"] self.assertEqual(len(col), 1) self.assertEqual(col[0]["a choice"], "a") self.assertEqual(col[0]["a string"], "s")
class ScalarUDFTest(OTMTestCase): def setUp(self): self.p = Point(-8515941.0, 4953519.0) self.instance = make_instance(point=self.p) def make_and_save_type(dtype): UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type="Plot", datatype=json.dumps({"type": dtype}), iscollection=False, name="Test %s" % dtype, ) allowed_types = "float", "int", "string", "user", "date" addl_fields = ["udf:Test %s" % ttype for ttype in allowed_types] addl_fields.append("udf:Test choice") addl_fields.append("udf:Test multichoice") self.commander_user = make_commander_user(self.instance) set_write_permissions(self.instance, self.commander_user, "Plot", addl_fields) for dtype in allowed_types: make_and_save_type(dtype) self.choice_udfd = UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type="Plot", datatype=json.dumps({"type": "choice", "choices": ["a", "b", "c"]}), iscollection=False, name="Test choice", ) self.multichoice_udfd = UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type="Plot", datatype=json.dumps({"type": "multichoice", "choices": ["a", "b", "c"]}), iscollection=False, name="Test multichoice", ) self.plot = Plot(geom=self.p, instance=self.instance) self.plot.save_with_user(self.commander_user) psycopg2.extras.register_hstore(connection.cursor(), globally=True) def _test_datatype(self, field, value): self.plot.udfs[field] = value self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(self.plot.udfs[field], value) def test_int_datatype(self): self._test_datatype("Test int", 4) def test_int_validation_non_integer(self): self.assertRaises(ValidationError, self._test_datatype, "Test int", 42.3) self.assertRaises(ValidationError, self._test_datatype, "Test int", "blah") def test_float_datatype(self): self._test_datatype("Test float", 4.4) def test_float_validation(self): self.assertRaises(ValidationError, self._test_datatype, "Test float", "blah") def test_cant_update_choices_on_non_choice_model(self): floatfield = UserDefinedFieldDefinition.objects.filter(name="Test float") self.assertRaises(ValidationError, floatfield[0].update_choice, "a", "b") def test_update_invalid_choice(self): self.assertRaises(ValidationError, self.choice_udfd.update_choice, "WHAT?????", "m") def test_delete_choice_value(self): self.plot.udfs["Test choice"] = "a" self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field="udf:Test choice") self.assertEqual(self.plot.udfs["Test choice"], "a") self.assertEqual(audit.current_value, "a") self.choice_udfd.delete_choice("a") self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().filter(field="udf:Test choice") self.assertEqual(self.plot.udfs["Test choice"], None) self.assertEqual(audit.exists(), False) choice = UserDefinedFieldDefinition.objects.get(pk=self.choice_udfd.pk) self.assertEqual(set(choice.datatype_dict["choices"]), {"b", "c"}) def test_delete_multichoice_value(self): self.plot.udfs["Test multichoice"] = ["a"] self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field="udf:Test multichoice") self.assertEqual(self.plot.udfs["Test multichoice"], ["a"]) self.assertEqual(json.loads(audit.current_value), ["a"]) self.multichoice_udfd.delete_choice("a") self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().filter(field="udf:Test multichoice") self.assertEqual(self.plot.udfs["Test multichoice"], None) self.assertEqual(json.loads(audit[0].current_value), None) choice = UserDefinedFieldDefinition.objects.get(pk=self.multichoice_udfd.pk) self.assertEqual(set(choice.datatype_dict["choices"]), {"b", "c"}) def test_update_multichoice_value(self): # setup plot and requery self.plot.udfs["Test multichoice"] = ["a"] self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) self.multichoice_udfd.update_choice("a", "weird \\\\\\1a2chars") self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field="udf:Test multichoice") self.assertEqual(self.plot.udfs["Test multichoice"], ["weird \\\\\\1a2chars"]) self.assertEqual(json.loads(audit.current_value), ["weird \\\\\\1a2chars"]) choice = UserDefinedFieldDefinition.objects.get(pk=self.multichoice_udfd.pk) self.assertEqual(set(choice.datatype_dict["choices"]), {"weird \\\\\\1a2chars", "b", "c"}) self.plot = Plot.objects.get(pk=self.plot.pk) self.multichoice_udfd.update_choice("b", "d") self.assertEqual(self.plot.udfs["Test multichoice"], ["weird \\\\\\1a2chars"]) choice = UserDefinedFieldDefinition.objects.get(pk=self.multichoice_udfd.pk) self.assertEqual(set(choice.datatype_dict["choices"]), {"weird \\\\\\1a2chars", "d", "c"}) def test_update_choice_value(self): self.plot.udfs["Test choice"] = "a" self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field="udf:Test choice") self.assertEqual(self.plot.udfs["Test choice"], "a") self.assertEqual(audit.current_value, "a") self.choice_udfd.update_choice("a", "m") self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field="udf:Test choice") self.assertEqual(self.plot.udfs["Test choice"], "m") self.assertEqual(audit.current_value, "m") choice = UserDefinedFieldDefinition.objects.get(pk=self.choice_udfd.pk) self.assertEqual(set(choice.datatype_dict["choices"]), {"m", "b", "c"}) def test_choice_datatype(self): self._test_datatype("Test choice", "a") def test_choice_validation(self): self.assertRaises(ValidationError, self._test_datatype, "Test choice", "bad choice") def test_user_datatype(self): self._test_datatype("Test user", self.commander_user) def test_date_datatype(self): d = datetime.now().replace(microsecond=0) self._test_datatype("Test date", d) def test_string_datatype(self): self._test_datatype("Test string", "Sweet Plot") def test_user_validation_invalid_id(self): self.assertRaises(ValidationError, self._test_datatype, "Test user", 349949) def test_user_validation_non_integer(self): self.assertRaises(ValidationError, self._test_datatype, "Test user", "zztop") def test_in_operator(self): self.assertEqual("Test string" in self.plot.udfs, True) self.assertEqual("RanDoM NAme" in self.plot.udfs, False) def test_returns_none_for_empty_but_valid_udfs(self): self.assertEqual(self.plot.udfs["Test string"], None) def test_raises_keyerror_for_invalid_udf(self): self.assertRaises(KeyError, lambda: self.plot.udfs["RaNdoName"])
class ReviewTest(MultiUserTestCase): def setUp(self): super(ReviewTest, self).setUp() self.plot = Plot(geom=self.p1, instance=self.instance) self.plot.save_with_user(self.commander_user) def test_simple_approve(self): self.plot.width = 444 self.plot.save_with_user(self.commander_user) width_audit = self.plot.audits().order_by('-created')[0] # Sanity check self.assertEqual(width_audit.field, 'width') # Should not have a reference associated with it self.assertIsNone(width_audit.ref) approve_or_reject_existing_edit( width_audit, self.commander_user, approved=True) width_audit_reloaded = Audit.objects.get(pk=width_audit.pk) self.assertIsNotNone(width_audit_reloaded.ref) refd = width_audit_reloaded.ref self.assertEqual(refd.action, Audit.Type.ReviewApprove) def test_reject_regular_edit(self): self.plot.width = 444 self.plot.save_with_user(self.commander_user) self.plot.width = 555 self.plot.save_with_user(self.commander_user) width_audit = self.plot.audits().order_by('-created')[0] # Sanity check self.assertEqual(width_audit.field, 'width') # Should not have a reference associated with it self.assertIsNone(width_audit.ref) approve_or_reject_existing_edit( width_audit, self.commander_user, approved=False) width_audit_reloaded = Audit.objects.get(pk=width_audit.pk) self.assertIsNotNone(width_audit_reloaded.ref) refd = width_audit_reloaded.ref self.assertEqual(refd.action, Audit.Type.ReviewReject) plot_reloaded = Plot.objects.get(pk=self.plot.pk) self.assertEqual(plot_reloaded.width, 444) def test_reject_id_edit(self): id_audit = self.plot.audits().get(field='id') approve_or_reject_existing_edit( id_audit, self.commander_user, approved=False) all_audits = list(self.plot.audits()) self.assertNotEqual(len(all_audits), 0) updated_audit = Audit.objects.get(pk=id_audit.pk) ref_audit = updated_audit.ref self.assertIsNotNone(ref_audit) self.assertEqual(ref_audit.action, Audit.Type.ReviewReject) self.assertRaises(Plot.DoesNotExist, Plot.objects.get, pk=self.plot.pk) def test_requires_write_permissions_on_field(self): self.plot.width = 333 self.plot.save_with_user(self.commander_user) width_audit = self.plot.audits().order_by('-created')[0] # Read only can't edit FieldPermission.objects.filter(field_name='width').update( permission_level=FieldPermission.READ_ONLY) self.assertRaises(AuthorizeException, approve_or_reject_existing_edit, width_audit, self.commander_user, approved=True) # Neither can 'write with audit' FieldPermission.objects.filter(field_name='width').update( permission_level=FieldPermission.WRITE_WITH_AUDIT) self.assertRaises(AuthorizeException, approve_or_reject_existing_edit, width_audit, self.commander_user, approved=True) # But write directly can FieldPermission.objects.filter(field_name='width').update( permission_level=FieldPermission.WRITE_DIRECTLY) approve_or_reject_existing_edit( width_audit, self.commander_user, approved=True) def test_reject_or_approve_pending_edit_fails(self): FieldPermission.objects.filter(field_name='width').update( permission_level=FieldPermission.WRITE_WITH_AUDIT) self.plot.width = 333 self.plot.save_with_user(self.commander_user) pdg_width_audit = self.plot.audits().order_by('-created')[0] FieldPermission.objects.filter(field_name='width').update( permission_level=FieldPermission.WRITE_DIRECTLY) self.assertRaises(Exception, approve_or_reject_existing_edit, pdg_width_audit, self.commander_user, approved=True) def test_rejecting_old_edits_doesnt_update_object(self): self.plot.width = 333 self.plot.save_with_user(self.commander_user) self.plot.width = 444 self.plot.save_with_user(self.commander_user) width_audit = self.plot.audits().order_by('-created')[0] self.plot.width = 555 self.plot.save_with_user(self.commander_user) approve_or_reject_existing_edit( width_audit, self.commander_user, approved=False) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(reloaded_plot.width, 555) def test_approving_edits_on_deleted_obj_doesnt_fail(self): self.plot.width = 444 self.plot.save_with_user(self.commander_user) width_audit = self.plot.audits().order_by('-created')[0] self.plot.delete_with_user(self.commander_user, cascade=True) approve_or_reject_existing_edit( width_audit, self.commander_user, approved=False)
class UDFAuditTest(OTMTestCase): def setUp(self): self.instance = make_instance() self.commander_user = make_commander_user(self.instance) set_write_permissions(self.instance, self.commander_user, 'Plot', ['udf:Test choice']) self.p = Point(-8515941.0, 4953519.0) UserDefinedFieldDefinition.objects.create(instance=self.instance, model_type='Plot', datatype=json.dumps({ 'type': 'choice', 'choices': ['a', 'b', 'c'] }), iscollection=False, name='Test choice') UserDefinedFieldDefinition.objects.create(instance=self.instance, model_type='Plot', datatype=json.dumps( {'type': 'string'}), iscollection=False, name='Test unauth') UserDefinedFieldDefinition.objects.create(instance=self.instance, model_type='Plot', datatype=json.dumps([{ 'type': 'choice', 'name': 'a choice', 'choices': ['a', 'b', 'c'] }, { 'type': 'string', 'name': 'a string' }]), iscollection=True, name='Test collection') self.plot = Plot(geom=self.p, instance=self.instance) self.plot.save_with_user(self.commander_user) psycopg2.extras.register_hstore(connection.cursor(), globally=True) def test_mask_unauthorized_with_udfs(self): officer_user = make_officer_user(self.instance) self.plot.udfs['Test choice'] = 'b' self.plot.save_with_user(self.commander_user) self.plot.udfs['Test unauth'] = 'foo' self.plot.save_base() newplot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(newplot.udfs['Test choice'], 'b') self.assertEqual(newplot.udfs['Test unauth'], 'foo') newplot = Plot.objects.get(pk=self.plot.pk) newplot.mask_unauthorized_fields(self.commander_user) self.assertEqual(newplot.udfs['Test choice'], 'b') self.assertEqual(newplot.udfs['Test unauth'], None) newplot = Plot.objects.get(pk=self.plot.pk) newplot.mask_unauthorized_fields(officer_user) self.assertEqual(newplot.udfs['Test choice'], None) self.assertEqual(newplot.udfs['Test unauth'], None) def test_update_field_creates_audit(self): self.plot.udfs['Test choice'] = 'b' self.plot.save_with_user(self.commander_user) last_audit = list(self.plot.audits())[-1] self.assertEqual(last_audit.model, 'Plot') self.assertEqual(last_audit.model_id, self.plot.pk) self.assertEqual(last_audit.field, 'udf:Test choice') self.assertEqual(last_audit.previous_value, None) self.assertEqual(last_audit.current_value, 'b') self.plot.udfs['Test choice'] = 'c' self.plot.save_with_user(self.commander_user) last_audit = list(self.plot.audits())[-1] self.assertEqual(last_audit.model, 'Plot') self.assertEqual(last_audit.model_id, self.plot.pk) self.assertEqual(last_audit.field, 'udf:Test choice') self.assertEqual(last_audit.previous_value, 'b') self.assertEqual(last_audit.current_value, 'c') def test_cant_edit_unauthorized_collection(self): self.plot.udfs['Test collection'] = [{ 'a choice': 'a', 'a string': 's' }] self.assertRaises(AuthorizeException, self.plot.save_with_user, self.commander_user) def test_cant_edit_unauthorized_field(self): self.plot.udfs['Test unauth'] = 'c' self.assertRaises(AuthorizeException, self.plot.save_with_user, self.commander_user) def test_create_and_apply_pending(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, _ = FieldPermission.objects.get_or_create( model_name='Plot', field_name='udf:Test unauth', permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance) self.plot.udfs['Test unauth'] = 'c' self.plot.save_with_user(self.commander_user) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(reloaded_plot.udfs['Test unauth'], None) pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 1) fp.permission_level = FieldPermission.WRITE_DIRECTLY fp.save() approve_or_reject_audit_and_apply(pending[0], self.commander_user, True) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(reloaded_plot.udfs['Test unauth'], 'c') def test_create_invalid_pending_collection(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, _ = FieldPermission.objects.get_or_create( model_name='Plot', field_name='udf:Test collection', permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance) self.plot.udfs['Test collection'] = [{ 'a choice': 'invalid choice', 'a string': 's' }] self.assertRaises(ValidationError, self.plot.save_with_user, self.commander_user) def test_create_and_apply_pending_collection(self): pending = self.plot.audits().filter(requires_auth=True) self.assertEqual(len(pending), 0) role = self.commander_user.get_role(self.instance) fp, _ = FieldPermission.objects.get_or_create( model_name='Plot', field_name='udf:Test collection', permission_level=FieldPermission.WRITE_WITH_AUDIT, role=role, instance=self.instance) self.plot.udfs['Test collection'] = [{ 'a choice': 'a', 'a string': 's' }] self.plot.save_with_user(self.commander_user) reloaded_plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(reloaded_plot.udfs['Test collection'], []) pending = self.plot.audits().filter(requires_auth=True) # Expecting 'model_id', 'id', 'field def id' # and two udf fields ('a string' and 'a choice') self.assertEqual(len(pending), 5) fp.permission_level = FieldPermission.WRITE_DIRECTLY fp.save() approve_or_reject_audits_and_apply(pending, self.commander_user, True) reloaded_plot = Plot.objects.get(pk=self.plot.pk) col = reloaded_plot.udfs['Test collection'] self.assertEqual(len(col), 1) self.assertEqual(col[0]['a choice'], 'a') self.assertEqual(col[0]['a string'], 's')
class ScalarUDFTest(OTMTestCase): def setUp(self): self.instance = make_instance() self.p = Point(-8515941.0, 4953519.0) def make_and_save_type(dtype): UserDefinedFieldDefinition.objects.create(instance=self.instance, model_type='Plot', datatype=json.dumps( {'type': dtype}), iscollection=False, name='Test %s' % dtype) allowed_types = 'float', 'int', 'string', 'user', 'date' addl_fields = ['udf:Test %s' % ttype for ttype in allowed_types] addl_fields.append('udf:Test choice') self.commander_user = make_commander_user(self.instance) set_write_permissions(self.instance, self.commander_user, 'Plot', addl_fields) for dtype in allowed_types: make_and_save_type(dtype) self.choice_udfd = UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type='Plot', datatype=json.dumps({ 'type': 'choice', 'choices': ['a', 'b', 'c'] }), iscollection=False, name='Test choice') self.plot = Plot(geom=self.p, instance=self.instance) self.plot.save_with_user(self.commander_user) psycopg2.extras.register_hstore(connection.cursor(), globally=True) def _test_datatype(self, field, value): self.plot.udfs[field] = value self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual(self.plot.udfs[field], value) def test_int_datatype(self): self._test_datatype('Test int', 4) def test_int_validation_non_integer(self): self.assertRaises(ValidationError, self._test_datatype, 'Test int', 42.3) self.assertRaises(ValidationError, self._test_datatype, 'Test int', 'blah') def test_float_datatype(self): self._test_datatype('Test float', 4.4) def test_float_validation(self): self.assertRaises(ValidationError, self._test_datatype, 'Test float', 'blah') def test_cant_update_choices_on_non_choice_model(self): floatfield = UserDefinedFieldDefinition\ .objects\ .filter(name='Test float') self.assertRaises(ValidationError, floatfield[0].update_choice, 'a', 'b') def test_update_invalid_choice(self): self.assertRaises(ValidationError, self.choice_udfd.update_choice, 'WHAT?????', 'm') def test_delete_choice_value(self): self.plot.udfs['Test choice'] = 'a' self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field='udf:Test choice') self.assertEqual(self.plot.udfs['Test choice'], 'a') self.assertEqual(audit.current_value, 'a') self.choice_udfd.delete_choice('a') self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().filter(field='udf:Test choice') self.assertEqual(self.plot.udfs['Test choice'], None) self.assertEqual(audit.exists(), False) choice = UserDefinedFieldDefinition.objects.get(pk=self.choice_udfd.pk) self.assertEqual(set(choice.datatype_dict['choices']), {'b', 'c'}) def test_update_choice_value(self): self.plot.udfs['Test choice'] = 'a' self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field='udf:Test choice') self.assertEqual(self.plot.udfs['Test choice'], 'a') self.assertEqual(audit.current_value, 'a') self.choice_udfd.update_choice('a', 'm') self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field='udf:Test choice') self.assertEqual(self.plot.udfs['Test choice'], 'm') self.assertEqual(audit.current_value, 'm') choice = UserDefinedFieldDefinition.objects.get(pk=self.choice_udfd.pk) self.assertEqual(set(choice.datatype_dict['choices']), {'m', 'b', 'c'}) def test_choice_datatype(self): self._test_datatype('Test choice', 'a') def test_choice_validation(self): self.assertRaises(ValidationError, self._test_datatype, 'Test choice', 'bad choice') def test_user_datatype(self): self._test_datatype('Test user', self.commander_user) def test_date_datatype(self): d = datetime.now().replace(microsecond=0) self._test_datatype('Test date', d) def test_string_datatype(self): self._test_datatype('Test string', 'Sweet Plot') def test_user_validation_invalid_id(self): self.assertRaises(ValidationError, self._test_datatype, 'Test user', 349949) def test_user_validation_non_integer(self): self.assertRaises(ValidationError, self._test_datatype, 'Test user', 'zztop') def test_in_operator(self): self.assertEqual('Test string' in self.plot.udfs, True) self.assertEqual('RanDoM NAme' in self.plot.udfs, False) def test_returns_none_for_empty_but_valid_udfs(self): self.assertEqual(self.plot.udfs['Test string'], None) def test_raises_keyerror_for_invalid_udf(self): self.assertRaises(KeyError, lambda: self.plot.udfs['RaNdoName'])
class ScalarUDFTest(TestCase): def setUp(self): self.instance = make_instance() self.p = Point(-8515941.0, 4953519.0) def make_and_save_type(dtype): UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type='Plot', datatype=json.dumps({'type': dtype}), iscollection=False, name='Test %s' % dtype) allowed_types = 'float', 'int', 'string', 'user', 'date' addl_fields = ['udf:Test %s' % ttype for ttype in allowed_types] addl_fields.append('udf:Test choice') self.commander_user = make_commander_user(self.instance) set_write_permissions(self.instance, self.commander_user, 'Plot', addl_fields) for dtype in allowed_types: make_and_save_type(dtype) self.choice_udfd = UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type='Plot', datatype=json.dumps({'type': 'choice', 'choices': ['a', 'b', 'c']}), iscollection=False, name='Test choice') self.plot = Plot(geom=self.p, instance=self.instance) self.plot.save_with_user(self.commander_user) psycopg2.extras.register_hstore(connection.cursor(), globally=True) def _test_datatype(self, field, value): self.plot.udfs[field] = value self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) self.assertEqual( self.plot.udfs[field], value) def test_int_datatype(self): self._test_datatype('Test int', 4) def test_int_validation_non_integer(self): self.assertRaises(ValidationError, self._test_datatype, 'Test int', 42.3) self.assertRaises(ValidationError, self._test_datatype, 'Test int', 'blah') def test_float_datatype(self): self._test_datatype('Test float', 4.4) def test_float_validation(self): self.assertRaises(ValidationError, self._test_datatype, 'Test float', 'blah') def test_cant_update_choices_on_non_choice_model(self): floatfield = UserDefinedFieldDefinition\ .objects\ .filter(name='Test float') self.assertRaises(ValidationError, floatfield[0].update_choice, 'a', 'b') def test_update_invalid_choice(self): self.assertRaises(ValidationError, self.choice_udfd.update_choice, 'WHAT?????', 'm') def test_delete_choice_value(self): self.plot.udfs['Test choice'] = 'a' self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field='udf:Test choice') self.assertEqual( self.plot.udfs['Test choice'], 'a') self.assertEqual( audit.current_value, 'a') self.choice_udfd.delete_choice('a') self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().filter(field='udf:Test choice') self.assertEqual( self.plot.udfs['Test choice'], None) self.assertEqual( audit.exists(), False) choice = UserDefinedFieldDefinition.objects.get( pk=self.choice_udfd.pk) self.assertEqual( set(choice.datatype_dict['choices']), {'b', 'c'}) def test_update_choice_value(self): self.plot.udfs['Test choice'] = 'a' self.plot.save_with_user(self.commander_user) self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field='udf:Test choice') self.assertEqual( self.plot.udfs['Test choice'], 'a') self.assertEqual( audit.current_value, 'a') self.choice_udfd.update_choice('a', 'm') self.plot = Plot.objects.get(pk=self.plot.pk) audit = self.plot.audits().get(field='udf:Test choice') self.assertEqual( self.plot.udfs['Test choice'], 'm') self.assertEqual( audit.current_value, 'm') choice = UserDefinedFieldDefinition.objects.get( pk=self.choice_udfd.pk) self.assertEqual( set(choice.datatype_dict['choices']), {'m', 'b', 'c'}) def test_choice_datatype(self): self._test_datatype('Test choice', 'a') def test_choice_validation(self): self.assertRaises(ValidationError, self._test_datatype, 'Test choice', 'bad choice') def test_user_datatype(self): self._test_datatype('Test user', self.commander_user) def test_date_datatype(self): d = datetime.now().replace(microsecond=0) self._test_datatype('Test date', d) def test_string_datatype(self): self._test_datatype('Test string', 'Sweet Plot') def test_user_validation_invalid_id(self): self.assertRaises(ValidationError, self._test_datatype, 'Test user', 349949) def test_user_validation_non_integer(self): self.assertRaises(ValidationError, self._test_datatype, 'Test user', 'zztop') def test_in_operator(self): self.assertEqual('Test string' in self.plot.udfs, True) self.assertEqual('RanDoM NAme' in self.plot.udfs, False) def test_returns_none_for_empty_but_valid_udfs(self): self.assertEqual(self.plot.udfs['Test string'], None) def test_raises_keyerror_for_invalid_udf(self): self.assertRaises(KeyError, lambda: self.plot.udfs['RaNdoName'])