diff --git a/.test_durations b/.test_durations index 6373c77837a6172e34e4f2e6470676fc98baab30..b75c8ef8c75ad467969fc0281f332312e643e07f 100644 --- a/.test_durations +++ b/.test_durations @@ -1,669 +1,669 @@ { - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_activity_created": 0.15622116602025926, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_handle_transition_public_to_public": 0.11254104098770767, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_handle_transition_to_private_to_public": 0.1516230000415817, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_handle_transition_to_public_to_private": 0.12896395893767476, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_internal_transition_kwarg_for_invisible_transition": 0.11071612499654293, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_activity_created": 0.1238382079754956, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_handle_transition_public_to_public": 0.1171614999184385, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_handle_transition_to_private_to_public": 0.15188470896100625, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_handle_transition_to_public_to_private": 0.13876925001386553, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_internal_transition_kwarg_for_invisible_transition": 0.08285395905841142, "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_lead_not_saved_on_activity": 0.10346592601854354, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_lead_saved_on_activity": 0.10993020900059491, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_public_transition_kwargs": 0.10942875000182539, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_review_saved_on_activity": 0.14057566702831537, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_message_both": 0.23541791702155024, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_message_no_added": 0.1198202099185437, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_message_no_removed": 0.13272458396386355, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_with_and_without_role": 0.19799787388183177, - "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_with_role": 58.13467112497892, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_activity_created": 0.13486366695724428, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_activity_lead_change": 0.1162876250455156, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_activity_lead_change_from_none": 0.11584366695024073, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_email_staff_update_invoice": 0.21926733397413045, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_applicant_update_invoice": 0.13566949998494238, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_created": 54.16529204195831, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_lead_change": 0.1296427499037236, - "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_staff_update_invoice": 0.1271418749820441, - "hypha/apply/activity/tests/test_messaging.py::TestAnyMailBehaviour::test_email_new_submission": 0.1355100410291925, - "hypha/apply/activity/tests/test_messaging.py::TestAnyMailBehaviour::test_webhook_adds_reject_reason": 0.12718500010669231, - "hypha/apply/activity/tests/test_messaging.py::TestAnyMailBehaviour::test_webhook_updates_status": 0.1375391249312088, - "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_calls_method_if_avaliable": 53.299532873905264, - "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_can_include_extra_kwargs": 0.11929216794669628, - "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_can_send_a_message": 0.0824252919992432, - "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_django_messages_used": 0.07164995896164328, - "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_doesnt_send_a_message_if_not_configured": 0.09355312504339963, - "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_that_kwargs_passed_to_send_message": 0.20675625011790544, - "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_that_message_is_formatted": 0.15560216596350074, - "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_email_failed": 0.39270045806188136, - "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_email_new_submission": 0.09615187509916723, - "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_email_sent": 0.11342545901425183, - "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_no_email_own_comment": 0.11332941707223654, - "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_no_email_private_comment": 0.11486445926129818, - "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_reviewer_update_email": 0.15956100111361593, - "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_reviewers_email": 0.15471450006589293, - "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendApplication::test_event_created": 0.2171912919729948, - "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendApplication::test_message_sent_to_adapter": 0.1030887080123648, - "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendApplication::test_message_sent_to_all_adapter": 0.09288750018458813, - "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendProject::test_event_created": 0.1586895000655204, - "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendProject::test_message_sent_to_adapter": 0.11586466699372977, - "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendProject::test_message_sent_to_all_adapter": 0.11438579205423594, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_400_bad_request": 0.13000170898158103, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_cant_send_with_no_room": 0.08840891683939844, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_cant_send_with_no_token": 0.08516858296934515, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_correct_payload": 0.08612241595983505, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_fund_custom_slack_channel": 0.13703129114583135, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_fund_multiple_custom_slack_channel": 0.17032066697720438, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_gets_blank_if_slack_not_set": 0.08843441598583013, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_gets_lead_if_slack_set": 0.06989941594656557, - "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_message_with_good_response": 0.21480724995490164, - "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_related_invoice": 0.25832999881822616, - "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_related_report": 0.25690624897833914, - "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_source_application": 0.11774445907212794, - "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_source_project": 0.12374466715846211, - "hypha/apply/activity/tests/test_models.py::TestActivityOnlyIncludesCurrent::test_doesnt_include_non_current": 0.27184329100418836, - "hypha/apply/activity/tests/test_tasks.py::TestSendEmail::test_args_passed_to_django": 0.3205880840541795, - "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_reviewer_cant_list_screening_statuses": 0.07995720813050866, - "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_staff_can_list_screening_statuses": 0.04845495906192809, - "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_staff_can_view_screening_statuses_detail": 0.03481295891106129, - "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_user_cant_list_screening_statuses": 0.04167466703802347, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_add_screening_status": 0.2516370009398088, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_add_screening_status_without_setting_default": 0.14604949986096472, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_add_two_types_of_screening_status": 0.14344608294777572, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_change_default_screening_status": 0.1464127510553226, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_remove_not_set_screening_status": 0.18066850095055997, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_remove_submission_default_screening_status": 0.13743912591598928, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_change_default_screening_status": 0.15612299996428192, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_remove_submission_screening_status": 0.15497579204384238, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_reviewer_cant_list_screening_statuses": 0.12685020896606147, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_set_default_screening_status": 0.14016562490724027, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_staff_can_list_submission_screening_statuses": 0.32360654103104025, - "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_user_cant_list_screening_statuses": 0.1403301249956712, - "hypha/apply/api/v1/tests/test_serializers.py::TestDeliverableSerializer::test_id_is_required": 0.011137875029817224, - "hypha/apply/api/v1/tests/test_serializers.py::TestDeliverableSerializer::test_quantity_not_required": 0.1423097929218784, - "hypha/apply/api/v1/tests/test_serializers.py::TestDeliverableSerializer::test_validate_id": 0.14980237488634884, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_lead_saved_on_activity": 0.09730487398337573, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_public_transition_kwargs": 0.09278300101868808, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_review_saved_on_activity": 0.09202558395918459, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_message_both": 0.21213320893002674, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_message_no_added": 0.10327933402732015, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_message_no_removed": 0.09462454193271697, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_with_and_without_role": 0.23094345803838223, + "hypha/apply/activity/tests/test_messaging.py::TestActivityAdapter::test_reviewers_with_role": 47.73333083395846, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_activity_created": 0.15268362505594268, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_activity_lead_change": 0.14951995701994747, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_activity_lead_change_from_none": 0.11902916699182242, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_email_staff_update_invoice": 0.14155945903621614, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_applicant_update_invoice": 0.11052658397238702, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_created": 47.48602349992143, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_lead_change": 0.11825299903284758, + "hypha/apply/activity/tests/test_messaging.py::TestAdaptersForProject::test_slack_staff_update_invoice": 0.13310266699409112, + "hypha/apply/activity/tests/test_messaging.py::TestAnyMailBehaviour::test_email_new_submission": 0.1500404590042308, + "hypha/apply/activity/tests/test_messaging.py::TestAnyMailBehaviour::test_webhook_adds_reject_reason": 0.18803249998018146, + "hypha/apply/activity/tests/test_messaging.py::TestAnyMailBehaviour::test_webhook_updates_status": 0.17489708412904292, + "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_calls_method_if_avaliable": 47.906467207940295, + "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_can_include_extra_kwargs": 0.0845225410303101, + "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_can_send_a_message": 0.09592704096576199, + "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_django_messages_used": 0.07743954192847013, + "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_doesnt_send_a_message_if_not_configured": 0.09835191600723192, + "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_that_kwargs_passed_to_send_message": 0.09245612402446568, + "hypha/apply/activity/tests/test_messaging.py::TestBaseAdapter::test_that_message_is_formatted": 0.13165591604774818, + "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_email_failed": 0.15192049893084913, + "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_email_new_submission": 0.10662350099300966, + "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_email_sent": 0.11383858398767188, + "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_no_email_own_comment": 0.09285833401372656, + "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_no_email_private_comment": 0.16527420905185863, + "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_reviewer_update_email": 0.20949699904303998, + "hypha/apply/activity/tests/test_messaging.py::TestEmailAdapter::test_reviewers_email": 0.16952445899369195, + "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendApplication::test_event_created": 0.13112020801054314, + "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendApplication::test_message_sent_to_adapter": 0.10940145701169968, + "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendApplication::test_message_sent_to_all_adapter": 0.09993212501285598, + "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendProject::test_event_created": 0.13866575103020296, + "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendProject::test_message_sent_to_adapter": 0.09959224902559072, + "hypha/apply/activity/tests/test_messaging.py::TestMessageBackendProject::test_message_sent_to_all_adapter": 0.11068808392155915, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_400_bad_request": 0.1297815419966355, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_cant_send_with_no_room": 0.07485283288406208, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_cant_send_with_no_token": 0.07143016590271145, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_correct_payload": 0.09908179199555889, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_fund_custom_slack_channel": 0.08437458303524181, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_fund_multiple_custom_slack_channel": 0.09744604106526822, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_gets_blank_if_slack_not_set": 0.07998300099279732, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_gets_lead_if_slack_set": 0.12432800000533462, + "hypha/apply/activity/tests/test_messaging.py::TestSlackAdapter::test_message_with_good_response": 0.3921164179337211, + "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_related_invoice": 0.19420499994885176, + "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_related_report": 0.2129346679430455, + "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_source_application": 0.11591845791554078, + "hypha/apply/activity/tests/test_models.py::TestActivityModel::test_can_save_source_project": 0.11624162399675697, + "hypha/apply/activity/tests/test_models.py::TestActivityOnlyIncludesCurrent::test_doesnt_include_non_current": 0.19171858398476616, + "hypha/apply/activity/tests/test_tasks.py::TestSendEmail::test_args_passed_to_django": 0.29254162503639236, + "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_reviewer_cant_list_screening_statuses": 0.11804758291691542, + "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_staff_can_list_screening_statuses": 0.08460991701576859, + "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_staff_can_view_screening_statuses_detail": 0.07517845794791356, + "hypha/apply/api/v1/screening/tests/test_views.py::ScreeningStatusViewSetTests::test_user_cant_list_screening_statuses": 0.06913070805603638, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_add_screening_status": 0.4383973330259323, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_add_screening_status_without_setting_default": 0.17237325001042336, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_add_two_types_of_screening_status": 0.16616412496659905, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_change_default_screening_status": 0.19408370897872373, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_remove_not_set_screening_status": 0.18300837505375966, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_cant_remove_submission_default_screening_status": 0.15282195806503296, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_change_default_screening_status": 0.2162731250282377, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_remove_submission_screening_status": 0.17058312508743256, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_reviewer_cant_list_screening_statuses": 0.1689779590233229, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_set_default_screening_status": 0.17652716592419893, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_staff_can_list_submission_screening_statuses": 0.17701066692825407, + "hypha/apply/api/v1/screening/tests/test_views.py::SubmissionScreeningStatusViewSetTests::test_user_cant_list_screening_statuses": 0.383644292014651, + "hypha/apply/api/v1/tests/test_serializers.py::TestDeliverableSerializer::test_id_is_required": 0.012257374008186162, + "hypha/apply/api/v1/tests/test_serializers.py::TestDeliverableSerializer::test_quantity_not_required": 0.1106178339687176, + "hypha/apply/api/v1/tests/test_serializers.py::TestDeliverableSerializer::test_validate_id": 0.09170537395402789, "hypha/apply/api/v1/tests/test_serializers.py::TestInvoiceRequiredChecksSerializer::test_valid_checks_link_required": 0.11694603395881131, "hypha/apply/api/v1/tests/test_serializers.py::TestInvoiceRequiredChecksSerializer::test_valid_checks_required": 0.052493724040687084, "hypha/apply/api/v1/tests/test_serializers.py::TestInvoiceRequiredChecksSerializer::test_validate_valid_checks_and_link": 0.17325492500094697, - "hypha/apply/api/v1/tests/test_serializers.py::TestReviewSummarySerializer::test_handles_negative_reviews": 53.39089049899485, - "hypha/apply/api/v1/tests/test_serializers.py::TestReviewSummarySerializer::test_handles_no_reviews": 0.08726566703990102, + "hypha/apply/api/v1/tests/test_serializers.py::TestReviewSummarySerializer::test_handles_negative_reviews": 47.900241416995414, + "hypha/apply/api/v1/tests/test_serializers.py::TestReviewSummarySerializer::test_handles_no_reviews": 0.07608712406363338, "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_can_change_visibility": 0.2947400030097924, - "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_cant_edit_if_not_author": 0.47102075000293553, - "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_does_nothing_if_same_message_and_visibility": 0.1584784589940682, - "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_edit_updates_correctly": 0.1365128338802606, - "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_incorrect_id_denied": 0.03154566593002528, - "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_out_of_order_does_nothing": 0.1728130830451846, - "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_staff_can_change_visibility": 0.1528444179566577, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_applicant_cant_add_deliverables": 0.21287220797967166, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_applicant_cant_remove_deliverables": 0.20939670910593122, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_cant_add_or_remove_wihtout_login": 0.1725520839681849, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverable_already_exists_in_invoice": 0.16973474889528006, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverable_available_gte_quantity": 0.17294012499041855, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverable_dont_exists_in_project_deliverables": 0.3154549158643931, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverables_cant_removed_after_finance2_approval": 0.22893149894662201, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance1_can_add_deliverables": 0.16282691701781005, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance1_can_remove_deliverables": 0.18649645801633596, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance1_cant_remove_deliverables_after_finance1_approval": 0.16996737418230623, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance2_can_add_deliverables": 0.1587066249921918, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance2_can_remove_deliverables": 0.19433812622446567, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_staff_can_add_deliverables": 0.1566219999222085, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_staff_can_remove_deliverables": 0.14834729093126953, - "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_staff_cant_remove_deliverables_after_staff_approval": 52.86434658290818, + "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_cant_edit_if_not_author": 0.23197316599544138, + "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_does_nothing_if_same_message_and_visibility": 0.19338529102969915, + "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_edit_updates_correctly": 0.1957722079823725, + "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_incorrect_id_denied": 0.06875616707839072, + "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_out_of_order_does_nothing": 0.21863037499133497, + "hypha/apply/api/v1/tests/test_views.py::TestCommentEdit::test_staff_can_change_visibility": 0.18349841696908697, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_applicant_cant_add_deliverables": 0.45137154194526374, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_applicant_cant_remove_deliverables": 0.17998354195151478, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_cant_add_or_remove_wihtout_login": 0.16972262400668114, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverable_already_exists_in_invoice": 0.2294130829977803, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverable_available_gte_quantity": 0.19909750000806525, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverable_dont_exists_in_project_deliverables": 0.29539158398984, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_deliverables_cant_removed_after_finance2_approval": 0.22738570807268843, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance1_can_add_deliverables": 0.19634779205080122, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance1_can_remove_deliverables": 0.21497191593516618, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance1_cant_remove_deliverables_after_finance1_approval": 0.22236529196379706, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance2_can_add_deliverables": 0.1910492920433171, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_finance2_can_remove_deliverables": 0.40230970905395225, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_staff_can_add_deliverables": 0.2188895409926772, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_staff_can_remove_deliverables": 0.19606629095505923, + "hypha/apply/api/v1/tests/test_views.py::TestInvoiceDeliverableViewset::test_staff_cant_remove_deliverables_after_staff_approval": 48.71799262496643, "hypha/apply/api/v1/tests/test_views.py::TestInvoiceRequiredChecksViewSet::test_applicant_cant_get_set_required_valid_checks": 0.6144257669802755, "hypha/apply/api/v1/tests/test_views.py::TestInvoiceRequiredChecksViewSet::test_cant_get_set_required_checks_without_login": 0.30361390503821895, "hypha/apply/api/v1/tests/test_views.py::TestInvoiceRequiredChecksViewSet::test_finance1_can_get_required_valid_checks": 0.32072118495125324, "hypha/apply/api/v1/tests/test_views.py::TestInvoiceRequiredChecksViewSet::test_finance1_can_set_required_valid_checks": 0.3616774979745969, "hypha/apply/api/v1/tests/test_views.py::TestInvoiceRequiredChecksViewSet::test_finance2_cant_get_set_required_valid_checks": 0.2886283140978776, "hypha/apply/api/v1/tests/test_views.py::TestInvoiceRequiredChecksViewSet::test_staff_cant_get_set_required_valid_checks": 0.33830336399842054, - "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_can_render_if_no_response": 0.06368333392310888, - "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_field_and_help_default": 0.011962668155319989, - "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_multi_select_disabled": 0.003674666048027575, - "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_multi_select_enabled": 0.004824416828341782, - "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_options_included_in_choices": 0.009934498928487301, - "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_supplied_field_and_help": 0.005348333972506225, - "hypha/apply/dashboard/tests/test_views.py::TestAdminDashboard::test_does_show_admin_button_to_admins": 0.3197833760641515, - "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_can_access_dashboard_with_active": 0.28440266591496766, - "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_can_have_draft_titles_on_dashboard": 0.30938212398905307, - "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_can_not_access_other_users_active": 0.17553641612175852, - "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_gets_invite_if_invited_to_proposal": 0.3157209169585258, - "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_no_edit_if_in_review": 0.23260362388100475, - "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_no_invite_if_can_edit": 0.17902404197957367, - "hypha/apply/dashboard/tests/test_views.py::TestReviewerDashboard::test_no_submissions_waiting_for_review": 0.4732738329330459, - "hypha/apply/dashboard/tests/test_views.py::TestReviewerDashboard::test_submission_assigned_but_not_in_external_review_status": 53.82880870893132, - "hypha/apply/dashboard/tests/test_views.py::TestReviewerDashboard::test_waiting_for_review_with_count": 0.444339832989499, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_active_invoices_with_invoices_in_correct_state": 0.5380933738779277, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_active_invoices_with_no_project": 0.2517163750017062, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_cannot_see_submission_in_determination_when_not_lead": 0.5979210830992088, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_doesnt_show_active_invoices_when_not_mine": 0.3928689588792622, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_doesnt_show_active_invoices_with_none": 0.40044466592371464, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_doest_show_active_invoices_when_paid_or_declined": 0.39634229301009327, + "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_can_render_if_no_response": 0.036066625034436584, + "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_field_and_help_default": 0.005301585013512522, + "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_multi_select_disabled": 0.0036877079983241856, + "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_multi_select_enabled": 0.005291416076943278, + "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_options_included_in_choices": 0.00799416605150327, + "hypha/apply/categories/tests/test_blocks.py::TestCategoryQuestionBlock::test_supplied_field_and_help": 0.008663999906275421, + "hypha/apply/dashboard/tests/test_views.py::TestAdminDashboard::test_does_show_admin_button_to_admins": 0.49195762496674433, + "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_can_access_dashboard_with_active": 0.2811352079734206, + "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_can_have_draft_titles_on_dashboard": 0.36781650001648813, + "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_can_not_access_other_users_active": 0.3000304579618387, + "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_gets_invite_if_invited_to_proposal": 0.22878554096678272, + "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_no_edit_if_in_review": 0.22108583396766335, + "hypha/apply/dashboard/tests/test_views.py::TestApplicantDashboard::test_no_invite_if_can_edit": 0.22134391695726663, + "hypha/apply/dashboard/tests/test_views.py::TestReviewerDashboard::test_no_submissions_waiting_for_review": 0.6434167079860345, + "hypha/apply/dashboard/tests/test_views.py::TestReviewerDashboard::test_submission_assigned_but_not_in_external_review_status": 48.49563883297378, + "hypha/apply/dashboard/tests/test_views.py::TestReviewerDashboard::test_waiting_for_review_with_count": 0.40596079104579985, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_active_invoices_with_invoices_in_correct_state": 0.7148654999909922, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_active_invoices_with_no_project": 0.29518508195178583, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_cannot_see_submission_in_determination_when_not_lead": 0.42824233399005607, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_doesnt_show_active_invoices_when_not_mine": 0.40279570798156783, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_doesnt_show_active_invoices_with_none": 0.3976340829394758, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_doest_show_active_invoices_when_paid_or_declined": 0.615537291043438, "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_staff_can_see_projects_awaiting_review_stats_or_table": 65.42799123498844, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_unassigned_staff_cant_see_projects_awaiting_review_stats_or_table": 0.3104223320260644, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_waiting_for_review_after_agreement_is_empty": 0.3971507509704679, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_waiting_for_review_with_count": 0.43167454190552235, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboardWithWagtailAdminAccess::test_does_show_admin_button_to_staff_with_wagtail_admin_access": 0.29581050004344434, - "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboardWithoutWagtailAdminAccess::test_doesnt_show_admin_button_to_staff_without_wagtail_admin_access": 0.5396512089064345, - "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_determination_block_required": 0.20600395905785263, - "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_field_label_required": 0.11256412602961063, - "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_form_creation": 0.10376991610974073, - "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_message_block_required": 0.12822470907121897, - "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_name_field_required": 0.2929227912100032, - "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_send_notice_block_required": 0.11331733397673815, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_can_submit_batch_determination": 1.1239819169277325, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_can_submit_batch_determination_more_info_comment": 0.8998360839905217, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_cant_access_without_action": 0.29788879211992025, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_cant_access_without_submissions": 0.15192141698207706, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_message_created_if_determination_exists": 0.7004209590377286, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_sets_next_on_redirect": 0.0201142089208588, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_success_if_no_next": 0.028741458081640303, - "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_success_redirects_if_exists": 0.0167721250327304, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_access_form_if_lead": 0.2795411248225719, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_edit_draft_determination": 0.39732999983243644, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_edit_draft_determination_if_not_lead": 0.36917637509759516, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_edit_draft_determination_if_not_lead_with_projects": 0.574998957104981, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_progress_stage_via_determination": 0.4457102088490501, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_cant_access_wrong_status": 0.3057255418971181, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_cant_edit_submitted_more_info": 0.21533391706179827, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_cant_resubmit_determination": 0.34880262485239655, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_disabling_project_auto_creation_stops_projects_being_created": 0.6254295839462429, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_disabling_projects_ignores_auto_creation_setting": 0.35022420797031373, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_first_stage_accepted_determination_does_not_create_project": 0.3951377071207389, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_first_stage_rejected_determination_does_not_create_project": 0.32274695893283933, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_second_stage_accepted_determination_creates_project": 0.5555361660663038, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_second_stage_rejected_determination_does_not_create_project": 0.3740730411373079, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_sends_message_if_requires_more_info": 53.24500287498813, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_single_stage_accepted_determination_creates_project": 0.36371379101183265, - "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_single_stage_rejected_determination_does_not_create_project": 0.4497926657786593, - "hypha/apply/determinations/tests/test_views.py::EditDeterminationFormTestCase::test_can_edit_determination": 0.4584017499582842, - "hypha/apply/determinations/tests/test_views.py::StaffDeterminationsTestCase::test_can_access_determination": 0.2628489169292152, - "hypha/apply/determinations/tests/test_views.py::StaffDeterminationsTestCase::test_lead_can_access_determination": 0.2115764160407707, - "hypha/apply/determinations/tests/test_views.py::UserDeterminationFormTestCase::test_cant_access_form": 0.192241249140352, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_active": 0.1310934571083635, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_annotated": 0.06212695804424584, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_by_lead": 0.12584670900832862, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_can_get": 0.05352362501434982, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_closed": 0.03731920791324228, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_inactive": 0.07862379110883921, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_new": 0.05332966602873057, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_no_submissions_not_either": 0.08079304208513349, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_open": 0.04613145790062845, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_with_determined": 0.10131074907258153, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_with_progress": 0.07140566606540233, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_active": 0.13352654210757464, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_annotated": 0.09856966813094914, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_by_lead": 0.1419911669800058, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_can_get": 0.07361695903819054, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_closed": 0.07386124995537102, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_inactive": 0.09993016696535051, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_new": 0.07018604106269777, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_no_submissions_not_either": 0.0725509988842532, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_open": 0.06527933396864682, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_with_determined": 0.0967254590941593, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_with_progress": 0.14043374999891967, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestRoundsAndLabsManager::test_cant_get_fund": 0.06796033203136176, - "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestRoundsAndLabsManager::test_doesnt_confuse_lab_and_round": 0.29577012616209686, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_can_save_multiple_forms_stage_two": 0.04961991612799466, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_can_save_two_forms": 0.04161399987060577, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_does_validates_without_project_approval_form": 0.015870373114012182, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_multiple_external_review_form": 0.021794166998006403, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_multiple_project_approval_form": 0.06363983312621713, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_no_form": 0.010387291200459003, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_two_first_stage_forms_in_two_stage": 0.020232082810252905, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_two_forms_one_stage": 0.034621958155184984, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validate_external_review_form": 0.02205070899799466, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validate_project_approval_form": 0.02532500005327165, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validates_with_one_form_one_stage": 0.024257375043816864, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validates_with_one_form_one_stage_with_deleted": 0.030707667116075754, - "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validates_without_external_review_form": 52.34273804188706, - "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_email_block_required": 0.2088026669807732, - "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_field_label_required": 0.149365292978473, - "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_form_creation": 0.11754074995405972, - "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_full_name_block_required": 0.40467620792333037, - "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_name_field_required": 0.14645566698163748, - "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_title_block_required": 0.16521475103218108, - "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_fund": 0.8218775829300284, - "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_fund_with_external_review_form": 0.3319704169407487, - "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_multi_phase_fund": 0.3293084999313578, - "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_multi_phase_fund_reuse_forms": 0.41299737396184355, - "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_multiple_forms_second_stage_in_fund": 0.3237355840392411, - "hypha/apply/funds/tests/test_admin_views.py::TestRoundIndexView::test_application_links": 0.24900691595394164, - "hypha/apply/funds/tests/test_admin_views.py::TestRoundIndexView::test_number_of_rounds": 0.16683674999512732, - "hypha/apply/funds/tests/test_admin_views.py::TestRoundIndexView::test_review_form_links": 0.18859074905049056, - "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_existing_reviews": 0.2270776240620762, - "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_init_and_render": 0.18790745793376118, - "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_reviewers_swap": 0.15377212490420789, - "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_roles_swap": 0.16281391610391438, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_draft_data": 0.1490496238693595, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_ordered_qs": 0.1249092509970069, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_required_block_names": 0.09873220801819116, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_reverse_ordered_qs": 0.1587739591486752, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_choices_added_for_search": 0.149843375897035, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_correct_file_path_generated": 0.09924179094377905, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_create_revision_on_create": 0.09179875091649592, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_create_revision_on_data_change": 0.0906527501065284, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_dont_create_revision_on_data_same": 0.09052220906596631, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_draft_updated": 0.11173420900013298, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_file_gets_uploaded": 0.11910374986473471, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_in_final_stage": 0.2448779579717666, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_is_draft_property": 0.09119662502780557, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_number_not_in_search": 0.08268812403548509, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_richtext_in_char_is_removed_for_search": 0.0871474581072107, - "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_richtext_is_removed_for_search": 0.10898320900741965, - "hypha/apply/funds/tests/test_models.py::TestAssignedReviewersQuerySet::test_reviewed": 0.12450108304619789, - "hypha/apply/funds/tests/test_models.py::TestAssignedReviewersQuerySet::test_reviewed_with_review_order": 0.10234258486889303, - "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_assigned_but_not_reviewed": 0.14217170898336917, - "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_disagree_review_is_maybe": 0.18134895898401737, - "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_dont_double_count_review_and_opinion": 0.20702958188485354, - "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_opinionated_slash_confused_reviewer": 0.14794070809148252, - "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_review_outcome": 0.12835533183533698, - "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_submissions_dont_conflict": 0.2732012089109048, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_associated_if_another_user_exists": 0.32096395909320563, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_associated_if_logged_in": 0.24763354193419218, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_associated_if_not_new": 0.2929042089963332, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_can_submit_if_blank_user_data_even_if_logged_in": 0.15598979103378952, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_can_submit_if_new": 0.22036704106722027, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_doesnt_mess_with_name": 0.6982206258689985, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_email_sent_to_user_on_submission_fund": 0.20850474992766976, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_email_sent_to_user_on_submission_lab": 0.1665749999228865, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_valid_email": 0.3073821240104735, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_draft": 0.1814717510715127, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_draft_lab": 0.185774251120165, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_status_assigned": 0.16890304209664464, - "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_status_assigned_lab": 0.2379047080175951, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_can_access_workflow_class": 0.042793499887920916, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_can_not_be_open_with_draft_round": 0.09543912496883422, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_closed_round": 0.07514170906506479, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_multiple_open_rounds": 0.11567800003103912, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_no_open_rounds": 0.029080708976835012, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_no_round_exists": 0.032593959011137486, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_normal_round": 0.09945729107130319, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_open_ended_round": 0.06348649994470179, - "hypha/apply/funds/tests/test_models.py::TestFundModel::test_round_not_open": 0.06429041584488004, - "hypha/apply/funds/tests/test_models.py::TestReminderModel::test_can_save_reminder": 0.14102758304215968, - "hypha/apply/funds/tests/test_models.py::TestReminderModel::test_check_default_action": 0.08828612591605633, - "hypha/apply/funds/tests/test_models.py::TestReminderModel::test_reminder_action_message": 0.09919620910659432, - "hypha/apply/funds/tests/test_models.py::TestRequestForPartners::test_form_when_round": 0.4896917912410572, - "hypha/apply/funds/tests/test_models.py::TestRequestForPartners::test_message_when_no_round": 0.05575866706203669, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_create_without_end_date": 0.10089066612999886, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_not_create_with_other_open_end_date": 0.10511479200795293, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_not_overlap_clean": 0.08662924985401332, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_not_overlap_with_normal_round": 0.09153591585345566, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_end_before_start": 0.035309332073666155, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_end_overlaps": 0.05701729201246053, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_inside_overlaps": 0.07519704196602106, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_normal_start_end_doesnt_error": 0.06965612503699958, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_other_fund_not_impacting": 0.10615220805630088, - "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_start_overlaps": 0.06443083297926933, - "hypha/apply/funds/tests/test_models.py::TestRoundModelWorkflowAndForms::test_can_change_round_form_not_fund": 0.12071304197888821, - "hypha/apply/funds/tests/test_models.py::TestRoundModelWorkflowAndForms::test_forms_are_copied_to_new_rounds": 0.06250629213172942, - "hypha/apply/funds/tests/test_models.py::TestRoundModelWorkflowAndForms::test_workflow_is_copied_to_new_rounds": 0.05548808316234499, - "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_file_private_url_included": 0.2338216241914779, - "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_named_blocks_dont_break_if_no_response": 0.10130649898201227, - "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_named_blocks_not_included_in_answers": 0.10962391598150134, - "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_normal_answers_included_in_answers": 0.10513508401345462, - "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_paragraph_not_rendered_in_answers": 0.1062420840607956, - "hypha/apply/funds/tests/test_tags.py::TestTemplateTags::test_markdown_tags": 0.006134833907708526, - "hypha/apply/funds/tests/test_tags.py::TestTemplateTags::test_submission_tags": 0.12460162513889372, - "hypha/apply/funds/tests/test_views.py::TestAnonSubmissionFileView::test_anonymous_can_not_access": 0.22671829094178975, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_edit_own_submission": 0.4169395408825949, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_see_view_determination_primary_action": 0.9132027919404209, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_submit_submission": 0.43798254092689604, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_view_own_submission": 0.30635708291083574, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_edit_other_submission": 0.40574666601605713, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_edit_submission_incorrect_state": 0.4315109169110656, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_screen_submission": 0.4150468750158325, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_add_determination_primary_action": 1.126294415909797, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_assign_reviewers_primary_action": 0.4851302499882877, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_assign_reviewers_secondary_action": 0.4752123741200194, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_create_review_primary_action": 0.6179650429403409, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_screening_status_block": 0.295956541900523, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_view_determination_primary_action": 0.6678542509907857, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_view_others_submission": 0.35142612585332245, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_get_congratulations_draft_proposal": 0.58507999998983, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_get_edit_link_when_editable": 0.4418560831109062, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_gets_draft_on_edit_submission": 0.5373793760081753, - "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_sees_latest_draft_if_it_exists": 0.5016270420746878, - "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_applicant_cannot_access_reviewer_leaderboard": 0.06163133401423693, - "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_community_reviewer_cannot_access_reviewer_leaderboard": 0.039557207841426134, - "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_partner_cannot_access_reviewer_leaderboard": 0.07404641690663993, - "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_reviewer_cannot_access_leader_board": 0.049408251070417464, - "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_staff_can_access_leaderboard": 0.11858241609297693, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_access_any_submission": 0.3128672499442473, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_accepted_submission": 0.5845487498445436, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_assigned_submission": 0.6517927489476278, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_external_review_or_higher_submission": 0.44838800095021725, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_reviewed_submission": 0.2901558759622276, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_see_create_review_primary_action": 0.562187749077566, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_see_view_determination_primary_action": 0.7028081668540835, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_access_dismissed_submission": 0.34087837510742247, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_add_determination_primary_action": 0.5245875420514494, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_assign_reviewers_primary_action": 0.22818424890283495, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_assign_reviewers_secondary_action": 0.2603712920099497, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_create_review_primary_action": 1.0149275419535115, - "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_view_determination_primary_action": 0.41726491693407297, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_can_add_external_reviewer_and_review_remains": 0.8257489589741454, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_can_be_made_role_and_not_duplciated": 0.45144966698717326, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_can_remove_external_reviewer_and_review_remains": 0.5620815821457654, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_add_reviewers_for_proposal": 0.4873921659309417, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_add_staff_single": 0.6824569570599124, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_change_role_reviewer_and_review_remains": 0.4493671261006966, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_change_staff_single": 0.4770331662148237, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_remove_reviewers_for_proposal": 0.746842457097955, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_remove_some_reviewers_for_proposal": 0.5127480837982148, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_cant_add_reviewers_single": 0.4263467499986291, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_staff_cant_add_reviewers_proposal": 0.4620940409367904, - "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_staff_cant_remove_reviewers_proposal": 0.8137773340567946, - "hypha/apply/funds/tests/test_views.py::TestRevisionCompare::test_renders_with_all_the_diffs": 0.3248190419981256, - "hypha/apply/funds/tests/test_views.py::TestRevisionList::test_get_in_correct_order": 0.497798457974568, - "hypha/apply/funds/tests/test_views.py::TestRevisionList::test_list_doesnt_include_draft": 0.34488670888822526, - "hypha/apply/funds/tests/test_views.py::TestRevisionsView::test_create_revisions_on_submit": 0.38965708296746016, - "hypha/apply/funds/tests/test_views.py::TestRevisionsView::test_dont_update_live_revision_on_save": 0.32660966797266155, - "hypha/apply/funds/tests/test_views.py::TestRevisionsView::test_existing_draft_edit_and_submit": 0.7188656670041382, - "hypha/apply/funds/tests/test_views.py::TestStaffReminderDeleteView::test_confirm_message": 0.43140212597791106, - "hypha/apply/funds/tests/test_views.py::TestStaffReminderDeleteView::test_has_access": 0.1736859999364242, - "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_cant_post_to_sealed": 0.3140248339623213, - "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_non_sealed_redirected_away": 0.3367313339840621, - "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_non_sealed_unaffected": 0.35245737596414983, - "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_redirected_to_sealed": 0.4905905839987099, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionFileView::test_staff_can_access": 0.1999512080801651, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_applicant_can_see_application_draft_status": 0.27073320804629475, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_access_edit": 0.32954245805740356, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_access_edit_button": 0.37549454101826996, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_create_project": 0.3760909589473158, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_edit_submission": 0.5899402508512139, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_progress_phase": 0.39777112391311675, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_screen_submission": 0.3471504159970209, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_add_determination_primary_action": 0.7420900000724941, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_assign_reviewers_primary_action": 1.4845561670372263, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_assign_reviewers_secondary_action": 1.2371138751041144, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_create_review_primary_action": 1.4618289999198169, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_view_determination_primary_action": 1.107450666022487, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_view_a_lab_submission": 0.41783874994143844, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_view_a_submission": 0.3368598339147866, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_view_submission_screening_block": 0.344336625887081, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_access_edit_button_when_applicant_editing": 0.4187689999816939, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_progress_stage_if_not_lead": 0.40149033395573497, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_add_determination_primary_action": 1.471973832929507, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_application_draft_status": 0.2396007931092754, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_assign_reviewers_primary_action": 0.9687096660491079, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_create_review_primary_action": 1.8450221660314128, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_view_determination_primary_action": 1.101752792019397, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_view_submission_screening_block": 0.3147491249255836, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_new_form_after_progress": 0.24671399989165366, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_not_included_fields_render": 0.4018669999204576, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_not_redirected_if_determination_submitted": 0.42448441800661385, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_not_redirected_if_wrong_determination_selected": 0.49752758303657174, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_previous_and_next_appears_on_page": 0.9396503329044208, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_redirected_to_determination": 0.3322940430371091, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_screen_application_primary_action_is_displayed": 0.315706167020835, - "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_screen_application_primary_action_is_not_displayed": 0.3573770399671048, - "hypha/apply/funds/tests/test_views.py::TestSubmissionDetailSimplifiedView::test_project_required": 0.1321598341455683, - "hypha/apply/funds/tests/test_views.py::TestSubmissionDetailSimplifiedView::test_staff_only": 0.12134012510068715, - "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_can_post_to_sealed": 0.4207257080124691, - "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_can_view_multiple_sealed": 0.9063680830877274, - "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_not_asked_again": 0.5518010839587077, - "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_peeking_is_logged": 0.3346030409447849, - "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_redirected_to_sealed": 0.2140774989966303, - "hypha/apply/funds/tests/test_views.py::TestSuperUserSubmissionView::test_can_screen_applications_in_final_status": 0.7690585830714554, - "hypha/apply/funds/tests/test_views.py::TestSuperUserSubmissionView::test_can_screen_submission": 0.38334191718604416, - "hypha/apply/funds/tests/test_views.py::TestUpdateReviewersMixin::test_submission_transition_all_reviewer_roles_not_assigned": 0.484276499832049, - "hypha/apply/funds/tests/test_views.py::TestUpdateReviewersMixin::test_submission_transition_to_internal_review": 0.5740112499333918, - "hypha/apply/funds/tests/test_views.py::TestUpdateReviewersMixin::test_submission_transition_to_proposal_internal_review": 0.4810352091444656, - "hypha/apply/funds/tests/test_views.py::TestUserReminderDeleteView::test_doesnt_has_access": 0.23820854211226106, - "hypha/apply/funds/tests/test_views.py::TestUserSubmissionFileView::test_owner_can_access": 0.15925191692076623, - "hypha/apply/funds/tests/test_views.py::TestUserSubmissionFileView::test_user_can_not_access": 0.14730862504802644, - "hypha/apply/funds/tests/views/test_batch_progress.py::ApplicantTestCase::test_cant_access_page_to_page": 0.08610325097106397, - "hypha/apply/funds/tests/views/test_batch_progress.py::ReivewersTestCase::test_cant_post_to_page": 0.3608955009840429, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_application": 0.45370379206724465, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_different_states": 0.5506767920451239, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_multiple_applications": 0.9527829589787871, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_one_in_mixed_state": 0.49793162394780666, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_cant_progress_in_incorrect_state": 0.3299887500470504, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_determine_redirects": 0.2182419589953497, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_messenger_not_called_with_failed": 0.3004915409255773, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_messenger_with_submission_in_review": 0.3768535410054028, - "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_mixed_determine_notifies": 0.37122058297973126, - "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_can_assign_role_reviewers": 0.9108087500790134, - "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_can_reassign_from_other_role_reviewers": 0.7777726660715416, - "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_can_reassign_role_reviewers": 0.7799941239645705, - "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_doesnt_remove_if_already_reviewed": 1.0364358740625903, - "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantRoundPage::test_cant_access_page": 0.08234191790688783, - "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_lab_page": 0.12256012472789735, - "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_non_existing_page": 0.044570248923264444, - "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_normal_page": 0.15356200106907636, - "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_round_page": 0.13131941703613847, - "hypha/apply/funds/tests/views/test_rounds.py::TestReviewerAllRoundPage::test_cant_access_page": 0.08593399997334927, - "hypha/apply/funds/tests/views/test_rounds.py::TestStaffRoundPage::test_can_access_page": 0.14833616698160768, - "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_can_access_lab_page": 0.2737620830303058, - "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_can_access_round_page": 0.45550508389715105, - "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_cant_access_non_existing_page": 0.07584341603796929, - "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_cant_access_normal_page": 0.14374800096265972, - "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_already_notified": 0.19513545895460993, - "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_project_complete": 0.13409304106608033, - "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_project_not_in_progress": 0.12156212504487485, - "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_report_due_in_7_days_already_submitted": 0.125589668052271, - "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_notify_report_due_in_7_days": 0.1717857918702066, - "hypha/apply/projects/tests/test_files.py::TestFlatten::test_no_items": 0.00656904187053442, - "hypha/apply/projects/tests/test_files.py::TestFlatten::test_one_level_of_items": 0.0012798751704394817, - "hypha/apply/projects/tests/test_files.py::TestFlatten::test_three_levels_of_items": 0.000812293030321598, - "hypha/apply/projects/tests/test_files.py::TestFlatten::test_two_levels_of_items": 0.0011532080825418234, - "hypha/apply/projects/tests/test_files.py::TestGetFiles::test_get_files": 0.1295463329879567, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_approved_by_finance1_status": 0.14656220795586705, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_approved_by_finance1_status_with_extended_flow": 0.13236879208125174, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_approved_by_staff_status": 0.14808366796933115, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_changes_requested_by_finance1_status": 0.1682244180701673, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_changes_requested_by_finance2_status": 0.1424597919685766, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_changes_requested_by_staff_status": 0.11559129203669727, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_resubmitted_status": 0.12777604104485363, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_submitted_status": 0.12977958307601511, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_approved_by_finance1_status": 0.13142820808570832, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_approved_by_staff_status": 0.11266949994023889, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_changes_requested_by_finance1_status": 0.14685695804655552, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_changes_requested_by_finance2_status": 0.12137499975506216, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_changes_requested_by_staff_status": 0.17739116703160107, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_resubmitted_status": 0.15250520908739418, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_submitted_status": 0.13672062510158867, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_approved_by_finance1_status": 0.1357324169948697, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_approved_by_staff_status": 0.15583287389017642, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_changes_requested_by_finance1_status": 0.1764742910163477, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_changes_requested_by_finance2_status": 0.1542377930600196, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_changes_requested_by_staff_status": 0.13213195896241814, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_resubmitted_status": 0.16957866703160107, - "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_submitted_status": 0.1503189168870449, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_unassigned_staff_cant_see_projects_awaiting_review_stats_or_table": 0.37664666696218774, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_waiting_for_review_after_agreement_is_empty": 0.48306254198541865, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboard::test_waiting_for_review_with_count": 0.4347812499618158, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboardWithWagtailAdminAccess::test_does_show_admin_button_to_staff_with_wagtail_admin_access": 0.3449161669705063, + "hypha/apply/dashboard/tests/test_views.py::TestStaffDashboardWithoutWagtailAdminAccess::test_doesnt_show_admin_button_to_staff_without_wagtail_admin_access": 0.3654038340318948, + "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_determination_block_required": 0.2471973320352845, + "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_field_label_required": 0.1337144589633681, + "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_form_creation": 0.12094916601199657, + "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_message_block_required": 0.14209624903742224, + "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_name_field_required": 0.1370073760044761, + "hypha/apply/determinations/tests/test_admin_views.py::TestCreateDeterminationFormView::test_send_notice_block_required": 0.13266274897614494, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_can_submit_batch_determination": 0.8987592090270482, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_can_submit_batch_determination_more_info_comment": 1.093036290956661, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_cant_access_without_action": 0.347631124954205, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_cant_access_without_submissions": 0.20394562499132007, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_message_created_if_determination_exists": 0.7172249159193598, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_sets_next_on_redirect": 0.008022917027119547, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_success_if_no_next": 0.007694582978729159, + "hypha/apply/determinations/tests/test_views.py::BatchDeterminationTestCase::test_success_redirects_if_exists": 0.010707416979130358, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_access_form_if_lead": 0.2652022919501178, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_edit_draft_determination": 0.4181396669591777, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_edit_draft_determination_if_not_lead": 0.3539232490584254, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_edit_draft_determination_if_not_lead_with_projects": 0.5771515830419958, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_can_progress_stage_via_determination": 0.42698445898713544, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_cant_access_wrong_status": 0.31131741689750925, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_cant_edit_submitted_more_info": 0.23528062499826774, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_cant_resubmit_determination": 0.6146564569789916, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_disabling_project_auto_creation_stops_projects_being_created": 0.39776529202936217, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_disabling_projects_ignores_auto_creation_setting": 0.3460802079644054, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_first_stage_accepted_determination_does_not_create_project": 0.6698565829428844, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_first_stage_rejected_determination_does_not_create_project": 0.364047082955949, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_second_stage_accepted_determination_creates_project": 0.4194268750725314, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_second_stage_rejected_determination_does_not_create_project": 0.35257112502586097, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_sends_message_if_requires_more_info": 47.620870457962155, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_single_stage_accepted_determination_creates_project": 0.3583696250570938, + "hypha/apply/determinations/tests/test_views.py::DeterminationFormTestCase::test_single_stage_rejected_determination_does_not_create_project": 0.4159843750530854, + "hypha/apply/determinations/tests/test_views.py::EditDeterminationFormTestCase::test_can_edit_determination": 0.42473558406345546, + "hypha/apply/determinations/tests/test_views.py::StaffDeterminationsTestCase::test_can_access_determination": 0.5007752500241622, + "hypha/apply/determinations/tests/test_views.py::StaffDeterminationsTestCase::test_lead_can_access_determination": 0.1905933739617467, + "hypha/apply/determinations/tests/test_views.py::UserDeterminationFormTestCase::test_cant_access_form": 0.19667095900513232, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_active": 0.08821174898184836, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_annotated": 0.03754920797655359, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_by_lead": 0.10936633206438273, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_can_get": 0.0375667919870466, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_closed": 0.034341249091085047, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_inactive": 0.06411208200734109, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_new": 0.0544566250173375, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_no_submissions_not_either": 0.03846766601782292, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_open": 0.037716708960942924, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_with_determined": 0.07131629198556766, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForLab::test_with_progress": 0.11110420897603035, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_active": 0.12810854200506583, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_annotated": 0.06556995899882168, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_by_lead": 0.11274895904352888, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_can_get": 0.060377124056685716, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_closed": 0.06118266697740182, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_inactive": 0.09110883297398686, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_new": 0.07164266600739211, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_no_submissions_not_either": 0.08204616693546996, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_open": 0.056571834022179246, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_with_determined": 0.09481474896892905, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestForRound::test_with_progress": 0.1226185419363901, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestRoundsAndLabsManager::test_cant_get_fund": 0.0459559999871999, + "hypha/apply/funds/tests/models/test_roundsandlabs.py::TestRoundsAndLabsManager::test_doesnt_confuse_lab_and_round": 0.22479037498123944, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_can_save_multiple_forms_stage_two": 0.0538997920230031, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_can_save_two_forms": 0.03590929199708626, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_does_validates_without_project_approval_form": 0.018417084007523954, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_multiple_external_review_form": 0.021515125001315027, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_multiple_project_approval_form": 0.055025165958795696, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_no_form": 0.009529665927402675, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_two_first_stage_forms_in_two_stage": 0.026386706973426044, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_doesnt_validates_with_two_forms_one_stage": 0.019531042024027556, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validate_external_review_form": 0.018824083963409066, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validate_project_approval_form": 0.030170165933668613, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validates_with_one_form_one_stage": 0.021481460018549114, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validates_with_one_form_one_stage_with_deleted": 0.02069579006638378, + "hypha/apply/funds/tests/test_admin_form.py::TestWorkflowFormAdminForm::test_validates_without_external_review_form": 48.361528916924726, + "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_email_block_required": 0.23669929197058082, + "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_field_label_required": 0.4264394990168512, + "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_form_creation": 0.1255045419675298, + "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_full_name_block_required": 0.21778983401600271, + "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_name_field_required": 0.16521474899491295, + "hypha/apply/funds/tests/test_admin_views.py::TestCreateApplicationFormView::test_title_block_required": 0.18796995794400573, + "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_fund": 0.5163307920447551, + "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_fund_with_external_review_form": 0.3089608349255286, + "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_multi_phase_fund": 0.6428762489231303, + "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_multi_phase_fund_reuse_forms": 0.32680133398389444, + "hypha/apply/funds/tests/test_admin_views.py::TestFundCreationView::test_can_create_multiple_forms_second_stage_in_fund": 0.38245924992952496, + "hypha/apply/funds/tests/test_admin_views.py::TestRoundIndexView::test_application_links": 0.23710004199529067, + "hypha/apply/funds/tests/test_admin_views.py::TestRoundIndexView::test_number_of_rounds": 0.19798845698824152, + "hypha/apply/funds/tests/test_admin_views.py::TestRoundIndexView::test_review_form_links": 0.19360833300743252, + "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_existing_reviews": 0.19348304194863886, + "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_init_and_render": 0.164736126025673, + "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_reviewers_swap": 0.16794008301803842, + "hypha/apply/funds/tests/test_forms.py::TestReviewerFormQueries::test_queries_roles_swap": 0.13378891604952514, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_draft_data": 0.14817379205487669, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_ordered_qs": 0.13801383302779868, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_required_block_names": 0.09193337493343279, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_can_get_reverse_ordered_qs": 0.10779045801609755, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_choices_added_for_search": 0.0961629580706358, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_correct_file_path_generated": 0.08538674999726936, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_create_revision_on_create": 0.12477433402091265, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_create_revision_on_data_change": 0.10634450102224946, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_dont_create_revision_on_data_same": 0.100119165959768, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_draft_updated": 0.14161733293440193, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_file_gets_uploaded": 0.12744712503626943, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_in_final_stage": 0.2055488329497166, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_is_draft_property": 0.11940320703433827, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_number_not_in_search": 0.08931800007121637, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_richtext_in_char_is_removed_for_search": 0.12436804198659956, + "hypha/apply/funds/tests/test_models.py::TestApplicationSubmission::test_richtext_is_removed_for_search": 0.1070792090613395, + "hypha/apply/funds/tests/test_models.py::TestAssignedReviewersQuerySet::test_reviewed": 0.11055675003444776, + "hypha/apply/funds/tests/test_models.py::TestAssignedReviewersQuerySet::test_reviewed_with_review_order": 0.1212779990164563, + "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_assigned_but_not_reviewed": 0.14393537596333772, + "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_disagree_review_is_maybe": 0.17617041704943404, + "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_dont_double_count_review_and_opinion": 0.15912662399932742, + "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_opinionated_slash_confused_reviewer": 0.1075845840969123, + "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_review_outcome": 0.12516620801761746, + "hypha/apply/funds/tests/test_models.py::TestForTableQueryset::test_submissions_dont_conflict": 0.2523494170163758, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_associated_if_another_user_exists": 0.3300747080356814, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_associated_if_logged_in": 0.169607832969632, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_associated_if_not_new": 0.27457179204793647, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_can_submit_if_blank_user_data_even_if_logged_in": 0.13648795802146196, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_can_submit_if_new": 0.16187208297196776, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_doesnt_mess_with_name": 0.2510277080582455, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_email_sent_to_user_on_submission_fund": 0.2040719169890508, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_email_sent_to_user_on_submission_lab": 0.18573704094160348, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_valid_email": 0.24251300003379583, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_draft": 0.19095224904594943, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_draft_lab": 0.160813957976643, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_status_assigned": 0.1561506660655141, + "hypha/apply/funds/tests/test_models.py::TestFormSubmission::test_workflow_and_status_assigned_lab": 0.13647924998076633, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_can_access_workflow_class": 0.05282920692116022, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_can_not_be_open_with_draft_round": 0.06382033205591142, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_closed_round": 0.059609292016830295, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_multiple_open_rounds": 0.10447883396409452, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_no_open_rounds": 0.03223233396420255, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_no_round_exists": 0.019256207975558937, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_normal_round": 0.11261362594086677, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_open_ended_round": 0.06533554097404703, + "hypha/apply/funds/tests/test_models.py::TestFundModel::test_round_not_open": 0.05114937399048358, + "hypha/apply/funds/tests/test_models.py::TestReminderModel::test_can_save_reminder": 0.10578825004631653, + "hypha/apply/funds/tests/test_models.py::TestReminderModel::test_check_default_action": 0.09030404192162678, + "hypha/apply/funds/tests/test_models.py::TestReminderModel::test_reminder_action_message": 0.09281583403935656, + "hypha/apply/funds/tests/test_models.py::TestRequestForPartners::test_form_when_round": 0.27410662395413965, + "hypha/apply/funds/tests/test_models.py::TestRequestForPartners::test_message_when_no_round": 0.08773758402094245, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_create_without_end_date": 0.07778404100099578, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_not_create_with_other_open_end_date": 0.10365545901004225, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_not_overlap_clean": 0.0764989159652032, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_can_not_overlap_with_normal_round": 0.09141387604176998, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_end_before_start": 0.034462166018784046, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_end_overlaps": 0.06619212403893471, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_inside_overlaps": 0.07186312502017245, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_normal_start_end_doesnt_error": 0.04751320800278336, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_other_fund_not_impacting": 0.13839333306532353, + "hypha/apply/funds/tests/test_models.py::TestRoundModelDates::test_start_overlaps": 0.08277758298208937, + "hypha/apply/funds/tests/test_models.py::TestRoundModelWorkflowAndForms::test_can_change_round_form_not_fund": 0.09724791703047231, + "hypha/apply/funds/tests/test_models.py::TestRoundModelWorkflowAndForms::test_forms_are_copied_to_new_rounds": 0.06082012504339218, + "hypha/apply/funds/tests/test_models.py::TestRoundModelWorkflowAndForms::test_workflow_is_copied_to_new_rounds": 0.06077770801493898, + "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_file_private_url_included": 0.1323906669858843, + "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_named_blocks_dont_break_if_no_response": 0.0864520839531906, + "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_named_blocks_not_included_in_answers": 0.09695274994010106, + "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_normal_answers_included_in_answers": 0.10001158399973065, + "hypha/apply/funds/tests/test_models.py::TestSubmissionRenderMethods::test_paragraph_not_rendered_in_answers": 0.11938187503255904, + "hypha/apply/funds/tests/test_tags.py::TestTemplateTags::test_markdown_tags": 0.01744779199361801, + "hypha/apply/funds/tests/test_tags.py::TestTemplateTags::test_submission_tags": 0.1305782090057619, + "hypha/apply/funds/tests/test_views.py::TestAnonSubmissionFileView::test_anonymous_can_not_access": 0.24070762598421425, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_edit_own_submission": 0.7094494999619201, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_see_view_determination_primary_action": 0.7554237499716692, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_submit_submission": 0.46202258398989215, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_can_view_own_submission": 0.3816945409635082, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_edit_other_submission": 0.42644787492463365, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_edit_submission_incorrect_state": 0.45967287599341944, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_screen_submission": 0.3974973341100849, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_add_determination_primary_action": 1.0543237089877948, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_assign_reviewers_primary_action": 0.41607945901341736, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_assign_reviewers_secondary_action": 0.42971941706491634, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_create_review_primary_action": 0.5564686259604059, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_screening_status_block": 0.5897678749752231, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_see_view_determination_primary_action": 0.6243275409797207, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_cant_view_others_submission": 0.3719659579801373, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_get_congratulations_draft_proposal": 0.3450066659715958, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_get_edit_link_when_editable": 0.49088912596926093, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_gets_draft_on_edit_submission": 0.5591084999614395, + "hypha/apply/funds/tests/test_views.py::TestApplicantSubmissionView::test_sees_latest_draft_if_it_exists": 0.7017644589650445, + "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_applicant_cannot_access_reviewer_leaderboard": 0.10273800004506484, + "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_community_reviewer_cannot_access_reviewer_leaderboard": 0.07304925000062212, + "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_partner_cannot_access_reviewer_leaderboard": 0.08130179200088605, + "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_reviewer_cannot_access_leader_board": 0.07935400103451684, + "hypha/apply/funds/tests/test_views.py::TestReviewerLeaderboard::test_staff_can_access_leaderboard": 0.20759108295897022, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_access_any_submission": 0.4016657070023939, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_accepted_submission": 0.6824897499755025, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_assigned_submission": 0.6668082919786684, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_external_review_or_higher_submission": 0.33893716789316386, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_only_access_reviewed_submission": 0.2681330419727601, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_see_create_review_primary_action": 0.5043630420113914, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_can_see_view_determination_primary_action": 0.7249346659518778, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_access_dismissed_submission": 0.3675867090350948, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_add_determination_primary_action": 0.55346120899776, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_assign_reviewers_primary_action": 0.30351766699459404, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_assign_reviewers_secondary_action": 0.2750765840173699, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_create_review_primary_action": 1.0963659989647567, + "hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView::test_cant_see_view_determination_primary_action": 0.5298776669660583, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_can_add_external_reviewer_and_review_remains": 0.6534512920188718, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_can_be_made_role_and_not_duplciated": 0.6818339169840328, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_can_remove_external_reviewer_and_review_remains": 0.5081400409690104, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_add_reviewers_for_proposal": 0.490133750019595, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_add_staff_single": 0.7280000840546563, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_change_role_reviewer_and_review_remains": 0.4881212509935722, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_change_staff_single": 0.4469773330492899, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_remove_reviewers_for_proposal": 0.4973102919757366, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_can_remove_some_reviewers_for_proposal": 0.7982138749794103, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_lead_cant_add_reviewers_single": 0.4260078339721076, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_staff_cant_add_reviewers_proposal": 0.4538681259728037, + "hypha/apply/funds/tests/test_views.py::TestReviewersUpdateView::test_staff_cant_remove_reviewers_proposal": 0.662929292069748, + "hypha/apply/funds/tests/test_views.py::TestRevisionCompare::test_renders_with_all_the_diffs": 0.5615033330395818, + "hypha/apply/funds/tests/test_views.py::TestRevisionList::test_get_in_correct_order": 0.5671977919409983, + "hypha/apply/funds/tests/test_views.py::TestRevisionList::test_list_doesnt_include_draft": 0.5241635830607265, + "hypha/apply/funds/tests/test_views.py::TestRevisionsView::test_create_revisions_on_submit": 0.4087889169459231, + "hypha/apply/funds/tests/test_views.py::TestRevisionsView::test_dont_update_live_revision_on_save": 0.33236058393958956, + "hypha/apply/funds/tests/test_views.py::TestRevisionsView::test_existing_draft_edit_and_submit": 0.5503149580326863, + "hypha/apply/funds/tests/test_views.py::TestStaffReminderDeleteView::test_confirm_message": 0.25645725103095174, + "hypha/apply/funds/tests/test_views.py::TestStaffReminderDeleteView::test_has_access": 0.23424820799846202, + "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_cant_post_to_sealed": 0.3014831249602139, + "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_non_sealed_redirected_away": 0.3376392510253936, + "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_non_sealed_unaffected": 0.40321325103286654, + "hypha/apply/funds/tests/test_views.py::TestStaffSealedView::test_redirected_to_sealed": 0.25951958494260907, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionFileView::test_staff_can_access": 0.244705916964449, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_applicant_can_see_application_draft_status": 0.2793214999837801, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_access_edit": 0.32853466598317027, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_access_edit_button": 0.38707658293424174, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_create_project": 0.31167029205244035, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_edit_submission": 0.6582669579656795, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_progress_phase": 0.4329052090179175, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_screen_submission": 0.3705467500258237, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_add_determination_primary_action": 0.8753968750243075, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_assign_reviewers_primary_action": 1.4947197499568574, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_assign_reviewers_secondary_action": 1.1712304589455016, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_create_review_primary_action": 1.1885729159694165, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_see_view_determination_primary_action": 1.0778108329395764, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_view_a_lab_submission": 0.4490732910344377, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_view_a_submission": 0.5647438760497607, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_can_view_submission_screening_block": 0.35359595803311095, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_access_edit_button_when_applicant_editing": 0.44850229198345914, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_progress_stage_if_not_lead": 0.4024465829716064, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_add_determination_primary_action": 1.423444250074681, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_application_draft_status": 0.22235716693103313, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_assign_reviewers_primary_action": 0.909417667076923, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_create_review_primary_action": 1.7061413750634529, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_see_view_determination_primary_action": 1.068954583024606, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_cant_view_submission_screening_block": 0.35347691597416997, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_new_form_after_progress": 0.2573237919714302, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_not_included_fields_render": 0.4275856660096906, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_not_redirected_if_determination_submitted": 0.65102858399041, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_not_redirected_if_wrong_determination_selected": 0.456320375087671, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_previous_and_next_appears_on_page": 0.6819471660419367, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_redirected_to_determination": 0.3450114580336958, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_screen_application_primary_action_is_displayed": 0.6308084579068236, + "hypha/apply/funds/tests/test_views.py::TestStaffSubmissionView::test_screen_application_primary_action_is_not_displayed": 0.3791784590575844, + "hypha/apply/funds/tests/test_views.py::TestSubmissionDetailSimplifiedView::test_project_required": 0.173337708984036, + "hypha/apply/funds/tests/test_views.py::TestSubmissionDetailSimplifiedView::test_staff_only": 0.11854575097095221, + "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_can_post_to_sealed": 0.7018020419636741, + "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_can_view_multiple_sealed": 0.6127214579610154, + "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_not_asked_again": 0.7633375010918826, + "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_peeking_is_logged": 0.3982291250140406, + "hypha/apply/funds/tests/test_views.py::TestSuperUserSealedView::test_redirected_to_sealed": 0.3025822100462392, + "hypha/apply/funds/tests/test_views.py::TestSuperUserSubmissionView::test_can_screen_applications_in_final_status": 0.5209657500381581, + "hypha/apply/funds/tests/test_views.py::TestSuperUserSubmissionView::test_can_screen_submission": 0.658688958035782, + "hypha/apply/funds/tests/test_views.py::TestUpdateReviewersMixin::test_submission_transition_all_reviewer_roles_not_assigned": 0.6442338328924961, + "hypha/apply/funds/tests/test_views.py::TestUpdateReviewersMixin::test_submission_transition_to_internal_review": 0.4375836249673739, + "hypha/apply/funds/tests/test_views.py::TestUpdateReviewersMixin::test_submission_transition_to_proposal_internal_review": 0.46655004197964445, + "hypha/apply/funds/tests/test_views.py::TestUserReminderDeleteView::test_doesnt_has_access": 0.409164208045695, + "hypha/apply/funds/tests/test_views.py::TestUserSubmissionFileView::test_owner_can_access": 0.2037353749619797, + "hypha/apply/funds/tests/test_views.py::TestUserSubmissionFileView::test_user_can_not_access": 0.22563641698798165, + "hypha/apply/funds/tests/views/test_batch_progress.py::ApplicantTestCase::test_cant_access_page_to_page": 0.11944358301116154, + "hypha/apply/funds/tests/views/test_batch_progress.py::ReivewersTestCase::test_cant_post_to_page": 0.36338904191507027, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_application": 0.7609355000313371, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_different_states": 0.5602312499540858, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_multiple_applications": 0.7270860420539975, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_can_progress_one_in_mixed_state": 0.5117592929746024, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_cant_progress_in_incorrect_state": 0.580062416032888, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_determine_redirects": 0.28385725006228313, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_messenger_not_called_with_failed": 0.36575408198405057, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_messenger_with_submission_in_review": 0.36334370903205127, + "hypha/apply/funds/tests/views/test_batch_progress.py::StaffTestCase::test_mixed_determine_notifies": 0.36032479105051607, + "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_can_assign_role_reviewers": 0.8074726249324158, + "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_can_reassign_from_other_role_reviewers": 1.036929707042873, + "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_can_reassign_role_reviewers": 0.7294273339794017, + "hypha/apply/funds/tests/views/test_batch_reviewers.py::StaffTestCase::test_doesnt_remove_if_already_reviewed": 0.8322332900133915, + "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantRoundPage::test_cant_access_page": 0.3773946659639478, + "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_lab_page": 0.17087579105282202, + "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_non_existing_page": 0.2679556249640882, + "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_normal_page": 0.14955275104148313, + "hypha/apply/funds/tests/views/test_rounds.py::TestApplicantSubmissionByRound::test_cant_access_round_page": 0.15875099902041256, + "hypha/apply/funds/tests/views/test_rounds.py::TestReviewerAllRoundPage::test_cant_access_page": 0.11560741602443159, + "hypha/apply/funds/tests/views/test_rounds.py::TestStaffRoundPage::test_can_access_page": 0.17996933305403218, + "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_can_access_lab_page": 0.31209162500454113, + "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_can_access_round_page": 0.2757782920380123, + "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_cant_access_non_existing_page": 0.10850608302280307, + "hypha/apply/funds/tests/views/test_rounds.py::TestStaffSubmissionByRound::test_cant_access_normal_page": 0.19533950107870623, + "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_already_notified": 0.18685820797691122, + "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_project_complete": 0.10539766697911546, + "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_project_not_in_progress": 0.10482662497088313, + "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_dont_notify_report_due_in_7_days_already_submitted": 0.18442729103844613, + "hypha/apply/projects/tests/test_commands.py::TestNotifyReportDue::test_notify_report_due_in_7_days": 0.13636937498813495, + "hypha/apply/projects/tests/test_files.py::TestFlatten::test_no_items": 0.005671833001542836, + "hypha/apply/projects/tests/test_files.py::TestFlatten::test_one_level_of_items": 0.0005060419207438827, + "hypha/apply/projects/tests/test_files.py::TestFlatten::test_three_levels_of_items": 0.0010021249763667583, + "hypha/apply/projects/tests/test_files.py::TestFlatten::test_two_levels_of_items": 0.0016584160039201379, + "hypha/apply/projects/tests/test_files.py::TestGetFiles::test_get_files": 0.14279512502253056, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_approved_by_finance1_status": 0.16588400094769895, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_approved_by_finance1_status_with_extended_flow": 0.1320433330256492, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_approved_by_staff_status": 0.13338145799934864, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_changes_requested_by_finance1_status": 0.0969262930448167, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_changes_requested_by_finance2_status": 0.15330187493236735, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_changes_requested_by_staff_status": 0.11806950002210215, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_resubmitted_status": 0.13932912598829716, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance1_choices_with_submitted_status": 0.14899625006364658, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_approved_by_finance1_status": 0.12847608391894028, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_approved_by_staff_status": 0.14547262497944757, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_changes_requested_by_finance1_status": 0.14052074996288866, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_changes_requested_by_finance2_status": 0.10986804100684822, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_changes_requested_by_staff_status": 0.12273612595163286, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_resubmitted_status": 0.11824754200642928, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_finance2_choices_with_submitted_status": 0.1264552510692738, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_approved_by_finance1_status": 0.1518614999949932, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_approved_by_staff_status": 0.13292975001968443, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_changes_requested_by_finance1_status": 0.13289824995445088, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_changes_requested_by_finance2_status": 0.11046295805135742, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_changes_requested_by_staff_status": 0.1264052088954486, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_resubmitted_status": 0.12441687507089227, + "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_staff_choices_with_submitted_status": 0.12730520905461162, "hypha/apply/projects/tests/test_forms.py::TestChangeInvoiceStatusFormForm::test_valid_checks_required_for_approved_by_finance1": 0.14640300802420825, - "hypha/apply/projects/tests/test_forms.py::TestChangePAFStatusForm::test_comment_is_not_required": 0.19300870806910098, - "hypha/apply/projects/tests/test_forms.py::TestChangePAFStatusForm::test_paf_status_is_required": 0.15398145886138082, + "hypha/apply/projects/tests/test_forms.py::TestChangePAFStatusForm::test_comment_is_not_required": 0.1718307089759037, + "hypha/apply/projects/tests/test_forms.py::TestChangePAFStatusForm::test_paf_status_is_required": 0.12084329198114574, "hypha/apply/projects/tests/test_forms.py::TestChangePAFStatusForm::test_role_is_required": 0.27957526297541335, - "hypha/apply/projects/tests/test_forms.py::TestContractUploadForm::test_applicant_can_upload_signed": 0.012523707933723927, - "hypha/apply/projects/tests/test_forms.py::TestContractUploadForm::test_applicant_cant_upload_unsigned": 0.0015236668987199664, - "hypha/apply/projects/tests/test_forms.py::TestCreateInvoiceForm::test_adding_invoice": 0.20054199907463044, - "hypha/apply/projects/tests/test_forms.py::TestCreateInvoiceForm::test_supporting_documents_not_required": 0.13114958407822996, - "hypha/apply/projects/tests/test_forms.py::TestEditInvoiceForm::test_add_new_supporting_document": 0.18472599901724607, - "hypha/apply/projects/tests/test_forms.py::TestEditInvoiceForm::test_keep_existing_supporting_document": 0.12283229199238122, - "hypha/apply/projects/tests/test_forms.py::TestEditInvoiceForm::test_remove_existing_supporting_document": 0.1436553749954328, + "hypha/apply/projects/tests/test_forms.py::TestContractUploadForm::test_applicant_can_upload_signed": 0.006403084029443562, + "hypha/apply/projects/tests/test_forms.py::TestContractUploadForm::test_applicant_cant_upload_unsigned": 0.0013619580422528088, + "hypha/apply/projects/tests/test_forms.py::TestCreateInvoiceForm::test_adding_invoice": 0.14031287498073652, + "hypha/apply/projects/tests/test_forms.py::TestCreateInvoiceForm::test_supporting_documents_not_required": 0.11470908299088478, + "hypha/apply/projects/tests/test_forms.py::TestEditInvoiceForm::test_add_new_supporting_document": 0.1444257089169696, + "hypha/apply/projects/tests/test_forms.py::TestEditInvoiceForm::test_keep_existing_supporting_document": 0.10962137498427182, + "hypha/apply/projects/tests/test_forms.py::TestEditInvoiceForm::test_remove_existing_supporting_document": 0.12516949890414253, "hypha/apply/projects/tests/test_forms.py::TestFinalApprovalForm::test_comment_is_not_required": 0.13221216498641297, "hypha/apply/projects/tests/test_forms.py::TestFinalApprovalForm::test_final_approval_status_is_required": 0.14672052202513441, - "hypha/apply/projects/tests/test_forms.py::TestProjectApprovalForm::test_updating_fields_sets_changed_flag": 0.18461233307607472, - "hypha/apply/projects/tests/test_forms.py::TestSelectDocumentForm::test_copying_files": 0.2475349169690162, - "hypha/apply/projects/tests/test_forms.py::TestStaffContractUploadForm::test_staff_can_upload_signed": 0.025492292013950646, - "hypha/apply/projects/tests/test_forms.py::TestStaffContractUploadForm::test_staff_can_upload_unsigned": 0.0016959580825641751, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_can_edit_invoice": 0.4677913341438398, + "hypha/apply/projects/tests/test_forms.py::TestProjectApprovalForm::test_updating_fields_sets_changed_flag": 0.1513795000500977, + "hypha/apply/projects/tests/test_forms.py::TestSelectDocumentForm::test_copying_files": 0.18573712499346584, + "hypha/apply/projects/tests/test_forms.py::TestStaffContractUploadForm::test_staff_can_upload_signed": 0.016540082986466587, + "hypha/apply/projects/tests/test_forms.py::TestStaffContractUploadForm::test_staff_can_upload_unsigned": 0.0009478750289417803, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_can_edit_invoice": 0.36330341699067503, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_cant_complete_required_checks": 0.2534002040629275, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_cant_edit_deliverables": 1.3421481680124998, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_cant_edit_invoice": 0.8605386249255389, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_cant_edit_deliverables": 1.1302305419230834, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_cant_edit_invoice": 0.8116131669376045, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_applicant_cant_view_required_checks": 0.15699885797221214, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_can_user_delete_from_submitted": 0.13923558394890279, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_deliverables_total_amount": 0.26896874990779907, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_change_status": 0.2687777921091765, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_change_status_with_extended_flow": 0.2564405840821564, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_can_user_delete_from_submitted": 0.1474017919972539, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_deliverables_total_amount": 0.22718766692560166, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_change_status": 0.24208254198310897, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_change_status_with_extended_flow": 0.26650112500647083, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_complete_required_checks": 0.13558499101782218, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_complete_required_checks_with_extended_flow": 0.262551411986351, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_edit_deliverables": 0.15919166698586196, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_edit_deliverables_with_extended_flow": 0.30434783222153783, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_edit_deliverables": 0.1268042500014417, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_edit_deliverables_with_extended_flow": 0.26172199996653944, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_can_view_required_checks": 0.13442321895854548, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_cant_change_status": 0.7777259999420494, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_cant_change_status_with_extended_flow": 1.124960500979796, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_cant_edit_deliverables": 1.1772799988975748, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_can_change_status_with_extended_flow": 0.31822366698179394, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_can_edit_deliverables": 0.18257191707380116, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_cant_change_status": 0.7050282080308534, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_cant_change_status_with_extended_flow": 0.9462360010365956, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance1_cant_edit_deliverables": 0.921039208129514, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_can_change_status_with_extended_flow": 0.2598687920253724, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_can_edit_deliverables": 0.10523770900908858, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_can_view_required_checks": 0.1515219429275021, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_cant_change_status": 1.0336496668169275, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_cant_change_status": 0.9600839590420946, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_cant_complete_required_checks": 0.2719519470119849, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_cant_edit_deliverables": 1.2482511668931693, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_invoice_status_user_choices": 0.029556000023148954, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_paid_value_overrides_paid_value": 0.24231670808512717, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_paid_value_used_when_no_paid_value": 0.11380149878095835, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_change_status": 0.5695527079515159, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_delete_from_submitted": 0.13154870888683945, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_edit_deliverables": 0.4835246258880943, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_edit_invoice": 0.3677802919410169, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_change_status": 0.827688624849543, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_finance2_cant_edit_deliverables": 1.2250069149886258, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_invoice_status_user_choices": 0.03718683298211545, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_paid_value_overrides_paid_value": 0.2030398749629967, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_paid_value_used_when_no_paid_value": 0.13652175100287423, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_change_status": 0.47239845793228596, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_delete_from_submitted": 0.12855129095260054, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_edit_deliverables": 0.39788370800670236, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_can_edit_invoice": 0.400879165972583, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_change_status": 1.0896235829568468, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_complete_required_checks": 0.25674830604111776, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_changes_requested": 0.12243487488012761, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_declined": 0.11556737590581179, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_paid": 0.13047170895151794, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_resubmitted": 0.14207054185681045, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_edit_deliverables": 0.9022454170044512, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_edit_invoice": 0.9730592080159113, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_changes_requested": 0.12655916705261916, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_declined": 0.1241452909889631, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_paid": 0.09894866601098329, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_delete_from_resubmitted": 0.11720466602127999, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_edit_deliverables": 0.8992272920440882, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_edit_invoice": 0.8716860840213485, "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_staff_cant_view_required_checks": 0.13086751097580418, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_changes_requested": 0.13185079209506512, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_declined": 0.13134587497916073, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_paid": 0.11496637493837625, - "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_resubmitted": 0.11964587401598692, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_approved_by_finance_1": 0.16413887590169907, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_approved_by_staff": 0.1464312489842996, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_for_finance_1": 0.47499566711485386, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_for_finance_1_with_extended_flow": 0.4038207909325138, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_get_totals": 0.29281766701024026, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_get_totals_no_value": 0.009484459063969553, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_in_progress": 0.5261278330581263, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_in_progress_with_extended_workflow": 0.5607747921021655, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_not_rejected": 0.24980391701683402, - "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_rejected": 0.2608390011591837, - "hypha/apply/projects/tests/test_models.py::TestProjectModel::test_create_from_submission": 0.13738808303605765, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_changes_requested": 0.11003816605079919, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_declined": 0.13892958394717425, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_paid": 0.1303658340475522, + "hypha/apply/projects/tests/test_models.py::TestInvoiceModel::test_user_cant_delete_from_resubmitted": 0.12873112497618422, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_approved_by_finance_1": 0.14149708399781957, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_approved_by_staff": 0.11375741701340303, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_for_finance_1": 0.3286479579983279, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_for_finance_1_with_extended_flow": 0.34988908405648544, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_get_totals": 0.2184157090377994, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_get_totals_no_value": 0.0021292089950293303, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_in_progress": 0.4871035839896649, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_in_progress_with_extended_workflow": 0.461409084033221, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_not_rejected": 0.25259441597154364, + "hypha/apply/projects/tests/test_models.py::TestInvoiceQueryset::test_rejected": 0.23775141587248072, + "hypha/apply/projects/tests/test_models.py::TestProjectModel::test_create_from_submission": 0.1269227919401601, "hypha/apply/projects/tests/test_models.py::TestProjectModel::test_get_missing_document_categories_with_enough_documents": 0.11543385393451899, "hypha/apply/projects/tests/test_models.py::TestProjectModel::test_get_missing_document_categories_with_no_documents": 0.12154749495675787, "hypha/apply/projects/tests/test_models.py::TestProjectModel::test_get_missing_document_categories_with_some_documents": 0.1251538940705359, - "hypha/apply/projects/tests/test_models.py::TestReport::test_late_if_two_weeks_behind": 0.14041937398724258, - "hypha/apply/projects/tests/test_models.py::TestReport::test_not_late_if_one_ahead": 0.1475888331187889, - "hypha/apply/projects/tests/test_models.py::TestReport::test_not_late_if_two_ahead_but_one_in_future": 0.13852524990215898, - "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_doesnt_includes_draft": 0.13393670704681426, - "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_doesnt_includes_to_do": 0.14236916694790125, - "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_includes_skipped": 0.11985287489369512, - "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_includes_submitted": 0.1529380000429228, - "hypha/apply/projects/tests/test_models.py::TestReport::test_start_date": 0.2827108330093324, - "hypha/apply/projects/tests/test_models.py::TestReport::test_start_date_with_submitted": 0.3177187921246514, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_current_due_report_gets_active_report": 0.16657691588625312, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_last_report_gets_report_in_past": 0.13111908407881856, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_last_report_gets_skipped": 0.13035574986133724, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_last_report_gets_submitted_report_in_past": 0.16823266702704132, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_months_always_relative": 0.14021316601429135, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_next_date_month_from_now": 0.1383220818825066, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_next_date_week_from_now": 0.1124104579212144, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_creates_report": 0.13419712509494275, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_creates_report_if_current_skipped": 0.29639283288270235, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_creates_report_not_in_past": 0.18723491800483316, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_schedule_in_future_creates_report": 0.12775712611619383, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due": 0.1407861680490896, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_has_drafts": 0.1162833331618458, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_no_future": 0.14742004196159542, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_no_skipped": 0.1485892499331385, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_no_submitted": 0.1205546660348773, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_report_creates_report": 0.17780787404626608, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_report_future_schedule_creates_report": 0.15225604199804366, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_submitted_report_unaffected": 0.12192612502258271, - "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_today_schedule_gets_report_today": 0.1461057069245726, - "hypha/apply/projects/tests/test_settings.py::TestProjectFeatureFlag::test_urls_404_when_turned_off": 0.13511179306078702, - "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_only_owner_or_contracting_can_upload_contract": 0.6426608330802992, + "hypha/apply/projects/tests/test_models.py::TestReport::test_late_if_two_weeks_behind": 0.1477487930096686, + "hypha/apply/projects/tests/test_models.py::TestReport::test_not_late_if_one_ahead": 0.13237629103241488, + "hypha/apply/projects/tests/test_models.py::TestReport::test_not_late_if_two_ahead_but_one_in_future": 0.1617117919959128, + "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_doesnt_includes_draft": 0.13124441704712808, + "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_doesnt_includes_to_do": 0.12062133406288922, + "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_includes_skipped": 0.14506729098502547, + "hypha/apply/projects/tests/test_models.py::TestReport::test_queryset_done_includes_submitted": 0.1238328319741413, + "hypha/apply/projects/tests/test_models.py::TestReport::test_start_date": 0.21993504301644862, + "hypha/apply/projects/tests/test_models.py::TestReport::test_start_date_with_submitted": 0.24898254103027284, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_current_due_report_gets_active_report": 0.16092424996895716, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_last_report_gets_report_in_past": 0.12169475003611296, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_last_report_gets_skipped": 0.1491424990235828, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_last_report_gets_submitted_report_in_past": 0.1257554159965366, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_months_always_relative": 0.13577125000301749, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_next_date_month_from_now": 0.1201719170785509, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_next_date_week_from_now": 0.12127966596744955, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_creates_report": 0.13493754208320752, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_creates_report_if_current_skipped": 0.23459212493617088, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_creates_report_not_in_past": 0.11976004095049575, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_no_report_schedule_in_future_creates_report": 0.1297682499862276, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due": 0.1139041249989532, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_has_drafts": 0.15932658303063363, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_no_future": 0.12547366600483656, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_no_skipped": 0.118757291988004, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_no_submitted": 0.1272358339629136, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_report_creates_report": 0.11167049902724102, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_past_due_report_future_schedule_creates_report": 0.12052008305909112, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_submitted_report_unaffected": 0.1280730830039829, + "hypha/apply/projects/tests/test_models.py::TestReportConfig::test_today_schedule_gets_report_today": 0.10225716698914766, + "hypha/apply/projects/tests/test_settings.py::TestProjectFeatureFlag::test_urls_404_when_turned_off": 0.18001758301397786, + "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_only_owner_or_contracting_can_upload_contract": 0.5239041250897571, "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_only_owner_or_staff_or_contracting_can_upload_contract": 0.6099863669951446, - "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_owner_can_only_upload_during_contracting": 0.7223308749962598, + "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_owner_can_only_upload_during_contracting": 0.6643426680820994, "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_staff_can_only_upload_during_contracting": 0.9420862589031458, "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_staff_can_upload_after_state_leaves_committed": 0.7649188670911826, - "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_staff_cant_upload_contract": 0.6458539160666987, + "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_staff_cant_upload_contract": 0.6652022080379538, "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_user_can_only_upload_during_contracting": 0.6449822820723057, "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_user_cannot_upload_first_contract": 0.13075465901056305, "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_user_cannot_upload_when_latest_is_approved": 0.13252823700895533, "hypha/apply/projects/tests/test_templatetags.py::TestContractTools::test_user_upload_happy_path": 0.2574270899640396, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_can_edit_in_resubmitted": 0.20081529207527637, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_can_edit_in_submitted": 0.17667258298024535, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_cant_edit_in_decline": 0.16733512608334422, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_cant_edit_in_paid": 0.14762791595421731, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_can_edit_in_changes_requested": 0.1495155009906739, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_change_status_from_changes_requested": 0.1446481669554487, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_change_status_from_resubmitted": 0.11919666698668152, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_change_status_from_submitted": 0.1579036668408662, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_delete_from_submitted": 0.143415667116642, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_change_status_from_declined": 0.14673970884177834, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_change_status_from_paid": 0.16521012503653765, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_changes_requested": 0.13709866616409272, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_declined": 0.12764229194726795, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_paid": 0.14702133391983807, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_resubmitted": 0.14646908198483288, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_edit_in_changes_requested": 0.14439691707957536, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_can_delete_from_changes_requested": 0.16820387495681643, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_can_delete_from_submitted": 0.11543937399983406, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_changes_requested": 0.14563395793084055, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_declined": 0.1374384588561952, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_paid": 0.11991154309362173, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_resubmitted": 0.11730445898137987, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_submitted": 0.140936418203637, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_delete_from_declined": 0.12267554190475494, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_delete_from_paid": 0.12980916700325906, - "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_delete_from_resubmitted": 0.1432627912145108, - "hypha/apply/projects/tests/test_views.py::ApplicantStaffProjectDetailDownloadView::test_cant_access_docx": 0.1966205829521641, - "hypha/apply/projects/tests/test_views.py::ApplicantStaffProjectDetailDownloadView::test_cant_access_pdf": 0.15883916686289012, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_can_edit_in_resubmitted": 0.1416441659675911, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_can_edit_in_submitted": 0.13269512495025992, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_cant_edit_in_decline": 0.11906229198211804, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_and_staff_cant_edit_in_paid": 0.13019908301066607, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_applicant_can_edit_in_changes_requested": 0.13013033400056884, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_change_status_from_changes_requested": 0.11940841592149809, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_change_status_from_resubmitted": 0.14355270902160555, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_change_status_from_submitted": 0.13288904097862542, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_can_delete_from_submitted": 0.1131814590189606, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_change_status_from_declined": 0.14224608399672434, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_change_status_from_paid": 0.11739499995019287, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_changes_requested": 0.13371045800158754, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_declined": 0.11702750099357218, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_paid": 0.10729066602652892, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_delete_from_resubmitted": 0.14401299902237952, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_staff_cant_edit_in_changes_requested": 0.1236842090729624, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_can_delete_from_changes_requested": 0.11744620994431898, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_can_delete_from_submitted": 0.10634854197269306, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_changes_requested": 0.1360518749570474, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_declined": 0.11879579199012369, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_paid": 0.11959391599521041, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_resubmitted": 0.11630808300105855, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_change_status_from_submitted": 0.13333870802307501, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_delete_from_declined": 0.13749158300925046, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_delete_from_paid": 0.12493983306922019, + "hypha/apply/projects/tests/test_templatetags.py::TestInvoiceTools::test_user_cant_delete_from_resubmitted": 0.10210883396212012, + "hypha/apply/projects/tests/test_views.py::ApplicantStaffProjectDetailDownloadView::test_cant_access_docx": 0.45916212402516976, + "hypha/apply/projects/tests/test_views.py::ApplicantStaffProjectDetailDownloadView::test_cant_access_pdf": 0.24529237597016618, "hypha/apply/projects/tests/test_views.py::ApplicantStaffProjectPDFExport::test_cant_access": 0.4367084689438343, - "hypha/apply/projects/tests/test_views.py::TestAnonPacketView::test_anonymous_can_not_access": 0.2985005429945886, - "hypha/apply/projects/tests/test_views.py::TestApplicantChangeInoviceStatus::test_can": 0.2696548749227077, - "hypha/apply/projects/tests/test_views.py::TestApplicantChangeInoviceStatus::test_other_cant": 0.1833043749211356, - "hypha/apply/projects/tests/test_views.py::TestApplicantDetailInvoiceStatus::test_can": 0.26966437592636794, - "hypha/apply/projects/tests/test_views.py::TestApplicantDetailInvoiceStatus::test_other_cant": 0.21466441499069333, - "hypha/apply/projects/tests/test_views.py::TestApplicantEditInvoiceView::test_editing_invoice_remove_supporting_document": 0.5716359990183264, - "hypha/apply/projects/tests/test_views.py::TestApplicantEditInvoiceView::test_editing_payment_keeps_receipts": 0.2577328330371529, - "hypha/apply/projects/tests/test_views.py::TestApplicantInvoiceDocumentPrivateMedia::test_can_access_own": 0.20194349891971797, - "hypha/apply/projects/tests/test_views.py::TestApplicantInvoiceDocumentPrivateMedia::test_cant_access_other": 0.16671270783990622, - "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_can_access_own_submitted_report": 0.28402716596610844, - "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_other_draft_report": 0.20395133295096457, - "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_other_future_report": 0.18712166603654623, - "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_other_submitted_report": 0.24219274998176843, - "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_own_draft_report": 0.3841152499662712, - "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_own_future_report": 0.16174466698430479, - "hypha/apply/projects/tests/test_views.py::TestApplicantSelectDocumentView::test_can_choose": 0.33903512405231595, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_edit_submitted_report": 0.2282239181222394, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_get_other_report": 0.2113874590722844, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_get_own_report_for_closing_and_complete_project": 0.2811180839780718, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_submit_blank_report": 0.25066425011027604, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_submit_other_report": 0.1684802919626236, + "hypha/apply/projects/tests/test_views.py::TestAnonPacketView::test_anonymous_can_not_access": 0.4795464590424672, + "hypha/apply/projects/tests/test_views.py::TestApplicantChangeInoviceStatus::test_can": 0.3256509589846246, + "hypha/apply/projects/tests/test_views.py::TestApplicantChangeInoviceStatus::test_other_cant": 0.22193012502975762, + "hypha/apply/projects/tests/test_views.py::TestApplicantDetailInvoiceStatus::test_can": 0.3115037499810569, + "hypha/apply/projects/tests/test_views.py::TestApplicantDetailInvoiceStatus::test_other_cant": 0.2415912079741247, + "hypha/apply/projects/tests/test_views.py::TestApplicantEditInvoiceView::test_editing_invoice_remove_supporting_document": 0.538654375995975, + "hypha/apply/projects/tests/test_views.py::TestApplicantEditInvoiceView::test_editing_payment_keeps_receipts": 0.34710566693684086, + "hypha/apply/projects/tests/test_views.py::TestApplicantInvoiceDocumentPrivateMedia::test_can_access_own": 0.303694000991527, + "hypha/apply/projects/tests/test_views.py::TestApplicantInvoiceDocumentPrivateMedia::test_cant_access_other": 0.21306154096964747, + "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_can_access_own_submitted_report": 0.3071528759901412, + "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_other_draft_report": 0.20377112395362929, + "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_other_future_report": 0.21426974999485537, + "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_other_submitted_report": 0.27217287494568154, + "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_own_draft_report": 0.2003725840477273, + "hypha/apply/projects/tests/test_views.py::TestApplicantReportDetail::test_cant_access_own_future_report": 0.213356250023935, + "hypha/apply/projects/tests/test_views.py::TestApplicantSelectDocumentView::test_can_choose": 0.37393970793345943, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_edit_submitted_report": 0.2687948750681244, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_get_other_report": 0.1986369170481339, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_get_own_report_for_closing_and_complete_project": 0.3425587509991601, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_submit_blank_report": 0.2760763339465484, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_cant_submit_other_report": 0.1870428750407882, "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_get_own_report": 0.2826117270742543, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_get_own_report_for_inprogress_project": 0.23057825001887977, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_save_report_draft": 0.3780158340232447, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_save_report_with_draft": 0.303628999972716, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_submit_own_report": 0.5435319581301883, - "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_submit_private_report": 0.3683913750573993, - "hypha/apply/projects/tests/test_views.py::TestApplicantSupportingDocumentPrivateMedia::test_can_access_own": 0.248186418088153, - "hypha/apply/projects/tests/test_views.py::TestApplicantSupportingDocumentPrivateMedia::test_cant_access_other": 0.25508024904411286, - "hypha/apply/projects/tests/test_views.py::TestApplicantUploadContractView::test_non_owner_upload_contract": 0.4791930830106139, - "hypha/apply/projects/tests/test_views.py::TestApplicantUploadContractView::test_owner_upload_contract": 0.28598516690544784, - "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_approve_already_approved_contract": 0.44596962514333427, - "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_approve_unapproved_contract": 0.462921499973163, - "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_approve_unsigned_contract": 0.29319612495601177, - "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_attempt_to_approve_non_latest": 0.2465409169672057, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_get_own_report_for_inprogress_project": 0.3384575830423273, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_save_report_draft": 0.3246157499961555, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_save_report_with_draft": 0.5627535410458222, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_submit_own_report": 0.3342833330389112, + "hypha/apply/projects/tests/test_views.py::TestApplicantSubmitReport::test_submit_private_report": 0.38345675001619384, + "hypha/apply/projects/tests/test_views.py::TestApplicantSupportingDocumentPrivateMedia::test_can_access_own": 0.2888711250270717, + "hypha/apply/projects/tests/test_views.py::TestApplicantSupportingDocumentPrivateMedia::test_cant_access_other": 0.5360604160232469, + "hypha/apply/projects/tests/test_views.py::TestApplicantUploadContractView::test_non_owner_upload_contract": 0.25273012602701783, + "hypha/apply/projects/tests/test_views.py::TestApplicantUploadContractView::test_owner_upload_contract": 0.33014037396060303, + "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_approve_already_approved_contract": 0.411870917014312, + "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_approve_unapproved_contract": 0.6934588749427348, + "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_approve_unsigned_contract": 0.31821533292531967, + "hypha/apply/projects/tests/test_views.py::TestApproveContractView::test_attempt_to_approve_non_latest": 0.31890566600486636, "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_applicant_cant_update_paf_status": 0.16629222000483423, - "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_assigned_approvers_can_approve_paf": 0.529611749923788, - "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_assigned_approvers_can_reject_paf": 0.41536887490656227, + "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_assigned_approvers_can_approve_paf": 0.456562418024987, + "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_assigned_approvers_can_reject_paf": 0.4152632079203613, "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_contracting_can_update_paf_status": 0.12587614404037595, "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_finance_can_update_paf_status": 0.1424186519579962, "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_reviewer_approve_paf": 0.11959398398175836, "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_reviewer_rejects_paf": 0.11641414504265413, "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_staff_can_update_paf_status": 0.14335077803116292, - "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_applicant_cant_update_paf_status": 0.2960075829178095, - "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_contracting_cant_update_paf_status": 0.257217500009574, - "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_finance_cant_update_paf_status": 0.2588361669331789, - "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_staff_cant_update_paf_status": 0.287305667065084, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_all_signed_and_approved_contracts_appear": 0.16733087494503707, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_all_signed_and_unapproved_returns_latest": 0.14290170895401388, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_all_unsigned_and_unapproved_returns_only_latest": 0.1126612500520423, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_of_both_latest_signed_and_approved": 0.13478079193737358, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_of_both_latest_signed_and_unapproved": 0.1597497520269826, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_of_both_latest_unsigned_and_unapproved": 0.1713441238971427, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_with_latest_signed_returns_no_unsigned": 0.1869870830560103, - "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_no_contracts_returns_nothing": 0.11318270908668637, + "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_applicant_cant_update_paf_status": 0.2950861669378355, + "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_contracting_cant_update_paf_status": 0.521577792998869, + "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_finance_cant_update_paf_status": 0.23723004100611433, + "hypha/apply/projects/tests/test_views.py::TestChangePAFStatusView::test_unassigned_staff_cant_update_paf_status": 0.2821604569326155, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_all_signed_and_approved_contracts_appear": 0.12316487601492554, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_all_signed_and_unapproved_returns_latest": 0.10773258411791176, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_all_unsigned_and_unapproved_returns_only_latest": 0.1178819989436306, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_of_both_latest_signed_and_approved": 0.11882074997993186, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_of_both_latest_signed_and_unapproved": 0.14017470710678026, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_of_both_latest_unsigned_and_unapproved": 0.11534129199571908, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_mixture_with_latest_signed_returns_no_unsigned": 0.10427795996656641, + "hypha/apply/projects/tests/test_views.py::TestContractsMixin::test_no_contracts_returns_nothing": 0.11602991598192602, "hypha/apply/projects/tests/test_views.py::TestFinalApprovalView::test_final_approval": 0.6934734180103987, "hypha/apply/projects/tests/test_views.py::TestFinalApprovalView::test_final_approver_cant_be_applicant": 0.1994648210820742, "hypha/apply/projects/tests/test_views.py::TestFinalApprovalView::test_final_approver_cant_be_approver": 0.2700507749686949, @@ -671,221 +671,221 @@ "hypha/apply/projects/tests/test_views.py::TestFinalApprovalView::test_final_approver_cant_be_finance": 0.24600107705919072, "hypha/apply/projects/tests/test_views.py::TestFinalApprovalView::test_final_approver_cant_be_staff": 0.25083705002907664, "hypha/apply/projects/tests/test_views.py::TestFinalApprovalView::test_final_rejection": 0.463428097020369, - "hypha/apply/projects/tests/test_views.py::TestFinanceDetailInvoiceStatus::test_can": 0.2918579989345744, - "hypha/apply/projects/tests/test_views.py::TestFinanceDetailInvoiceStatus::test_wrong_project_cant": 0.31055020820349455, - "hypha/apply/projects/tests/test_views.py::TestFinanceProjectDetailView::test_has_access": 0.5254750840831548, - "hypha/apply/projects/tests/test_views.py::TestFinanceProjectDetailView::test_lab_project_renders": 0.24427445698529482, - "hypha/apply/projects/tests/test_views.py::TestProjectDetailApprovalView::test_staff_only": 0.21805266686715186, + "hypha/apply/projects/tests/test_views.py::TestFinanceDetailInvoiceStatus::test_can": 0.3208207089919597, + "hypha/apply/projects/tests/test_views.py::TestFinanceDetailInvoiceStatus::test_wrong_project_cant": 0.32072658301331103, + "hypha/apply/projects/tests/test_views.py::TestFinanceProjectDetailView::test_has_access": 0.3069825819693506, + "hypha/apply/projects/tests/test_views.py::TestFinanceProjectDetailView::test_lab_project_renders": 0.2706773330573924, + "hypha/apply/projects/tests/test_views.py::TestProjectDetailApprovalView::test_staff_only": 0.13856237498112023, "hypha/apply/projects/tests/test_views.py::TestProjectDetailSimplifiedView::test_staff_only": 0.15704163699410856, - "hypha/apply/projects/tests/test_views.py::TestProjectListView::test_applicants_cannot_access_project_list_page": 0.35646595794241875, - "hypha/apply/projects/tests/test_views.py::TestProjectListView::test_staff_can_access_project_list_page": 0.4130909158848226, - "hypha/apply/projects/tests/test_views.py::TestProjectOverviewView::test_applicants_cannot_access": 0.3156660831300542, - "hypha/apply/projects/tests/test_views.py::TestProjectOverviewView::test_staff_can_access": 0.3794998340308666, - "hypha/apply/projects/tests/test_views.py::TestRemoveDocumentView::test_remove_document": 0.6011455829720944, - "hypha/apply/projects/tests/test_views.py::TestRemoveDocumentView::test_remove_non_existent_document": 0.4119464160175994, - "hypha/apply/projects/tests/test_views.py::TestReviewerUserProjectDetailView::test_doesnt_have_access": 0.2568367099156603, - "hypha/apply/projects/tests/test_views.py::TestSendForApprovalView::test_send_for_approval_fails_when_project_is_locked": 0.21470729308202863, + "hypha/apply/projects/tests/test_views.py::TestProjectListView::test_applicants_cannot_access_project_list_page": 0.4246058319695294, + "hypha/apply/projects/tests/test_views.py::TestProjectListView::test_staff_can_access_project_list_page": 0.36219254101160914, + "hypha/apply/projects/tests/test_views.py::TestProjectOverviewView::test_applicants_cannot_access": 0.37630616599926725, + "hypha/apply/projects/tests/test_views.py::TestProjectOverviewView::test_staff_can_access": 0.41673837590496987, + "hypha/apply/projects/tests/test_views.py::TestRemoveDocumentView::test_remove_document": 0.48997466603759676, + "hypha/apply/projects/tests/test_views.py::TestRemoveDocumentView::test_remove_non_existent_document": 0.3139536670059897, + "hypha/apply/projects/tests/test_views.py::TestReviewerUserProjectDetailView::test_doesnt_have_access": 0.5179437079932541, + "hypha/apply/projects/tests/test_views.py::TestSendForApprovalView::test_send_for_approval_fails_when_project_is_locked": 0.17156754207098857, "hypha/apply/projects/tests/test_views.py::TestSendForApprovalView::test_send_for_approval_fails_when_project_is_not_in_committed_state": 0.11484798201126978, - "hypha/apply/projects/tests/test_views.py::TestSendForApprovalView::test_send_for_approval_fails_when_project_is_not_in_draft_state": 0.14769441704265773, - "hypha/apply/projects/tests/test_views.py::TestSendForApprovalView::test_send_for_approval_happy_path": 0.6986223750282079, - "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_can_skip_draft_report": 0.45594166696537286, - "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_can_skip_report": 0.4073158329119906, - "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_can_unskip_report": 0.33946179191116244, - "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_cant_skip_current_report": 0.38838975108228624, - "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_cant_skip_submitted_report": 0.48223537614103407, - "hypha/apply/projects/tests/test_views.py::TestStaffChangeInvoiceStatus::test_can": 0.6096435419749469, - "hypha/apply/projects/tests/test_views.py::TestStaffDetailInvoiceStatus::test_can": 0.27719737589359283, - "hypha/apply/projects/tests/test_views.py::TestStaffDetailInvoiceStatus::test_wrong_project_cant": 0.3097846240270883, - "hypha/apply/projects/tests/test_views.py::TestStaffEditInvoiceView::test_editing_invoice_keeps_supprting_document": 0.3054182920604944, - "hypha/apply/projects/tests/test_views.py::TestStaffEditInvoiceView::test_editing_invoice_remove_supporting_document": 0.33160770789254457, - "hypha/apply/projects/tests/test_views.py::TestStaffInoviceDocumentPrivateMedia::test_can_access": 0.23991429095622152, - "hypha/apply/projects/tests/test_views.py::TestStaffInoviceDocumentPrivateMedia::test_cant_access_if_project_wrong": 0.34424449992366135, - "hypha/apply/projects/tests/test_views.py::TestStaffInvoiceSupportingDocumentPrivateMedia::test_can_access": 0.26419045904185623, - "hypha/apply/projects/tests/test_views.py::TestStaffPacketView::test_staff_can_access": 0.542893375037238, - "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_can_access_docx": 0.2526711248792708, - "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_can_access_pdf": 0.22196891601197422, - "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_response_object_is_docx": 0.18210512504447252, - "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_response_object_is_pdf": 0.423069374053739, - "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailView::test_has_access": 0.39090833195950836, - "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailView::test_lab_project_renders": 0.2163510420359671, + "hypha/apply/projects/tests/test_views.py::TestSendForApprovalView::test_send_for_approval_fails_when_project_is_not_in_draft_state": 0.14426654000999406, + "hypha/apply/projects/tests/test_views.py::TestSendForApprovalView::test_send_for_approval_happy_path": 0.45225474901963025, + "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_can_skip_draft_report": 0.7346736240433529, + "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_can_skip_report": 0.4331095829838887, + "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_can_unskip_report": 0.5356489589903504, + "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_cant_skip_current_report": 0.49836270802188665, + "hypha/apply/projects/tests/test_views.py::TestSkipReport::test_cant_skip_submitted_report": 0.38844799995422363, + "hypha/apply/projects/tests/test_views.py::TestStaffChangeInvoiceStatus::test_can": 0.5439029589761049, + "hypha/apply/projects/tests/test_views.py::TestStaffDetailInvoiceStatus::test_can": 0.3614245840581134, + "hypha/apply/projects/tests/test_views.py::TestStaffDetailInvoiceStatus::test_wrong_project_cant": 0.3226270829909481, + "hypha/apply/projects/tests/test_views.py::TestStaffEditInvoiceView::test_editing_invoice_keeps_supprting_document": 0.44923462596489117, + "hypha/apply/projects/tests/test_views.py::TestStaffEditInvoiceView::test_editing_invoice_remove_supporting_document": 0.3660999580170028, + "hypha/apply/projects/tests/test_views.py::TestStaffInoviceDocumentPrivateMedia::test_can_access": 0.3106673340080306, + "hypha/apply/projects/tests/test_views.py::TestStaffInoviceDocumentPrivateMedia::test_cant_access_if_project_wrong": 0.3133041240507737, + "hypha/apply/projects/tests/test_views.py::TestStaffInvoiceSupportingDocumentPrivateMedia::test_can_access": 0.48374729201896116, + "hypha/apply/projects/tests/test_views.py::TestStaffPacketView::test_staff_can_access": 0.24483416695147753, + "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_can_access_docx": 0.2842131249490194, + "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_can_access_pdf": 0.2532527500297874, + "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_response_object_is_docx": 0.2087979579810053, + "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailDownloadView::test_response_object_is_pdf": 0.23951404099352658, + "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailView::test_has_access": 0.3380022089695558, + "hypha/apply/projects/tests/test_views.py::TestStaffProjectDetailView::test_lab_project_renders": 0.4964867499656975, "hypha/apply/projects/tests/test_views.py::TestStaffProjectPDFExport::test_can_access": 0.62907274288591, "hypha/apply/projects/tests/test_views.py::TestStaffProjectPDFExport::test_reponse_object_is_pdf": 0.49607601994648576, - "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_can_access_submitted_report": 0.633369543007575, - "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_cant_access_draft_report": 0.2028960419120267, - "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_cant_access_future_report": 0.18843545811250806, - "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_cant_access_skipped_report": 0.15538466710131615, - "hypha/apply/projects/tests/test_views.py::TestStaffSelectDocumentView::test_can_choose": 0.3985551248770207, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_get_page_for_closing_and_complete_project": 0.36881350108888, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_submit_blank_report": 0.2565447079250589, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_submit_future_report": 0.18748716602567583, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_submit_report_for_closing_and_complete_project": 0.35878841613885015, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_edit_submitted_report": 0.616601207992062, + "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_can_access_submitted_report": 0.7208559580030851, + "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_cant_access_draft_report": 0.1993922510300763, + "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_cant_access_future_report": 0.19288537505781278, + "hypha/apply/projects/tests/test_views.py::TestStaffReportDetail::test_cant_access_skipped_report": 0.24741629196796566, + "hypha/apply/projects/tests/test_views.py::TestStaffSelectDocumentView::test_can_choose": 0.5797827090136707, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_get_page_for_closing_and_complete_project": 0.41048508300445974, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_submit_blank_report": 0.46325166698079556, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_submit_future_report": 0.23543595790397376, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_cant_submit_report_for_closing_and_complete_project": 0.39520945894764736, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_edit_submitted_report": 0.4390557080041617, "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_get_page": 0.2761989119462669, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_get_page_for_inprogress_project": 0.21260137599892914, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_resubmit_submitted_report": 0.38562366797123104, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_save_report_draft": 0.45716437499504536, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_save_report_with_draft": 0.4391555840848014, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_submit_private_report": 0.3835993749089539, - "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_submit_report": 0.5758337920997292, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_get_page_for_inprogress_project": 0.2642857500468381, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_resubmit_submitted_report": 0.4863973740139045, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_save_report_draft": 0.396255124011077, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_save_report_with_draft": 0.6368727079825476, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_submit_private_report": 0.4309600000269711, + "hypha/apply/projects/tests/test_views.py::TestStaffSubmitReport::test_submit_report": 0.4222774589434266, "hypha/apply/projects/tests/test_views.py::TestStaffUploadContractView::test_upload_contract": 0.6011504890047945, "hypha/apply/projects/tests/test_views.py::TestStaffUploadContractView::test_upload_contract_with_signed_set_to_true": 0.7100242809974588, - "hypha/apply/projects/tests/test_views.py::TestSuperUserProjectDetailView::test_has_access": 0.3404494160786271, - "hypha/apply/projects/tests/test_views.py::TestUpdateLeadView::test_update_lead": 0.6488694158615544, - "hypha/apply/projects/tests/test_views.py::TestUpdateLeadView::test_update_lead_from_none": 0.353453041985631, - "hypha/apply/projects/tests/test_views.py::TestUploadDocumentView::test_upload_document": 0.3495344161055982, - "hypha/apply/projects/tests/test_views.py::TestUserPacketView::test_owner_can_access": 0.33545812394004315, - "hypha/apply/projects/tests/test_views.py::TestUserPacketView::test_user_can_not_access": 0.20576012507081032, - "hypha/apply/projects/tests/test_views.py::TestUserProjectDetailView::test_doesnt_have_access": 0.18093812407460064, - "hypha/apply/projects/tests/test_views.py::TestUserProjectDetailView::test_owner_has_access": 0.26805891608819366, - "hypha/apply/review/tests/test_admin.py::TestReviewFormAdminForm::test_can_create_review_form": 0.011869458016008139, - "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_comments_block_required": 0.20544070890173316, - "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_field_label_required": 0.14705174998380244, - "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_form_creation": 0.09497791691683233, - "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_name_field_required": 0.10215525003150105, - "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_recommendation_block_required": 0.10985474998597056, - "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_visibility_block_required": 0.11987654096446931, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_no_opinion_agree": 0.13917420711368322, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_no_opinion_disagree": 0.3636568750953302, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_not_all_opinion": 0.16282629093620926, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_yes_mixed_opinion": 0.14262116607278585, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_yes_opinion_agree": 0.11128175002522767, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_yes_opinion_disagree": 0.12608304212335497, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_maybe": 0.10440991690848023, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_mixed": 0.1266885829390958, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_no": 0.1545254159718752, - "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_yes": 0.11492637603078038, - "hypha/apply/review/tests/test_views.py::NonStaffReviewOpinionCase::test_nonstaff_cant_post_opinion_to_review": 0.25852475001011044, - "hypha/apply/review/tests/test_views.py::ReviewDetailTestCase::test_review_detail_opinion": 0.3494584161089733, - "hypha/apply/review/tests/test_views.py::ReviewDetailTestCase::test_review_detail_recommendation": 0.24479608400724828, - "hypha/apply/review/tests/test_views.py::ReviewDetailVisibilityTestCase::test_review_detail_visibility_private": 0.21798725111875683, - "hypha/apply/review/tests/test_views.py::ReviewDetailVisibilityTestCase::test_review_detail_visibility_reviewer": 0.2873614178970456, - "hypha/apply/review/tests/test_views.py::ReviewListTestCase::test_review_list_opinion": 0.296927543124184, - "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_com_external_review_to_ready_for_discussion": 0.3388680829666555, - "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_ext_external_review_to_ready_for_discussion": 0.3326782069634646, - "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_external_review_to_ready_for_discussion": 0.34529587405268103, - "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_initial_state_transition_to_internal_review": 0.6244569580303505, - "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_internal_review_to_ready_for_discussion": 0.36454141791909933, - "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_proposal_discussion_to_proposal_internal_review": 0.4163980430457741, - "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_submission_did_not_transition": 0.24663300102110952, - "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_can_access_form": 0.274870999972336, - "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_can_edit_draft_review": 0.23591608414426446, - "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_can_submit_draft_review": 0.44210195809137076, - "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_cant_access_wrong_status": 0.26254008314572275, - "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_cant_resubmit_review": 0.1984747510869056, - "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_revision_captured_on_review": 0.38767075003124774, - "hypha/apply/review/tests/test_views.py::StaffReviewListingTestCase::test_can_access_review_listing": 0.3263881659368053, - "hypha/apply/review/tests/test_views.py::StaffReviewListingTestCase::test_draft_reviews_dont_appear": 0.2494624579558149, - "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_can_add_opinion_to_others_review": 0.49202100094407797, - "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_can_see_opinion_buttons_on_others_review": 0.18765587511006743, - "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_cant_see_opinion_buttons_on_self_review": 0.2060839991318062, - "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_disagree_opinion_redirects_to_review_form": 0.2845542909344658, - "hypha/apply/review/tests/test_views.py::StaffReviewsTestCase::test_can_access_other_review": 0.2563229991355911, - "hypha/apply/review/tests/test_views.py::StaffReviewsTestCase::test_can_access_review": 0.2578002088703215, - "hypha/apply/review/tests/test_views.py::TestReviewScore::test_average_score_calculated": 0.6326144568156451, - "hypha/apply/review/tests/test_views.py::TestReviewScore::test_na_included_in_review_average": 0.4118264999706298, - "hypha/apply/review/tests/test_views.py::TestReviewScore::test_na_included_multiple_reviews_average": 0.8284147089580074, - "hypha/apply/review/tests/test_views.py::TestReviewScore::test_na_included_reviews_average": 0.4461417091079056, - "hypha/apply/review/tests/test_views.py::TestReviewScore::test_no_score_is_NA": 0.37893874989822507, - "hypha/apply/review/tests/test_views.py::TestReviewScore::test_score_calculated": 0.5917663330910727, - "hypha/apply/review/tests/test_views.py::UserReviewFormTestCase::test_cant_access_form": 0.11791095905937254, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens0-date_field-expected0]": 0.0008633758407086134, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens1-date_field-expected1]": 0.2487529581412673, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens10-date_field-expected10]": 0.00032166705932468176, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens11-date_field-expected11]": 0.0003079997841268778, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens2-date_field-expected2]": 0.0010131660383194685, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens3-date_field-expected3]": 0.00038766697980463505, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens4-date_field-expected4]": 0.0005627501523122191, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens5-date_field-expected5]": 0.00032462505623698235, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens6-date_field-expected6]": 0.000332833849824965, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens7-date_field-expected7]": 0.00042587402276694775, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens8-date_field-expected8]": 0.0003458750434219837, - "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens9-date_field-expected9]": 0.0003647500416263938, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[\"hello world\"-expected8]": 0.000824082875624299, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[#12 #13-expected1]": 0.0006767080631107092, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[#12 text after-expected3]": 0.00036995799746364355, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[-expected0]": 0.0003527089720591903, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[hello-expected4]": 0.0004931669682264328, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[submitted:\"hello world\"-expected7]": 0.0003858740674331784, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[submitted:2023-12-02 hello-expected5]": 0.0007135840132832527, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[submitted:>2023-12-02 submitted:<2023-12-01 hello-expected6]": 0.0004955840995535254, - "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[text before #12-expected2]": 0.0004830829566344619, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[1111-12-89-expected7]": 0.0003257909556850791, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[2023-12-expected5]": 0.0004110001027584076, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[2023-24-expected6]": 0.0003435820108279586, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[2023-expected8]": 0.00032008392736315727, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[<2023-12-01-expected1]": 0.0005006259307265282, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[<=2023-12-01-expected2]": 0.0008225421188399196, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>2023-12-02-expected0]": 0.0006244999822229147, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>2023-expected9]": 0.00032824999652802944, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>=2023-12-01-expected3]": 0.00035345798823982477, - "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>=2023-12-expected4]": 0.0005740410415455699, - "hypha/apply/stream_forms/tests.py::TestBlocks::test_blocks_decode_none": 0.007605333114042878, - "hypha/apply/users/tests/test_forms.py::TestEmailChangePasswordForm::test_can_update_slack": 0.02227200078777969, - "hypha/apply/users/tests/test_forms.py::TestEmailChangePasswordForm::test_doesnt_error_on_null_slack_field": 0.009237498976290226, - "hypha/apply/users/tests/test_forms.py::TestProfileForm::test_can_change_email": 0.01382191595621407, - "hypha/apply/users/tests/test_forms.py::TestProfileForm::test_cant_set_slack_name": 0.013793665915727615, - "hypha/apply/users/tests/test_forms.py::TestProfileForm::test_email_unique": 0.032328416127711535, - "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_auto_prepend_at": 0.017780249007046223, - "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_can_clear_slack_name": 0.02372016606386751, - "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_can_set_slack_name": 0.005592416040599346, - "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_can_set_slack_name_with_trailing_space": 0.011761041940189898, - "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_cant_change_email": 0.008614414953626692, - "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_cant_set_slack_name_with_space": 0.016710375086404383, - "hypha/apply/users/tests/test_middleware.py::TestTwoFactorAuthenticationMiddleware::test_unverified_user_can_access_allowed_urls": 0.283555917092599, - "hypha/apply/users/tests/test_middleware.py::TestTwoFactorAuthenticationMiddleware::test_unverified_user_redirect": 0.11384358303621411, - "hypha/apply/users/tests/test_middleware.py::TestTwoFactorAuthenticationMiddleware::test_verified_user_redirect": 0.11694704205729067, - "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_not_set_up": 0.0737853329628706, - "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_page_requires_login": 0.059891041833907366, - "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_user_email_not_whitelisted": 0.2785152919823304, - "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_whitelisted_user_can_access_oauth_settings_page": 0.07490591693203896, - "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_whitelisted_user_can_see_link_to_oauth_settings_page": 0.08536875003483146, - "hypha/apply/users/tests/test_registration.py::TestRegistration::test_duplicate_registration_fails": 1.1095537910005078, - "hypha/apply/users/tests/test_registration.py::TestRegistration::test_force_login": 0.07362799998372793, - "hypha/apply/users/tests/test_registration.py::TestRegistration::test_registration": 0.05405937402974814, - "hypha/apply/users/tests/test_registration.py::TestRegistration::test_registration_enabled_has_link": 0.11622841598000377, - "hypha/apply/users/tests/test_registration.py::TestRegistration::test_registration_enabled_has_no_link": 0.07047733408398926, - "hypha/apply/users/tests/test_utils.py::TestActivationEmail::test_activation_email_includes_link": 0.018656583968549967, - "hypha/apply/users/tests/test_utils.py::TestGetUserByEmail::test_multiple_accounts_same_email": 0.264990124036558, - "hypha/apply/users/tests/test_utils.py::TestGetUserByEmail::test_no_account": 0.006179541000165045, - "hypha/apply/users/tests/test_utils.py::TestGetUserByEmail::test_single_same_email": 0.007662498974241316, - "hypha/apply/users/tests/test_utils.py::TestUserAlreadyRegistered::test_case_sensitive_email": 0.013083998928777874, - "hypha/apply/users/tests/test_utils.py::TestUserAlreadyRegistered::test_no_account": 0.00882116798311472, - "hypha/apply/users/tests/test_views.py::TestBecome::test_staff_cannot_become_superuser": 0.3818438759772107, - "hypha/apply/users/tests/test_views.py::TestBecome::test_staff_cannot_become_user": 0.07258499995805323, - "hypha/apply/users/tests/test_views.py::TestBecome::test_superuser_can_become_staff": 0.3476316658779979, - "hypha/apply/users/tests/test_views.py::TestBecome::test_superuser_cannot_become_superuser": 0.2632557920878753, - "hypha/apply/users/tests/test_views.py::TestBecome::test_user_cannot_become_other_user": 0.06921558303292841, - "hypha/apply/users/tests/test_views.py::TestBecome::test_user_cannot_become_staff": 0.09651295910589397, - "hypha/apply/users/tests/test_views.py::TestBecome::test_user_cannot_become_superuser": 0.05581383407115936, - "hypha/apply/users/tests/test_views.py::TestPasswordReset::test_recieves_email": 0.546951541909948, - "hypha/apply/users/tests/test_views.py::TestProfileView::test_cant_acces_if_not_logged_in": 0.10695858299732208, - "hypha/apply/users/tests/test_views.py::TestProfileView::test_cant_set_slack_name": 0.07533599890302867, - "hypha/apply/users/tests/test_views.py::TestProfileView::test_doesnt_includes_change_password_for_oauth": 0.12171199999283999, - "hypha/apply/users/tests/test_views.py::TestProfileView::test_includes_change_password": 0.0876262920210138, - "hypha/apply/users/tests/test_views.py::TestStaffProfileView::test_can_set_slack_name": 0.10759624990168959, + "hypha/apply/projects/tests/test_views.py::TestSuperUserProjectDetailView::test_has_access": 0.3391688749543391, + "hypha/apply/projects/tests/test_views.py::TestUpdateLeadView::test_update_lead": 0.40778812498319894, + "hypha/apply/projects/tests/test_views.py::TestUpdateLeadView::test_update_lead_from_none": 0.5957383739296347, + "hypha/apply/projects/tests/test_views.py::TestUploadDocumentView::test_upload_document": 0.4540349580347538, + "hypha/apply/projects/tests/test_views.py::TestUserPacketView::test_owner_can_access": 0.2611806660424918, + "hypha/apply/projects/tests/test_views.py::TestUserPacketView::test_user_can_not_access": 0.2293828340480104, + "hypha/apply/projects/tests/test_views.py::TestUserProjectDetailView::test_doesnt_have_access": 0.26785816700430587, + "hypha/apply/projects/tests/test_views.py::TestUserProjectDetailView::test_owner_has_access": 0.2852826260495931, + "hypha/apply/review/tests/test_admin.py::TestReviewFormAdminForm::test_can_create_review_form": 0.025559333036653697, + "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_comments_block_required": 0.2139011659892276, + "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_field_label_required": 0.12697383406339213, + "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_form_creation": 0.14681141602341086, + "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_name_field_required": 0.16924870904767886, + "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_recommendation_block_required": 0.3443185409414582, + "hypha/apply/review/tests/test_admin_views.py::TestCreateReviewFormView::test_visibility_block_required": 0.13432608300354332, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_no_opinion_agree": 0.15352487500058487, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_no_opinion_disagree": 0.13338916702196002, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_not_all_opinion": 0.13556991697987542, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_yes_mixed_opinion": 0.20167166803730652, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_yes_opinion_agree": 0.10976754198782146, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_review_yes_opinion_disagree": 0.1065160830039531, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_maybe": 0.10898670798633248, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_mixed": 0.15790229005506262, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_no": 0.4051346249761991, + "hypha/apply/review/tests/test_models.py::TestReviewQueryset::test_reviews_yes": 0.09628162503940985, + "hypha/apply/review/tests/test_views.py::NonStaffReviewOpinionCase::test_nonstaff_cant_post_opinion_to_review": 0.25356183300027624, + "hypha/apply/review/tests/test_views.py::ReviewDetailTestCase::test_review_detail_opinion": 0.3422890829970129, + "hypha/apply/review/tests/test_views.py::ReviewDetailTestCase::test_review_detail_recommendation": 0.25260195799637586, + "hypha/apply/review/tests/test_views.py::ReviewDetailVisibilityTestCase::test_review_detail_visibility_private": 0.2541005829698406, + "hypha/apply/review/tests/test_views.py::ReviewDetailVisibilityTestCase::test_review_detail_visibility_reviewer": 0.2859520830097608, + "hypha/apply/review/tests/test_views.py::ReviewListTestCase::test_review_list_opinion": 0.29913162492448464, + "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_com_external_review_to_ready_for_discussion": 0.6151829569134861, + "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_ext_external_review_to_ready_for_discussion": 0.330972999043297, + "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_external_review_to_ready_for_discussion": 0.3619700830313377, + "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_initial_state_transition_to_internal_review": 0.39601245999801904, + "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_internal_review_to_ready_for_discussion": 0.4144460830138996, + "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_proposal_discussion_to_proposal_internal_review": 0.5859039160422981, + "hypha/apply/review/tests/test_views.py::ReviewWorkFlowActionTestCase::test_submission_did_not_transition": 0.4111545409541577, + "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_can_access_form": 0.3118844159762375, + "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_can_edit_draft_review": 0.30636616703122854, + "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_can_submit_draft_review": 0.6729637079988606, + "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_cant_access_wrong_status": 0.2599057499319315, + "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_cant_resubmit_review": 0.2100437090266496, + "hypha/apply/review/tests/test_views.py::StaffReviewFormTestCase::test_revision_captured_on_review": 0.48076970799593255, + "hypha/apply/review/tests/test_views.py::StaffReviewListingTestCase::test_can_access_review_listing": 0.40731233393307775, + "hypha/apply/review/tests/test_views.py::StaffReviewListingTestCase::test_draft_reviews_dont_appear": 0.22873454302316532, + "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_can_add_opinion_to_others_review": 0.6085471249534748, + "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_can_see_opinion_buttons_on_others_review": 0.24384395801462233, + "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_cant_see_opinion_buttons_on_self_review": 0.248379125026986, + "hypha/apply/review/tests/test_views.py::StaffReviewOpinionCase::test_disagree_opinion_redirects_to_review_form": 0.38472329097567126, + "hypha/apply/review/tests/test_views.py::StaffReviewsTestCase::test_can_access_other_review": 0.30059083399828523, + "hypha/apply/review/tests/test_views.py::StaffReviewsTestCase::test_can_access_review": 0.22167387598892674, + "hypha/apply/review/tests/test_views.py::TestReviewScore::test_average_score_calculated": 0.5768150840303861, + "hypha/apply/review/tests/test_views.py::TestReviewScore::test_na_included_in_review_average": 0.508686956949532, + "hypha/apply/review/tests/test_views.py::TestReviewScore::test_na_included_multiple_reviews_average": 0.8996606669970788, + "hypha/apply/review/tests/test_views.py::TestReviewScore::test_na_included_reviews_average": 0.3935017079929821, + "hypha/apply/review/tests/test_views.py::TestReviewScore::test_no_score_is_NA": 0.46648699999786913, + "hypha/apply/review/tests/test_views.py::TestReviewScore::test_score_calculated": 0.5067357090301812, + "hypha/apply/review/tests/test_views.py::UserReviewFormTestCase::test_cant_access_form": 0.54031412495533, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens0-date_field-expected0]": 0.0005503330612555146, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens1-date_field-expected1]": 0.0003978319000452757, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens10-date_field-expected10]": 0.0008721250342205167, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens11-date_field-expected11]": 0.0008979590493254364, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens2-date_field-expected2]": 0.0009763759444467723, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens3-date_field-expected3]": 0.0009276660275645554, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens4-date_field-expected4]": 0.0009425410535186529, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens5-date_field-expected5]": 0.0009253339958377182, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens6-date_field-expected6]": 0.0008558339322917163, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens7-date_field-expected7]": 0.000898751022759825, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens8-date_field-expected8]": 0.004949666967149824, + "hypha/apply/search/tests/test_filters.py::test_date_filter_tokens_to_q_obj[tokens9-date_field-expected9]": 0.0012595829903148115, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[\"hello world\"-expected8]": 0.0009242090745829046, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[#12 #13-expected1]": 0.002065416076220572, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[#12 text after-expected3]": 0.0009625009843148291, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[-expected0]": 0.0009918330470100045, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[hello-expected4]": 0.0010198740055784583, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[submitted:\"hello world\"-expected7]": 0.0010261240531690419, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[submitted:2023-12-02 hello-expected5]": 0.001243750040885061, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[submitted:>2023-12-02 submitted:<2023-12-01 hello-expected6]": 0.00046183395897969604, + "hypha/apply/search/tests/test_query_parser.py::test_parse_search_query[text before #12-expected2]": 0.0012453750241547823, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[1111-12-89-expected7]": 0.0008087919559329748, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[2023-12-expected5]": 0.000329000991769135, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[2023-24-expected6]": 0.0003075840068049729, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[2023-expected8]": 0.0008797079790383577, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[<2023-12-01-expected1]": 0.000899831997230649, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[<=2023-12-01-expected2]": 0.0003706669667735696, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>2023-12-02-expected0]": 0.002301833941601217, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>2023-expected9]": 0.00036154198460280895, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>=2023-12-01-expected3]": 0.000352540984749794, + "hypha/apply/search/tests/test_query_parser.py::test_tokenize_date_filter_value[>=2023-12-expected4]": 0.0005730839911848307, + "hypha/apply/stream_forms/tests.py::TestBlocks::test_blocks_decode_none": 0.007933374959975481, + "hypha/apply/users/tests/test_forms.py::TestEmailChangePasswordForm::test_can_update_slack": 0.012895333988126367, + "hypha/apply/users/tests/test_forms.py::TestEmailChangePasswordForm::test_doesnt_error_on_null_slack_field": 0.004665916028898209, + "hypha/apply/users/tests/test_forms.py::TestProfileForm::test_can_change_email": 0.024179249943699688, + "hypha/apply/users/tests/test_forms.py::TestProfileForm::test_cant_set_slack_name": 0.006112375995144248, + "hypha/apply/users/tests/test_forms.py::TestProfileForm::test_email_unique": 0.020395499013829976, + "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_auto_prepend_at": 0.017060500045772642, + "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_can_clear_slack_name": 0.006809582991991192, + "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_can_set_slack_name": 0.011181749985553324, + "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_can_set_slack_name_with_trailing_space": 0.011195708997547626, + "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_cant_change_email": 0.007692208979278803, + "hypha/apply/users/tests/test_forms.py::TestStaffProfileForm::test_cant_set_slack_name_with_space": 0.012088084011338651, + "hypha/apply/users/tests/test_middleware.py::TestTwoFactorAuthenticationMiddleware::test_unverified_user_can_access_allowed_urls": 0.2864917920087464, + "hypha/apply/users/tests/test_middleware.py::TestTwoFactorAuthenticationMiddleware::test_unverified_user_redirect": 0.14059175102738664, + "hypha/apply/users/tests/test_middleware.py::TestTwoFactorAuthenticationMiddleware::test_verified_user_redirect": 0.13204412494087592, + "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_not_set_up": 0.11334274901309982, + "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_page_requires_login": 0.2748591679846868, + "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_user_email_not_whitelisted": 0.0654975829529576, + "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_whitelisted_user_can_access_oauth_settings_page": 0.14729795791208744, + "hypha/apply/users/tests/test_oauth_access.py::TestOAuthAccess::test_oauth_whitelisted_user_can_see_link_to_oauth_settings_page": 0.31927924894262105, + "hypha/apply/users/tests/test_registration.py::TestRegistration::test_duplicate_registration_fails": 0.16601058200467378, + "hypha/apply/users/tests/test_registration.py::TestRegistration::test_force_login": 0.040093874966260046, + "hypha/apply/users/tests/test_registration.py::TestRegistration::test_registration": 0.1198088750243187, + "hypha/apply/users/tests/test_registration.py::TestRegistration::test_registration_enabled_has_link": 0.17216083296807483, + "hypha/apply/users/tests/test_registration.py::TestRegistration::test_registration_enabled_has_no_link": 0.38800258294213563, + "hypha/apply/users/tests/test_utils.py::TestActivationEmail::test_activation_email_includes_link": 0.0421943329856731, + "hypha/apply/users/tests/test_utils.py::TestGetUserByEmail::test_multiple_accounts_same_email": 0.029899457993451506, + "hypha/apply/users/tests/test_utils.py::TestGetUserByEmail::test_no_account": 0.0013387909857556224, + "hypha/apply/users/tests/test_utils.py::TestGetUserByEmail::test_single_same_email": 0.01954558299621567, + "hypha/apply/users/tests/test_utils.py::TestUserAlreadyRegistered::test_case_sensitive_email": 0.04988624999532476, + "hypha/apply/users/tests/test_utils.py::TestUserAlreadyRegistered::test_no_account": 0.01419004105264321, + "hypha/apply/users/tests/test_views.py::TestBecome::test_staff_cannot_become_superuser": 0.13059508294099942, + "hypha/apply/users/tests/test_views.py::TestBecome::test_staff_cannot_become_user": 0.08360487490426749, + "hypha/apply/users/tests/test_views.py::TestBecome::test_superuser_can_become_staff": 0.481149458035361, + "hypha/apply/users/tests/test_views.py::TestBecome::test_superuser_cannot_become_superuser": 0.1572645420092158, + "hypha/apply/users/tests/test_views.py::TestBecome::test_user_cannot_become_other_user": 0.11106458405265585, + "hypha/apply/users/tests/test_views.py::TestBecome::test_user_cannot_become_staff": 0.17713054100750014, + "hypha/apply/users/tests/test_views.py::TestBecome::test_user_cannot_become_superuser": 0.11396770901046693, + "hypha/apply/users/tests/test_views.py::TestPasswordReset::test_recieves_email": 0.3137735840282403, + "hypha/apply/users/tests/test_views.py::TestProfileView::test_cant_acces_if_not_logged_in": 0.4167119169142097, + "hypha/apply/users/tests/test_views.py::TestProfileView::test_cant_set_slack_name": 0.08891379105625674, + "hypha/apply/users/tests/test_views.py::TestProfileView::test_doesnt_includes_change_password_for_oauth": 0.4324275830294937, + "hypha/apply/users/tests/test_views.py::TestProfileView::test_includes_change_password": 0.1497047088923864, + "hypha/apply/users/tests/test_views.py::TestStaffProfileView::test_can_set_slack_name": 0.16758129105437547, "hypha/apply/utils/tests/test_templatetags.py::WebpackTagsTestCase::test_render_bundle_calls_webpack_loader_when_enabled": 0.002394415088929236, "hypha/apply/utils/tests/test_templatetags.py::WebpackTagsTestCase::test_render_bundle_does_not_call_webpack_loader_when_disabled": 0.002298294915817678, - "hypha/apply/utils/tests/test_views.py::TestDelegatedViewMixin::test__access_if_no_object": 0.005382082890719175, - "hypha/apply/utils/tests/test_views.py::TestDelegatedViewMixin::test_parent_access_if_no_object": 0.0018752510659396648, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_add_to_query": 0.0028106679674237967, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_add_to_query_only_query_string": 0.42328820808324963, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_construct_query_string": 0.018966666888445616, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_construct_query_string_only_query_string": 0.0007347071077674627, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_modify_query": 0.0037198332138359547, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_modify_query_only_query_string": 0.002193792024627328, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_remove_from_query": 0.0020272919209674, - "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_remove_from_query_only_query_string": 0.002454749890603125, - "hypha/core/tests/test_utils.py::test_markdown_to_html[**bold**-<p><strong>bold</strong></p>]": 0.001456082914955914, - "hypha/core/tests/test_utils.py::test_markdown_to_html[Header1 | Header2\\n------ | ------\\nCell1 | Cell2-<table><thead><tr><th>Header1</th><th>Header2</th></tr></thead><tbody><tr><td>Cell1</td><td>Cell2</td></tr></tbody></table>]": 0.46120237396098673, - "hypha/core/tests/test_utils.py::test_markdown_to_html[~~strike~~-<p><del>strike</del></p>]": 0.4606062079546973, - "hypha/public/mailchimp/tests/test_views.py::TestNewsletterView::test_can_subscribe": 0.2957030009711161, - "hypha/public/mailchimp/tests/test_views.py::TestNewsletterView::test_error_in_form": 0.14298324997071177, - "hypha/public/mailchimp/tests/test_views.py::TestNewsletterView::test_redirected_home_if_get": 0.39467079006135464, - "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_access_categories_and_options": 0.012230750056914985, - "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_decompress_data": 0.019092082977294922, - "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_decompress_multiple_data": 0.00521787500474602, - "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_get_data_from_form": 0.004270416800864041, - "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_get_multiple_categories": 0.007622041855938733, - "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_get_multiple_data_from_form": 0.006844124058261514, - "hypha/public/projects/tests.py::TestCategoriesWidget::test_init_has_no_queries": 0.002373542985878885 + "hypha/apply/utils/tests/test_views.py::TestDelegatedViewMixin::test__access_if_no_object": 0.01312483404763043, + "hypha/apply/utils/tests/test_views.py::TestDelegatedViewMixin::test_parent_access_if_no_object": 0.004492042062338442, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_add_to_query": 0.5803023760090582, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_add_to_query_only_query_string": 0.008416500000748783, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_construct_query_string": 0.001480666978750378, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_construct_query_string_only_query_string": 0.008895165985450149, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_modify_query": 0.0017681249883025885, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_modify_query_only_query_string": 0.535828624968417, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_remove_from_query": 0.006329791969619691, + "hypha/core/templatetags/tests/test_query_params.py::QueryParamsTemplateTagTests::test_remove_from_query_only_query_string": 0.0015494589461013675, + "hypha/core/tests/test_utils.py::test_markdown_to_html[**bold**-<p><strong>bold</strong></p>]": 0.004082165949512273, + "hypha/core/tests/test_utils.py::test_markdown_to_html[Header1 | Header2\\n------ | ------\\nCell1 | Cell2-<table><thead><tr><th>Header1</th><th>Header2</th></tr></thead><tbody><tr><td>Cell1</td><td>Cell2</td></tr></tbody></table>]": 0.5622706249705516, + "hypha/core/tests/test_utils.py::test_markdown_to_html[~~strike~~-<p><del>strike</del></p>]": 0.003962667018640786, + "hypha/public/mailchimp/tests/test_views.py::TestNewsletterView::test_can_subscribe": 0.22826729097869247, + "hypha/public/mailchimp/tests/test_views.py::TestNewsletterView::test_error_in_form": 0.20641158294165507, + "hypha/public/mailchimp/tests/test_views.py::TestNewsletterView::test_redirected_home_if_get": 0.5709066240233369, + "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_access_categories_and_options": 0.5840413760161027, + "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_decompress_data": 0.009283084014896303, + "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_decompress_multiple_data": 0.005859207944013178, + "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_get_data_from_form": 0.005932166997808963, + "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_get_multiple_categories": 0.007769458054099232, + "hypha/public/projects/tests.py::TestCategoriesWidget::test_can_get_multiple_data_from_form": 0.012393665907438844, + "hypha/public/projects/tests.py::TestCategoriesWidget::test_init_has_no_queries": 0.0045277500175870955 } \ No newline at end of file diff --git a/docs/references/notifications.md b/docs/references/notifications.md index e421b2986ca510a9094444a9b70827757cc37801..78f0762a3ffe313ae1b133074903e44f78dfea96 100644 --- a/docs/references/notifications.md +++ b/docs/references/notifications.md @@ -12,10 +12,10 @@ The types of messages are as follows: The options for statuses for messages are as follows: -- `APPROVED_BY_FINANCE_1` +- `APPROVED_BY_FINANCE` - `APPROVED_BY_FINANCE_2` - `APPROVED_BY_STAFF` -- `CHANGES_REQUESTED_BY_FINANCE_1` +- `CHANGES_REQUESTED_BY_FINANCE` - `CHANGES_REQUESTED_BY_FINANCE_2` - `CONVERTED` - `PAID` diff --git a/docs/setup/administrators/configuration.md b/docs/setup/administrators/configuration.md index 2df23f261647db26a8065e55ea38c0f8246069a2..93f93d8aac705dd80cf46af895d0ea407b9910de 100644 --- a/docs/setup/administrators/configuration.md +++ b/docs/setup/administrators/configuration.md @@ -247,3 +247,15 @@ See <https://github.com/tm-kn/django-basic-auth-ip-whitelist> BASIC_AUTH_PASSWORD = env.str('BASIC_AUTH_PASSWORD', None) BASIC_AUTH_WHITELISTED_HTTP_HOSTS = env.list('BASIC_AUTH_WHITELISTED_HTTP_HOSTS', []) BASIC_AUTH_WHITELISTED_IP_NETWORKS = env.list('BASIC_AUTH_WHITELISTED_IP_NETWORKS', []) + +## Django Elevate settings + +[How this works?](https://django-elevate.readthedocs.io/en/latest/how/index.html) + +How long should Elevate mode be active for? + + ELEVATE_COOKIE_AGE = env.int("ELEVATE_COOKIE_AGE", 3600) # 1 hours + +# An extra salt to be added into the cookie signature. + + ELEVATE_COOKIE_SALT = env.str("ELEVATE_COOKIE_SALT", SECRET_KEY) diff --git a/hypha/apply/activity/adapters/activity_feed.py b/hypha/apply/activity/adapters/activity_feed.py index 6613dcf8a8631105c6641ca4adde8ccf541d6cb2..bd3e6ca898778a9c2e5d672e12033884a43672df 100644 --- a/hypha/apply/activity/adapters/activity_feed.py +++ b/hypha/apply/activity/adapters/activity_feed.py @@ -4,7 +4,7 @@ from django.db.models import Model as DjangoModel from django.utils import timezone from django.utils.translation import gettext as _ -from hypha.apply.activity.models import ALL, TEAM +from hypha.apply.activity.models import ALL, APPLICANT, TEAM from hypha.apply.activity.options import MESSAGES from hypha.apply.projects.utils import ( get_invoice_public_status, @@ -41,12 +41,16 @@ class ActivityAdapter(AdapterBase): MESSAGES.REVIEW_OPINION: _( "{user} {opinion.opinion_display}s with {opinion.review.author}s review of {source}" ), - MESSAGES.CREATED_PROJECT: _("Created"), + MESSAGES.DELETE_REVIEW_OPINION: _( + "{user} deleted the opinion for review: {review_opinion.review}" + ), + MESSAGES.CREATED_PROJECT: _("Created project"), MESSAGES.PROJECT_TRANSITION: "handle_project_transition", MESSAGES.UPDATE_PROJECT_LEAD: _( "Lead changed from {old_lead} to {source.lead}" ), MESSAGES.SEND_FOR_APPROVAL: _("Requested approval"), + MESSAGES.APPROVE_PAF: _("PAF assigned to {user}"), MESSAGES.APPROVE_PROJECT: _("Approved"), MESSAGES.REQUEST_PROJECT_CHANGE: _( 'Requested changes for acceptance: "{comment}"' @@ -68,6 +72,7 @@ class ActivityAdapter(AdapterBase): MESSAGES.UNARCHIVE_SUBMISSION: _( "{user} has unarchived the submission: {source.title}" ), + MESSAGES.DELETE_INVOICE: _("Deleted an invoice"), } def recipients(self, message_type, **kwargs): @@ -79,15 +84,29 @@ class ActivityAdapter(AdapterBase): MESSAGES.REVIEWERS_UPDATED, MESSAGES.SCREENING, MESSAGES.REVIEW_OPINION, + MESSAGES.DELETE_REVIEW_OPINION, MESSAGES.BATCH_REVIEWERS_UPDATED, MESSAGES.PARTNERS_UPDATED, MESSAGES.APPROVE_PROJECT, MESSAGES.REQUEST_PROJECT_CHANGE, MESSAGES.SEND_FOR_APPROVAL, + MESSAGES.APPROVE_PAF, MESSAGES.NEW_REVIEW, + MESSAGES.UPDATE_PROJECT_LEAD, ]: return {"visibility": TEAM} + if message_type in [ + MESSAGES.CREATED_PROJECT, + MESSAGES.APPROVE_CONTRACT, + MESSAGES.UPLOAD_CONTRACT, + MESSAGES.SUBMIT_CONTRACT_DOCUMENTS, + MESSAGES.UPDATE_INVOICE_STATUS, + MESSAGES.DELETE_INVOICE, + MESSAGES.CREATE_INVOICE, + ]: + return {"visibility": APPLICANT} + source = source or sources[0] if is_transition(message_type) and not source.phase.permissions.can_view( source.user diff --git a/hypha/apply/activity/adapters/base.py b/hypha/apply/activity/adapters/base.py index f8263851b3b7cae339bb77ce99667e48159cee43..894b880daf18722777452772dd94701f0c47f7d1 100644 --- a/hypha/apply/activity/adapters/base.py +++ b/hypha/apply/activity/adapters/base.py @@ -16,6 +16,7 @@ neat_related = { MESSAGES.SCREENING: "old_status", MESSAGES.REVIEW_OPINION: "opinion", MESSAGES.DELETE_REVIEW: "review", + MESSAGES.DELETE_REVIEW_OPINION: "review_opinion", MESSAGES.EDIT_REVIEW: "review", MESSAGES.CREATED_PROJECT: "submission", MESSAGES.PROJECT_TRANSITION: "old_stage", diff --git a/hypha/apply/activity/adapters/slack.py b/hypha/apply/activity/adapters/slack.py index 5925265e966a5c3b61c548ffd93e37f607e44eba..74d0daaf2a2309b8f002c58cd8d47cd4a49137d0 100644 --- a/hypha/apply/activity/adapters/slack.py +++ b/hypha/apply/activity/adapters/slack.py @@ -9,12 +9,13 @@ from hypha.apply.activity.adapters.base import AdapterBase from hypha.apply.activity.adapters.utils import link_to, reviewers_message from hypha.apply.activity.options import MESSAGES from hypha.apply.projects.models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, PAID, + PAYMENT_FAILED, RESUBMITTED, SUBMITTED, ) @@ -73,6 +74,9 @@ class SlackAdapter(AdapterBase): MESSAGES.DELETE_REVIEW: _( "{user} has deleted {review.author} review for <{link}|{source.title}>" ), + MESSAGES.DELETE_REVIEW_OPINION: _( + "{user} has deleted {review_opinion.author} review opinion for <{link}|{source.title}>" + ), MESSAGES.CREATED_PROJECT: _( "{user} has created a Project: <{link}|{source.title}>" ), @@ -171,24 +175,25 @@ class SlackAdapter(AdapterBase): recipients = [self.slack_id(source.lead)] # Notify second reviewer when first reviewer is done. - if message_type == MESSAGES.NEW_REVIEW and related: + if message_type in [MESSAGES.NEW_REVIEW, MESSAGES.REVIEW_OPINION] and related: submission = source - if ( - submission.assigned.with_roles().count() == 2 - and related.author.reviewer - == submission.assigned.with_roles().first().reviewer - ): - recipients.append( - self.slack_id(submission.assigned.with_roles().last().reviewer) - ) + role_reviewers = [ + role_reviewer.reviewer + for role_reviewer in submission.assigned.with_roles() + ] + if related.author.reviewer in role_reviewers: + for reviewer in role_reviewers: + if reviewer != related.author.reviewer: + recipients.append(self.slack_id(reviewer)) if message_type == MESSAGES.UPDATE_INVOICE_STATUS: if related.status in [ SUBMITTED, RESUBMITTED, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, APPROVED_BY_FINANCE_2, PAID, + PAYMENT_FAILED, ]: # Notify project lead/staff return recipients @@ -199,7 +204,7 @@ class SlackAdapter(AdapterBase): for user in User.objects.finances_level_1() if self.slack_id(user) ] - if related.status in [APPROVED_BY_FINANCE_1]: + if related.status in [APPROVED_BY_FINANCE]: # Notify finance 2 return [ self.slack_id(user) diff --git a/hypha/apply/activity/adapters/utils.py b/hypha/apply/activity/adapters/utils.py index ecaffde8a6712ab52d081a7b70f851bba64ba120..98f95af826163c5b59edc738bd0eb1396d8eb45b 100644 --- a/hypha/apply/activity/adapters/utils.py +++ b/hypha/apply/activity/adapters/utils.py @@ -7,7 +7,7 @@ from django.utils.translation import gettext as _ from hypha.apply.activity.options import MESSAGES from hypha.apply.projects.models import ProjectSettings from hypha.apply.projects.models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, DECLINED, @@ -64,10 +64,7 @@ def is_invoice_public_transition(invoice): PAID, ]: return True - if ( - not settings.INVOICE_EXTENDED_WORKFLOW - and invoice.status == APPROVED_BY_FINANCE_1 - ): + if not settings.INVOICE_EXTENDED_WORKFLOW and invoice.status == APPROVED_BY_FINANCE: return True return False diff --git a/hypha/apply/activity/migrations/0076_alter_event_type.py b/hypha/apply/activity/migrations/0076_alter_event_type.py new file mode 100644 index 0000000000000000000000000000000000000000..84e9a723a4104683cb79308af8badd6e528bede1 --- /dev/null +++ b/hypha/apply/activity/migrations/0076_alter_event_type.py @@ -0,0 +1,83 @@ +# Generated by Django 3.2.20 on 2023-09-09 07:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("activity", "0075_alter_activity_visibility"), + ] + + operations = [ + migrations.AlterField( + model_name="event", + name="type", + field=models.CharField( + choices=[ + ("UPDATE_LEAD", "updated lead"), + ("BATCH_UPDATE_LEAD", "batch updated lead"), + ("EDIT_SUBMISSION", "edited submission"), + ("APPLICANT_EDIT", "edited applicant"), + ("NEW_SUBMISSION", "submitted new submission"), + ("DRAFT_SUBMISSION", "submitted new draft submission"), + ("SCREENING", "screened"), + ("TRANSITION", "transitioned"), + ("BATCH_TRANSITION", "batch transitioned"), + ("DETERMINATION_OUTCOME", "sent determination outcome"), + ("BATCH_DETERMINATION_OUTCOME", "sent batch determination outcome"), + ("INVITED_TO_PROPOSAL", "invited to proposal"), + ("REVIEWERS_UPDATED", "updated reviewers"), + ("BATCH_REVIEWERS_UPDATED", "batch updated reviewers"), + ("PARTNERS_UPDATED", "updated partners"), + ("PARTNERS_UPDATED_PARTNER", "partners updated partner"), + ("READY_FOR_REVIEW", "marked ready for review"), + ("BATCH_READY_FOR_REVIEW", "marked batch ready for review"), + ("NEW_REVIEW", "added new review"), + ("COMMENT", "added comment"), + ("PROPOSAL_SUBMITTED", "submitted proposal"), + ("OPENED_SEALED", "opened sealed submission"), + ("REVIEW_OPINION", "reviewed opinion"), + ("DELETE_SUBMISSION", "deleted submission"), + ("DELETE_REVIEW", "deleted review"), + ("DELETE_REVIEW_OPINION", "deleted review opinion"), + ("CREATED_PROJECT", "created project"), + ("UPDATED_VENDOR", "updated contracting information"), + ("UPDATE_PROJECT_LEAD", "updated project lead"), + ("EDIT_REVIEW", "edited review"), + ("SEND_FOR_APPROVAL", "sent for approval"), + ("APPROVE_PROJECT", "approved project"), + ("ASSIGN_PAF_APPROVER", "assign paf approver"), + ("APPROVE_PAF", "approved paf"), + ("PROJECT_TRANSITION", "transitioned project"), + ("REQUEST_PROJECT_CHANGE", "requested project change"), + ("SUBMIT_CONTRACT_DOCUMENTS", "submitted contract documents"), + ("UPLOAD_DOCUMENT", "uploaded document to project"), + ("REMOVE_DOCUMENT", "removed document from project"), + ("UPLOAD_CONTRACT", "uploaded contract to project"), + ("APPROVE_CONTRACT", "approved contract"), + ("CREATE_INVOICE", "created invoice for project"), + ("UPDATE_INVOICE_STATUS", "updated invoice status"), + ("APPROVE_INVOICE", "approve invoice"), + ("DELETE_INVOICE", "deleted invoice"), + ("SENT_TO_COMPLIANCE", "sent project to compliance"), + ("UPDATE_INVOICE", "updated invoice"), + ("SUBMIT_REPORT", "submitted report"), + ("SKIPPED_REPORT", "skipped report"), + ("REPORT_FREQUENCY_CHANGED", "changed report frequency"), + ("DISABLED_REPORTING", "disabled reporting"), + ("REPORT_NOTIFY", "notified report"), + ("CREATE_REMINDER", "created reminder"), + ("DELETE_REMINDER", "deleted reminder"), + ("REVIEW_REMINDER", "reminder to review"), + ("BATCH_DELETE_SUBMISSION", "batch deleted submissions"), + ("BATCH_ARCHIVE_SUBMISSION", "batch archive submissions"), + ("STAFF_ACCOUNT_CREATED", "created new account"), + ("STAFF_ACCOUNT_EDITED", "edited account"), + ("ARCHIVE_SUBMISSION", "archived submission"), + ("UNARCHIVE_SUBMISSION", "unarchived submission"), + ], + max_length=50, + verbose_name="verb", + ), + ), + ] diff --git a/hypha/apply/activity/options.py b/hypha/apply/activity/options.py index bb3861fa7ed90ae0ac1f825a1ef8c11be1dcabb4..117727d85734e3a18584fd615a3a83d8dffa9716 100644 --- a/hypha/apply/activity/options.py +++ b/hypha/apply/activity/options.py @@ -33,6 +33,7 @@ class MESSAGES(TextChoices): REVIEW_OPINION = "REVIEW_OPINION", _("reviewed opinion") DELETE_SUBMISSION = "DELETE_SUBMISSION", _("deleted submission") DELETE_REVIEW = "DELETE_REVIEW", _("deleted review") + DELETE_REVIEW_OPINION = "DELETE_REVIEW_OPINION", _("deleted review opinion") CREATED_PROJECT = "CREATED_PROJECT", _("created project") UPDATED_VENDOR = "UPDATED_VENDOR", _("updated contracting information") UPDATE_PROJECT_LEAD = "UPDATE_PROJECT_LEAD", _("updated project lead") diff --git a/hypha/apply/activity/views.py b/hypha/apply/activity/views.py index 36b5d91e2d6a4c913d63f06e87b0fa7d0271890d..ec106f4224533ac884f0ace33d2a69507a97da61 100644 --- a/hypha/apply/activity/views.py +++ b/hypha/apply/activity/views.py @@ -1,6 +1,8 @@ +from django.conf import settings from django.utils import timezone from django.utils.decorators import method_decorator from django.views.generic import CreateView, ListView +from django_ratelimit.decorators import ratelimit from hypha.apply.users.decorators import staff_required from hypha.apply.utils.views import DelegatedViewMixin @@ -24,6 +26,10 @@ class ActivityContextMixin: return super().get_context_data(**extra, **kwargs) +@method_decorator( + ratelimit(key="user", rate=settings.DEFAULT_RATE_LIMIT, method="POST"), + name="dispatch", +) class CommentFormView(DelegatedViewMixin, CreateView): form_class = CommentForm context_name = "comment_form" diff --git a/hypha/apply/api/v1/tests/test_views.py b/hypha/apply/api/v1/tests/test_views.py index f8fe382d71b67ed0473d0d27b75c6c7e7c26d25b..da222eab59234ae459298b5f9e43e2b385c15735 100644 --- a/hypha/apply/api/v1/tests/test_views.py +++ b/hypha/apply/api/v1/tests/test_views.py @@ -5,7 +5,7 @@ from rest_framework.exceptions import ErrorDetail from hypha.apply.activity.models import ALL, APPLICANT, Activity from hypha.apply.activity.tests.factories import CommentFactory from hypha.apply.projects.models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, SUBMITTED, @@ -183,7 +183,7 @@ class TestInvoiceDeliverableViewset(TestCase): def test_finance2_can_add_deliverables(self): user = Finance2Factory() project = ProjectFactory() - invoice = InvoiceFactory(project=project, status=APPROVED_BY_FINANCE_1) + invoice = InvoiceFactory(project=project, status=APPROVED_BY_FINANCE) deliverable = DeliverableFactory(project=project) self.client.force_login(user) @@ -241,7 +241,7 @@ class TestInvoiceDeliverableViewset(TestCase): def test_finance1_cant_remove_deliverables_after_finance1_approval(self): user = FinanceFactory() project = ProjectFactory() - invoice = InvoiceFactory(project=project, status=APPROVED_BY_FINANCE_1) + invoice = InvoiceFactory(project=project, status=APPROVED_BY_FINANCE) deliverable = DeliverableFactory(project=project) invoice_deliverable = InvoiceDeliverableFactory(deliverable=deliverable) invoice.deliverables.add(invoice_deliverable) @@ -254,7 +254,7 @@ class TestInvoiceDeliverableViewset(TestCase): def test_finance2_can_remove_deliverables(self): user = Finance2Factory() project = ProjectFactory() - invoice = InvoiceFactory(project=project, status=APPROVED_BY_FINANCE_1) + invoice = InvoiceFactory(project=project, status=APPROVED_BY_FINANCE) deliverable = DeliverableFactory(project=project) invoice_deliverable = InvoiceDeliverableFactory(deliverable=deliverable) invoice.deliverables.add(invoice_deliverable) diff --git a/hypha/apply/api/v1/views.py b/hypha/apply/api/v1/views.py index e5f7280120d733d6119043ecc8e71af79b6e4749..4c56b86c3e1ba818ba98bcb0e57c4897f7b87bc3 100644 --- a/hypha/apply/api/v1/views.py +++ b/hypha/apply/api/v1/views.py @@ -348,10 +348,7 @@ class SubmissionCommentViewSet( ) -class CommentViewSet( - mixins.ListModelMixin, - viewsets.GenericViewSet, -): +class CommentViewSet(viewsets.GenericViewSet): """ Edit a comment. """ diff --git a/hypha/apply/funds/models/applications.py b/hypha/apply/funds/models/applications.py index b3ac973ab478080218d404783ab991db8743c042..e4f8e79b7e4472869fe3b6e868cbf4fd1dc30c71 100644 --- a/hypha/apply/funds/models/applications.py +++ b/hypha/apply/funds/models/applications.py @@ -22,9 +22,11 @@ from django.db.models.functions import Coalesce, Left, Length from django.http import Http404 from django.shortcuts import redirect, render from django.template.response import TemplateResponse +from django.utils.decorators import method_decorator from django.utils.functional import cached_property from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ +from django_ratelimit.decorators import ratelimit from modelcluster.fields import ParentalManyToManyField from wagtail.admin.panels import ( FieldPanel, @@ -67,6 +69,9 @@ class ApplicationBaseManager(PageQuerySet): return qs.order_by("end_date") +@method_decorator( + ratelimit(key="ip", rate=settings.DEFAULT_RATE_LIMIT, method="POST"), name="serve" +) class ApplicationBase(EmailForm, WorkflowStreamForm): # type: ignore is_createable = False @@ -489,6 +494,9 @@ class RoundBase(WorkflowStreamForm, SubmittableStreamForm): # type: ignore raise Http404() +@method_decorator( + ratelimit(key="ip", rate=settings.DEFAULT_RATE_LIMIT, method="POST"), name="serve" +) class LabBase(EmailForm, WorkflowStreamForm, SubmittableStreamForm): # type: ignore is_createable = False submission_class = ApplicationSubmission @@ -576,8 +584,9 @@ class LabBase(EmailForm, WorkflowStreamForm, SubmittableStreamForm): # type: ig return self.live def get_form(self, *args, **kwargs): + draft = kwargs.pop("draft", False) user = kwargs.get("user") - form_class = self.get_form_class(user=user) + form_class = self.get_form_class(draft=draft, user=user) form_params = self.get_form_parameters() form_params.update(kwargs) @@ -591,10 +600,10 @@ class LabBase(EmailForm, WorkflowStreamForm, SubmittableStreamForm): # type: ig ) if request.method == "POST": + draft = request.POST.get("draft", False) form = self.get_form( - request.POST, request.FILES, page=self, user=request.user + request.POST, request.FILES, page=self, user=request.user, draft=draft ) - draft = request.POST.get("draft", False) if form.is_valid(): form_submission = SubmittableStreamForm.process_form_submission( self, form, draft=draft diff --git a/hypha/apply/funds/templates/funds/application_base_landing.html b/hypha/apply/funds/templates/funds/application_base_landing.html index e9ac3fca1b71174c74c69b0ed65b302ca2572a3d..1097899405aa599618c02bce4d53bf90da8b76f0 100644 --- a/hypha/apply/funds/templates/funds/application_base_landing.html +++ b/hypha/apply/funds/templates/funds/application_base_landing.html @@ -6,29 +6,57 @@ <div class="wrapper max-w-2xl mt-8"> {% if form_submission.status == 'draft' %} <h3>{% trans "Your application is saved as a draft." %}</h3> - {% else %} - <h3>{% blocktrans %}Thank you for your submission to the {{ ORG_LONG_NAME }}.{% endblocktrans %}</h3> - {% endif %} - <div class="rich-text"> - {% if form_submission.status == 'draft' %} - <p>{% trans "Please note that it is not submitted for review. You can complete your application by following the log-in details emailed to you." %}</p> + + <p>{% trans "Please note that your application is not submitted for review." %}</p> + + {% if request.user.is_authenticated %} + <p>{% trans "You can access your applications from your dashboard. From there, you can complete and submit them." %}</p> {% else %} - <p>{% trans "An e-mail with more information has been sent to the address you entered." %}</p> + <p>{% trans "You can complete your application by following the log-in details emailed to you." %}</p> {% endif %} - <p> - {% blocktrans with email=ORG_EMAIL|urlize %}If you do not receive an e-mail within 15 minutes please check your spam folder and contact {{ email }} for further assistance.{% endblocktrans %}</p> - {% with email_context=page.specific %}<p>{{ email_context.confirmation_text_extra|urlize }}</p>{% endwith %} + {% else %} + <h3>{% blocktrans %}Thank you for your submission to the {{ ORG_LONG_NAME }}.{% endblocktrans %}</h3> - {% block extra_text %}{{ settings.funds.ApplicationSettings.extra_text_round|richtext }}{% endblock %} + <p>{% trans "An e-mail with more information has been sent to the address you entered." %}</p> <p> - {% if request.user.is_authenticated %} - <a href="{% url 'dashboard:dashboard' %}"><button class="button button--primary">{% blocktrans %}Go to my dashboard.{% endblocktrans %}</button></a> - {% else %} - <a href="{% url 'users_public:login' %}"><button class="button button--primary">{% blocktrans %}Log in{% endblocktrans %}</button></a> - {% endif %} + {% blocktrans with email=ORG_EMAIL|urlize %} + If you do not receive an e-mail within 15 minutes + please check your spam folder and contact {{ email }} + for further assistance. + {% endblocktrans %} </p> + + {% with email_context=page.specific %} + <p>{{ email_context.confirmation_text_extra|urlize }}</p> + {% endwith %} + + {% block extra_text %} + <div class="prose"> + {{ settings.funds.ApplicationSettings.extra_text_round|richtext }} + </div> + {% endblock %} + + {% endif %} + + <div class="mt-4"> + {% if request.user.is_authenticated %} + <a + class="button button--primary" + href="{% url 'dashboard:dashboard' %}" + > + {% trans "Go to your dashboard" %} + </a> + {% else %} + <a + class="button button--primary" + href="{% url 'users_public:login' %}" + > + {% trans "Log in" %} + </a> + {% endif %} </div> + </div> {% endblock %} diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html index 1dfba9b0a633c4b58f390eb465acf7944ef3d7ae..66b72c2ee392a2ca37a1a89db3594b86c3658c9b 100644 --- a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html +++ b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html @@ -55,9 +55,8 @@ hx-target="#tab-3 .feed" hx-trigger="open-tab-3 once" data-tab="tab-3" - x-data + x-init="$nextTick(() => { location.hash === '#activity-feed' ? $dispatch('open-tab-3') : '' })" @hashchange.window="location.hash === '#activity-feed' ? $dispatch('open-tab-3') : ''" - x-init="location.hash === '#activity-feed' ? $dispatch('open-tab-3') : ''" > {% trans "Activity feed" %} </a> diff --git a/hypha/apply/funds/templates/funds/includes/review_sidebar_item.html b/hypha/apply/funds/templates/funds/includes/review_sidebar_item.html index 9aaf018142714f18d0b78668f9179ddb0f786a36..11eb7c0fbc512686d177a5f685d563aca1b1918c 100644 --- a/hypha/apply/funds/templates/funds/includes/review_sidebar_item.html +++ b/hypha/apply/funds/templates/funds/includes/review_sidebar_item.html @@ -1,4 +1,4 @@ -{% load wagtailimages_tags %} +{% load wagtailimages_tags heroicons %} <li class="reviews-sidebar__item {% if not reviewer.review %}no-response {% endif %}" @@ -48,6 +48,9 @@ </div> <div></div> <div class="reviews-sidebar__outcome {{ opinion.get_opinion_display|slugify }}">{{ opinion.get_opinion_display}}</div> + <div class="text-center"><a href="{% url 'apply:submissions:reviews:delete_opinion' submission_pk=opinion.review.submission.id pk=opinion.id %}"> + {% heroicon_outline "trash" aria_hidden="true" size=14 class="stroke-red-800 align-middle inline" %}</a> + </div> </li> {% if forloop.last %} </ul> diff --git a/hypha/apply/funds/views.py b/hypha/apply/funds/views.py index 087101453637e6e98c9bfa7d84f4d08324deb883..3761903d5cd29454efabcf263df0639759a81c4d 100644 --- a/hypha/apply/funds/views.py +++ b/hypha/apply/funds/views.py @@ -1271,6 +1271,16 @@ class BaseSubmissionEditView(UpdateView): yield ("save", "white", _("Save draft")) def get_form_kwargs(self): + """ + Returns the keyword arguments for instantiating the form. + + This method is called by the form mixin during form instantiation. + It returns a dictionary of keyword arguments that will be passed to + the form's constructor. + + Returns: + dict: A dictionary of keyword arguments for the form constructor. + """ kwargs = super().get_form_kwargs() instance = kwargs.pop("instance").from_draft() initial = instance.raw_data @@ -1292,13 +1302,36 @@ class BaseSubmissionEditView(UpdateView): for f in initial_file ] + def save_draft_and_refresh_page(self, form) -> HttpResponseRedirect: + self.object.create_revision(draft=True, by=self.request.user) + form.delete_temporary_files() + messages.success(self.request, _("Draft saved")) + return HttpResponseRedirect( + reverse_lazy("funds:submissions:edit", args=(self.object.id,)) + ) + def get_context_data(self, **kwargs): return super().get_context_data(buttons=self.buttons(), **kwargs) def get_form_class(self): - draft = self.request.POST.get("save", False) + """ + Returns the form class for the view. + + This method is called by the view during form instantiation. It returns + the form class that will be used to render the form. + + When trying to save as draft, this method will return a version of form + class that doesn't validate required fields while saving. + + The method also disables any group toggle fields in the form, as they + are not supported on edit forms. + + Returns: + class: The form class for the view. + """ + is_draft = True if "save" in self.request.POST else False form_fields = self.object.get_form_fields( - draft, self.object.raw_data, user=self.request.user + draft=is_draft, form_data=self.object.raw_data, user=self.request.user ) field_blocks = self.object.get_defined_fields() for field_block in field_blocks: @@ -1316,8 +1349,7 @@ class AdminSubmissionEditView(BaseSubmissionEditView): self.object.new_data(form.cleaned_data) if "save" in self.request.POST: - self.object.create_revision(draft=True, by=self.request.user) - return self.form_invalid(form) + return self.save_draft_and_refresh_page(form=form) if "submit" in self.request.POST: revision = self.object.create_revision(by=self.request.user) @@ -1370,9 +1402,7 @@ class ApplicantSubmissionEditView(BaseSubmissionEditView): self.object.save(update_fields=["submit_time", "round"]) if "save" in self.request.POST: - self.object.create_revision(draft=True, by=self.request.user) - messages.success(self.request, _("Submission saved successfully")) - return self.form_invalid(form) + return self.save_draft_and_refresh_page(form=form) revision = self.object.create_revision(by=self.request.user) submitting_proposal = self.object.phase.name in STAGE_CHANGE_ACTIONS diff --git a/hypha/apply/projects/forms/payment.py b/hypha/apply/projects/forms/payment.py index ceb6fe68fa4473bf39847b35d7c7d9d143197397..8379e92de535512b7243fef996db491327a77b48 100644 --- a/hypha/apply/projects/forms/payment.py +++ b/hypha/apply/projects/forms/payment.py @@ -11,15 +11,16 @@ from django_file_form.forms import FileFormMixin from hypha.apply.stream_forms.fields import MultiFileField, SingleFileField from ..models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, DECLINED, INVOICE_STATUS_CHOICES, PAID, + PAYMENT_FAILED, RESUBMITTED, SUBMITTED, Invoice, @@ -59,27 +60,29 @@ class ChangeInvoiceStatusForm(forms.ModelForm): ), APPROVED_BY_STAFF: filter_request_choices( [ - CHANGES_REQUESTED_BY_FINANCE_1, - APPROVED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, + APPROVED_BY_FINANCE, ], user_choices, ), - CHANGES_REQUESTED_BY_FINANCE_1: filter_request_choices( + CHANGES_REQUESTED_BY_FINANCE: filter_request_choices( [CHANGES_REQUESTED_BY_STAFF, DECLINED], user_choices ), - APPROVED_BY_FINANCE_1: filter_request_choices([PAID], user_choices), + APPROVED_BY_FINANCE: filter_request_choices([PAID], user_choices), + PAID: filter_request_choices([PAYMENT_FAILED], user_choices), + PAYMENT_FAILED: filter_request_choices([PAID], user_choices), } if settings.INVOICE_EXTENDED_WORKFLOW: possible_status_transitions_lut.update( { CHANGES_REQUESTED_BY_FINANCE_2: filter_request_choices( [ - CHANGES_REQUESTED_BY_FINANCE_1, - APPROVED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, + APPROVED_BY_FINANCE, ], user_choices, ), - APPROVED_BY_FINANCE_1: filter_request_choices( + APPROVED_BY_FINANCE: filter_request_choices( [CHANGES_REQUESTED_BY_FINANCE_2, APPROVED_BY_FINANCE_2], user_choices, ), diff --git a/hypha/apply/projects/migrations/0080_alter_invoice_status.py b/hypha/apply/projects/migrations/0080_alter_invoice_status.py new file mode 100644 index 0000000000000000000000000000000000000000..1378fa06a539f5df4c4fc04afd20e2c0025f90f9 --- /dev/null +++ b/hypha/apply/projects/migrations/0080_alter_invoice_status.py @@ -0,0 +1,34 @@ +# Generated by Django 3.2.20 on 2023-09-19 06:23 + +from django.db import migrations +import django_fsm + + +class Migration(migrations.Migration): + dependencies = [ + ("application_projects", "0079_alter_invoice_add_fields"), + ] + + operations = [ + migrations.AlterField( + model_name="invoice", + name="status", + field=django_fsm.FSMField( + choices=[ + ("submitted", "Submitted"), + ("resubmitted", "Resubmitted"), + ("changes_requested_staff", "Changes requested by staff"), + ("changes_requested_finance_1", "Changes requested by finance"), + ("changes_requested_finance_2", "Changes requested by finance 2"), + ("approved_by_staff", "Approved by staff"), + ("approved_by_finance_1", "Approved by finance"), + ("approved_by_finance_2", "Approved by finance 2"), + ("paid", "Paid"), + ("payment_failed", "Payment failed"), + ("declined", "Declined"), + ], + default="submitted", + max_length=50, + ), + ), + ] diff --git a/hypha/apply/projects/models/payment.py b/hypha/apply/projects/models/payment.py index 952ec3264c4ce33b345111c042efca24fa28dea8..c96cccf88764c3f1812e6a9f9bfce8a227ff4dd6 100644 --- a/hypha/apply/projects/models/payment.py +++ b/hypha/apply/projects/models/payment.py @@ -18,24 +18,26 @@ from hypha.apply.utils.storage import PrivateStorage SUBMITTED = "submitted" RESUBMITTED = "resubmitted" CHANGES_REQUESTED_BY_STAFF = "changes_requested_staff" -CHANGES_REQUESTED_BY_FINANCE_1 = "changes_requested_finance_1" +CHANGES_REQUESTED_BY_FINANCE = "changes_requested_finance_1" CHANGES_REQUESTED_BY_FINANCE_2 = "changes_requested_finance_2" APPROVED_BY_STAFF = "approved_by_staff" -APPROVED_BY_FINANCE_1 = "approved_by_finance_1" +APPROVED_BY_FINANCE = "approved_by_finance_1" APPROVED_BY_FINANCE_2 = "approved_by_finance_2" PAID = "paid" +PAYMENT_FAILED = "payment_failed" DECLINED = "declined" INVOICE_STATUS_CHOICES = [ (SUBMITTED, _("Submitted")), (RESUBMITTED, _("Resubmitted")), - (CHANGES_REQUESTED_BY_STAFF, _("Changes Requested by Staff")), - (CHANGES_REQUESTED_BY_FINANCE_1, _("Changes Requested by Finance 1")), - (CHANGES_REQUESTED_BY_FINANCE_2, _("Changes Requested by Finance 2")), - (APPROVED_BY_STAFF, _("Approved by Staff")), - (APPROVED_BY_FINANCE_1, _("Approved by Finance 1")), - (APPROVED_BY_FINANCE_2, _("Approved by Finance 2")), + (CHANGES_REQUESTED_BY_STAFF, _("Changes requested by staff")), + (CHANGES_REQUESTED_BY_FINANCE, _("Changes requested by finance")), + (CHANGES_REQUESTED_BY_FINANCE_2, _("Changes requested by finance 2")), + (APPROVED_BY_STAFF, _("Approved by staff")), + (APPROVED_BY_FINANCE, _("Approved by finance")), + (APPROVED_BY_FINANCE_2, _("Approved by finance 2")), (PAID, _("Paid")), + (PAYMENT_FAILED, _("Payment failed")), (DECLINED, _("Declined")), ] @@ -44,26 +46,31 @@ INVOICE_TRANISTION_TO_RESUBMITTED = [ SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, ] INVOICE_STATUS_PM_CHOICES = [CHANGES_REQUESTED_BY_STAFF, APPROVED_BY_STAFF, DECLINED] INVOICE_STATUS_FINANCE_1_CHOICES = [ - CHANGES_REQUESTED_BY_FINANCE_1, - APPROVED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, + APPROVED_BY_FINANCE, + DECLINED, PAID, + PAYMENT_FAILED, ] INVOICE_STATUS_FINANCE_2_CHOICES = [] if settings.INVOICE_EXTENDED_WORKFLOW: INVOICE_STATUS_FINANCE_1_CHOICES = [ - CHANGES_REQUESTED_BY_FINANCE_1, - APPROVED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, + APPROVED_BY_FINANCE, + DECLINED, ] INVOICE_STATUS_FINANCE_2_CHOICES = [ CHANGES_REQUESTED_BY_FINANCE_2, APPROVED_BY_FINANCE_2, + DECLINED, PAID, + PAYMENT_FAILED, ] @@ -89,7 +96,7 @@ class InvoiceQueryset(models.QuerySet): return self.filter(status=APPROVED_BY_STAFF) def approved_by_finance_1(self): - return self.filter(status=APPROVED_BY_FINANCE_1) + return self.filter(status=APPROVED_BY_FINANCE) def approved_by_finance_2(self): return self.filter(status=APPROVED_BY_FINANCE_2) @@ -97,20 +104,18 @@ class InvoiceQueryset(models.QuerySet): def waiting_to_convert(self): if settings.INVOICE_EXTENDED_WORKFLOW: return self.filter(status=APPROVED_BY_FINANCE_2) - return self.filter(status=APPROVED_BY_FINANCE_1) + return self.filter(status=APPROVED_BY_FINANCE) def for_finance_1(self): if settings.INVOICE_EXTENDED_WORKFLOW: return self.filter( status__in=[APPROVED_BY_STAFF, CHANGES_REQUESTED_BY_FINANCE_2] ) - return self.filter(status__in=[APPROVED_BY_STAFF, APPROVED_BY_FINANCE_1]) + return self.filter(status__in=[APPROVED_BY_STAFF, APPROVED_BY_FINANCE]) def for_finance_2(self): if settings.INVOICE_EXTENDED_WORKFLOW: - return self.filter( - status__in=[APPROVED_BY_FINANCE_1, APPROVED_BY_FINANCE_2] - ) + return self.filter(status__in=[APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2]) return [] def rejected(self): @@ -231,7 +236,7 @@ class Invoice(models.Model): return True if user.is_apply_staff: - if self.status in {SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE_1}: + if self.status in {SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE}: return True return False @@ -248,7 +253,7 @@ class Invoice(models.Model): ): return False # Users can't change status - if self.status in {PAID, DECLINED}: + if self.status in {DECLINED}: return False if user.is_contracting: @@ -260,7 +265,7 @@ class Invoice(models.Model): SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, }: return True @@ -269,11 +274,21 @@ class Invoice(models.Model): if self.status in {APPROVED_BY_STAFF, CHANGES_REQUESTED_BY_FINANCE_2}: return True else: - if self.status in {APPROVED_BY_STAFF, APPROVED_BY_FINANCE_1}: + if self.status in { + APPROVED_BY_STAFF, + APPROVED_BY_FINANCE, + PAID, + PAYMENT_FAILED, + }: return True if user.is_finance_level_2: - if self.status in {APPROVED_BY_FINANCE_1, APPROVED_BY_FINANCE_2}: + if self.status in { + APPROVED_BY_FINANCE, + APPROVED_BY_FINANCE_2, + PAID, + PAYMENT_FAILED, + }: return True return False @@ -284,7 +299,7 @@ class Invoice(models.Model): ): return False if user.is_apply_staff: - if self.status in {SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE_1}: + if self.status in {SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE}: return True if user.is_finance_level_1: if self.status in {APPROVED_BY_STAFF}: @@ -294,7 +309,7 @@ class Invoice(models.Model): ]: return True if user.is_finance_level_2: - if self.status in {APPROVED_BY_FINANCE_1}: + if self.status in {APPROVED_BY_FINANCE}: return True return False diff --git a/hypha/apply/projects/tables.py b/hypha/apply/projects/tables.py index 97e177d3f0f485b8e1e8ba03e67b9eadc376fb05..117d6db83bd59105cf473888bb3029e413ea1be9 100644 --- a/hypha/apply/projects/tables.py +++ b/hypha/apply/projects/tables.py @@ -8,7 +8,7 @@ from .models import Invoice, Project, Report class BaseInvoiceTable(tables.Table): - vendor_document_number = tables.LinkColumn( + invoice_number = tables.LinkColumn( "funds:projects:invoice-detail", verbose_name=_("Invoice Number"), args=[tables.utils.A("project__pk"), tables.utils.A("pk")], diff --git a/hypha/apply/projects/templates/application_projects/invoice_detail.html b/hypha/apply/projects/templates/application_projects/invoice_detail.html index 01ad8ead450eb4d8a513b43a88cfcdd131283149..edf5fa4d9a052b5374f2bf72b3be8b3ddf454b25 100644 --- a/hypha/apply/projects/templates/application_projects/invoice_detail.html +++ b/hypha/apply/projects/templates/application_projects/invoice_detail.html @@ -19,9 +19,8 @@ <div class="card card--solid"> <p class="card__text"><b>{% trans "Invoice number" %}:</b> {{ object.invoice_number }}</p> {% is_vendor_setup request as show_vendor_information %} - {% if show_vendor_information %} - <p class="card__text"><b>{% trans "Vendor" %}:</b> {{ object.project.vendor.name }}</p> - {% endif %} + <p class="card__text"><b>{% trans "Vendor" %}:</b> + {% if show_vendor_information %}{{ object.project.vendor.name }}{% else %}{{ object.project.user }}{% endif %}</p> <p class="card__text"><b>{% trans "Lead" %}:</b> {{ object.project.lead }}</p> <p class="card__text"><b>{% trans "Fund" %}:</b> {{ object.project.submission.page }}</p> </div> @@ -29,18 +28,32 @@ <div class="flex-none"> <p><b>{% trans "Status" %}: </b></p> </div> - <div class="flex-1 pl-2"> + <div class="pl-2"> {% extract_status latest_activity user as latest_activity_status %} - <p>{{ latest_activity_status }} ({{ latest_activity.user }})</p> + {% get_comment_for_invoice_action object latest_activity as latest_activity_comment %} + <p>{{ latest_activity_status }} {% if user.is_applicant and latest_activity.user != user %} ({{ ORG_SHORT_NAME }}){% else %}({{ latest_activity.user }}){% endif %} + <span class="text-gray-400">{{ latest_activity.timestamp }}</span> + {% if latest_activity_comment %} + <svg class="icon icon--request-changes"><use xlink:href="#request-changes"></use></svg> + <a href="{% url 'apply:projects:detail' pk=object.project.id %}#communications#{{ latest_activity_comment.id }}" class="font-bold" target="_blank">View comment</a> + {% endif %} + </p> {% for activity in activities %} {% extract_status activity user as activity_status %} - <p x-show="!collapsed">{{ activity_status }} ({{ activity.user }})</p> + {% get_comment_for_invoice_action object activity as activity_comment %} + <p x-show="!collapsed">{{ activity_status }} {% if user.is_applicant and activity.user != user %} ({{ ORG_SHORT_NAME }}){% else %}({{ activity.user }}){% endif %} + <span class="text-gray-400">{{ activity.timestamp }}</span> + {% if activity_comment %} + <svg class="icon icon--request-changes"><use xlink:href="#request-changes"></use></svg> + <a href="{% url 'apply:projects:detail' pk=object.project.id %}#communications#{{ activity_comment.id }}" class="font-bold" target="_blank">View comment</a> + {% endif %} + </p> {% endfor %} </div> <div class="flex-1 text-right" x-on:click="collapsed = ! collapsed" role="button"> - <p class="font-bold text-light-blue" x-show="collapsed">{% trans "View status history" %} + <p class="font-bold text-light-blue" x-show="collapsed">{% trans "View" %} <svg class="icon icon--arrow-down top-1" aria-hidden=true><use xlink:href="#arrow-down"></use></svg></p> - <p class="font-bold text-light-blue" x-show="!collapsed">{% trans "Hide status history" %} + <p class="font-bold text-light-blue" x-show="!collapsed">{% trans "Hide" %} <svg class="icon icon--arrow-up top-1" aria-hidden=true><use xlink:href="#arrow-up"></use></svg></p> </div> diff --git a/hypha/apply/projects/templates/application_projects/paf_export.html b/hypha/apply/projects/templates/application_projects/paf_export.html index 56a23d796bc9f22f7b993f3ea4c9f153841613b9..c5b3c55c1f0c2749929c88be345b75a76b77f4a9 100644 --- a/hypha/apply/projects/templates/application_projects/paf_export.html +++ b/hypha/apply/projects/templates/application_projects/paf_export.html @@ -39,7 +39,6 @@ .title { text-align: center; font-size: 22px; - font-weight: bold; } p { font-size: 16px; @@ -62,37 +61,35 @@ </head> <body> <div> - {%block page_header%} - <h1 class="title"> {{ org_name }}(Project Approval Form | <a href="{{ project_link }}">{{ title }}</a>)</h1> - {%endblock%} {%block content%} <table id="page-width"> <!-- Project details in table format --> <tr> - <td class="align-left"> - <b>Project Title</b> + <td rowspan="4" align="left" class="align-left"> + <p class="title"> <b>{{ org_name|upper }}</b> PROJECT APPROVAL FORM</p> </td> <td align="right" class="align-right"> - <b>Project ID</b> + <b>Project Title</b> </td> </tr> <tr> - <td> - {{ title }} + <td align="right" class="align-right"> + <a href="{{ project_link }}">{{ title }}</a> </td> + </tr> + <tr> <td align="right" class="align-right"> - {{ id }} + <b>Project ID</b> </td> </tr> - <tr></tr> - <tr> - <td class="align-left"> - <b>Contractor: </b> {{ contractor_name|default:"None" }} + <td align="right" class="align-right"> + {{ id }} </td> </tr> </table> + <br> <!-- PAF fields data in paragraph format--> {% for field_name, field_value in paf_data.items %} <p><b>{{ field_name }}</b></p> diff --git a/hypha/apply/projects/templates/application_projects/project_approval_detail.html b/hypha/apply/projects/templates/application_projects/project_approval_detail.html index 1b27a780deb1094d4cf2a69c8b5b7a02ef854188..f2f5eb89c4eabcd7d88b02b16ecc2e7f801231b7 100644 --- a/hypha/apply/projects/templates/application_projects/project_approval_detail.html +++ b/hypha/apply/projects/templates/application_projects/project_approval_detail.html @@ -32,7 +32,7 @@ <div class="wrapper wrapper--large wrapper--tabs"> <div class="wrapper wrapper--sidebar"> <article class="wrapper--sidebar--inner"> - <h4>{% trans "Project Information" %}</h4> + <h4 class="mb-2">{% trans "Project Information" %}</h4> <div class="card card--solid"> {% if object.output_answers %} @@ -49,7 +49,7 @@ {% endif %} </div> - <h4>{% trans "Approvals" %}</h4> + <h4 class="mb-2">{% trans "Approvals" %}</h4> <div class="card card--solid"> {% for approval in project.paf_approvals.all %} {% if approval.approved %} @@ -60,7 +60,7 @@ {% endfor %} </div> - <h4>{% trans "Review" %}</h4> + <h4 class="mb-2">{% trans "Review" %}</h4> <div class="card card--solid"> <p class="font-bold mb-0 mt-0">{% trans "Submission lead" %}</p> <p class="mt-2 mb-0">{{ project.submission.lead }}</p> @@ -87,7 +87,7 @@ {% endfor %} </div> - <h4>{% trans "Supporting Documents" %}</h4> + <h4 class="mb-2">{% trans "Supporting Documents" %}</h4> <div class="card card--solid"> <p><a href="{% url 'apply:submissions:simplified' pk=object.submission_id %}">{% trans "Submission" %}</a></p> {% for packet_file in object.packet_files.all %} @@ -120,6 +120,35 @@ {% trans 'Download as DOCX' %}</a> </div> </div> + {% user_can_update_paf_approvers object user request as can_update_paf_approvers %} + {% if can_update_paf_approvers %} + {% if user != project.lead %} + <a data-fancybox + data-src="#change-assigned-paf-approvers" + class="button button--bottom-space button--white button--full-width" + href="#"> + {% trans "Change approver" %} + </a> + <div class="modal" id="change-assigned-paf-approvers"> + <h4 class="modal__project-header-bar">{% trans "Change Approver" %}</h4> + <p>{% trans "Selected approver will be notified. On unselecting, every listed member here will be notified." %} </p> + {% trans "Submit" as submit %} + {% include 'funds/includes/delegated_form_base.html' with form=assign_approvers_form value=submit %} + </div> + {% endif %} + {% endif %} + {% user_can_assign_approvers_to_project object user request as can_assign_paf_approvers %} + {% if can_assign_paf_approvers %} + <a data-fancybox data-src="#assign-paf-approvers" class="button button--bottom-space button--primary button--full-width" href="#"> + {% trans "Assign approver" %} + </a> + <div class="modal" id="assign-paf-approvers"> + <h4 class="modal__project-header-bar">{% trans "Assign Approver" %}</h4> + <p>{% trans "Selected approver will be notified. On unselecting, every listed member here will be notified." %} </p> + {% trans "Submit" as submit %} + {% include 'funds/includes/delegated_form_base.html' with form=assign_approvers_form value=submit %} + </div> + {% endif %} {% if can_update_paf_status %} <a data-fancybox data-src="#change-status" class="button button--primary button--full-width {% if user_can_approve %} is-disabled {% endif %}" href="#">{% trans "Update Status" %}</a> <div class="modal" id="change-status"> diff --git a/hypha/apply/projects/templates/application_projects/project_detail.html b/hypha/apply/projects/templates/application_projects/project_detail.html index e566323670da04ed72d58656db0b457e3ff30ad3..73183c690c009a148a1f0ca314119617d8c659ab 100644 --- a/hypha/apply/projects/templates/application_projects/project_detail.html +++ b/hypha/apply/projects/templates/application_projects/project_detail.html @@ -149,13 +149,15 @@ {% user_next_step_on_project object user request=request as next_step %} {% if next_step %} {% if mobile %} - <a class="js-actions-toggle button button--white button--full-width button--actions">{% trans "Next Step" %}</a> + <a class="js-actions-toggle button button--white button--full-width button--actions">{{ next_step.heading }}</a> {% endif %} <div class="js-actions-sidebar sidebar__inner sidebar__inner--actions {% if mobile %}sidebar__inner--mobile{% endif %}"> - <h5>{% trans "Next Step" %}</h5> - <p>{{ next_step }}</p> + <h5><svg class="icon icon--side-arrow"><use xlink:href="#side-arrow"></use></svg> + {{ next_step.heading }} + </h5> + <p>{{ next_step.text }}</p> {% user_next_step_instructions object user as instructions %} {% if instructions %} <div class="sidebar__inner--actions--instructions"> diff --git a/hypha/apply/projects/templatetags/invoice_tools.py b/hypha/apply/projects/templatetags/invoice_tools.py index 49bdcbb4321379d8aa081046f18dd7c8c17dea49..a808740e74b350fe690ce82fc139e7aeda5c08e1 100644 --- a/hypha/apply/projects/templatetags/invoice_tools.py +++ b/hypha/apply/projects/templatetags/invoice_tools.py @@ -1,7 +1,11 @@ import decimal +from datetime import timedelta from django import template +from django.conf import settings +from django.utils.translation import gettext_lazy as _ +from hypha.apply.activity.models import Activity from hypha.apply.activity.templatetags.activity_tags import display_for from hypha.apply.projects.models.project import ( CLOSING, @@ -92,9 +96,24 @@ def get_invoice_form_id(form, invoice): def extract_status(activity, user): if activity and user: invoice_activity_message = display_for(activity, user) - return invoice_activity_message.replace( + invoice_status = invoice_activity_message.replace( "Updated Invoice status to: ", "" ).replace(".", "") + if " by " not in str(invoice_status) and not user.is_applicant: + if activity.user.is_apply_staff: + user_role = "staff" + elif ( + activity.user.is_finance_level_2 and settings.INVOICE_EXTENDED_WORKFLOW + ): + user_role = "finance2" + elif activity.user.is_finance: + user_role = "finance" + else: + user_role = "vendor" + return _("{status} by {user_role}").format( + status=invoice_status, user_role=user_role + ) + return invoice_status return "" @@ -103,3 +122,16 @@ def display_invoice_status_for_user(user, invoice): if user.is_apply_staff or user.is_contracting or user.is_finance: return invoice.status_display return get_invoice_public_status(invoice_status=invoice.status) + + +@register.simple_tag +def get_comment_for_invoice_action(invoice, action): + if action and invoice: + return Activity.comments.filter( + timestamp__range=( + action.timestamp - timedelta(minutes=1), + action.timestamp + timedelta(minutes=1), + ), + related_content_type__model="invoice", + related_object_id=invoice.id, + ).first() diff --git a/hypha/apply/projects/templatetags/project_tags.py b/hypha/apply/projects/templatetags/project_tags.py index e68e10b293e4bfc529fc799e308782cb20e4f170..5432966ef40093f975ff4610e302678fb5261e42 100644 --- a/hypha/apply/projects/templatetags/project_tags.py +++ b/hypha/apply/projects/templatetags/project_tags.py @@ -32,24 +32,45 @@ def user_next_step_on_project(project, user, request=None): if project.status == DRAFT: if user.is_apply_staff: if not project.user_has_updated_details: - return _("Fill in the Approval Form(PAF)") + return { + "heading": _("To do"), + "text": _("Fill in the Approval Form(PAF)"), + } if project.paf_approvals.exists(): - return _("Resubmit project documents for approval") - return _("Submit project documents for approval") + return { + "heading": _("To do"), + "text": _("Resubmit project documents for approval"), + } + return { + "heading": _("To do"), + "text": _("Submit project documents for approval"), + } elif user.is_applicant: - return _( - "Awaiting project documents to be created and approved by {org_short_name} internally. " - "Please check back when the project has moved to contracting stage." - ).format(org_short_name=settings.ORG_SHORT_NAME) + return { + "heading": _("Waiting for"), + "text": _( + "Awaiting project documents to be created and approved by {org_short_name} internally. " + "Please check back when the project has moved to contracting stage." + ).format(org_short_name=settings.ORG_SHORT_NAME), + } if project.paf_approvals.exists(): - return _("Changes requested. Awaiting documents to be resubmitted.") - return _("Awaiting approval form to be created.") + return { + "heading": _("Waiting for"), + "text": _("Changes requested. Awaiting documents to be resubmitted."), + } + return { + "heading": _("Waiting for"), + "text": _("Awaiting approval form to be created."), + } elif project.status == INTERNAL_APPROVAL: if user.is_applicant: - return _( - "Awaiting project documents to be created and approved by {org_short_name} internally. " - "Please check back when the project has moved to contracting stage." - ).format(org_short_name=settings.ORG_SHORT_NAME) + return { + "heading": _("Waiting for"), + "text": _( + "Awaiting project documents to be created and approved by {org_short_name} internally. " + "Please check back when the project has moved to contracting stage." + ).format(org_short_name=settings.ORG_SHORT_NAME), + } if request: project_settings = ProjectSettings.for_request(request=request) @@ -59,12 +80,20 @@ def user_next_step_on_project(project, user, request=None): ).first() if latest_unapproved_approval: if latest_unapproved_approval.user: - return _("Awaiting approval. Assigned to {approver}").format( - approver=latest_unapproved_approval.user - ) - return _("Awaiting {reviewer_role} to assign an approver").format( - reviewer_role=latest_unapproved_approval.paf_reviewer_role.label - ) + return { + "heading": _("Waiting for"), + "text": _( + "Awaiting approval. Assigned to {approver}" + ).format(approver=latest_unapproved_approval.user), + } + return { + "heading": _("Waiting for"), + "text": _( + "Awaiting {reviewer_role} to assign an approver" + ).format( + reviewer_role=latest_unapproved_approval.paf_reviewer_role.label + ), + } else: matched_roles = PAFReviewersRole.objects.annotate( roles_count=Count("user_roles") @@ -72,57 +101,109 @@ def user_next_step_on_project(project, user, request=None): for group in user.groups.all(): matched_roles = matched_roles.filter(user_roles__id=group.id) if not matched_roles: - return _("Awaiting PAF approval form to be approved") + return { + "heading": _("Waiting for"), + "text": _("Awaiting PAF approval form to be approved"), + } else: matched_unapproved_approval = project.paf_approvals.filter( approved=False, paf_reviewer_role__in=matched_roles ) if not matched_unapproved_approval.exists(): - return _("Awaiting approval from other approvers teams") + return { + "heading": _("Waiting for"), + "text": _("Awaiting approval from other approvers teams"), + } else: if matched_unapproved_approval.first().user: - return _( - "Awaiting approval. Assigned to {approver}" - ).format(approver=matched_unapproved_approval.first().user) - return _( - "Awaiting {reviewer_role} to assign an approver" - ).format( - reviewer_role=matched_unapproved_approval.first().paf_reviewer_role.label - ) - - return _("Awaiting project approval from assigned approvers") + return { + "heading": _("Waiting for"), + "text": _( + "Awaiting approval. Assigned to {approver}" + ).format( + approver=matched_unapproved_approval.first().user + ), + } + return { + "heading": _("Waiting for"), + "text": _( + "Awaiting {reviewer_role} to assign an approver" + ).format( + reviewer_role=matched_unapproved_approval.first().paf_reviewer_role.label + ), + } + + return { + "heading": _("Waiting for"), + "text": _("Awaiting project approval from assigned approvers"), + } elif project.status == CONTRACTING: if not project.contracts.exists(): if user.is_applicant: - return _("Awaiting signed contract from {org_short_name}").format( - org_short_name=settings.ORG_SHORT_NAME - ) - return _("Awaiting signed contract from Contracting team") + return { + "heading": _("Waiting for"), + "text": _("Awaiting signed contract from {org_short_name}").format( + org_short_name=settings.ORG_SHORT_NAME + ), + } + return { + "heading": _("Waiting for"), + "text": _("Awaiting signed contract from Contracting team"), + } else: contract = project.contracts.order_by("-created_at").first() if not contract.signed_by_applicant: if user.is_applicant: - return _("Awaiting contract documents to be submitted by you.") - return _("Awaiting countersigned contract from Vendor") + return { + "heading": _("To do"), + "text": _( + "Awaiting contract documents to be submitted by you." + ), + } + return { + "heading": _("Waiting for"), + "text": _("Awaiting countersigned contract from Vendor"), + } elif not project.submitted_contract_documents: if user.is_applicant: - return _("Awaiting contract documents submission by you") - return _("Awaiting contract documents submission from Vendor") + return { + "heading": _("To do"), + "text": _("Awaiting contract documents submission by you"), + } + return { + "heading": _("Waiting for"), + "text": _("Awaiting contract documents submission from Vendor"), + } else: if user.is_apply_staff: - return _( - "Review the contract for all relevant details and approve." - ) + return { + "heading": _("To do"), + "text": _( + "Review the contract for all relevant details and approve." + ), + } if user.is_applicant: - return _("Awaiting contract approval from {org_short_name}").format( - org_short_name=settings.ORG_SHORT_NAME - ) - return _("Awaiting contract approval from Staff") + return { + "heading": _("Waiting for"), + "text": _( + "Awaiting contract approval from {org_short_name}" + ).format(org_short_name=settings.ORG_SHORT_NAME), + } + return { + "heading": _("Waiting for"), + "text": _("Awaiting contract approval from Staff"), + } elif project.status == INVOICING_AND_REPORTING: if user.is_applicant and not project.invoices.exists(): - return _("Add invoices") + return { + "heading": _("To do"), + "text": _("Add invoices"), + } elif user.is_apply_staff or user.is_finance: - return _("Review invoice and take action") + return { + "heading": _("To do"), + "text": _("Review invoice and take action"), + } return False diff --git a/hypha/apply/projects/tests/test_forms.py b/hypha/apply/projects/tests/test_forms.py index a1d85c869bfa5d29f3ae686f9b63a4d1344977ca..0c9ff6274fb4b2eca005b0d32f9a94ebd5c8f579 100644 --- a/hypha/apply/projects/tests/test_forms.py +++ b/hypha/apply/projects/tests/test_forms.py @@ -28,10 +28,10 @@ from ..forms.project import ( UploadContractForm, ) from ..models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, DECLINED, @@ -176,7 +176,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): expected = set( filter_request_choices( - [CHANGES_REQUESTED_BY_FINANCE_1, APPROVED_BY_FINANCE_1], + [CHANGES_REQUESTED_BY_FINANCE, APPROVED_BY_FINANCE], invoice_status_user_choices(user), ) ) @@ -190,7 +190,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): expected = set( filter_request_choices( - [CHANGES_REQUESTED_BY_FINANCE_1, APPROVED_BY_FINANCE_1], + [CHANGES_REQUESTED_BY_FINANCE, APPROVED_BY_FINANCE], invoice_status_user_choices(user), ) ) @@ -204,7 +204,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): expected = set( filter_request_choices( - [CHANGES_REQUESTED_BY_FINANCE_1, APPROVED_BY_FINANCE_1], + [CHANGES_REQUESTED_BY_FINANCE, APPROVED_BY_FINANCE], invoice_status_user_choices(user), ) ) @@ -212,7 +212,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): self.assertEqual(expected, actual) def test_staff_choices_with_changes_requested_by_finance1_status(self): - invoice = InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE_1) + invoice = InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE) user = StaffFactory() form = ChangeInvoiceStatusForm(instance=invoice, user=user) @@ -226,7 +226,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): self.assertEqual(expected, actual) def test_finance1_choices_with_changes_requested_by_finance1_status(self): - invoice = InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE_1) + invoice = InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE) user = FinanceFactory() form = ChangeInvoiceStatusForm(instance=invoice, user=user) @@ -240,7 +240,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): self.assertEqual(expected, actual) def test_finance2_choices_with_changes_requested_by_finance1_status(self): - invoice = InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE_1) + invoice = InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE) user = Finance2Factory() form = ChangeInvoiceStatusForm(instance=invoice, user=user) @@ -254,7 +254,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): self.assertEqual(expected, actual) def test_staff_choices_with_approved_by_finance1_status(self): - invoice = InvoiceFactory(status=APPROVED_BY_FINANCE_1) + invoice = InvoiceFactory(status=APPROVED_BY_FINANCE) user = StaffFactory() form = ChangeInvoiceStatusForm(instance=invoice, user=user) @@ -269,7 +269,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=True) def test_finance1_choices_with_approved_by_finance1_status_with_extended_flow(self): - invoice = InvoiceFactory(status=APPROVED_BY_FINANCE_1) + invoice = InvoiceFactory(status=APPROVED_BY_FINANCE) user = FinanceFactory() form = ChangeInvoiceStatusForm(instance=invoice, user=user) @@ -284,7 +284,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=False) def test_finance1_choices_with_approved_by_finance1_status(self): - invoice = InvoiceFactory(status=APPROVED_BY_FINANCE_1) + invoice = InvoiceFactory(status=APPROVED_BY_FINANCE) user = FinanceFactory() form = ChangeInvoiceStatusForm(instance=invoice, user=user) @@ -296,7 +296,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=True) def test_finance2_choices_with_approved_by_finance1_status(self): - invoice = InvoiceFactory(status=APPROVED_BY_FINANCE_1) + invoice = InvoiceFactory(status=APPROVED_BY_FINANCE) user = Finance2Factory() form = ChangeInvoiceStatusForm(instance=invoice, user=user) @@ -317,7 +317,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): expected = set( filter_request_choices( - [CHANGES_REQUESTED_BY_FINANCE_1, APPROVED_BY_FINANCE_1], + [CHANGES_REQUESTED_BY_FINANCE, APPROVED_BY_FINANCE], invoice_status_user_choices(user), ) ) @@ -332,7 +332,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): expected = set( filter_request_choices( - [CHANGES_REQUESTED_BY_FINANCE_1, APPROVED_BY_FINANCE_1], + [CHANGES_REQUESTED_BY_FINANCE, APPROVED_BY_FINANCE], invoice_status_user_choices(user), ) ) @@ -347,7 +347,7 @@ class TestChangeInvoiceStatusFormForm(TestCase): expected = set( filter_request_choices( - [CHANGES_REQUESTED_BY_FINANCE_1, APPROVED_BY_FINANCE_1], + [CHANGES_REQUESTED_BY_FINANCE, APPROVED_BY_FINANCE], invoice_status_user_choices(user), ) ) diff --git a/hypha/apply/projects/tests/test_models.py b/hypha/apply/projects/tests/test_models.py index 4a2199decceb0ee01e53d8eeb77f784f486efc31..df84018b99bf8cb73365b5eef5c8d0bad609aca6 100644 --- a/hypha/apply/projects/tests/test_models.py +++ b/hypha/apply/projects/tests/test_models.py @@ -13,10 +13,10 @@ from hypha.apply.users.tests.factories import ( ) from ..models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, DECLINED, @@ -24,6 +24,7 @@ from ..models.payment import ( INVOICE_STATUS_FINANCE_2_CHOICES, INVOICE_STATUS_PM_CHOICES, PAID, + PAYMENT_FAILED, RESUBMITTED, SUBMITTED, Invoice, @@ -162,7 +163,7 @@ class TestInvoiceModel(TestCase): SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, ] user = StaffFactory() for status in statuses: @@ -172,7 +173,7 @@ class TestInvoiceModel(TestCase): def test_staff_cant_change_status(self): statuses = [ APPROVED_BY_STAFF, - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, CHANGES_REQUESTED_BY_FINANCE_2, DECLINED, @@ -193,7 +194,7 @@ class TestInvoiceModel(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=False) def test_finance1_can_change_status(self): - statuses = [APPROVED_BY_STAFF, APPROVED_BY_FINANCE_1] + statuses = [APPROVED_BY_STAFF, APPROVED_BY_FINANCE, PAID, PAYMENT_FAILED] user = FinanceFactory() for status in statuses: invoice = InvoiceFactory(status=status) @@ -202,10 +203,10 @@ class TestInvoiceModel(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=True) def test_finance1_cant_change_status_with_extended_flow(self): statuses = [ - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, DECLINED, PAID, RESUBMITTED, @@ -220,9 +221,8 @@ class TestInvoiceModel(TestCase): def test_finance1_cant_change_status(self): statuses = [ CHANGES_REQUESTED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, DECLINED, - PAID, RESUBMITTED, SUBMITTED, ] @@ -233,7 +233,7 @@ class TestInvoiceModel(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=True) def test_finance2_can_change_status_with_extended_flow(self): - statuses = [APPROVED_BY_FINANCE_1, APPROVED_BY_FINANCE_2] + statuses = [APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, PAID, PAYMENT_FAILED] user = Finance2Factory() for status in statuses: invoice = InvoiceFactory(status=status) @@ -243,11 +243,10 @@ class TestInvoiceModel(TestCase): def test_finance2_cant_change_status(self): statuses = [ APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, DECLINED, - PAID, RESUBMITTED, SUBMITTED, ] @@ -265,10 +264,10 @@ class TestInvoiceModel(TestCase): def test_applicant_cant_edit_invoice(self): statuses = [ - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, DECLINED, PAID, @@ -279,7 +278,7 @@ class TestInvoiceModel(TestCase): self.assertFalse(invoice.can_user_edit(user)) def test_staff_can_edit_invoice(self): - statuses = [SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE_1] + statuses = [SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE] user = StaffFactory() for status in statuses: invoice = InvoiceFactory(status=status) @@ -287,7 +286,7 @@ class TestInvoiceModel(TestCase): def test_staff_cant_edit_invoice(self): statuses = [ - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, CHANGES_REQUESTED_BY_FINANCE_2, @@ -306,8 +305,8 @@ class TestInvoiceModel(TestCase): RESUBMITTED, CHANGES_REQUESTED_BY_STAFF, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, - APPROVED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, + APPROVED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, APPROVED_BY_FINANCE_2, DECLINED, @@ -319,7 +318,7 @@ class TestInvoiceModel(TestCase): self.assertFalse(invoice.can_user_edit_deliverables(user)) def test_staff_can_edit_deliverables(self): - statuses = [SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE_1] + statuses = [SUBMITTED, RESUBMITTED, CHANGES_REQUESTED_BY_FINANCE] user = StaffFactory() for status in statuses: invoice = InvoiceFactory(status=status) @@ -327,7 +326,7 @@ class TestInvoiceModel(TestCase): def test_staff_cant_edit_deliverables(self): statuses = [ - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, CHANGES_REQUESTED_BY_FINANCE_2, @@ -358,9 +357,9 @@ class TestInvoiceModel(TestCase): def test_finance1_cant_edit_deliverables(self): statuses = [ - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_STAFF, DECLINED, PAID, @@ -374,7 +373,7 @@ class TestInvoiceModel(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=True) def test_finance2_can_edit_deliverables(self): - statuses = [APPROVED_BY_FINANCE_1] + statuses = [APPROVED_BY_FINANCE] user = Finance2Factory() for status in statuses: invoice = InvoiceFactory(status=status) @@ -385,7 +384,7 @@ class TestInvoiceModel(TestCase): statuses = [ APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, DECLINED, @@ -412,7 +411,7 @@ class TestInvoiceQueryset(TestCase): def test_in_progress(self): InvoiceFactory(status=SUBMITTED) InvoiceFactory(status=APPROVED_BY_STAFF) - InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE_1) + InvoiceFactory(status=CHANGES_REQUESTED_BY_FINANCE) InvoiceFactory(status=DECLINED) self.assertEqual(Invoice.objects.in_progress().count(), 3) @@ -421,7 +420,7 @@ class TestInvoiceQueryset(TestCase): self.assertEqual(Invoice.objects.approved_by_staff().count(), 1) def test_approved_by_finance_1(self): - InvoiceFactory(status=APPROVED_BY_FINANCE_1) + InvoiceFactory(status=APPROVED_BY_FINANCE) self.assertEqual(Invoice.objects.approved_by_finance_1().count(), 1) @override_settings(INVOICE_EXTENDED_WORKFLOW=True) @@ -434,7 +433,7 @@ class TestInvoiceQueryset(TestCase): @override_settings(INVOICE_EXTENDED_WORKFLOW=False) def test_for_finance_1(self): InvoiceFactory(status=APPROVED_BY_STAFF) - InvoiceFactory(status=APPROVED_BY_FINANCE_1) + InvoiceFactory(status=APPROVED_BY_FINANCE) InvoiceFactory(status=SUBMITTED) self.assertEqual(Invoice.objects.for_finance_1().count(), 2) diff --git a/hypha/apply/projects/utils.py b/hypha/apply/projects/utils.py index aab11ecce982351b8a8d95d19e02f7c820fcd069..b367f0ea5a08a754c0c7ac86bab50a1872d216f1 100644 --- a/hypha/apply/projects/utils.py +++ b/hypha/apply/projects/utils.py @@ -3,10 +3,10 @@ from django.utils.translation import gettext_lazy as _ from .models import Deliverable, Project from .models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_FINANCE_2, APPROVED_BY_STAFF, - CHANGES_REQUESTED_BY_FINANCE_1, + CHANGES_REQUESTED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2, CHANGES_REQUESTED_BY_STAFF, DECLINED, @@ -120,13 +120,13 @@ def get_paf_status_display(paf_status): def get_invoice_public_status(invoice_status): if ( invoice_status - in [SUBMITTED, RESUBMITTED, APPROVED_BY_STAFF, CHANGES_REQUESTED_BY_FINANCE_1] + in [SUBMITTED, RESUBMITTED, APPROVED_BY_STAFF, CHANGES_REQUESTED_BY_FINANCE] ) or ( - invoice_status in [APPROVED_BY_FINANCE_1, CHANGES_REQUESTED_BY_FINANCE_2] + invoice_status in [APPROVED_BY_FINANCE, CHANGES_REQUESTED_BY_FINANCE_2] and settings.INVOICE_EXTENDED_WORKFLOW ): - return _("Pending Approval") - if (invoice_status == APPROVED_BY_FINANCE_1) or ( + return _("Pending approval") + if (invoice_status == APPROVED_BY_FINANCE) or ( invoice_status == APPROVED_BY_FINANCE_2 and settings.INVOICE_EXTENDED_WORKFLOW ): return _("Approved") diff --git a/hypha/apply/projects/views/payment.py b/hypha/apply/projects/views/payment.py index 1a876dd47aa0ca8cf9fcd5b133efcfc6fb7e7540..7a3f934ad16a3f79ee6bc94715454794eb987654 100644 --- a/hypha/apply/projects/views/payment.py +++ b/hypha/apply/projects/views/payment.py @@ -13,7 +13,7 @@ from django_filters.views import FilterView from django_tables2 import SingleTableMixin from hypha.apply.activity.messaging import MESSAGES, messenger -from hypha.apply.activity.models import ALL, COMMENT, Activity +from hypha.apply.activity.models import APPLICANT, COMMENT, Activity from hypha.apply.users.decorators import staff_or_finance_required from hypha.apply.utils.storage import PrivateMediaView from hypha.apply.utils.views import DelegateableView, DelegatedViewMixin, ViewDispatcher @@ -21,7 +21,7 @@ from hypha.apply.utils.views import DelegateableView, DelegatedViewMixin, ViewDi from ..filters import InvoiceListFilter from ..forms import ChangeInvoiceStatusForm, CreateInvoiceForm, EditInvoiceForm from ..models.payment import ( - APPROVED_BY_FINANCE_1, + APPROVED_BY_FINANCE, APPROVED_BY_STAFF, INVOICE_TRANISTION_TO_RESUBMITTED, Invoice, @@ -73,7 +73,7 @@ class ChangeInvoiceStatusView(DelegatedViewMixin, InvoiceAccessMixin, UpdateView source=self.object.project, timestamp=timezone.now(), message=message, - visibility=ALL, + visibility=APPLICANT, related_object=self.object, ) @@ -82,7 +82,7 @@ class ChangeInvoiceStatusView(DelegatedViewMixin, InvoiceAccessMixin, UpdateView ) or ( settings.INVOICE_EXTENDED_WORKFLOW and self.request.user.is_finance_level_1 - and self.object.status == APPROVED_BY_FINANCE_1 + and self.object.status == APPROVED_BY_FINANCE ): messenger( MESSAGES.APPROVE_INVOICE, @@ -212,7 +212,7 @@ class CreateInvoiceView(CreateView): source=self.project, timestamp=timezone.now(), message=message, - visibility=ALL, + visibility=APPLICANT, related_object=self.object, ) @@ -293,7 +293,7 @@ class EditInvoiceView(InvoiceAccessMixin, UpdateView): source=self.object.project, timestamp=timezone.now(), message=message, - visibility=ALL, + visibility=APPLICANT, related_object=self.object, ) diff --git a/hypha/apply/projects/views/project.py b/hypha/apply/projects/views/project.py index aa58efdd9705ed6f9e0b3880aa5b95bf6db95494..fb0521ec9779db0fb6740ccb4017d864daa3fd5a 100644 --- a/hypha/apply/projects/views/project.py +++ b/hypha/apply/projects/views/project.py @@ -37,7 +37,7 @@ from xhtml2pdf import pisa from hypha.apply.activity.adapters.utils import get_users_for_groups from hypha.apply.activity.messaging import MESSAGES, messenger -from hypha.apply.activity.models import ACTION, ALL, COMMENT, Activity +from hypha.apply.activity.models import ACTION, ALL, COMMENT, TEAM, Activity from hypha.apply.activity.views import ActivityContextMixin, CommentFormView from hypha.apply.stream_forms.models import BaseStreamForm from hypha.apply.users.decorators import ( @@ -535,13 +535,6 @@ class UploadContractDocumentView(DelegatedViewMixin, CreateView): form.instance.project = project response = super().form_valid(form) - messenger( - MESSAGES.UPLOAD_DOCUMENT, - request=self.request, - user=self.request.user, - source=project, - ) - messages.success( self.request, _("Contracting document has been uploaded"), @@ -610,10 +603,11 @@ class ChangePAFStatusView(DelegatedViewMixin, UpdateView): source=self.object, timestamp=timezone.now(), message=paf_status_update_message, - visibility=ALL, + visibility=TEAM, ) if paf_status == REQUEST_CHANGE: + old_stage = self.object.status self.object.status = DRAFT self.object.save(update_fields=["status"]) paf_approval.save() @@ -629,6 +623,13 @@ class ChangePAFStatusView(DelegatedViewMixin, UpdateView): source=self.object, comment=comment, ) + messenger( + MESSAGES.PROJECT_TRANSITION, + request=self.request, + user=self.request.user, + source=self.object, + related=old_stage, + ) messages.success( self.request, _("PAF status has been updated"), @@ -673,7 +674,7 @@ class ChangePAFStatusView(DelegatedViewMixin, UpdateView): source=self.object, timestamp=timezone.now(), message=message, - visibility=ALL, + visibility=TEAM, ) if self.object.is_approved_by_all_paf_reviewers: @@ -1130,7 +1131,7 @@ class ContractDocumentPrivateMediaView(UserPassesTestMixin, PrivateMediaView): @method_decorator(staff_or_finance_or_contracting_required, name="dispatch") class ProjectDetailApprovalView(DelegateableView, DetailView): - form_views = [ChangePAFStatusView] + form_views = [ChangePAFStatusView, UpdateAssignApproversView] model = Project template_name_suffix = "_approval_detail" diff --git a/hypha/apply/review/models.py b/hypha/apply/review/models.py index 19dc4ff3aea5e8d8e77d00b4d36fc20463e6d885..ec1b1bd1667b425d6b7d80555127950d253b5989 100644 --- a/hypha/apply/review/models.py +++ b/hypha/apply/review/models.py @@ -248,6 +248,9 @@ class ReviewOpinion(models.Model): class Meta: unique_together = ("author", "review") + def __str__(self): + return f"Review Opinion for {self.review}" + @property def opinion_display(self): return self.get_opinion_display() diff --git a/hypha/apply/review/templates/review/reviewopinion_confirm_delete.html b/hypha/apply/review/templates/review/reviewopinion_confirm_delete.html new file mode 100644 index 0000000000000000000000000000000000000000..21238b428002c3a7369f43027bbbb54dae56fe34 --- /dev/null +++ b/hypha/apply/review/templates/review/reviewopinion_confirm_delete.html @@ -0,0 +1,22 @@ +{% extends "base-apply.html" %} +{% load i18n %} + +{% block title %}{% trans "Deleting" %}: {{ object }}{% endblock %} + +{% block content %} + <div class="admin-bar"> + <div class="admin-bar__inner"> + <h2 class="heading heading--no-margin">{% trans "Deleting" %}: {{ object }}</h2> + </div> + </div> + + <div class="wrapper wrapper--light-grey-bg wrapper--form wrapper--sidebar"> + <div class="wrapper--sidebar--inner"> + <form class="form" action="" method="post"> + {% csrf_token %} + <p><strong>{% trans "Are you sure you want to delete" %} "{{ object }}"?</strong></p> + <button class="button button--warning button--submit button--top-space" type="submit">{% trans "Confirm" %}</button> + </form> + </div> + </div> +{% endblock %} diff --git a/hypha/apply/review/urls.py b/hypha/apply/review/urls.py index 9c0dc1e41e84d18513018085a289e5780a4a88a2..c5258be782cc370fc106a166c347e82024091b41 100644 --- a/hypha/apply/review/urls.py +++ b/hypha/apply/review/urls.py @@ -6,6 +6,7 @@ from .views import ( ReviewDetailView, ReviewEditView, ReviewListView, + ReviewOpinionDeleteView, ) app_name = "reviews" @@ -16,4 +17,9 @@ urlpatterns = [ path("reviews/<int:pk>/delete/", ReviewDeleteView.as_view(), name="delete"), path("reviews/<int:pk>/edit/", ReviewEditView.as_view(), name="edit"), path("review/", ReviewCreateOrUpdateView.as_view(), name="form"), + path( + "review/opinion/<int:pk>/delete/", + ReviewOpinionDeleteView.as_view(), + name="delete_opinion", + ), ] diff --git a/hypha/apply/review/views.py b/hypha/apply/review/views.py index fe10489a992d8f375fac82f2ce380fd41ae153b1..c098c0a69d884ebb6dc1203955db71e36e612d66 100644 --- a/hypha/apply/review/views.py +++ b/hypha/apply/review/views.py @@ -27,7 +27,7 @@ from hypha.apply.users.decorators import staff_required from hypha.apply.utils.image import generate_image_tag from hypha.apply.utils.views import CreateOrUpdateView -from .models import Review +from .models import Review, ReviewOpinion from .options import DISAGREE @@ -490,3 +490,30 @@ class ReviewDeleteView(UserPassesTestMixin, DeleteView): def get_success_url(self): review = self.get_object() return reverse_lazy("funds:submissions:detail", args=(review.submission.id,)) + + +@method_decorator(login_required, name="dispatch") +class ReviewOpinionDeleteView(DeleteView): + model = ReviewOpinion + raise_exception = True + + def dispatch(self, request, *args, **kwargs): + self.review_opinion = self.get_object() + if self.request.user != self.review_opinion.author.reviewer: + raise PermissionDenied + return super().dispatch(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + messenger( + MESSAGES.DELETE_REVIEW_OPINION, + user=request.user, + request=request, + source=self.review_opinion.review.submission, + related=self.review_opinion, + ) + response = super().delete(request, *args, **kwargs) + return response + + def get_success_url(self): + review = self.review_opinion.review + return reverse_lazy("funds:submissions:detail", args=(review.submission.id,)) diff --git a/hypha/apply/templates/forms/includes/field.html b/hypha/apply/templates/forms/includes/field.html index acd6033620c2782680561c0ef95036bd0eed095f..9a943ba70076455d9c4ca29c809c67f43a918ae2 100644 --- a/hypha/apply/templates/forms/includes/field.html +++ b/hypha/apply/templates/forms/includes/field.html @@ -4,7 +4,7 @@ <div class="form__group {{ field.id_for_label }} form__group--{{ widget_type }} {% if widget_type == 'checkbox_input' %} form__group--checkbox{% endif %}{% if widget_type == 'clearable_file_input' or widget_type == 'multi_file_input' or widget_type == 'single_file_field_widget' or widget_type == 'multi_file_field_widget' %} form__group--file{% endif %}{% if field.help_text %} form__group--wrap{% endif %}{% if field.errors %} form__error{% endif %}{% if is_application and field.field.group_number > 1 %} field-group field-group-{{ field.field.group_number }}{% endif %}{% if is_application and field.field.grouper_for %} form-fields-grouper{% endif %}"{% if is_application and field.field.grouper_for %}data-grouper-for="{{ field.field.grouper_for }}" data-toggle-on="{{ field.field.choices.0.0 }}" data-toggle-off="{{ field.field.choices.1.0 }}"{% endif %}{% if is_application and field.field.group_number > 1 %} data-hidden="{% if not show_all_group_fields and not field.field.visible %}true{% else %}false{% endif %}" data-required="{{ field.field.required_when_visible }}"{% endif %}{% if field.field.word_limit %} data-word-limit="{{ field.field.word_limit }}"{% endif %}> {% if widget_type == 'clearable_file_input' or widget_type == 'multi_file_input' or widget_type == 'single_file_field_widget' or widget_type == 'multi_file_field_widget'%} - <span class="form__question">{{ field.label }}</span> + <span class="form__question form__file-label">{{ field.label }}</span> <label for="{{ field.id_for_label }}" class="form__question form__question--{{ field_type }} {{ widget_type }}" {% if field.field.required %}required{% endif %}> <span>{% trans "Upload" %}</span> {% if field.field.required %} diff --git a/hypha/apply/users/forms.py b/hypha/apply/users/forms.py index 3be84f4dc09514d20c3f57281ef2cf8ff09c0663..13dcd722e7c1e7baffd5d66aa7058f41de46314f 100644 --- a/hypha/apply/users/forms.py +++ b/hypha/apply/users/forms.py @@ -90,6 +90,14 @@ class ProfileForm(forms.ModelForm): return slack + def clean_email(self): + email = self.cleaned_data["email"] + if User.objects.filter(email=email).exists(): + email = ( + self.instance.email + ) # updated email to avoid email existing message, fix information leak. + return email + class BecomeUserForm(forms.Form): user_pk = forms.ModelChoiceField( diff --git a/hypha/apply/users/templates/elevate/elevate.html b/hypha/apply/users/templates/elevate/elevate.html new file mode 100644 index 0000000000000000000000000000000000000000..9a55046959590ced3e9d0930aa3768f83282b2f9 --- /dev/null +++ b/hypha/apply/users/templates/elevate/elevate.html @@ -0,0 +1,39 @@ +{% extends "base-apply.html" %} +{% load i18n wagtailcore_tags %} + +{% block title %}{% trans "Confirm access" %}{% endblock %} +{% block body_class %}bg-white{% endblock %} + +{% block content %} + <div class="max-w-lg px-4 pt-4 mx-auto md:mt-5 md:py-4"> + + <form class="form" method="post" action="./" class="px-4 pt-4"> + {% csrf_token %} + <h2 class="text-2xl">{% trans "Confirm access" %}</h2> + + <p class="px-3 py-2 bg-orange-100 rounded mb-4"> + Signed in as <strong>{{ request.user }} ({{ request.user.email }})</strong> + </p> + + {% if form.non_field_errors %} + <div class="wrapper wrapper--error">{{ form.non_field_errors.as_text }}</div> + {% endif %} + + {% for field in form %} + {% include "forms/includes/field.html" %} + {% endfor %} + + <div class="form__group"> + <button class="button button--primary" type="submit">{% trans "Confirm" %}</button> + </div> + </form> + + <p class="text-xs text-center max-w-sm mt-8 text-gray-500 mx-auto"> + {% blocktrans %} + <strong>Tip:</strong> You are entering sudo mode. After you've performed a sudo-protected + action, you'll only be asked to re-authenticate again after a few hours of inactivity. + {% endblocktrans %} + </p> + + </div> +{% endblock %} diff --git a/hypha/apply/users/templates/users/email_change/update_info_email.html b/hypha/apply/users/templates/users/email_change/update_info_email.html new file mode 100644 index 0000000000000000000000000000000000000000..4bd7c7355094075fc0e584b7b0e437c12310c0ff --- /dev/null +++ b/hypha/apply/users/templates/users/email_change/update_info_email.html @@ -0,0 +1,12 @@ +{% load i18n wagtailadmin_tags %}{% base_url_setting as base_url %}{% firstof name username as user %} +{% blocktrans %}Dear {{ user }},{% endblocktrans %} + +{% blocktrans %}There has been an attempt to change email of your account on the {{ org_long_name }} web site. If this action wasn't made by you, please contact support at {{ org_email }} {% endblocktrans %} + + +{% blocktrans %}Kind Regards, + The {{ org_short_name }} Team{% endblocktrans %} + +-- +{{ org_long_name }} +{% if site %}{{ site.root_url }}{% else %}{{ base_url }}{% endif %} diff --git a/hypha/apply/users/tests/test_forms.py b/hypha/apply/users/tests/test_forms.py index 9dc5009c885d1389120f179453dd938110aca904..dc7fd7d6f958e6bb141074b3b6c1cc631d4baa9d 100644 --- a/hypha/apply/users/tests/test_forms.py +++ b/hypha/apply/users/tests/test_forms.py @@ -29,7 +29,8 @@ class TestProfileForm(BaseTestProfileForm): def test_email_unique(self): other_user = UserFactory() form = self.submit_form(self.user, email=other_user.email) - self.assertFalse(form.is_valid()) + # form will update the other user's email with same user email, only non exiting email address can be added + self.assertTrue(form.is_valid()) self.user.refresh_from_db() self.assertNotEqual(self.user.email, other_user.email) diff --git a/hypha/apply/users/urls.py b/hypha/apply/users/urls.py index 708d8f315490cb4a4623e32a80d890fd14b90bc4..9d8e26b75e1aa0fec29349feebd2d22a6751e6c8 100644 --- a/hypha/apply/users/urls.py +++ b/hypha/apply/users/urls.py @@ -2,10 +2,12 @@ from django.conf import settings from django.contrib.auth import views as auth_views from django.urls import include, path, reverse_lazy from django_ratelimit.decorators import ratelimit +from elevate.views import elevate as elevate_view from .views import ( AccountView, ActivationView, + BackupTokensView, EmailChangeConfirmationView, EmailChangeDoneView, EmailChangePasswordView, @@ -15,7 +17,6 @@ from .views import ( RegisterView, RegistrationSuccessView, TWOFAAdminDisableView, - TWOFABackupTokensPasswordView, TWOFADisableView, TWOFARequiredMessageView, TWOFASetupView, @@ -131,7 +132,7 @@ urlpatterns = [ path("two_factor/setup/", TWOFASetupView.as_view(), name="setup"), path( "two_factor/backup_tokens/password/", - TWOFABackupTokensPasswordView.as_view(), + BackupTokensView.as_view(), name="backup_tokens_password", ), path("two_factor/disable/", TWOFADisableView.as_view(), name="disable"), @@ -140,6 +141,12 @@ urlpatterns = [ TWOFAAdminDisableView.as_view(), name="admin_disable", ), + path( + "sessions/trusted-device/", + elevate_view, + {"template_name": "elevate/elevate.html"}, + name="elevate", + ), ] ), ), diff --git a/hypha/apply/users/views.py b/hypha/apply/users/views.py index f6e2146abe64463951885161fffa771388607bbb..d7c3b0d29adaf8fa058383b66faf05060c8fbce9 100644 --- a/hypha/apply/users/views.py +++ b/hypha/apply/users/views.py @@ -21,6 +21,7 @@ from django.core.exceptions import PermissionDenied from django.core.signing import BadSignature, Signer, TimestampSigner, dumps, loads from django.http import HttpResponseRedirect from django.shortcuts import Http404, get_object_or_404, redirect, render, resolve_url +from django.template.loader import render_to_string from django.template.response import TemplateResponse from django.urls import reverse, reverse_lazy from django.utils.decorators import method_decorator @@ -34,6 +35,7 @@ from django.views.generic.base import TemplateView, View from django.views.generic.edit import FormView from django_otp import devices_for_user from django_ratelimit.decorators import ratelimit +from elevate.mixins import ElevateMixin from hijack.views import AcquireUserView from two_factor.forms import AuthenticationTokenForm, BackupTokenForm from two_factor.utils import default_device, get_otpauth_url, totp_digits @@ -164,7 +166,7 @@ class AccountView(UpdateView): name = form.cleaned_data["full_name"] slack = form.cleaned_data.get("slack", "") user = get_object_or_404(User, id=self.request.user.id) - if updated_email and updated_email != user.email: + if updated_email: base_url = reverse("users:email_change_confirm_password") query_dict = {"updated_email": updated_email, "name": name, "slack": slack} @@ -243,11 +245,28 @@ class EmailChangePasswordView(FormView): return redirect("users:account") value = loads(unsigned_value) form.save(**value) - send_confirmation_email( - self.request.user, - signer.sign(dumps(value["updated_email"])), - updated_email=value["updated_email"], - site=Site.find_for_request(self.request), + user = self.request.user + if user.email != value["updated_email"]: + send_confirmation_email( + user, + signer.sign(dumps(value["updated_email"])), + updated_email=value["updated_email"], + site=Site.find_for_request(self.request), + ) + # alert email + user.email_user( + subject="Alert! An attempt to update your email.", + message=render_to_string( + "users/email_change/update_info_email.html", + { + "name": user.get_full_name(), + "username": user.get_username(), + "org_email": settings.ORG_EMAIL, + "org_short_name": settings.ORG_SHORT_NAME, + "org_long_name": settings.ORG_LONG_NAME, + }, + ), + from_email=settings.DEFAULT_FROM_EMAIL, ) return super(EmailChangePasswordView, self).form_valid(form) @@ -475,26 +494,6 @@ class TWOFASetupView(TwoFactorSetupView): return context -@method_decorator(login_required, name="dispatch") -@method_decorator( - ratelimit(key="user", rate=settings.DEFAULT_RATE_LIMIT, method="POST"), - name="dispatch", -) -class TWOFABackupTokensPasswordView(TwoFactorBackupTokensView): - """ - Require password to see backup codes - """ - - form_class = TWOFAPasswordForm - success_url = reverse_lazy("two_factor:backup_tokens") - template_name = "two_factor/core/backup_tokens_password.html" - - def get_form_kwargs(self): - kwargs = super().get_form_kwargs() - kwargs["user"] = self.request.user - return kwargs - - @method_decorator( ratelimit(key="user", rate=settings.DEFAULT_RATE_LIMIT, method="POST"), name="dispatch", @@ -558,6 +557,10 @@ class TWOFARequiredMessageView(TemplateView): template_name = "two_factor/core/two_factor_required.html" +class BackupTokensView(ElevateMixin, TwoFactorBackupTokensView): + pass + + class PasswordResetConfirmView(DjPasswordResetConfirmView): redirect_field_name = "next" template_name = "users/password_reset/confirm.html" diff --git a/hypha/public/navigation/templates/navigation/primarynav-apply.html b/hypha/public/navigation/templates/navigation/primarynav-apply.html index 72f8366482e3ca23c99c7f4a4fb686f468a5b484..0980776acb4ffaf2606d912b74fa15fca2b94516 100644 --- a/hypha/public/navigation/templates/navigation/primarynav-apply.html +++ b/hypha/public/navigation/templates/navigation/primarynav-apply.html @@ -1,5 +1,5 @@ {% if request.user.is_authenticated %} - <nav role="navigation" aria-label="Primary"> + <nav role="navigation" aria-label="Primary" class="w-full"> <ul class="nav nav--primary" role="menubar"> {% if request.user.is_apply_staff %} {% include "navigation/primarynav-apply-item.html" with name="My dashboard" url="dashboard:dashboard" %} diff --git a/hypha/settings/base.py b/hypha/settings/base.py index 01c7e242b409b28f2ca9c4760262b1fba286868f..e2c0241470a9c95b8ba478f34f2c859c5e4a6c4b 100644 --- a/hypha/settings/base.py +++ b/hypha/settings/base.py @@ -493,6 +493,7 @@ SECURE_CONTENT_TYPE_NOSNIFF = env.bool("SECURE_CONTENT_TYPE_NOSNIFF", True) if env.bool("COOKIE_SECURE", False): SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True + ELEVATE_COOKIE_SECURE = True # Referrer-policy header settings # https://django-referrer-policy.readthedocs.io/en/1.0/ @@ -501,9 +502,17 @@ REFERRER_POLICY = env.str( "SECURE_REFERRER_POLICY", "no-referrer-when-downgrade" ).strip() +# Django Elevate settings +# https://django-elevate.readthedocs.io/en/latest/config/index.html -# Rest Framework settings +# How long should Elevate mode be active for? +ELEVATE_COOKIE_AGE = env.int("ELEVATE_COOKIE_AGE", 3600) # 1 hours + +# An extra salt to be added into the cookie signature. +ELEVATE_COOKIE_SALT = env.str("ELEVATE_COOKIE_SALT", SECRET_KEY) + +# Rest Framework settings REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination", "PAGE_SIZE": 10, diff --git a/hypha/settings/django.py b/hypha/settings/django.py index 980e89bb16bbb171f3195bd1ae5a3e0a007e1786..7d9ca32d6268e36ef5d2b9c75d3062d85867f3df 100644 --- a/hypha/settings/django.py +++ b/hypha/settings/django.py @@ -74,6 +74,7 @@ INSTALLED_APPS = [ "wagtail_purge", "django_file_form", "hijack", + "elevate", # https://django-elevate.readthedocs.io/ "pagedown", "django.contrib.admin", "django.contrib.auth", @@ -92,6 +93,7 @@ MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", + "elevate.middleware.ElevateMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", @@ -204,6 +206,10 @@ AUTH_USER_MODEL = "users.User" LOGIN_URL = "users_public:login" LOGIN_REDIRECT_URL = "dashboard:dashboard" +# https://django-elevate.readthedocs.io/en/latest/config/index.html#configuration +ELEVATE_URL = "users:elevate" +ELEVATE_REDIRECT_URL = LOGIN_REDIRECT_URL + CUSTOM_AUTH_BACKEND = "hypha.apply.users.backends.CustomModelBackend" AUTHENTICATION_BACKENDS = ( diff --git a/hypha/settings/test.py b/hypha/settings/test.py index ddeb4708891ec9d6c75d4a835b7dd2fc7da989e5..3b1e3bf01b7c9d10628b21e66de1864f7471c0b9 100644 --- a/hypha/settings/test.py +++ b/hypha/settings/test.py @@ -27,3 +27,6 @@ WAGTAILADMIN_BASE_URL = "https://primary-test-host.org" # Required by django-coverage-plugin to report template coverage TEMPLATES[0]["OPTIONS"]["debug"] = True + +# An extra salt to be added into the cookie signature. +ELEVATE_COOKIE_SALT = SECRET_KEY diff --git a/hypha/static_src/src/javascript/apply/application-form.js b/hypha/static_src/src/javascript/apply/application-form.js index 0c186933b71cac927c5c381b81802de5d8631c82..433d207955f8b26078a7c1da5bdc74cdb93c0277 100644 --- a/hypha/static_src/src/javascript/apply/application-form.js +++ b/hypha/static_src/src/javascript/apply/application-form.js @@ -1,72 +1,71 @@ -(function ($) { +(function () { "use strict"; - $(".application-form").each(function () { - var $application_form = $(this); - var $application_form_button = $application_form.find( - 'button[type="submit"]' - ); + const form = document.querySelector(".application-form"); + const button = form.querySelector("[type=submit]"); + const required = form.querySelectorAll("input[required]"); + const groups = form.querySelectorAll(".form__group"); + const errors = form.querySelectorAll(".form__error"); - // set aria-required attribute true for required fields - $application_form - .find("input[required]") - .each(function (index, input_field) { - input_field.setAttribute("aria-required", true); - }); - - // add label_id as aria-describedby to help texts - $application_form - .find(".form__group") - .each(function (index, form_group) { - var label = form_group.querySelector("label"); - if (label) { - var label_id = label.getAttribute("for"); - if (form_group.querySelector(".form__help")) { - form_group - .querySelector(".form__help") - .setAttribute("aria-describedby", label_id); - } - } - }); - - // set aria-invalid for field with errors - var $error_fields = $application_form.find(".form__error"); - if ($error_fields.length) { - // set focus to the first error field - $error_fields[0].querySelector("input").focus(); + // Set aria-required attribute true for required fields. + required.forEach(function (field) { + field.setAttribute("aria-required", true); + }); - $error_fields.each(function (index, error_field) { - const inputEl = error_field.querySelector("input, textarea"); - if (inputEl) { - inputEl.setAttribute("aria-invalid", true); - } - }); + // Add label_id as aria-describedby to help text. + groups.forEach(function (group) { + const label = group.querySelector("label"); + if (label) { + const label_id = label.getAttribute("for"); + if (group.querySelector(".form__help")) { + group + .querySelector(".form__help") + .setAttribute("aria-describedby", label_id); + } } + }); - // Remove the "no javascript" messages - $(".message-no-js").detach(); + if (errors.length) { + // Set focus to the first error field. + const first_error = errors[0].querySelector("input"); + if (first_error) { + first_error.focus(); + } - // Wait for a mouse to move, indicating they are human. - $("body").mousemove(function () { - // Unlock the form. - $application_form.attr("action", ""); - $application_form_button.attr("disabled", false); + // Set aria-invalid for field with errors. + errors.forEach(function (error) { + const input = error.querySelector("input, textarea"); + if (input) { + input.setAttribute("aria-invalid", true); + } }); + } - // Wait for a touch move event, indicating that they are human. - $("body").on("touchmove", function () { - // Unlock the form. - $application_form.attr("action", ""); - $application_form_button.attr("disabled", false); - }); + // Remove the "no javascript" messages + document.querySelector(".message-no-js").remove(); - // A tab or enter key pressed can also indicate they are human. - $("body").keydown(function (e) { - if (e.keyCode === 9 || e.keyCode === 13) { - // Unlock the form. - $application_form.attr("action", ""); - $application_form_button.attr("disabled", false); - } - }); + const unlockApplicationForm = function () { + form.setAttribute("action", ""); + button.removeAttribute("disabled"); + }; + + // Unlock form on + // 1. mouse move + // 2. touch move + // 3. tab or enter key pressed + document.body.addEventListener("mousemove", unlockApplicationForm, { + once: true, + }); + document.body.addEventListener("touchmove", unlockApplicationForm, { + once: true, }); -})(jQuery); + document.body.addEventListener( + "keydown", + function (e) { + if (e.key === "Tab" || e.key === "Enter") { + unlockApplicationForm(); + } + }, + { once: true } + ); +})(); diff --git a/hypha/static_src/src/sass/apply/components/_form.scss b/hypha/static_src/src/sass/apply/components/_form.scss index fc7a2fa9ec75c74e7f9849fb3a29b8e4e4788bc6..aa871b21703b0ca9271c021075c8c279456173af 100644 --- a/hypha/static_src/src/sass/apply/components/_form.scss +++ b/hypha/static_src/src/sass/apply/components/_form.scss @@ -150,6 +150,10 @@ // stylelint-enable selector-class-pattern } + &__file-label { + padding-bottom: 0.5rem; + } + &__file-list { ul { margin: 0.5rem 0; diff --git a/hypha/static_src/src/sass/apply/components/_icon.scss b/hypha/static_src/src/sass/apply/components/_icon.scss index 5cee7bc02e3f8ba51ba64df2f751e62ae065d656..dcc3730deec2e9d416edeabce3a0da74557c6359 100644 --- a/hypha/static_src/src/sass/apply/components/_icon.scss +++ b/hypha/static_src/src/sass/apply/components/_icon.scss @@ -164,6 +164,13 @@ stroke: $color--light-blue; } + &--side-arrow { + position: relative; + align-self: center; + width: 8px; + height: 30px; + } + &--arrow-up-short-bar { position: relative; align-self: center; diff --git a/hypha/static_src/src/sass/apply/components/_nav.scss b/hypha/static_src/src/sass/apply/components/_nav.scss index b96b60e8ce7e70593cf68b8ae33826aa15d3ed59..2a3a61049492c4b103fc59e0ca8ed7689ba8063f 100644 --- a/hypha/static_src/src/sass/apply/components/_nav.scss +++ b/hypha/static_src/src/sass/apply/components/_nav.scss @@ -17,15 +17,18 @@ @include media-query(tablet-portrait) { flex-direction: row; justify-content: center; + gap: 2rem; margin-top: 0; text-transform: none; } + + @include media-query(tablet-landscape) { + gap: 3rem; + } } &__item { @include media-query(tablet-portrait) { - margin-right: 75px; - &:last-child { margin-right: 0; } diff --git a/hypha/static_src/src/sass/apply/components/_simplified.scss b/hypha/static_src/src/sass/apply/components/_simplified.scss index d68bc7418688638780fad285969b22d7545c0ed4..76161b522d410a8f015abd0c16635fb86ca82260 100644 --- a/hypha/static_src/src/sass/apply/components/_simplified.scss +++ b/hypha/static_src/src/sass/apply/components/_simplified.scss @@ -154,7 +154,12 @@ } &__paf_answers { + section { + margin: 0 0 1.5rem; + } + h4 { + margin: 0; font-size: 16px; } } diff --git a/hypha/templates/includes/sprites.html b/hypha/templates/includes/sprites.html index 159e4efee2464776ff580cd9ec63c7ed11aea06f..1087051313a55f766558e55cf6fc0566bf4f8555 100644 --- a/hypha/templates/includes/sprites.html +++ b/hypha/templates/includes/sprites.html @@ -254,6 +254,11 @@ <path d="M1 8L8 2L15 8" stroke-width="2"/> </svg> + <symbol id="side-arrow" viewBox="0 0 8 12" fill="none" > + <path fill-rule="evenodd" clip-rule="evenodd" d="M8 6L0 0L0 12L8 6Z" fill="#0D7DB0"/> + </symbol> + + <symbol id="wifi" viewBox="0 0 69 42"> diff --git a/requirements.txt b/requirements.txt index 77e819a24a3616be3e77bf724136de06409313fa..f04bb7ca56db8e9e54823f73e2cac966b356d9d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,7 @@ django-anymail==9.0 django-basic-auth-ip-whitelist==0.3.4 django-bleach==3.0.1 django-countries==7.5 +django-elevate==2.0.3 django-extensions==3.2.1 django-file-form==3.4.3 django-filter==2.4.0 @@ -32,7 +33,7 @@ django-tables2==2.5.1 django-tinymce==3.5.0 django-two-factor-auth==1.14.0 django-web-components==0.1.1 -django==3.2.21 +django==3.2.22 djangorestframework-api-key==2.3.0 djangorestframework==3.14.0 drf-nested-routers==0.93.4