class PendingReviewsReminderTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category ) self.client.login(email=self.user.email, password='******') self.doc1 = DocumentFactory( category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), } ) self.doc2 = DocumentFactory( category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), } ) def test_empty_reminder_list(self): call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 0) def test_send_reminders(self): self.doc1.get_latest_revision().start_review() self.assertEqual(Review.objects.all().count(), 1) call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 1) def test_finished_reviews(self): rev = self.doc1.get_latest_revision() rev.start_review() rev.end_review() self.assertEqual(Review.objects.all().count(), 1) call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 0) def test_do_not_send_reminder(self): """Reminders are not send to users if their mail config says so.""" self.doc1.get_latest_revision().start_review() self.assertEqual(Review.objects.all().count(), 1) self.user.send_pending_reviews_mails = False self.user.save() call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 0)
class PendingReviewsReminderTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory(email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=self.user.email, password='******') self.doc1 = DocumentFactory(category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), }) self.doc2 = DocumentFactory(category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), }) def test_empty_reminder_list(self): call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 0) def test_send_reminders(self): self.doc1.get_latest_revision().start_review() self.assertEqual(Review.objects.all().count(), 1) call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 1) def test_finished_reviews(self): rev = self.doc1.get_latest_revision() rev.start_review() rev.end_review() self.assertEqual(Review.objects.all().count(), 1) call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 0) def test_do_not_send_reminder(self): """Reminders are not send to users if their mail config says so.""" self.doc1.get_latest_revision().start_review() self.assertEqual(Review.objects.all().count(), 1) self.user.send_pending_reviews_mails = False self.user.save() call_command('send_review_reminders') self.assertEqual(len(mail.outbox), 0)
class PrivateMediaViewTests(TestCase): def setUp(self): self.category = CategoryFactory() user = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=user.email, password='******') self.doc = DocumentFactory() self.rev = self.doc.get_latest_revision() pdf_doc = 'sample_doc_pdf.pdf' self.sample_pdf = SimpleUploadedFile(pdf_doc, b'content') def test_serve_wrong_field(self): with self.assertRaises(Http404): serve_model_file_field(self.rev, 'i_do_not_exist') def test_serve_empty_field(self): with self.assertRaises(Http404): serve_model_file_field(self.rev, 'pdf_file') def test_serve_file_field(self): self.rev.pdf_file = self.sample_pdf self.rev.save() res = serve_model_file_field(self.rev, 'pdf_file') self.assertTrue(isinstance(res, HttpResponse)) self.assertTrue('X-Accel-Redirect' in res)
class CleanMediaTests(TestCase): def setUp(self): self.category = CategoryFactory() user = UserFactory(email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=user.email, password='******') self.doc = DocumentFactory() self.rev = self.doc.get_latest_revision() def test_command(self): document = DocumentFactory(category=self.category, ) native_doc = 'sample_doc_native.docx' pdf_doc = 'sample_doc_pdf.pdf' MetadataRevisionFactory( metadata=document.get_metadata(), revision=2, native_file=SimpleUploadedFile(native_doc, b'content'), pdf_file=SimpleUploadedFile(pdf_doc, b'content'), ) # Document without files DocumentFactory(category=self.category, ) rev = document.get_latest_revision() filepath = rev.pdf_file.path # check file is on disk after doc deletion document.delete() self.assertTrue(os.path.exists(filepath)) call_command('clearmedia') # command has deleted file self.assertFalse(os.path.exists(filepath))
def test_command(self): document = DocumentFactory( category=self.category, ) native_doc = 'sample_doc_native.docx' pdf_doc = 'sample_doc_pdf.pdf' MetadataRevisionFactory( metadata=document.get_metadata(), revision=2, native_file=SimpleUploadedFile(native_doc, b'content'), pdf_file=SimpleUploadedFile(pdf_doc, b'content'), ) # Document without files DocumentFactory( category=self.category, ) rev = document.get_latest_revision() filepath = rev.pdf_file.path # check file is on disk after doc deletion document.delete() self.assertTrue(os.path.exists(filepath)) call_command('clearmedia') # command has deleted file self.assertFalse(os.path.exists(filepath))
class PrivateMediaViewTests(TestCase): def setUp(self): self.category = CategoryFactory() user = UserFactory(email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=user.email, password='******') self.doc = DocumentFactory() self.rev = self.doc.get_latest_revision() sample_path = b'documents/tests/' pdf_doc = b'sample_doc_pdf.pdf' self.sample_pdf = SimpleUploadedFile(pdf_doc, sample_path + pdf_doc) def test_serve_wrong_field(self): with self.assertRaises(Http404): serve_model_file_field(self.rev, 'i_do_not_exist') def test_serve_empty_field(self): with self.assertRaises(Http404): serve_model_file_field(self.rev, 'pdf_file') def test_serve_file_field(self): self.rev.pdf_file = self.sample_pdf self.rev.save() res = serve_model_file_field(self.rev, 'pdf_file') self.assertTrue(isinstance(res, HttpResponse)) self.assertTrue('X-Accel-Redirect' in res)
class StartReviewTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category ) self.doc = DocumentFactory( document_key='test_document', category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), } ) self.client.login(email=self.user.email, password='******') self.start_review_url = reverse('document_start_review', args=[ self.category.organisation.slug, self.category.slug, 'test_document']) def test_start_review_with_remarks(self): self.assertEqual(self.doc.note_set.all().count(), 0) res = self.client.post( self.start_review_url, {'body': 'This is a notification!'}, follow=True) self.assertEqual(res.status_code, 200) self.assertEqual(self.doc.note_set.all().count(), 1) activities = Activity.objects.all() self.assertEqual(activities.count(), 1) self.assertEqual(activities.get().verb, Activity.VERB_STARTED_REVIEW) self.assertEqual(activities.get().action_object, self.doc.get_latest_revision()) def test_start_review_with_empty_remark(self): self.assertEqual(self.doc.note_set.all().count(), 0) res = self.client.post( self.start_review_url, {'body': ''}, follow=True) self.assertEqual(res.status_code, 200) self.assertEqual(self.doc.note_set.all().count(), 0) def test_start_review_with_no_remark(self): self.assertEqual(self.doc.note_set.all().count(), 0) res = self.client.post(self.start_review_url, follow=True) self.assertEqual(res.status_code, 200) self.assertEqual(self.doc.note_set.all().count(), 0)
class PrivateDownloadTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=self.user.email, password='******') self.doc = DocumentFactory(category=self.category) self.rev = self.doc.get_latest_revision() sample_path = b'documents/tests/' pdf_doc = b'sample_doc_pdf.pdf' self.sample_pdf = SimpleUploadedFile(pdf_doc, sample_path + pdf_doc) self.url = reverse('revision_file_download', args=[ self.category.organisation.slug, self.category.slug, self.doc.document_key, self.rev.revision, 'pdf_file', ]) def test_download_empty_file(self): res = self.client.get(self.url) self.assertEqual(res.status_code, 404) def test_download_file(self): self.rev.pdf_file = self.sample_pdf self.rev.save() res = self.client.get(self.url) self.assertEqual(res.status_code, 200) def test_download_file_without_permissions(self): self.user.categories.clear() self.rev.pdf_file = self.sample_pdf self.rev.save() res = self.client.get(self.url) self.assertEqual(res.status_code, 404)
class PrivateDownloadTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory(email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=self.user.email, password='******') self.doc = DocumentFactory(category=self.category) self.rev = self.doc.get_latest_revision() sample_path = b'documents/tests/' pdf_doc = b'sample_doc_pdf.pdf' self.sample_pdf = SimpleUploadedFile(pdf_doc, sample_path + pdf_doc) self.url = reverse('revision_file_download', args=[ self.category.organisation.slug, self.category.slug, self.doc.document_key, self.rev.revision, 'pdf_file', ]) def test_download_empty_file(self): res = self.client.get(self.url) self.assertEqual(res.status_code, 404) def test_download_file(self): self.rev.pdf_file = self.sample_pdf self.rev.save() res = self.client.get(self.url) self.assertEqual(res.status_code, 200) def test_download_file_without_permissions(self): self.user.categories.clear() self.rev.pdf_file = self.sample_pdf self.rev.save() res = self.client.get(self.url) self.assertEqual(res.status_code, 404)
class CleanMediaTests(TestCase): def setUp(self): self.category = CategoryFactory() user = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=user.email, password='******') self.doc = DocumentFactory() self.rev = self.doc.get_latest_revision() def test_command(self): document = DocumentFactory( category=self.category, ) sample_path = b'documents/tests/' native_doc = b'sample_doc_native.docx' pdf_doc = b'sample_doc_pdf.pdf' MetadataRevisionFactory( metadata=document.get_metadata(), revision=2, native_file=SimpleUploadedFile(native_doc, sample_path + native_doc), pdf_file=SimpleUploadedFile(pdf_doc, sample_path + pdf_doc), ) # Document without files DocumentFactory( category=self.category, ) rev = document.get_latest_revision() filepath = rev.pdf_file.path # check file is on disk after doc deletion document.delete() self.assertTrue(os.path.exists(filepath)) call_command('clearmedia') # command has deleted file self.assertFalse(os.path.exists(filepath))
def create_lines(self, nb_existing=1, nb_new=1, **kwargs): """Create `nb_existing` + `nb_new` lines in the transmittal.""" doc = DocumentFactory( metadata_factory_class=ContractorDeliverableFactory, revision_factory_class=ContractorDeliverableRevisionFactory, category=self.category) rev = doc.get_latest_revision() metadata = doc.metadata arguments = { 'transmittal': self.transmittal, 'document': doc, 'document_key': doc.document_key, 'title': doc.title, 'is_new_revision': False, 'category': self.category, 'revision': rev.revision, } arguments.update(kwargs) # Existing revisions for i in range(nb_existing): rev = ContractorDeliverableRevisionFactory( metadata=metadata) arguments.update({'revision': rev.revision}) TrsRevisionFactory(**arguments) metadata.latest_revision = rev metadata.save() arguments.update({'is_new_revision': True}) # New revisions for i in range(nb_new): arguments.update({'revision': rev.revision + i + 1}) TrsRevisionFactory(**arguments) return doc
def test_command(self): document = DocumentFactory(category=self.category, ) native_doc = 'sample_doc_native.docx' pdf_doc = 'sample_doc_pdf.pdf' MetadataRevisionFactory( metadata=document.get_metadata(), revision=2, native_file=SimpleUploadedFile(native_doc, b'content'), pdf_file=SimpleUploadedFile(pdf_doc, b'content'), ) # Document without files DocumentFactory(category=self.category, ) rev = document.get_latest_revision() filepath = rev.pdf_file.path # check file is on disk after doc deletion document.delete() self.assertTrue(os.path.exists(filepath)) call_command('clearmedia') # command has deleted file self.assertFalse(os.path.exists(filepath))
def create_lines(self, nb_existing=1, nb_new=1, **kwargs): """Create `nb_existing` + `nb_new` lines in the transmittal.""" doc = DocumentFactory( metadata_factory_class=ContractorDeliverableFactory, revision_factory_class=ContractorDeliverableRevisionFactory, category=self.category) rev = doc.get_latest_revision() metadata = doc.metadata arguments = { 'transmittal': self.transmittal, 'document': doc, 'document_key': doc.document_key, 'title': doc.title, 'is_new_revision': False, 'category': self.category, 'revision': rev.revision, } arguments.update(kwargs) # Existing revisions for i in range(nb_existing): rev = ContractorDeliverableRevisionFactory(metadata=metadata) arguments.update({'revision': rev.revision}) TrsRevisionFactory(**arguments) metadata.latest_revision = rev metadata.save() arguments.update({'is_new_revision': True}) # New revisions for i in range(nb_new): arguments.update({'revision': rev.revision + i + 1}) TrsRevisionFactory(**arguments) return doc
class BatchReviewTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category ) self.client.login(email=self.user.email, password='******') self.doc1 = DocumentFactory( category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), } ) self.doc2 = DocumentFactory( category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), } ) self.doc3 = DocumentFactory( category=self.category, revision={ 'reviewers': [], 'leader': None, 'approver': None, 'received_date': datetime.date.today(), } ) self.content_type = ContentType.objects.get_for_model(self.doc3.metadata) self.ok = 'The review started for the following documents' self.nok = "We failed to start the review for the following documents" def test_batch_review_documents_success(self): self.assertFalse(self.doc1.metadata.latest_revision.is_under_review()) self.assertFalse(self.doc2.metadata.latest_revision.is_under_review()) do_batch_import.delay( self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc2.id]) doc1 = Document.objects.get(pk=self.doc1.pk) self.assertTrue(doc1.metadata.latest_revision.is_under_review()) doc2 = Document.objects.get(pk=self.doc2.pk) self.assertTrue(doc2.metadata.latest_revision.is_under_review()) # Check audit trail activities = Activity.objects.order_by('created_on') self.assertEqual(activities[0].verb, Activity.VERB_STARTED_REVIEW) self.assertEqual(activities[0].target, self.doc1.metadata.latest_revision) self.assertEqual(activities[1].verb, Activity.VERB_STARTED_REVIEW) self.assertEqual(activities[1].target, self.doc2.metadata.latest_revision) def test_batch_review_errors(self): self.assertFalse(self.doc3.metadata.latest_revision.is_under_review()) do_batch_import.delay( self.user.id, self.category.id, self.content_type.id, [self.doc3.id]) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc3.metadata.latest_revision.is_under_review()) # No activity was logged self.assertEqual(Activity.objects.count(), 0) def test_batch_review_half_success(self): self.assertFalse(self.doc1.metadata.latest_revision.is_under_review()) self.assertFalse(self.doc3.metadata.latest_revision.is_under_review()) do_batch_import.delay( self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc3.id]) doc1 = Document.objects.get(pk=self.doc1.pk) self.assertTrue(doc1.metadata.latest_revision.is_under_review()) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc3.metadata.latest_revision.is_under_review()) def test_batch_cancel_review(self): self.doc1.get_latest_revision().start_review() self.doc2.get_latest_revision().start_review() self.assertTrue(self.doc1.get_latest_revision().is_under_review()) self.assertTrue(self.doc2.get_latest_revision().is_under_review()) self.assertFalse(self.doc3.get_latest_revision().is_under_review()) batch_cancel_reviews.delay( self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc2.id, self.doc3.id]) doc1 = Document.objects.get(pk=self.doc1.pk) doc2 = Document.objects.get(pk=self.doc2.pk) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc1.get_latest_revision().is_under_review()) self.assertFalse(doc2.get_latest_revision().is_under_review()) self.assertFalse(doc3.get_latest_revision().is_under_review()) # Check audit trail activities = Activity.objects.order_by('created_on') # Only two reviews were canceled self.assertEqual(activities.count(), 2) for i, doc in enumerate([doc1, doc2]): self.assertEqual(activities[i].verb, Activity.VERB_CANCELLED_REVIEW) self.assertEqual(activities[i].target, doc.get_latest_revision())
class BatchReviewTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory(email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.client.login(email=self.user.email, password='******') self.doc1 = DocumentFactory(category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), }) self.doc2 = DocumentFactory(category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), }) self.doc3 = DocumentFactory(category=self.category, revision={ 'reviewers': [], 'leader': None, 'approver': None, 'received_date': datetime.date.today(), }) self.content_type = ContentType.objects.get_for_model( self.doc3.metadata) self.ok = 'The review started for the following documents' self.nok = "We failed to start the review for the following documents" def test_batch_review_documents_success(self): self.assertFalse(self.doc1.metadata.latest_revision.is_under_review()) self.assertFalse(self.doc2.metadata.latest_revision.is_under_review()) do_batch_import.delay(self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc2.id]) doc1 = Document.objects.get(pk=self.doc1.pk) self.assertTrue(doc1.metadata.latest_revision.is_under_review()) doc2 = Document.objects.get(pk=self.doc2.pk) self.assertTrue(doc2.metadata.latest_revision.is_under_review()) # Check audit trail activities = Activity.objects.order_by('created_on') self.assertEqual(activities[0].verb, Activity.VERB_STARTED_REVIEW) self.assertEqual(activities[0].target, self.doc1.metadata.latest_revision) self.assertEqual(activities[1].verb, Activity.VERB_STARTED_REVIEW) self.assertEqual(activities[1].target, self.doc2.metadata.latest_revision) def test_batch_review_errors(self): self.assertFalse(self.doc3.metadata.latest_revision.is_under_review()) do_batch_import.delay(self.user.id, self.category.id, self.content_type.id, [self.doc3.id]) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc3.metadata.latest_revision.is_under_review()) # No activity was logged self.assertEqual(Activity.objects.count(), 0) def test_batch_review_half_success(self): self.assertFalse(self.doc1.metadata.latest_revision.is_under_review()) self.assertFalse(self.doc3.metadata.latest_revision.is_under_review()) do_batch_import.delay(self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc3.id]) doc1 = Document.objects.get(pk=self.doc1.pk) self.assertTrue(doc1.metadata.latest_revision.is_under_review()) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc3.metadata.latest_revision.is_under_review()) def test_batch_cancel_review(self): self.doc1.get_latest_revision().start_review() self.doc2.get_latest_revision().start_review() self.assertTrue(self.doc1.get_latest_revision().is_under_review()) self.assertTrue(self.doc2.get_latest_revision().is_under_review()) self.assertFalse(self.doc3.get_latest_revision().is_under_review()) batch_cancel_reviews.delay(self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc2.id, self.doc3.id]) doc1 = Document.objects.get(pk=self.doc1.pk) doc2 = Document.objects.get(pk=self.doc2.pk) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc1.get_latest_revision().is_under_review()) self.assertFalse(doc2.get_latest_revision().is_under_review()) self.assertFalse(doc3.get_latest_revision().is_under_review()) # Check audit trail activities = Activity.objects.order_by('created_on') # Only two reviews were canceled self.assertEqual(activities.count(), 2) for i, doc in enumerate([doc1, doc2]): self.assertEqual(activities[i].verb, Activity.VERB_CANCELLED_REVIEW) self.assertEqual(activities[i].target, doc.get_latest_revision())
class UpdateDistribListTests(BaseReviewFormMixinTests): """Test distribution list updates during review. When reviewers, leader or approver are modified during a review, the actual distribution list must be updated accordingly. """ def setUp(self): super(UpdateDistribListTests, self).setUp() self.user4 = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.doc = DocumentFactory( metadata_factory_class=ContractorDeliverableFactory, revision_factory_class=ContractorDeliverableRevisionFactory, category=self.category, revision={ 'reviewers': [self.user], 'leader': self.user2, 'approver': self.user3, 'received_date': datetime.datetime.today(), }) self.rev = self.doc.get_latest_revision() self.data.update({ 'reviewers': str(self.user.id), 'leader': self.user2.id, 'approver': self.user3.id, 'review_start_date': datetime.datetime.today(), 'review_due_date': datetime.datetime.today() + datetime.timedelta(days=14) }) def test_form_is_valid(self): form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) def test_reviewers_cannot_be_added_after_reviewers_step(self): self.rev.start_review() self.rev.end_reviewers_step() reviewers = '{},{}'.format(self.user.id, self.user4.id) self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('reviewers' in form.errors) def test_reviewers_cannot_be_deleted_after_reviewers_step(self): self.rev.start_review() self.rev.end_reviewers_step() self.data.update({'reviewers': ''}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('reviewers' in form.errors) def test_reviewer_can_be_added_during_reviewers_step(self): self.rev.start_review() # Count initial Reviews qs = Review.objects \ .filter(document=self.rev.document) \ .filter(revision=self.rev.revision) \ .filter(role='reviewer') self.assertEqual(qs.count(), 1) # Add a reviewer reviewers = '{},{}'.format(self.user.id, self.user4.id) self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Count updated Reviews self.assertEqual(qs.count(), 2) def test_reviewer_may_be_deleted_during_reviewers_step(self): """A reviewer can be deleted if they didn't submit a review yet.""" self.rev.start_review() # Count initial Reviews qs = Review.objects \ .filter(document=self.rev.document) \ .filter(revision=self.rev.revision) \ .filter(role='reviewer') self.assertEqual(qs.count(), 1) # Remove a reviewer reviewers = '' self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Count updated Reviews self.assertEqual(qs.count(), 0) def test_reviewer_may_not_be_deleted_during_reviewers_step(self): """Reviewers that submitted a review cannot be removed.""" self.rev.reviewers.add(self.user4) self.rev.start_review() # Post a review review = self.rev.get_review(self.user) review.post_review(comments=None) # Assert the reviewers stop is still open self.rev.refresh_from_db() self.assertIsNone(self.rev.reviewers_step_closed) # Try to remove the initial reviewer reviewers = str(self.user4.id) self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('reviewers' in form.errors) def test_removing_reviewers_can_end_reviewers_step(self): """Remove all reviewers, and the review goes up to leader step.""" self.rev.reviewers.add(self.user4) self.rev.start_review() leader_review = self.rev.get_review(self.user2) self.assertEqual(leader_review.status, 'pending') # Count Review objects qs = Review.objects \ .filter(document=self.rev.document) \ .filter(revision=self.rev.revision) \ .filter(role='reviewer') self.assertEqual(qs.count(), 2) # Remove one reviewer self.data.update({'reviewers': str(self.user.id)}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Assert the reviewers step is still open self.rev.refresh_from_db() self.assertIsNone(self.rev.reviewers_step_closed) self.assertEqual(qs.count(), 1) # Remove second reviewer self.data.update({'reviewers': ''}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Assert the reviewers step is closed self.rev.refresh_from_db() self.assertEqual(qs.count(), 0) self.assertIsNotNone(self.rev.reviewers_step_closed) leader_review.refresh_from_db() self.assertEqual(leader_review.status, 'progress') def test_leader_cannot_be_changed_after_leader_step(self): self.rev.start_review() self.rev.end_leader_step() self.data.update({'leader': self.user4.id}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('leader' in form.errors) def test_update_leader_updates_distrib_list(self): self.rev.start_review() review = self.rev.get_review(self.user2) self.assertEqual(review.role, 'leader') self.data.update({'leader': self.user4.id}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user2) self.assertIsNone(review) review = rev.get_review(self.user4) self.assertEqual(review.role, 'leader') def test_approver_cannot_be_changed_after_approver_step(self): self.rev.start_review() self.rev.end_review() self.data.update({'approver': self.user4.id}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('approver' in form.errors) def test_update_approver_updates_distrib_list(self): self.rev.start_review() review = self.rev.get_review(self.user3) self.assertEqual(review.role, 'approver') self.data.update({'approver': self.user4.id}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user3) self.assertIsNone(review) review = rev.get_review(self.user4) self.assertEqual(review.role, 'approver') def test_removing_approver_during_approver_step_ends_review(self): self.rev.start_review() self.rev.end_leader_step() self.assertIsNone(self.rev.review_end_date) self.data.update({'approver': ''}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user3) self.assertIsNone(review) self.assertIsNotNone(self.rev.review_end_date) def test_removing_approver_before_approver_step_doesnt_end_review(self): self.rev.start_review() self.assertIsNone(self.rev.review_end_date) self.data.update({'approver': ''}) form = ContractorDeliverableRevisionForm( self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user3) self.assertIsNone(review) self.assertIsNone(self.rev.review_end_date)
class UpdateDistribListTests(BaseReviewFormMixinTests): """Test distribution list updates during review. When reviewers, leader or approver are modified during a review, the actual distribution list must be updated accordingly. """ def setUp(self): super(UpdateDistribListTests, self).setUp() self.user4 = UserFactory(email='*****@*****.**', password='******', is_superuser=True, category=self.category) self.doc = DocumentFactory( metadata_factory_class=ContractorDeliverableFactory, revision_factory_class=ContractorDeliverableRevisionFactory, category=self.category, revision={ 'reviewers': [self.user], 'leader': self.user2, 'approver': self.user3, 'received_date': datetime.datetime.today(), }) self.rev = self.doc.get_latest_revision() self.data.update({ 'reviewers': str(self.user.id), 'leader': self.user2.id, 'approver': self.user3.id, 'review_start_date': datetime.datetime.today(), 'review_due_date': datetime.datetime.today() + datetime.timedelta(days=14) }) def test_form_is_valid(self): form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) def test_reviewers_cannot_be_added_after_reviewers_step(self): self.rev.start_review() self.rev.end_reviewers_step() reviewers = '{},{}'.format(self.user.id, self.user4.id) self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('reviewers' in form.errors) def test_reviewers_cannot_be_deleted_after_reviewers_step(self): self.rev.start_review() self.rev.end_reviewers_step() self.data.update({'reviewers': ''}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('reviewers' in form.errors) def test_reviewer_can_be_added_during_reviewers_step(self): self.rev.start_review() # Count initial Reviews qs = Review.objects \ .filter(document=self.rev.document) \ .filter(revision=self.rev.revision) \ .filter(role='reviewer') self.assertEqual(qs.count(), 1) # Add a reviewer reviewers = '{},{}'.format(self.user.id, self.user4.id) self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Count updated Reviews self.assertEqual(qs.count(), 2) def test_reviewer_may_be_deleted_during_reviewers_step(self): """A reviewer can be deleted if they didn't submit a review yet.""" self.rev.start_review() # Count initial Reviews qs = Review.objects \ .filter(document=self.rev.document) \ .filter(revision=self.rev.revision) \ .filter(role='reviewer') self.assertEqual(qs.count(), 1) # Remove a reviewer reviewers = '' self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Count updated Reviews self.assertEqual(qs.count(), 0) def test_reviewer_may_not_be_deleted_during_reviewers_step(self): """Reviewers that submitted a review cannot be removed.""" self.rev.reviewers.add(self.user4) self.rev.start_review() # Post a review review = self.rev.get_review(self.user) review.post_review(comments=None) # Assert the reviewers stop is still open self.rev.refresh_from_db() self.assertIsNone(self.rev.reviewers_step_closed) # Try to remove the initial reviewer reviewers = str(self.user4.id) self.data.update({'reviewers': reviewers}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('reviewers' in form.errors) def test_removing_reviewers_can_end_reviewers_step(self): """Remove all reviewers, and the review goes up to leader step.""" self.rev.reviewers.add(self.user4) self.rev.start_review() leader_review = self.rev.get_review(self.user2) self.assertEqual(leader_review.status, 'pending') # Count Review objects qs = Review.objects \ .filter(document=self.rev.document) \ .filter(revision=self.rev.revision) \ .filter(role='reviewer') self.assertEqual(qs.count(), 2) # Remove one reviewer self.data.update({'reviewers': str(self.user.id)}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Assert the reviewers step is still open self.rev.refresh_from_db() self.assertIsNone(self.rev.reviewers_step_closed) self.assertEqual(qs.count(), 1) # Remove second reviewer self.data.update({'reviewers': ''}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertTrue(form.is_valid()) form.save() # Assert the reviewers step is closed self.rev.refresh_from_db() self.assertEqual(qs.count(), 0) self.assertIsNotNone(self.rev.reviewers_step_closed) leader_review.refresh_from_db() self.assertEqual(leader_review.status, 'progress') def test_leader_cannot_be_changed_after_leader_step(self): self.rev.start_review() self.rev.end_leader_step() self.data.update({'leader': self.user4.id}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('leader' in form.errors) def test_update_leader_updates_distrib_list(self): self.rev.start_review() review = self.rev.get_review(self.user2) self.assertEqual(review.role, 'leader') self.data.update({'leader': self.user4.id}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user2) self.assertIsNone(review) review = rev.get_review(self.user4) self.assertEqual(review.role, 'leader') def test_approver_cannot_be_changed_after_approver_step(self): self.rev.start_review() self.rev.end_review() self.data.update({'approver': self.user4.id}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) self.assertFalse(form.is_valid()) self.assertTrue('approver' in form.errors) def test_update_approver_updates_distrib_list(self): self.rev.start_review() review = self.rev.get_review(self.user3) self.assertEqual(review.role, 'approver') self.data.update({'approver': self.user4.id}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user3) self.assertIsNone(review) review = rev.get_review(self.user4) self.assertEqual(review.role, 'approver') def test_removing_approver_during_approver_step_ends_review(self): self.rev.start_review() self.rev.end_leader_step() self.assertIsNone(self.rev.review_end_date) self.data.update({'approver': ''}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user3) self.assertIsNone(review) self.assertIsNotNone(self.rev.review_end_date) def test_removing_approver_before_approver_step_doesnt_end_review(self): self.rev.start_review() self.assertIsNone(self.rev.review_end_date) self.data.update({'approver': ''}) form = ContractorDeliverableRevisionForm(self.data, instance=self.rev, category=self.category) rev = form.save() review = rev.get_review(self.user3) self.assertIsNone(review) self.assertIsNone(self.rev.review_end_date)
class BatchReviewTests(TestCase): def setUp(self): self.category = CategoryFactory() self.user = UserFactory( email='*****@*****.**', password='******', is_superuser=True, category=self.category ) self.client.login(email=self.user.email, password='******') self.doc1 = DocumentFactory( category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), } ) self.doc2 = DocumentFactory( category=self.category, revision={ 'leader': self.user, 'received_date': datetime.date.today(), } ) self.doc3 = DocumentFactory( category=self.category, revision={ 'reviewers': [], 'leader': None, 'approver': None, 'received_date': datetime.date.today(), } ) self.content_type = ContentType.objects.get_for_model(self.doc3.metadata) self.ok = 'The review started for the following documents' self.nok = "We failed to start the review for the following documents" def test_batch_review_documents_success(self): self.assertFalse(self.doc1.metadata.latest_revision.is_under_review()) self.assertFalse(self.doc2.metadata.latest_revision.is_under_review()) do_batch_import.delay( self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc2.id]) doc1 = Document.objects.get(pk=self.doc1.pk) self.assertTrue(doc1.metadata.latest_revision.is_under_review()) doc2 = Document.objects.get(pk=self.doc2.pk) self.assertTrue(doc2.metadata.latest_revision.is_under_review()) def test_batch_review_errors(self): self.assertFalse(self.doc3.metadata.latest_revision.is_under_review()) do_batch_import.delay( self.user.id, self.category.id, self.content_type.id, [self.doc3.id]) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc3.metadata.latest_revision.is_under_review()) def test_batch_review_half_success(self): self.assertFalse(self.doc1.metadata.latest_revision.is_under_review()) self.assertFalse(self.doc3.metadata.latest_revision.is_under_review()) do_batch_import.delay( self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc3.id]) doc1 = Document.objects.get(pk=self.doc1.pk) self.assertTrue(doc1.metadata.latest_revision.is_under_review()) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc3.metadata.latest_revision.is_under_review()) def test_batch_cancel_review(self): self.doc1.get_latest_revision().start_review() self.doc2.get_latest_revision().start_review() self.assertTrue(self.doc1.get_latest_revision().is_under_review()) self.assertTrue(self.doc2.get_latest_revision().is_under_review()) self.assertFalse(self.doc3.get_latest_revision().is_under_review()) batch_cancel_reviews.delay( self.user.id, self.category.id, self.content_type.id, [self.doc1.id, self.doc2.id, self.doc3.id]) doc1 = Document.objects.get(pk=self.doc1.pk) doc2 = Document.objects.get(pk=self.doc2.pk) doc3 = Document.objects.get(pk=self.doc3.pk) self.assertFalse(doc1.get_latest_revision().is_under_review()) self.assertFalse(doc2.get_latest_revision().is_under_review()) self.assertFalse(doc3.get_latest_revision().is_under_review())