예제 #1
0
    def test_select_field(self):
        obj_type = ContentType.objects.get_for_model(Site)

        # Create a custom field
        cf = CustomField(
            type=CustomFieldTypeChoices.TYPE_SELECT,
            name="my_field",
            required=False,
        )
        cf.save()
        cf.content_types.set([obj_type])

        CustomFieldChoice.objects.create(field=cf, value="Option A")
        CustomFieldChoice.objects.create(field=cf, value="Option B")
        CustomFieldChoice.objects.create(field=cf, value="Option C")

        # Assign a value to the first Site
        site = Site.objects.first()
        site.cf[cf.name] = "Option A"
        site.save()

        # Retrieve the stored value
        site.refresh_from_db()
        self.assertEqual(site.cf[cf.name], "Option A")

        # Delete the stored value
        site.cf.pop(cf.name)
        site.save()
        site.refresh_from_db()
        self.assertIsNone(site.cf.get(cf.name))

        # Delete the custom field
        cf.delete()
예제 #2
0
    def test_delete_custom_field_data_task(self):
        obj_type = ContentType.objects.get_for_model(Site)
        cf = CustomField(
            name="cf1",
            type=CustomFieldTypeChoices.TYPE_TEXT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        # Synchronously process all jobs on the queue in this process
        self.get_worker()

        site = Site(name="Site 1",
                    slug="site-1",
                    _custom_field_data={"cf1": "foo"})
        site.save()

        cf.delete()

        # Synchronously process all jobs on the queue in this process
        self.get_worker()

        site.refresh_from_db()

        self.assertTrue("cf1" not in site.cf)
예제 #3
0
    def setUp(self):
        super().setUp()

        # Create a custom field on the Site model
        ct = ContentType.objects.get_for_model(Site)
        cf = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="my_field", required=False)
        cf.save()
        cf.content_types.set([ct])

        # Create a select custom field on the Site model
        cf_select = CustomField(
            type=CustomFieldTypeChoices.TYPE_SELECT,
            name="my_field_select",
            required=False,
            choices=["Bar", "Foo"],
        )
        cf_select.save()
        cf_select.content_types.set([ct])

        # Create some tags
        Tag.objects.create(name="Tag 1", slug="tag-1")
        Tag.objects.create(name="Tag 2", slug="tag-2")
        Tag.objects.create(name="Tag 3", slug="tag-3")

        self.statuses = Status.objects.get_for_model(Site)
예제 #4
0
    def test_update_custom_field_choice_data_task(self):
        self.clear_worker()

        obj_type = ContentType.objects.get_for_model(Site)
        cf = CustomField(
            name="cf1",
            type=CustomFieldTypeChoices.TYPE_SELECT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        self.wait_on_active_tasks()

        choice = CustomFieldChoice(field=cf, value="Foo")
        choice.save()

        site = Site(name="Site 1", slug="site-1", _custom_field_data={"cf1": "Foo"})
        site.save()

        choice.value = "Bar"
        choice.save()

        self.wait_on_active_tasks()

        site.refresh_from_db()

        self.assertEqual(site.cf["cf1"], "Bar")
예제 #5
0
 def setUp(self):
     content_type = ContentType.objects.get_for_model(Site)
     custom_field = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT,
                                name="text_field",
                                default="foo")
     custom_field.save()
     custom_field.content_types.set([content_type])
예제 #6
0
    def setUp(self):
        super().setUp()

        # Create a custom field on the Site model
        ct = ContentType.objects.get_for_model(Site)
        cf = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="my_field", required=False)
        cf.save()
        cf.content_types.set([ct])

        # Create a select custom field on the Site model
        cf_select = CustomField(
            type=CustomFieldTypeChoices.TYPE_SELECT,
            name="my_field_select",
            required=False,
        )
        cf_select.save()
        cf_select.content_types.set([ct])

        CustomFieldChoice.objects.create(field=cf_select, value="Bar")
        CustomFieldChoice.objects.create(field=cf_select, value="Foo")

        # Create some tags
        tags = (
            Tag.objects.create(name="Tag 1", slug="tag-1"),
            Tag.objects.create(name="Tag 2", slug="tag-2"),
            Tag.objects.create(name="Tag 3", slug="tag-3"),
        )
        for tag in tags:
            tag.content_types.add(ContentType.objects.get_for_model(Site))

        self.statuses = Status.objects.get_for_model(Site)
