def test_create_new_user_creates_email_preferences(self): self.assertFalse(EmailPreference.objects.all().exists()) # Signals take care of creating the Email preferences UserFactory.create() self.assertTrue(EmailPreference.objects.all().exists())
def test_archivist_cannot_download(self): archivist = UserFactory.create(role__can_review_destruction=True, role__type=RoleTypeChoices.archivist) process_owner = UserFactory.create( role__can_review_destruction=True, role__type=RoleTypeChoices.functional_admin, ) list_reviewed = DestructionListFactory.create( name="list reviewed", status=ListItemStatus.destroyed) DestructionListReviewFactory.create(destruction_list=list_reviewed, author=archivist) DestructionReportFactory.create(destruction_list=list_reviewed, process_owner=process_owner) self.app.set_user(archivist) response = self.app.get(self.url, {"reviewed": ReviewerDisplay.reviewed}) self.assertEqual(response.status_code, 200) destruction_lists = response.html.find_all( class_="destruction-list-preview") self.assertEqual(len(destruction_lists), 1) self.assertNotIn("Download verklaring van vernietiging", response.html.text)
def test_only_assigned_process_owner_can_access(self): process_owner_assigned = UserFactory.create( role__type=RoleTypeChoices.process_owner ) another_process_owner = UserFactory.create( role__type=RoleTypeChoices.process_owner ) report = DestructionReportFactory.create(process_owner=process_owner_assigned) self.client.force_login(process_owner_assigned) 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) self.client.force_login(another_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(403, response_pdf.status_code) self.assertEqual(403, response_csv.status_code)
def setUpTestData(cls): AutomaticEmailFactory.create( type=EmailTypeChoices.review_required, body="Review is required!", subject="Review", ) AutomaticEmailFactory.create( type=EmailTypeChoices.changes_required, body="Changes are required!", subject="Changes", ) record_manager = RoleFactory.create(record_manager=True) process_owner = RoleFactory.create(process_owner=True) user_author = UserFactory.create(role=record_manager, email="*****@*****.**") user_reviewer = UserFactory.create(role=process_owner, email="*****@*****.**") destruction_list = DestructionListFactory.create(author=user_author) DestructionListAssigneeFactory.create( destruction_list=destruction_list, assignee=user_reviewer) cls.destruction_list = destruction_list cls.user_author = user_author cls.user_reviewer = user_reviewer
def test_reviewer_landing_page(self): url = reverse("destruction:reviewer-list") reviewer = UserFactory.create(role__can_review_destruction=True) other_user = UserFactory.create(role__can_review_destruction=False) self.assertLoginRequired(url) self.assertHasPermission(url, reviewer) self.assertHasNoPermission(url, other_user)
def test_wrong_user_cant_access(self): user_1 = UserFactory.create() user_2 = UserFactory.create() self.client.force_login(user_1) response = self.client.get( reverse("emails:email-preference-update", args=[user_2.emailpreference.pk])) self.assertEqual(403, response.status_code)
def test_only_comments_from_archivaris_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_destruction_list_archivaris_comments(destruction_list) self.assertEqual("What a magnificent 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_archivarist_cant_access(self): 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_send_email_with_variables(self): recipient = UserFactory.create(first_name="John", last_name="Doe") config = EmailConfig.objects.create() config.municipality = "Gemeente X" config.save() destruction_list = DestructionListFactory.create( name="Interesting List") email = AutomaticEmailFactory( body="This is a test email for {{ user }} " "from municipality {{ municipality }} about " "the list {{ list }} ({{ link_list }})", subject="This is a test subject", ) email.send(recipient=recipient, destruction_list=destruction_list) self.assertEqual(1, len(mail.outbox)) sent_mail = mail.outbox[0] list_url = get_absolute_url( reverse("destruction:dl-redirect", args=[destruction_list.pk])) expected_body = ( f"This is a test email for John Doe from municipality Gemeente X about the " f"list Interesting List ({list_url})") self.assertEqual(expected_body, sent_mail.body) self.assertEqual("This is a test subject", sent_mail.subject)
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_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_no_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=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=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"])) # Since the list does NOT contain sensitive data, the process owner 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_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_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=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=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"])) # The list contains sensitive data, the archivist should NOT be able to see it zaak_1_data = response_data["items"][0]["zaak"] self.assertNotIn("omschrijving", zaak_1_data) zaak_2_data = response_data["items"][1]["zaak"] self.assertNotIn("omschrijving", zaak_2_data)
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_functional_admin_can_access(self): process_owner = UserFactory.create(role__type=RoleTypeChoices.process_owner) functional_admin = UserFactory.create( role__type=RoleTypeChoices.functional_admin ) report = DestructionReportFactory.create(process_owner=process_owner) self.client.force_login(functional_admin) 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 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
def setUpTestData(cls): cls.user = UserFactory.create(role__can_review_destruction=True) cls.list_to_review = DestructionListFactory.create( assignee=cls.user, name="list to review") DestructionListReviewFactory.create( destruction_list=cls.list_to_review, author=cls.user) cls.list_reviewed = DestructionListFactory.create(name="list reviewed") DestructionListReviewFactory.create(destruction_list=cls.list_reviewed, author=cls.user) cls.list_extra = DestructionListFactory.create(author=cls.user, name="list extra")
def test_zaakafhandelcomponent_link(self, m): self._set_up_services() config = ArchiveConfig.get_solo() config.link_to_zac = ( "http://example.nl/{{ bronorganisatie }}/{{ identificatie }}/{{ uuid }}" ) config.save() user = UserFactory.create( username="******", password="******", email="*****@*****.**", role__can_start_destruction=True, role__can_review_destruction=True, ) destruction_list = DestructionListFactory.create(author=user, assignee=user) DestructionListItemFactory.create( destruction_list=destruction_list, zaak=ZAAK_1["url"] ) DestructionListItemFactory.create( destruction_list=destruction_list, zaak=ZAAK_2["url"] ) self._set_up_mocks(m) 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) response_data = response.json() self.assertIn("items", response_data) self.assertEqual(2, len(response_data["items"])) zaak_1_data = response_data["items"][0]["zaak"] self.assertIn("zac_link", zaak_1_data) self.assertEqual( "http://example.nl/123456789/ZAAK-001/uuid-1", zaak_1_data["zac_link"] ) zaak_2_data = response_data["items"][1]["zaak"] self.assertIn("zac_link", zaak_2_data) self.assertEqual( "http://example.nl/987654321/ZAAK-002/uuid-2", zaak_2_data["zac_link"] )
def test_returns_list_items_and_zaak_data(self, m): self._set_up_services() user = UserFactory.create( username="******", password="******", email="*****@*****.**", role__can_start_destruction=True, role__can_review_destruction=True, ) destruction_list = DestructionListFactory.create(author=user, assignee=user) DestructionListItemFactory.create( destruction_list=destruction_list, zaak=ZAAK_1["url"] ) DestructionListItemFactory.create( destruction_list=destruction_list, zaak=ZAAK_2["url"] ) self._set_up_mocks(m) 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) response_data = response.json() self.assertIn("items", response_data) self.assertEqual(2, len(response_data["items"])) # Test first item (No related zaken, no process type) zaak_1_data = response_data["items"][0]["zaak"] self.assertEqual(f"{ZAKEN_ROOT}zaken/uuid-1", zaak_1_data["url"]) self.assertEqual([], zaak_1_data["relevanteAndereZaken"]) self.assertNotIn("processtype", zaak_1_data["zaaktype"]) self.assertEqual("10 days", zaak_1_data["looptijd"]) # Test second item (related zaken and process type) zaak_2_data = response_data["items"][1]["zaak"] self.assertEqual(f"{ZAKEN_ROOT}zaken/uuid-2", zaak_2_data["url"]) self.assertEqual( zaak_2_data["relevanteAndereZaken"], [{"url": f"{ZAKEN_ROOT}zaken/uuid-3", "aardRelatie": "vervolg"}], ) self.assertIn("processtype", zaak_2_data["zaaktype"])
def test_destruction_report_data_with_sensitive_info(self): destruction_list = DestructionListFactory.create( name="Winter cases", contains_sensitive_info=True, ) DestructionListItemFactory.create( destruction_list=destruction_list, status=ListItemStatus.destroyed, 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", "verantwoordelijke_organisatie": "Nicer organisation", "resultaat": { "resultaattype": { "omschrijving": "Nicer result type", "archiefactietermijn": "40 days", } }, "relevante_andere_zaken": [{ "url": "http://some.zaak" }], }, ) archivaris = UserFactory.create( role__type=RoleTypeChoices.archivist, role__can_start_destruction=False, role__can_review_destruction=True, role__can_view_case_details=False, ) DestructionListReviewFactory.create( destruction_list=destruction_list, status=ReviewStatus.approved, author=archivaris, text="What a magnificent list!", ) report_data = get_destruction_report_data(destruction_list) self.assertEqual(1, len(report_data)) zaak_data = report_data[0] self.assertNotIn("omschrijving", zaak_data) self.assertNotIn("opmerkingen", zaak_data)
def test_no_sensitive_info_archivist(self): destruction_list = DestructionListFactory.create(contains_sensitive_info=False) archivist = UserFactory.create( role__can_review_destruction=True, role__type=RoleTypeChoices.archivist, ) DestructionListAssigneeFactory.create( destruction_list=destruction_list, assignee=archivist ) url = reverse("destruction:reviewer-create", args=[destruction_list.id]) self.client.force_login(archivist) response = self.client.get(url) # Archivist can see everything since it's not sensitive self.assertTrue(response.context["show_optional_columns"])
def test_sensitive_info_process_owner(self): destruction_list = DestructionListFactory.create(contains_sensitive_info=True) process_owner = UserFactory.create( role__can_review_destruction=True, role__type=RoleTypeChoices.process_owner, ) DestructionListAssigneeFactory.create( destruction_list=destruction_list, assignee=process_owner ) url = reverse("destruction:reviewer-create", args=[destruction_list.id]) self.client.force_login(process_owner) response = self.client.get(url) # Process owner can see sensitive info self.assertTrue(response.context["show_optional_columns"])
def test_no_variables(self): 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" form["subject"] = "Test subject" response = form.submit().follow() self.assertEqual(200, response.status_code) self.assertEqual(1, AutomaticEmail.objects.count())
def test_unknown_variable(self): 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 an unknown variable {{ unknown }}" form["subject"] = "Test subject" response = form.submit() self.assertIn("Unknown variable used in the email body.", response.text) self.assertEqual(0, AutomaticEmail.objects.count())
def test_superuser_without_role_can_download(self): superuser = UserFactory.create(is_staff=True, is_superuser=True) superuser.role = None superuser.save() report = DestructionReportFactory.create() url = reverse("admin:report_destructionreport_change", args=[report.pk]) response = self.app.get(url, user=superuser) self.assertEqual(200, response.status_code) url = reverse("report:download-report", args=[report.pk]) response = self.app.get(f"{url}?type=pdf", user=superuser) self.assertEqual(200, response.status_code) self.assertGreater(len(response.content), 0)