pdf-quiz-generator/backend/tests
Daniel b2a75b9e08
Some checks failed
Tests / backend (push) Failing after 5s
Tests / frontend (push) Failing after 37s
Tests / e2e (push) Failing after 38s
feat: signed in over there, signed in here
Opening one PedsHub app while already signed in at the provider for the
other one should not produce a sign-in page. It asks the provider once,
with prompt=none — "do you already know this person?" — and if the
answer is yes the round trip finishes with no screen and no click.

The refusal is the interesting half. login_required,
interaction_required, consent_required and account_selection_required
are the provider saying nobody is signed in, which is an answer rather
than a failure: the visitor lands on the page they asked for, with no
message and no sign of having been anywhere. Anything else still goes to
/login?error=sso_failed, and a silent attempt that throws is swallowed
too — nobody should be interrupted by a request they did not make.

The whole risk in this is a loop between two sites, so: at most one
attempt per browser session, never after somebody has signed themselves
out, and never inside a native shell where there is no third-party
cookie to carry the provider's session. Signing out sets a marker that
outlives the tab; pressing any sign-in control clears it, because that
is a person saying they have changed their mind.

A deep link survives the trip. The intended path rides in the server
session rather than the URL, and is validated on the way back — a
scheme, a host or a protocol-relative //evil all collapse to "/",
because a sign-in round trip is exactly where an open redirect would
live.

Verified against the live provider: /api/auth/sso/login?prompt=none
answers 302 to Authentik carrying prompt=none, state and nonce, and a
visitor with no session anywhere lands on the landing page with the
attempt marked spent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
2026-09-13 17:09:46 +02:00
..
__init__.py Initial commit: PDF Quiz Generator app 2026-03-30 20:04:53 +00:00
api-contract.json feat: cards come from articles, and Nextcloud is gone 2026-09-13 16:03:04 +02:00
test_access.py fix: a role is not set here while the provider holds it 2026-09-13 14:04:16 +02:00
test_ai_mode.py feat: AI Mode gives the same answer twice, and a typo no longer empties the library 2026-09-13 16:24:48 +02:00
test_ai_mode_matching.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_ai_practice.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_api_contract.py feat: a versioned API, refresh tokens, and an end-to-end stack that found four bugs 2026-09-13 01:23:38 +02:00
test_article_ai.py feat: half the bedside, half the mechanism 2026-09-13 16:05:57 +02:00
test_article_notes.py feat: question folders, per-section notes, and two feedback paths 2026-09-12 18:37:43 +02:00
test_article_search_index.py feat: three answers, chosen by a number rather than by the model 2026-09-12 16:15:05 +02:00
test_articles_cards.py feat: an article follows a topic, rather than copying it once 2026-09-12 19:57:06 +02:00
test_articles_migration.py feat: linked topic articles and card associations 2026-09-07 15:16:48 +02:00
test_bank_cleanup.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_blueprint_plans.py feat: study plans built to the board's content outline 2026-09-11 21:40:17 +02:00
test_captcha.py feat: Cap replaces hCaptcha, self-hosted beside the app 2026-09-12 06:14:14 +02:00
test_category_grants.py fix: the answer side of a question needs an attempt, or the job of writing it 2026-09-13 00:13:43 +02:00
test_category_migration.py feat: retire the tags, and stop settings from hiding from the page that 2026-09-12 05:06:58 +02:00
test_collections.py refactor: remove per-question sharing 2026-09-12 08:42:51 +02:00
test_contact_privacy.py fix: the contact form's messages were readable by anyone 2026-09-12 22:37:28 +02:00
test_draft_questions.py fix: the other registration form, our own transcriber first, and a rail 2026-09-12 04:41:27 +02:00
test_exam_admin.py feat: exams are a group you can build, with the board's own blueprint 2026-09-11 20:27:48 +02:00
test_exam_blueprint.py feat: adaptive weighs the paper as well as the learner, and Session 2026-09-12 05:54:09 +02:00
test_exam_scoped_tags.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_exams.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_feedback.py feat: question folders, per-section notes, and two feedback paths 2026-09-12 18:37:43 +02:00
test_file_intake.py fix: an upload is what its bytes say, not what its name claims 2026-09-12 19:05:12 +02:00
test_global_search.py refactor: remove per-question sharing 2026-09-12 08:42:51 +02:00
test_hybrid_search.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_media_library.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_multi_category.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_option_explanations.py feat: key points smart links, difficulty tags, adaptive sessions, educator-only question management 2026-09-09 02:26:45 +02:00
test_prepared_session.py feat: a session prepared for you, and a model that can see when the one on the job cannot 2026-09-12 15:46:04 +02:00
test_question_detail_access.py fix: the figures route handed out the answer side to anybody signed in 2026-09-13 15:29:29 +02:00
test_question_figures.py fix: a schema promising an owner where the column now says NULL 2026-09-13 14:17:55 +02:00
test_question_folders.py feat: question folders, per-section notes, and two feedback paths 2026-09-12 18:37:43 +02:00
test_question_trash.py feat: questions are soft-deleted, and the trash holds them 2026-09-11 20:12:58 +02:00
test_question_versions.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_quiz_builder.py refactor: the app is a PWA, so the native wrapper goes 2026-09-13 00:26:35 +02:00
test_quiz_sessions.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_refresh_tokens.py feat: a versioned API, refresh tokens, and an end-to-end stack that found four bugs 2026-09-13 01:23:38 +02:00
test_related_privacy.py feat: the bank belongs to a role, not to a person 2026-09-13 13:26:25 +02:00
test_rerank.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_session_lifecycle.py refactor: remove per-question sharing 2026-09-12 08:42:51 +02:00
test_share_public.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_shared_category.py feat: ground AI drafts in the library and PubMed, and mend the card system 2026-09-13 02:44:42 +02:00
test_sso_hardening.py feat: signed in over there, signed in here 2026-09-13 17:09:46 +02:00
test_sso_roles.py fix: a role is not set here while the provider holds it 2026-09-13 14:04:16 +02:00
test_study_plan_editing.py feat: study plans you can open, work through, and edit 2026-09-10 12:10:39 +02:00
test_study_plan_sessions.py feat: study-plan blocks as modules, sessions that know their block 2026-09-11 04:31:21 +02:00
test_study_tools.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_study_tools_migration.py fix: preserve saved quiz progress across resume failures 2026-09-07 03:34:55 +02:00
test_tag_hierarchy.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
test_thumbnails.py feat: thumbnails for uploaded images, at two widths and no others 2026-09-12 08:49:20 +02:00
test_tts_voices.py fix: a speech model is added with its voices, and Orpheus is sent where it works 2026-09-13 05:04:37 +02:00
test_vision_fallback.py fix: the answer side of a question needs an attempt, or the job of writing it 2026-09-13 00:13:43 +02:00