예제 #7
0
    def test_update_custom_field_choice_data_task(self):
        obj_type = ContentType.objects.get_for_model(Site)
        cf = CustomField(
            name="cf1",
            type=CustomFieldTypeChoices.TYPE_SELECT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        # Synchronously process all jobs on the queue in this process
        self.get_worker()

        choice = CustomFieldChoice(field=cf, value="Foo")
        choice.save()

        site = Site(name="Site 1",
                    slug="site-1",
                    _custom_field_data={"cf1": "Foo"})
        site.save()

        choice.value = "Bar"
        choice.save()

        # Synchronously process all jobs on the queue in this process
        self.get_worker()

        site.refresh_from_db()

        self.assertEqual(site.cf["cf1"], "Bar")
예제 #8
0
    def setUpTestData(cls):
        cf1 = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="foo")
        cf1.save()
        cf1.content_types.set([ContentType.objects.get_for_model(Site)])

        cf2 = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="bar")
        cf2.save()
        cf2.content_types.set([ContentType.objects.get_for_model(Rack)])
예제 #9
0
    def test_missing_required_field(self):
        """
        Check that a ValidationError is raised if any required custom fields are not present.
        """
        cf3 = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="baz", required=True)
        cf3.save()
        cf3.content_types.set([ContentType.objects.get_for_model(Site)])

        site = Site(name="Test Site", slug="test-site")

        # Set custom field data with a required field omitted
        site.cf["foo"] = "abc"
        with self.assertRaises(ValidationError):
            site.clean()

        site.cf["baz"] = "def"
        site.clean()
예제 #10
0
    def setUpTestData(cls):

        # Create a custom field on the Site model
        ct = ContentType.objects.get_for_model(Site)
        cf = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="my_field", required=False)
        cf.save()
        cf.content_types.set([ct])

        # Create a select custom field on the Site model
        cf_select = CustomField(
            type=CustomFieldTypeChoices.TYPE_SELECT,
            name="my_field_select",
            required=False,
            choices=["Bar", "Foo"],
        )
        cf_select.save()
        cf_select.content_types.set([ct])
예제 #11
0
 def test_no_exception_raised(self):
     """
     Demonstrate that custom fields with JSON type handle None values correctly
     """
     self.user.is_superuser = True
     self.user.save()
     create_test_device("Foo Device")
     custom_field = CustomField(
         type="json",
         name="json-field",
         required=False,
     )
     custom_field.save()
     device_content_type = ContentType.objects.get_for_model(Device)
     custom_field.content_types.set([device_content_type])
     # Fetch URL with filter parameter
     response = self.client.get(
         f'{reverse("dcim:device_list")}?name=Foo%20Device')
     self.assertIn("Foo Device", str(response.content))
예제 #12
0
    def test_provision_field_task(self):
        self.clear_worker()

        site = Site(
            name="Site 1",
            slug="site-1",
        )
        site.save()

        obj_type = ContentType.objects.get_for_model(Site)
        cf = CustomField(name="cf1", type=CustomFieldTypeChoices.TYPE_TEXT, default="Foo")
        cf.save()
        cf.content_types.set([obj_type])

        self.wait_on_active_tasks()

        site.refresh_from_db()

        self.assertEqual(site.cf["cf1"], "Foo")
예제 #13
0
    def test_provision_field_task(self):
        site = Site(
            name="Site 1",
            slug="site-1",
        )
        site.save()

        obj_type = ContentType.objects.get_for_model(Site)
        cf = CustomField(name="cf1",
                         type=CustomFieldTypeChoices.TYPE_TEXT,
                         default="Foo")
        cf.save()
        cf.content_types.set([obj_type])

        # Synchronously process all jobs on the queue in this process
        self.get_worker()

        site.refresh_from_db()

        self.assertEqual(site.cf["cf1"], "Foo")
예제 #14
0
class APIDocsTestCase(TestCase):
    def setUp(self):
        self.client = Client()

        # Populate a CustomField to activate CustomFieldSerializer
        content_type = ContentType.objects.get_for_model(Site)
        self.cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="test")
        self.cf_text.save()
        self.cf_text.content_types.set([content_type])
        self.cf_text.save()

    def test_api_docs(self):

        url = reverse("api_docs")
        params = {
            "format": "openapi",
        }

        response = self.client.get("{}?{}".format(url, urllib.parse.urlencode(params)))
        self.assertEqual(response.status_code, 200)
예제 #15
0
class CustomFieldChoiceTest(TestCase):
    def setUp(self):
        obj_type = ContentType.objects.get_for_model(Site)
        self.cf = CustomField(
            name="cf1",
            type=CustomFieldTypeChoices.TYPE_SELECT,
        )
        self.cf.save()
        self.cf.content_types.set([obj_type])

        self.choice = CustomFieldChoice(field=self.cf, value="Foo")
        self.choice.save()

        self.site = Site(
            name="Site 1",
            slug="site-1",
            _custom_field_data={
                "cf1": "Foo",
            },
        )
        self.site.save()

    def test_default_value_must_be_valid_choice_sad_path(self):
        self.cf.default = "invalid value"
        with self.assertRaises(ValidationError):
            self.cf.full_clean()

    def test_default_value_must_be_valid_choice_happy_path(self):
        self.cf.default = "Foo"
        self.cf.full_clean()
        self.cf.save()
        self.assertEqual(self.cf.default, "Foo")

    def test_active_choice_cannot_be_deleted(self):
        with self.assertRaises(ProtectedError):
            self.choice.delete()

    def test_custom_choice_deleted_with_field(self):
        self.cf.delete()
        self.assertEqual(CustomField.objects.count(), 0)
        self.assertEqual(CustomFieldChoice.objects.count(), 0)
