Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: created mock_apps for ci testing #8

Merged
merged 8 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
matrix:
os: [ubuntu-latest]
python-version: ['3.11']
toxenv: [quality, docs, pii_check, django42]
toxenv: [quality, pii_check, django42]

steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ docs/channel_integrations.*.rst
# Private requirements
requirements/private.in
requirements/private.txt

# Code editor settings
.idea/
.vscode/
5 changes: 4 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ Unreleased

*

0.1.0 – 2024-10-30
0.1.0 – 2025-01-16
sameeramin marked this conversation as resolved.
Show resolved Hide resolved
**********************************************

Added
=====

* Created ``mock_apps`` for testing purposes.
* Updated requirements in ``base.in`` and run ``make requirements``.
* Migrated ``integrated_channel`` app from edx-enterprise.
* First release on PyPI.
2 changes: 1 addition & 1 deletion channel_integrations/catalog_service_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
A utility collection for calls from integrated_channels to Catalog service
A utility collection for calls from integrated_channels to Catalog service.
"""
from enterprise.api_client.discovery import get_course_catalog_api_service_client

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from django.conf import settings
from django.db.models import Q
from django.utils import timezone

from enterprise.api_client.enterprise_catalog import EnterpriseCatalogApiClient
from enterprise.constants import (
EXEC_ED_CONTENT_DESCRIPTION_TAG,
Expand All @@ -23,6 +22,7 @@
TRANSMISSION_MARK_CREATE,
)
from enterprise.utils import get_content_metadata_item_id

from channel_integrations.integrated_channel.exporters import Exporter
from channel_integrations.utils import generate_formatted_log, truncate_item_dicts

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@
from datetime import datetime
from logging import getLogger

from opaque_keys import InvalidKeyError
from requests.exceptions import HTTPError

from consent.models import DataSharingConsent

Check warning on line 12 in channel_integrations/integrated_channel/exporters/learner_data.py

View check run for this annotation

Codecov / codecov/patch

channel_integrations/integrated_channel/exporters/learner_data.py#L12

Added line #L12 was not covered by tests
from django.apps import apps
from django.contrib import auth
from django.utils import timezone
from django.utils.dateparse import parse_datetime
from enterprise.api_client.lms import GradesApiClient
from enterprise.models import EnterpriseCourseEnrollment
from opaque_keys import InvalidKeyError
from requests.exceptions import HTTPError

Check warning on line 20 in channel_integrations/integrated_channel/exporters/learner_data.py

View check run for this annotation

Codecov / codecov/patch

channel_integrations/integrated_channel/exporters/learner_data.py#L17-L20

Added lines #L17 - L20 were not covered by tests

from channel_integrations.integrated_channel.channel_settings import ChannelSettingsMixin

try:
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
except ImportError:
CourseOverview = None
from consent.models import DataSharingConsent
from enterprise.api_client.lms import GradesApiClient
from enterprise.models import EnterpriseCourseEnrollment
from channel_integrations.catalog_service_utils import get_course_id_for_enrollment
from channel_integrations.integrated_channel.exporters import Exporter
from channel_integrations.lms_utils import (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

from django.core.management.base import CommandError
from django.utils.translation import gettext as _

from enterprise.models import EnterpriseCustomer

from channel_integrations.blackboard.models import BlackboardEnterpriseCustomerConfiguration
from channel_integrations.canvas.models import CanvasEnterpriseCustomerConfiguration
from channel_integrations.cornerstone.models import CornerstoneEnterpriseCustomerConfiguration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
"""
from logging import getLogger

from requests.exceptions import ConnectionError, RequestException, Timeout # pylint: disable=redefined-builtin

from django.contrib import auth
from django.core.management.base import BaseCommand, CommandError

from enterprise.api_client.enterprise_catalog import EnterpriseCatalogApiClient
from requests.exceptions import ConnectionError, RequestException, Timeout # pylint: disable=redefined-builtin

Check warning on line 9 in channel_integrations/integrated_channel/management/commands/assign_skills_to_degreed_courses.py

View check run for this annotation

Codecov / codecov/patch

channel_integrations/integrated_channel/management/commands/assign_skills_to_degreed_courses.py#L9

