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
« prev ^ index » next coverage.py v7.3.1, created at 2023-12-20 00:45 +0000
1import json
3import httpx
4import pytest
5from datasette.app import Datasette
7from tests.conftest import plugin_metadata
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
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
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"] == "*"
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}}"
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}}"
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}}"
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
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
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"] == "*"
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"] == "*"
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"] == "*"
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"] == "*"
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"] == "*"
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()
208 assert "meta" in data
209 assert data["meta"][0]["id"] == "status"
210 assert data["meta"][0]["name"] == "status"
211 assert "rows" in data
213 expect = {
214 "1": "good dog",
215 "2": "bad dog",
216 "3": "bad dog",
217 "4": "good dog",
218 }
220 for key in expect.keys():
221 assert data["rows"][key]["status"][0]["str"] == expect[key]
223 expect_nums = {
224 "1": 5,
225 "2": 4,
226 "3": 3,
227 "4": 3,
228 }
230 for key in expect_nums.keys():
231 assert data["rows"][key]["age"][0]["int"] == expect_nums[key]
233 assert response.headers["Access-Control-Allow-Origin"] == "*"
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()
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"] == "*"
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()
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"] == "*"
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()
272 assert "result" in data
273 assert len(data["result"]) == 0
274 assert response.headers["Access-Control-Allow-Origin"] == "*"