mirror of
https://github.com/ansible/awx.git
synced 2026-02-04 11:08:13 -03:30
Merge pull request #906 from jangsutsr/refactor_named_url_tests
Refactor named URL unit tests
This commit is contained in:
190
awx/main/tests/functional/test_named_url.py
Normal file
190
awx/main/tests/functional/test_named_url.py
Normal file
@@ -0,0 +1,190 @@
|
||||
import pytest
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from awx.api.versioning import reverse
|
||||
from awx.main.middleware import URLModificationMiddleware
|
||||
from awx.main.models import * # noqa
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=True)
|
||||
def init_url_modification_middleware():
|
||||
# In real-world scenario, named url graph structure is populated by __init__
|
||||
# of URLModificationMiddleware. The way Django bootstraps ensures the initialization
|
||||
# will happen *once and only once*, while the number of initialization is uncontrollable
|
||||
# in unit test environment. So it is wrapped by try-except block to mute any
|
||||
# unwanted exceptions.
|
||||
try:
|
||||
URLModificationMiddleware()
|
||||
except ImproperlyConfigured:
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_user(get, admin_user):
|
||||
test_user = User.objects.create(username='test_user', password='test_user', is_superuser=False)
|
||||
url = reverse('api:user_detail', kwargs={'pk': test_user.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_user/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_team(get, admin_user):
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_team = test_org.teams.create(name='test_team')
|
||||
url = reverse('api:team_detail', kwargs={'pk': test_team.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_team++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_organization(get, admin_user):
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
url = reverse('api:organization_detail', kwargs={'pk': test_org.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_job_template(get, admin_user):
|
||||
test_jt = JobTemplate.objects.create(name='test_jt')
|
||||
url = reverse('api:job_template_detail', kwargs={'pk': test_jt.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_jt/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_workflow_job_template(get, admin_user):
|
||||
test_wfjt = WorkflowJobTemplate.objects.create(name='test_wfjt')
|
||||
url = reverse('api:workflow_job_template_detail', kwargs={'pk': test_wfjt.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_wfjt++/')
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_wfjt.organization = test_org
|
||||
test_wfjt.save()
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_wfjt++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_label(get, admin_user):
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_label = test_org.labels.create(name='test_label')
|
||||
url = reverse('api:label_detail', kwargs={'pk': test_label.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_label++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_project(get, admin_user):
|
||||
test_proj = Project.objects.create(name='test_proj')
|
||||
url = reverse('api:project_detail', kwargs={'pk': test_proj.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_proj++/')
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_proj.organization = test_org
|
||||
test_proj.save()
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_proj++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_notification_template(get, admin_user):
|
||||
test_notification_template = NotificationTemplate.objects.create(
|
||||
name='test_note', notification_type='slack',
|
||||
notification_configuration=dict(channels=["Foo", "Bar"], token="token")
|
||||
)
|
||||
url = reverse('api:notification_template_detail', kwargs={'pk': test_notification_template.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_note++/')
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_notification_template.organization = test_org
|
||||
test_notification_template.save()
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_note++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_instance(get, admin_user):
|
||||
test_instance = Instance.objects.create(
|
||||
uuid=settings.SYSTEM_UUID, hostname="localhost", capacity=100
|
||||
)
|
||||
url = reverse('api:instance_detail', kwargs={'pk': test_instance.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/localhost/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_instance_group(get, admin_user):
|
||||
test_instance_group = InstanceGroup.objects.create(name='Tower')
|
||||
url = reverse('api:instance_group_detail', kwargs={'pk': test_instance_group.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/Tower/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_inventory(get, admin_user):
|
||||
test_inv = Inventory.objects.create(name='test_inv')
|
||||
url = reverse('api:inventory_detail', kwargs={'pk': test_inv.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_inv++/')
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_inv.organization = test_org
|
||||
test_inv.save()
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_inv++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_host(get, admin_user):
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_inv = Inventory.objects.create(name='test_inv', organization=test_org)
|
||||
test_host = Host.objects.create(name='test_host', inventory=test_inv)
|
||||
url = reverse('api:host_detail', kwargs={'pk': test_host.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_host++test_inv++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_group(get, admin_user):
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_inv = Inventory.objects.create(name='test_inv', organization=test_org)
|
||||
test_group = Group.objects.create(name='test_group', inventory=test_inv)
|
||||
url = reverse('api:group_detail', kwargs={'pk': test_group.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_group++test_inv++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_inventory_source(get, admin_user):
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_inv = Inventory.objects.create(name='test_inv', organization=test_org)
|
||||
test_source = InventorySource.objects.create(name='test_source', inventory=test_inv)
|
||||
url = reverse('api:inventory_source_detail', kwargs={'pk': test_source.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_source++test_inv++test_org/')
|
||||
test_source.inventory = None
|
||||
test_source.save()
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_source++/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_inventory_script(get, admin_user):
|
||||
test_script = CustomInventoryScript.objects.create(name='test_script')
|
||||
url = reverse('api:inventory_script_detail', kwargs={'pk': test_script.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_script++/')
|
||||
test_org = Organization.objects.create(name='test_org')
|
||||
test_script.organization = test_org
|
||||
test_script.save()
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_script++test_org/')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_credential(get, admin_user, credentialtype_ssh):
|
||||
test_cred = Credential.objects.create(name='test_cred', credential_type=credentialtype_ssh)
|
||||
url = reverse('api:credential_detail', kwargs={'pk': test_cred.pk})
|
||||
response = get(url, user=admin_user, expect=200)
|
||||
assert response.data['related']['named_url'].endswith('/test_cred++Machine+ssh++/')
|
||||
@@ -1,505 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
import mock
|
||||
import random
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from awx.main.utils.named_url_graph import generate_graph
|
||||
from awx.main.models.base import CommonModel, CommonModelNameNotUnique
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def common_model_class_mock():
|
||||
def class_generator(plural):
|
||||
class ModelClass(CommonModel):
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = plural
|
||||
pass
|
||||
return ModelClass
|
||||
return class_generator
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def common_model_name_not_unique_class_mock():
|
||||
def class_generator(ut, fk_a_obj, fk_b_obj, plural, soft_ut=[]):
|
||||
class ModelClass(CommonModelNameNotUnique):
|
||||
|
||||
SOFT_UNIQUE_TOGETHER = soft_ut
|
||||
|
||||
class Meta:
|
||||
unique_together = ut
|
||||
verbose_name_plural = plural
|
||||
|
||||
fk_a = models.ForeignKey(
|
||||
fk_a_obj,
|
||||
null=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
fk_b = models.ForeignKey(
|
||||
fk_b_obj,
|
||||
null=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
str_with_choices_a = models.CharField(
|
||||
choices=("foo", "bar")
|
||||
)
|
||||
str_with_choices_b = models.CharField(
|
||||
choices=("foo", "bar")
|
||||
)
|
||||
integer = models.IntegerField()
|
||||
str_without_choices = models.CharField()
|
||||
return ModelClass
|
||||
return class_generator
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def settings_mock():
|
||||
class settings_class(object):
|
||||
pass
|
||||
return settings_class
|
||||
|
||||
|
||||
@pytest.mark.parametrize("unique_together", [
|
||||
("name", "str_without_choices"),
|
||||
("name", "str_with_choices_a", 'str_without_choices'),
|
||||
("name", "str_with_choices_a", 'integer'),
|
||||
("name", "fk_a"),
|
||||
("name", "fk_b"),
|
||||
])
|
||||
def test_invalid_generation(common_model_name_not_unique_class_mock,
|
||||
common_model_class_mock, settings_mock, unique_together):
|
||||
models = []
|
||||
valid_parent_out_of_range = common_model_class_mock('valid_parent_out_of_range')
|
||||
invalid_parent = common_model_name_not_unique_class_mock(
|
||||
('integer', 'name'),
|
||||
valid_parent_out_of_range,
|
||||
valid_parent_out_of_range,
|
||||
'invalid_parent',
|
||||
)
|
||||
models.append(invalid_parent)
|
||||
model_1 = common_model_name_not_unique_class_mock(
|
||||
unique_together,
|
||||
invalid_parent,
|
||||
valid_parent_out_of_range,
|
||||
'model_1'
|
||||
)
|
||||
models.append(model_1)
|
||||
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
assert not settings_mock.NAMED_URL_FORMATS
|
||||
|
||||
|
||||
def test_soft_unique_together_being_included(common_model_name_not_unique_class_mock,
|
||||
common_model_class_mock, settings_mock):
|
||||
models = []
|
||||
model_1 = common_model_class_mock('model_1')
|
||||
models.append(model_1)
|
||||
model_2 = common_model_name_not_unique_class_mock(
|
||||
(),
|
||||
model_1,
|
||||
model_1,
|
||||
'model_2',
|
||||
soft_ut=[('name', 'fk_a')]
|
||||
)
|
||||
models.append(model_2)
|
||||
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].model == model_1
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].fields == ('name',)
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].adj_list == []
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2].model == model_2
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_2].adj_list)[0] == ('fk_a',)
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_2].adj_list)[1]] == [model_1]
|
||||
|
||||
|
||||
def test_chain_generation(common_model_class_mock, common_model_name_not_unique_class_mock, settings_mock):
|
||||
"""
|
||||
Graph topology:
|
||||
|
||||
model_3
|
||||
|
|
||||
| fk_a
|
||||
|
|
||||
V
|
||||
model_2
|
||||
|
|
||||
| fk_a
|
||||
|
|
||||
V
|
||||
model_1
|
||||
"""
|
||||
models = []
|
||||
model_1 = common_model_class_mock('model_1')
|
||||
models.append(model_1)
|
||||
model_2 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a'),
|
||||
model_1,
|
||||
model_1,
|
||||
'model_2',
|
||||
)
|
||||
models.append(model_2)
|
||||
model_3 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a'),
|
||||
model_2,
|
||||
model_1,
|
||||
'model_3',
|
||||
)
|
||||
models.append(model_3)
|
||||
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].model == model_1
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].fields == ('name',)
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].adj_list == []
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2].model == model_2
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_2].adj_list)[0] == ('fk_a',)
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_2].adj_list)[1]] == [model_1]
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3].model == model_3
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_3].adj_list)[0] == ('fk_a',)
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_3].adj_list)[1]] == [model_2]
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||
def test_graph_generation(common_model_class_mock, common_model_name_not_unique_class_mock, settings_mock):
|
||||
"""
|
||||
Graph topology:
|
||||
|
||||
model_1
|
||||
/\
|
||||
fk_a / \ fk_b
|
||||
/ \
|
||||
V V
|
||||
model_2_1 model_2_2
|
||||
/\fk_b /\
|
||||
fk_a / \ / \ fk_b
|
||||
/ \ /fk_a\
|
||||
V V V
|
||||
model_3_1 model_3_2 model_3_3
|
||||
"""
|
||||
models = []
|
||||
model_3_1 = common_model_class_mock('model_3_1')
|
||||
models.append(model_3_1)
|
||||
model_3_2 = common_model_class_mock('model_3_2')
|
||||
models.append(model_3_2)
|
||||
model_3_3 = common_model_class_mock('model_3_3')
|
||||
models.append(model_3_3)
|
||||
model_2_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_b', 'fk_a'),
|
||||
model_3_1,
|
||||
model_3_2,
|
||||
'model_2_1',
|
||||
)
|
||||
models.append(model_2_1)
|
||||
model_2_2 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_b', 'fk_a'),
|
||||
model_3_2,
|
||||
model_3_3,
|
||||
'model_2_2',
|
||||
)
|
||||
models.append(model_2_2)
|
||||
model_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a', 'fk_b'),
|
||||
model_2_1,
|
||||
model_2_2,
|
||||
'model_1',
|
||||
)
|
||||
models.append(model_1)
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].model == model_1
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_1].adj_list)[0] == ('fk_a', 'fk_b')
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_1].adj_list)[1]] == [model_2_1, model_2_2]
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2_1].model == model_2_1
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2_1].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_2_1].adj_list)[0] == ('fk_a', 'fk_b')
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_2_1].adj_list)[1]] == [model_3_1, model_3_2]
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2_2].model == model_2_2
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2_2].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_2_2].adj_list)[0] == ('fk_a', 'fk_b')
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_2_2].adj_list)[1]] == [model_3_2, model_3_3]
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_1].model == model_3_1
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_1].fields == ('name',)
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_1].adj_list == []
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_2].model == model_3_2
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_2].fields == ('name',)
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_2].adj_list == []
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_3].model == model_3_3
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_3].fields == ('name',)
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_3_3].adj_list == []
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||
def test_largest_graph_is_generated(common_model_name_not_unique_class_mock,
|
||||
common_model_class_mock, settings_mock):
|
||||
"""
|
||||
Graph topology:
|
||||
|
||||
model_1
|
||||
|
|
||||
| fk_a
|
||||
|
|
||||
V
|
||||
model_2
|
||||
/ \
|
||||
fk_b / \ fk_a
|
||||
/ \
|
||||
V V
|
||||
valid_model invalid_model
|
||||
"""
|
||||
models = []
|
||||
valid_model = common_model_class_mock('valid_model')
|
||||
models.append(valid_model)
|
||||
invalid_model = common_model_class_mock('invalid_model')
|
||||
model_2 = common_model_name_not_unique_class_mock(
|
||||
(('name', 'fk_a'), ('name', 'fk_b')),
|
||||
invalid_model,
|
||||
valid_model,
|
||||
'model_2',
|
||||
)
|
||||
models.append(model_2)
|
||||
model_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a'),
|
||||
model_2,
|
||||
model_2,
|
||||
'model_1',
|
||||
)
|
||||
models.append(model_1)
|
||||
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].model == model_1
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_1].adj_list)[0] == ('fk_a',)
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_1].adj_list)[1]] == [model_2]
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2].model == model_2
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_2].fields == ('name',)
|
||||
assert zip(*settings_mock.NAMED_URL_GRAPH[model_2].adj_list)[0] == ('fk_b',)
|
||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_2].adj_list)[1]] == [valid_model]
|
||||
|
||||
assert settings_mock.NAMED_URL_GRAPH[valid_model].model == valid_model
|
||||
assert settings_mock.NAMED_URL_GRAPH[valid_model].fields == ('name',)
|
||||
assert settings_mock.NAMED_URL_GRAPH[valid_model].adj_list == []
|
||||
|
||||
assert invalid_model not in settings_mock.NAMED_URL_GRAPH
|
||||
|
||||
|
||||
def test_contenttype_being_ignored(common_model_name_not_unique_class_mock, settings_mock):
|
||||
model = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a'),
|
||||
ContentType,
|
||||
ContentType,
|
||||
'model',
|
||||
)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph([model])
|
||||
assert settings_mock.NAMED_URL_GRAPH[model].model == model
|
||||
assert settings_mock.NAMED_URL_GRAPH[model].fields == ('name',)
|
||||
assert settings_mock.NAMED_URL_GRAPH[model].adj_list == []
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||
@pytest.mark.parametrize('input_, output', [
|
||||
('alice++bob+foo++cat++dog', {
|
||||
'name': 'alice',
|
||||
'fk_a__name': 'bob',
|
||||
'fk_a__str_with_choices_a': 'foo',
|
||||
'fk_b__name': 'dog',
|
||||
'fk_a__fk_a__name': 'cat',
|
||||
}),
|
||||
('alice++++dog', {
|
||||
'name': 'alice',
|
||||
'fk_b__name': 'dog',
|
||||
}),
|
||||
('alice++bob+foo++cat++', {
|
||||
'name': 'alice',
|
||||
'fk_a__name': 'bob',
|
||||
'fk_a__str_with_choices_a': 'foo',
|
||||
'fk_a__fk_a__name': 'cat',
|
||||
}),
|
||||
('alice++bob+foo++++dog', {
|
||||
'name': 'alice',
|
||||
'fk_a__name': 'bob',
|
||||
'fk_a__str_with_choices_a': 'foo',
|
||||
'fk_b__name': 'dog',
|
||||
}),
|
||||
])
|
||||
def test_populate_named_url_query_kwargs(common_model_name_not_unique_class_mock,
|
||||
common_model_class_mock, settings_mock,
|
||||
input_, output):
|
||||
"""
|
||||
graph topology:
|
||||
|
||||
model_1
|
||||
| \
|
||||
fk_a | \ fk_b
|
||||
| \
|
||||
v v
|
||||
model_2_1 model_2_2
|
||||
|
|
||||
| fk_a
|
||||
|
|
||||
v
|
||||
model_3
|
||||
"""
|
||||
models = []
|
||||
model_3 = common_model_class_mock('model_3')
|
||||
models.append(model_3)
|
||||
model_2_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a', 'str_with_choices_a'),
|
||||
model_3,
|
||||
model_3,
|
||||
'model_2_1',
|
||||
)
|
||||
models.append(model_2_1)
|
||||
model_2_2 = common_model_class_mock('model_2_2')
|
||||
models.append(model_2_2)
|
||||
model_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a', 'fk_b'),
|
||||
model_2_1,
|
||||
model_2_2,
|
||||
'model_1',
|
||||
)
|
||||
models.append(model_1)
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
kwargs = {}
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].populate_named_url_query_kwargs(kwargs, input_)
|
||||
assert kwargs == output
|
||||
|
||||
|
||||
@pytest.mark.parametrize('input_', [
|
||||
'4399',
|
||||
'alice-foo',
|
||||
'alice--bob',
|
||||
'alice-foo--bob--cat',
|
||||
'alice-foo--bob-',
|
||||
])
|
||||
def test_populate_named_url_invalid_query_kwargs(common_model_name_not_unique_class_mock,
|
||||
common_model_class_mock, settings_mock,
|
||||
input_):
|
||||
models = []
|
||||
model_2 = common_model_class_mock('model_2')
|
||||
models.append(model_2)
|
||||
model_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a', 'str_with_choices_a'),
|
||||
model_2,
|
||||
model_2,
|
||||
'model_1',
|
||||
)
|
||||
models.append(model_1)
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
kwargs = {}
|
||||
assert not settings_mock.NAMED_URL_GRAPH[model_1].populate_named_url_query_kwargs(kwargs, input_)
|
||||
|
||||
|
||||
def test_reserved_uri_char_decoding(common_model_class_mock, settings_mock):
|
||||
model = common_model_class_mock('model')
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph([model])
|
||||
kwargs = {}
|
||||
settings_mock.NAMED_URL_GRAPH[model].populate_named_url_query_kwargs(kwargs, r"%3B%2F%3F%3A%40%3D%26[+]")
|
||||
assert kwargs == {'name': ';/?:@=&+'}
|
||||
|
||||
|
||||
def test_unicode_decoding(common_model_class_mock, settings_mock):
|
||||
model = common_model_class_mock('model')
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph([model])
|
||||
kwargs = {}
|
||||
settings_mock.NAMED_URL_GRAPH[model].populate_named_url_query_kwargs(
|
||||
kwargs, r"%E6%88%91%E4%B8%BA%E6%88%91%E8%9B%A4%E7%BB%AD1s"
|
||||
)
|
||||
assert kwargs == {'name': u'我为我蛤续1s'}
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||
def test_generate_named_url(common_model_name_not_unique_class_mock,
|
||||
common_model_class_mock, settings_mock):
|
||||
"""
|
||||
graph topology:
|
||||
|
||||
model_1
|
||||
| \
|
||||
fk_a | \ fk_b
|
||||
| \
|
||||
v v
|
||||
model_2_1 model_2_2
|
||||
|
|
||||
| fk_a
|
||||
|
|
||||
v
|
||||
model_3
|
||||
"""
|
||||
models = []
|
||||
model_3 = common_model_class_mock('model_3')
|
||||
models.append(model_3)
|
||||
model_2_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a', 'str_with_choices_a'),
|
||||
model_3,
|
||||
model_3,
|
||||
'model_2_1',
|
||||
)
|
||||
models.append(model_2_1)
|
||||
model_2_2 = common_model_class_mock('model_2_2')
|
||||
models.append(model_2_2)
|
||||
model_1 = common_model_name_not_unique_class_mock(
|
||||
('name', 'fk_a', 'fk_b'),
|
||||
model_2_1,
|
||||
model_2_2,
|
||||
'model_1',
|
||||
)
|
||||
models.append(model_1)
|
||||
random.shuffle(models)
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph(models)
|
||||
obj_3 = model_3(name='cat')
|
||||
obj_2_2 = model_2_2(name='dog')
|
||||
obj_2_1 = model_2_1(name='bob', str_with_choices_a='foo', fk_a=obj_3)
|
||||
obj_1 = model_1(name='alice', fk_a=obj_2_1, fk_b=obj_2_2)
|
||||
obj_1.fk_b = None
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].generate_named_url(obj_1) == 'alice++bob+foo++cat++'
|
||||
obj_1.fk_b = obj_2_2
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].generate_named_url(obj_1) == 'alice++bob+foo++cat++dog'
|
||||
obj_2_1.fk_a = None
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].generate_named_url(obj_1) == 'alice++bob+foo++++dog'
|
||||
obj_1.fk_a = None
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].generate_named_url(obj_1) == 'alice++++dog'
|
||||
obj_1.fk_b = None
|
||||
assert settings_mock.NAMED_URL_GRAPH[model_1].generate_named_url(obj_1) == 'alice++++'
|
||||
|
||||
|
||||
def test_reserved_uri_char_encoding(common_model_class_mock, settings_mock):
|
||||
model = common_model_class_mock('model')
|
||||
with mock.patch('awx.main.utils.named_url_graph.settings', settings_mock):
|
||||
generate_graph([model])
|
||||
obj = model(name=u';/?:@=&+我为我蛤续1s')
|
||||
assert settings_mock.NAMED_URL_GRAPH[model].generate_named_url(obj) == u"%3B%2F%3F%3A%40%3D%26[+]我为我蛤续1s"
|
||||
Reference in New Issue
Block a user