Skip to content

Commit 839ffde

Browse files
committed
tests
1 parent 94329d5 commit 839ffde

File tree

6 files changed

+216
-15
lines changed

6 files changed

+216
-15
lines changed

backend/visa/admin.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
)
2121

2222

23-
def process_invitation_letters(modeladmin, request, queryset):
24-
for invitation_letter_request in queryset:
25-
invitation_letter_request.schedule()
26-
27-
2823
@admin.register(InvitationLetterRequest)
2924
class InvitationLetterRequestAdmin(admin.ModelAdmin):
3025
fields = (
@@ -76,7 +71,6 @@ class InvitationLetterRequestAdmin(admin.ModelAdmin):
7671
"has_accommodation_via_grant",
7772
"send_via_email",
7873
)
79-
actions = [process_invitation_letters]
8074

8175
def save_form(self, request, form, change):
8276
obj = super().save_form(request, form, change)

backend/visa/models.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,23 +85,21 @@ def email(self):
8585

8686
return self.requester.email
8787

88-
@property
8988
def has_accommodation_via_grant(self):
9089
grant = self.user_grant
9190

9291
if not grant:
9392
return False
9493

95-
return grant.has_approved_accommodation
94+
return grant.has_approved_accommodation()
9695

97-
@property
9896
def has_travel_via_grant(self):
9997
grant = self.user_grant
10098

10199
if not grant:
102100
return False
103101

104-
return grant.has_approved_travel
102+
return grant.has_approved_travel()
105103

106104
@property
107105
def grant_approved_type(self):
@@ -116,7 +114,7 @@ def grant_approved_type(self):
116114
def user_grant(self):
117115
return Grant.objects.for_conference(self.conference).of_user(self.user).first()
118116

119-
def role(self):
117+
def get_role(self):
120118
user = self.user
121119

122120
if not user:

backend/visa/tasks.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ def _render_content(content, invitation_letter_request, config):
140140
"date_of_birth": invitation_letter_request.date_of_birth,
141141
"passport_number": invitation_letter_request.passport_number,
142142
"embassy_name": invitation_letter_request.embassy_name,
143-
"role": invitation_letter_request.role,
143+
"role": invitation_letter_request.get_role(),
144144
"grant_approved_type": invitation_letter_request.grant_approved_type,
145-
"has_accommodation_via_grant": invitation_letter_request.has_accommodation_via_grant,
146-
"has_travel_via_grant": invitation_letter_request.has_travel_via_grant,
145+
"has_accommodation_via_grant": invitation_letter_request.has_accommodation_via_grant(),
146+
"has_travel_via_grant": invitation_letter_request.has_travel_via_grant(),
147147
# conference
148148
"conference": invitation_letter_request.conference,
149149
}
@@ -159,7 +159,7 @@ def download_pretix_ticket(invitation_letter_request):
159159
attendee_ticket = next(
160160
(ticket for ticket in attendee_tickets if ticket["item"]["admission"]), None
161161
)
162-
assert attendee_ticket
162+
assert attendee_ticket, "No attendee ticket found"
163163

164164
ticket_url = attendee_ticket["downloads"][0]["url"]
165165

backend/visa/tests/test_admin.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
from django.urls import reverse
2+
from django.contrib.admin.sites import AdminSite
3+
from visa.models import InvitationLetterOrganizerConfig, InvitationLetterRequest
4+
from visa.admin import InvitationLetterDocumentInline, InvitationLetterRequestAdmin
5+
import pytest
6+
7+
from visa.tests.factories import (
8+
InvitationLetterDocumentFactory,
9+
InvitationLetterOrganizerConfigFactory,
10+
InvitationLetterRequestFactory,
11+
)
12+
13+
pytestmark = pytest.mark.django_db
14+
15+
16+
def test_edit_dynamic_document_view(rf, admin_user):
17+
admin = InvitationLetterDocumentInline(
18+
parent_model=InvitationLetterOrganizerConfig, admin_site=AdminSite()
19+
)
20+
21+
config = InvitationLetterOrganizerConfigFactory()
22+
document = InvitationLetterDocumentFactory(
23+
invitation_letter_organizer_config=config,
24+
document=None,
25+
)
26+
27+
request = rf.get("/")
28+
request.user = admin_user
29+
response = admin.edit_dynamic_document_view(request, config.id, document.id)
30+
31+
assert response.status_code == 200
32+
assert response.template_name == "astro/invitation-letter-document-builder.html"
33+
assert response.context_data["arguments"]["document_id"] == document.id
34+
assert response.context_data["arguments"]["breadcrumbs"]
35+
36+
37+
def test_edit_dynamic_document_button():
38+
admin = InvitationLetterDocumentInline(
39+
parent_model=InvitationLetterOrganizerConfig, admin_site=AdminSite()
40+
)
41+
42+
config = InvitationLetterOrganizerConfigFactory()
43+
document = InvitationLetterDocumentFactory(
44+
invitation_letter_organizer_config=config,
45+
document=None,
46+
)
47+
48+
html = admin.edit_dynamic_document(document)
49+
50+
url = reverse(
51+
"admin:edit_dynamic_document",
52+
kwargs={
53+
"config_id": config.id,
54+
"document_id": document.id,
55+
},
56+
)
57+
assert html == f'<a href="{url}">Edit</a>'
58+
59+
60+
def test_edit_dynamic_document_button_is_empty_for_static_docs():
61+
admin = InvitationLetterDocumentInline(
62+
parent_model=InvitationLetterOrganizerConfig, admin_site=AdminSite()
63+
)
64+
65+
config = InvitationLetterOrganizerConfigFactory()
66+
document = InvitationLetterDocumentFactory(
67+
invitation_letter_organizer_config=config
68+
)
69+
70+
html = admin.edit_dynamic_document(document)
71+
72+
assert html == ""
73+
74+
75+
def test_invitation_letter_request_admin():
76+
admin = InvitationLetterRequestAdmin(
77+
model=InvitationLetterRequest, admin_site=AdminSite()
78+
)
79+
80+
invitation_letter_request = InvitationLetterRequestFactory()
81+
82+
assert 'name="_process_now"' in admin.process_now(invitation_letter_request)
83+
assert "Generate the invitation letter first" == admin.send_via_email(
84+
invitation_letter_request
85+
)
86+
87+
88+
def test_invitation_letter_request_admin_post_processing_redirects_to_changelist(
89+
rf, admin_user
90+
):
91+
admin = InvitationLetterRequestAdmin(
92+
model=InvitationLetterRequest, admin_site=AdminSite()
93+
)
94+
95+
invitation_letter_request = InvitationLetterRequestFactory()
96+
request = rf.post("/")
97+
request.user = admin_user
98+
request.POST = {"_process_now": "1"}
99+
response = admin.response_post_save_change(request, invitation_letter_request)
100+
101+
assert response.status_code == 302
102+
assert response.url == reverse(
103+
"admin:visa_invitationletterrequest_change", args=[invitation_letter_request.id]
104+
)

