155 lines
3.7 KiB
Python
155 lines
3.7 KiB
Python
|
|
"""Unit test untuk composite score (pure, tanpa DB).
|
||
|
|
|
||
|
|
Ditandai `unit` supaya fixture autouse _isolate_database melewatinya —
|
||
|
|
tidak butuh PostgreSQL hidup.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from services.evaluation import compute_composite
|
||
|
|
|
||
|
|
pytestmark = pytest.mark.unit
|
||
|
|
|
||
|
|
EX_W = 70.0
|
||
|
|
QZ_W = 30.0
|
||
|
|
DONE = 75.0
|
||
|
|
|
||
|
|
|
||
|
|
def test_exercise_quiz_3of4_both_pass():
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=True,
|
||
|
|
quiz_earned=3,
|
||
|
|
quiz_total=4,
|
||
|
|
has_exercise=True,
|
||
|
|
has_quiz=True,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == pytest.approx(92.5)
|
||
|
|
assert r.is_done is True
|
||
|
|
|
||
|
|
|
||
|
|
def test_exercise_passed_quiz_not_attempted():
|
||
|
|
# Exercise contributes its full weight (70); quiz term contributes 0
|
||
|
|
# (not attempted) → composite = 70.0, which is < 75 threshold → not done.
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=True,
|
||
|
|
quiz_earned=None,
|
||
|
|
quiz_total=None,
|
||
|
|
has_exercise=True,
|
||
|
|
has_quiz=True,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 70.0
|
||
|
|
assert r.is_done is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_quiz_attempted_exercise_not_passed():
|
||
|
|
# Exercise term contributes 0 (not passed); quiz contributes its full
|
||
|
|
# weight (30) → composite = 30.0, < 75 threshold → not done.
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=False,
|
||
|
|
quiz_earned=4,
|
||
|
|
quiz_total=4,
|
||
|
|
has_exercise=True,
|
||
|
|
has_quiz=True,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 30.0
|
||
|
|
assert r.is_done is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_exercise_only_passed():
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=True,
|
||
|
|
quiz_earned=None,
|
||
|
|
quiz_total=None,
|
||
|
|
has_exercise=True,
|
||
|
|
has_quiz=False,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 100.0
|
||
|
|
assert r.is_done is True
|
||
|
|
|
||
|
|
|
||
|
|
def test_exercise_only_not_passed():
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=False,
|
||
|
|
quiz_earned=None,
|
||
|
|
quiz_total=None,
|
||
|
|
has_exercise=True,
|
||
|
|
has_quiz=False,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 0.0
|
||
|
|
assert r.is_done is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_quiz_only_3of4():
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=None,
|
||
|
|
quiz_earned=3,
|
||
|
|
quiz_total=4,
|
||
|
|
has_exercise=False,
|
||
|
|
has_quiz=True,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 75.0
|
||
|
|
assert r.is_done is True
|
||
|
|
|
||
|
|
|
||
|
|
def test_quiz_only_1of4():
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=None,
|
||
|
|
quiz_earned=1,
|
||
|
|
quiz_total=4,
|
||
|
|
has_exercise=False,
|
||
|
|
has_quiz=True,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 25.0
|
||
|
|
assert r.is_done is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_reading_only():
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=None,
|
||
|
|
quiz_earned=None,
|
||
|
|
quiz_total=None,
|
||
|
|
has_exercise=False,
|
||
|
|
has_quiz=False,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 100.0
|
||
|
|
assert r.is_done is True
|
||
|
|
|
||
|
|
|
||
|
|
def test_exercise_pass_quiz_0of4_below_threshold():
|
||
|
|
r = compute_composite(
|
||
|
|
exercise_passed=True,
|
||
|
|
quiz_earned=0,
|
||
|
|
quiz_total=4,
|
||
|
|
has_exercise=True,
|
||
|
|
has_quiz=True,
|
||
|
|
exercise_weight=EX_W,
|
||
|
|
quiz_weight=QZ_W,
|
||
|
|
done_min_percent=DONE,
|
||
|
|
)
|
||
|
|
assert r.composite_percent == 70.0
|
||
|
|
assert r.is_done is False
|