def test_filter_and_sorting(self, staff_client, program_data, fin_aid_status, sort_param):
        """
        Tests ReviewFinancialAidView correctly applies sort and filter parameters, or
        uses defaults for those parameters
        """
        FinancialAidFactory.create_batch(
            10,
            tier_program=program_data.tier_programs["0k"],
            status=factory.Iterator([
                ReviewFinancialAidView.default_status,
                FinancialAidStatus.AUTO_APPROVED
            ])
        )
        url = self.review_url(program_data.program.id, status=fin_aid_status, sort_param=sort_param)
        resp = staff_client.get(url)
        assert resp.status_code == status.HTTP_200_OK
        financial_aid_objects = resp.context_data["financial_aid_objects"]

        # View should filter FinancialAid objects by the provided status or a default status
        expected_status = fin_aid_status or ReviewFinancialAidView.default_status
        assert all(fin_aid.status == expected_status for fin_aid in financial_aid_objects)
        # View should sort by the given parameter, or sort by ascending last name by default
        should_reverse_sort = sort_param == '-last_name'
        assert (
            list(financial_aid_objects) ==
            sorted(financial_aid_objects, key=lambda f: f.user.last_name, reverse=should_reverse_sort)
        )
Exemple #2
0
def test_approve_docs(browser, base_test_data, logged_in_staff):
    """
    Test the financial aid review page
    """
    program = base_test_data.program
    tier_program = program.tier_programs.get(discount_amount=0)
    FinancialAidFactory.create(
        user=base_test_data.student_user,
        tier_program=tier_program,
        status=FinancialAidStatus.DOCS_SENT,
    )

    browser.get("/financial_aid/review/{}/{}".format(program.id, FinancialAidStatus.DOCS_SENT))
    browser.click_when_loaded(By.CLASS_NAME, "mark-docs-as-received")
    alert = browser.driver.switch_to_alert()
    alert.accept()
    browser.wait_until_loaded(By.CLASS_NAME, "alert-success")
    browser.assert_no_console_errors()

    def is_now_pending(driver):  # pylint: disable=unused-argument
        """Wait until the change to the financial aid takes effect"""
        assert FinancialAid.objects.count() == 1
        financial_aid = FinancialAid.objects.first()
        return financial_aid.status == FinancialAidStatus.PENDING_MANUAL_APPROVAL

    browser.wait().until(is_now_pending)
    def test_view_with_search(self, staff_client, program_data):
        """
        Tests that ReviewFinancialAidView returns the expected results with search
        """
        fin_aid_status = FinancialAidStatus.AUTO_APPROVED
        profiles = ProfileFactory.create_batch(
            4,
            first_name=factory.Iterator(['match_name', 'x', 'y', 'z']),
            last_name=factory.Iterator(['x', 'y', 'z', 'match_name']),
        )
        FinancialAidFactory.create_batch(
            4,
            tier_program=program_data.tier_programs["0k"],
            status=fin_aid_status,
            user=factory.Iterator([p.user for p in profiles])
        )
        name_query = 'match_name'
        url = self.review_url(program_data.program.id, status=fin_aid_status, search_param=name_query)
        resp = staff_client.get(url)
        assert resp.status_code == status.HTTP_200_OK
        financial_aid_objects = resp.context_data["financial_aid_objects"]

        # Two users should match the search term - one for first_name, one for last_name
        assert len(financial_aid_objects) == 2
        assert all(
            fin_aid.user.profile.first_name == name_query or fin_aid.user.profile.last_name == name_query
            for fin_aid in financial_aid_objects
        )
Exemple #4
0
    def test_filter_and_sorting(self, staff_client, program_data, fin_aid_status, sort_param):
        """
        Tests ReviewFinancialAidView correctly applies sort and filter parameters, or
        uses defaults for those parameters
        """
        FinancialAidFactory.create_batch(
            10,
            tier_program=program_data.tier_programs["0k"],
            status=factory.Iterator([
                ReviewFinancialAidView.default_status,
                FinancialAidStatus.AUTO_APPROVED
            ])
        )
        url = self.review_url(program_data.program.id, status=fin_aid_status, sort_param=sort_param)
        resp = staff_client.get(url)
        assert resp.status_code == status.HTTP_200_OK
        financial_aid_objects = resp.context_data["financial_aid_objects"]

        # View should filter FinancialAid objects by the provided status or a default status
        expected_status = fin_aid_status or ReviewFinancialAidView.default_status
        assert all(fin_aid.status == expected_status for fin_aid in financial_aid_objects)
        # View should sort by the given parameter, or sort by ascending last name by default
        should_reverse_sort = sort_param == '-last_name'
        assert (
            list(financial_aid_objects) ==
            sorted(financial_aid_objects, key=lambda f: f.user.last_name, reverse=should_reverse_sort)
        )
