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()
Пример #2
0
    def test_state_after_changes_requested(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)
        archivist = UserFactory(role__can_review_destruction=True,
                                role__type=RoleTypeChoices.archivist)

        destruction_list = DestructionListFactory.create(author=record_manager)

        DestructionListAssigneeFactory.create(
            assignee=process_owner, destruction_list=destruction_list, order=1)
        DestructionListAssigneeFactory.create(
            assignee=archivist, destruction_list=destruction_list, order=2)

        DestructionListReviewFactory.create(
            author=process_owner,
            status=ReviewStatus.changes_requested,
            destruction_list=destruction_list,
        )

        destruction_list.assignee = record_manager
        destruction_list.save()

        list_state = destruction_list.list_state()

        self.assertEqual("changes_requested", list_state.value)
        self.assertEqual(2, destruction_list.total_reviewers())
        self.assertEqual(0, destruction_list.completed_reviewers())
    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)
Пример #4
0
    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
Пример #5
0
    def test_user_unauthenticated_cant_access(self, m):
        destruction_list = DestructionListFactory.create()
        url = reverse("destruction:fetch-list-items", args=[destruction_list.id])

        response = self.client.get(url)

        self.assertEqual(302, response.status_code)
        self.assertEqual(f"/admin/login/?next={url}", response.url)
Пример #6
0
    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_relation_between_report_and_destructionlist(
            self, m_vcs, m_zaaktype):
        destruction_list = DestructionListFactory.create(name="Winter cases")
        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": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        DestructionListItemFactory.create(
            destruction_list=destruction_list,
            status=ListItemStatus.destroyed,
            extra_zaak_data={
                "identificatie": "ZAAK-2",
                "omschrijving": "Een andere zaak",
                "toelichting": "Boh",
                "startdatum": "2020-02-01",
                "einddatum": "2021-03-01",
                "zaaktype": "https://oz.nl/catalogi/api/v1/zaaktypen/uuid-2",
                "verantwoordelijke_organisatie": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        DestructionListReviewFactory.create(
            destruction_list=destruction_list,
            status=ReviewStatus.approved,
            text="What a magnificent list!",
        )

        report = create_destruction_report(destruction_list)

        # can't use refresh_from_db() because of django-fsm
        destruction_list = DestructionList.objects.get(id=destruction_list.id)

        self.assertEqual(1, destruction_list.destructionreport_set.count())
        self.assertEqual(report, destruction_list.destructionreport_set.get())
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    def test_failed_destruction_not_in_report_content(self, m_vcs, m_zaaktype):
        destruction_list = DestructionListFactory.create(
            status=ListStatus.processing,
            contains_sensitive_info=False,
        )
        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",
                "verantwoordelijke_organisatie": "Nicer organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nicer result type",
                        "archiefactietermijn": "40 days",
                    }
                },
                "relevante_andere_zaken": [{
                    "url": "http://some.zaak"
                }],
            },
        )
        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",
                "verantwoordelijke_organisatie": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )

        report_data = get_destruction_report_data(destruction_list)

        self.assertEqual(1, len(report_data))

        self.assertEqual("ZAAK-2", report_data[0]["identificatie"])
    def test_email_body_and_subject(self):
        destruction_list = DestructionListFactory.create()
        email = AutomaticEmailFactory(body="This is a test text",
                                      subject="This is a test subject")
        email.send(recipient=self.user, destruction_list=destruction_list)

        self.assertEqual(1, len(mail.outbox))

        sent_mail = mail.outbox[0]

        self.assertEqual("*****@*****.**", sent_mail.to[0])
        self.assertEqual("This is a test text", sent_mail.body)
        self.assertEqual("This is a test subject", sent_mail.subject)
Пример #12
0
    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"]
        )
Пример #13
0
    def test_destruction_report_content_generation_without_toelichting(
            self, m_vcs, m_zaaktype):
        destruction_list = DestructionListFactory.create(
            contains_sensitive_info=False)
        DestructionListItemFactory.create(
            destruction_list=destruction_list,
            status=ListItemStatus.destroyed,
            extra_zaak_data={
                "identificatie": "ZAAK-1",
                "omschrijving": "Een zaak",
                "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"
                }],
            },
        )

        report_data = get_destruction_report_data(destruction_list)

        self.assertEqual(1, len(report_data))

        # Test sensitive info
        self.assertIn("omschrijving", report_data[0])
        self.assertIn("opmerkingen", report_data[0])

        # Test remaining info
        self.assertEqual("ZAAK-1", report_data[0]["identificatie"])
        self.assertEqual("Een zaak", report_data[0]["omschrijving"])
        self.assertEqual("366 days", report_data[0]["looptijd"])
        self.assertEqual("1", report_data[0]["vernietigings_categorie"])
        self.assertNotIn("toelichting", report_data[0])
        self.assertEqual("", report_data[0]["opmerkingen"])
        self.assertEqual("", report_data[0]["reactie_zorgdrager"])
        self.assertEqual("This is a zaaktype", report_data[0]["zaaktype"])
        self.assertEqual("40 days", report_data[0]["archiefactietermijn"])
        self.assertEqual("Nicer result type", report_data[0]["resultaattype"])
        self.assertEqual("Nicer organisation",
                         report_data[0]["verantwoordelijke_organisatie"])
        self.assertEqual("Yes", report_data[0]["relaties"])
