',
],
] == [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
def test_table_csv_json_export_interface(app_client):
response = app_client.get("/fixtures/simple_primary_key?id__gt=2")
assert response.status == 200
# The links at the top of the page
links = (
Soup(response.body, "html.parser")
.find("p", {"class": "export-links"})
.findAll("a")
)
actual = [l["href"] for l in links]
expected = [
"/fixtures/simple_primary_key.json?id__gt=2",
"/fixtures/simple_primary_key.testall?id__gt=2",
"/fixtures/simple_primary_key.testnone?id__gt=2",
"/fixtures/simple_primary_key.testresponse?id__gt=2",
"/fixtures/simple_primary_key.csv?id__gt=2&_size=max",
"#export",
]
assert expected == actual
# And the advaced export box at the bottom:
div = Soup(response.body, "html.parser").find("div", {"class": "advanced-export"})
json_links = [a["href"] for a in div.find("p").findAll("a")]
assert [
"/fixtures/simple_primary_key.json?id__gt=2",
"/fixtures/simple_primary_key.json?id__gt=2&_shape=array",
"/fixtures/simple_primary_key.json?id__gt=2&_shape=array&_nl=on",
"/fixtures/simple_primary_key.json?id__gt=2&_shape=object",
] == json_links
# And the CSV form
form = div.find("form")
assert form["action"].endswith("/simple_primary_key.csv")
inputs = [str(input) for input in form.findAll("input")]
assert [
'',
'',
'',
'',
] == inputs
def test_csv_json_export_links_include_labels_if_foreign_keys(app_client):
response = app_client.get("/fixtures/facetable")
assert response.status == 200
links = (
Soup(response.body, "html.parser")
.find("p", {"class": "export-links"})
.findAll("a")
)
actual = [l["href"] for l in links]
expected = [
"/fixtures/facetable.json?_labels=on",
"/fixtures/facetable.testall?_labels=on",
"/fixtures/facetable.testnone?_labels=on",
"/fixtures/facetable.testresponse?_labels=on",
"/fixtures/facetable.csv?_labels=on&_size=max",
"#export",
]
assert expected == actual
def test_table_not_exists(app_client):
assert "Table not found: blah" in app_client.get("/fixtures/blah").text
def test_table_html_no_primary_key(app_client):
response = app_client.get("/fixtures/no_primary_key")
assert response.status == 200
table = Soup(response.body, "html.parser").find("table")
# We have disabled sorting for this table using metadata.json
assert ["content", "a", "b", "c"] == [
th.string.strip() for th in table.select("thead th")[2:]
]
expected = [
[
'
',
]
]
assert expected == [
[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")
]
def test_table_html_foreign_key_links(app_client):
response = app_client.get("/fixtures/foreign_key_references")
assert response.status == 200
table = Soup(response.body, "html.parser").find("table")
actual = [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
assert actual == [
[
'
"
) in response.text
def test_table_html_disable_foreign_key_links_with_labels(app_client):
response = app_client.get("/fixtures/foreign_key_references?_labels=off&_size=1")
assert response.status == 200
table = Soup(response.body, "html.parser").find("table")
actual = [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
assert actual == [
[
'
',
],
]
assert expected == rows
# Make sure you can reverse that sort order
response = app_client.get("/fixtures/attraction_characteristic?_sort=pk")
assert response.status == 200
table = Soup(response.body, "html.parser").find("table")
rows = [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
assert list(reversed(expected)) == rows
@pytest.mark.parametrize(
"max_returned_rows,path,expected_num_facets,expected_ellipses,expected_ellipses_url",
(
(
5,
# Default should show 2 facets
"/fixtures/facetable?_facet=_neighborhood",
2,
True,
"/fixtures/facetable?_facet=_neighborhood&_facet_size=max",
),
# _facet_size above max_returned_rows should show max_returned_rows (5)
(
5,
"/fixtures/facetable?_facet=_neighborhood&_facet_size=50",
5,
True,
"/fixtures/facetable?_facet=_neighborhood&_facet_size=max",
),
# If max_returned_rows is high enough, should return all
(
20,
"/fixtures/facetable?_facet=_neighborhood&_facet_size=max",
14,
False,
None,
),
# If num facets > max_returned_rows, show ... without a link
# _facet_size above max_returned_rows should show max_returned_rows (5)
(
5,
"/fixtures/facetable?_facet=_neighborhood&_facet_size=max",
5,
True,
None,
),
),
)
def test_facet_more_links(
max_returned_rows,
path,
expected_num_facets,
expected_ellipses,
expected_ellipses_url,
):
with make_app_client(
settings={"max_returned_rows": max_returned_rows, "default_facet_size": 2}
) as client:
response = client.get(path)
soup = Soup(response.body, "html.parser")
lis = soup.select("#facet-neighborhood-b352a7 ul li:not(.facet-truncated)")
facet_truncated = soup.select_one(".facet-truncated")
assert len(lis) == expected_num_facets
if not expected_ellipses:
assert facet_truncated is None
else:
if expected_ellipses_url:
assert facet_truncated.find("a")["href"] == expected_ellipses_url
else:
assert facet_truncated.find("a") is None
def test_unavailable_table_does_not_break_sort_relationships():
# https://github.com/simonw/datasette/issues/1305
with make_app_client(
metadata={
"databases": {
"fixtures": {"tables": {"foreign_key_references": {"allow": False}}}
}
}
) as client:
response = client.get("/?_sort=relationships")
assert response.status == 200
def test_column_metadata(app_client):
response = app_client.get("/fixtures/roadside_attractions")
soup = Soup(response.body, "html.parser")
dl = soup.find("dl")
assert [(dt.text, dt.nextSibling.text) for dt in dl.findAll("dt")] == [
("name", "The name of the attraction"),
("address", "The street address for the attraction"),
]
assert (
soup.select("th[data-column=name]")[0]["data-column-description"]
== "The name of the attraction"
)
assert (
soup.select("th[data-column=address]")[0]["data-column-description"]
== "The street address for the attraction"
)
@pytest.mark.parametrize("use_facet_size_max", (True, False))
def test_facet_total_shown_if_facet_max_size(use_facet_size_max):
# https://github.com/simonw/datasette/issues/1423
with make_app_client(settings={"max_returned_rows": 100}) as client:
path = "/fixtures/sortable?_facet=content&_facet=pk1"
if use_facet_size_max:
path += "&_facet_size=max"
response = client.get(path)
assert response.status == 200
fragments = (
'>100',
'8',
)
for fragment in fragments:
if use_facet_size_max:
assert fragment in response.text
else:
assert fragment not in response.text
def test_sort_rowid_with_next(app_client):
# https://github.com/simonw/datasette/issues/1470
response = app_client.get("/fixtures/binary_data?_size=1&_next=1&_sort=rowid")
assert response.status == 200
def assert_querystring_equal(expected, actual):
assert sorted(expected.split("&")) == sorted(actual.split("&"))