Beispiel #1
0
 def setUp(self):
     super().setUp()
     self.agency_ein_860 = "0860"
     uf = UserFactory()
     self.agency_user_860 = uf.create_agency_user(agency_ein=self.agency_ein_860)
     self.admin_860 = uf.create_agency_admin(agency_ein=self.agency_ein_860)
     self.rf = RequestFactory
     self.rf_agency_860 = RequestFactory(agency_ein=self.agency_ein_860)
     self.request = self.rf_agency_860.create_request_as_public_user()
Beispiel #2
0
 def setUp(self):
     super().setUp()
     self.agency_ein_860 = "0860"
     uf = UserFactory()
     self.admin_860 = uf.create_agency_admin(agency_ein=self.agency_ein_860)
     self.rf = RequestFactory()
     self.rf_agency_860 = RequestFactory(agency_ein=self.agency_ein_860)
     self.request = self.rf_agency_860.create_request_as_public_user()
     self.email_content = 'test email body'
     self.closing_reasons = [choice([r.id for r in Reasons.query.filter_by(type=determination_type.CLOSING).all()])]
     self.denial_reasons = [choice([r.id for r in Reasons.query.filter_by(type=determination_type.DENIAL).all()])]
Beispiel #3
0
 def setUp(self):
     super().setUp()
     self.agency_ein_860 = "0860"
     self.parent_ein_860 = "860"
     self.agency_ein_002 = "0002"
     uf = UserFactory()
     self.user_860 = uf.create_agency_user(self.agency_ein_860)
     self.admin_860 = uf.create_agency_admin(self.agency_ein_860)
     self.rf = RequestFactory()
     self.rf_agency_860 = RequestFactory(agency_ein=self.agency_ein_860)
     self.rf_agency_002 = RequestFactory(agency_ein=self.agency_ein_002)
     self.tz_name = current_app.config["APP_TIMEZONE"]
Beispiel #4
0
class ResponseUtilsTests(BaseTestCase, TestHelpers):
    def setUp(self):
        super().setUp()
        self.agency_ein_860 = "0860"
        uf = UserFactory()
        self.admin_860 = uf.create_agency_admin(agency_ein=self.agency_ein_860)
        self.rf = RequestFactory()
        self.rf_agency_860 = RequestFactory(agency_ein=self.agency_ein_860)
        self.request = self.rf_agency_860.create_request_as_public_user()
        self.email_content = 'test email body'
        self.closing_reasons = [choice([r.id for r in Reasons.query.filter_by(type=determination_type.CLOSING).all()])]
        self.denial_reasons = [choice([r.id for r in Reasons.query.filter_by(type=determination_type.DENIAL).all()])]

    @patch('app.response.utils._send_response_email')
    def test_add_denial(self, send_response_email_patch):
        with flask_login_user(self.admin_860):
            add_denial(self.request.id, self.denial_reasons, self.email_content)
            send_response_email_patch.assert_called_once_with(
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                self.email_content,
                'Request {} Closed'.format(self.request.id)
            )
        response = self.request.responses.join(Determinations).filter(
            Determinations.dtype == determination_type.DENIAL).one()
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                response.reason
            ],
            [
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.DENIAL,
                format_determination_reasons(self.denial_reasons)
            ]
        )
        self.assert_response_event(self.request.id, event_type.REQ_CLOSED, response, self.admin_860)

    def test_add_denial_invalid_request(self):
        with flask_login_user(self.admin_860):
            with self.assertRaises(NoResultFound):
                add_denial('FOIL-2017-002-00001', self.denial_reasons, self.email_content)

    def test_add_denial_already_closed(self):
        with flask_login_user(self.admin_860):
            self.request.close()
            with self.assertRaises(UserRequestException):
                add_denial(self.request.id, self.denial_reasons, self.email_content)

    @patch('app.response.utils._send_response_email')
    def test_add_closing(self, send_response_email_patch):
        with flask_login_user(self.admin_860):
            self.request.acknowledge(days=30)
            self.request.set_agency_request_summary('blah')
            self.request.set_agency_request_summary_privacy(False)
            add_closing(self.request.id, self.closing_reasons, self.email_content)
            send_response_email_patch.assert_called_once_with(
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                self.email_content,
                'Request {} Closed'.format(self.request.id)
            )
        response = self.request.responses.join(Determinations).filter(
            Determinations.dtype == determination_type.CLOSING).one()
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                response.reason
            ],
            [
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.CLOSING,
                format_determination_reasons(self.closing_reasons)
            ]
        )
        self.assert_response_event(self.request.id, event_type.REQ_CLOSED, response, self.admin_860)

    def test_add_closing_invalid_request(self):
        with flask_login_user(self.admin_860):
            with self.assertRaises(NoResultFound):
                add_closing('FOIL-2017-002-00001', self.closing_reasons, self.email_content)

    def test_add_closing_not_acknowledged(self):
        with flask_login_user(self.admin_860):
            self.request.close()
            with self.assertRaises(UserRequestException):
                add_closing(self.request.id, self.closing_reasons, self.email_content)

    def test_add_closing_already_closed(self):
        with flask_login_user(self.admin_860):
            self.request.close()
            with self.assertRaises(UserRequestException):
                add_closing(self.request.id, self.closing_reasons, self.email_content)

    def test_add_closing_no_agency_request_summary(self):
        with flask_login_user(self.admin_860):
            self.request.acknowledge(days=30)
            with self.assertRaises(UserRequestException):
                add_closing(self.request.id, self.closing_reasons, self.email_content)

    def test_add_closing_file_private(self):
        with flask_login_user(self.admin_860):
            self.request.acknowledge(days=30)
            self.request.add_file()
            with self.assertRaises(UserRequestException):
                add_closing(self.request.id, self.closing_reasons, self.email_content)

    @patch('app.response.utils._send_response_email')
    def test_add_closing_file_release_public(self, send_response_email_patch):
        request_title_public = self.rf_agency_860.create_request_as_public_user(title_privacy=False)
        with flask_login_user(self.admin_860):
            request_title_public.acknowledge(days=30)
            request_title_public.add_file(privacy=response_privacy.RELEASE_AND_PUBLIC)
            add_closing(request_title_public.id, self.closing_reasons, self.email_content)
            send_response_email_patch.assert_called_once_with(
                request_title_public.id,
                response_privacy.RELEASE_AND_PUBLIC,
                self.email_content,
                'Request {} Closed'.format(request_title_public.id)
            )
        response = request_title_public.responses.join(Determinations).filter(
            Determinations.dtype == determination_type.CLOSING).one()
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                response.reason
            ],
            [
                request_title_public.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.CLOSING,
                format_determination_reasons(self.closing_reasons)
            ]
        )
        self.assert_response_event(request_title_public.id, event_type.REQ_CLOSED, response, self.admin_860)

    @patch('app.response.utils._send_response_email')
    def test_add_closing_not_fulfilled_reasons(self, send_response_email_patch):
        not_fulfilled_reasons = ['7', '8', '9']
        with flask_login_user(self.admin_860):
            self.request.acknowledge(days=30)
            self.request.set_agency_request_summary('blah')
            self.request.set_agency_request_summary_privacy(False)
            add_closing(self.request.id, not_fulfilled_reasons, self.email_content)
            send_response_email_patch.assert_called_once_with(
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                self.email_content,
                'Request {} Closed'.format(self.request.id)
            )
        response = self.request.responses.join(Determinations).filter(
            Determinations.dtype == determination_type.CLOSING).one()
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                response.reason
            ],
            [
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.CLOSING,
                format_determination_reasons(not_fulfilled_reasons)
            ]
        )
        self.assert_response_event(self.request.id, event_type.REQ_CLOSED, response, self.admin_860)
