@@ -1079,3 +1079,104 @@ def test_cancel_upload_swallows_exceptions(
10791079
10801080 assert upload_cancelled_route .called
10811081 assert "HTTPStatusError" not in result .output
1082+
1083+
1084+ @pytest .mark .respx (base_url = settings .base_api_url )
1085+ def test_deploy_successfully_with_token (
1086+ logged_out_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
1087+ ) -> None :
1088+ app_data = _get_random_app ()
1089+ team_data = _get_random_team ()
1090+ app_id = app_data ["id" ]
1091+ team_id = team_data ["id" ]
1092+ deployment_data = _get_random_deployment (app_id = app_id )
1093+
1094+ config_path = tmp_path / ".fastapicloud" / "cloud.json"
1095+
1096+ config_path .parent .mkdir (parents = True , exist_ok = True )
1097+ config_path .write_text (f'{{"app_id": "{ app_id } ", "team_id": "{ team_id } "}}' )
1098+
1099+ respx_mock .get (f"/apps/{ app_id } " , headers = {"Authorization" : "Bearer hello" }).mock (
1100+ return_value = Response (200 , json = app_data )
1101+ )
1102+
1103+ respx_mock .post (
1104+ f"/apps/{ app_id } /deployments/" , headers = {"Authorization" : "Bearer hello" }
1105+ ).mock (return_value = Response (201 , json = deployment_data ))
1106+
1107+ respx_mock .post (
1108+ f"/deployments/{ deployment_data ['id' ]} /upload" ,
1109+ headers = {"Authorization" : "Bearer hello" },
1110+ ).mock (
1111+ return_value = Response (
1112+ 200 ,
1113+ json = {"url" : "http://test.com" , "fields" : {"key" : "value" }},
1114+ )
1115+ )
1116+
1117+ respx_mock .post ("http://test.com" , data = {"key" : "value" }).mock (
1118+ return_value = Response (200 )
1119+ )
1120+
1121+ respx_mock .get (
1122+ f"/deployments/{ deployment_data ['id' ]} /build-logs" ,
1123+ headers = {"Authorization" : "Bearer hello" },
1124+ ).mock (
1125+ return_value = Response (
1126+ 200 ,
1127+ content = build_logs_response (
1128+ {"type" : "message" , "message" : "Building..." , "id" : "1" },
1129+ {"type" : "message" , "message" : "All good!" , "id" : "2" },
1130+ {"type" : "complete" },
1131+ ),
1132+ )
1133+ )
1134+
1135+ respx_mock .post (
1136+ f"/deployments/{ deployment_data ['id' ]} /upload-complete" ,
1137+ headers = {"Authorization" : "Bearer hello" },
1138+ ).mock (return_value = Response (200 ))
1139+
1140+ with changing_dir (tmp_path ):
1141+ result = runner .invoke (app , ["deploy" ], env = {"FASTAPI_CLOUD_TOKEN" : "hello" })
1142+
1143+ assert result .exit_code == 0
1144+
1145+ # check that logs are shown
1146+ assert "All good!" in result .output
1147+
1148+ # check that the dashboard URL is shown
1149+ assert "You can also check the app logs at" in result .output
1150+ assert deployment_data ["dashboard_url" ] in result .output
1151+
1152+ # check that the app URL is shown
1153+ assert deployment_data ["url" ] in result .output
1154+
1155+
1156+ @pytest .mark .respx (base_url = settings .base_api_url )
1157+ def test_deploy_with_token_fails (
1158+ logged_out_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
1159+ ) -> None :
1160+ app_data = _get_random_app ()
1161+ team_data = _get_random_team ()
1162+ app_id = app_data ["id" ]
1163+ team_id = team_data ["id" ]
1164+
1165+ config_path = tmp_path / ".fastapicloud" / "cloud.json"
1166+
1167+ config_path .parent .mkdir (parents = True , exist_ok = True )
1168+ config_path .write_text (f'{{"app_id": "{ app_id } ", "team_id": "{ team_id } "}}' )
1169+
1170+ respx_mock .get (f"/apps/{ app_id } " , headers = {"Authorization" : "Bearer hello" }).mock (
1171+ return_value = Response (401 , json = app_data )
1172+ )
1173+
1174+ with changing_dir (tmp_path ):
1175+ result = runner .invoke (app , ["deploy" ], env = {"FASTAPI_CLOUD_TOKEN" : "hello" })
1176+
1177+ assert result .exit_code == 1
1178+
1179+ assert (
1180+ "The specified token is not valid. Make sure to use a valid token."
1181+ in result .output
1182+ )
0 commit comments