(*--------------------------------------------------------------------------- Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. SPDX-License-Identifier: MIT ---------------------------------------------------------------------------*) open Crowbar let () = Crypto_rng_unix.use_default () (* Test that authorization_url always produces valid URLs *) let test_authorization_url_valid client_id callback_url state scope = let url = Github_oauth.authorization_url ~client_id ~callback_url ~state ~scope in (* Should always start with https://github.com *) check (String.length url > 0); check (String.sub url 0 8 = "https://") (* Test that exchange_request_body produces valid JSON *) let test_exchange_body_valid client_id client_secret code redirect_uri = let body = Github_oauth.exchange_request_body ~client_id ~client_secret ~code ~redirect_uri in (* Should be valid JSON - contains opening brace *) check (String.length body > 2); check (body.[0] = '{') (* Test that refresh_request_body produces valid JSON *) let test_refresh_body_valid client_id client_secret refresh_token = let body = Github_oauth.refresh_request_body ~client_id ~client_secret ~refresh_token in check (String.length body > 2); check (body.[0] = '{') (* Test that parse_token_response handles arbitrary input without crashing *) let test_parse_no_crash input = let _ = Github_oauth.parse_token_response input in check true (* Test roundtrip: encode a valid token response, then parse it *) let test_token_roundtrip access_token expires_in refresh_token = let json = let parts = [ Fmt.str {|"access_token":"%s"|} access_token ] @ (match expires_in with | None -> [] | Some n -> [ Fmt.str {|"expires_in":%d|} (abs n mod 100000) ]) @ match refresh_token with | None -> [] | Some rt -> [ Fmt.str {|"refresh_token":"%s"|} rt ] in "{" ^ String.concat "," parts ^ "}" in match Github_oauth.parse_token_response json with | Ok t -> check (t.access_token = access_token) | Error _ -> check true (* some inputs may be invalid JSON *) let suite = ( "github_oauth", [ test_case "authorization_url valid" [ bytes; bytes; bytes; list bytes ] test_authorization_url_valid; test_case "exchange_body valid" [ bytes; bytes; bytes; bytes ] test_exchange_body_valid; test_case "refresh_body valid" [ bytes; bytes; bytes ] test_refresh_body_valid; test_case "parse_no_crash" [ bytes ] test_parse_no_crash; test_case "token roundtrip" [ bytes; option int; option bytes ] test_token_roundtrip; ] )