Added line #L9 was not covered by tests

from channel_integrations.degreed2.client import Degreed2APIClient
from channel_integrations.exceptions import ClientError
from channel_integrations.integrated_channel.management.commands import IntegratedChannelCommandMixin
Expand Down
8 changes: 3 additions & 5 deletions channel_integrations/integrated_channel/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@
import json
import logging

from jsonfield.fields import JSONField

from django.contrib import auth
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Q
from django.db.models.query import QuerySet
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from model_utils.models import TimeStampedModel

from enterprise.constants import TRANSMISSION_MARK_CREATE, TRANSMISSION_MARK_DELETE, TRANSMISSION_MARK_UPDATE
from enterprise.models import EnterpriseCustomer, EnterpriseCustomerCatalog
from enterprise.utils import localized_utcnow
from jsonfield.fields import JSONField
from model_utils.models import TimeStampedModel

Check warning on line 19 in channel_integrations/integrated_channel/models.py

View check run for this annotation

Codecov / codecov/patch

channel_integrations/integrated_channel/models.py#L18-L19

Added lines #L18 - L19 were not covered by tests

from channel_integrations.integrated_channel.exporters.content_metadata import ContentMetadataExporter
from channel_integrations.integrated_channel.exporters.learner_data import LearnerExporter
from channel_integrations.integrated_channel.transmitters.content_metadata import ContentMetadataTransmitter
Expand Down
5 changes: 2 additions & 3 deletions channel_integrations/integrated_channel/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@

from celery import shared_task
from celery.utils.log import get_task_logger
from edx_django_utils.monitoring import set_code_owner_attribute

from django.conf import settings
from django.contrib import auth
from django.core.cache import cache
from django.utils import timezone

from edx_django_utils.monitoring import set_code_owner_attribute

Check warning on line 14 in channel_integrations/integrated_channel/tasks.py

View check run for this annotation

Codecov / codecov/patch

channel_integrations/integrated_channel/tasks.py#L14

Added line #L14 was not covered by tests
from enterprise.utils import get_enterprise_uuids_for_user_and_course

from channel_integrations.integrated_channel.constants import TASK_LOCK_EXPIRY_SECONDS
from channel_integrations.integrated_channel.management.commands import (
INTEGRATED_CHANNEL_CHOICES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
from itertools import islice

import requests

from django.apps import apps
from django.conf import settings

from enterprise.utils import localized_utcnow, truncate_string

from channel_integrations.exceptions import ClientError
from channel_integrations.integrated_channel.client import IntegratedChannelApiClient
from channel_integrations.integrated_channel.transmitters import Transmitter
Expand Down Expand Up @@ -130,7 +129,7 @@
"""
return response

def _transmit_action(self, content_metadata_item_map, client_method, action_name): # pylint: disable=too-many-statements
def _transmit_action(self, content_metadata_item_map, client_method, action_name): # pylint: disable=R0915

Check warning on line 132 in channel_integrations/integrated_channel/transmitters/content_metadata.py

View check run for this annotation

Codecov / codecov/patch

channel_integrations/integrated_channel/transmitters/content_metadata.py#L132

Added line #L132 was not covered by tests
"""
Do the work of calling the appropriate client method, saving the results, and updating
the appropriate timestamps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from http import HTTPStatus

from django.apps import apps

from enterprise.utils import localized_utcnow

from channel_integrations.exceptions import ClientError
from channel_integrations.integrated_channel.channel_settings import ChannelSettingsMixin
from channel_integrations.integrated_channel.client import IntegratedChannelApiClient
Expand Down
6 changes: 3 additions & 3 deletions channel_integrations/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@

import pytz
import requests

from django.apps import apps
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from django.utils import timezone
from django.utils.html import strip_tags

from enterprise.utils import parse_datetime_handle_invalid, parse_lms_api_datetime

from channel_integrations.catalog_service_utils import get_course_run_for_enrollment

UNIX_EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc)
Expand Down Expand Up @@ -503,8 +502,9 @@
"""
Get the appropriate enterprise client based on channel code
"""
# TODO: Suppress pylint warning for E0401 and E0611 until we migrate canvas
# TODO: Other configs
from channel_integrations.canvas.client import CanvasAPIClient # pylint: disable=C0415
from channel_integrations.canvas.client import CanvasAPIClient # pylint: disable=C0415, E0401, E0611

