Coverage for tests\test_reconcile.py: 100%

192 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-12-20 00:45 +0000

1import json 

2 

3import httpx 

4import pytest 

5from datasette.app import Datasette 

6 

7from tests.conftest import plugin_metadata 

8 

9 

10@pytest.mark.asyncio 

11async def test_plugin_is_installed(): 

12 app = Datasette([], memory=True).app() 

13 async with httpx.AsyncClient(app=app) as client: 

14 response = await client.get("http://localhost/-/plugins.json") 

15 assert 200 == response.status_code 

16 installed_plugins = {p["name"] for p in response.json()} 

17 assert "datasette-reconcile" in installed_plugins 

18 

19 

20@pytest.mark.asyncio 

21async def test_response_not_configured(db_path): 

22 app = Datasette([db_path]).app() 

23 async with httpx.AsyncClient(app=app) as client: 

24 response = await client.get("http://localhost/test/dogs/-/reconcile") 

25 assert 404 == response.status_code 

26 

27 

28@pytest.mark.asyncio 

29async def test_response_without_query(db_path): 

30 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

31 async with httpx.AsyncClient(app=app) as client: 

32 response = await client.get("http://localhost/test/dogs/-/reconcile") 

33 assert 200 == response.status_code 

34 data = response.json() 

35 assert "name" in data.keys() 

36 assert isinstance(data["defaultTypes"], list) 

37 assert len(data["defaultTypes"]) == 1 

38 assert data["defaultTypes"][0]["id"] == "object" 

39 assert data["defaultTypes"][0]["name"] == "Object" 

40 assert data["view"]["url"].startswith("http") 

41 assert response.headers["Access-Control-Allow-Origin"] == "*" 

42 

43 

44@pytest.mark.asyncio 

45async def test_servce_manifest_view_url_default(db_path): 

46 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

47 async with httpx.AsyncClient(app=app) as client: 

48 response = await client.get("http://localhost/test/dogs/-/reconcile") 

49 assert 200 == response.status_code 

50 data = response.json() 

51 assert data["view"]["url"] == "http://localhost/test/dogs/{{id}}" 

52 

53 

54@pytest.mark.asyncio 

55async def test_servce_manifest_https(db_path): 

56 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

57 async with httpx.AsyncClient(app=app) as client: 

58 response = await client.get("https://localhost/test/dogs/-/reconcile") 

59 assert 200 == response.status_code 

60 data = response.json() 

61 assert data["view"]["url"] == "https://localhost/test/dogs/{{id}}" 

62 

63 

64@pytest.mark.asyncio 

65async def test_servce_manifest_x_forwarded_proto_https(db_path): 

66 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

67 async with httpx.AsyncClient(app=app) as client: 

68 response = await client.get("http://localhost/test/dogs/-/reconcile", headers={"x-forwarded-proto": "https"}) 

69 assert 200 == response.status_code 

70 data = response.json() 

71 assert data["view"]["url"] == "https://localhost/test/dogs/{{id}}" 

72 

73 

74@pytest.mark.asyncio 

75async def test_servce_manifest_view_url_custom(db_path): 

76 custom_view_url = "https://example.com/{{id}}" 

77 app = Datasette( 

78 [db_path], 

79 metadata=plugin_metadata( 

80 { 

81 "name_field": "name", 

82 "view_url": custom_view_url, 

83 } 

84 ), 

85 ).app() 

86 async with httpx.AsyncClient(app=app) as client: 

87 response = await client.get("http://localhost/test/dogs/-/reconcile") 

88 assert 200 == response.status_code 

89 data = response.json() 

90 assert data["view"]["url"] == custom_view_url 

91 

92 

93@pytest.mark.asyncio 

94async def test_servce_manifest_view_extend(db_path): 

95 app = Datasette( 

96 [db_path], 

97 metadata=plugin_metadata({"name_field": "name"}), 

98 ).app() 

99 async with httpx.AsyncClient(app=app) as client: 

100 response = await client.get("http://localhost/test/dogs/-/reconcile") 

101 assert 200 == response.status_code 

102 data = response.json() 

103 assert "extend" in data 

104 assert data["extend"]["propose_properties"]["service_url"] == "http://localhost//test/dogs/-/reconcile" 

105 assert data["extend"]["property_settings"][3]["name"] == "status" 

106 assert len(data["suggest"]) == 3 

107 

108 

109@pytest.mark.asyncio 

110async def test_response_queries_post(db_path): 

111 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

112 async with httpx.AsyncClient(app=app) as client: 

113 response = await client.post( 

114 "http://localhost/test/dogs/-/reconcile", 

115 data={"queries": json.dumps({"q0": {"query": "fido"}})}, 

116 ) 

117 assert 200 == response.status_code 

118 data = response.json() 

119 assert "q0" in data.keys() 

120 assert len(data["q0"]["result"]) == 1 

121 result = data["q0"]["result"][0] 

122 assert result["id"] == "3" 

123 assert result["name"] == "Fido" 

124 assert result["score"] == 100 

125 assert result["type"] == [ 

126 { 

127 "name": "Object", 

128 "id": "object", 

129 } 

130 ] 

131 assert response.headers["Access-Control-Allow-Origin"] == "*" 

132 

133 

134@pytest.mark.asyncio 

135async def test_response_queries_get(db_path): 

136 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

137 async with httpx.AsyncClient(app=app) as client: 