Exemple #5
0
    def test_view_with_search(self, staff_client, program_data):
        """
        Tests that ReviewFinancialAidView returns the expected results with search
        """
        fin_aid_status = FinancialAidStatus.AUTO_APPROVED
        profiles = ProfileFactory.create_batch(
            4,
            first_name=factory.Iterator(['match_name', 'x', 'y', 'z']),
            last_name=factory.Iterator(['x', 'y', 'z', 'match_name']),
        )
        FinancialAidFactory.create_batch(
            4,
            tier_program=program_data.tier_programs["0k"],
            status=fin_aid_status,
            user=factory.Iterator([p.user for p in profiles])
        )
        name_query = 'match_name'
        url = self.review_url(program_data.program.id, status=fin_aid_status, search_param=name_query)
        resp = staff_client.get(url)
        assert resp.status_code == status.HTTP_200_OK
        financial_aid_objects = resp.context_data["financial_aid_objects"]

        # Two users should match the search term - one for first_name, one for last_name
        assert len(financial_aid_objects) == 2
        assert all(
            name_query in (fin_aid.user.profile.first_name, fin_aid.user.profile.last_name)
            for fin_aid in financial_aid_objects
        )
Exemple #6
0
    def setUpTestData(cls):
        # replace imported thresholds with fake ones created here
        CountryIncomeThreshold.objects.all().delete()

        cls.program, cls.tier_programs = create_program()
        cls.profile = create_enrolled_profile(cls.program, country="50")
        cls.staff_user_profile = create_enrolled_profile(cls.program,
                                                         role=Staff.ROLE_ID)
        cls.instructor_user_profile = create_enrolled_profile(
            cls.program, role=Instructor.ROLE_ID)
        cls.country_income_threshold_0 = CountryIncomeThreshold.objects.create(
            country_code="0",
            income_threshold=0,
        )
        CountryIncomeThreshold.objects.create(
            country_code=cls.profile.country,
            income_threshold=50000,
        )

        # Create a FinancialAid with a reset status to verify that it is ignored
        FinancialAidFactory.create(
            user=cls.profile.user,
            tier_program=cls.tier_programs['75k'],
            status=FinancialAidStatus.RESET,
        )
Exemple #7
0
def test_approve_docs(browser, base_test_data, logged_in_staff):
    """
    Test the financial aid review page
    """
    program = base_test_data.program
    tier_program = program.tier_programs.get(discount_amount=0)
    FinancialAidFactory.create(
        user=base_test_data.student_user,
        tier_program=tier_program,
        status=FinancialAidStatus.DOCS_SENT,
    )

    browser.get("/financial_aid/review/{}/{}".format(
        program.id, FinancialAidStatus.DOCS_SENT))
    browser.click_when_loaded(By.CLASS_NAME, "mark-docs-as-received")
    alert = browser.driver.switch_to_alert()
    alert.accept()
    browser.wait_until_loaded(By.CLASS_NAME, "alert-success")
    browser.assert_no_console_errors()

    def is_now_pending(driver):  # pylint: disable=unused-argument
        """Wait until the change to the financial aid takes effect"""
        assert FinancialAid.objects.count() == 1
        financial_aid = FinancialAid.objects.first()
        return financial_aid.status == FinancialAidStatus.PENDING_MANUAL_APPROVAL

    browser.wait().until(is_now_pending)
    def setUpTestData(cls):
        cls.user = SocialUserFactory.create()

        cls.run_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc() - timedelta(days=1),
            course__program__financial_aid_availability=True,
        )
        cls.run_fa_with_cert = CourseRunFactory.create(
            freeze_grade_date=None,
            course__program=cls.run_fa.course.program,
        )

        cls.run_no_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc() + timedelta(days=1),
            course__program__financial_aid_availability=False,
        )
        cls.run_no_fa_with_cert = CourseRunFactory.create(
            course__program=cls.run_no_fa.course.program, )

        all_course_runs = (
            cls.run_fa,
            cls.run_fa_with_cert,
            cls.run_no_fa,
            cls.run_no_fa_with_cert,
        )

        for run in all_course_runs:
            if run.course.program.financial_aid_availability:
                FinancialAidFactory.create(
                    user=cls.user,
                    tier_program=TierProgramFactory.create(
                        program=run.course.program,
                        income_threshold=0,
                        current=True),
                    status=FinancialAidStatus.RESET,
                )

        cls.enrollments = {
            course_run.edx_course_key:
            CachedEnrollmentFactory.create(user=cls.user,
                                           course_run=course_run)
            for course_run in all_course_runs
        }

        cls.current_grades = {
            course_run.edx_course_key:
            CachedCurrentGradeFactory.create(user=cls.user,
                                             course_run=course_run)
            for course_run in all_course_runs
        }

        cls.certificates = {
            course_run.edx_course_key:
            CachedCertificateFactory.create(user=cls.user,
                                            course_run=course_run)
            for course_run in (cls.run_fa_with_cert, cls.run_no_fa_with_cert)
        }

        cls.user_edx_data = CachedEdxUserData(cls.user)
 def test_invalid_sorting_and_filter(self, staff_client, program_data, fin_aid_status, sort_param):
     """
     Shouldn't break with invalid sorting or filter parameters
     """
     FinancialAidFactory.create(tier_program=program_data.tier_programs["0k"])
     url = self.review_url(program_data.program.id, status=fin_aid_status, sort_param=sort_param)
     resp = staff_client.get(url)
     assert resp.status_code == status.HTTP_200_OK