예제 #16
0
    def test_delete_custom_field_data_task(self):
        self.clear_worker()

        obj_type = ContentType.objects.get_for_model(Site)
        cf = CustomField(
            name="cf1",
            type=CustomFieldTypeChoices.TYPE_TEXT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        site = Site(name="Site 1", slug="site-1", _custom_field_data={"cf1": "foo"})
        site.save()

        cf.delete()

        self.wait_on_active_tasks()

        site.refresh_from_db()

        self.assertTrue("cf1" not in site.cf)
예제 #17
0
class APIDocsTestCase(TestCase):
    def setUp(self):
        self.client = Client()

        # Populate a CustomField to activate CustomFieldSerializer
        content_type = ContentType.objects.get_for_model(Site)
        self.cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT,
                                   name="test")
        self.cf_text.save()
        self.cf_text.content_types.set([content_type])
        self.cf_text.save()

    def test_api_docs(self):
        url = reverse("api_docs")
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        headers = {
            "HTTP_ACCEPT": "application/vnd.oai.openapi",
        }
        url = reverse("schema")
        response = self.client.get(url, **headers)
        self.assertEqual(response.status_code, 200)
예제 #18
0
    def test_simple_fields(self):
        DATA = (
            {
                "field_type": CustomFieldTypeChoices.TYPE_TEXT,
                "field_value": "Foobar!",
                "empty_value": "",
            },
            {
                "field_type": CustomFieldTypeChoices.TYPE_INTEGER,
                "field_value": 0,
                "empty_value": None,
            },
            {
                "field_type": CustomFieldTypeChoices.TYPE_INTEGER,
                "field_value": 42,
                "empty_value": None,
            },
            {
                "field_type": CustomFieldTypeChoices.TYPE_BOOLEAN,
                "field_value": True,
                "empty_value": None,
            },
            {
                "field_type": CustomFieldTypeChoices.TYPE_BOOLEAN,
                "field_value": False,
                "empty_value": None,
            },
            {
                "field_type": CustomFieldTypeChoices.TYPE_DATE,
                "field_value": "2016-06-23",
                "empty_value": None,
            },
            {
                "field_type": CustomFieldTypeChoices.TYPE_URL,
                "field_value": "http://example.com/",
                "empty_value": "",
            },
        )

        obj_type = ContentType.objects.get_for_model(Site)

        for data in DATA:

            # Create a custom field
            cf = CustomField(type=data["field_type"], name="my_field", required=False)
            cf.save()
            cf.content_types.set([obj_type])

            # Assign a value to the first Site
            site = Site.objects.first()
            site.cf[cf.name] = data["field_value"]
            site.save()

            # Retrieve the stored value
            site.refresh_from_db()
            self.assertEqual(site.cf[cf.name], data["field_value"])

            # Delete the stored value
            site.cf.pop(cf.name)
            site.save()
            site.refresh_from_db()
            self.assertIsNone(site.cf.get(cf.name))

            # Delete the custom field
            cf.delete()