Beispiel #5
0
 def setUp(self):
     super().setUp()
     self.rf = RequestFactory()
     self.uf = UserFactory()
     self.request = self.rf.create_request_as_anonymous_user()
     self.tz_name = current_app.config["APP_TIMEZONE"]
Beispiel #6
0
class RequestWrapperTests(BaseTestCase, TestHelpers):

    def setUp(self):
        super().setUp()
        self.rf = RequestFactory()
        self.uf = UserFactory()
        self.request = self.rf.create_request_as_anonymous_user()
        self.tz_name = current_app.config["APP_TIMEZONE"]

    def test_set_title(self):
        title = "The Time Has Come"
        self.request.set_title(title)
        request = Requests.query.get(self.request.id)
        self.assertEqual(request.title, title)

    def test_set_agency_request_summary(self):
        agency_request_summary = "To talk of many things."
        self.request.set_agency_request_summary(agency_request_summary)
        request = Requests.query.get(self.request.id)
        self.assertEqual(request.agency_request_summary, agency_request_summary)

    def test_set_title_privacy(self):
        privacy = not self.request.privacy["title"]
        self.request.set_title_privacy(privacy)
        request = Requests.query.get(self.request.id)
        self.assertEqual(request.privacy["title"], privacy)

    def test_set_agency_request_summary_privacy(self):
        privacy = not self.request.privacy["agency_request_summary"]
        self.request.set_agency_request_summary_privacy(privacy)
        request = Requests.query.get(self.request.id)
        self.assertEqual(request.privacy["agency_request_summary"], privacy)

    def test_add_file_default(self):
        response = self.request.add_file()
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.mime_type,
                type(response.title),
                type(response.name),
                type(response.size),
                type(response.hash)
            ],
            [
                self.request.id,
                response_privacy.PRIVATE,
                'text/plain',
                str,  # title
                str,  # filename
                int,  # size
                str,  # hash
            ]
        )
        self.assertTrue(response.size > 0)
        self.assertTrue(
            os.path.exists(
                os.path.join(
                    current_app.config["UPLOAD_DIRECTORY"],
                    self.request.id,
                    response.name
                )
            )
        )
        self.assert_response_event(self.request.id, event_type.FILE_ADDED, response, self.rf.agency_user)

    def test_add_file_custom_without_path(self):
        title = "Having Fun Isn't Hard"
        name = "libary_card"
        privacy = response_privacy.RELEASE_AND_PUBLIC
        response = self.request.add_file(
            title=title,
            name=name,
            privacy=privacy,
            user=self.rf.public_user,
        )
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.title,
                response.name,
                response.mime_type,
                type(response.size),
                type(response.hash)
            ],
            [
                self.request.id,
                privacy,
                title,
                name,
                "text/plain",
                int,  # size
                str,  # hash
            ]
        )
        self.assertTrue(response.size > 0)
        self.assertTrue(
            os.path.exists(
                os.path.join(
                    current_app.config["UPLOAD_DIRECTORY"],
                    self.request.id,
                    response.name
                )
            )
        )
        self.assert_response_event(self.request.id, event_type.FILE_ADDED, response, self.rf.public_user)

    def test_add_file_custom_with_path(self):
        title = "Open Wide"
        response = self.request.add_file(
            title=title,
            name="dont_mind_me",
            filepath=SCREAM_FILE.path,
        )
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.title,
                response.name,
                response.mime_type,
                response.size,
                response.hash
            ],
            [
                self.request.id,
                response_privacy.PRIVATE,
                title,
                SCREAM_FILE.name,
                SCREAM_FILE.mime_type,
                SCREAM_FILE.size,
                SCREAM_FILE.hash
            ]
        )
        self.assert_response_event(self.request.id, event_type.FILE_ADDED, response, self.rf.agency_user)

    def test_add_link(self):
        response = self.request.add_link()

        title = "Urlification"
        url = "http://url.com"
        privacy = response_privacy.RELEASE_AND_PUBLIC
        response_custom = self.request.add_link(title, url, privacy, self.rf.public_user)

        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                type(response.title),
                type(response.url)
            ],
            [
                self.request.id,
                response_privacy.PRIVATE,
                str,  # title
                str,  # url
            ]
        )
        self.assert_response_event(self.request.id, event_type.LINK_ADDED, response, self.rf.agency_user)

        response = Responses.query.get(response_custom.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.title,
                response.url
            ],
            [
                self.request.id,
                privacy,
                title,
                url
            ]
        )
        self.assert_response_event(self.request.id, event_type.LINK_ADDED, response, self.rf.public_user)

    def test_add_note(self):
        response = self.request.add_note()

        content = "I. AM. A. NOTE."
        privacy = response_privacy.RELEASE_AND_PUBLIC
        response_custom = self.request.add_note(content, privacy, self.rf.public_user)

        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                type(response.content)
            ],
            [
                self.request.id,
                response_privacy.PRIVATE,
                str
            ]
        )
        self.assert_response_event(self.request.id, event_type.NOTE_ADDED, response, self.rf.agency_user)

        response = Responses.query.get(response_custom.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.content
            ],
            [
                self.request.id,
                privacy,
                content
            ]
        )
        self.assert_response_event(self.request.id, event_type.NOTE_ADDED, response, self.rf.public_user)

    def test_add_instructions(self):
        response = self.request.add_instructions()

        content = "I want to play a game. In the room to your left you will find..."
        privacy = response_privacy.RELEASE_AND_PUBLIC
        response_custom = self.request.add_instructions(content, privacy, self.rf.public_user)

        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                type(response.content)
            ],
            [
                self.request.id,
                response_privacy.PRIVATE,
                str
            ]
        )
        self.assert_response_event(self.request.id, event_type.INSTRUCTIONS_ADDED, response, self.rf.agency_user)

        response = Responses.query.get(response_custom.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.content
            ],
            [
                self.request.id,
                privacy,
                content
            ]
        )
        self.assert_response_event(self.request.id, event_type.INSTRUCTIONS_ADDED, response, self.rf.public_user)

    def test_acknowledge_days(self):
        days = 30
        info = "Informative information that will inform you."
        due_date = get_due_date(
            utc_to_local(
                self.request.due_date,
                self.tz_name
            ),
            days,
            self.tz_name
        )
        response = self.request.acknowledge(info=info, days=days)
        self.__test_extension(response, determination_type.ACKNOWLEDGMENT, info, due_date)

    def test_acknowledge_date(self):
        date = calendar.addbusdays(datetime.now(), 100)
        response = self.request.acknowledge(date=date)
        due_date = process_due_date(local_to_utc(date, self.tz_name))
        self.__test_extension(response, determination_type.ACKNOWLEDGMENT, str, due_date)

    def test_acknowledge_missing_args(self):
        with self.assertRaises(AssertionError):
            self.request.acknowledge()

    def test_extend_days(self):
        days = 20
        reason = "Reasonable reasoning for the rational reasoner."
        due_date = get_due_date(
            utc_to_local(
                self.request.due_date,
                self.tz_name
            ),
            days,
            self.tz_name
        )
        response = self.request.extend(reason=reason, days=days)
        self.__test_extension(response, determination_type.EXTENSION, reason, due_date)

    def test_extend_date_due_soon(self):
        request = self.rf.create_request_as_anonymous_user(due_date=datetime.utcnow())
        date = calendar.addbusdays(utc_to_local(request.due_date, self.tz_name), 1)
        due_date = process_due_date(local_to_utc(date, self.tz_name))
        response = request.extend(date=date)
        self.__test_extension(
            response, determination_type.EXTENSION, str, due_date, request_status.DUE_SOON, request=request)

    def test_extend_date_overdue(self):
        request = self.rf.create_request_as_anonymous_user(
            due_date=calendar.addbusdays(datetime.utcnow(), -2))
        date = calendar.addbusdays(utc_to_local(request.due_date, self.tz_name), 1)
        due_date = process_due_date(local_to_utc(date, self.tz_name))
        response = request.extend(date=date)
        self.__test_extension(
            response, determination_type.EXTENSION, str, due_date, request_status.OVERDUE, request=request)

    # TODO: prevent users from extending a request to a date that will still result in an OVERDUE status
    def test_extend_bad_due_date(self):
        with self.assertRaises(AssertionError):
            self.request.extend(date=calendar.addbusdays(
                utc_to_local(self.request.due_date, self.tz_name), -1))

    def test_reopen(self):
        date = calendar.addbusdays(utc_to_local(self.request.due_date, self.tz_name), 1)
        response = self.request.reopen(date)
        due_date = process_due_date(local_to_utc(date, self.tz_name))
        self.__test_extension(response, determination_type.REOPENING, None, due_date)
        self.assertEqual(self.request.agency_request_summary, None)

    def __test_extension(self,
                         response,
                         type_,
                         reason,
                         due_date,
                         status=request_status.IN_PROGRESS,
                         user=None,
                         request=None):
        request_id = request.id if request is not None else self.request.id
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                type(response.reason) if isinstance(reason, type) else response.reason,
                response.date
            ],
            [
                request_id,
                response_privacy.RELEASE_AND_PUBLIC,
                type_,
                reason,
                due_date
            ]
        )
        request = Requests.query.get(request_id)
        self.assertEqual(
            [
                request.status,
                request.due_date,
            ],
            [
                status,
                due_date
            ]
        )
        self.assert_response_event(request.id, type_, response, user or self.rf.agency_user)

    def test_close_default(self):
        response = self.request.close()
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                type(response.reason)
            ],
            [
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.CLOSING,
                str
            ]
        )
        self.assert_response_event(self.request.id, event_type.REQ_CLOSED, response, self.rf.agency_user)

    def test_close_custom(self):
        reason_ids = sample(set([r.id for r in Reasons.query.filter_by(type=determination_type.CLOSING).all()]), 3)
        response_custom = self.request.close(reason_ids, self.rf.public_user)
        response = Responses.query.get(response_custom.id)
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                response.reason
            ],
            [
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.CLOSING,
                format_determination_reasons(reason_ids)
            ]
        )
        self.assert_response_event(self.request.id, event_type.REQ_CLOSED, response, self.rf.public_user)

    def test_deny_default(self):
        response = self.request.deny()
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                type(response.reason)
            ],
            [
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.DENIAL,
                str
            ]
        )
        self.assert_response_event(self.request.id, event_type.REQ_CLOSED, response, self.rf.agency_user)

    def test_deny_custom(self):
        reason_ids = sample(set([r.id for r in Reasons.query.filter_by(type=determination_type.DENIAL).all()]), 3)
        response_custom = self.request.deny(reason_ids, self.rf.public_user)
        response = Responses.query.get(response_custom.id)
        response = Responses.query.get(response.id)
        self.assertEqual(
            [
                response.request_id,
                response.privacy,
                response.dtype,
                response.reason
            ],
            [
                self.request.id,
                response_privacy.RELEASE_AND_PUBLIC,
                determination_type.DENIAL,
                format_determination_reasons(reason_ids)
            ]
        )
        self.assert_response_event(self.request.id, event_type.REQ_CLOSED, response, self.rf.public_user)

    def test_set_due_soon(self):
        self.__test_due_soon_or_overdue(
            request_status.DUE_SOON,
            calendar.addbusdays(
                datetime.utcnow(), current_app.config["DUE_SOON_DAYS_THRESHOLD"]
            ).replace(hour=23, minute=59, second=59, microsecond=0),
        )

    def test_set_due_soon_no_shift(self):
        self.__test_due_soon_or_overdue(request_status.DUE_SOON, no_shift=True)

    def test_set_overdue(self):
        self.__test_due_soon_or_overdue(
            request_status.OVERDUE,
            calendar.addbusdays(
                datetime.utcnow(), -1
            ).replace(microsecond=0)
        )

    def test_set_overdue_no_shift(self):
        self.__test_due_soon_or_overdue(request_status.OVERDUE, no_shift=True)

    def __test_due_soon_or_overdue(self, status, due_date=None, no_shift=False):
        if no_shift:
            due_date = self.request.due_date
            date_submitted = self.request.date_submitted
            date_created = self.request.date_created

            {request_status.DUE_SOON: self.request.set_due_soon,
             request_status.OVERDUE: self.request.set_overdue
            }[status](shift_dates=False)

            request = Requests.query.get(self.request.id)
            self.assertEqual(
                [
                    request.status,
                    request.due_date,
                    request.date_submitted,
                    request.date_created
                ],
                [
                    status,
                    due_date,
                    date_submitted,
                    date_created
                ]
            )
        else:
            shift = due_date - self.request.due_date
            date_submitted = self.request.date_submitted + shift
            date_created = self.request.date_created + shift
            old_status = self.request.status

            {request_status.DUE_SOON: self.request.set_due_soon,
             request_status.OVERDUE: self.request.set_overdue
             }[status]()

            request = Requests.query.get(self.request.id)
            self.assertEqual(
                [
                    request.status,
                    request.due_date,
                    request.date_submitted,
                    request.date_created,
                    # TODO: request.agency_request_summary_release_date
                ],
                [
                    status,
                    due_date,
                    date_submitted,
                    date_created
                ]
            )
            event = Events.query.filter_by(type=event_type.REQ_STATUS_CHANGED).one()
            self.assertEqual(
                [
                    event.request_id,
                    event.user_guid,
                    event.auth_user_type,
                    event.previous_value,
                    event.new_value,
                    event.response_id
                ],
                [
                    self.request.id,
                    None,  # user_guid
                    None,  # auth_user_type
                    {"status": old_status},
                    {"status": status},
                    None
                ]
            )

    def test_add_user_anonymous(self):
        self.__test_add_user_default(
            self.uf.create_anonymous_user(),
            user_type_request.REQUESTER,
            role_name.ANONYMOUS
        )

    def test_add_user_public(self):
        self.__test_add_user_default(
            self.uf.create_public_user(),
            user_type_request.REQUESTER,
            role_name.PUBLIC_REQUESTER
        )

    def test_add_user_agency_inactive(self):
        self.__test_add_user_default(
            self.uf.create_agency_user(agency_ein=self.request.agency.ein),
            user_type_request.AGENCY,
            role_name.AGENCY_HELPER
        )

    def test_add_user_agency_active(self):
        self.__test_add_user_default(
            self.uf.create_agency_user(agency_ein=self.request.agency.ein,
                                       is_agency_active=True),
            user_type_request.AGENCY,
            role_name.AGENCY_OFFICER
        )

    def test_add_user_agency_admin(self):
        self.__test_add_user_default(
            self.uf.create_agency_admin(agency_ein=self.request.agency.ein),
            user_type_request.AGENCY,
            role_name.AGENCY_ADMIN
        )

    def __test_add_user_default(self, user, request_user_type, role):
        user_request = self.request.add_user(user)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.assertEqual(
            [
                user_request.request_id,
                user_request.request_user_type,
                user_request.permissions
            ],
            [
                self.request.id,
                request_user_type,
                Roles.query.filter_by(name=role).one().permissions
            ]
        )
        self.__assert_user_request_event(event_type.USER_ADDED, user_request, self.rf.agency_user)

    def test_add_user_custom_agent(self):
        user = self.uf.create_anonymous_user()
        agency_user = self.uf.create_agency_user(agency_ein=self.request.agency.ein)
        user_request = self.request.add_user(user, agent=agency_user)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.__assert_user_request_event(event_type.USER_ADDED, user_request, agency_user)

    def test_add_user_custom_role(self):
        user = self.uf.create_anonymous_user()
        rname = role_name.PUBLIC_REQUESTER
        user_request = self.request.add_user(user, role=rname)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.assertEqual(
            user_request.permissions,
            Roles.query.filter_by(name=rname).one().permissions
        )

    def test_add_user_custom_permissions(self):
        user = self.uf.create_anonymous_user()
        permissions = permission.ADD_LINK
        user_request = self.request.add_user(user, permissions=permissions)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.assertEqual(user_request.permissions, permissions)

    def test_edit_user_set_permissions(self):
        user = self.uf.create_public_user()
        user_request = self.request.add_user(user)
        old_permissions = user_request.permissions
        permissions = [permission.ADD_FILE, permission.ADD_OFFLINE_INSTRUCTIONS]
        self.request.edit_user(user, perms_set=permissions)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.assertEqual(user_request.permissions, reduce(ior, permissions))
        self.__assert_user_request_event(
            event_type.USER_PERM_CHANGED, user_request, self.rf.agency_user, old_permissions)

    def test_edit_user_add_permissions(self):
        user = self.uf.create_public_user()
        user_request = self.request.add_user(user)
        old_permissions = user_request.permissions
        permissions = [permission.ADD_OFFLINE_INSTRUCTIONS]
        self.request.edit_user(user, perms_add=permissions)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.assertEqual(user_request.permissions, permissions[0] | old_permissions)
        self.__assert_user_request_event(
            event_type.USER_PERM_CHANGED, user_request, self.rf.agency_user, old_permissions)

    def test_edit_user_remove_permissions(self):
        user = self.uf.create_public_user()
        user_request = self.request.add_user(user)
        old_permissions = [user_request.permissions]
        self.request.edit_user(user, perms_remove=old_permissions)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.assertEqual(user_request.permissions, permission.NONE)
        self.__assert_user_request_event(
            event_type.USER_PERM_CHANGED, user_request, self.rf.agency_user, old_permissions[0])

    def test_edit_user_as_agent(self):
        user = self.uf.create_anonymous_user()
        agency_user = self.uf.create_agency_user(agency_ein=self.request.agency.ein)
        user_request = self.request.add_user(user)
        old_permissions = user_request.permissions
        self.request.edit_user(user, perms_set=permission.NONE, agent=agency_user)
        user_request = UserRequests.query.filter_by(user_guid=user.guid).one()
        self.__assert_user_request_event(
            event_type.USER_PERM_CHANGED, user_request, agency_user, old_permissions)

    def test_edit_user_missing_permissions(self):
        user = self.uf.create_anonymous_user()
        with self.assertRaises(AssertionError):
            self.request.edit_user(user)

    def test_remove_user(self):
        user = self.uf.create_anonymous_user()
        user_request = self.request.add_user(user)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.request.remove_user(user)
        self.__assert_user_request_event(event_type.USER_REMOVED, user_request, self.rf.agency_user)
        self.assertTrue(UserRequests.query.filter_by(user_guid=user.guid).first() is None)

    def test_remove_user_as_agent(self):
        user = self.uf.create_anonymous_user()
        agency_user = self.uf.create_agency_user(agency_ein=self.request.agency.ein)
        user_request = self.request.add_user(user)
        user_request = UserRequests.query.filter_by(user_guid=user_request.user_guid).one()
        self.request.remove_user(user, agent=agency_user)
        self.__assert_user_request_event(event_type.USER_REMOVED, user_request, agency_user)
        self.assertTrue(UserRequests.query.filter_by(user_guid=user.guid).first() is None)

    def test_destructor(self):
        response = self.request.add_file()
        self.assertTrue(
            os.path.exists(
                os.path.join(
                    current_app.config["UPLOAD_DIRECTORY"],
                    self.request.id,
                    response.name
                )
            )
        )
        request_id = self.request.id
        del self.request
        self.assertFalse(
            os.path.exists(
                os.path.join(
                    current_app.config["UPLOAD_DIRECTORY"],
                    request_id,
                    response.name
                )
            )
        )

    def __assert_user_request_event(self, type_, user_request, user, old_permissions=None):
        # get latest event with type `type_`
        event = Events.query.filter_by(type=type_).order_by(Events.timestamp.desc()).first()
        self.assertEqual(
            [
                event.request_id,
                event.user_guid,
                event.auth_user_type,
                event.previous_value,
                event.new_value
            ],
            [
                self.request.id,
                user.guid,
                user.auth_user_type,
                {"permissions": old_permissions} if old_permissions is not None else None,
                user_request.val_for_events
            ]
        )