Exemple #10
0
 def test_invalid_sorting_and_filter(self, staff_client, program_data, fin_aid_status, sort_param):
     """
     Shouldn't break with invalid sorting or filter parameters
     """
     FinancialAidFactory.create(tier_program=program_data.tier_programs["0k"])
     url = self.review_url(program_data.program.id, status=fin_aid_status, sort_param=sort_param)
     resp = staff_client.get(url)
     assert resp.status_code == status.HTTP_200_OK
 def test_financialaid_object_cannot_be_skipped_if_already_terminal_status(self, financial_aid_status):
     """
     Tests that an existing FinancialAid object that has already reached a terminal status cannot be skipped.
     """
     FinancialAidFactory.create(
         user=self.profile.user,
         tier_program=self.tier_programs["25k"],
         status=financial_aid_status,
     )
     self.make_http_request(self.client.patch, self.skip_url, status.HTTP_400_BAD_REQUEST)
 def test_financial_aid_factory_create(self):
     """
     Tests that FinancialAidFactory.create() will create a profile for the user field if a user is not specified
     """
     assert FinancialAid.objects.count() == 0
     assert User.objects.count() == 0
     assert Profile.objects.count() == 0
     FinancialAidFactory.create()
     assert FinancialAid.objects.count() == 1
     assert User.objects.count() == 1
     assert Profile.objects.count() == 1
 def test_financial_aid_factory_create_with_user(self):
     """
     Tests that FinancialAidFactory.create() will still work normally if provided a User object
     """
     with mute_signals(post_save):
         user = UserFactory.create()
     assert FinancialAid.objects.count() == 0
     assert User.objects.count() == 1
     assert Profile.objects.count() == 0
     FinancialAidFactory.create(user=user)
     assert FinancialAid.objects.count() == 1
     assert User.objects.count() == 1
     assert Profile.objects.count() == 0
Exemple #14
0
 def make_fa_program_enrollment(self, status):
     """Enroll user in financial aid program"""
     Program.objects.get(title='Analog Learning').delete()
     # We need to use Digital Learning here since it has financial aid enabled. Deleting Analog Learning
     # because it's simpler than adjusting the UI to show the right one
     program = Program.objects.get(title='Digital Learning')
     ProgramEnrollment.objects.create(user=self.user, program=program)
     FinancialAidFactory.create(
         user=self.user,
         status=status,
         tier_program__program=program,
         tier_program__discount_amount=50,
     )
