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])
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")
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")
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 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)
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)
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)])
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()
def setUpTestData(cls): custom_fields = ( CustomField(name="text", type=CustomFieldTypeChoices.TYPE_TEXT), CustomField(name="integer", type=CustomFieldTypeChoices.TYPE_INTEGER), CustomField(name="boolean", type=CustomFieldTypeChoices.TYPE_BOOLEAN), CustomField(name="date", type=CustomFieldTypeChoices.TYPE_DATE), CustomField(name="url", type=CustomFieldTypeChoices.TYPE_URL), CustomField( name="select", type=CustomFieldTypeChoices.TYPE_SELECT, ), CustomField( name="multiselect", type=CustomFieldTypeChoices.TYPE_MULTISELECT, ), ) for cf in custom_fields: cf.save() cf.content_types.set([ContentType.objects.get_for_model(Site)]) CustomFieldChoice.objects.create(field=CustomField.objects.get(name="select"), value="Choice A") CustomFieldChoice.objects.create(field=CustomField.objects.get(name="select"), value="Choice B") CustomFieldChoice.objects.create(field=CustomField.objects.get(name="select"), value="Choice C") CustomFieldChoice.objects.create(field=CustomField.objects.get(name="multiselect"), value="Choice A") CustomFieldChoice.objects.create(field=CustomField.objects.get(name="multiselect"), value="Choice B") CustomFieldChoice.objects.create(field=CustomField.objects.get(name="multiselect"), value="Choice C")
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")
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))
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_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")
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)
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)
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()
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)
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)
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])
def setUpTestData(cls): custom_fields = ( CustomField(name="text", type=CustomFieldTypeChoices.TYPE_TEXT), CustomField(name="integer", type=CustomFieldTypeChoices.TYPE_INTEGER), CustomField(name="boolean", type=CustomFieldTypeChoices.TYPE_BOOLEAN), CustomField(name="date", type=CustomFieldTypeChoices.TYPE_DATE), CustomField(name="url", type=CustomFieldTypeChoices.TYPE_URL), CustomField( name="select", type=CustomFieldTypeChoices.TYPE_SELECT, choices=["Choice A", "Choice B", "Choice C"], ), ) for cf in custom_fields: cf.save() cf.content_types.set([ContentType.objects.get_for_model(Site)])
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)
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()
def setUpTestData(cls): content_type = ContentType.objects.get_for_model(Site) # Text custom field cls.cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name="text_field", default="foo") cls.cf_text.save() cls.cf_text.content_types.set([content_type]) # Integer custom field cls.cf_integer = CustomField(type=CustomFieldTypeChoices.TYPE_INTEGER, name="number_field", default=123) cls.cf_integer.save() cls.cf_integer.content_types.set([content_type]) # Boolean custom field cls.cf_boolean = CustomField( type=CustomFieldTypeChoices.TYPE_BOOLEAN, name="boolean_field", default=False, ) cls.cf_boolean.save() cls.cf_boolean.content_types.set([content_type]) # Date custom field cls.cf_date = CustomField( type=CustomFieldTypeChoices.TYPE_DATE, name="date_field", default="2020-01-01", ) cls.cf_date.save() cls.cf_date.content_types.set([content_type]) # URL custom field cls.cf_url = CustomField( type=CustomFieldTypeChoices.TYPE_URL, name="url_field", default="http://example.com/1", ) cls.cf_url.save() cls.cf_url.content_types.set([content_type]) # Select custom field cls.cf_select = CustomField( type=CustomFieldTypeChoices.TYPE_SELECT, name="choice_field", ) cls.cf_select.save() cls.cf_select.content_types.set([content_type]) CustomFieldChoice.objects.create(field=cls.cf_select, value="Foo") CustomFieldChoice.objects.create(field=cls.cf_select, value="Bar") CustomFieldChoice.objects.create(field=cls.cf_select, value="Baz") cls.cf_select.default = "Foo" cls.cf_select.save() # Multi-select custom field cls.cf_multi_select = CustomField( type=CustomFieldTypeChoices.TYPE_MULTISELECT, name="multi_choice_field", ) cls.cf_multi_select.save() cls.cf_multi_select.content_types.set([content_type]) CustomFieldChoice.objects.create(field=cls.cf_multi_select, value="Foo") CustomFieldChoice.objects.create(field=cls.cf_multi_select, value="Bar") CustomFieldChoice.objects.create(field=cls.cf_multi_select, value="Baz") cls.cf_multi_select.default = ["Foo", "Bar"] cls.cf_multi_select.save() statuses = Status.objects.get_for_model(Site) # Create some sites cls.sites = ( Site.objects.create(name="Site 1", slug="site-1", status=statuses.get(slug="active")), Site.objects.create(name="Site 2", slug="site-2", status=statuses.get(slug="active")), ) # Assign custom field values for site 2 cls.sites[1]._custom_field_data = { cls.cf_text.name: "bar", cls.cf_integer.name: 456, cls.cf_boolean.name: True, cls.cf_date.name: "2020-01-02", cls.cf_url.name: "http://example.com/2", cls.cf_select.name: "Bar", cls.cf_multi_select.name: ["Bar", "Baz"], } cls.sites[1].save()
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={})