예제 #19
0
    def setUp(self):
        content_type = ContentType.objects.get_for_model(Site)

        # Text custom field
        cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="text_field", default="foo")
        cf_text.save()
        cf_text.content_types.set([content_type])

        # Integer custom field
        cf_integer = CustomField(type=CustomFieldTypeChoices.TYPE_INTEGER, name="number_field", default=123)
        cf_integer.save()
        cf_integer.content_types.set([content_type])

        # Boolean custom field
        cf_boolean = CustomField(
            type=CustomFieldTypeChoices.TYPE_BOOLEAN,
            name="boolean_field",
            default=False,
        )
        cf_boolean.save()
        cf_boolean.content_types.set([content_type])

        # Date custom field
        cf_date = CustomField(
            type=CustomFieldTypeChoices.TYPE_DATE,
            name="date_field",
            default="2020-01-01",
        )
        cf_date.save()
        cf_date.content_types.set([content_type])

        # URL custom field
        cf_url = CustomField(
            type=CustomFieldTypeChoices.TYPE_URL,
            name="url_field",
            default="http://example.com/1",
        )
        cf_url.save()
        cf_url.content_types.set([content_type])

        # Select custom field
        cf_select = CustomField(
            type=CustomFieldTypeChoices.TYPE_SELECT,
            name="choice_field",
        )
        cf_select.save()
        cf_select.content_types.set([content_type])
        CustomFieldChoice.objects.create(field=cf_select, value="Foo")
        CustomFieldChoice.objects.create(field=cf_select, value="Bar")
        CustomFieldChoice.objects.create(field=cf_select, value="Baz")
        cf_select.default = "Foo"
        cf_select.save()

        # Multi-select custom field
        cf_multi_select = CustomField(
            type=CustomFieldTypeChoices.TYPE_MULTISELECT,
            name="multi_choice_field",
        )
        cf_multi_select.save()
        cf_multi_select.content_types.set([content_type])
        CustomFieldChoice.objects.create(field=cf_multi_select, value="Foo")
        CustomFieldChoice.objects.create(field=cf_multi_select, value="Bar")
        CustomFieldChoice.objects.create(field=cf_multi_select, value="Baz")
        cf_multi_select.default = ["Foo", "Bar"]
        cf_multi_select.save()

        statuses = Status.objects.get_for_model(Site)

        # Create a site
        self.site = Site.objects.create(name="Site Custom", slug="site-1", status=statuses.get(slug="active"))

        # Assign custom field values for site 2
        self.site._custom_field_data = {
            cf_text.name: "bar",
            cf_integer.name: 456,
            cf_boolean.name: True,
            cf_date.name: "2020-01-02",
            cf_url.name: "http://example.com/2",
            cf_select.name: "Bar",
            cf_multi_select.name: ["Bar", "Baz"],
        }
        self.site.save()
예제 #20
0
    def setUpTestData(cls):
        obj_type = ContentType.objects.get_for_model(Site)

        # Integer filtering
        cf = CustomField(name="cf1", type=CustomFieldTypeChoices.TYPE_INTEGER)
        cf.save()
        cf.content_types.set([obj_type])

        # Boolean filtering
        cf = CustomField(name="cf2", type=CustomFieldTypeChoices.TYPE_BOOLEAN)
        cf.save()
        cf.content_types.set([obj_type])

        # Exact text filtering
        cf = CustomField(
            name="cf3",
            type=CustomFieldTypeChoices.TYPE_TEXT,
            filter_logic=CustomFieldFilterLogicChoices.FILTER_EXACT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        # Loose text filtering
        cf = CustomField(
            name="cf4",
            type=CustomFieldTypeChoices.TYPE_TEXT,
            filter_logic=CustomFieldFilterLogicChoices.FILTER_LOOSE,
        )
        cf.save()
        cf.content_types.set([obj_type])

        # Date filtering
        cf = CustomField(name="cf5", type=CustomFieldTypeChoices.TYPE_DATE)
        cf.save()
        cf.content_types.set([obj_type])

        # Exact URL filtering
        cf = CustomField(
            name="cf6",
            type=CustomFieldTypeChoices.TYPE_URL,
            filter_logic=CustomFieldFilterLogicChoices.FILTER_EXACT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        # Loose URL filtering
        cf = CustomField(
            name="cf7",
            type=CustomFieldTypeChoices.TYPE_URL,
            filter_logic=CustomFieldFilterLogicChoices.FILTER_LOOSE,
        )
        cf.save()
        cf.content_types.set([obj_type])

        # Selection filtering
        cf = CustomField(
            name="cf8",
            type=CustomFieldTypeChoices.TYPE_SELECT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        CustomFieldChoice.objects.create(field=cf, value="Foo")
        CustomFieldChoice.objects.create(field=cf, value="Bar")

        # Multi-select filtering
        cf = CustomField(
            name="cf9",
            type=CustomFieldTypeChoices.TYPE_MULTISELECT,
        )
        cf.save()
        cf.content_types.set([obj_type])

        CustomFieldChoice.objects.create(field=cf, value="Foo")
        CustomFieldChoice.objects.create(field=cf, value="Bar")

        Site.objects.create(
            name="Site 1",
            slug="site-1",
            _custom_field_data={
                "cf1": 100,
                "cf2": True,
                "cf3": "foo",
                "cf4": "foo",
                "cf5": "2016-06-26",
                "cf6": "http://foo.example.com/",
                "cf7": "http://foo.example.com/",
                "cf8": "Foo",
                "cf9": [],
            },
        )
        Site.objects.create(
            name="Site 2",
            slug="site-2",
            _custom_field_data={
                "cf1": 200,
                "cf2": False,
                "cf3": "foobar",
                "cf4": "foobar",
                "cf5": "2016-06-27",
                "cf6": "http://bar.example.com/",
                "cf7": "http://bar.example.com/",
                "cf8": "Bar",
                "cf9": ["Foo"],
            },
        )
        Site.objects.create(
            name="Site 3",
            slug="site-3",
            _custom_field_data={"cf9": ["Foo", "Bar"]},
        )
        Site.objects.create(name="Site 4", slug="site-4", _custom_field_data={})