# -*- coding: utf-8 -*- """The LinkedIn OAuth callback endpoint's guidance when opened by a person. Real incident: the Agent -> MCP page tells the operator to copy the callback URL so it can be registered in the LinkedIn Developer Portal. Someone copied it and opened it in a browser tab instead, landing on this endpoint with no query string at all, and got "Missing code or state." — accurate, and useless to the person reading it. Only LinkedIn is supposed to call this URL, carrying ?code=...&state=... after a real login. A bare visit is therefore a strong signal that somebody misunderstood the copy step, and the response is the only place left to tell them so. """ from fastapi import FastAPI from fastapi.testclient import TestClient from adclaw.app.routers import mcp as mcp_router def _client() -> TestClient: app = FastAPI() app.include_router(mcp_router.router, prefix="/api") return TestClient(app) def test_opening_the_callback_directly_explains_what_it_is_for(): response = _client().get("/api/mcp/linkedin/oauth/callback") assert response.status_code == 400 body = response.text # Names what the URL is actually for, rather than the raw symptom. assert "not meant to be opened directly" in body assert "Authorized redirect URLs" in body assert "Authenticate" in body def test_the_old_bare_symptom_message_is_gone(): """"Missing code or state" told the operator nothing they could act on. If it ever comes back, this endpoint has lost the only guidance a misdirected person gets.""" body = _client().get("/api/mcp/linkedin/oauth/callback").text assert "Missing code or state" not in body def test_a_real_linkedin_error_is_still_shown_verbatim(): """LinkedIn's own refusal (user denied, app misconfigured) must not be replaced by the copy-step guidance — that is a different failure and the operator needs LinkedIn's own words.""" response = _client().get( "/api/mcp/linkedin/oauth/callback", params={ "error": "user_cancelled_login", "error_description": "The user cancelled the login.", }, ) assert response.status_code == 400 assert "The user cancelled the login." in response.text assert "not meant to be opened directly" not in response.text def test_a_code_without_state_is_not_treated_as_a_stray_visit(): """Half a callback is a real OAuth problem, not someone pasting a URL, but it lands in the same branch — the guidance is still the most useful thing to say, so this only pins that it does not crash.""" response = _client().get( "/api/mcp/linkedin/oauth/callback", params={"code": "abc123"}, ) assert response.status_code == 400