138 queries = json.dumps({"q0": {"query": "fido"}}) 

139 response = await client.get(f"http://localhost/test/dogs/-/reconcile?queries={queries}") 

140 assert 200 == response.status_code 

141 data = response.json() 

142 assert "q0" in data.keys() 

143 assert len(data["q0"]["result"]) == 1 

144 result = data["q0"]["result"][0] 

145 assert result["id"] == "3" 

146 assert result["name"] == "Fido" 

147 assert result["score"] == 100 

148 assert result["type"] == [ 

149 { 

150 "name": "Object", 

151 "id": "object", 

152 } 

153 ] 

154 assert response.headers["Access-Control-Allow-Origin"] == "*" 

155 

156 

157@pytest.mark.asyncio 

158async def test_response_queries_no_results_post(db_path): 

159 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

160 async with httpx.AsyncClient(app=app) as client: 

161 response = await client.post( 

162 "http://localhost/test/dogs/-/reconcile", 

163 data={"queries": json.dumps({"q0": {"query": "abcdef"}})}, 

164 ) 

165 assert 200 == response.status_code 

166 data = response.json() 

167 assert "q0" in data.keys() 

168 assert len(data["q0"]["result"]) == 0 

169 assert response.headers["Access-Control-Allow-Origin"] == "*" 

170 

171 

172@pytest.mark.asyncio 

173async def test_response_queries_no_results_get(db_path): 

174 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

175 async with httpx.AsyncClient(app=app) as client: 

176 queries = json.dumps({"q0": {"query": "abcdef"}}) 

177 response = await client.get(f"http://localhost/test/dogs/-/reconcile?queries={queries}") 

178 assert 200 == response.status_code 

179 data = response.json() 

180 assert "q0" in data.keys() 

181 assert len(data["q0"]["result"]) == 0 

182 assert response.headers["Access-Control-Allow-Origin"] == "*" 

183 

184 

185@pytest.mark.asyncio 

186async def test_response_propose_properties(db_path): 

187 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

188 async with httpx.AsyncClient(app=app) as client: 

189 response = await client.get("http://localhost/test/dogs/-/reconcile/extend/propose?type=object") 

190 assert 200 == response.status_code 

191 data = response.json() 

192 assert len(data["properties"]) == 4 

193 result = data["properties"][3] 

194 assert result["name"] == "status" 

195 assert result["id"] == "status" 

196 assert response.headers["Access-Control-Allow-Origin"] == "*" 

197 

198 

199@pytest.mark.asyncio 

200async def test_response_extend(db_path): 

201 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

202 async with httpx.AsyncClient(app=app) as client: 

203 extend = {"extend": json.dumps({"ids": ["1", "2", "3", "4"], "properties": [{"id": "status"}, {"id": "age"}]})} 

204 response = await client.post("http://localhost/test/dogs/-/reconcile", data=extend) 

205 assert 200 == response.status_code 

206 data = response.json() 

207 

208 assert "meta" in data 

209 assert data["meta"][0]["id"] == "status" 

210 assert data["meta"][0]["name"] == "status" 

211 assert "rows" in data 

212 

213 expect = { 

214 "1": "good dog", 

215 "2": "bad dog", 

216 "3": "bad dog", 

217 "4": "good dog", 

218 } 

219 

220 for key in expect.keys(): 

221 assert data["rows"][key]["status"][0]["str"] == expect[key] 

222 

223 expect_nums = { 

224 "1": 5, 

225 "2": 4, 

226 "3": 3, 

227 "4": 3, 

228 } 

229 

230 for key in expect_nums.keys(): 

231 assert data["rows"][key]["age"][0]["int"] == expect_nums[key] 

232 

233 assert response.headers["Access-Control-Allow-Origin"] == "*" 

234 

235 

236@pytest.mark.asyncio 

237async def test_response_suggest_entity(db_path): 

238 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

239 async with httpx.AsyncClient(app=app) as client: 

240 response = await client.get("http://localhost/test/dogs/-/reconcile/suggest/entity?prefix=f") 

241 assert 200 == response.status_code 

242 data = response.json() 

243 

244 assert "result" in data 

245 assert data["result"][0]["id"] == 3 

246 assert data["result"][0]["name"] == "Fido" 

247 assert response.headers["Access-Control-Allow-Origin"] == "*" 

248 

249 

250@pytest.mark.asyncio 

251async def test_response_suggest_property(db_path): 

252 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

253 async with httpx.AsyncClient(app=app) as client: 

254 response = await client.get("http://localhost/test/dogs/-/reconcile/suggest/property?prefix=a") 

255 assert 200 == response.status_code 

256 data = response.json() 

257 

258 assert "result" in data 

259 assert data["result"][0]["id"] == "age" 

260 assert data["result"][0]["name"] == "age" 

261 assert response.headers["Access-Control-Allow-Origin"] == "*" 

262 

263 

264@pytest.mark.asyncio 

265async def test_response_suggest_type(db_path): 

266 app = Datasette([db_path], metadata=plugin_metadata({"name_field": "name"})).app() 

267 async with httpx.AsyncClient(app=app) as client: 

268 response = await client.get("http://localhost/test/dogs/-/reconcile/suggest/type?prefix=a") 

269 assert 200 == response.status_code 

270 data = response.json() 

271 

272 assert "result" in data 

273 assert len(data["result"]) == 0 

274 assert response.headers["Access-Control-Allow-Origin"] == "*"