def test_only_comments_from_process_owner_returned(self): archivaris = UserFactory.create( role__type=RoleTypeChoices.archivist, role__can_start_destruction=False, role__can_review_destruction=True, role__can_view_case_details=False, ) process_owner = UserFactory.create( role__type=RoleTypeChoices.process_owner, role__can_start_destruction=False, role__can_review_destruction=True, role__can_view_case_details=True, ) destruction_list = DestructionListFactory.create( status=ListStatus.processing) DestructionListItemFactory.create( destruction_list=destruction_list, status=ListItemStatus.failed, extra_zaak_data={ "identificatie": "ZAAK-1", "omschrijving": "Een zaak", "toelichting": "Bah", "startdatum": "2020-01-01", "einddatum": "2021-01-01", "zaaktype": "https://oz.nl/catalogi/api/v1/zaaktypen/uuid-1", }, ) DestructionListItemFactory.create( destruction_list=destruction_list, status=ListItemStatus.destroyed, extra_zaak_data={ "identificatie": "ZAAK-2", "omschrijving": "Een andere zaak", "toelichting": "", "startdatum": "2020-02-01", "einddatum": "2021-03-01", "zaaktype": "https://oz.nl/catalogi/api/v1/zaaktypen/uuid-2", }, ) DestructionListReviewFactory.create( destruction_list=destruction_list, status=ReviewStatus.approved, author=archivaris, text="What a magnificent list!", ) DestructionListReviewFactory.create( destruction_list=destruction_list, status=ReviewStatus.approved, author=process_owner, text="I am happy with this list!", ) comment = get_process_owner_comments(destruction_list) self.assertEqual("I am happy with this list!", comment)
def test_start_page_with_demo_details_if_demo_mode(self): UserFactory.create( username="******", role__can_start_destruction=True, role__can_review_destruction=False, role__can_view_case_details=True, ) response = self.client.get(reverse("entry"), follow=True) self.assertEqual(200, response.status_code) self.assertIn(b"demo mode", response.content)
def test_demo_mode_normal_user(self): UserFactory.create( username="******", role__can_start_destruction=True, role__can_review_destruction=False, role__can_view_case_details=True, ) response = self.client.get( reverse("demo-login", args=[self.user.pk]), follow=True ) self.assertEqual(200, response.status_code) self.assertEqual(response.request["PATH_INFO"], reverse("start-page"))
def test_retrieve_missing_zaak(self, m): self._set_up_services() self._set_up_mocks(m) user = UserFactory.create( username="******", password="******", email="*****@*****.**", role__can_start_destruction=True, role__can_review_destruction=True, ) destruction_list = DestructionListFactory.create(author=user, assignee=user) missing_zaak_url = f"{ZAKEN_ROOT}zaken/uuid-3" DestructionListItemFactory.create(destruction_list=destruction_list, zaak=missing_zaak_url) m.get(missing_zaak_url, status_code=404) url = reverse("destruction:fetch-list-items", args=[destruction_list.id]) self.client.force_login(user) response = self.client.get(url) self.assertEqual(200, response.status_code) self.assertIn("error", response.json())
def test_empty_archiefactiedatum(self, m_update_zaak, m_fetch_zaak): user = UserFactory(role__can_start_destruction=True) view_url = furl(reverse("destruction:update-zaak-archive-details")) view_url.args.set("url", "http://openzaak.nl/some/zaak") form = self.app.get(view_url.url, user=user).form form["url"] = "http://openzaak.nl/some/valid/zaak/url" form["archiefnominatie"] = Archiefnominatie.blijvend_bewaren form["comment"] = "Some interesting comment" response = form.submit() self.assertRedirects(response, view_url.url, fetch_redirect_response=False) m_update_zaak.assert_called_with( "http://openzaak.nl/some/valid/zaak/url", {"archiefnominatie": Archiefnominatie.blijvend_bewaren}, audit_comment="Some interesting comment", ) response = response.follow() messages = list(response.context.get("messages")) self.assertEqual(1, len(messages)) self.assertEqual(messages[0].tags, "success")
def test_assigned_on_field_population_on_assignment(self): reviewers = UserFactory.create_batch(2, role__can_review_destruction=True) zaken = [f"http://some.zaken.nl/api/v1/zaken/{i}" for i in range(1, 3)] zaken_identificaties = ["ZAAK-1", "ZAAK-2", "ZAAK-3"] url = reverse("destruction:record-manager-create") data = { "name": "test list", "zaken": ",".join(zaken), "reviewer_1": reviewers[0].id, "reviewer_2": reviewers[1].id, "zaken_identificaties": ",".join(zaken_identificaties), } response = self.client.post(url, data) self.assertRedirects(response, reverse("destruction:record-manager-list")) destruction_list = DestructionList.objects.get() assignees = destruction_list.assignees.order_by("id") self.assertIsNotNone(assignees.first().assigned_on) self.assertIsNone(assignees.last().assigned_on)
def test_no_municipality_configured(self): config = EmailConfig.get_solo() config.municipality = "" config.save() user = UserFactory.create(is_staff=True, is_superuser=True) response = self.app.get(reverse("admin:emails_automaticemail_add"), user=user) form = response.form form["type"] = EmailTypeChoices.review_required form["body"] = "This is a test body with a variable {{ municipality }}" form["subject"] = "Test subject" response = form.submit() self.assertEqual(200, response.status_code) self.assertIn( "When using the municipality variable, a municipality name needs to be configured.", response.text, ) self.assertEqual(0, AutomaticEmail.objects.count())
def setUpTestData(cls): super().setUpTestData() cls.functioneel_beheer = UserFactory.create( username="******", role__can_start_destruction=True, role__can_review_destruction=True, role__can_view_case_details=True, ) cls.process_eigenaar = UserFactory.create( username="******", role__can_start_destruction=False, role__can_review_destruction=True, role__can_view_case_details=True, ) cls.user = UserFactory.create(username="******")
def test_create_zaak_set(self): user = UserFactory.create(is_staff=True, is_superuser=True) response = self.app.get( reverse("admin:destruction_archiveconfig_change"), user=user ) form = response.form form["create_zaak"] = True form["source_organisation"] = "111222333" form["case_type"] = "http://openzaak.nl/zaaktype/1" form["status_type"] = "http://openzaak.nl/statustype/1" form["result_type"] = "http://openzaak.nl/resultaattype/1" form["document_type"] = "http://openzaak.nl/informatieobjecttype/1" response = form.submit().follow() self.assertEqual(200, response.status_code) conf = ArchiveConfig.get_solo() self.assertEqual(conf.create_zaak, True) self.assertEqual(conf.source_organisation, "111222333") self.assertEqual(conf.case_type, "http://openzaak.nl/zaaktype/1") self.assertEqual(conf.result_type, "http://openzaak.nl/resultaattype/1") self.assertEqual(conf.status_type, "http://openzaak.nl/statustype/1") self.assertEqual( conf.document_type, "http://openzaak.nl/informatieobjecttype/1" )
def test_empty_comment_is_not_saved(self, m): record_manager = UserFactory( role__can_start_destruction=True, role__type=RoleTypeChoices.archivist ) process_owner = UserFactory( role__can_review_destruction=True, role__type=RoleTypeChoices.process_owner ) destruction_list = DestructionListFactory.create(author=record_manager) item = DestructionListItemFactory.create(destruction_list=destruction_list) DestructionListAssigneeFactory.create( assignee=record_manager, destruction_list=destruction_list ) destruction_list.assignee = record_manager destruction_list.save() DestructionListReviewFactory.create( destruction_list=destruction_list, author=process_owner, status=ReviewStatus.changes_requested, ) data = { "items-TOTAL_FORMS": 1, "items-INITIAL_FORMS": 1, "items-MIN_NUM_FORMS": 0, "items-MAX_NUM_FORMS": 1000, "items-0-id": item.id, "items-0-action": "", "items-0-archiefnominatie": "blijvend_bewaren", "items-0-archiefactiedatum": "2020-06-17", "items-0-identificatie": "ZAAK-01", "text": "", } self.client.force_login(record_manager) response = self.client.post( reverse("destruction:record-manager-detail", args=[destruction_list.pk]), data=data, ) self.assertRedirects(response, reverse("destruction:record-manager-list")) comments = DestructionListReviewComment.objects.all() self.assertEqual(0, comments.count())
def test_logs_are_in_correct_order(self): record_manager = UserFactory.create( role__type=RoleTypeChoices.record_manager) archivaris = UserFactory.create(role__type=RoleTypeChoices.archivist) destruction_list = DestructionListFactory.create(author=record_manager) review = DestructionListReviewFactory.create( destruction_list=destruction_list, author=archivaris) with freeze_time("2012-01-14 12:00"): TimelineLog.objects.create( content_object=destruction_list, template="destruction/logs/created.html", extra_data={"n_items": 3}, user=record_manager, ) with freeze_time("2012-01-14 12:05"): TimelineLog.objects.create( content_object=review, template="destruction/logs/review_created.html", user=archivaris, ) with freeze_time("2012-01-14 12:10"): TimelineLog.objects.create( content_object=destruction_list, template="destruction/logs/updated.html", extra_data={"n_items": 1}, user=record_manager, ) with freeze_time("2012-01-14 12:15"): TimelineLog.objects.create( content_object=destruction_list, template="destruction/logs/aborted.html", extra_data={"n_items": 3}, user=record_manager, ) report = create_audittrail_report(destruction_list) html_report = document_fromstring(report) self.assertEqual(4, len(html_report.find_class("log-item"))) titles = html_report.find_class("log-item__title") times = [title.text_content() for title in titles] sorted_times = sorted(times) self.assertEqual(times, sorted_times)
def test_permission_denied_if_no_zaak_url(self): user = UserFactory(role__can_start_destruction=True) self.client.force_login(user) response = self.client.get( reverse("destruction:update-zaak-archive-details")) self.assertEqual(403, response.status_code)
def test_no_zaak_urls_query_param_raises_error(self): user = UserFactory(role__can_start_destruction=True) self.client.force_login(user) url = furl(reverse("destruction:export-zaken-without-archive-date")) response = self.client.get(url.url) self.assertEqual(400, response.status_code)
def test_fetch_zaken_no_filters(self, m): user = UserFactory.create(role__can_start_destruction=True) self.client.force_login(user) response = self.client.get(reverse("destruction:fetch-zaken")) self.assertEqual(200, response.status_code) m.assert_called_once_with({})
def setUpTestData(cls): cls.user = UserFactory.create(role__can_review_destruction=True) destruction_list = DestructionListFactory.create() DestructionListReviewFactory.create(destruction_list=destruction_list, author=cls.user) DestructionReportFactory.create(destruction_list=destruction_list, process_owner=cls.user)
def test_sensitive_data_for_process_owner(self, m): self._set_up_services() record_manager = UserFactory.create( role__can_start_destruction=True, role__type=RoleTypeChoices.record_manager, ) process_owner = UserFactory.create( role__can_review_destruction=True, role__type=RoleTypeChoices.process_owner, ) destruction_list = DestructionListFactory.create( author=record_manager, assignee=process_owner, contains_sensitive_info=True, ) DestructionListItemFactory.create(destruction_list=destruction_list, zaak=ZAAK_1["url"]) DestructionListItemFactory.create(destruction_list=destruction_list, zaak=ZAAK_2["url"]) DestructionListAssigneeFactory.create( destruction_list=destruction_list, assignee=process_owner) self._set_up_mocks(m) url = reverse("destruction:fetch-list-items", args=[destruction_list.id]) self.client.force_login(process_owner) response = self.client.get(url) self.assertEqual(200, response.status_code) response_data = response.json() self.assertIn("items", response_data) self.assertEqual(2, len(response_data["items"])) # Even if the list contains sensitive data, the process owner should be able to see it zaak_1_data = response_data["items"][0]["zaak"] self.assertIn("omschrijving", zaak_1_data) zaak_2_data = response_data["items"][1]["zaak"] self.assertIn("omschrijving", zaak_2_data)
def test_no_sensitive_data_for_archivist(self, m): self._set_up_services() record_manager = UserFactory.create( role__can_start_destruction=True, role__type=RoleTypeChoices.record_manager, ) archivist = UserFactory.create( role__can_review_destruction=True, role__type=RoleTypeChoices.archivist, ) destruction_list = DestructionListFactory.create( author=record_manager, assignee=archivist, contains_sensitive_info=False, ) DestructionListItemFactory.create(destruction_list=destruction_list, zaak=ZAAK_1["url"]) DestructionListItemFactory.create(destruction_list=destruction_list, zaak=ZAAK_2["url"]) DestructionListAssigneeFactory.create( destruction_list=destruction_list, assignee=archivist) self._set_up_mocks(m) url = reverse("destruction:fetch-list-items", args=[destruction_list.id]) self.client.force_login(archivist) response = self.client.get(url) self.assertEqual(200, response.status_code) response_data = response.json() self.assertIn("items", response_data) self.assertEqual(2, len(response_data["items"])) # Since the list does NOT contain sensitive data, the archivist can see it zaak_1_data = response_data["items"][0]["zaak"] self.assertIn("omschrijving", zaak_1_data) zaak_2_data = response_data["items"][1]["zaak"] self.assertIn("omschrijving", zaak_2_data)
def test_cant_access_without_can_start_destruction(self): user = UserFactory(role__can_start_destruction=False) self.client.force_login(user) response = self.client.get( reverse("destruction:zaken-without-archive-date")) self.assertEqual(403, response.status_code)
def setUpTestData(cls): cls.record_manager = UserFactory( role__can_start_destruction=True, role__type=RoleTypeChoices.record_manager ) cls.process_owner = UserFactory( role__can_review_destruction=True, role__type=RoleTypeChoices.process_owner ) # List 1: In progress cls.dl_in_progress = DestructionListFactory.create(author=cls.record_manager) assignee = DestructionListAssigneeFactory.create( assignee=cls.process_owner, destruction_list=cls.dl_in_progress, order=1 ) cls.dl_in_progress.assignee = assignee.assignee cls.dl_in_progress.save() # List 2: Changes requested cls.dl_changes_required = DestructionListFactory.create( author=cls.record_manager ) assignee = DestructionListAssigneeFactory.create( assignee=cls.record_manager, destruction_list=cls.dl_changes_required ) cls.dl_changes_required.assignee = assignee.assignee cls.dl_changes_required.save() # List 3: Rejected cls.dl_rejected = DestructionListFactory.create(author=cls.record_manager) assignee = DestructionListAssigneeFactory.create( assignee=cls.record_manager, destruction_list=cls.dl_rejected ) cls.dl_rejected.assignee = assignee.assignee cls.dl_rejected.save() # List 4: Approved cls.dl_approved = DestructionListFactory.create(author=cls.record_manager) cls.dl_approved.assignee = None cls.dl_approved.save() # List 5: Complete cls.dl_complete = DestructionListFactory.create(author=cls.record_manager) cls.dl_complete.process() cls.dl_complete.save() cls.dl_complete.complete() cls.dl_complete.save()
def test_right_user_can_access(self): user = UserFactory.create() self.client.force_login(user) response = self.client.get( reverse("emails:email-preference-update", args=[user.emailpreference.pk])) self.assertEqual(200, response.status_code)
def test_cant_add_report(self): superuser = UserFactory.create(is_staff=True, is_superuser=True) self.client.force_login(superuser) url = reverse("admin:report_destructionreport_add") response = self.client.get(url) self.assertEqual(403, response.status_code)
def test_logs_from_right_list_are_shown(self): record_manager = UserFactory.create( role__type=RoleTypeChoices.record_manager) archivaris = UserFactory.create(role__type=RoleTypeChoices.archivist) destruction_list_1 = DestructionListFactory.create( author=record_manager, name="Incredible list 1") review_1 = DestructionListReviewFactory.create( destruction_list=destruction_list_1, author=archivaris) destruction_list_2 = DestructionListFactory.create( author=record_manager, name="Incredible list 2") review_2 = DestructionListReviewFactory.create( destruction_list=destruction_list_2, author=archivaris) TimelineLog.objects.create( content_object=destruction_list_1, template="destruction/logs/created.html", extra_data={"n_items": 3}, user=record_manager, ) TimelineLog.objects.create( content_object=review_1, template="destruction/logs/review_created.html", user=archivaris, ) # These should not appear in the audit trail report, because they are not related to the right list TimelineLog.objects.create( content_object=destruction_list_2, template="destruction/logs/created.html", extra_data={"n_items": 3}, user=record_manager, ) TimelineLog.objects.create( content_object=review_2, template="destruction/logs/review_created.html", user=archivaris, ) report = create_audittrail_report(destruction_list_1) html_report = document_fromstring(report) self.assertEqual(2, len(html_report.find_class("log-item"))) self.assertIn("Incredible list 1", report) self.assertNotIn("Incredible list 2", report)
def test_archivarist_cant_access(self, m_archive_config): m_archive_config.return_value = ArchiveConfig( destruction_report_downloadable=True) process_owner = UserFactory.create( role__type=RoleTypeChoices.process_owner) archivist = UserFactory.create(role__type=RoleTypeChoices.archivist) report = DestructionReportFactory.create(process_owner=process_owner) self.client.force_login(archivist) response_pdf = self.client.get(reverse("report:download-report", args=[report.pk]), data={"type": "pdf"}) response_csv = self.client.get(reverse("report:download-report", args=[report.pk]), data={"type": "csv"}) self.assertEqual(403, response_pdf.status_code) self.assertEqual(403, response_csv.status_code)
def test_can_access_with_can_start_destruction_and_zaak_url( self, m_fetch_zaak): user = UserFactory(role__can_start_destruction=True) self.client.force_login(user) form_url = furl(reverse("destruction:update-zaak-archive-details")) form_url.args.set("url", "http://openzaak.nl/some/zaak") response = self.client.get(form_url.url) self.assertEqual(200, response.status_code)
def test_can_access_with_can_start_destruction(self, m_choices): user = UserFactory(role__can_start_destruction=True) self.client.force_login(user) response = self.client.get( reverse("destruction:zaken-without-archive-date")) self.assertEqual(200, response.status_code) self.assertIn("zaaktypen", response.context_data) self.assertEqual("http://test.zaaktype.nl", response.context_data["zaaktypen"][0]["url"])
def test_complete_and_notify_process_owner(self, m): process_owner = UserFactory.create( role__type=RoleTypeChoices.process_owner, role__can_review_destruction=True, role__can_view_case_details=True, ) destruction_list = DestructionListFactory.create(name="Summer List", ) DestructionListReviewFactory.create( author=process_owner, status=ReviewStatus.approved, destruction_list=destruction_list, ) destruction_list.process() destruction_list.save() complete_and_notify(destruction_list.id) notifications = Notification.objects.all() self.assertEqual(2, notifications.count()) notification = notifications.get(user=process_owner) self.assertEqual(notification.destruction_list, destruction_list) report = DestructionReport.objects.get() self.assertEqual( notification.message, _("Destruction list %(list)s has been processed. " "You can download the report of destruction here: %(url)s") % { "list": "Summer List", "url": "http://example.com{}".format( reverse("report:download-report", args=[report.pk])), }, ) self.client.force_login(process_owner) response_pdf = self.client.get(reverse("report:download-report", args=[report.pk]), data={"type": "pdf"}) response_csv = self.client.get(reverse("report:download-report", args=[report.pk]), data={"type": "csv"}) self.assertEqual(200, response_pdf.status_code) self.assertGreater(len(response_pdf.content), 0) self.assertEqual(200, response_csv.status_code) self.assertGreater(len(response_csv.content), 0)
def test_state_after_rejection(self): record_manager = UserFactory( role__can_start_destruction=True, role__type=RoleTypeChoices.record_manager ) archivist = UserFactory( role__can_review_destruction=True, role__type=RoleTypeChoices.archivist ) destruction_list = DestructionListFactory.create(author=record_manager) DestructionListReviewFactory.create( author=archivist, status=ReviewStatus.rejected, destruction_list=destruction_list, ) destruction_list.assignee = record_manager destruction_list.save() list_state = destruction_list.list_state() self.assertEqual("rejected", list_state.value)
def test_state_after_last_review(self): record_manager = UserFactory( role__can_start_destruction=True, role__type=RoleTypeChoices.record_manager ) destruction_list = DestructionListFactory.create(author=record_manager) destruction_list.assignee = None destruction_list.save() list_state = destruction_list.list_state() self.assertEqual("approved", list_state.value)
def test_state_after_creation(self): record_manager = UserFactory( role__can_start_destruction=True, role__type=RoleTypeChoices.record_manager ) process_owner = UserFactory( role__can_review_destruction=True, role__type=RoleTypeChoices.process_owner ) destruction_list = DestructionListFactory.create(author=record_manager) assignee = DestructionListAssigneeFactory.create( assignee=process_owner, destruction_list=destruction_list, order=1 ) destruction_list.assignee = assignee.assignee destruction_list.save() list_state = destruction_list.list_state() self.assertEqual("in_progress", list_state.value) self.assertEqual(1, destruction_list.total_reviewers()) self.assertEqual(0, destruction_list.completed_reviewers())
def setUpTestData(cls): record_manager = RoleFactory.create(record_manager=True) process_owner = RoleFactory.create(process_owner=True) archivaris = RoleFactory.create(archivaris=True) user1 = UserFactory.create(role=record_manager) user2 = UserFactory.create(role=process_owner) user3 = UserFactory.create(role=archivaris) destruction_list = DestructionListFactory.create(author=user1) DestructionListAssigneeFactory.create( destruction_list=destruction_list, assignee=user2 ) DestructionListAssigneeFactory.create( destruction_list=destruction_list, assignee=user3 ) cls.destruction_list = destruction_list cls.user1 = user1 cls.user2 = user2 cls.user3 = user3