Skip to content

Commit 3dd9d51

Browse files
committed
added tests for web app
1 parent 97186e1 commit 3dd9d51

6 files changed

Lines changed: 168 additions & 36 deletions

File tree

app/tests/conftest.py

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
"""Configure pytest for the tests module."""
22

3-
import io
43
import uuid
5-
from pathlib import Path
64
from unittest import mock
75

86
import pytest
9-
from faker import Faker
10-
from PIL import Image
117
from rest_framework.test import APIRequestFactory
128

139
from django.conf import settings
14-
from django.core.files.uploadedfile import SimpleUploadedFile
1510

1611
from app.settings import TenantTypes
1712
from oauth.models import User
@@ -142,44 +137,27 @@ def auth_user(client, factories, test_username, test_password):
142137

143138

144139
@pytest.fixture
145-
def admin_user(factories):
140+
def admin_user(factories, test_username, test_password):
146141
"""Inject a staff user."""
147-
return factories.users.create(is_staff=True)
142+
return factories.users.create(
143+
username=test_username,
144+
password=test_password,
145+
is_staff=True,
146+
)
148147

149148

150149
@pytest.fixture
151-
def superuser(factories):
150+
def superuser(factories, test_username, test_password):
152151
"""Inject a superuser."""
153-
return factories.users.create(is_superuser=True)
152+
return factories.users.create(
153+
username=test_username,
154+
password=test_password,
155+
is_staff=True,
156+
is_superuser=True,
157+
)
154158

155159

156160
@pytest.fixture
157161
def bare_agent(factories):
158162
"""Inject a **Bare Agent**, ie. a person without a related user."""
159163
return factories.people(bare_agent=True)
160-
161-
162-
@pytest.fixture
163-
def team_member(factories):
164-
"""Inject a regular team member."""
165-
return factories.team_members.create()
166-
167-
168-
@pytest.fixture
169-
def avatar_image():
170-
"""Inject an avatar image."""
171-
fake = Faker()
172-
filename = fake.file_name(category='image', extension='png')
173-
174-
with io.BytesIO() as buffer:
175-
image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
176-
image.save(buffer, 'png')
177-
buffer.name = filename
178-
buffer.seek(0)
179-
image_file = SimpleUploadedFile(name=filename, content=buffer.getvalue(), content_type='image/png')
180-
181-
# Manifest handling and filename collisions can cause a non-deterministic
182-
# hash to be added to the filename, so we retrieve the *actual* name next.
183-
filename = Path(image_file.name).name
184-
185-
return image_file

app/tests/domain/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Configure pytest for the tests.domain module."""

app/tests/factories/web.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Meta:
2424

2525
user = factory.SubFactory(UserFactory)
2626
name = factory.Faker('name')
27-
roles = factory.RelatedFactory(TeamMemberRoleFactory, factory_related_name='team_member')
27+
roles = factory.RelatedFactory(TeamMemberRoleFactory)
2828
title = factory.Faker('job')
2929
affiliation = factory.Faker('company')
3030
biography = factory.Faker('paragraph')
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""Test basic avatar functionality in the CMS."""
2+
3+
import pytest
4+
5+
from django.conf import settings
6+
from django.test import Client
7+
from django.urls import reverse
8+
9+
10+
@pytest.mark.django_db
11+
def test_avatar_saving_user(auth_user, avatar_image):
12+
auth_user.avatar.save(avatar_image.name, avatar_image, save=True)
13+
14+
assert (
15+
auth_user.avatar.url
16+
== f'/{settings.MEDIA_LOCATION}/public/{settings.AVATARS_LOCATION}/user/{avatar_image.name}'
17+
)
18+
19+
20+
@pytest.mark.django_db
21+
def test_avatar_saving_teammember(team_member, avatar_image):
22+
team_member.avatar.save(avatar_image.name, avatar_image, save=True)
23+
24+
assert (
25+
team_member.avatar.url
26+
== f'/{settings.MEDIA_LOCATION}/public/{settings.AVATARS_LOCATION}/teammember/{avatar_image.name}'
27+
)
28+
29+
30+
@pytest.mark.django_db
31+
def test_avatar_url_retrieval(team_member, avatar_image):
32+
user = team_member.user
33+
# Because the property `avatar_url` favours a team_member avatar over a user
34+
# avatar, the following assertion only works if the avatar is set in the `user` model first
35+
user.avatar.save(avatar_image.name, avatar_image, save=True)
36+
assert (
37+
team_member.avatar_url
38+
== f'/{settings.MEDIA_LOCATION}/public/{settings.AVATARS_LOCATION}/user/{avatar_image.name}'
39+
)
40+
41+
# If the team member avatar is set, it should now override the user's avatar
42+
team_member.avatar.save(avatar_image.name, avatar_image, save=True)
43+
assert (
44+
team_member.avatar_url
45+
== f'/{settings.MEDIA_LOCATION}/public/{settings.AVATARS_LOCATION}/teammember/{avatar_image.name}'
46+
)
47+
48+
49+
@pytest.mark.django_db
50+
@pytest.mark.urls('app.urls.urls_tenant')
51+
def test_avatar_rendering_in_views(superuser, avatar_image, test_username, test_password):
52+
client = Client(HTTP_HOST='dalme.localhost')
53+
client.login(username=test_username, password=test_password)
54+
response = client.get(reverse('wagtailadmin_home'))
55+
56+
assert '<img src="//www.gravatar.com/avatar' in response.content.decode(response.charset)
57+
58+
superuser.avatar.save(avatar_image.name, avatar_image, save=True)
59+
60+
response = client.get(reverse('wagtailadmin_home'))
61+
assert (
62+
f'<img src="/{settings.MEDIA_LOCATION}/public/{settings.AVATARS_LOCATION}/user/{avatar_image.name}"'
63+
in response.content.decode(response.charset)
64+
)

