Kentlo commited on
Commit
8b7e28b
ยท
verified ยท
1 Parent(s): 88c7275

Sync from GitHub b098d17dbed1a6386c212d28b4bfa6138ad59d75 (part 2)

Browse files
streamlit_app.py CHANGED
The diff for this file is too large to render. See raw diff
 
tests/test_learning_lab_content.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections import Counter
2
+
3
+ from cert_study_app.services.docs_source_service import active_docs_sources, doc_source_by_id
4
+ from cert_study_app.services.learning_lab_service import PRACTICE_TASKS, lessons_for_track, quizzes_for_track
5
+
6
+
7
+ ACTIVE_TRACKS = ("linux", "azure", "tool_docs")
8
+
9
+
10
+ def test_learning_lab_content_has_no_duplicate_ids():
11
+ lesson_ids = [lesson.id for track in ACTIVE_TRACKS for lesson in lessons_for_track(track)]
12
+ quiz_ids = [quiz.id for track in ACTIVE_TRACKS for quiz in quizzes_for_track(track)]
13
+ practice_ids = [task.id for task in PRACTICE_TASKS]
14
+
15
+ assert [item_id for item_id, count in Counter(lesson_ids).items() if count > 1] == []
16
+ assert [item_id for item_id, count in Counter(quiz_ids).items() if count > 1] == []
17
+ assert [item_id for item_id, count in Counter(practice_ids).items() if count > 1] == []
18
+
19
+
20
+ def test_learning_lab_content_sources_are_registered():
21
+ source_ids = {
22
+ item.source_id
23
+ for track in ACTIVE_TRACKS
24
+ for item in [*lessons_for_track(track), *quizzes_for_track(track)]
25
+ }
26
+
27
+ assert sorted(source_id for source_id in source_ids if not doc_source_by_id(source_id)) == []
28
+
29
+
30
+ def test_learning_lab_quizzes_point_to_existing_lessons():
31
+ lesson_ids = {lesson.id for track in ACTIVE_TRACKS for lesson in lessons_for_track(track)}
32
+
33
+ assert sorted(
34
+ quiz.lesson_id
35
+ for track in ACTIVE_TRACKS
36
+ for quiz in quizzes_for_track(track)
37
+ if quiz.lesson_id not in lesson_ids
38
+ ) == []
39
+
40
+
41
+ def test_learning_lab_has_exam_ready_content_volume():
42
+ assert len(lessons_for_track("linux")) >= 50
43
+ assert len(quizzes_for_track("linux")) >= 25
44
+ assert len([task for task in PRACTICE_TASKS if task.track == "linux"]) >= 30
45
+
46
+ assert len(lessons_for_track("azure")) >= 50
47
+ assert len(quizzes_for_track("azure")) >= 25
48
+
49
+ assert len(lessons_for_track("tool_docs")) >= 10
50
+ assert len(quizzes_for_track("tool_docs")) >= 7
51
+
52
+
53
+ def test_docs_sources_cover_active_tracks():
54
+ assert len(active_docs_sources("azure")) >= 20
55
+ assert len(active_docs_sources("linux")) >= 10
56
+ assert len(active_docs_sources("tool_docs")) >= 4
tests/test_learning_progress_service.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import date
2
+
3
+ from cert_study_app.services import learning_progress_service as progress_service
4
+
5
+
6
+ def test_learning_progress_migrates_legacy_daily_key(tmp_path, monkeypatch):
7
+ progress_path = tmp_path / "learning_progress.json"
8
+ progress_path.write_text(
9
+ '{"daily": {"2026-06-21": {"tracks": {"linux": {"steps": ["lesson"], "counts": {"lesson": 1}}}}}}',
10
+ encoding="utf-8",
11
+ )
12
+ monkeypatch.setattr(progress_service, "PROGRESS_PATH", progress_path)
13
+
14
+ assert progress_service.completed_steps("linux", date(2026, 6, 21)) == {"lesson"}
15
+ assert progress_service.study_units("linux", date(2026, 6, 21)) == 0.3
16
+
17
+
18
+ def test_learning_progress_writes_activity_key(tmp_path, monkeypatch):
19
+ progress_path = tmp_path / "learning_progress.json"
20
+ monkeypatch.setattr(progress_service, "PROGRESS_PATH", progress_path)
21
+
22
+ progress_service.record_activity("linux", "practice", amount=1, target_date=date(2026, 6, 21))
23
+ payload = progress_path.read_text(encoding="utf-8")
24
+
25
+ assert '"activity"' in payload
26
+ assert '"daily"' not in payload
tests/test_streamlit_routes.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit_app
2
+
3
+
4
+ def test_learning_landing_routes_are_registered():
5
+ routes = streamlit_app.learning_landing_routes()
6
+
7
+ assert routes["๊ฐœ๋…๊ณต๋ถ€"] == streamlit_app.render_concept_mode_home
8
+ assert routes["๊ฐœ๋… ๊ณต๋ถ€"] == streamlit_app.render_concept_mode_home
9
+ assert routes["์‹ค์Šต"] == streamlit_app.render_practice_mode_home
10
+ assert routes["์‹œํ—˜์ค€๋น„"] == streamlit_app.render_exam_prep_home
11
+ assert routes["์‹œํ—˜ ์ค€๋น„"] == streamlit_app.render_exam_prep_home