示例#1
0
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)
示例#2
0
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)
示例#3
0
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)
示例#4
0
 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)
示例#5
0
    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)
示例#6
0
 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)
示例#7
0
    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)
示例#8
0
    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)
示例#9
0
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}
示例#10
0
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}