Exemple #15
0
    def setUpTestData(cls):
        cls.user = SocialUserFactory.create()

        cls.run_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc()-timedelta(days=1),
            course__program__financial_aid_availability=True,
        )
        cls.run_fa_with_cert = CourseRunFactory.create(
            freeze_grade_date=None,
            course__program=cls.run_fa.course.program,
        )

        cls.run_no_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc()+timedelta(days=1),
            course__program__financial_aid_availability=False,
        )
        cls.run_no_fa_with_cert = CourseRunFactory.create(
            course__program=cls.run_no_fa.course.program,
        )

        all_course_runs = (cls.run_fa, cls.run_fa_with_cert, cls.run_no_fa, cls.run_no_fa_with_cert, )

        for run in all_course_runs:
            if run.course.program.financial_aid_availability:
                FinancialAidFactory.create(
                    user=cls.user,
                    tier_program=TierProgramFactory.create(
                        program=run.course.program, income_threshold=0, current=True
                    ),
                    status=FinancialAidStatus.RESET,
                )

        cls.enrollments = {
            course_run.edx_course_key: CachedEnrollmentFactory.create(
                user=cls.user, course_run=course_run) for course_run in all_course_runs
        }

        cls.current_grades = {
            course_run.edx_course_key: CachedCurrentGradeFactory.create(
                user=cls.user, course_run=course_run) for course_run in all_course_runs
        }

        cls.certificates = {
            course_run.edx_course_key: CachedCertificateFactory.create(
                user=cls.user, course_run=course_run) for course_run in (cls.run_fa_with_cert, cls.run_no_fa_with_cert)
        }

        cls.user_edx_data = CachedEdxUserData(cls.user)
 def test_props(self, program_data):
     """
     Fixture that provides test properties for FinancialAidDetailView test cases
     """
     user = create_enrolled_profile(program_data.program).user
     pending_fa = FinancialAidFactory.create(
         user=user,
         tier_program=program_data.tier_programs["25k"],
         status=FinancialAidStatus.PENDING_DOCS
     )
     docs_sent_url = reverse(
         "financial_aid",
         kwargs={"financial_aid_id": pending_fa.id}
     )
     docs_sent_date = now_in_utc().date()
     docs_sent_request_params = dict(
         content_type="application/json",
         data=json.dumps({
             "date_documents_sent": docs_sent_date.strftime("%Y-%m-%d")
         })
     )
     return SimpleNamespace(
         user=user,
         pending_fa=pending_fa,
         docs_sent_url=docs_sent_url,
         docs_sent_request_params=docs_sent_request_params,
         docs_sent_date=docs_sent_date,
     )
 def test_save_and_log(self):
     """
     Tests that FinancialAid.save_and_log() creates an audit record with the correct information.
     """
     with mute_signals(post_save):
         profile = ProfileFactory.create()
     acting_user = profile.user
     financial_aid = FinancialAidFactory.create()
     original_before_json = serialize_model_object(financial_aid)
     # Make sure audit object is created
     assert FinancialAidAudit.objects.count() == 0
     financial_aid.status = FinancialAidStatus.AUTO_APPROVED
     financial_aid.save_and_log(acting_user)
     assert FinancialAidAudit.objects.count() == 1
     # Make sure the before and after data are correct
     financial_aid.refresh_from_db()
     original_after_json = serialize_model_object(financial_aid)
     financial_aid_audit = FinancialAidAudit.objects.first()
     before_json = financial_aid_audit.data_before
     after_json = financial_aid_audit.data_after
     for field, value in before_json.items():
         # Data before
         if isinstance(value, float):
             # JSON serialization of FloatField is precise, so we need to do almost equal
             self.assertAlmostEqual(value, original_before_json[field])
         else:
             assert value == original_before_json[field]
     for field, value in after_json.items():
         # Data after
         if isinstance(value, float):
             # JSON serialization of FloatField is precise, so we need to do almost equal
             self.assertAlmostEqual(value, original_after_json[field])
         else:
             assert value == original_after_json[field]
Exemple #18
0
 def test_props(self, program_data):
     """
     Fixture that provides test properties for FinancialAidDetailView test cases
     """
     user = create_enrolled_profile(program_data.program).user
     pending_fa = FinancialAidFactory.create(
         user=user,
         tier_program=program_data.tier_programs["25k"],
         status=FinancialAidStatus.PENDING_DOCS
     )
     docs_sent_url = reverse(
         "financial_aid",
         kwargs={"financial_aid_id": pending_fa.id}
     )
     docs_sent_date = now_in_utc().date()
     docs_sent_request_params = dict(
         content_type="application/json",
         data=json.dumps({
             "date_documents_sent": docs_sent_date.strftime("%Y-%m-%d")
         })
     )
     return SimpleNamespace(
         user=user,
         pending_fa=pending_fa,
         docs_sent_url=docs_sent_url,
         docs_sent_request_params=docs_sent_request_params,
         docs_sent_date=docs_sent_date,
     )
Exemple #19
0
 def test_datetime(self):
     """
     Test that a model with a datetime and date field is handled correctly
     """
     financial_aid = FinancialAidFactory.create(justification=None)
     assert serialize_model_object(financial_aid) == {
         'country_of_income':
         financial_aid.country_of_income,
         'country_of_residence':
         financial_aid.country_of_residence,
         'created_on':
         format_as_iso8601(financial_aid.created_on),
         'date_documents_sent':
         financial_aid.date_documents_sent.isoformat(),
         'date_exchange_rate':
         format_as_iso8601(financial_aid.date_exchange_rate),
         'id':
         financial_aid.id,
         'income_usd':
         financial_aid.income_usd,
         'justification':
         None,
         'original_currency':
         financial_aid.original_currency,
         'original_income':
         financial_aid.original_income,
         'status':
         financial_aid.status,
         'tier_program':
         financial_aid.tier_program.id,
         'updated_on':
         format_as_iso8601(financial_aid.updated_on),
         'user':
         financial_aid.user.id,
     }
 def setUpTestData(cls):
     super().setUpTestData()
     cls.financialaid = FinancialAidFactory.create(
         user=cls.profile.user,
         tier_program=cls.tier_programs["25k"],
         status=FinancialAidStatus.PENDING_MANUAL_APPROVAL
     )
     cls.action_url = reverse("financial_aid_action", kwargs={"financial_aid_id": cls.financialaid.id})
