Esempio n. 1
0
    def test_add_several_organizations(self):
        """
        Test that the query_count of bulk_add_organizations does not increase
        when given more organizations.
        """
        existing_org = api.add_organization(
            self.make_organization_data("existing_org"))
        api.remove_organization(
            api.add_organization(
                self.make_organization_data("org_to_reactivate"))["id"])

        # 1 query to load list of existing orgs,
        # 1 query to filter for only inactive existing orgs,
        # 1 query for activate-existing, and 1 query for create-new.
        with self.assertNumQueries(4):
            api.bulk_add_organizations([
                existing_org,
                existing_org,
                existing_org,
                self.make_organization_data("org_to_reactivate"),
                self.make_organization_data("new_org_1"),
                self.make_organization_data("new_org_2"),
                self.make_organization_data("new_org_3"),
                self.make_organization_data("new_org_4"),
                self.make_organization_data("new_org_5"),
                self.make_organization_data("new_org_6"),
                self.make_organization_data("new_org_7"),
                self.make_organization_data("new_org_8"),
                self.make_organization_data("new_org_9"),
                self.make_organization_data("new_org_9"),  # Redundant.
                self.make_organization_data("new_org_9"),  # Redundant.
            ])
        assert len(api.get_organizations()) == 11
def get_organizations():
    """
    Client API operation adapter/wrapper
    """
    if not settings.FEATURES.get('ORGANIZATIONS_APP', False):
        return []
    from organizations import api as organizations_api
    return organizations_api.get_organizations()
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     organizations = get_organizations()
     org_choices = [(org["id"], org["name"]) for org in organizations]
     org_choices.insert(0, ('', 'None'))
     self.fields['organization_id'] = forms.TypedChoiceField(
         choices=org_choices, required=False, coerce=int, empty_value=None)
     languages = list(settings.CERTIFICATE_TEMPLATE_LANGUAGES.items())
     lang_choices = sorted(languages, key=itemgetter(1))
     lang_choices.insert(0, (None, 'All Languages'))
     self.fields['language'] = forms.ChoiceField(choices=lang_choices,
                                                 required=False)
 def test_get_organizations(self):
     """ Unit Test: test_get_organizations """
     api.add_organization({
         'name': 'local_organization_1ßßß',
         'description': 'Local Organization 1 Descriptionßßß'
     })
     api.add_organization({
         'name': 'local_organization_2ßßß',
         'description': 'Local Organization 2 Descriptionßßß'
     })
     with self.assertNumQueries(1):
         organizations = api.get_organizations()
     self.assertEqual(len(organizations), 3)  # One from SetUp, two from local
Esempio n. 5
0
    def test_dry_run(self, mock_log_info):
        """
        Test that `bulk_add_organizations` does nothing when `dry_run` is
        specified (except logging).
        """
        api.bulk_add_organizations(
            [self.make_organization_data("org_a")],
            dry_run=True,
        )

        assert api.get_organizations() == []
        # One for reactivations, one for creations.
        assert mock_log_info.call_count == 2
Esempio n. 6
0
 def test_validation_errors(self):
     """
     Test the `bulk_add_organizations` raises validation errors on bad input,
     and no organizations are created.
     """
     with self.assertRaises(exceptions.InvalidOrganizationException):
         api.bulk_add_organizations([
             self.make_organization_data("valid_org"),
             {
                 "description": "org with no short_name!"
             },
         ])
     assert len(api.get_organizations()) == 0
Esempio n. 7
0
def get_organizations():
    """
    Client API operation adapter/wrapper
    """
    if not organizations_enabled():
        return []
    from organizations import api as organizations_api
    # Due to the way unit tests run for edx-platform, models are not yet available at the time
    # of Django admin form instantiation.  This unfortunately results in an invocation of the following
    # workflow, because the test configuration is (correctly) configured to exercise the application
    # The good news is that this case does not manifest in the Real World, because migrations have
    # been run ahead of application instantiation and the flag set only when that is truly the case.
    try:
        return organizations_api.get_organizations()
    except DatabaseError:
        return []
def get_organizations():
    """
    Client API operation adapter/wrapper
    """
    if not organizations_enabled():
        return []
    from organizations import api as organizations_api
    # Due to the way unit tests run for edx-platform, models are not yet available at the time
    # of Django admin form instantiation.  This unfortunately results in an invocation of the following
    # workflow, because the test configuration is (correctly) configured to exercise the application
    # The good news is that this case does not manifest in the Real World, because migrations have
    # been run ahead of application instantiation and the flag set only when that is truly the case.
    try:
        return organizations_api.get_organizations()
    except DatabaseError:
        return []
