mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 11:00:03 -03:30
Refactor named URL unit tests
The original tests set no longer works after Django 1.11 due to more strict rules against dynamic model definition. The refactored tests set aims at each existing model that apply named URL rules, instead of abstract general use cases, thus significantly improves maintainability and readability. Signed-off-by: Aaron Tan <jangsutsr@gmail.com>
This commit is contained in:
parent
28c612ae9c
commit
54bf7e13d8
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"
|
||||
Loading…
x
Reference in New Issue
Block a user