Exemple #21
0
def create_purchasable_course_run():
    """
    Creates a purchasable course run and an associated user
    """
    course_run = CourseRunFactory.create(
        course__program__live=True,
        course__program__financial_aid_availability=True,
    )
    price = course_run.course.program.price
    user = UserFactory.create()
    FinancialAidFactory.create(
        tier_program__current=True,
        tier_program__program=course_run.course.program,
        tier_program__discount_amount=price/2,
        user=user,
        status=FinancialAidStatus.APPROVED,
    )
    ProgramEnrollment.objects.create(user=user, program=course_run.course.program)
    return course_run, user
Exemple #22
0
def create_purchasable_course_run():
    """
    Creates a purchasable course run and an associated user
    """
    course_run = CourseRunFactory.create(
        course__program__live=True,
        course__program__financial_aid_availability=True,
    )
    price = course_run.course.program.price
    user = UserFactory.create()
    FinancialAidFactory.create(
        tier_program__current=True,
        tier_program__program=course_run.course.program,
        tier_program__discount_amount=price/2,
        user=user,
        status=FinancialAidStatus.APPROVED,
    )
    ProgramEnrollment.objects.create(user=user, program=course_run.course.program)
    return course_run, user
Exemple #23
0
 def test_financial_aid_with_application_in_reset(self):
     """
     Test that a user that has a FinancialAid record with the reset status will have serialized financial aid
     information that indicates that they have not applied
     """
     FinancialAidFactory.create(user=self.user,
                                tier_program=self.min_tier_program,
                                date_documents_sent=None,
                                status=FinancialAidStatus.RESET)
     serialized = FinancialAidDashboardSerializer.serialize(
         self.user, self.program)
     assert serialized == {
         "id": None,
         "has_user_applied": False,
         "application_status": None,
         "min_possible_cost": 250,
         "max_possible_cost": 1000,
         "date_documents_sent": None,
     }
Exemple #24
0
 def setUpTestData(cls):
     with mute_signals(post_save):
         cls.staff_user_profile = ProfileFactory.create()
     course_run = CourseRunFactory.create()
     cls.financial_aid = FinancialAidFactory.create()
     cls.tier_program = cls.financial_aid.tier_program
     cls.tier_program.program = course_run.course.program
     cls.tier_program.save()
     cls.program_enrollment = ProgramEnrollment.objects.create(
         user=cls.financial_aid.user, program=cls.tier_program.program)
Exemple #25
0
 def test_determine_auto_approval(self, income_usd, country_code, expected):
     """
     Tests determine_auto_approval() assigning the correct auto-approval status. This should return True
     if income is strictly greater than the threshold (or if the threshold is 0, which is inclusive of 0).
     """
     financial_aid = FinancialAidFactory.create(
         income_usd=income_usd,
         country_of_income=country_code,
     )
     tier_program = determine_tier_program(self.program, income_usd)
     assert determine_auto_approval(financial_aid, tier_program) is expected
Exemple #26
0
 def test_determine_auto_approval(self, income_usd, country_code, expected):
     """
     Tests determine_auto_approval() assigning the correct auto-approval status. This should return True
     if income is strictly greater than the threshold (or if the threshold is 0, which is inclusive of 0).
     """
     financial_aid = FinancialAidFactory.create(
         income_usd=income_usd,
         country_of_income=country_code,
     )
     tier_program = determine_tier_program(self.program, income_usd)
     assert determine_auto_approval(financial_aid, tier_program) is expected
 def test_financial_aid_with_application_in_reset(self):
     """
     Test that a user that has a FinancialAid record with the reset status will have serialized financial aid
     information that indicates that they have not applied
     """
     FinancialAidFactory.create(
         user=self.user,
         tier_program=self.min_tier_program,
         date_documents_sent=None,
         status=FinancialAidStatus.RESET
     )
     serialized = FinancialAidDashboardSerializer.serialize(self.user, self.program)
     assert serialized == {
         "id": None,
         "has_user_applied": False,
         "application_status": None,
         "min_possible_cost": 250,
         "max_possible_cost": 1000,
         "date_documents_sent": None,
     }
Exemple #28
0
    def setUpTestData(cls):
        super().setUpTestData()

        cls.financial_aid = FinancialAidFactory.create(
            tier_program=TierProgramFactory.create(program=cls.program))
        cls.url = reverse('financial_aid_mail_api',
                          kwargs={'financial_aid_id': cls.financial_aid.id})
        cls.request_data = {
            'email_subject': 'email subject',
            'email_body': 'email body'
        }