Пример #14
0
    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"])
Пример #15
0
    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)
Пример #16
0
    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_report_creation_without_process_owner(self, m_vcs, m_zaaktype):
        destruction_list = DestructionListFactory.create(name="Winter cases")
        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": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        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",
                "verantwoordelijke_organisatie": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )

        report = create_destruction_report(destruction_list)

        self.assertEqual(None, report.process_owner)
Пример #18
0
    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)
Пример #19
0
    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())
Пример #20
0
    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)
Пример #21
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)
Пример #22
0
    def test_state_after_destruction(self):
        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.complete()
        destruction_list.save()

        list_state = destruction_list.list_state()

        self.assertEqual("finished", list_state.value)
    def test_private_media_is_not_accessible(self, m_vcs, m_zaaktype):
        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(name="Winter cases")
        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": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        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",
                "verantwoordelijke_organisatie": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        DestructionListReviewFactory.create(
            destruction_list=destruction_list,
            status=ReviewStatus.approved,
            author=process_owner,
            text="What a magnificent list!",
        )

        report = create_destruction_report(destruction_list)

        response_csv = self.client.get(report.content_csv.url)

        self.assertEqual(404, response_csv.status_code)

        response_pdf = self.client.get(report.content_pdf.url)

        self.assertEqual(404, response_pdf.status_code)