backend/visa/tests/test_models.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from submissions.models import Submission
2+
from submissions.tests.factories import SubmissionFactory
3+
from grants.models import Grant
4+
from grants.tests.factories import GrantFactory
5+
from users.tests.factories import UserFactory
6+
from visa.models import InvitationLetterRequestOnBehalfOf
7+
from visa.tests.factories import InvitationLetterRequestFactory
8+
import pytest
9+
10+
pytestmark = pytest.mark.django_db
11+
12+
13+
def test_request_on_behalf_of_other():
14+
request = InvitationLetterRequestFactory(
15+
on_behalf_of=InvitationLetterRequestOnBehalfOf.OTHER,
16+
email_address="[email protected]",
17+
)
18+
19+
assert request.on_behalf_of_other
20+
assert request.email == "[email protected]"
21+
assert request.user is None
22+
assert request.get_role() == "Attendee"
23+
24+
# With matching user, it is found
25+
user = UserFactory(email="[email protected]")
26+
assert request.user.id == user.id
27+
28+
29+
@pytest.mark.parametrize(
30+
"approved_type",
31+
[
32+
Grant.ApprovedType.ticket_accommodation,
33+
Grant.ApprovedType.ticket_only,
34+
Grant.ApprovedType.ticket_travel,
35+
Grant.ApprovedType.ticket_travel_accommodation,
36+
],
37+
)
38+
def test_request_grant_info(approved_type):
39+
request = InvitationLetterRequestFactory(
40+
on_behalf_of=InvitationLetterRequestOnBehalfOf.SELF,
41+
email_address="[email protected]",
42+
)
43+
grant = GrantFactory(
44+
conference=request.conference,
45+
user=request.requester,
46+
approved_type=approved_type,
47+
)
48+
49+
assert request.user_grant == grant
50+
assert request.has_accommodation_via_grant() == (
51+
approved_type
52+
in [
53+
Grant.ApprovedType.ticket_accommodation,
54+
Grant.ApprovedType.ticket_travel_accommodation,
55+
]
56+
)
57+
assert request.has_travel_via_grant() == (
58+
approved_type
59+
in [
60+
Grant.ApprovedType.ticket_travel,
61+
Grant.ApprovedType.ticket_travel_accommodation,
62+
]
63+
)
64+
assert request.grant_approved_type == approved_type
65+
66+
67+
def test_role_for_speakers():
68+
request = InvitationLetterRequestFactory(
69+
on_behalf_of=InvitationLetterRequestOnBehalfOf.SELF,
70+
)
71+
SubmissionFactory(
72+
speaker=request.requester,
73+
conference=request.conference,
74+
status=Submission.STATUS.accepted,
75+
)
76+
77+
assert request.get_role() == "Speaker"
78+
79+
80+
def test_schedule_processing(django_capture_on_commit_callbacks, mocker):
81+
mock_task = mocker.patch("visa.tasks.process_invitation_letter_request")
82+
request = InvitationLetterRequestFactory(
83+
on_behalf_of=InvitationLetterRequestOnBehalfOf.SELF,
84+
)
85+
86+
with django_capture_on_commit_callbacks(execute=True):
87+
request.schedule()
88+
89+
mock_task.delay.assert_called_once_with(invitation_letter_request_id=request.id)

backend/visa/tests/test_tasks.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,22 @@ def test_process_invitation_letter_request_handles_failing_ticket_pdfs(
204204
)
205205

206206

207+
@override_settings(PRETIX_API="https://pretix/api/")
208+
def test_process_invitation_letter_request_does_nothing_for_processed_reqs():
209+
conference = ConferenceFactory()
210+
InvitationLetterOrganizerConfigFactory(organizer=conference.organizer)
211+
212+
request = InvitationLetterRequestFactory(
213+
conference=conference,
214+
status=InvitationLetterRequestStatus.PROCESSED,
215+
)
216+
217+
process_invitation_letter_request(invitation_letter_request_id=request.id)
218+
219+
request.refresh_from_db()
220+
assert request.status == InvitationLetterRequestStatus.PROCESSED
221+
222+
207223
def test_process_invitation_letter_request_failed():
208224
request = InvitationLetterRequestFactory()
209225

0 commit comments

Comments
 (0)