Exemple #29
0
 def test_get_course_price_for_learner_with_financial_aid_in_reset(self):
     """
     Tests get_course_price_for_learner() who has financial aid request in status `reset`
     """
     enrollment = ProgramEnrollment.objects.get(program=self.program,
                                                user=self.profile.user)
     FinancialAidFactory.create(
         user=self.profile.user,
         tier_program=self.tier_programs['25k'],
         status=FinancialAidStatus.RESET,
     )
     # Enrolled and has no financial aid
     course_price = self.program.price
     expected_response = {
         "program_id": enrollment.program.id,
         "price": course_price,
         "financial_aid_availability": True,
         "has_financial_aid_request": False
     }
     self.assertDictEqual(get_formatted_course_price(enrollment),
                          expected_response)
Exemple #30
0
 def setUpTestData(cls):
     with mute_signals(post_save):
         cls.staff_user_profile = ProfileFactory.create()
     course_run = CourseRunFactory.create()
     cls.financial_aid = FinancialAidFactory.create()
     cls.tier_program = cls.financial_aid.tier_program
     cls.tier_program.program = course_run.course.program
     cls.tier_program.save()
     cls.program_enrollment = ProgramEnrollment.objects.create(
         user=cls.financial_aid.user,
         program=cls.tier_program.program
     )
 def test_financial_aid_model_duplicate_if_reset(self):
     """
     Tests that FinancialAid objects can not be unique per User and Program
     if the other are in reset status
     """
     financial_aid = FinancialAidFactory.create()
     # change the first one to any state that is not `reset` will fail to create a new financial aid
     for status in FinancialAidStatus.ALL_STATUSES:
         if status == FinancialAidStatus.RESET:
             continue
         financial_aid.status = status
         financial_aid.save()
         with self.assertRaises(ValidationError):
             FinancialAidFactory.create(
                 user=financial_aid.user,
                 tier_program=financial_aid.tier_program)
     # reset status will allow a new financial aid
     financial_aid.status = FinancialAidStatus.RESET
     financial_aid.save()
     FinancialAidFactory.create(user=financial_aid.user,
                                tier_program=financial_aid.tier_program)
Exemple #32
0
 def test_get_course_price_for_learner_with_financial_aid_in_reset(self):
     """
     Tests get_course_price_for_learner() who has financial aid request in status `reset`
     """
     enrollment = ProgramEnrollment.objects.get(program=self.program, user=self.profile.user)
     FinancialAidFactory.create(
         user=self.profile.user,
         tier_program=self.tier_programs['25k'],
         status=FinancialAidStatus.RESET,
     )
     # Enrolled and has no financial aid
     course_price = self.program.price
     expected_response = {
         "program_id": enrollment.program.id,
         "price": course_price,
         "financial_aid_availability": True,
         "has_financial_aid_request": False
     }
     self.assertDictEqual(
         get_formatted_course_price(enrollment),
         expected_response
     )
Exemple #33
0
    def setUpTestData(cls):
        super().setUpTestData()

        cls.financial_aid = FinancialAidFactory.create(
            tier_program=TierProgramFactory.create(program=cls.program)
        )
        cls.url = reverse(
            'financial_aid_mail_api',
            kwargs={'financial_aid_id': cls.financial_aid.id}
        )
        cls.request_data = {
            'email_subject': 'email subject',
            'email_body': 'email body'
        }
