// Tests for AuthInterceptor::wantsJson + urlEncode (the negotiation primitives // that decide whether a 401/403 returns JSON vs HTML/redirect). // // Kept dependency-free on purpose — the harness exists so future tests have // somewhere to land, not to pull in doctest/Catch2. #include "oatpp-authkit/auth/AuthInterceptor.hpp" #include #include #include namespace { int g_failures = 0; #define REQUIRE(expr) do { \ if (!(expr)) { \ std::fprintf(stderr, "FAIL %s:%d %s\n", __FILE__, __LINE__, #expr); \ ++g_failures; \ } \ } while (0) using oatpp_authkit::AuthInterceptor; void test_wantsJson_api_path() { // /api/* always wants JSON, no matter what Accept says. REQUIRE( AuthInterceptor::wantsJson("/api/users", "", "text/html")); REQUIRE( AuthInterceptor::wantsJson("/api/", "", "")); } void test_wantsJson_xrequested_with() { // Explicit AJAX wins regardless of path/Accept. REQUIRE( AuthInterceptor::wantsJson("/admin", "XMLHttpRequest", "text/html")); } void test_wantsJson_accept_header() { // application/json without text/html → JSON. REQUIRE( AuthInterceptor::wantsJson("/admin", "", "application/json")); // text/html present → browser navigation. REQUIRE(!AuthInterceptor::wantsJson("/admin", "", "text/html,application/xhtml+xml")); REQUIRE(!AuthInterceptor::wantsJson("/admin", "", "text/html,application/json")); // No Accept → assume browser (HTML/redirect). REQUIRE(!AuthInterceptor::wantsJson("/set-password", "", "")); } void test_wantsJson_set_password_browser() { // The motivating regression: a browser following the password-reset link // must NOT be served JSON. (Path is public so it shouldn't reach this in // normal flow, but if auth ever rejects it the user sees HTML/redirect.) REQUIRE(!AuthInterceptor::wantsJson("/set-password", "", "text/html,application/xhtml+xml,application/xml;q=0.9")); } void test_urlEncode() { REQUIRE(AuthInterceptor::urlEncode("/admin") == "%2Fadmin"); REQUIRE(AuthInterceptor::urlEncode("/set-password?t=1")== "%2Fset-password%3Ft%3D1"); REQUIRE(AuthInterceptor::urlEncode("abc-_.~123") == "abc-_.~123"); REQUIRE(AuthInterceptor::urlEncode(" ") == "%20"); } } // namespace int main() { test_wantsJson_api_path(); test_wantsJson_xrequested_with(); test_wantsJson_accept_header(); test_wantsJson_set_password_browser(); test_urlEncode(); if (g_failures) { std::fprintf(stderr, "%d test(s) failed\n", g_failures); return 1; } std::puts("ok"); return 0; }