Check warning on line 507 in channel_integrations/utils.py

View check run for this annotation

Codecov / codecov/patch

channel_integrations/utils.py#L507

Added line #L507 was not covered by tests
_enterprise_client_model_by_channel_code = {
'canvas': CanvasAPIClient,
}
Expand Down
1 change: 1 addition & 0 deletions manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_settings')
sys.path.append('./mock_apps')
sys.path.append(PWD)
try:
from django.core.management import execute_from_command_line
Expand Down
Empty file added mock_apps/__init__.py
Empty file.
Empty file added mock_apps/consent/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions mock_apps/consent/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
Errors thrown by the APIs in the Consent application.
"""


class InvalidProxyConsent(Exception):
"""A proxy consent object with the given details could not be created."""
9 changes: 9 additions & 0 deletions mock_apps/consent/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
Mixins for edX Enterprise's Consent application.
"""


class ConsentModelMixin:
"""
A mixin for Data Sharing Consent classes that require common, reusable functionality.
"""
11 changes: 11 additions & 0 deletions mock_apps/consent/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class DataSharingConsent:
"""
An abstract representation of Data Sharing Consent granted to an Enterprise for a course by a User.

The model is used to store a persistent, historical consent state for users granting, not granting, or revoking
data sharing consent to an Enterprise for a course.

.. pii: The username field inherited from Consent contains PII.
.. pii_types: username
.. pii_retirement: consumer_api
"""
Empty file.
Empty file.
7 changes: 7 additions & 0 deletions mock_apps/enterprise/api_client/discovery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
Utilities to get details from the course catalog API.
"""


def get_course_catalog_api_service_client(site=None):
return []
15 changes: 15 additions & 0 deletions mock_apps/enterprise/api_client/enterprise_catalog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Mock Client for communicating with the Enterprise API.
"""


class EnterpriseCatalogApiClient:
"""
The API client to make calls to the Enterprise Catalog API.
"""

def get_catalog_diff(self, enterprise_customer_catalog, content_keys, should_raise_exception=True):
return [], [], []

def get_content_metadata(self, enterprise_customer, enterprise_catalogs=None, content_keys_filter=None):
return []
14 changes: 14 additions & 0 deletions mock_apps/enterprise/api_client/lms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""
Utilities to get details from the course catalog API.
"""


class GradesApiClient:
"""
The API client to make calls to the LMS Grades API.

Note that this API client requires a JWT token, and so it keeps its token alive.
"""

def get_course_assessment_grades(self, course_id, username):
return []
20 changes: 20 additions & 0 deletions mock_apps/enterprise/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
Enterprise Django application constants.
"""

TRANSMISSION_MARK_CREATE = 'create'
TRANSMISSION_MARK_UPDATE = 'update'
TRANSMISSION_MARK_DELETE = 'delete'

# ContentFilter field types for validation.
CONTENT_FILTER_FIELD_TYPES = {
'key': {'type': list, 'subtype': str},
'first_enrollable_paid_seat_price__lte': {'type': str}
}

MAX_ALLOWED_TEXT_LENGTH = 16_000_000
EXEC_ED_COURSE_TYPE = "executive-education-2u"
IC_CREATE_ACTION = 'create'
IC_UPDATE_ACTION = 'update'
EXEC_ED_CONTENT_DESCRIPTION_TAG = ("This instructor-led Executive Education course is "
"presented by GetSmarter, an edX partner. ")
23 changes: 23 additions & 0 deletions mock_apps/enterprise/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
Database models for enterprise.
"""
from django.db import models


class EnterpriseCustomerCatalog:
"""
Store catalog information from course discovery specifically for Enterprises.
"""


class EnterpriseCourseEnrollment:
"""
Store information about the enrollment of a user in a course.
"""


class EnterpriseCustomer:
enterprise_customer_catalogs = models.ManyToManyField(
EnterpriseCustomerCatalog,
verbose_name="Enterprise Customer Catalogs",
)
Loading