Coverage for tests/domains/test_setup.py: 100%
22 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-11-09 00:25 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-11-09 00:25 +0000
1from typing import Any 1abcdefg
3import pytest 1abcdefg
5from fastapi_cloud_cli.api import CustomDomain, CustomDomainStatus 1abcdefg
6from fastapi_cloud_cli.commands.domains._setup import get_setup_steps 1abcdefg
8APP_ID = "00000000-0000-4000-8000-000000000002" 1abcdefg
9DOMAIN_ID = "00000000-0000-4000-8000-000000000003" 1abcdefg
11STANDARD_CNAME_RECORD = { 1abcdefg
12 "type": "CNAME",
13 "name": "www",
14 "value": f"{DOMAIN_ID}.endpoints.fastapicloud.dev.",
15}
16PRE_VALIDATION_RECORDS = [ 1abcdefg
17 {"type": "TXT", "name": "_fc-dcv.www", "value": "ownership-value"},
18 {"type": "TXT", "name": None, "value": None},
19 {
20 "type": "CNAME",
21 "name": "_acme-challenge.www",
22 "value": "certificate-value",
23 },
24 {"type": "A", "name": "@", "value": "192.0.2.10"},
25 {"type": "CNAME", "name": "www", "value": "traffic-value"},
26]
29def _custom_domain(**overrides: Any) -> CustomDomain: 1abcdefg
30 return CustomDomain.model_validate( 1hijklmnopqrstu
31 {
32 "id": DOMAIN_ID,
33 "name": "www.example.com",
34 "status": CustomDomainStatus.internal_dcv_pending,
35 "setup_in_progress": True,
36 "setup_failed": False,
37 "setup_successful": False,
38 "is_using_pre_validation": False,
39 "dns_records": [STANDARD_CNAME_RECORD],
40 "created_at": "2026-08-28T10:00:00Z",
41 "updated_at": "2026-08-28T10:01:00Z",
42 "setup_started_at": "2026-08-28T10:00:00Z",
43 "setup_checked_at": "2026-08-28T10:01:00Z",
44 "app_id": APP_ID,
45 **overrides,
46 }
47 )
50@pytest.mark.parametrize( 1abcdefg
51 ("statuses", "expected_statuses"),
52 [
53 (
54 (
55 CustomDomainStatus.internal_dcv_pending,
56 CustomDomainStatus.internal_dcv_missing,
57 ),
58 ("in_progress", "locked", "locked"),
59 ),
60 (
61 (CustomDomainStatus.internal_dcv_invalid,),
62 ("attention", "locked", "locked"),
63 ),
64 (
65 (
66 CustomDomainStatus.internal_dcv_timeout,
67 CustomDomainStatus.internal_dcv_revoked,
68 ),
69 ("failed", "locked", "locked"),
70 ),
71 (
72 (
73 CustomDomainStatus.external_dcv_pending,
74 CustomDomainStatus.external_dcv_proxied,
75 CustomDomainStatus.external_dcv_secured,
76 ),
77 ("verified", "in_progress", "locked"),
78 ),
79 (
80 (
81 CustomDomainStatus.external_dcv_blocked,
82 CustomDomainStatus.external_dcv_timeout,
83 ),
84 ("verified", "failed", "locked"),
85 ),
86 (
87 (
88 CustomDomainStatus.origin_setup_pending,
89 CustomDomainStatus.origin_setup_missing,
90 ),
91 ("verified", "verified", "in_progress"),
92 ),
93 (
94 (CustomDomainStatus.origin_setup_invalid,),
95 ("verified", "verified", "attention"),
96 ),
97 (
98 (
99 CustomDomainStatus.origin_setup_timeout,
100 CustomDomainStatus.origin_setup_removed,
101 ),
102 ("verified", "verified", "failed"),
103 ),
104 (
105 (CustomDomainStatus.origin_setup_success,),
106 ("verified", "verified", "verified"),
107 ),
108 ],
109)
110def test_pre_validation_setup_steps_follow_domain_phase( 1abcdefg
111 statuses: tuple[CustomDomainStatus, ...],
112 expected_statuses: tuple[str, str, str],
113) -> None:
114 for status in statuses: 1hjlnprt
115 steps = get_setup_steps( 1hjlnprt
116 _custom_domain(
117 status=status,
118 is_using_pre_validation=True,
119 dns_records=PRE_VALIDATION_RECORDS,
120 )
121 )
123 assert tuple(step.status for step in steps) == expected_statuses 1hjlnprt
124 assert [[record.name for record in step.records] for step in steps] == [ 1hjlnprt
125 ["_fc-dcv.www"],
126 [None, "_acme-challenge.www"],
127 ["@", "www"],
128 ]
131@pytest.mark.parametrize( 1abcdefg
132 ("overrides", "expected_status", "expected_description"),
133 [
134 (
135 {},
136 "in_progress",
137 (
138 "Add the record below. We'll verify ownership, issue your TLS "
139 "certificate, and route traffic automatically."
140 ),
141 ),
142 (
143 {"dns_records": [{"type": "A", "name": "@", "value": "192.0.2.10"}]},
144 "in_progress",
145 (
146 "Add the records below. We'll verify ownership, issue your TLS "
147 "certificate, and route traffic automatically."
148 ),
149 ),
150 (
151 {"status": CustomDomainStatus.internal_dcv_invalid},
152 "attention",
153 (
154 "We found your records, but some values don't match. Update them to "
155 "the values below. We re-check automatically."
156 ),
157 ),
158 (
159 {
160 "status": CustomDomainStatus.internal_dcv_timeout,
161 "setup_in_progress": False,
162 "setup_failed": True,
163 },
164 "failed",
165 (
166 "We couldn't complete setup. Re-check the records below, then restart "
167 "verification."
168 ),
169 ),
170 (
171 {
172 "status": CustomDomainStatus.origin_setup_success,
173 "setup_in_progress": False,
174 "setup_successful": True,
175 },
176 "verified",
177 "Your domain is live on FastAPI Cloud.",
178 ),
179 ],
180)
181def test_standard_setup_step_reflects_domain_state( 1abcdefg
182 overrides: dict[str, Any],
183 expected_status: str,
184 expected_description: str,
185) -> None:
186 [step] = get_setup_steps(_custom_domain(**overrides)) 1ikmoqsu
188 assert step.id == "combined" 1ikmoqsu
189 assert step.status == expected_status 1ikmoqsu
190 assert step.description == expected_description 1ikmoqsu