|
20 | 20 | from fastapi import FastAPI |
21 | 21 | from fastapi.requests import Request |
22 | 22 | from fastapi.testclient import TestClient |
23 | | -from pytest import fixture, mark |
| 23 | +from pytest import fixture, mark, raises |
| 24 | +from urllib.parse import urlparse |
24 | 25 |
|
25 | 26 | from supertokens_python import InputAppInfo, SupertokensConfig, init |
| 27 | +from supertokens_python.exceptions import GeneralError |
26 | 28 | from supertokens_python.framework.fastapi import get_middleware |
27 | 29 | from supertokens_python.ingredients.emaildelivery import EmailDeliveryInterface |
28 | 30 | from supertokens_python.ingredients.emaildelivery.types import ( |
|
37 | 39 | session, |
38 | 40 | thirdpartyemailpassword, |
39 | 41 | ) |
| 42 | +from supertokens_python.recipe.thirdpartyemailpassword.asyncio import ( |
| 43 | + create_reset_password_link, |
| 44 | + send_reset_password_email, |
| 45 | +) |
| 46 | +from supertokens_python.recipe.thirdpartyemailpassword.interfaces import ( |
| 47 | + CreateResetPasswordLinkUnknownUserIdError, |
| 48 | + SendResetPasswordEmailEmailOkResult, |
| 49 | + SendResetPasswordEmailUnknownUserIdError, |
| 50 | +) |
40 | 51 | from supertokens_python.recipe.emailverification.emaildelivery.services import ( |
41 | 52 | SMTPService as EVSMTPService, |
42 | 53 | ) |
@@ -1036,3 +1047,139 @@ async def send_email( |
1036 | 1047 |
|
1037 | 1048 | assert email == "[email protected]" |
1038 | 1049 | assert email_verify_url != "" |
| 1050 | + |
| 1051 | + |
| 1052 | +@mark.asyncio |
| 1053 | +async def test_create_reset_password_link( |
| 1054 | + driver_config_client: TestClient, |
| 1055 | +): |
| 1056 | + init( |
| 1057 | + supertokens_config=SupertokensConfig("http://localhost:3567"), |
| 1058 | + app_info=InputAppInfo( |
| 1059 | + app_name="SuperTokens Demo", |
| 1060 | + api_domain="http://api.supertokens.io", |
| 1061 | + website_domain="http://supertokens.io", |
| 1062 | + api_base_path="/auth", |
| 1063 | + ), |
| 1064 | + framework="fastapi", |
| 1065 | + recipe_list=[ |
| 1066 | + thirdpartyemailpassword.init(), |
| 1067 | + session.init(get_token_transfer_method=lambda _, __, ___: "cookie"), |
| 1068 | + ], |
| 1069 | + ) |
| 1070 | + start_st() |
| 1071 | + |
| 1072 | + response_1 = sign_up_request( |
| 1073 | + driver_config_client, "[email protected]", "validpass123" |
| 1074 | + ) |
| 1075 | + assert response_1.status_code == 200 |
| 1076 | + dict_response = json.loads(response_1.text) |
| 1077 | + user_info = dict_response["user"] |
| 1078 | + assert dict_response["status"] == "OK" |
| 1079 | + link = await create_reset_password_link("public", user_info["id"]) |
| 1080 | + url = urlparse(link.link) # type: ignore |
| 1081 | + queries = url.query.strip("&").split("&") |
| 1082 | + assert url.path == "/auth/reset-password" |
| 1083 | + assert "tenantId=public" in queries |
| 1084 | + assert "rid=thirdpartyemailpassword" in queries |
| 1085 | + |
| 1086 | + link = await create_reset_password_link("public", "invalidUserId") |
| 1087 | + assert isinstance(link, CreateResetPasswordLinkUnknownUserIdError) |
| 1088 | + |
| 1089 | + with raises(GeneralError) as err: |
| 1090 | + await create_reset_password_link("invalidTenantId", user_info["id"]) |
| 1091 | + assert "status code: 400" in str(err.value) |
| 1092 | + |
| 1093 | + |
| 1094 | +@mark.asyncio |
| 1095 | +async def test_send_reset_password_email( |
| 1096 | + driver_config_client: TestClient, |
| 1097 | +): |
| 1098 | + |
| 1099 | + tenant_info, token_info, rid_info, reset_url = "", "", "", "" |
| 1100 | + |
| 1101 | + class CustomEmailDeliveryService( |
| 1102 | + thirdpartyemailpassword.EmailDeliveryInterface[PasswordResetEmailTemplateVars] |
| 1103 | + ): |
| 1104 | + async def send_email( |
| 1105 | + self, |
| 1106 | + template_vars: PasswordResetEmailTemplateVars, |
| 1107 | + user_context: Dict[str, Any], |
| 1108 | + ): |
| 1109 | + nonlocal reset_url, token_info, rid_info, tenant_info |
| 1110 | + password_reset_url = template_vars.password_reset_link |
| 1111 | + reset_url = password_reset_url.split("?")[0] |
| 1112 | + token_info = password_reset_url.split("?")[1].split("&")[0] |
| 1113 | + rid_info = password_reset_url.split("?")[1].split("&")[1] |
| 1114 | + tenant_info = password_reset_url.split("?")[1].split("&")[2] |
| 1115 | + |
| 1116 | + init( |
| 1117 | + supertokens_config=SupertokensConfig("http://localhost:3567"), |
| 1118 | + app_info=InputAppInfo( |
| 1119 | + app_name="SuperTokens Demo", |
| 1120 | + api_domain="http://api.supertokens.io", |
| 1121 | + website_domain="http://supertokens.io", |
| 1122 | + api_base_path="/auth", |
| 1123 | + ), |
| 1124 | + framework="fastapi", |
| 1125 | + recipe_list=[ |
| 1126 | + thirdpartyemailpassword.init( |
| 1127 | + email_delivery=thirdpartyemailpassword.EmailDeliveryConfig( |
| 1128 | + CustomEmailDeliveryService() |
| 1129 | + ) |
| 1130 | + ), |
| 1131 | + session.init(get_token_transfer_method=lambda _, __, ___: "cookie"), |
| 1132 | + ], |
| 1133 | + ) |
| 1134 | + start_st() |
| 1135 | + |
| 1136 | + response_1 = sign_up_request( |
| 1137 | + driver_config_client, "[email protected]", "validpass123" |
| 1138 | + ) |
| 1139 | + assert response_1.status_code == 200 |
| 1140 | + dict_response = json.loads(response_1.text) |
| 1141 | + user_info = dict_response["user"] |
| 1142 | + assert dict_response["status"] == "OK" |
| 1143 | + resp = await send_reset_password_email("public", user_info["id"]) |
| 1144 | + assert isinstance(resp, SendResetPasswordEmailEmailOkResult) |
| 1145 | + |
| 1146 | + assert reset_url == "http://supertokens.io/auth/reset-password" |
| 1147 | + assert token_info is not None and "token=" in token_info |
| 1148 | + assert rid_info is not None and "rid=thirdpartyemailpassword" in rid_info |
| 1149 | + assert tenant_info is not None and "tenantId=public" in tenant_info |
| 1150 | + |
| 1151 | + |
| 1152 | +@mark.asyncio |
| 1153 | +async def test_send_reset_password_email_invalid_input( |
| 1154 | + driver_config_client: TestClient, |
| 1155 | +): |
| 1156 | + |
| 1157 | + init( |
| 1158 | + supertokens_config=SupertokensConfig("http://localhost:3567"), |
| 1159 | + app_info=InputAppInfo( |
| 1160 | + app_name="SuperTokens Demo", |
| 1161 | + api_domain="http://api.supertokens.io", |
| 1162 | + website_domain="http://supertokens.io", |
| 1163 | + api_base_path="/auth", |
| 1164 | + ), |
| 1165 | + framework="fastapi", |
| 1166 | + recipe_list=[ |
| 1167 | + thirdpartyemailpassword.init(), |
| 1168 | + session.init(get_token_transfer_method=lambda _, __, ___: "cookie"), |
| 1169 | + ], |
| 1170 | + ) |
| 1171 | + start_st() |
| 1172 | + |
| 1173 | + response_1 = sign_up_request( |
| 1174 | + driver_config_client, "[email protected]", "validpass123" |
| 1175 | + ) |
| 1176 | + assert response_1.status_code == 200 |
| 1177 | + dict_response = json.loads(response_1.text) |
| 1178 | + user_info = dict_response["user"] |
| 1179 | + |
| 1180 | + link = await send_reset_password_email("public", "invalidUserId") |
| 1181 | + assert isinstance(link, SendResetPasswordEmailUnknownUserIdError) |
| 1182 | + |
| 1183 | + with raises(GeneralError) as err: |
| 1184 | + await send_reset_password_email("invalidTenantId", user_info["id"]) |
| 1185 | + assert "status code: 400" in str(err.value) |
0 commit comments