@@ -1115,3 +1115,104 @@ def test_cancel_upload_swallows_exceptions(
11151115
11161116 assert upload_cancelled_route .called
11171117 assert "HTTPStatusError" not in result .output
1118+
1119+
1120+ @pytest .mark .respx (base_url = settings .base_api_url )
1121+ def test_deploy_successfully_with_token (
1122+ logged_out_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
1123+ ) -> None :
1124+ app_data = _get_random_app ()
1125+ team_data = _get_random_team ()
1126+ app_id = app_data ["id" ]
1127+ team_id = team_data ["id" ]
1128+ deployment_data = _get_random_deployment (app_id = app_id )
1129+
1130+ config_path = tmp_path / ".fastapicloud" / "cloud.json"
1131+
1132+ config_path .parent .mkdir (parents = True , exist_ok = True )
1133+ config_path .write_text (f'{{"app_id": "{ app_id } ", "team_id": "{ team_id } "}}' )
1134+
1135+ respx_mock .get (f"/apps/{ app_id } " , headers = {"Authorization" : "Bearer hello" }).mock (
1136+ return_value = Response (200 , json = app_data )
1137+ )
1138+
1139+ respx_mock .post (
1140+ f"/apps/{ app_id } /deployments/" , headers = {"Authorization" : "Bearer hello" }
1141+ ).mock (return_value = Response (201 , json = deployment_data ))
1142+
1143+ respx_mock .post (
1144+ f"/deployments/{ deployment_data ['id' ]} /upload" ,
1145+ headers = {"Authorization" : "Bearer hello" },
1146+ ).mock (
1147+ return_value = Response (
1148+ 200 ,
1149+ json = {"url" : "http://test.com" , "fields" : {"key" : "value" }},
1150+ )
1151+ )
1152+
1153+ respx_mock .post ("http://test.com" , data = {"key" : "value" }).mock (
1154+ return_value = Response (200 )
1155+ )
1156+
1157+ respx_mock .get (
1158+ f"/deployments/{ deployment_data ['id' ]} /build-logs" ,
1159+ headers = {"Authorization" : "Bearer hello" },
1160+ ).mock (
1161+ return_value = Response (
1162+ 200 ,
1163+ content = build_logs_response (
1164+ {"type" : "message" , "message" : "Building..." , "id" : "1" },
1165+ {"type" : "message" , "message" : "All good!" , "id" : "2" },
1166+ {"type" : "complete" },
1167+ ),
1168+ )
1169+ )
1170+
1171+ respx_mock .post (
1172+ f"/deployments/{ deployment_data ['id' ]} /upload-complete" ,
1173+ headers = {"Authorization" : "Bearer hello" },
1174+ ).mock (return_value = Response (200 ))
1175+
1176+ with changing_dir (tmp_path ):
1177+ result = runner .invoke (app , ["deploy" ], env = {"FASTAPI_CLOUD_TOKEN" : "hello" })
1178+
1179+ assert result .exit_code == 0
1180+
1181+ # check that logs are shown
1182+ assert "All good!" in result .output
1183+
1184+ # check that the dashboard URL is shown
1185+ assert "You can also check the app logs at" in result .output
1186+ assert deployment_data ["dashboard_url" ] in result .output
1187+
1188+ # check that the app URL is shown
1189+ assert deployment_data ["url" ] in result .output
1190+
1191+
1192+ @pytest .mark .respx (base_url = settings .base_api_url )
1193+ def test_deploy_with_token_fails (
1194+ logged_out_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
1195+ ) -> None :
1196+ app_data = _get_random_app ()
1197+ team_data = _get_random_team ()
1198+ app_id = app_data ["id" ]
1199+ team_id = team_data ["id" ]
1200+
1201+ config_path = tmp_path / ".fastapicloud" / "cloud.json"
1202+
1203+ config_path .parent .mkdir (parents = True , exist_ok = True )
1204+ config_path .write_text (f'{{"app_id": "{ app_id } ", "team_id": "{ team_id } "}}' )
1205+
1206+ respx_mock .get (f"/apps/{ app_id } " , headers = {"Authorization" : "Bearer hello" }).mock (
1207+ return_value = Response (401 , json = app_data )
1208+ )
1209+
1210+ with changing_dir (tmp_path ):
1211+ result = runner .invoke (app , ["deploy" ], env = {"FASTAPI_CLOUD_TOKEN" : "hello" })
1212+
1213+ assert result .exit_code == 1
1214+
1215+ assert (
1216+ "The specified token is not valid. Make sure to use a valid token."
1217+ in result .output
1218+ )
0 commit comments