Skip to content

Commit 591ae38

Browse files
committed
test: add tests
1 parent 0997c27 commit 591ae38

File tree

5 files changed

+125
-3
lines changed

5 files changed

+125
-3
lines changed

run_edx_integration_tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ run_plugin_tests() {
7878
fi
7979

8080
# Run the pytest command with CMS settings (for ol_openedx_chat)
81-
if [[ "$plugin_dir" == *"ol_openedx_chat"* ]]; then
81+
if [[ "$plugin_dir" == *"ol_openedx_chat"* || "$plugin_dir" == *"ol_openedx_course_sync"* ]]; then
8282
pytest . --cov . --ds=cms.envs.test
8383

8484
PYTEST_SUCCESS=$?

src/ol_openedx_course_sync/BUILD

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ python_sources(
22
name="ol_openedx_course_sync_source",
33
dependencies=[
44
"src/ol_openedx_course_sync/migrations:ol_openedx_course_sync_migrations",
5-
"//:external_dependencies#edx-opaque-keys",
6-
"//:external_dependencies#celery",
75
],
86
)
97

src/ol_openedx_course_sync/models.py

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class CourseSyncParentOrg(models.Model):
2121

2222
organization = models.CharField(max_length=255, unique=True)
2323

24+
class Meta:
25+
app_label = "ol_openedx_course_sync"
26+
2427
def __str__(self):
2528
return f"{self.organization} Course Sync Parent Org"
2629

@@ -39,6 +42,9 @@ class CourseSyncMap(models.Model):
3942
blank=True, help_text="Comma separated list of target course keys"
4043
)
4144

45+
class Meta:
46+
app_label = "ol_openedx_course_sync"
47+
4248
def __str__(self):
4349
return f"{self.source_course} Course Sync Map"
4450

src/ol_openedx_course_sync/setup.cfg

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[isort]
2+
include_trailing_comma = True
3+
indent = ' '
4+
line_length = 120
5+
multi_line_output = 3
6+
skip=
7+
migrations
8+
9+
[wheel]
10+
universal = 1
11+
12+
[tool:pytest]
13+
pep8maxlinelength = 119
14+
DJANGO_SETTINGS_MODULE = lms.envs.test
15+
addopts = --nomigrations --reuse-db --durations=20
16+
# Enable default handling for all warnings, including those that are ignored by default;
17+
# but hide rate-limit warnings (because we deliberately don't throttle test user logins)
18+
# and field_data deprecation warnings (because fixing them requires a major low-priority refactoring)
19+
filterwarnings =
20+
default
21+
ignore::xblock.exceptions.FieldDataDeprecationWarning
22+
ignore::pytest.PytestConfigWarning
23+
ignore:No request passed to the backend, unable to rate-limit:UserWarning
24+
ignore:Flags not at the start of the expression:DeprecationWarning
25+
ignore:Using or importing the ABCs from 'collections' instead of from 'collections.abc':DeprecationWarning
26+
ignore:invalid escape sequence:DeprecationWarning
27+
ignore:`formatargspec` is deprecated since Python 3.5:DeprecationWarning
28+
ignore:the imp module is deprecated in favour of importlib:DeprecationWarning
29+
ignore:"is" with a literal:SyntaxWarning
30+
ignore:defusedxml.lxml is no longer supported:DeprecationWarning
31+
ignore: `np.int` is a deprecated alias for the builtin `int`.:DeprecationWarning
32+
ignore: `np.float` is a deprecated alias for the builtin `float`.:DeprecationWarning
33+
ignore: `np.complex` is a deprecated alias for the builtin `complex`.:DeprecationWarning
34+
ignore: 'etree' is deprecated. Use 'xml.etree.ElementTree' instead.:DeprecationWarning
35+
ignore: defusedxml.cElementTree is deprecated, import from defusedxml.ElementTree instead.:DeprecationWarning
36+
37+
38+
junit_family = xunit2
39+
norecursedirs = .* *.egg build conf dist node_modules test_root cms/envs lms/envs
40+
python_classes =
41+
python_files = tests.py test_*.py tests_*.py *_tests.py __init__.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
Tests for models
3+
"""
4+
5+
import pytest
6+
from django.core.exceptions import ValidationError
7+
from ol_openedx_course_sync.models import CourseSyncMap
8+
from openedx.core.djangolib.testing.utils import skip_unless_cms
9+
10+
11+
@skip_unless_cms
12+
@pytest.mark.django_db()
13+
@pytest.mark.parametrize(
14+
("existing", "new", "expected_error_field"),
15+
[
16+
# Case 1: source_course is already a target_course elsewhere
17+
(
18+
{
19+
"source_course": "course-v1:edX+DemoX+2025",
20+
"target_courses": "course-v1:edX+DemoX+2026",
21+
},
22+
{
23+
"source_course": "course-v1:edX+DemoX+2026",
24+
"target_courses": "course-v1:edX+DemoX+2027",
25+
},
26+
"source_course",
27+
),
28+
# Case 2: target_course is already a source_course elsewhere
29+
(
30+
{
31+
"source_course": "course-v1:edX+DemoX+2028",
32+
"target_courses": "course-v1:edX+DemoX+2029",
33+
},
34+
{
35+
"source_course": "course-v1:edX+DemoX+2030",
36+
"target_courses": "course-v1:edX+DemoX+2028",
37+
},
38+
"target_courses",
39+
),
40+
# Case 3: target_course is already used as target_course in another mapping
41+
(
42+
{
43+
"source_course": "course-v1:edX+DemoX+2031",
44+
"target_courses": "course-v1:edX+DemoX+2032",
45+
},
46+
{
47+
"source_course": "course-v1:edX+DemoX+2033",
48+
"target_courses": "course-v1:edX+DemoX+2032",
49+
},
50+
"target_courses",
51+
),
52+
],
53+
)
54+
def test_course_sync_map_clean_conflicts(existing, new, expected_error_field):
55+
"""
56+
Parametrized test to validate CourseSyncMap.clean() conflicts:
57+
- A source course cannot be used as a target.
58+
- A target course cannot be used as a source.
59+
- Target courses cannot be duplicated across mappings.
60+
"""
61+
CourseSyncMap.objects.create(**existing)
62+
obj = CourseSyncMap(**new)
63+
64+
with pytest.raises(ValidationError) as context:
65+
obj.full_clean()
66+
assert expected_error_field in context.value.error_dict
67+
68+
69+
@skip_unless_cms
70+
@pytest.mark.django_db()
71+
def test_valid_course_sync_map():
72+
"""Valid CourseSyncMap instance should pass validation."""
73+
obj = CourseSyncMap(
74+
source_course="course-v1:edX+DemoX+2040",
75+
target_courses="course-v1:edX+DemoX+2041,course-v1:edX+DemoX+2042",
76+
)
77+
obj.full_clean() # Should not raise

0 commit comments

Comments
 (0)