@@ -424,3 +424,119 @@ async def fake_request(method: str, url: httpx.URL, **kwargs: object) -> httpx.R
424424
425425 assert exc_info .value .error == "UNAUTHORIZED"
426426 assert exc_info .value .message == "Invalid credentials"
427+
428+
429+ def test_email_verification_and_reset_password_json_endpoints_request_expected_payloads () -> None :
430+ async def scenario () -> tuple [list [dict [str , object ]], object , object , object , object , object ]:
431+ calls : list [dict [str , object ]] = []
432+
433+ async def fake_request (method : str , url : httpx .URL , ** kwargs : object ) -> httpx .Response :
434+ calls .append ({"method" : method , "url" : str (url ), "kwargs" : kwargs })
435+
436+ if str (url ).endswith ("/api/auth/email/send-verification" ):
437+ return httpx .Response (202 , json = {"success" : True , "message" : "Verification email sent" })
438+
439+ if str (url ).endswith ("/api/auth/email/verify" ):
440+ return httpx .Response (
441+ 200 ,
442+ json = {
443+ "user" : {
444+ "id" : "u1" ,
445+ "email" : "a@example.com" ,
446+ "profile" : {"name" : "Ada" },
447+ "emailVerified" : True ,
448+ },
449+ "accessToken" : "access" ,
450+ "refreshToken" : "refresh" ,
451+ },
452+ )
453+
454+ if str (url ).endswith ("/api/auth/email/send-reset-password" ):
455+ return httpx .Response (202 , json = {"success" : True , "message" : "Reset email sent" })
456+
457+ if str (url ).endswith ("/api/auth/email/exchange-reset-password-token" ):
458+ return httpx .Response (200 , json = {"token" : "reset-token" , "expiresAt" : "2026-03-28T12:34:56Z" })
459+
460+ return httpx .Response (200 , json = {"message" : "Password reset successfully" })
461+
462+ async with InsforgeClient (
463+ base_url = "https://example.com" ,
464+ api_key = "ins_test" ,
465+ ) as client :
466+ client .http_client .request = fake_request # type: ignore[method-assign]
467+ send_verification = await client .auth .send_email_verification (
468+ email = "a@example.com" ,
469+ redirect_to = "https://app.example.com/sign-in" ,
470+ )
471+ verify = await client .auth .verify_email (
472+ email = "a@example.com" ,
473+ otp = "123456" ,
474+ )
475+ send_reset = await client .auth .send_reset_password_email (
476+ email = "a@example.com" ,
477+ redirect_to = "https://app.example.com/reset-password" ,
478+ )
479+ exchange = await client .auth .exchange_reset_password_token (
480+ email = "a@example.com" ,
481+ code = "123456" ,
482+ )
483+ reset = await client .auth .reset_password (
484+ new_password = "new-password" ,
485+ otp = "reset-token" ,
486+ )
487+
488+ return calls , send_verification , verify , send_reset , exchange , reset
489+
490+ calls , send_verification , verify , send_reset , exchange , reset = asyncio .run (scenario ())
491+
492+ assert calls [0 ]["method" ] == "POST"
493+ assert calls [0 ]["url" ] == "https://example.com/api/auth/email/send-verification"
494+ assert calls [0 ]["kwargs" ]["json" ] == {
495+ "email" : "a@example.com" ,
496+ "redirectTo" : "https://app.example.com/sign-in" ,
497+ }
498+ assert calls [0 ]["kwargs" ]["headers" ]["X-API-Key" ] == "ins_test"
499+ assert "Authorization" not in calls [0 ]["kwargs" ]["headers" ]
500+
501+ assert calls [1 ]["method" ] == "POST"
502+ assert calls [1 ]["url" ] == "https://example.com/api/auth/email/verify"
503+ assert calls [1 ]["kwargs" ]["params" ] == {"client_type" : "server" }
504+ assert calls [1 ]["kwargs" ]["json" ] == {"email" : "a@example.com" , "otp" : "123456" }
505+ assert calls [1 ]["kwargs" ]["headers" ]["X-API-Key" ] == "ins_test"
506+ assert "Authorization" not in calls [1 ]["kwargs" ]["headers" ]
507+
508+ assert calls [2 ]["method" ] == "POST"
509+ assert calls [2 ]["url" ] == "https://example.com/api/auth/email/send-reset-password"
510+ assert calls [2 ]["kwargs" ]["json" ] == {
511+ "email" : "a@example.com" ,
512+ "redirectTo" : "https://app.example.com/reset-password" ,
513+ }
514+ assert calls [2 ]["kwargs" ]["headers" ]["X-API-Key" ] == "ins_test"
515+ assert "Authorization" not in calls [2 ]["kwargs" ]["headers" ]
516+
517+ assert calls [3 ]["method" ] == "POST"
518+ assert calls [3 ]["url" ] == "https://example.com/api/auth/email/exchange-reset-password-token"
519+ assert calls [3 ]["kwargs" ]["json" ] == {"email" : "a@example.com" , "code" : "123456" }
520+ assert calls [3 ]["kwargs" ]["headers" ]["X-API-Key" ] == "ins_test"
521+ assert "Authorization" not in calls [3 ]["kwargs" ]["headers" ]
522+
523+ assert calls [4 ]["method" ] == "POST"
524+ assert calls [4 ]["url" ] == "https://example.com/api/auth/email/reset-password"
525+ assert calls [4 ]["kwargs" ]["json" ] == {"newPassword" : "new-password" , "otp" : "reset-token" }
526+ assert calls [4 ]["kwargs" ]["headers" ]["X-API-Key" ] == "ins_test"
527+ assert "Authorization" not in calls [4 ]["kwargs" ]["headers" ]
528+
529+ assert send_verification .success is True
530+ assert send_verification .message == "Verification email sent"
531+
532+ assert verify .user .email == "a@example.com"
533+ assert verify .access_token == "access"
534+ assert verify .refresh_token == "refresh"
535+
536+ assert send_reset .success is True
537+ assert send_reset .message == "Reset email sent"
538+
539+ assert exchange .token == "reset-token"
540+ assert exchange .expires_at .isoformat () == "2026-03-28T12:34:56+00:00"
541+
542+ assert reset .message == "Password reset successfully"
0 commit comments