app/tests/web/conftest.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""Configure pytest for the tests.web module."""
2+
3+
import io
4+
from pathlib import Path
5+
6+
import pytest
7+
from django_tenants.utils import schema_context
8+
from faker import Faker
9+
from PIL import Image
10+
11+
from django.conf import settings
12+
from django.core.files.uploadedfile import SimpleUploadedFile
13+
from django.core.management import call_command
14+
from django.db import connection
15+
16+
from tenants.models import Domain, Tenant
17+
18+
19+
@pytest.fixture(scope='session', autouse=True)
20+
def setup_tenant_schema(django_db_setup, django_db_blocker): # noqa: ARG001
21+
tenants = settings.TENANTS()
22+
with django_db_blocker.unblock(), schema_context('public'):
23+
for tenant in tenants:
24+
domain, additional_domains, name, schema_name, is_primary, tenant_type = tenant.value
25+
26+
if not Tenant.objects.filter(name=name).exists():
27+
tenant_obj = Tenant.objects.create(
28+
name=name,
29+
schema_name=schema_name,
30+
tenant_type=tenant_type.value,
31+
)
32+
Domain.objects.create(
33+
domain=domain,
34+
tenant=tenant_obj,
35+
is_primary=is_primary,
36+
)
37+
38+
if schema_name not in [
39+
row[0]
40+
for row in connection.cursor()
41+
.execute('SELECT schema_name FROM information_schema.schemata')
42+
.fetchall()
43+
]:
44+
connection.cursor().execute(f'CREATE SCHEMA "{schema_name}"')
45+
call_command(
46+
'migrate_schemas', tenant=True, schema_name=schema_name, interactive=False, verbosity=0
47+
)
48+
49+
50+
@pytest.fixture
51+
def team_member(factories):
52+
"""Inject a regular team member."""
53+
return factories.team_members.create()
54+
55+
56+
@pytest.fixture
57+
def avatar_image():
58+
"""Inject an avatar image."""
59+
fake = Faker()
60+
filename = fake.file_name(category='image', extension='png')
61+
62+
with io.BytesIO() as buffer:
63+
image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
64+
image.save(buffer, 'png')
65+
buffer.name = filename
66+
buffer.seek(0)
67+
image_file = SimpleUploadedFile(name=filename, content=buffer.getvalue(), content_type='image/png')
68+
69+
# Manifest handling and filename collisions can cause a non-deterministic
70+
# hash to be added to the filename, so we retrieve the *actual* name next.
71+
filename = Path(image_file.name).name
72+
73+
return image_file
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""Test the web.management module."""
2+
3+
import os
4+
from unittest import mock
5+
6+
from web.management.commands.generate_tree import Command as GenerateTree
7+
8+
9+
@mock.patch.dict(os.environ, {'ENV': 'production'})
10+
@mock.patch('web.management.commands.generate_tree.logger')
11+
def test_generate_tree_production(mock_logger):
12+
GenerateTree().handle()
13+
14+
assert mock_logger.mock_calls == [
15+
mock.call.error('This command should never be run in production'),
16+
]

0 commit comments

Comments
 (0)