Browse Source

wip #865: field modules loading

Rafał Pitoń 8 years ago
parent
commit
d3fefacb72

+ 14 - 3
misago/users/profilefields/__init__.py

@@ -15,17 +15,26 @@ class ProfileFields(object):
     def load(self):
         self.fields_dict = {}
 
+        fieldnames = {}
+
         for group in self.fields_groups:
             for field_path in group['fields']:
                 field = import_string(field_path)
                 field._field_path = field_path
-                if not field.fieldname:
+
+                if field_path in self.fields_dict:
+                    raise ValueError(
+                        "{} profile field has been specified twice".format(field._field_path)
+                    )
+
+                if not getattr(field, 'fieldname', None):
                     raise ValueError(
                         "{} profile field has to specify fieldname attribute".format(
                             field._field_path,
                         )
                     )
-                if field.fieldname in self.fields_dict:
+
+                if field.fieldname in fieldnames:
                     raise ValueError(
                         (
                             '{} profile field defines fieldname "{}" '
@@ -33,9 +42,11 @@ class ProfileFields(object):
                         ).format(
                             field._field_path,
                             field.fieldname,
-                            dict_from_map[field.fieldname]._field_path,
+                            fieldnames[field.fieldname],
                         )
                     )
+
+                fieldnames[field.fieldname] = field_path
                 self.fields_dict[field_path] = field()
 
         self.is_loaded = True

+ 124 - 0
misago/users/tests/test_profilefields.py

@@ -0,0 +1,124 @@
+from django.contrib.auth import get_user_model
+from django.test import TestCase
+from django.utils.six import text_type
+
+from misago.users.profilefields import ProfileFields
+
+
+UserModel = get_user_model()
+
+
+class ProfileFieldsLoadTests(TestCase):
+    def test_no_groups(self):
+        """profile fields util handles empty list"""
+        profilefields = ProfileFields([])
+        profilefields.load()
+
+        self.assertFalse(profilefields.fields_dict)
+
+    def test_empty_group(self):
+        """profile fields util handles empty group"""
+        profilefields = ProfileFields([
+            {
+                'name': "Test",
+                'fields': [],
+            },
+        ])
+
+        profilefields.load()
+
+        self.assertFalse(profilefields.fields_dict)
+
+    def test_field_defines_fieldname(self):
+        """fields need to define fieldname"""
+        profilefields = ProfileFields([
+            {
+                'name': "Test",
+                'fields': [
+                    'misago.users.tests.testfiles.profilefields.NofieldnameField',
+                ],
+            },
+        ])
+
+        with self.assertRaises(ValueError):
+            profilefields.load()
+
+        try:
+            profilefields.load()
+        except ValueError as e:
+            error = text_type(e)
+
+            self.assertIn('misago.users.tests.testfiles.profilefields.NofieldnameField', error)
+            self.assertIn('profile field has to specify fieldname attribute', error)
+
+    def test_detect_repeated_imports(self):
+        """fields can't be specified multiple times"""
+        profilefields = ProfileFields([
+            {
+                'name': "Test",
+                'fields': [
+                    'misago.users.profilefields.default.TwitterHandleField',
+                ],
+            },
+            {
+                'name': "Other test",
+                'fields': [
+                    'misago.users.profilefields.default.TwitterHandleField',
+                ],
+            },
+        ])
+
+        with self.assertRaises(ValueError):
+            profilefields.load()
+
+        try:
+            profilefields.load()
+        except ValueError as e:
+            error = text_type(e)
+
+            self.assertIn('misago.users.profilefields.default.TwitterHandleField', error)
+            self.assertIn('profile field has been specified twice', error)
+
+    def test_detect_repeated_fieldnames(self):
+        """fields can't reuse other field's fieldnames"""
+        profilefields = ProfileFields([
+            {
+                'name': "Test",
+                'fields': [
+                    'misago.users.tests.testfiles.profilefields.FieldnameField',
+                ],
+            },
+            {
+                'name': "Other test",
+                'fields': [
+                    'misago.users.tests.testfiles.profilefields.RepeatedFieldnameField',
+                ],
+            },
+        ])
+
+        with self.assertRaises(ValueError):
+            profilefields.load()
+
+        try:
+            profilefields.load()
+        except ValueError as e:
+            error = text_type(e)
+
+            self.assertIn('misago.users.tests.testfiles.profilefields.FieldnameField', error)
+            self.assertIn('misago.users.tests.testfiles.profilefields.RepeatedFieldnameField', error)
+            self.assertIn('field defines fieldname "hello" that is already in use by the', error)
+
+    def test_field_correct_field(self):
+        """util loads correct field"""
+        field_path = 'misago.users.profilefields.default.FullNameField'
+
+        profilefields = ProfileFields([
+            {
+                'name': "Test",
+                'fields': [field_path],
+            },
+        ])
+
+        profilefields.load()
+
+        self.assertIn(field_path, profilefields.fields_dict)

+ 0 - 0
misago/users/tests/testfiles/__init__.py


+ 10 - 0
misago/users/tests/testfiles/profilefields.py

@@ -0,0 +1,10 @@
+class NofieldnameField(object):
+    pass
+
+
+class FieldnameField(object):
+    fieldname = 'hello'
+
+
+class RepeatedFieldnameField(FieldnameField):
+    pass