aboutsummaryrefslogtreecommitdiff
"""Test the 'parse' module in the web-ui"""
import sys

import redis
import pytest

from qc_app.jobs import job, jobsnamespace

from tests.conftest import uploadable_file_object

def test_parse_with_existing_uploaded_file(#pylint: disable=[too-many-arguments]
        client,
        db_url,
        redis_url,
        redis_ttl,
        jobs_prefix,
        job_id,
        monkeypatch):
    """
    GIVEN: 1. A flask application testing client
           2. A valid file, and filetype
    WHEN: The file is uploaded, and the parsing triggered
    THEN: Ensure that:
          1. the system redirects to the job/parse status page
          2. the job is placed on redis for processing
    """
    monkeypatch.setattr("qc_app.jobs.uuid4", lambda : job_id)
    # Upload a file
    speciesid = 1
    filename = "no_data_errors.tsv"
    filetype = "average"
    client.post(
        "/upload", data={
            "speciesid": speciesid,
            "filetype": filetype,
            "qc_text_file": uploadable_file_object(filename)})
    # Checks
    resp = client.get(f"/parse/parse?speciesid={speciesid}&filename={filename}"
                      f"&filetype={filetype}")
    assert resp.status_code == 302
    assert b'Redirecting...' in resp.data
    assert b'/parse/status/934c55d8-396e-4959-90e1-2698e9205758' in resp.data

    with redis.Redis.from_url(redis_url, decode_responses=True) as rconn:
        the_job = job(rconn, jobsnamespace(), job_id)

    assert the_job["jobid"] == job_id
    assert the_job["filename"] == filename
    assert the_job["command"] == " ".join([
        sys.executable, "-m", "scripts.validate_file", db_url, redis_url,
        jobs_prefix, job_id, "--redisexpiry", str(redis_ttl), str(speciesid),
        filetype, f"{client.application.config['UPLOAD_FOLDER']}/{filename}"])

@pytest.mark.parametrize(
    "filename,uri,error_msgs",
    (("non_existent.file",
      "/parse/parse?filename=non_existent.file&filename=average",
      [b'Selected file does not exist (any longer)']),
     ("non_existent.file",
      "/parse/parse?filename=non_existent.file&filename=standard-error",
      [b'Selected file does not exist (any longer)']),
     ("non_existent.file",
      "/parse/parse?filename=non_existent.file&filename=percival",
      [b'Selected file does not exist (any longer)',
       b'Invalid filetype provided']),
     ("no_data_errors.tsv",
      "/parse/parse?filename=no_data_errors.tsv&filename=percival",
      [b'Invalid filetype provided']),
     ("no_data_errors.tsv",
      "/parse/parse?filename=no_data_errors.tsv",
      [b'No filetype provided']),
     (None, "/parse/parse", [b'No file provided', b'No filetype provided'])))
def test_parse_with_non_uploaded_file(client, filename, uri, error_msgs):
    """
    GIVEN: 1. A flask application testing client
           2. A valid filetype
           3. A filename to a file that has not been uploaded yet
    WHEN: The parsing triggered
    THEN: Ensure that the appropriate errors are displayed
    """
    ## Conditionally upload files
    if filename and filename != "non_existent.file":
        client.post(
        "/upload", data={
            "filetype": "average",
            "qc_text_file": uploadable_file_object(filename)})
    # Trigger
    resp = client.get(uri,follow_redirects=True)
    ## Check that there was exactly one redirect
    assert len(resp.history) == 1 and resp.history[0].status_code == 302
    ## Check that redirect is to home page and is successful
    assert resp.request.path == "/upload"
    assert resp.status_code == 200
    ## Check that error(s) are displayed
    for error_msg in error_msgs:
        assert error_msg in resp.data