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_can_access_determination(self): submission = ApplicationSubmissionFactory(status='in_discussion') determination = DeterminationFactory(submission=submission, author=self.user, submitted=True) response = self.get_page(determination) self.assertContains(response, determination.submission.title) self.assertContains(response, self.user.full_name) self.assertContains(response, submission.get_absolute_url())
def test_mixed_determine_notifies(self): submission = ApplicationSubmissionFactory() dismissed_submission = ApplicationSubmissionFactory(status='rejected') DeterminationFactory(submission=dismissed_submission, rejected=True, submitted=True) action = 'dismiss' response = self.post_page( data=self.data(action, [submission, dismissed_submission])) self.assertEqual(len(response.context['messages']), 1)
def test_can_progress_one_in_mixed_state(self): bad_submission = ApplicationSubmissionFactory() good_submission = ApplicationSubmissionFactory( status='internal_review') action = 'close-review' self.post_page( data=self.data(action, [good_submission, bad_submission])) good_submission = self.refresh(good_submission) bad_submission = self.refresh(bad_submission) self.assertEqual(bad_submission.status, 'in_discussion') self.assertEqual(good_submission.status, 'post_review_discussion')
def test_can_edit_draft_determination_if_not_lead_with_projects(self): submission = ApplicationSubmissionFactory(status='in_discussion') determination = DeterminationFactory(submission=submission, author=self.user, accepted=True) response = self.post_page(submission, { 'data': 'value', 'outcome': determination.outcome }, 'form') self.assertContains(response, 'Approved') self.assertRedirects(response, self.absolute_url(submission.get_absolute_url()))
def test_cant_resubmit_determination(self): submission = ApplicationSubmissionFactory(status='in_discussion', lead=self.user) determination = DeterminationFactory(submission=submission, author=self.user, accepted=True, submitted=True) response = self.post_page(submission, { 'data': 'value', 'outcome': determination.outcome }, 'form') self.assertRedirects(response, self.absolute_url(submission.get_absolute_url()))
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_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_staff_cant_remove_reviewers_proposal(self): submission = ApplicationSubmissionFactory(reviewers=self.reviewers) self.assertCountEqual(submission.reviewers.all(), self.reviewers) self.post_form(submission, reviewers=[]) self.assertCountEqual(submission.reviewers.all(), self.reviewers)
def test_staff_can_remove_staff_single(self): submission = ApplicationSubmissionFactory(reviewers=self.staff) self.assertCountEqual(submission.reviewers.all(), self.staff) self.post_form(submission, []) self.assertCountEqual(submission.reviewers.all(), [])
def test_lead_can_remove_some_staff(self): submission = ApplicationSubmissionFactory(lead=self.user, reviewers=self.staff) self.assertCountEqual(submission.reviewers.all(), self.staff) self.post_form(submission, self.staff[0:2]) self.assertCountEqual(submission.reviewers.all(), self.staff[0:2])
def test_review_yes_mixed_opinion(self): submission = ApplicationSubmissionFactory() review = ReviewFactory(submission=submission) ReviewOpinionFactory(review=review, opinion_agree=True) ReviewOpinionFactory(review=review, opinion_disagree=True) recommendation = submission.reviews.recommendation() self.assertEqual(recommendation, MAYBE)
def test_review_not_all_opinion(self): submission = ApplicationSubmissionFactory() ReviewFactory(recommendation_yes=True, submission=submission) review = ReviewFactory(recommendation_yes=True, submission=submission) ReviewOpinionFactory(review=review, opinion_agree=True) recommendation = submission.reviews.recommendation() self.assertEqual(recommendation, YES)
def test_anonymous_can_not_access(self): submission = ApplicationSubmissionFactory() response = self.get_page(submission) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.redirect_chain), 2) for path, _ in response.redirect_chain: self.assertIn(reverse('users_public:login'), path)
def test_can_be_made_role_and_not_duplciated(self): submission = ApplicationSubmissionFactory() ReviewFactory(submission=submission, author__reviewer=self.staff[0], author__staff=True) self.post_form(submission, reviewer_roles=[self.staff[0]]) self.assertCountEqual(submission.reviewers.all(), [self.staff[0]])
def test_new_form_after_progress(self): submission = ApplicationSubmissionFactory(status='invited_to_proposal', workflow_stages=2, lead=self.user) stage = submission.stage DeterminationFactory(submission=submission, accepted=True) request = make_request(self.user, method='get', site=submission.page.get_site()) submission.progress_stage_when_possible(self.user, request) submission = self.refresh(submission) new_stage = submission.stage self.assertNotEqual(stage, new_stage) get_forms = submission.get_from_parent('get_defined_fields') self.assertEqual(submission.form_fields, get_forms(new_stage)) self.assertNotEqual(submission.form_fields, get_forms(stage))
def test_gets_blank_if_slack_not_set(self): adapter = SlackAdapter() submission = ApplicationSubmissionFactory(lead__slack='') recipients = adapter.recipients(MESSAGES.COMMENT, source=submission, related=None) self.assertTrue(submission.lead.slack in recipients[0])
def test_no_invite_if_can_edit(self): ApplicationSubmissionFactory(user=self.user, status='concept_more_info', workflow_stages=2) response = self.get_page() self.assertNotContains(response, 'Start your ') self.assertContains(response, 'Edit', 1)
def test_no_submissions_waiting_for_review(self): submission = ApplicationSubmissionFactory(status='external_review', workflow_stages=2, reviewers=[]) response = self.get_page() self.assertNotContains(response, submission.title) self.assertEquals(response.context['in_review_count'], 0)
def test_public_transition_kwargs(self): submission = ApplicationSubmissionFactory() kwargs = self.adapter.extra_kwargs(MESSAGES.TRANSITION, source=submission, sources=None) self.assertNotIn('visibility', kwargs)
def test_can_see_need_determinations(self): ApplicationSubmissionFactory(status='concept_review_discussion', workflow_stages=2, lead=self.user, form_data__title='Internet of things') response = self.get_page() self.assertContains(response, 'Internet of things')
def test_message_created_if_determination_exists(self): submissions = ApplicationSubmissionFactory.create_batch(2) DeterminationFactory(submission=submissions[0], accepted=True, is_draft=False) url = self.url(None) + '?submissions=' + ','.join( [str(submission.id) for submission in submissions]) + '&action=rejected' data = { 'submissions': [submission.id for submission in submissions], 'data': 'some data', 'outcome': REJECTED, 'message': 'Sorry', 'author': self.user.id, } response = self.client.post(url, data, secure=True, follow=True) self.assertEqual(submissions[0].determinations.count(), 1) self.assertEqual(submissions[0].determinations.first().outcome, ACCEPTED) self.assertEqual(submissions[1].determinations.count(), 1) self.assertEqual(submissions[1].determinations.first().outcome, REJECTED) # 5 base - 2 x django messages, 1 x activity feed, 1 x email, 1 x slack # plus 1 extra for unable to determine self.assertEqual(len(response.context['messages']), 6)
def test_cant_access_without_action(self): submission = ApplicationSubmissionFactory() url = self.url(None) + '?submissions=' + str(submission.id) response = self.client.get(url, follow=True, secure=True) self.assertRedirects(response, self.url_from_pattern('apply:submissions:list')) self.assertEqual(len(response.context['messages']), 1)
def test_second_stage_accepted_determination_creates_project(self): submission = ApplicationSubmissionFactory( status='proposal_determination', workflow_stages=2, lead=self.user, ) self.post_page( submission, { 'data': 'value', 'outcome': ACCEPTED, 'message': 'You are invited to submit a proposal', }, 'form') # Cant use refresh from DB with FSM submission_original = self.refresh(submission) submission_next = submission_original.next # import ipdb;ipdb.set_trace() # There should be no next submission since rejected is an end to the # applications flow. self.assertIsNone(submission_next) self.assertTrue(hasattr(submission_original, 'project')) self.assertFalse(hasattr(submission_next, 'project'))
def test_first_stage_rejected_determination_does_not_create_project(self): submission = ApplicationSubmissionFactory( status='concept_review_discussion', workflow_stages=2, lead=self.user, ) self.post_page( submission, { 'data': 'value', 'outcome': REJECTED, 'message': 'You are not invited to submit a proposal', }, 'form') # Cant use refresh from DB with FSM submission_original = self.refresh(submission) submission_next = submission_original.next # There should be no next submission since rejected is an end to the # applications flow. self.assertIsNone(submission_next) # Confirm a Project was not created for the original # ApplicationSubmission. self.assertFalse(hasattr(submission_original, 'project'))
def test_handle_transition_to_public_to_private(self): submission = ApplicationSubmissionFactory(status='internal_review') old_phase = submission.workflow.phases_for()[0] message = self.adapter.handle_transition(old_phase, submission) self.assertIn(submission.phase.display_name, message) self.assertIn(old_phase.display_name, message)
def test_internal_transition_kwarg_for_invisible_transition(self): submission = ApplicationSubmissionFactory( status='post_review_discussion') kwargs = self.adapter.extra_kwargs(MESSAGES.TRANSITION, source=submission, sources=None) self.assertEqual(kwargs['visibility'], TEAM)
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_not_redirected_if_determination_submitted(self): submission = ApplicationSubmissionFactory(lead=self.user) DeterminationFactory(submission=submission, rejected=True, submitted=True) self.post_page(submission, {'form-submitted-progress_form': '', 'action': 'rejected'}) submission = self.refresh(submission) self.assertEqual(submission.status, 'rejected')
def test_cant_edit_submitted_more_info(self): submission = ApplicationSubmissionFactory(status='in_discussion', lead=self.user) DeterminationFactory(submission=submission, author=self.user, submitted=True) response = self.get_page(submission, 'form') self.assertNotContains(response, 'Update ')