Esempio n. 9
0
def index(request):
    from organizations.api import get_organizations

    # org_list = []
    course_discovery_meanings = getattr(settings, 'COURSE_DISCOVERY_MEANINGS',
                                        {})

    org_list = get_organizations()

    sorted_assoc_list = sorted(org_list,
                               key=lambda organizations: organizations['name'])

    return render_to_response(
        "associations/associations.html", {
            'organizations': sorted_assoc_list,
            'course_discovery_meanings': course_discovery_meanings
        })
Esempio n. 10
0
 def test_get_organizations(self):
     """ Unit Test: test_get_organizations """
     api.add_organization({
         'name':
         'local_organization_1ßßß',
         'description':
         'Local Organization 1 Descriptionßßß'
     })
     api.add_organization({
         'name':
         'local_organization_2ßßß',
         'description':
         'Local Organization 2 Descriptionßßß'
     })
     with self.assertNumQueries(1):
         organizations = api.get_organizations()
     self.assertEqual(len(organizations),
                      3)  # One from SetUp, two from local
Esempio n. 11
0
    def test_end_to_end(self, run_type):
        """
        Test the happy path of the backfill command without any mocking.
        """
        # org_A: already existing, with courses and a library.
        org_a = add_organization({"short_name": "org_A", "name": "Org A"})
        course_a1_key = CourseOverviewFactory(org="org_A", run="1").id
        CourseOverviewFactory(org="org_A", run="2")
        LibraryFactory(org="org_A")

        # Write linkage for org_a->course_a1.
        # (Linkage for org_a->course_a2 is purposefully left out here;
        # it should be created by the backfill).
        add_organization_course(org_a, course_a1_key)

        # org_B: already existing, but has no content.
        add_organization({"short_name": "org_B", "name": "Org B"})

        # org_C: has a few courses; should be created.
        CourseOverviewFactory(org="org_C", run="1")
        CourseOverviewFactory(org="org_C", run="2")
        # Include an Old Mongo Modulestore -style deprecated course key.
        # This can be safely removed when Old Mongo Modulestore support is
        # removed.
        CourseOverviewFactory(
            id=CourseLocator.from_string("org_C/toy/3"),
            org="org_C",
            run="3",
        )

        # org_D: has both a course and a library; should be created.
        CourseOverviewFactory(org="org_D", run="1")
        LibraryFactory(org="org_D")

        # org_E: just has a library; should be created.
        LibraryFactory(org="org_E")

        # Confirm starting condition:
        # Only orgs are org_A and org_B, and only linkage is org_a->course_a1.
        assert set(
            org["short_name"] for org in get_organizations()
        ) == {
            "org_A", "org_B"
        }
        assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 1
        assert len(get_organization_courses(get_organization_by_short_name('org_B'))) == 0

        # Run the backfill.
        call_command("backfill_orgs_and_org_courses", run_type)

        if run_type == "--dry":
            # Confirm ending conditions are the same as the starting conditions.
            assert set(
                org["short_name"] for org in get_organizations()
            ) == {
                "org_A", "org_B"
            }
            assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 1
            assert len(get_organization_courses(get_organization_by_short_name('org_B'))) == 0
        else:
            # Confirm ending condition:
            # All five orgs present. Each org a has expected number of org-course linkages.
            assert set(
                org["short_name"] for org in get_organizations()
            ) == {
                "org_A", "org_B", "org_C", "org_D", "org_E"
            }
            assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 2
            assert len(get_organization_courses(get_organization_by_short_name('org_B'))) == 0
            assert len(get_organization_courses(get_organization_by_short_name('org_C'))) == 3
            assert len(get_organization_courses(get_organization_by_short_name('org_D'))) == 1
            assert len(get_organization_courses(get_organization_by_short_name('org_E'))) == 0
