def test_list_project_samples(mocker, credentials, project_id, recording, vcr):  # pylint: disable=unused-argument
    """Test project samples being outputed to the shell."""
    runner = CliRunner()

    if not recording:
        # Mock get_project_samples only if using the cassettes,
        # since we mock the return value.
        mocked_samples = get_vcr_response("/api/v2/project-samples/", vcr,
                                          operator.contains)
        mocked_get_project_samples = mocker.patch.object(
            APIClient,
            "get_project_samples",
            return_value=ProjectSamples(**mocked_samples),
        )
    res = runner.invoke(
        list_project_samples,
        [project_id, *credentials],
    )
    assert res.exit_code == 0
    if not recording:
        mocked_get_project_samples.assert_called_once()
        output_line = io.BytesIO()
        sys.stdout = output_line
        for mocked_sample in mocked_samples["results"]:
            mocked_sample = SampleDetails(**mocked_sample)
            echo_data("\t".join([
                str(mocked_sample.last_status.created.isoformat()),
                str(mocked_sample.id),
                mocked_sample.client_id,
                mocked_sample.last_status.status,
                mocked_sample.archive_last_status.status,
            ]))
        assert output_line.getvalue() == res.output.encode()
def test_download_stdout_no_flag(
    credentials, mocker, project_id_download, recording, vcr
):
    """Test command exits if no flag provided and stdout defined."""
    runner = CliRunner()
    if not recording:
        # Mock only if using the cassettes, since we mock the return value.
        get_project_samples_response = get_vcr_response(
            "/api/v2/project-samples/", vcr, operator.contains
        )
        mocked_project_samples = mocker.patch.object(
            APIClient,
            "get_project_samples",
            return_value=ProjectSamples(**get_project_samples_response),
        )
    res = runner.invoke(
        download,
        [
            "-",
            "--project-id",
            project_id_download,
            *credentials,
        ],
    )
    assert res.exit_code == 1
    output_line = io.BytesIO()
    sys.stdout = output_line
    echo("ERROR: Cannot have - as a destination without download-urls.")
    assert output_line.getvalue() in res.output.encode()
    if not recording:
        mocked_project_samples.assert_called_once()
def test_list_empty(mocker, credentials, project_id):
    """Test project has no samples."""
    runner = CliRunner()
    mocked_get_project_samples = mocker.patch.object(
        APIClient,
        "get_project_samples",
        return_value=ProjectSamples(results=[], meta=dict(next=None)),
    )
    res = runner.invoke(
        list_project_samples,
        [project_id, *credentials],
    )
    assert res.exit_code == 0
    mocked_get_project_samples.assert_called_once()
    assert res.output == ""
def test_download_urls_to_file(
    credentials, mocker, project_id_download, recording, vcr
):
    """Test saving downloaded urls output to a json file."""
    runner = CliRunner()
    if not recording:
        # Mock only if using the cassettes, since we mock the return value.
        get_project_samples_response = get_vcr_response(
            "/api/v2/project-samples/", vcr, operator.contains
        )
        mocked_project_samples = mocker.patch.object(
            APIClient,
            "get_project_samples",
            return_value=ProjectSamples(**get_project_samples_response),
        )
        get_sample_details_response = get_vcr_response(
            "/api/v2/samples/", vcr, operator.contains
        )
        sample = SampleDetails(**get_sample_details_response)
        mocked_sample_details = mocker.patch.object(
            APIClient,
            "get_sample_details",
            return_value=sample,
        )
    mocked_output_list = mocker.patch(
        "gencove.command.download.main.Download.output_list"
    )
    with runner.isolated_filesystem():
        res = runner.invoke(
            download,
            [
                "output.json",
                "--project-id",
                project_id_download,
                *credentials,
                "--download-urls",
            ],
        )
        assert res.exit_code == 0
        mocked_output_list.assert_called_once()
        if not recording:
            mocked_project_samples.assert_called_once()
            mocked_sample_details.assert_called_once()
def test_project_id_provided_filter_not_archived(credentials, mocker):
    """Check happy flow."""
    runner = CliRunner()
    with runner.isolated_filesystem():
        mocked_project_samples = mocker.patch.object(
            APIClient,
            "get_project_samples",
            return_value=ProjectSamples(
                **{"results": [], "meta": {"next": None}}
            ),
        )
        mocked_sample_details = mocker.patch.object(
            APIClient, "get_sample_details"
        )
        mocked_qc_metrics = mocker.patch.object(
            APIClient, "get_sample_qc_metrics"
        )
        mocked_get_metadata = mocker.patch.object(APIClient, "get_metadata")
        mocked_download_file = mocker.patch(
            "gencove.command.download.main.download_file"
        )
        res = runner.invoke(
            download,
            [
                "cli_test_data",
                "--project-id",
                "123",
                *credentials,
            ],
        )
        assert res.exit_code == 1
        mocked_project_samples.assert_called_once()
        mocked_qc_metrics.assert_not_called()
        mocked_get_metadata.assert_not_called()
        mocked_download_file.assert_not_called()
        mocked_sample_details.assert_not_called()
