mathly / tests /test_focus_browser.py
3v324v23's picture
Add tests for student task list and quiz modes functionality
0ba5932
Raw History Blame Contribute Delete
5.53 kB
"""Focus practice end to end: the class teacher gives skills to one student from the report; only that student sees
it, marked as personal, and the report counts only them."""
import socket
import threading
import time
import pytest
from app.main import create_app
from test_assignments import MemoryAssignments
from test_worksheets import MemoryWorksheets
from test_worksheets_browser import NoAnswers, uvicorn
playwright = pytest.importorskip("playwright.sync_api")
TEACHER, DANA, YOSSI = ("bbbbbbbb-0000-4000-8000-00000000000%d" % i for i in (1, 2, 3))
mail = {TEACHER: "teacher@test.invalid", DANA: "dana@test.invalid", YOSSI: "yossi@test.invalid"}
class SchoolAuth:
url, key, secret = "https://test.invalid", "public-test", "server-test"
teachers = developers = frozenset()
def user(self, token):
return {"id": token, "email": mail[token]} if token in mail else None
def classes(self, fresh=False):
return [{"id": 3, "name": "讟壮1", "lessons": ["t", "k"], "teachers": [mail[TEACHER]],
"emails": list(mail.values()), "nicknames": {}, "exams": []}]
def access_for(self, _id, **kwargs):
return None
def user_accounts(self, emails):
return {email: {"id": uid, "name": ""} for uid, email in mail.items() if email in emails}
def _admin(self, path, method="GET", body=None, prefer=""):
from app.auth import AuthUnavailable
if path.startswith("/rest/v1/math_progress"):
return []
raise AuthUnavailable("supabase answered 404: no other tables here")
def session(browser, uid):
ctx = browser.new_context(viewport={"width": 390, "height": 844}, is_mobile=True, has_touch=True)
ctx.route("https://cdn.jsdelivr.net/**", lambda route: route.abort())
ctx.add_init_script('''window.supabase={createClient:()=>({auth:{
getSession:async()=>({data:{session:{access_token:"%s",user:{id:"%s"}}}}),
onAuthStateChange:()=>({data:{subscription:{unsubscribe(){}}}}),signOut:async()=>{}
}})};''' % (uid, uid))
page = ctx.new_page()
errors = []
page.on("pageerror", lambda e: errors.append(str(e)))
return page, errors
@pytest.fixture
def school():
app = create_app(auth=SchoolAuth())
app.state.assignments, app.state.worksheets, app.state.answers = MemoryAssignments(), MemoryWorksheets(), NoAnswers()
with socket.socket() as sock:
sock.bind(("127.0.0.1", 0))
server = uvicorn().Server(uvicorn().Config(app, log_level="error"))
thread = threading.Thread(target=server.run, kwargs={"sockets": [sock]}, daemon=True)
thread.start()
try:
while not server.started:
time.sleep(.01)
yield f"http://127.0.0.1:{sock.getsockname()[1]}", app
finally:
server.should_exit = True
thread.join(timeout=5)
def test_the_teacher_gives_focus_practice_to_one_student(school):
url, app = school
with playwright.sync_playwright() as p:
browser = p.chromium.launch()
try:
teacher, t_errors = session(browser, TEACHER)
teacher.goto(url)
teacher.locator('[data-act="class-report"]').click()
sheet = teacher.locator(".mx-report-sheet")
sheet.locator("[data-report-tab=tasks]").click()
sheet.locator("[data-asg-focus-new]").click()
form = sheet.locator("[data-focus-form]")
form.locator("button[type=submit]").click()
playwright.expect(form.locator(".mx-row [role=status]")).to_have_text("讘讞专讜 诇驻讞讜转 转诇诪讬讚 讗讞讚.")
form.locator('[name=student][value="dana@test.invalid"]').check()
form.locator("details", has_text="讟讻谞讬拽讛 讗诇讙讘专讬转 1").locator("summary").click()
form.locator('[name=skill][value="t_ext"]').check()
form.locator("[name=title]").fill("讞讬讝讜拽 驻讬诇讜讙")
form.locator("[name=due_on]").fill("2099-01-01")
form.locator("button[type=submit]").click()
card = sheet.locator(".mx-asg-t")
playwright.expect(card).to_contain_text("讗讬砖讬")
playwright.expect(card).to_contain_text("转专讙讜诇 诪诪讜拽讚 诇: dana")
playwright.expect(card.locator(".mx-asg-count")).to_contain_text("0 诪转讜讱 1 转诇诪讬讚讬诐 住讬讬诪讜") # only Dana counts
(row,) = app.state.assignments.rows.values()
assert row["student_emails"] == ["dana@test.invalid"] and row["items"] == [{"kind": "skill", "id": "t_ext"}]
dana, d_errors = session(browser, DANA)
dana.goto(url)
dana.locator('.mx-nav [data-view="home"]').click()
asg = dana.locator(".mx-asgs .mx-asg")
playwright.expect(asg).to_contain_text("讞讬讝讜拽 驻讬诇讜讙")
playwright.expect(asg.locator(".mx-asg-personal")).to_have_text("馃幆 讗讬砖讬")
yossi, y_errors = session(browser, YOSSI)
with yossi.expect_response(lambda r: "/api/math/assignments" in r.url) as got:
yossi.goto(url)
assert got.value.json()["assignments"] == []
yossi.locator('.mx-nav [data-view="home"]').click()
playwright.expect(yossi.locator(".mx-continue")).to_be_visible()
playwright.expect(yossi.locator(".mx-asgs")).to_have_count(0) # not given to Yossi
assert not (t_errors or d_errors or y_errors), (t_errors, d_errors, y_errors)
finally:
browser.close()