Newer
Older
from opentech.apply.activity.models import Activity
from opentech.apply.funds.tests.factories import (
ApplicationSubmissionFactory,
ApplicationRevisionFactory,
LabSubmissionFactory,
SealedRoundFactory,
from opentech.apply.stream_forms.testing.factories import flatten_for_form
from opentech.apply.users.tests.factories import UserFactory, StaffFactory, SuperUserFactory
from opentech.apply.utils.testing.tests import BaseViewTestCase
from ..models import ApplicationRevision
def prepare_form_data(submission, **kwargs):
data = submission.raw_data
for field, value in kwargs.items():
# convert named fields into id
field_id = submission.field(field).id
data[field_id] = value
address_field = submission.must_include['address']
address = data.pop(address_field)
data.update(**prepare_address(address, address_field))
return data
def prepare_address(address, field):
address = json.loads(address)
address['locality'] = {
'localityname': address.pop('localityname'),
'administrativearea': address.pop('administrativearea'),
'postalcode': address.pop('postalcode'),
}
address = flatten_for_form(address, field, number=True)
return address
class BaseSubmissionViewTestCase(BaseViewTestCase):
url_name = 'funds:submissions:{}'
base_view_name = 'detail'
def get_kwargs(self, instance):
return {'pk': instance.id}
class TestStaffSubmissionView(BaseSubmissionViewTestCase):
user_factory = StaffFactory
@classmethod
def setUpTestData(cls):
cls.submission = ApplicationSubmissionFactory()
def __setUp__(self):
self.refresh(self.submission)
def test_can_view_a_submission(self):
response = self.get_page(self.submission)
self.assertContains(response, self.submission.title)
def test_can_view_a_lab_submission(self):
submission = LabSubmissionFactory()
response = self.get_page(submission)
self.assertContains(response, submission.title)
def test_can_progress_phase(self):
next_status = list(self.submission.get_actions_for_user(self.user))[0][0]
self.post_page(self.submission, {'form-submitted-progress_form': '', 'action': next_status})
submission = self.refresh(self.submission)
self.assertEqual(submission.status, next_status)
def test_redirected_to_determination(self):
submission = ApplicationSubmissionFactory(status='concept_review_discussion', workflow_stages=2, lead=self.user)
response = self.post_page(submission, {'form-submitted-progress_form': '', 'action': 'invited_to_proposal'})
# Invited for proposal is a a determination, so this will redirect to the determination form.
url = self.url_from_pattern('funds:submissions:determinations:form', kwargs={'submission_pk': submission.id})
self.assertRedirects(response, f"{url}?action=invited_to_proposal")
def test_cant_progress_stage_if_not_lead(self):
submission = ApplicationSubmissionFactory(status='concept_review_discussion', workflow_stages=2)
self.post_page(submission, {'form-submitted-progress_form': '', 'action': 'invited_to_proposal'})
submission = self.refresh(submission)
self.assertEqual(submission.status, 'concept_review_discussion')
self.assertIsNone(submission.next)
def test_cant_access_edit_button_when_applicant_editing(self):
submission = ApplicationSubmissionFactory(status='more_info')
response = self.get_page(submission)
self.assertNotContains(response, self.url(submission, 'edit', absolute=False))
def test_can_access_edit_button(self):
response = self.get_page(self.submission)
self.assertContains(response, self.url(self.submission, 'edit', absolute=False))
def test_can_access_edit(self):
response = self.get_page(self.submission, 'edit')
self.assertContains(response, self.submission.title)
def test_previous_and_next_appears_on_page(self):
proposal = InvitedToProposalFactory()
response = self.get_page(proposal)
self.assertContains(response, self.url(proposal.previous, absolute=False))
response = self.get_page(proposal.previous)
self.assertContains(response, self.url(proposal, absolute=False))
def test_can_edit_submission(self):
old_status = self.submission.status
data = prepare_form_data(self.submission, title=new_title)
response = self.post_page(self.submission, {'submit': True, **data}, 'edit')
url = self.url_from_pattern('funds:submissions:detail', kwargs={'pk': self.submission.id})
self.assertRedirects(response, url)
submission = self.refresh(self.submission)
# Staff edits don't affect the status
self.assertEqual(old_status, submission.status)
self.assertEqual(new_title, submission.title)
class TestApplicantSubmissionView(BaseSubmissionViewTestCase):
user_factory = UserFactory
@classmethod
def setUpTestData(cls):
super().setUpTestData()
cls.submission = ApplicationSubmissionFactory(user=cls.user)
cls.draft_proposal_submission = InvitedToProposalFactory(user=cls.user, draft=True)
def __setUp__(self):
self.refresh(self.submission)
self.refresh(self.draft_proposal_submission)
def test_can_view_own_submission(self):
response = self.get_page(self.submission)
self.assertContains(response, self.submission.title)
def test_sees_latest_draft_if_it_exists(self):
draft_revision = ApplicationRevisionFactory(submission=self.submission)
self.submission.draft_revision = draft_revision
self.submission.save()
draft_submission = self.submission.from_draft()
response = self.get_page(self.submission)
self.assertContains(response, draft_submission.title)
def test_cant_view_others_submission(self):
submission = ApplicationSubmissionFactory()
response = self.get_page(submission)
self.assertEqual(response.status_code, 403)
def test_get_edit_link_when_editable(self):
submission = ApplicationSubmissionFactory(user=self.user, status='more_info')
response = self.get_page(submission)
self.assertContains(response, 'Edit')
self.assertContains(response, self.url(submission, 'edit', absolute=False))
self.assertNotContains(response, 'Congratulations')
def test_get_congratulations_draft_proposal(self):
response = self.get_page(self.draft_proposal_submission)
self.assertContains(response, 'Congratulations')
response = self.get_page(self.draft_proposal_submission, 'edit')
self.assertContains(response, self.draft_proposal_submission.title)
def test_can_submit_submission(self):
old_status = self.draft_proposal_submission.status
data = prepare_form_data(self.draft_proposal_submission, title='This is different')
response = self.post_page(self.draft_proposal_submission, {'submit': True, **data}, 'edit')
url = self.url_from_pattern('funds:submissions:detail', kwargs={'pk': self.draft_proposal_submission.id})
self.assertRedirects(response, url)
submission = self.refresh(self.draft_proposal_submission)
self.assertNotEqual(old_status, submission.status)
def test_gets_draft_on_edit_submission(self):
draft_revision = ApplicationRevisionFactory(submission=self.draft_proposal_submission)
self.draft_proposal_submission.draft_revision = draft_revision
self.draft_proposal_submission.save()
response = self.get_page(self.draft_proposal_submission, 'edit')
self.assertDictEqual(response.context['object'].form_data, draft_revision.form_data)
def test_cant_edit_submission_incorrect_state(self):
submission = InvitedToProposalFactory(user=self.user)
response = self.get_page(submission, 'edit')
self.assertEqual(response.status_code, 403)
def test_cant_edit_other_submission(self):
submission = InvitedToProposalFactory(draft=True)
response = self.get_page(submission, 'edit')
self.assertEqual(response.status_code, 403)
class TestRevisionsView(BaseSubmissionViewTestCase):
user_factory = UserFactory
def test_create_revisions_on_submit(self):
submission = ApplicationSubmissionFactory(status='draft_proposal', workflow_stages=2, user=self.user)
old_data = submission.form_data.copy()
new_title = 'New title'
new_data = prepare_form_data(submission, title=new_title)
self.post_page(submission, {'submit': True, **new_data}, 'edit')
submission = self.refresh(submission)
self.assertEqual(submission.status, 'proposal_discussion')
self.assertEqual(submission.revisions.count(), 2)
self.assertDictEqual(submission.revisions.last().form_data, old_data)
self.assertDictEqual(submission.live_revision.form_data, submission.form_data)
self.assertEqual(submission.live_revision.author, self.user)
self.assertEqual(submission.title, new_title)
def test_dont_update_live_revision_on_save(self):
submission = ApplicationSubmissionFactory(status='draft_proposal', workflow_stages=2, user=self.user)
old_data = submission.form_data.copy()
new_data = prepare_form_data(submission, title='New title')
self.post_page(submission, {'save': True, **new_data}, 'edit')
submission = self.refresh(submission)
self.assertEqual(submission.status, 'draft_proposal')
self.assertEqual(submission.revisions.count(), 2)
self.assertDictEqual(submission.draft_revision.form_data, submission.from_draft().form_data)
self.assertEqual(submission.draft_revision.author, self.user)
self.assertDictEqual(submission.live_revision.form_data, old_data)
def test_existing_draft_edit_and_submit(self):
submission = ApplicationSubmissionFactory(status='draft_proposal', workflow_stages=2, user=self.user)
draft_data = prepare_form_data(submission, title='A new title')
self.post_page(submission, {'save': True, **draft_data}, 'edit')
submission = self.refresh(submission)
newer_title = 'Newer title'
draft_data = prepare_form_data(submission, title=newer_title)
self.post_page(submission, {'submit': True, **draft_data}, 'edit')
submission = self.refresh(submission)
self.maxDiff = None
self.assertEqual(submission.revisions.count(), 2)
self.assertDictEqual(submission.draft_revision.form_data, submission.from_draft().form_data)
self.assertDictEqual(submission.live_revision.form_data, submission.form_data)
self.assertEqual(submission.title, newer_title)
class TestRevisionCompare(BaseSubmissionViewTestCase):
base_view_name = 'revisions:compare'
user_factory = StaffFactory
def get_kwargs(self, instance):
return {
'submission_pk': instance.pk,
'to': instance.live_revision.id,
'from': instance.revisions.last().id,
}
def test_renders_with_all_the_diffs(self):
submission = ApplicationSubmissionFactory()
new_data = ApplicationSubmissionFactory(round=submission.round, form_fields=submission.form_fields).form_data
submission.form_data = new_data
submission.create_revision()
response = self.get_page(submission)
self.assertEqual(response.status_code, 200)
class TestRevisionList(BaseSubmissionViewTestCase):
base_view_name = 'revisions:list'
user_factory = StaffFactory
def get_kwargs(self, instance):
return {'submission_pk': instance.pk}
def test_list_doesnt_include_draft(self):
submission = ApplicationSubmissionFactory()
draft_revision = ApplicationRevisionFactory(submission=submission)
submission.draft_revision = draft_revision
submission.save()
response = self.get_page(submission)
self.assertNotIn(draft_revision, response.context['object_list'])
def test_get_in_correct_order(self):
submission = ApplicationSubmissionFactory()
revision = ApplicationRevisionFactory(submission=submission)
ApplicationRevision.objects.filter(id=revision.id).update(timestamp=datetime.now() - timedelta(days=1))
revision_older = ApplicationRevisionFactory(submission=submission)
ApplicationRevision.objects.filter(id=revision_older.id).update(timestamp=datetime.now() - timedelta(days=2))
response = self.get_page(submission)
self.assertSequenceEqual(
response.context['object_list'],
[submission.live_revision, revision, revision_older],
)
class TestStaffSealedView(BaseSubmissionViewTestCase):
user_factory = StaffFactory
def test_redirected_to_sealed(self):
submission = SealedSubmissionFactory()
response = self.get_page(submission)
url = self.url_from_pattern('funds:submissions:sealed', kwargs={'pk': submission.id})
self.assertRedirects(response, url)
def test_cant_post_to_sealed(self):
submission = SealedSubmissionFactory()
response = self.post_page(submission, {'some': 'data'}, 'sealed')
# Because of the redirect chain the url returned is not absolute
url = self.url_from_pattern('funds:submissions:sealed', kwargs={'pk': submission.id}, absolute=False)
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
self.assertRedirects(response, url)
def test_non_sealed_unaffected(self):
submission = ApplicationSubmissionFactory()
response = self.get_page(submission)
self.assertEqual(response.status_code, 200)
def test_non_sealed_redirected_away(self):
submission = ApplicationSubmissionFactory()
response = self.get_page(submission, 'sealed')
url = self.url_from_pattern('funds:submissions:detail', kwargs={'pk': submission.id})
self.assertRedirects(response, url)
class TestSuperUserSealedView(BaseSubmissionViewTestCase):
user_factory = SuperUserFactory
def test_redirected_to_sealed(self):
submission = SealedSubmissionFactory()
response = self.get_page(submission)
url = self.url_from_pattern('funds:submissions:sealed', kwargs={'pk': submission.id})
self.assertRedirects(response, url)
def test_can_post_to_sealed(self):
submission = SealedSubmissionFactory()
response = self.post_page(submission, {}, 'sealed')
url = self.url_from_pattern('funds:submissions:detail', kwargs={'pk': submission.id})
self.assertRedirects(response, url)
def test_peeking_is_logged(self):
submission = SealedSubmissionFactory()
self.post_page(submission, {}, 'sealed')
self.assertTrue('peeked' in self.client.session)
self.assertTrue(str(submission.id) in self.client.session['peeked'])
self.assertEqual(Activity.objects.count(), 1)
self.assertTrue('sealed' in Activity.objects.first().message)
def test_not_asked_again(self):
submission = SealedSubmissionFactory()
self.post_page(submission, {}, 'sealed')
# Now request the page again
response = self.get_page(submission)
self.assertEqual(response.status_code, 200)
def test_can_view_multiple_sealed(self):
sealed_round = SealedRoundFactory()
first, second = SealedSubmissionFactory.create_batch(2, round=sealed_round)
self.post_page(first, {}, 'sealed')
self.post_page(second, {}, 'sealed')
self.assertTrue('peeked' in self.client.session)
self.assertTrue(str(first.id) in self.client.session['peeked'])
self.assertTrue(str(second.id) in self.client.session['peeked'])