Пример #24
0
    def test_logs_contain_comments(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_1 = DestructionListReviewFactory.create(
            destruction_list=destruction_list,
            author=archivaris,
            text="This is a comment for the author.",
        )
        author_comment = DestructionListReviewComment.objects.create(
            text="This is a comment for the reviewer.", review=review_1)

        review_2 = DestructionListReviewFactory.create(
            destruction_list=destruction_list, author=archivaris, text="")

        TimelineLog.objects.create(
            content_object=destruction_list,
            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,
            extra_data={
                "n_items": 1,
                "text": review_1.text
            },
        )
        TimelineLog.objects.create(
            content_object=destruction_list,
            template="destruction/logs/updated.html",
            user=record_manager,
            extra_data={
                "n_items": 1,
                "text": author_comment.text
            },
        )
        TimelineLog.objects.create(
            content_object=review_2,
            template="destruction/logs/review_created.html",
            user=archivaris,
            extra_data={
                "n_items": 1,
                "text": review_2.text
            },
        )

        report = create_audittrail_report(destruction_list)
        html_report = document_fromstring(report)

        self.assertEqual(4, len(html_report.find_class("log-item")))

        # The second review should not have this tag, because the review text was empty
        self.assertEqual(1,
                         len(html_report.find_class("log-item__review-text")))
        self.assertIn("This is a comment for the author.", report)
        self.assertEqual(
            1, len(html_report.find_class("log-item__author-comment")))
        self.assertIn("This is a comment for the reviewer.", report)
    def test_create_html_content_without_sensitive_info(
            self, m_vcs, m_zaaktype):
        destruction_list = DestructionListFactory.create(
            name="Winter cases",
            contains_sensitive_info=False,
        )
        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!",
        )

        zaken_data = get_destruction_report_data(destruction_list)
        html_content = create_html_report_content(
            zaken_data, destruction_list.contains_sensitive_info)

        expected_html_nodes = [
            "<th>Unique ID</th>",
            "<th>Description</th>",
            "<th>Duration</th>",
            "<th>Destruction category Selectielijst</th>",
            "<th>Explanation</th>",
            "<th>Reaction caretaker</th>",
            "<th>Remarks SAD</th>",
            "<th>Case type</th>",
            "<th>Archive action period</th>",
            "<th>Result type</th>",
            "<th>Organisation responsible</th>",
            "<th>Relations</th>",
            "<td>Een zaak</td>",
            "<td>ZAAK-1</td>",
            "<td>What a magnificent list!</td>",
            "<td>366 days</td>",
            "<td>1</td>",
            "<td>Bah</td>",
            "<td></td>",
            "<td>This is a zaaktype</td>",
            "<td>40 days</td>",
            "<td>Nicer result type</td>",
            "<td>Nicer organisation</td>",
            "<td>Yes</td>",
        ]

        for node in expected_html_nodes:
            self.assertIn(node, html_content)
    def test_create_csv_content_without_sensitive_info(self, m_vcs,
                                                       m_zaaktype):
        destruction_list = DestructionListFactory.create(
            name="Winter cases",
            contains_sensitive_info=False,
        )
        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!",
        )

        zaken_data = get_destruction_report_data(destruction_list)
        html_content = create_csv_report_content(
            zaken_data, destruction_list.contains_sensitive_info)

        html_content.seek(0)

        lines = [line for line in html_content.readlines()]

        expected_header_row = [
            "Unique ID",
            "Description",
            "Duration",
            "Destruction category Selectielijst",
            "Explanation",
            "Remarks SAD",
            "Reaction caretaker",
            "Case type",
            "Archive action period",
            "Result type",
            "Organisation responsible",
            "Relations",
        ]
        expected_zaak_row = [
            "ZAAK-1",
            "Een zaak",
            "366 days",
            "1",
            "Bah",
            "What a magnificent list!",
            "",
            "This is a zaaktype",
            "40 days",
            "Nicer result type",
            "Nicer organisation",
            "Yes",
        ]

        self.assertEqual(2, len(lines))
        for header in expected_header_row:
            self.assertIn(header, lines[0])

        for zaak in expected_zaak_row:
            self.assertIn(zaak, lines[1])
    def test_invalid_report_type(self, m_vcs, m_zaaktype):
        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(
            name="Winter cases", contains_sensitive_info=False)
        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": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        DestructionListItemFactory.create(
            destruction_list=destruction_list,
            status=ListItemStatus.destroyed,
            extra_zaak_data={
                "identificatie": "ZAAK-2",
                "omschrijving": "Een andere zaak",
                "toelichting": "Boh",
                "startdatum": "2020-02-01",
                "einddatum": "2021-03-01",
                "zaaktype": "https://oz.nl/catalogi/api/v1/zaaktypen/uuid-2",
                "verantwoordelijke_organisatie": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        DestructionListReviewFactory.create(
            destruction_list=destruction_list,
            status=ReviewStatus.approved,
            author=process_owner,
            text="What a magnificent list!",
        )

        report = create_destruction_report(destruction_list)

        self.assertEqual(process_owner, report.process_owner)
        self.assertEqual(
            "Declaration of destruction - Winter cases (2021-05-05)",
            report.title)

        self.client.force_login(process_owner)
        response = self.client.get(reverse("report:download-report",
                                           args=[report.pk]),
                                   data={"type": "GNE"})

        self.assertEqual(400, response.status_code)
Пример #28
0
    def test_destruction_report_data_without_sensitive_info(
            self, m_vcs, m_zaaktype):
        destruction_list = DestructionListFactory.create(
            name="Winter cases",
            contains_sensitive_info=False,
        )
        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"
                }],
            },
        )
        DestructionListItemFactory.create(
            destruction_list=destruction_list,
            status=ListItemStatus.destroyed,
            extra_zaak_data={
                "identificatie": "ZAAK-2",
                "omschrijving": "Een andere zaak",
                "toelichting": "Boh",
                "startdatum": "2020-02-01",
                "einddatum": "2021-03-01",
                "zaaktype": "https://oz.nl/catalogi/api/v1/zaaktypen/uuid-2",
                "verantwoordelijke_organisatie": "Nice organisation",
                "resultaat": {
                    "resultaattype": {
                        "omschrijving": "Nice result type",
                        "archiefactietermijn": "20 days",
                    }
                },
                "relevante_andere_zaken": [],
            },
        )
        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(2, len(report_data))

        # Test sensitive info
        self.assertIn("omschrijving", report_data[0])
        self.assertIn("opmerkingen", report_data[0])
        self.assertIn("omschrijving", report_data[1])
        self.assertIn("opmerkingen", report_data[1])

        # Test remaining info
        self.assertEqual("ZAAK-1", report_data[0]["identificatie"])
        self.assertEqual("Een zaak", report_data[0]["omschrijving"])
        self.assertEqual("366 days", report_data[0]["looptijd"])
        self.assertEqual("1", report_data[0]["vernietigings_categorie"])
        self.assertEqual("Bah", report_data[0]["toelichting"])
        self.assertEqual("What a magnificent list!",
                         report_data[0]["opmerkingen"])
        self.assertEqual("", report_data[0]["reactie_zorgdrager"])
        self.assertEqual("This is a zaaktype", report_data[0]["zaaktype"])
        self.assertEqual("40 days", report_data[0]["archiefactietermijn"])
        self.assertEqual("Nicer result type", report_data[0]["resultaattype"])
        self.assertEqual("Nicer organisation",
                         report_data[0]["verantwoordelijke_organisatie"])
        self.assertEqual("Yes", report_data[0]["relaties"])

        # Test remaining info
        self.assertEqual("ZAAK-2", report_data[1]["identificatie"])
        self.assertEqual("Een andere zaak", report_data[1]["omschrijving"])
        self.assertEqual("394 days", report_data[1]["looptijd"])
        self.assertEqual("1", report_data[1]["vernietigings_categorie"])
        self.assertEqual("Boh", report_data[1]["toelichting"])
        self.assertEqual("What a magnificent list!",
                         report_data[1]["opmerkingen"])
        self.assertEqual("", report_data[1]["reactie_zorgdrager"])
        self.assertEqual("This is a zaaktype", report_data[1]["zaaktype"])
        self.assertEqual("20 days", report_data[1]["archiefactietermijn"])
        self.assertEqual("Nice result type", report_data[1]["resultaattype"])
        self.assertEqual("Nice organisation",
                         report_data[1]["verantwoordelijke_organisatie"])
        self.assertEqual("No", report_data[1]["relaties"])