{"html_url": "https://github.com/simonw/datasette/pull/1999#issuecomment-1460759358", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1999", "id": 1460759358, "node_id": "IC_kwDOBm6k_c5XEWs-", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-03-08T19:48:13Z", "updated_at": "2023-03-20T18:47:12Z", "author_association": "OWNER", "body": "Breaking this down into smaller steps:\r\n\r\n- [x] Get `?_next=` working\r\n- [x] Implement extensions - so `.json` is needed again for the JSON version, and anything without an extension is passed through a new code path for HTML\r\n- [ ] That HTML view should only access JSON data, which can be seen by using `.context` - this will require a lot of updates to templates (it may be necessary to still provide access to some helper functions though). This will form the basis of the ambition to fully document the template context.\r\n- [ ] Get a bunch of the existing table HTML and JSON tests to pass\r\n- [ ] Use those tests to refactor the nasty `_next` code, see https://github.com/simonw/datasette/pull/1999#issuecomment-1460905469\r\n- [ ] Figure out how the [register_output_renderer(datasette)](https://docs.datasette.io/en/stable/plugin_hooks.html#register-output-renderer-datasette) plugin hook should work", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1551694938, "label": "?_extra= support (draft)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1999#issuecomment-1476781401", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1999", "id": 1476781401, "node_id": "IC_kwDOBm6k_c5YBeVZ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-03-20T19:01:35Z", "updated_at": "2023-03-20T19:01:35Z", "author_association": "OWNER", "body": "Down to just these failures:\r\n```\r\nFAILED tests/test_table_html.py::test_sort_links - AssertionError: assert [{'attrs': {'class': ['col-Link'], 'scope': 'col', 'data-column': 'Link', 'data-column-type': '', 'data-column-not-null': '0', 'data-is-pk': '0'}, 'a_href': None}, {'attrs': {'class': ['col-pk1'], 'scope': 'col', 'data-column': 'pk1', 'data-column-typ...\r\nFAILED tests/test_table_html.py::test_table_html_simple_primary_key - AssertionError: assert 'id\\xa0\u25bc' == 'id'\r\nFAILED tests/test_table_html.py::test_table_csv_json_export_interface - AssertionError: assert ['/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=ma...\r\nFAILED tests/test_table_html.py::test_csv_json_export_links_include_labels_if_foreign_keys - AssertionError: assert ['/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'] == ['/', '', '#export']\r\nFAILED tests/test_table_html.py::test_rowid_sortable_no_primary_key - AssertionError: assert 'rowid\\xa0\u25bc' == 'rowid'\r\nFAILED tests/test_table_html.py::test_table_html_filter_form_column_options[/fixtures/infinity-expected_column_options0] - AssertionError: assert ['- column -', 'rowid', 'value'] == ['- column -']\r\nFAILED tests/test_table_html.py::test_table_html_filter_form_column_options[/fixtures/primary_key_multiple_columns-expected_column_options1] - AssertionError: assert ['- column -', 'id', 'content', 'content2'] == ['- column -']\r\nFAILED tests/test_table_html.py::test_table_html_filter_form_column_options[/fixtures/compound_primary_key-expected_column_options2] - AssertionError: assert ['- column -', 'pk1', 'pk2', 'content'] == ['- column -']\r\nFAILED tests/test_table_html.py::test_table_html_filter_form_still_shows_nocol_columns - AssertionError: assert ['- column -'] == ['- column -', 'pk1', 'pk2', 'content', 'sortable_with_nulls', 'sortable_with_nulls_2', 'text', 'sortable']\r\nFAILED tests/test_table_html.py::test_metadata_sort - AssertionError: assert ['id', 'name\\xa0\u25bc'] == ['id', 'name']\r\nFAILED tests/test_table_html.py::test_metadata_sort_desc - AssertionError: assert ['pk\\xa0\u25b2', 'name'] == ['pk', 'name']\r\n=== 11 failed, 57 passed in 7.59s ===\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1551694938, "label": "?_extra= support (draft)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1999#issuecomment-1476851525", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1999", "id": 1476851525, "node_id": "IC_kwDOBm6k_c5YBvdF", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-03-20T19:59:51Z", "updated_at": "2023-03-20T20:01:40Z", "author_association": "OWNER", "body": "Three failures in `test_html.py`:\r\n```\r\nFAILED tests/test_html.py::test_templates_considered[/fixtures/simple_primary_key-table-fixtures-simple_primary_key.html, *table.html] - assert '' in '\\n\\n\\n fixtures: simple_primary_key: 5 rows\\n ' in '\\n\\n\\n fixtures: table/with/slashes.csv: 1 row\\n assert view.view_class.__name__ == expected_class\r\nE AttributeError: 'function' object has no attribute 'view_class'\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1551694938, "label": "?_extra= support (draft)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1999#issuecomment-1476860334", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1999", "id": 1476860334, "node_id": "IC_kwDOBm6k_c5YBxmu", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-03-20T20:06:56Z", "updated_at": "2023-03-20T22:09:03Z", "author_association": "OWNER", "body": "`pytest -n 8` locally says:\r\n\r\n```\r\nFAILED tests/test_canned_queries.py::test_canned_query_form_csrf_hidden_field[add_name_specify_id-True] - assert '\\n\\n\\n Error 500\\n details.open = false);\\n});\\n\\n\\n\\n Error 500\\n details.open = false);\\n});\\n' in '\\n\\n\\n Error 500\\n details.open = false);\\...\r\nFAILED tests/test_canned_queries.py::test_insert - KeyError: 'ds_csrftoken'\r\nFAILED tests/test_canned_queries.py::test_insert_error - KeyError: 'ds_csrftoken'\r\nFAILED tests/test_canned_queries.py::test_magic_parameters_csrf_json[False-True] - KeyError: 'ds_csrftoken'\r\nFAILED tests/test_canned_queries.py::test_magic_parameters_csrf_json[True-True] - KeyError: 'ds_csrftoken'\r\nFAILED tests/test_canned_queries.py::test_vary_header - KeyError: 'vary'\r\nFAILED tests/test_csv.py::test_csv_trace - AssertionError: assert 'application/...charset=utf-8' == 'text/html; charset=utf-8'\r\nFAILED tests/test_csv.py::test_table_csv - AssertionError: assert 'application/...charset=utf-8' == 'text/plain; charset=utf-8'\r\nFAILED tests/test_csv.py::test_table_csv_blob_columns - AssertionError: assert 'application/...charset=utf-8' == 'text/plain; charset=utf-8'\r\nFAILED tests/test_csv.py::test_table_csv_download - AssertionError: assert 'application/...charset=utf-8' == 'text/csv; charset=utf-8'\r\nFAILED tests/test_csv.py::test_table_csv_no_header - AssertionError: assert 'application/...charset=utf-8' == 'text/plain; charset=utf-8'\r\nFAILED tests/test_csv.py::test_table_csv_stream - assert 1 == 101\r\nFAILED tests/test_csv.py::test_table_csv_stream_does_not_calculate_counts - AttributeError: 'NoneType' object has no attribute 'text'\r\nFAILED tests/test_csv.py::test_table_csv_stream_does_not_calculate_facets - AttributeError: 'NoneType' object has no attribute 'text'\r\nFAILED tests/test_csv.py::test_table_csv_with_labels - AssertionError: assert 'application/...charset=utf-8' == 'text/plain; charset=utf-8'\r\nFAILED tests/test_csv.py::test_table_csv_with_nullable_labels - AssertionError: assert 'application/...charset=utf-8' == 'text/plain; charset=utf-8'\r\nFAILED tests/test_facets.py::test_array_facet_handle_duplicate_tags - KeyError: 'facet_results'\r\nFAILED tests/test_facets.py::test_conflicting_facet_names_json - AssertionError: assert {'results', 'timed_out'} == {'created', '...gs', 'tags_2'}\r\nFAILED tests/test_facets.py::test_facet_size - KeyError: 'suggested_facets'\r\nFAILED tests/test_facets.py::test_json_array_with_blanks_and_nulls - KeyError: 'suggested_facets'\r\nFAILED tests/test_facets.py::test_other_types_of_facet_in_metadata - assert 'created (date)\\n' in '\\n\\n\\n fixtures: facetable: 15 rows\\n \\n\\n\\n\\n' in '\\n\\n\\n fixtures: simple_primary_key: 5 rows\\n ' in '\\n\\n\\n fixtures: table/with/slashes.csv: 1 row\\n ', ...}\r\nFAILED tests/test_plugins.py::test_hook_register_output_renderer_no_parameters - assert b'Hello' == b'{\"ok\": true... \"n\": null}]}'\r\nFAILED tests/test_plugins.py::test_hook_register_output_renderer_returning_broken_value - assert 200 == 500\r\nFAILED tests/test_plugins.py::test_hook_register_output_renderer_returning_response - assert {'next': None...', ...}, ...]} == {'this_is': 'json'}\r\n=== 39 failed, 1259 passed, 2 skipped, 1 xfailed in 58.07s ===\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1551694938, "label": "?_extra= support (draft)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1999#issuecomment-1476898261", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1999", "id": 1476898261, "node_id": "IC_kwDOBm6k_c5YB63V", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-03-20T20:37:52Z", "updated_at": "2023-03-20T20:37:52Z", "author_association": "OWNER", "body": "Manual testing spotted a bug.\r\n\r\n`/content/repos.json?owner=9599&_facet_array=topics` - does not return a `facet_results` key.\r\n\r\n`/content/repos.json?owner=9599&_facet_array=topics&_facet=owner` does.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1551694938, "label": "?_extra= support (draft)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1999#issuecomment-1477082852", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1999", "id": 1477082852, "node_id": "IC_kwDOBm6k_c5YCn7k", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-03-20T23:27:25Z", "updated_at": "2023-03-20T23:27:25Z", "author_association": "OWNER", "body": "Urgh getting CSV to work is going to be _so hard_, because the logic for that currently lives in a huge chunk of code in `BaseView` which depends on the old design of the `data()` method:\r\n\r\nhttps://github.com/simonw/datasette/blob/4bb49848697e40b8b9a1557be42b8e59eac965b3/datasette/views/base.py#L177-L343", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1551694938, "label": "?_extra= support (draft)"}, "performed_via_github_app": null}