Beispiel #7
0
class RequestFactoryTests(BaseTestCase):

    def setUp(self):
        super().setUp()
        self.agency_ein_860 = "0860"
        self.parent_ein_860 = "860"
        self.agency_ein_002 = "0002"
        uf = UserFactory()
        self.user_860 = uf.create_agency_user(self.agency_ein_860)
        self.admin_860 = uf.create_agency_admin(self.agency_ein_860)
        self.rf = RequestFactory()
        self.rf_agency_860 = RequestFactory(agency_ein=self.agency_ein_860)
        self.rf_agency_002 = RequestFactory(agency_ein=self.agency_ein_002)
        self.tz_name = current_app.config["APP_TIMEZONE"]

    def test_create_request_default(self):
        request = self.rf.create_request(self.user_860)
        self.__assert_request_data_correct(
            self.user_860,
            request,
            self.parent_ein_860,
            default=True,
        )
        # check associated users
        requester = Users.query.filter_by(auth_user_type=user_type_auth.ANONYMOUS_USER).one()
        self.assertEqual(request.requester, requester)
        self.assertFalse(self.user_860 in request.agency_users)
        self.assertTrue(self.admin_860 in request.agency_users)

    def test_create_request_custom(self):
        title = "Where did all the fish go?"
        description = "I demand to know where all of my fish ran off to."
        agency_request_summary = "Inquiry into the disappearance local marine life."
        category = "Fishies"
        title_privacy = False
        agency_request_summary_privacy = False
        submission = submission_methods.IN_PERSON
        status = request_status.IN_PROGRESS
        date_created = datetime.utcnow()
        due_date = date_created + timedelta(days=90)
        request = self.rf.create_request(
            self.user_860,
            title,
            description,
            agency_request_summary,
            self.user_860.agency_ein,
            date_created,
            due_date=due_date,
            category=category,
            title_privacy=title_privacy,
            agency_request_summary_privacy=agency_request_summary_privacy,
            submission=submission,
            status=status
        )
        self.__assert_request_data_correct(
            self.user_860,
            request,
            self.parent_ein_860,
            title=title,
            description=description,
            agency_request_summary=agency_request_summary,
            agency_ein=self.agency_ein_860,
            date_created=date_created,
            due_date=due_date,
            category=category,
            title_privacy=title_privacy,
            agency_request_summary_privacy=agency_request_summary_privacy,
            submission=submission,
            status=status
        )
        # check associated users
        requester = Users.query.filter_by(auth_user_type=user_type_auth.ANONYMOUS_USER).one()
        self.assertEqual(request.requester, requester)
        self.assertFalse(self.user_860 in request.agency_users)
        self.assertTrue(self.admin_860 in request.agency_users)

    def test_create_request_agency_ein(self):
        request = self.rf_agency_860.create_request_as_public_user()
        self.__assert_request_data_correct(
            self.rf_agency_860.public_user,
            request,
            self.parent_ein_860,
            default=True
        )
        self.assertTrue(self.admin_860 in request.agency_users)

    def test_create_request_as_anonymous_user(self):
        request = self.rf.create_request_as_anonymous_user()
        user = Users.query.filter_by(auth_user_type=user_type_auth.ANONYMOUS_USER).one()
        self.__assert_request_data_correct(
            user,
            request,
            request.agency.parent_ein,
            default=True
        )
        self.assertEqual(request.requester, user)

    def test_create_request_as_agency_user(self):
        request = self.rf.create_request_as_agency_user()
        self.__assert_request_data_correct(
            self.rf.agency_user,
            request,
            self.rf.agency_user.agency.parent_ein,
            default=True
        )
        self.assertFalse(self.rf.agency_user in request.agency_users)

    def test_create_request_as_public_user(self):
        request = self.rf.create_request_as_public_user()
        self.__assert_request_data_correct(
            self.rf.public_user,
            request,
            request.agency.parent_ein,
            default=True
        )
        self.assertEqual(request.requester, self.rf.public_user)

    def test_create_request_wrong_dates(self):
        now = datetime.utcnow()
        tomorrow = now + timedelta(days=1)

        with self.assertRaises(AssertionError):
            self.rf.create_request(self.user_860, due_date=now, date_created=now)

        with self.assertRaises(AssertionError):
            self.rf.create_request(self.user_860, due_date=now, date_submitted=now)

        with self.assertRaises(AssertionError):
            self.rf.create_request(self.user_860, due_date=now, date_created=tomorrow)

        with self.assertRaises(AssertionError):
            self.rf.create_request(self.user_860, due_date=now, date_submitted=tomorrow)

    def test_create_request_wrong_agency_ein(self):

        with self.assertRaises(AssertionError):
            self.rf.create_request(self.user_860, agency_ein=self.agency_ein_002)

        with self.assertRaises(AssertionError):
            self.rf_agency_002.create_request(self.user_860)

    def __assert_request_data_correct(self,
                                      user,
                                      request,
                                      agency_parent_ein,
                                      default=False,
                                      title=None,
                                      description=None,
                                      agency_request_summary=None,
                                      agency_ein=None,
                                      date_created=None,
                                      due_date=None,
                                      category='All',
                                      title_privacy=True,
                                      agency_request_summary_privacy=True,
                                      submission=None,
                                      status=request_status.OPEN):
        request = Requests.query.get(request.id)

        privacy = {"title": title_privacy, "agency_request_summary": agency_request_summary_privacy}
        agency_ein = agency_ein or user.agency_ein or request.agency_ein
        date_created_local = utc_to_local(date_created or request.date_created, self.tz_name)
        date_submitted_local = get_following_date(date_created_local)

        if default:
            self.assertTrue(request.submission in submission_methods.ALL)
            request_list = [
                type(request.title),
                type(request.description),
            ]
            check_list = [
                str,
                str,
            ]
        else:
            request_list = [
                request.title,
                request.description,
                request.agency_request_summary,
                request.date_created,
                request.submission,
            ]
            check_list = [
                title,
                description,
                agency_request_summary,
                date_created,
                submission,
            ]
        request_list += [
            request.id,
            request.category,
            request.privacy,
            request.agency_ein,
            request.status,
            request.date_submitted,
            request.due_date,
        ]
        check_list += [
            "FOIL-{}-{}-00001".format(datetime.today().year, agency_parent_ein),
            category,
            privacy,
            agency_ein,
            status,
            local_to_utc(date_submitted_local, self.tz_name),
            due_date or get_due_date(date_submitted_local, ACKNOWLEDGMENT_DAYS_DUE, self.tz_name)
        ]
        self.assertEqual(request_list, check_list)

        # check associated events
        event_req_created = Events.query.filter_by(type=event_type.REQ_CREATED).one()
        self.assertEqual(
            [
                event_req_created.user_guid,
                event_req_created.auth_user_type,
                event_req_created.request_id,
                event_req_created.response_id,
                event_req_created.previous_value,
                event_req_created.new_value,
            ],
            [
                user.guid,
                user.auth_user_type,
                request.id,
                None,  # response_id
                None,  # previous_value
                request.val_for_events  # new_value
            ]
        )
        if user.is_agency:
            event_agency_req_created = Events.query.filter_by(type=event_type.AGENCY_REQ_CREATED).one()
            self.assertEqual(
                [
                    event_agency_req_created.user_guid,
                    event_agency_req_created.auth_user_type,
                    event_agency_req_created.request_id,
                    event_agency_req_created.response_id,
                    event_agency_req_created.previous_value,
                    event_agency_req_created.new_value,
                ],
                [
                    user.guid,
                    user.auth_user_type,
                    request.id,
                    None,  # response_id
                    None,  # previous_value
                    None,  # new_value
                ]
            )
