From e04511410f57e88c806455b9182a853bf07122a2 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Tue, 14 May 2019 08:46:57 -0700 Subject: [PATCH] Don't show hidden tables on index page, closes #455 Refs #460. Also bulked out HTML index page unit tests. --- datasette/views/index.py | 4 +++- tests/fixtures.py | 39 +++++++++++++++++++++++++++++++++++++-- tests/test_html.py | 31 ++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/datasette/views/index.py b/datasette/views/index.py index b5d55a21..bb6154cf 100644 --- a/datasette/views/index.py +++ b/datasette/views/index.py @@ -52,7 +52,9 @@ class IndexView(RenderMixin): else hashlib.md5(name.encode("utf8")).hexdigest()[:6], "path": self.database_url(name), "tables_truncated": sorted( - tables.values(), key=lambda t: t["count"] or 0, reverse=True + (t for t in tables.values() if t not in hidden_tables), + key=lambda t: t["count"] or 0, + reverse=True, )[:5], "tables_count": len(tables), "tables_more": len(tables) > 5, diff --git a/tests/fixtures.py b/tests/fixtures.py index efbbf8b4..23c8c7a8 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -30,14 +30,26 @@ def make_app_client( config=None, filename="fixtures.db", is_immutable=False, + extra_databases=None, ): with tempfile.TemporaryDirectory() as tmpdir: filepath = os.path.join(tmpdir, filename) + if is_immutable: + files = [] + immutables = [filepath] + else: + files = [filepath] + immutables = [] conn = sqlite3.connect(filepath) conn.executescript(TABLES) for sql, params in TABLE_PARAMETERIZED_SQL: with conn: conn.execute(sql, params) + if extra_databases is not None: + for extra_filename, extra_sql in extra_databases.items(): + extra_filepath = os.path.join(tmpdir, extra_filename) + sqlite3.connect(extra_filepath).executescript(extra_sql) + files.append(extra_filepath) os.chdir(os.path.dirname(filepath)) plugins_dir = os.path.join(tmpdir, "plugins") os.mkdir(plugins_dir) @@ -52,8 +64,8 @@ def make_app_client( } ) ds = Datasette( - [] if is_immutable else [filepath], - immutables=[filepath] if is_immutable else [], + files, + immutables=immutables, memory=memory, cors=cors, metadata=METADATA, @@ -79,6 +91,13 @@ def app_client_no_files(): yield client +@pytest.fixture(scope="session") +def app_client_two_attached_databases(): + yield from make_app_client( + extra_databases={"extra_database.db": EXTRA_DATABASE_SQL} + ) + + @pytest.fixture(scope="session") def app_client_with_memory(): yield from make_app_client(memory=True) @@ -586,6 +605,22 @@ TABLE_PARAMETERIZED_SQL = [ ("insert into binary_data (data) values (?);", [b"this is binary data"]) ] +EXTRA_DATABASE_SQL = """ +CREATE TABLE searchable ( + pk integer primary key, + text1 text, + text2 text +); + +INSERT INTO searchable VALUES (1, 'barry cat', 'terry dog'); +INSERT INTO searchable VALUES (2, 'terry dog', 'sara weasel'); + +CREATE VIRTUAL TABLE "searchable_fts" + USING FTS3 (text1, text2, content="searchable"); +INSERT INTO "searchable_fts" (rowid, text1, text2) + SELECT rowid, text1, text2 FROM searchable; +""" + if __name__ == "__main__": # Can be called with data.db OR data.db metadata.json arg_index = -1 diff --git a/tests/test_html.py b/tests/test_html.py index b25263cb..7b16e6d0 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -2,6 +2,7 @@ from bs4 import BeautifulSoup as Soup from .fixtures import ( # noqa app_client, app_client_shorter_time_limit, + app_client_two_attached_databases, app_client_with_hash, app_client_with_memory, make_app_client, @@ -13,10 +14,34 @@ import re import urllib.parse -def test_homepage(app_client): - response = app_client.get("/") +def test_homepage(app_client_two_attached_databases): + response = app_client_two_attached_databases.get("/") assert response.status == 200 - assert "fixtures" in response.text + soup = Soup(response.body, "html.parser") + assert "Datasette Fixtures" == soup.find("h1").text + assert ( + "An example SQLite database demonstrating Datasette" + == soup.select(".metadata-description")[0].text.strip() + ) + # Should be two attached databases + assert [ + {"href": "/fixtures", "text": "fixtures"}, + {"href": "/extra_database", "text": "extra_database"}, + ] == [{"href": a["href"], "text": a.text.strip()} for a in soup.select("h2 a")] + # The second attached database should show count text and attached tables + h2 = soup.select("h2")[1] + assert "extra_database" == h2.text.strip() + counts_p, links_p = h2.find_all_next("p") + assert "7 rows in 5 tables, 5 rows in 4 hidden tables" == counts_p.text.strip().replace( + " ", "" + ).replace( + "\n", "" + ) + # We should only show visible, not hidden tables here: + table_links = [ + {"href": a["href"], "text": a.text.strip()} for a in links_p.findAll("a") + ] + assert [{"href": "/extra_database/searchable", "text": "searchable"}] == table_links def test_memory_database_page(app_client_with_memory):