Exemple #34
0
    def setUpTestData(cls):
        # replace imported thresholds with fake ones created here
        CountryIncomeThreshold.objects.all().delete()

        cls.program, cls.tier_programs = create_program()
        cls.profile = create_enrolled_profile(cls.program, country="50")
        cls.staff_user_profile = create_enrolled_profile(cls.program, role=Staff.ROLE_ID)
        cls.instructor_user_profile = create_enrolled_profile(cls.program, role=Instructor.ROLE_ID)
        cls.country_income_threshold_0 = CountryIncomeThreshold.objects.create(
            country_code="0",
            income_threshold=0,
        )
        CountryIncomeThreshold.objects.create(
            country_code=cls.profile.country,
            income_threshold=50000,
        )

        # Create a FinancialAid with a reset status to verify that it is ignored
        FinancialAidFactory.create(
            user=cls.profile.user,
            tier_program=cls.tier_programs['75k'],
            status=FinancialAidStatus.RESET,
        )
    def test_determine_auto_approval(self):  # pylint: disable=no-self-use
        """
        Tests determine_auto_approval()
        """
        # Assumes US threshold is 100000
        assert COUNTRY_INCOME_THRESHOLDS["US"] == 100000
        financial_aid = FinancialAidFactory.create(income_usd=150000,
                                                   country_of_income="US")
        assert determine_auto_approval(financial_aid) is True
        financial_aid = FinancialAidFactory.create(income_usd=1000,
                                                   country_of_income="US")
        assert not determine_auto_approval(financial_aid)
        financial_aid = FinancialAidFactory.create(income_usd=0,
                                                   country_of_income="US")
        assert not determine_auto_approval(financial_aid)

        # Assumes MX threshold is 50000
        assert COUNTRY_INCOME_THRESHOLDS["MX"] == 50000
        financial_aid = FinancialAidFactory.create(income_usd=55000,
                                                   country_of_income="MX")
        assert determine_auto_approval(financial_aid) is True
        financial_aid = FinancialAidFactory.create(income_usd=45000,
                                                   country_of_income="MX")
        assert not determine_auto_approval(financial_aid)

        # Assumes IN threshold is 15000
        assert COUNTRY_INCOME_THRESHOLDS["IN"] == 15000
        financial_aid = FinancialAidFactory.create(income_usd=20000,
                                                   country_of_income="IN")
        assert determine_auto_approval(financial_aid) is True
        financial_aid = FinancialAidFactory.create(income_usd=1000,
                                                   country_of_income="IN")
        assert not determine_auto_approval(financial_aid)

        # Assumes KP threshold is 0
        assert COUNTRY_INCOME_THRESHOLDS["KP"] == 0
        financial_aid = FinancialAidFactory.create(income_usd=3000,
                                                   country_of_income="KP")
        assert determine_auto_approval(financial_aid) is True
        financial_aid = FinancialAidFactory.create(income_usd=0,
                                                   country_of_income="KP")
        assert determine_auto_approval(financial_aid) is True
 def test_save_and_log_model(self):
     """
     Tests that the save_model() function on FinancialAidAdmin model creates FinancialAidAudit
     object
     """
     financial_aid = FinancialAidFactory.create()
     assert FinancialAidAudit.objects.count() == 0
     financial_aid_admin = FinancialAidAdmin(model=financial_aid,
                                             admin_site=Mock())
     mock_request = Mock(user=self.staff_user_profile.user)
     financial_aid_admin.save_model(request=mock_request,
                                    obj=financial_aid_admin.model,
                                    form=Mock(),
                                    change=Mock())
     assert FinancialAidAudit.objects.count() == 1
Exemple #37
0
 def test_save_and_log_model(self):
     """
     Tests that the save_model() function on FinancialAidAdmin model creates FinancialAidAudit
     object
     """
     financial_aid = FinancialAidFactory.create()
     assert FinancialAidAudit.objects.count() == 0
     financial_aid_admin = FinancialAidAdmin(model=financial_aid, admin_site=Mock())
     mock_request = Mock(user=self.staff_user_profile.user)
     financial_aid_admin.save_model(
         request=mock_request,
         obj=financial_aid_admin.model,
         form=Mock(),
         change=Mock()
     )
     assert FinancialAidAudit.objects.count() == 1
    def test_skipped_financialaid_object_updated(self, financial_aid_status):
        """
        Tests that an existing FinancialAid object is updated to have the status "skipped"
        """
        financial_aid = FinancialAidFactory.create(
            user=self.profile.user,
            tier_program=self.tier_programs["75k"],
            status=financial_aid_status,
        )

        assert FinancialAidAudit.objects.count() == 0
        self.make_http_request(self.client.patch, self.skip_url, status.HTTP_200_OK)
        assert FinancialAid.objects.exclude(status=FinancialAidStatus.RESET).count() == 1
        financial_aid.refresh_from_db()
        assert financial_aid.tier_program == self.tier_programs["75k"]
        assert financial_aid.status == FinancialAidStatus.SKIPPED
        # Check logging
        assert FinancialAidAudit.objects.count() == 1
 def test_financial_aid_model_unique(self):
     """
     Tests that FinancialAid objects are unique per User and Program
     """
     financial_aid = FinancialAidFactory.create()
     # Test creation of FinancialAid that isn't unique_together with "user" and "tier_program__program"
     # financial aid with same user and different program (new program created by the factory)
     FinancialAidFactory.create(user=financial_aid.user)
     # financial aid with same program and different user (new user created by the factory)
     FinancialAidFactory.create(tier_program=financial_aid.tier_program)
     # Test updating the original FinancialAid doesn't raise ValidationError
     financial_aid.income_usd = 100
     financial_aid.save()
     # Test creation should fail for FinancialAid already existing with the same "user" and "tier_program__program"
     with self.assertRaises(ValidationError):
         FinancialAidFactory.create(user=financial_aid.user,
                                    tier_program=financial_aid.tier_program)
 def test_financial_aid_with_documents_sent(self):
     """
     Test that a user that has a FinancialAid record and has sent documents will have serialized financial aid
     information that indicates the date that documents were sent
     """
     now = now_in_utc()
     fin_aid = FinancialAidFactory.create(
         user=self.user,
         tier_program=self.min_tier_program,
         date_documents_sent=now,
     )
     serialized = FinancialAidDashboardSerializer.serialize(self.user, self.program)
     assert serialized == {
         "id": fin_aid.id,
         "has_user_applied": True,
         "application_status": fin_aid.status,
         "min_possible_cost": 250,
         "max_possible_cost": 1000,
         "date_documents_sent": now.date(),
     }