Esempio n. 12
0
    def test_end_to_end(self):
        """
        Test the happy path of the backfill command without any mocking.
        """
        # org_A: already existing, with courses and a library.
        org_a = add_organization({"short_name": "org_A", "name": "Org A"})
        course_a1_key = CourseOverviewFactory(org="org_A", run="1").id
        CourseOverviewFactory(org="org_A", run="2")
        LibraryFactory(org="org_A")

        # Write linkage for org_a->course_a1.
        # (Linkage for org_a->course_a2 is purposefully left out here;
        # it should be created by the backfill).
        add_organization_course(org_a, course_a1_key)

        # org_B: already existing, but has no content.
        add_organization({"short_name": "org_B", "name": "Org B"})

        # org_C: has a couple courses; should be created.
        CourseOverviewFactory(org="org_C", run="1")
        CourseOverviewFactory(org="org_C", run="2")

        # org_D: has both a course and a library; should be created.
        CourseOverviewFactory(org="org_D", run="1")
        LibraryFactory(org="org_D")

        # org_E: just has a library; should be created.
        LibraryFactory(org="org_E")

        # Confirm starting condition:
        # Only orgs are org_A and org_B, and only linkage is org_a->course_a1.
        assert set(org["short_name"]
                   for org in get_organizations()) == {"org_A", "org_B"}
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_A'))) == 1
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_B'))) == 0

        # Run the backfill.
        call_command("backfill_orgs_and_org_courses", "--apply")

        # Confirm ending condition:
        # All five orgs present. Each org a has expected number of org-course linkages.
        assert set(org["short_name"] for org in get_organizations()) == {
            "org_A", "org_B", "org_C", "org_D", "org_E"
        }
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_A'))) == 2
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_B'))) == 0
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_C'))) == 2
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_D'))) == 1
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_E'))) == 0
Esempio n. 13
0
 def get(self, request, *args, **kwargs):
     """Returns organization list as json."""
     organizations = get_organizations()
     org_names_list = [(org["short_name"]) for org in organizations]
     return HttpResponse(dump_js_escaped_json(org_names_list),
                         content_type='application/json; charset=utf-8')
Esempio n. 14
0
 def get(self, request, *args, **kwargs):  # lint-amnesty, pylint: disable=unused-argument
     """Returns organization list as json."""
     organizations = get_organizations()
     org_names_list = [(org["short_name"]) for org in organizations]
     return HttpResponse(dump_js_escaped_json(org_names_list), content_type='application/json; charset=utf-8')  # lint-amnesty, pylint: disable=http-response-with-content-type-json
Esempio n. 15
0
    def test_edge_cases(self, mock_log_info):
        """
        Test that bulk_add_organizations handles a few edge cases as expected.
        """
        # Add three orgs, and remove all but the first.
        # Use capitalized name to confirm case insensitivity when checking
        # for existing orgs.
        api.add_organization(self.make_organization_data("EXISTING_ORG"))
        api.remove_organization(
            api.add_organization(
                self.make_organization_data("org_to_reactivate"))["id"])
        api.remove_organization(
            api.add_organization(
                self.make_organization_data("org_to_leave_inactive"))["id"])

        # 1 query to load list of existing orgs,
        # 1 query to filter for only inactive existing orgs,
        # 1 query for create, and 1 query for update.
        with self.assertNumQueries(4):
            api.bulk_add_organizations([

                # New organization.
                self.make_organization_data("org_X"),

                # Modify existing active organization; should be no-op.
                {
                    **self.make_organization_data("existing_org"), "description":
                    "this name should be ignored"
                },

                # Deleted organizations are still stored in the DB as "inactive".
                # Bulk-adding should reactivate it.
                self.make_organization_data("org_to_reactivate"),

                # Another new organizaiton.
                self.make_organization_data("org_Y"),

                # Another org with same short name (case-insensitively)
                # as first new organization; should be ignored.
                {
                    **self.make_organization_data("ORG_x"), "name":
                    "this name should be ignored"
                }
            ])

        # There should exist the already-existing org, the org that existed as inactive
        # but is not activated, and the two new orgs.
        # This should not include `org_to_leave_inactive`.
        organizations = api.get_organizations()
        assert {organization["short_name"]
                for organization in organizations
                } == {"EXISTING_ORG", "org_to_reactivate", "org_X", "org_Y"}

        # Organization dicts with already-taken short_names shouldn't have modified
        # the existing orgs.
        assert "this name should be ignored" not in {
            organization["name"]
            for organization in organizations
        }

        # Based on logging messages, make sure we dropped the appropriate
        # organization dict from the bulk-add batch.
        logging_of_drop_from_batch = mock_log_info.call_args_list[0][0]
        assert logging_of_drop_from_batch[1]["short_name"] == (
            # We dropped this org data:
            self.make_organization_data("ORG_x")["short_name"])
        assert logging_of_drop_from_batch[2]["short_name"] == (
            # in favor of this org data, which came earlier in the batch.
            self.make_organization_data("org_X")["short_name"])

        # Based on logging messages, make sure the expected breakdown of
        #    created vs. reactivated vs. not touched
        # is true for the organizations passed to `bulk_add_organizations`.
        logged_orgs_to_reactivate = mock_log_info.call_args_list[1][0][2]
        assert set(logged_orgs_to_reactivate) == {"org_to_reactivate"}
        logged_orgs_to_create = mock_log_info.call_args_list[2][0][2]
        assert set(logged_orgs_to_create) == {"org_X", "org_Y"}
Esempio n. 16
0
 def test_add_no_organizations(self):
     """
     Test that `bulk_add_organizations` is a no-op when given an empty list.
     """
     api.bulk_add_organizations([])
     assert len(api.get_organizations()) == 0