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

1from typing import Any 1abcdefg

2 

3import pytest 1abcdefg

4 

5from fastapi_cloud_cli.api import CustomDomain, CustomDomainStatus 1abcdefg

6from fastapi_cloud_cli.commands.domains._setup import get_setup_steps 1abcdefg

7 

8APP_ID = "00000000-0000-4000-8000-000000000002" 1abcdefg

9DOMAIN_ID = "00000000-0000-4000-8000-000000000003" 1abcdefg

10 

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] 

27 

28 

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 ) 

48 

49 

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 ) 

122 

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 ] 

129 

130 

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

187 

188 assert step.id == "combined" 1ikmoqsu

189 assert step.status == expected_status 1ikmoqsu

190 assert step.description == expected_description 1ikmoqsu