def test_project_id_provided_skip_existing_qc_and_metadata(
    credentials, mocker, project_id_download, recording, vcr
):
    """Check happy flow."""
    # pylint: disable=too-many-locals
    runner = CliRunner()
    with runner.isolated_filesystem():
        if not recording:
            # Mock only if using the cassettes, since we mock the return value.
            get_project_samples_response = get_vcr_response(
                "/api/v2/project-samples/", vcr, operator.contains
            )
            mocked_project_samples = mocker.patch.object(
                APIClient,
                "get_project_samples",
                return_value=ProjectSamples(**get_project_samples_response),
            )
            get_sample_details_response = get_vcr_response(
                "/api/v2/samples/", vcr, operator.contains
            )
            mocked_sample_details = mocker.patch.object(
                APIClient,
                "get_sample_details",
                return_value=SampleDetails(**get_sample_details_response),
            )
            get_sample_qc_metrics_response = get_vcr_response(
                "/api/v2/sample-quality-controls/", vcr, operator.contains
            )
            mocked_qc_metrics = mocker.patch.object(
                APIClient,
                "get_sample_qc_metrics",
                return_value=SampleQC(**get_sample_qc_metrics_response),
            )
            get_metadata_response = get_vcr_response(
                "/api/v2/sample-metadata/", vcr, operator.contains
            )
            mocked_get_metadata = mocker.patch.object(
                APIClient,
                "get_metadata",
                return_value=SampleMetadata(**get_metadata_response),
            )
        mocked_download_file = mocker.patch(
            "gencove.command.download.main.download_file",
            side_effect=download_file,
        )
        res = runner.invoke(
            download,
            [
                "cli_test_data",
                "--project-id",
                project_id_download,
                *credentials,
                "--no-skip-existing",
            ],
        )
        assert res.exit_code == 0
        if not recording:
            mocked_project_samples.assert_called_once()
            mocked_sample_details.assert_called_once()
            mocked_qc_metrics.assert_called_once()
            mocked_get_metadata.assert_called_once()
        mocked_download_file.assert_called_once()

        # call it the second time
        mocked_qc_metrics = mocker.patch.object(
            APIClient, "get_sample_qc_metrics"
        )
        mocked_get_metadata = mocker.patch.object(APIClient, "get_metadata")
        res = runner.invoke(
            download,
            [
                "cli_test_data",
                "--project-id",
                project_id_download,
                *credentials,
                "--skip-existing",
            ],
        )
        assert res.exit_code == 0
        mocked_qc_metrics.assert_not_called()
        mocked_get_metadata.assert_not_called()
def test_download_stdout_with_flag(
    credentials, mocker, project_id_download, recording, vcr
):
    """Test command outputs json to stdout."""
    # pylint: disable=too-many-locals
    runner = CliRunner()
    if not recording:
        # Mock only if using the cassettes, since we mock the return value.
        get_project_samples_response = get_vcr_response(
            "/api/v2/project-samples/", vcr, operator.contains
        )
        mocked_project_samples = mocker.patch.object(
            APIClient,
            "get_project_samples",
            return_value=ProjectSamples(**get_project_samples_response),
        )
        get_sample_details_response = get_vcr_response(
            "/api/v2/samples/", vcr, operator.contains
        )
        sample = SampleDetails(**get_sample_details_response)
        mocked_sample_details = mocker.patch.object(
            APIClient,
            "get_sample_details",
            return_value=sample,
        )
    res = runner.invoke(
        download,
        [
            "-",
            "--project-id",
            project_id_download,
            *credentials,
            "--download-urls",
        ],
    )
    assert res.exit_code == 0
    if not recording:
        mocked_project_samples.assert_called_once()
        mocked_sample_details.assert_called_once()
        output_line = io.BytesIO()
        sys.stdout = output_line
        for _ in get_project_samples_response["results"]:
            archive_last_status_created = (
                sample.archive_last_status.created.isoformat()
            )
            download_url = "https://example.com/r1.fastq.gz"
            mocked_result = json.dumps(
                [
                    {
                        "gencove_id": MOCK_UUID,
                        "client_id": "mock_client_id",
                        "last_status": {
                            "id": MOCK_UUID,
                            "status": sample.last_status.status,
                            "created": sample.last_status.created.isoformat(),
                        },
                        "archive_last_status": {
                            "id": MOCK_UUID,
                            "status": sample.archive_last_status.status,
                            "created": archive_last_status_created,
                            "transition_cutoff": None,
                        },
                        "files": {
                            "fastq-r1": {
                                "id": MOCK_UUID,
                                "download_url": download_url,
                            }
                        },
                    }
                ],
                indent=4,
            )
            echo(mocked_result)
        assert output_line.getvalue() in res.output.encode()