async def test_upload(client, mock_csv): user = await create_user() client.login(user) csv_file = open(mock_csv.name, "r") url = app.url_path_for("profile", username=user["username"]) data = {"name": "new table"} response = await client.post(url, data=data, allow_redirects=False) expected_redirect = url assert response.is_redirect assert URL(response.headers["location"]).path == expected_redirect url = app.url_path_for("upload", username=user["username"], table_id="new-table") response = await client.post(url, files={"upload-file": csv_file}, allow_redirects=False) expected_redirect = app.url_path_for("table", username=user["username"], table_id="new-table") assert response.is_redirect assert URL(response.headers["location"]).path == expected_redirect
async def test_login_flow(client): # Ensure the user is not logged in. url = app.url_path_for("dashboard") response = await client.get(url) assert response.status_code == 200 assert response.template.name == "dashboard.html" assert "username" not in response.context["request"].session # A POST /auth/login should redirect to the github auth URL. url = app.url_path_for("auth:login") response = await client.post(url, allow_redirects=True) assert response.status_code == 200 assert response.template.name == "mock_github/authorize.html" # Once the callback is made, the user should be authenticated, and end up on the homepage. url = app.url_path_for("auth:callback") response = await client.get(url) assert response.status_code == 200 assert response.template.name == "profile.html" assert response.context["request"].session["username"] == "tomchristie" # A POST /auth/logout should unauthenticate the user and redirect to the homepage. url = app.url_path_for("auth:logout") response = await client.post(url, allow_redirects=True) assert response.template.name == "dashboard.html" assert "username" not in response.context["request"].session
async def test_table_delete(client): """ Test table delete. """ user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for("delete-table", username=user["username"], table_id=table["identity"]) response = await client.post(url, allow_redirects=False) expected_redirect = app.url_path_for("profile", username=user["username"]) assert response.is_redirect assert URL(response.headers["location"]).path == expected_redirect
async def test_valid_edit(client): """ Test row edit. """ user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for( "detail", username=user["username"], table_id=table["identity"], row_uuid=rows[0]["uuid"], ) data = { "constituency": "Harrow East", "surname": "WALLACE", "first_name": "Emma", "party": "Green Party", "votes": 846, } response = await client.post(url, data=data, allow_redirects=False) expected_redirect = url assert response.is_redirect assert URL(response.headers["location"]).path == expected_redirect
async def test_complete_column_delete(client): """ Deleting all columns in the table should remove all the rows. """ user = await create_user() table, columns, rows = await create_table(user) client.login(user) query = (select([func.count()]).select_from( tables.row).where(tables.row.c.table == table["pk"])) row_count = await database.fetch_val(query) assert row_count > 0 for column in columns: url = app.url_path_for( "delete-column", username=user["username"], table_id=table["identity"], column_id=column["identity"], ) response = await client.post(url, allow_redirects=False) assert response.is_redirect row_count = await database.fetch_val(query) assert row_count == 0
async def test_invalid_edit(client): """ Test an invalid row edit. """ user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for( "detail", username=user["username"], table_id=table["identity"], row_uuid=rows[0]["uuid"], ) data = { "constituency": "", "surname": "WALLACE", "first_name": "Emma", "party": "Green Party", "votes": 846, } response = await client.post(url, data=data) assert response.status_code == 400 assert response.context["form_errors"][ "constituency"] == "Must not be blank."
async def test_no_permissions_create_table(client): user = await create_user() url = app.url_path_for("profile", username=user["username"]) data = {"name": "A new table"} response = await client.post(url, data=data) assert response.status_code == 403
async def test_invalid_create_table(client): user = await create_user() client.login(user) url = app.url_path_for("profile", username=user["username"]) data = {"name": ""} response = await client.post(url, data=data) assert response.status_code == 400 assert response.context["form_errors"]["name"] == "Must not be blank."
async def test_valid_create_table(client): user = await create_user() client.login(user) url = app.url_path_for("profile", username=user["username"]) data = {"name": "A new table"} response = await client.post(url, data=data, allow_redirects=False) expected_redirect = url assert response.is_redirect assert URL(response.headers["location"]).path == expected_redirect
async def test_dashboard(client): """ Ensure that the dashboard renders the 'dashboard.html' template. """ user = await create_user() table, columns, rows = await create_table(user) url = app.url_path_for("dashboard") response = await client.get(url) assert response.status_code == 200 assert response.template.name == "dashboard.html"
async def test_invalid_create_duplicate_table(client): user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for("profile", username=user["username"]) data = {"name": table["name"]} response = await client.post(url, data=data) assert response.status_code == 400 assert (response.context["form_errors"]["name"] == "A table with this name already exists.")
async def test_table_404(client): """ Ensure that tabular pages with an invalid year render the '404.html' template. """ user = await create_user() url = app.url_path_for("table", username=user["username"], table_id="does-not-exist") response = await client.get(url) assert response.status_code == 404 assert response.template.name == "404.html"
async def test_table_with_json_response(client): """ Ensure that tables can return application/json. """ user = await create_user() table, columns, rows = await create_table(user) url = app.url_path_for("table", username=user["username"], table_id=table["identity"]) response = await client.get(url, headers={"Accept": "application/json"}) assert response.status_code == 200 assert len(response.json()) == len(rows)
async def test_columns(client): """ Ensure that the tabular column results render the 'columns.html' template. """ user = await create_user() table, columns, rows = await create_table(user) url = app.url_path_for("columns", username=user["username"], table_id=table["identity"]) response = await client.get(url) assert response.status_code == 200 assert response.template.name == "columns.html"
async def test_invalid_create_column(client): user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for("columns", username=user["username"], table_id=table["identity"]) data = {"name": "", "datatype": "nonsense"} response = await client.post(url, data=data) assert response.status_code == 400 assert response.context["form_errors"]["name"] == "Must not be blank." assert response.context["form_errors"]["datatype"] == "Not a valid choice."
async def test_invalid_create_duplicate_column(client): user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for("columns", username=user["username"], table_id=table["identity"]) data = {"name": "party", "datatype": "integer"} response = await client.post(url, data=data) assert response.status_code == 400 assert (response.context["form_errors"]["name"] == "A column with this name already exists.")
async def test_valid_create_column(client): user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for("columns", username=user["username"], table_id=table["identity"]) data = {"name": "notes", "datatype": "string"} response = await client.post(url, data=data, allow_redirects=False) expected_redirect = url assert response.is_redirect assert URL(response.headers["location"]).path == expected_redirect
async def auth_client(): from source.app import app from source.resources import database await database.connect() try: client = TestClient(app=app) # A POST /auth/login should redirect to the github auth URL. url = app.url_path_for("auth:login") response = await client.post(url, allow_redirects=True) assert response.status_code == 200 assert response.template.name == "mock_github/authorize.html" # Once the callback is made, the user should be authenticated, and end up on the homepage. url = app.url_path_for("auth:callback") response = await client.get(url) assert response.status_code == 200 assert response.template.name == "profile.html" assert response.context["request"].session["username"] == "tomchristie" yield client finally: await database.disconnect()
async def test_export_csv(client): """ Ensure that tables can export as a CSV file. """ user = await create_user() table, columns, rows = await create_table(user) url = (app.url_path_for( "table", username=user["username"], table_id=table["identity"]) + "?export=csv") response = await client.get(url) assert response.status_code == 200 assert "Content-Disposition" in response.headers assert len(response.text.splitlines()) == len(rows) + 1
async def test_table_with_json_view(client): """ Ensure that tables can render a JSON view. """ user = await create_user() table, columns, rows = await create_table(user) url = (app.url_path_for( "table", username=user["username"], table_id=table["identity"]) + "?view=json") response = await client.get(url) json_data = response.context["json_data"] assert response.status_code == 200 assert response.template.name == "table.html" assert len(json.loads(json_data)) == len(rows)
async def test_detail(client): """ Ensure that the detail pages renders the 'detail.html' template. """ user = await create_user() table, columns, rows = await create_table(user) url = app.url_path_for( "detail", username=user["username"], table_id=table["identity"], row_uuid=rows[0]["uuid"], ) response = await client.get(url) assert response.status_code == 200 assert response.template.name == "detail.html"
async def test_row_delete_404(client): """ Ensure that delete rows with an invalid PK render the '404.html' template. """ user = await create_user() table, columns, rows = await create_table(user) client.login(user) url = app.url_path_for( "delete-row", username=user["username"], table_id=table["identity"], row_uuid="does-not-exist", ) response = await client.post(url) assert response.status_code == 404 assert response.template.name == "404.html"
async def test_table_with_ordering(client): """ Ensure that a column ordering renders a sorted 'table.html' template. """ user = await create_user() table, columns, rows = await create_table(user) url = (app.url_path_for( "table", username=user["username"], table_id=table["identity"]) + "?order=votes") response = await client.get(url) template_queryset = response.context["queryset"] rendered_votes = [item["votes"] for item in template_queryset] assert response.status_code == 200 assert response.template.name == "table.html" assert rendered_votes == sorted(rendered_votes)
async def test_table_with_search(client): """ Ensure that a column ordering renders a sorted 'table.html' template. """ user = await create_user() table, columns, rows = await create_table(user) url = (app.url_path_for( "table", username=user["username"], table_id=table["identity"]) + "?search=party") response = await client.get(url) template_queryset = response.context["queryset"] rendered_party_names = [item["party"] for item in template_queryset] assert response.status_code == 200 assert response.template.name == "table.html" assert all( ["party" in party_name.lower() for party_name in rendered_party_names])
async def test_details_with_json_view(client): """ Ensure that detail pages can render a JSON view. """ user = await create_user() table, columns, rows = await create_table(user) url = (app.url_path_for( "detail", username=user["username"], table_id=table["identity"], row_uuid=rows[0]["uuid"], ) + "?view=json") response = await client.get(url) json_data = response.context["json_data"] assert response.status_code == 200 assert response.template.name == "detail.html" assert len(json.loads(json_data).keys()) == len(columns)
def url_for(*args, **kwargs): from source.app import app return app.url_path_for(*args, **kwargs)