Beispiel #8
0
 def setUp(self):
     super().setUp()
     uf = UserFactory()
     self.agency_admin = uf.create_agency_admin()
     self.request = RequestFactory().create_request_as_anonymous_user()
Beispiel #9
0
 def setUp(self):
     super().setUp()
     uf = UserFactory()
     self.rf = RequestFactory()
Beispiel #10
0
class RequestUtilsTests(BaseTestCase):
    def setUp(self):
        super().setUp()
        uf = UserFactory()
        self.rf = RequestFactory()

    @patch('app.request.utils.send_contact_email')
    def test_create_contact_record_anon(self, send_contact_email_patch):
        request = self.rf.create_request_as_anonymous_user()
        first_name = 'John'
        last_name = 'Doris'
        subject = 'Inquire about {}'.format(request.id)
        email = '*****@*****.**'
        message = 'I need more information about my request.'
        body = "Name: {} {}\n\nEmail: {}\n\nSubject: {}\n\nMessage:\n{}".format(
            first_name, last_name, email, subject, message)
        agency_emails = get_agency_emails(request.id)

        create_contact_record(request,
                              first_name,
                              last_name,
                              email,
                              subject,
                              message)
        send_contact_email_patch.assert_called_once_with(
            subject,
            agency_emails,
            message,
            email
        )

        user = Users.query.filter_by(email=email).one()
        self.assertEqual(
            [
                user.first_name,
                user.last_name,
                user.auth_user_type,
                user.email
            ],
            [
                first_name,
                last_name,
                user_type_auth.ANONYMOUS_USER,
                email
            ]
        )
        user_created_event = Events.query.filter(Events.request_id == request.id,
                                                 Events.type == event_type.USER_CREATED).one()
        self.assertEqual(user.val_for_events, user_created_event.new_value)
        email_obj = Emails.query.filter(Emails.request_id == request.id,
                                        Emails.subject == subject).one()
        self.assertEqual(
            [
                [email_obj.to],
                email_obj.body
            ],
            [
                agency_emails,
                body
            ]
        )

        contact_event = Events.query.filter_by(response_id=email_obj.id).one()
        self.assertEqual(
            [
                contact_event.request_id,
                contact_event.user_guid,
                contact_event.auth_user_type,
                contact_event.type,
                contact_event.new_value
            ],
            [
                request.id,
                user.guid,
                user.auth_user_type,
                event_type.CONTACT_EMAIL_SENT,
                email_obj.val_for_events
            ]
        )

    @patch('app.request.utils.send_contact_email')
    def test_create_contact_record_public(self, send_contact_email_patch):
        request = self.rf.create_request_as_public_user()
        user = self.rf.public_user
        subject = 'Inquire about {}'.format(request.id)
        message = 'I need more information about my request.'
        body = "Name: {} {}\n\nEmail: {}\n\nSubject: {}\n\nMessage:\n{}".format(
            user.first_name, user.last_name, user.email, subject, message)
        agency_emails = get_agency_emails(request.id)

        with flask_login_user(user):
            create_contact_record(request,
                                  user.first_name,
                                  user.last_name,
                                  user.email,
                                  subject,
                                  message)
            send_contact_email_patch.assert_called_once_with(
                subject,
                agency_emails,
                message,
                user.email
            )
        email_obj = Emails.query.filter(Emails.request_id == request.id,
                                        Emails.subject == subject).one()
        self.assertEqual(
            [
                [email_obj.to],
                email_obj.body
            ],
            [
                agency_emails,
                body
            ]
        )

        contact_event = Events.query.filter_by(response_id=email_obj.id).one()
        self.assertEqual(
            [
                contact_event.request_id,
                contact_event.user_guid,
                contact_event.auth_user_type,
                contact_event.type,
                contact_event.new_value
            ],
            [
                request.id,
                user.guid,
                user.auth_user_type,
                event_type.CONTACT_EMAIL_SENT,
                email_obj.val_for_events
            ]
        )
