From 85215361b561d332cab954ea68438a2d442c96d8 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Thu, 17 Oct 2024 10:26:15 -0500 Subject: Rename test module. --- tests/qc_app/__init__.py | 0 tests/qc_app/test_entry.py | 43 ---------- tests/qc_app/test_expression_data_pages.py | 92 ---------------------- tests/qc_app/test_parse.py | 96 ----------------------- tests/qc_app/test_progress_indication.py | 109 -------------------------- tests/qc_app/test_results_page.py | 68 ---------------- tests/qc_app/test_uploads_with_zip_files.py | 84 -------------------- tests/uploader/__init__.py | 0 tests/uploader/test_entry.py | 43 ++++++++++ tests/uploader/test_expression_data_pages.py | 92 ++++++++++++++++++++++ tests/uploader/test_parse.py | 96 +++++++++++++++++++++++ tests/uploader/test_progress_indication.py | 109 ++++++++++++++++++++++++++ tests/uploader/test_results_page.py | 68 ++++++++++++++++ tests/uploader/test_uploads_with_zip_files.py | 84 ++++++++++++++++++++ 14 files changed, 492 insertions(+), 492 deletions(-) delete mode 100644 tests/qc_app/__init__.py delete mode 100644 tests/qc_app/test_entry.py delete mode 100644 tests/qc_app/test_expression_data_pages.py delete mode 100644 tests/qc_app/test_parse.py delete mode 100644 tests/qc_app/test_progress_indication.py delete mode 100644 tests/qc_app/test_results_page.py delete mode 100644 tests/qc_app/test_uploads_with_zip_files.py create mode 100644 tests/uploader/__init__.py create mode 100644 tests/uploader/test_entry.py create mode 100644 tests/uploader/test_expression_data_pages.py create mode 100644 tests/uploader/test_parse.py create mode 100644 tests/uploader/test_progress_indication.py create mode 100644 tests/uploader/test_results_page.py create mode 100644 tests/uploader/test_uploads_with_zip_files.py diff --git a/tests/qc_app/__init__.py b/tests/qc_app/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/qc_app/test_entry.py b/tests/qc_app/test_entry.py deleted file mode 100644 index 0c614a5..0000000 --- a/tests/qc_app/test_entry.py +++ /dev/null @@ -1,43 +0,0 @@ -"""Test the entry module in the web-ui""" -import pytest - -@pytest.mark.parametrize( - "dataitem,lower", - ( - # expression data UI elements - (b'

expression data

', True), - (b'', False), - - # samples/cases data UI elements - (b'

samples/cases

', True), - (b'
r/qtl2 bundles', True), - (b'405: The method is not allowed for the requested URL.' - in resp.data) diff --git a/tests/qc_app/test_expression_data_pages.py b/tests/qc_app/test_expression_data_pages.py deleted file mode 100644 index c2f7de1..0000000 --- a/tests/qc_app/test_expression_data_pages.py +++ /dev/null @@ -1,92 +0,0 @@ -"""Test expression data path""" -import pytest - -from tests.conftest import uploadable_file_object - -def test_basic_elements_present_in_index_page(client): - """ - GIVEN: A flask application testing client - WHEN: the index page is requested with the "GET" method and no data - THEN: verify that the response contains error notifications - """ - response = client.get("/upload") - assert response.status_code == 200 - ## form present - assert b'
' in response.data - ## filetype elements - assert b'non-existent-job-id' was found!" - in resp.data) - assert b'' in resp.data - -def test_with_unstarted_job(client, job_id, redis_conn_with_fresh_job): # pylint: disable=[unused-argument] - """ - GIVEN: 1. A flask application testing client - 2. A redis instance with a fresh, unstarted job - WHEN: The parsing progress page is loaded - THEN: Ensure that the page: - 1. Has a meta tag to refresh it after 5 seconds - 2. Has a progress indicator with zero progress - """ - resp = client.get(f"/parse/status/{job_id}") - assert b'' in resp.data - assert ( - b'' in resp.data - -def test_with_in_progress_no_error_job( - client, job_id, redis_conn_with_in_progress_job_no_errors): # pylint: disable=[unused-argument] - """ - GIVEN: 1. A flask application testing client - 2. A redis instance with a job in progress, with no errors found in - the file so far - WHEN: The parsing progress page is loaded - THEN: Ensure that the page: - 1. Has a meta tag to refresh it after 5 seconds - 2. Has a progress indicator with the percent of the file processed - indicated - """ - resp = client.get(f"/parse/status/{job_id}") - assert b'' in resp.data - assert ( - b'' in resp.data - assert ( - b'No errors found so far' - in resp.data) - assert b"' in resp.data - assert ( - b'' in resp.data - assert ( - b'

We have found the following errors so far

' - in resp.data) - assert b'table class="table reports-table">' in resp.data - assert b'Duplicate Header' in resp.data - assert b'Invalid Value' in resp.data - -def test_with_completed_job_no_errors( - client, job_id, redis_conn_with_completed_job_no_errors): # pylint: disable=[unused-argument] - """ - GIVEN: 1. A flask application testing client - 2. A redis instance with a completed job, with no errors found in - the file so far - WHEN: The parsing progress page is loaded - THEN: Ensure that the response is a redirection to the results page - """ - resp = client.get(f"/parse/status/{job_id}") - assert resp.status_code == 302 - assert f"/parse/results/{job_id}".encode("utf8") in resp.data - -def test_with_completed_job_some_errors( - client, job_id, redis_conn_with_completed_job_no_errors): # pylint: disable=[unused-argument] - """ - GIVEN: 1. A flask application testing client - 2. A redis instance with a completed job, with some errors found in - the file so far - WHEN: The parsing progress page is loaded - THEN: Ensure that the response is a redirection to the results page - """ - resp = client.get(f"/parse/status/{job_id}") - assert resp.status_code == 302 - assert f"/parse/results/{job_id}".encode("utf8") in resp.data diff --git a/tests/qc_app/test_results_page.py b/tests/qc_app/test_results_page.py deleted file mode 100644 index 8c8379f..0000000 --- a/tests/qc_app/test_results_page.py +++ /dev/null @@ -1,68 +0,0 @@ -"Test results page" - -def test_results_with_stderr_output( - client, job_id, stderr_with_output, # pylint: disable=[unused-argument] - redis_conn_with_in_progress_job_no_errors): # pylint: disable=[unused-argument] - """ - GIVEN: 1. A flask application testing client - 2. A file with content to simulate the stderr output - 3. A sample job to prevent the "No such job" error message - WHEN: The parsing progress page is loaded for a non existing job - THEN: Ensure that the page: - 1. Redirects to a job failure display page - 2. The job failure display page: - a) indicates that this is a worker failure - b) provides some debugging information - """ - # Maybe get rid of the use of a stderr file, and check for actual exceptions - resp = client.get(f"/parse/status/{job_id}", follow_redirects=True) - assert len(resp.history) == 1 - assert b'

Worker Failure

' in resp.data - assert b'

Debugging Information

' in resp.data - assert ( - f"
  • job id: {job_id}
  • ".encode("utf8") - in resp.data) - -def test_results_with_completed_job_no_errors( - client, job_id, stderr_with_no_output, # pylint: disable=[unused-argument] - redis_conn_with_completed_job_no_errors): # pylint: disable=[unused-argument] - """ - GIVEN: 1. A flask application testing client - 2. A redis instance with a completed job, with no errors found in - the file - 3. A file with no contents to simulate no stderr output - WHEN: The parsing progress page is loaded - THEN: Ensure that: - 1. the system redirects to the results page - 2. the results page indicates that there are no errors in the file - being processed - """ - resp = client.get(f"/parse/status/{job_id}", follow_redirects=True) - assert len(resp.history) == 1 - assert ( - b'No errors found in the file' - in resp.data) - -def test_results_with_completed_job_some_errors( - client, job_id, stderr_with_no_output, # pylint: disable=[unused-argument] - redis_conn_with_completed_job_some_errors): # pylint: disable=[unused-argument] - """ - GIVEN: 1. A flask application testing client - 2. A redis instance with a completed job, with some errors found in - the file - 3. A file with no contents to simulate no stderr output - WHEN: The parsing progress page is loaded - THEN: Ensure that: - 1. the system redirects to the results page - 2. the results page displays the errors found - """ - resp = client.get(f"/parse/status/{job_id}", follow_redirects=True) - assert len(resp.history) == 1 - assert ( - b'

    We found the following errors

    ' - in resp.data) - assert b'' in resp.data - assert b'Duplicate Header' in resp.data - assert b'' in resp.data - assert b'Invalid Value' in resp.data - assert b'' in resp.data diff --git a/tests/qc_app/test_uploads_with_zip_files.py b/tests/qc_app/test_uploads_with_zip_files.py deleted file mode 100644 index 1506cfa..0000000 --- a/tests/qc_app/test_uploads_with_zip_files.py +++ /dev/null @@ -1,84 +0,0 @@ -"""Test the upload of zip files""" -from tests.conftest import uploadable_file_object - -def test_upload_zipfile_with_zero_files(client): - """ - GIVEN: A flask application testing client - WHEN: A zip file with no files is uploaded - THEN: Ensure that the system responds with the appropriate error message and - status code - """ - resp = client.post("/upload", - data={ - "filetype": "average", - "qc_text_file": uploadable_file_object("empty.zip")}, - follow_redirects=True) - assert len(resp.history) == 1 - redirect = resp.history[0] - assert redirect.status_code == 302 - assert redirect.location == "/upload" - - assert resp.status_code == 200 - assert (b"Expected exactly one (1) member file within the uploaded zip " - b"file. Got 0 member files.") in resp.data - -def test_upload_zipfile_with_multiple_files(client): - """ - GIVEN: A flask application testing client - WHEN: A zip file with more than one file is uploaded - THEN: Ensure that the system responds with the appropriate error message and - status code - """ - resp = client.post( - "/upload", - data={ - "filetype": "average", - "qc_text_file": uploadable_file_object("multiple_files.zip")}, - follow_redirects=True) - assert len(resp.history) == 1 - redirect = resp.history[0] - assert redirect.status_code == 302 - assert redirect.location == "/upload" - - assert resp.status_code == 200 - assert (b"Expected exactly one (1) member file within the uploaded zip " - b"file. Got 3 member files.") in resp.data - -def test_upload_zipfile_with_one_tsv_file(client): - """ - GIVEN: A flask application testing client - WHEN: A zip file with exactly one valid TSV file is uploaded - THEN: Ensure that the system redirects to the correct next URL - """ - resp = client.post("/upload", data={ - "speciesid": 1, - "filetype": "average", - "qc_text_file": uploadable_file_object("average.tsv.zip")}) - assert resp.status_code == 302 - assert b"Redirecting..." in resp.data - assert ( - b"/parse/parse?speciesid=1&filename=average.tsv.zip&filetype=average" - in resp.data) - -def test_upload_zipfile_with_one_non_tsv_file(client): - """ - GIVEN: A flask application testing client - WHEN: A zip file with exactly one file, which is not a valid TSV, is - uploaded - THEN: Ensure that the system responds with the appropriate error message and - status code - """ - resp = client.post( - "/upload", - data={ - "filetype": "average", - "qc_text_file": uploadable_file_object("non_tsv.zip")}, - follow_redirects=True) - assert len(resp.history) == 1 - redirect = resp.history[0] - assert redirect.status_code == 302 - assert redirect.location == "/upload" - - assert resp.status_code == 200 - assert (b"Expected the member text file in the uploaded zip file to " - b"be a tab-separated file.") in resp.data diff --git a/tests/uploader/__init__.py b/tests/uploader/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/uploader/test_entry.py b/tests/uploader/test_entry.py new file mode 100644 index 0000000..0c614a5 --- /dev/null +++ b/tests/uploader/test_entry.py @@ -0,0 +1,43 @@ +"""Test the entry module in the web-ui""" +import pytest + +@pytest.mark.parametrize( + "dataitem,lower", + ( + # expression data UI elements + (b'

    expression data

    ', True), + (b'', False), + + # samples/cases data UI elements + (b'

    samples/cases

    ', True), + (b'
    r/qtl2 bundles', True), + (b'405: The method is not allowed for the requested URL.' + in resp.data) diff --git a/tests/uploader/test_expression_data_pages.py b/tests/uploader/test_expression_data_pages.py new file mode 100644 index 0000000..c2f7de1 --- /dev/null +++ b/tests/uploader/test_expression_data_pages.py @@ -0,0 +1,92 @@ +"""Test expression data path""" +import pytest + +from tests.conftest import uploadable_file_object + +def test_basic_elements_present_in_index_page(client): + """ + GIVEN: A flask application testing client + WHEN: the index page is requested with the "GET" method and no data + THEN: verify that the response contains error notifications + """ + response = client.get("/upload") + assert response.status_code == 200 + ## form present + assert b'' in response.data + ## filetype elements + assert b'non-existent-job-id' was found!" + in resp.data) + assert b'' in resp.data + +def test_with_unstarted_job(client, job_id, redis_conn_with_fresh_job): # pylint: disable=[unused-argument] + """ + GIVEN: 1. A flask application testing client + 2. A redis instance with a fresh, unstarted job + WHEN: The parsing progress page is loaded + THEN: Ensure that the page: + 1. Has a meta tag to refresh it after 5 seconds + 2. Has a progress indicator with zero progress + """ + resp = client.get(f"/parse/status/{job_id}") + assert b'' in resp.data + assert ( + b'' in resp.data + +def test_with_in_progress_no_error_job( + client, job_id, redis_conn_with_in_progress_job_no_errors): # pylint: disable=[unused-argument] + """ + GIVEN: 1. A flask application testing client + 2. A redis instance with a job in progress, with no errors found in + the file so far + WHEN: The parsing progress page is loaded + THEN: Ensure that the page: + 1. Has a meta tag to refresh it after 5 seconds + 2. Has a progress indicator with the percent of the file processed + indicated + """ + resp = client.get(f"/parse/status/{job_id}") + assert b'' in resp.data + assert ( + b'' in resp.data + assert ( + b'No errors found so far' + in resp.data) + assert b"' in resp.data + assert ( + b'' in resp.data + assert ( + b'

    We have found the following errors so far

    ' + in resp.data) + assert b'table class="table reports-table">' in resp.data + assert b'Duplicate Header' in resp.data + assert b'Invalid Value' in resp.data + +def test_with_completed_job_no_errors( + client, job_id, redis_conn_with_completed_job_no_errors): # pylint: disable=[unused-argument] + """ + GIVEN: 1. A flask application testing client + 2. A redis instance with a completed job, with no errors found in + the file so far + WHEN: The parsing progress page is loaded + THEN: Ensure that the response is a redirection to the results page + """ + resp = client.get(f"/parse/status/{job_id}") + assert resp.status_code == 302 + assert f"/parse/results/{job_id}".encode("utf8") in resp.data + +def test_with_completed_job_some_errors( + client, job_id, redis_conn_with_completed_job_no_errors): # pylint: disable=[unused-argument] + """ + GIVEN: 1. A flask application testing client + 2. A redis instance with a completed job, with some errors found in + the file so far + WHEN: The parsing progress page is loaded + THEN: Ensure that the response is a redirection to the results page + """ + resp = client.get(f"/parse/status/{job_id}") + assert resp.status_code == 302 + assert f"/parse/results/{job_id}".encode("utf8") in resp.data diff --git a/tests/uploader/test_results_page.py b/tests/uploader/test_results_page.py new file mode 100644 index 0000000..8c8379f --- /dev/null +++ b/tests/uploader/test_results_page.py @@ -0,0 +1,68 @@ +"Test results page" + +def test_results_with_stderr_output( + client, job_id, stderr_with_output, # pylint: disable=[unused-argument] + redis_conn_with_in_progress_job_no_errors): # pylint: disable=[unused-argument] + """ + GIVEN: 1. A flask application testing client + 2. A file with content to simulate the stderr output + 3. A sample job to prevent the "No such job" error message + WHEN: The parsing progress page is loaded for a non existing job + THEN: Ensure that the page: + 1. Redirects to a job failure display page + 2. The job failure display page: + a) indicates that this is a worker failure + b) provides some debugging information + """ + # Maybe get rid of the use of a stderr file, and check for actual exceptions + resp = client.get(f"/parse/status/{job_id}", follow_redirects=True) + assert len(resp.history) == 1 + assert b'

    Worker Failure

    ' in resp.data + assert b'

    Debugging Information

    ' in resp.data + assert ( + f"
  • job id: {job_id}
  • ".encode("utf8") + in resp.data) + +def test_results_with_completed_job_no_errors( + client, job_id, stderr_with_no_output, # pylint: disable=[unused-argument] + redis_conn_with_completed_job_no_errors): # pylint: disable=[unused-argument] + """ + GIVEN: 1. A flask application testing client + 2. A redis instance with a completed job, with no errors found in + the file + 3. A file with no contents to simulate no stderr output + WHEN: The parsing progress page is loaded + THEN: Ensure that: + 1. the system redirects to the results page + 2. the results page indicates that there are no errors in the file + being processed + """ + resp = client.get(f"/parse/status/{job_id}", follow_redirects=True) + assert len(resp.history) == 1 + assert ( + b'No errors found in the file' + in resp.data) + +def test_results_with_completed_job_some_errors( + client, job_id, stderr_with_no_output, # pylint: disable=[unused-argument] + redis_conn_with_completed_job_some_errors): # pylint: disable=[unused-argument] + """ + GIVEN: 1. A flask application testing client + 2. A redis instance with a completed job, with some errors found in + the file + 3. A file with no contents to simulate no stderr output + WHEN: The parsing progress page is loaded + THEN: Ensure that: + 1. the system redirects to the results page + 2. the results page displays the errors found + """ + resp = client.get(f"/parse/status/{job_id}", follow_redirects=True) + assert len(resp.history) == 1 + assert ( + b'

    We found the following errors

    ' + in resp.data) + assert b'
    Heading 'DupHead' is repeatedInvalid value 'ohMy'
    ' in resp.data + assert b'Duplicate Header' in resp.data + assert b'' in resp.data + assert b'Invalid Value' in resp.data + assert b'' in resp.data diff --git a/tests/uploader/test_uploads_with_zip_files.py b/tests/uploader/test_uploads_with_zip_files.py new file mode 100644 index 0000000..1506cfa --- /dev/null +++ b/tests/uploader/test_uploads_with_zip_files.py @@ -0,0 +1,84 @@ +"""Test the upload of zip files""" +from tests.conftest import uploadable_file_object + +def test_upload_zipfile_with_zero_files(client): + """ + GIVEN: A flask application testing client + WHEN: A zip file with no files is uploaded + THEN: Ensure that the system responds with the appropriate error message and + status code + """ + resp = client.post("/upload", + data={ + "filetype": "average", + "qc_text_file": uploadable_file_object("empty.zip")}, + follow_redirects=True) + assert len(resp.history) == 1 + redirect = resp.history[0] + assert redirect.status_code == 302 + assert redirect.location == "/upload" + + assert resp.status_code == 200 + assert (b"Expected exactly one (1) member file within the uploaded zip " + b"file. Got 0 member files.") in resp.data + +def test_upload_zipfile_with_multiple_files(client): + """ + GIVEN: A flask application testing client + WHEN: A zip file with more than one file is uploaded + THEN: Ensure that the system responds with the appropriate error message and + status code + """ + resp = client.post( + "/upload", + data={ + "filetype": "average", + "qc_text_file": uploadable_file_object("multiple_files.zip")}, + follow_redirects=True) + assert len(resp.history) == 1 + redirect = resp.history[0] + assert redirect.status_code == 302 + assert redirect.location == "/upload" + + assert resp.status_code == 200 + assert (b"Expected exactly one (1) member file within the uploaded zip " + b"file. Got 3 member files.") in resp.data + +def test_upload_zipfile_with_one_tsv_file(client): + """ + GIVEN: A flask application testing client + WHEN: A zip file with exactly one valid TSV file is uploaded + THEN: Ensure that the system redirects to the correct next URL + """ + resp = client.post("/upload", data={ + "speciesid": 1, + "filetype": "average", + "qc_text_file": uploadable_file_object("average.tsv.zip")}) + assert resp.status_code == 302 + assert b"Redirecting..." in resp.data + assert ( + b"/parse/parse?speciesid=1&filename=average.tsv.zip&filetype=average" + in resp.data) + +def test_upload_zipfile_with_one_non_tsv_file(client): + """ + GIVEN: A flask application testing client + WHEN: A zip file with exactly one file, which is not a valid TSV, is + uploaded + THEN: Ensure that the system responds with the appropriate error message and + status code + """ + resp = client.post( + "/upload", + data={ + "filetype": "average", + "qc_text_file": uploadable_file_object("non_tsv.zip")}, + follow_redirects=True) + assert len(resp.history) == 1 + redirect = resp.history[0] + assert redirect.status_code == 302 + assert redirect.location == "/upload" + + assert resp.status_code == 200 + assert (b"Expected the member text file in the uploaded zip file to " + b"be a tab-separated file.") in resp.data -- cgit v1.2.3
    Heading 'DupHead' is repeatedInvalid value 'ohMy'