class UserCanDeleteTestCase(OTMTestCase): def setUp(self): instance = make_instance() self.creator_user = make_officer_user(instance) self.admin_user = make_admin_user(instance) self.other_user = make_officer_user(instance, username='******') self.plot = Plot(geom=instance.center, instance=instance) self.plot.save_with_user(self.creator_user) self.tree = Tree(plot=self.plot, instance=instance) self.tree.save_with_user(self.creator_user) self.rainBarrel = RainBarrel(geom=instance.center, instance=instance, capacity=5) self.rainBarrel.save_with_user(self.creator_user) def assert_can_delete(self, user, deletable, should_be_able_to_delete): can = deletable.user_can_delete(user) self.assertEqual(can, should_be_able_to_delete) def test_user_can_delete(self): self.assert_can_delete(self.creator_user, self.plot, True) self.assert_can_delete(self.admin_user, self.plot, True) self.assert_can_delete(self.other_user, self.plot, False) self.assert_can_delete(self.creator_user, self.rainBarrel, True) self.assert_can_delete(self.admin_user, self.rainBarrel, True) self.assert_can_delete(self.other_user, self.rainBarrel, False) self.assert_can_delete(self.creator_user, self.tree, True) self.assert_can_delete(self.admin_user, self.tree, True) self.assert_can_delete(self.other_user, self.tree, False)
class UserCanDeleteTestCase(OTMTestCase): def setUp(self): instance = make_instance() # Fancy name, but no write, create, or delete permissions instance.default_role.name = Role.ADMINISTRATOR self.creator_user = make_officer_user(instance) self.admin_user = make_admin_user(instance) self.other_user = make_observer_user(instance, username='******') self.tweaker_user = make_tweaker_user(instance) self.conjurer_user = make_conjurer_user(instance) self.plot = Plot(geom=instance.center, instance=instance) self.plot.save_with_user(self.creator_user) self.tree = Tree(plot=self.plot, instance=instance) self.tree.save_with_user(self.creator_user) self.rainBarrel = RainBarrel(geom=instance.center, instance=instance, capacity=5) self.rainBarrel.save_with_user(self.creator_user) def assert_can_delete(self, user, deletable, should_be_able_to_delete): can = deletable.user_can_delete(user) self.assertEqual(can, should_be_able_to_delete) def test_user_can_delete(self): self.assert_can_delete(self.conjurer_user, self.plot, True) self.assert_can_delete(self.conjurer_user, self.rainBarrel, True) self.assert_can_delete(self.conjurer_user, self.tree, True) self.assert_can_delete(self.creator_user, self.plot, True) self.assert_can_delete(self.creator_user, self.rainBarrel, True) self.assert_can_delete(self.creator_user, self.tree, True) self.assert_can_delete(self.admin_user, self.plot, True) self.assert_can_delete(self.admin_user, self.rainBarrel, True) self.assert_can_delete(self.admin_user, self.tree, True) def test_user_cannot_delete(self): self.assert_can_delete(self.tweaker_user, self.plot, False) self.assert_can_delete(self.tweaker_user, self.rainBarrel, False) self.assert_can_delete(self.tweaker_user, self.tree, False) self.assert_can_delete(self.other_user, self.plot, False) self.assert_can_delete(self.other_user, self.rainBarrel, False) self.assert_can_delete(self.other_user, self.tree, False) def test_admin_cannot_delete_by_flag(self): instance = self.tree.get_instance() role = self.admin_user.get_role(instance) role.instance_permissions.clear() self.assertTrue(self.admin_user.get_instance_user(instance).admin) self.assertEqual(role.instance_permissions.count(), 0) self.assert_can_delete(self.admin_user, self.tree, False)
def _create_rainbarrel_return_map_feature(self): # Create a RainBarrel, but return the MapFeature # referenced by it, to make sure the permission codename # is constructed correctly even when passed a MapFeature. rainbarrel = RainBarrel(instance=self.instance, geom=self.p, capacity=50.0) rainbarrel.save_with_user(self.commander) rainbarrel.refresh_from_db() return MapFeature.objects.get(pk=rainbarrel.pk)
def setUp(self): instance = make_instance() # Fancy name, but no write, create, or delete permissions instance.default_role.name = Role.ADMINISTRATOR self.creator_user = make_officer_user(instance) self.admin_user = make_admin_user(instance) self.other_user = make_observer_user(instance, username='******') self.tweaker_user = make_tweaker_user(instance) self.conjurer_user = make_conjurer_user(instance) self.plot = Plot(geom=instance.center, instance=instance) self.plot.save_with_user(self.creator_user) self.tree = Tree(plot=self.plot, instance=instance) self.tree.save_with_user(self.creator_user) self.rainBarrel = RainBarrel(geom=instance.center, instance=instance, capacity=5) self.rainBarrel.save_with_user(self.creator_user)
def setUp(self): instance = make_instance() self.creator_user = make_officer_user(instance) self.admin_user = make_admin_user(instance) self.other_user = make_officer_user(instance, username='******') self.plot = Plot(geom=instance.center, instance=instance) self.plot.save_with_user(self.creator_user) self.tree = Tree(plot=self.plot, instance=instance) self.tree.save_with_user(self.creator_user) self.rainBarrel = RainBarrel(geom=instance.center, instance=instance, capacity=5) self.rainBarrel.save_with_user(self.creator_user)
def units(request, instance): """ Build context for "Units" tab, which allows specifying units and number of decimal digits for values like plot.width or eco.stormwater. For each such value we build a "field spec" for "units" and for "digits", which drive the creation of display/edit fields on the tab form. """ value_names = [ {'title': _("Planting Site Fields"), 'category_name': 'plot', 'model': Plot, 'value_names': ['width', 'length']}, {'title': _("Tree Fields"), 'category_name': 'tree', 'model': Tree, 'value_names': ['diameter', 'height', 'canopy_height']}, {'title': _("Eco Benefits"), 'category_name': 'eco', 'label_dict': benefit_labels, 'value_names': BenefitCategory.GROUPS}, {'title': _("{bioswale} Fields") .format(bioswale=Bioswale.display_name(instance)), 'category_name': 'bioswale', 'model': Bioswale, 'value_names': ['drainage_area']}, {'title': _("{rainBarrel} Fields") .format(rainBarrel=RainBarrel.display_name(instance)), 'category_name': 'rainBarrel', 'model': RainBarrel, 'value_names': ['capacity']}, {'title': _("{rainGarden} Fields") .format(rainGarden=RainGarden.display_name(instance)), 'category_name': 'rainGarden', 'model': RainGarden, 'value_names': ['drainage_area']}, {'title': _("Green Infrastructure"), 'category_name': 'greenInfrastructure', 'inclusion_test': lambda: instance.feature_enabled('green_infrastructure'), 'label_dict': { GreenInfrastructureCategory.RAINFALL: _('Annual Rainfall'), GreenInfrastructureCategory.AREA: _('Area') }, 'value_names': GreenInfrastructureCategory.GROUPS}, ] def get_label_getter(attrs): inclusion_test = attrs.get('inclusion_test') if inclusion_test: if not inclusion_test(): return None Model = attrs.get('model') if Model: name = Model.__name__ if name == 'Tree' or name in instance.map_feature_types: return lambda value_name: \ Model._meta.get_field(value_name).verbose_name else: label_dict = attrs.get('label_dict') if label_dict: return label_dict.get return None specs_by_category = [] for attrs in value_names: get_label = get_label_getter(attrs) if not get_label: continue category_name = attrs['category_name'] category_specs = [] for value_name in attrs['value_names']: def identifier_and_value(key): return get_value_display_attr( instance, category_name, value_name, key) label = get_label(value_name) # Make a dropdown choice for each unit we can convert to abbrevs = get_convertible_units(category_name, value_name) choices = [{'value': abbrev, 'display_value': get_unit_name(abbrev)} for abbrev in abbrevs] # Make field spec for units identifier, abbrev = identifier_and_value('units') units_field_spec = { 'identifier': identifier, 'value': abbrev, 'display_value': get_unit_name(abbrev), 'data_type': 'choice', 'choices': choices } # Make field spec for number of decimal digits identifier, value = identifier_and_value('digits') digits_field_spec = { 'identifier': identifier, 'value': value, 'display_value': value } category_specs.append({ 'label': label, 'units': units_field_spec, 'digits': digits_field_spec}) if category_specs: specs_by_category.append({'title': attrs['title'], 'items': category_specs}) return {'value_specs': specs_by_category}
def units(request, instance): """ Build context for "Units" tab, which allows specifying units and number of decimal digits for values like plot.width or eco.stormwater. For each such value we build a "field spec" for "units" and for "digits", which drive the creation of display/edit fields on the tab form. """ value_names = [ { 'title': _("Planting Site Fields"), 'category_name': 'plot', 'model': Plot, 'value_names': ['width', 'length'] }, { 'title': _("Tree Fields"), 'category_name': 'tree', 'model': Tree, 'value_names': ['diameter', 'height', 'canopy_height'] }, { 'title': _("Eco Benefits"), 'category_name': 'eco', 'label_dict': benefit_labels, 'value_names': BenefitCategory.GROUPS }, { 'title': _("{bioswale} Fields").format( bioswale=Bioswale.display_name(instance)), 'category_name': 'bioswale', 'model': Bioswale, 'value_names': ['drainage_area'] }, { 'title': _("{rainBarrel} Fields").format( rainBarrel=RainBarrel.display_name(instance)), 'category_name': 'rainBarrel', 'model': RainBarrel, 'value_names': ['capacity'] }, { 'title': _("{rainGarden} Fields").format( rainGarden=RainGarden.display_name(instance)), 'category_name': 'rainGarden', 'model': RainGarden, 'value_names': ['drainage_area'] }, { 'title': _("Green Infrastructure"), 'category_name': 'greenInfrastructure', 'inclusion_test': lambda: instance.feature_enabled('green_infrastructure'), 'label_dict': { GreenInfrastructureCategory.RAINFALL: _('Annual Rainfall'), GreenInfrastructureCategory.AREA: _('Area') }, 'value_names': GreenInfrastructureCategory.GROUPS }, ] def get_label_getter(attrs): inclusion_test = attrs.get('inclusion_test') if inclusion_test: if not inclusion_test(): return None Model = attrs.get('model') if Model: name = Model.__name__ if name == 'Tree' or name in instance.map_feature_types: return lambda value_name: \ Model._meta.get_field(value_name).verbose_name else: label_dict = attrs.get('label_dict') if label_dict: return label_dict.get return None specs_by_category = [] for attrs in value_names: get_label = get_label_getter(attrs) if not get_label: continue category_name = attrs['category_name'] category_specs = [] for value_name in attrs['value_names']: def identifier_and_value(key): return get_value_display_attr(instance, category_name, value_name, key) label = get_label(value_name) # Make a dropdown choice for each unit we can convert to abbrevs = get_convertible_units(category_name, value_name) choices = [{ 'value': abbrev, 'display_value': get_unit_name(abbrev) } for abbrev in abbrevs] # Make field spec for units identifier, abbrev = identifier_and_value('units') units_field_spec = { 'identifier': identifier, 'value': abbrev, 'display_value': get_unit_name(abbrev), 'data_type': 'choice', 'choices': choices } # Make field spec for number of decimal digits identifier, value = identifier_and_value('digits') digits_field_spec = { 'identifier': identifier, 'value': value, 'display_value': value } category_specs.append({ 'label': label, 'units': units_field_spec, 'digits': digits_field_spec }) if category_specs: specs_by_category.append({ 'title': attrs['title'], 'items': category_specs }) return {'value_specs': specs_by_category}