Beispiel #11
0
class ResponseViewsTests(BaseTestCase, TestHelpers):
    def setUp(self):
        super().setUp()
        self.agency_ein_860 = "0860"
        uf = UserFactory()
        self.agency_user_860 = uf.create_agency_user(agency_ein=self.agency_ein_860)
        self.admin_860 = uf.create_agency_admin(agency_ein=self.agency_ein_860)
        self.rf = RequestFactory
        self.rf_agency_860 = RequestFactory(agency_ein=self.agency_ein_860)
        self.request = self.rf_agency_860.create_request_as_public_user()

    def test_response_denial(self):
        with self.client as client:
            login_user_with_client(client, self.admin_860.get_id())
            response = self.client.post(
                '/response/denial/' + self.request.id,
                data={
                    "reasons": ['1', '2', '3'],
                    "email-summary": 'This is a email summary'
                }
            )
        self.assertEqual(response.status_code, 302)
        self.assertEqual(urlparse(response.location).path, url_for('request.view', request_id=self.request.id))

    def test_response_denial_missing_reasons(self):
        with self.client as client:
            login_user_with_client(client, self.admin_860.get_id())
            response = self.client.post(
                '/response/denial/' + self.request.id,
                data={
                    "email-summary": 'This is a email summary'
                }
            )
        self.assert_flashes(expected_message='Uh Oh, it looks like the denial reasons is missing! '
                                             'This is probably NOT your fault.', expected_category='danger')
        self.assertEqual(response.status_code, 302)
        self.assertEqual(urlparse(response.location).path, url_for('request.view', request_id=self.request.id))

    def test_response_closing(self):
        self.request.acknowledge(days=30)
        self.request.set_agency_request_summary(agency_request_summary='blah')
        self.request.set_agency_request_summary_privacy(privacy=False)
        with self.client as client:
            login_user_with_client(client, self.admin_860.get_id())
            response = self.client.post(
                '/response/closing/' + self.request.id,
                data={
                    "reasons": ['1', '2', '3'],
                    "email-summary": 'This is a email summary'
                }
            )
        self.assertEqual(response.status_code, 302)
        self.assertEqual(urlparse(response.location).path, url_for('request.view', request_id=self.request.id))

    def test_response_closing_missing_reasons(self):
        self.request.acknowledge(days=30)
        with self.client as client:
            login_user_with_client(client, self.admin_860.get_id())
            response = self.client.post(
                '/response/closing/' + self.request.id,
                data={
                    "email-summary": 'This is a email summary'
                }
            )
        self.assert_flashes(expected_message='Uh Oh, it looks like the closing reasons is missing! '
                                             'This is probably NOT your fault.', expected_category='danger')
        self.assertEqual(response.status_code, 302)
        self.assertEqual(urlparse(response.location).path, url_for('request.view', request_id=self.request.id))

    def test_response_closing_no_agency_request_summary(self):
        self.request.acknowledge(days=30)
        with self.client as client:
            login_user_with_client(client, self.admin_860.get_id())
            response = self.client.post(
                '/response/closing/' + self.request.id,
                data={
                    "reasons": ['1', '2', '3'],
                    "email-summary": 'This is a email summary'
                }
            )
        self.assert_flashes(expected_message='Unable to close request:', expected_category='danger')
        self.assertEqual(response.status_code, 302)
        self.assertEqual(urlparse(response.location).path, url_for('request.view', request_id=self.request.id))