Exemple #41
0
 def test_get_course_price_for_learner_with_financial_aid(self, status):
     """
     Tests get_course_price_for_learner() who has approved financial aid
     """
     enrollment = ProgramEnrollment.objects.get(program=self.program,
                                                user=self.profile.user)
     financial_aid = FinancialAidFactory.create(
         user=self.profile.user,
         tier_program=self.tier_programs['25k'],
         status=status,
     )
     course_price = self.program.price
     expected_response = {
         "program_id": enrollment.program.id,
         "price": course_price - financial_aid.tier_program.discount_amount,
         "financial_aid_availability": True,
         "has_financial_aid_request": True
     }
     self.assertDictEqual(get_formatted_course_price(enrollment),
                          expected_response)
Exemple #42
0
 def test_financial_aid_with_documents_sent(self):
     """
     Test that a user that has a FinancialAid record and has sent documents will have serialized financial aid
     information that indicates the date that documents were sent
     """
     now = now_in_utc()
     fin_aid = FinancialAidFactory.create(
         user=self.user,
         tier_program=self.min_tier_program,
         date_documents_sent=now,
     )
     serialized = FinancialAidDashboardSerializer.serialize(
         self.user, self.program)
     assert serialized == {
         "id": fin_aid.id,
         "has_user_applied": True,
         "application_status": fin_aid.status,
         "min_possible_cost": 250,
         "max_possible_cost": 1000,
         "date_documents_sent": now.date(),
     }
Exemple #43
0
 def test_get_course_price_for_learner_with_financial_aid(self, status):
     """
     Tests get_course_price_for_learner() who has approved financial aid
     """
     enrollment = ProgramEnrollment.objects.get(program=self.program, user=self.profile.user)
     financial_aid = FinancialAidFactory.create(
         user=self.profile.user,
         tier_program=self.tier_programs['25k'],
         status=status,
     )
     course_price = self.program.price
     expected_response = {
         "program_id": enrollment.program.id,
         "price": course_price - financial_aid.tier_program.discount_amount,
         "financial_aid_availability": True,
         "has_financial_aid_request": True
     }
     self.assertDictEqual(
         get_formatted_course_price(enrollment),
         expected_response
     )
Exemple #44
0
 def test_datetime(self):
     """
     Test that a model with a datetime and date field is handled correctly
     """
     financial_aid = FinancialAidFactory.create(justification=None)
     assert serialize_model_object(financial_aid) == {
         'country_of_income': financial_aid.country_of_income,
         'country_of_residence': financial_aid.country_of_residence,
         'created_on': format_as_iso8601(financial_aid.created_on),
         'date_documents_sent': financial_aid.date_documents_sent.isoformat(),
         'date_exchange_rate': format_as_iso8601(financial_aid.date_exchange_rate),
         'id': financial_aid.id,
         'income_usd': financial_aid.income_usd,
         'justification': None,
         'original_currency': financial_aid.original_currency,
         'original_income': financial_aid.original_income,
         'status': financial_aid.status,
         'tier_program': financial_aid.tier_program.id,
         'updated_on': format_as_iso8601(financial_aid.updated_on),
         'user': financial_aid.user.id,
     }
 def test_to_dict(self):
     """
     assert output of to_dict
     """
     financial_aid = FinancialAidFactory.create()
     assert financial_aid.to_dict() == serialize_model_object(financial_aid)
Exemple #46
0
 def setUpTestData(cls):
     course_run = CourseRunFactory.create()
     cls.financial_aid = FinancialAidFactory.create()
     cls.tier_program = cls.financial_aid.tier_program
     cls.tier_program.program = course_run.course.program
     cls.tier_program.save()
Exemple #47
0
 def setUpTestData(cls):
     course_run = CourseRunFactory.create()
     cls.financial_aid = FinancialAidFactory.create()
     cls.tier_program = cls.financial_aid.tier_program
     cls.tier_program.program = course_run.course.program
     cls.tier_program.save()