def test_export_task_resubmission_no_project(mock_env_access_key):
    # pylint: disable=unused-argument
    """Test the export resubmission task but project isn't found in bluebeam"""
    # don't include previous submission
    finish_submissions_exports()
    # create a resubmission so there's something to export
    create_submission(db, mocks.RESUBMISSION_POST_DATA)
    # create the export
    export_obj = create_export(db, BLUEBEAM_USERNAME)
    # mock all responses for expected requests
    with patch('service.resources.bluebeam.requests.request') as mock_reqs:
        fake_responses = []
        # project exists
        fake_responses.append(Mock())
        fake_responses[0].status_code = 404

        mock_reqs.side_effect = fake_responses

        bluebeam_export.s(export_obj=export_obj,
                          access_code=BLUEBEAM_ACCESS_CODE).apply()

        db.refresh(export_obj)

        assert export_obj.date_finished is not None
        assert len(export_obj.result['success']) == 0
        assert len(export_obj.result['failure']) > 0

    # clear out the queue
    queue.control.purge()
def test_export_task_new_project(mock_env_access_key):
    # pylint: disable=unused-argument
    """Test the export task"""
    # don't include previous submission
    finish_submissions_exports()
    # create a submission so there's something to export
    data = mocks.SUBMISSION_POST_DATA.copy()
    data['logger'] = mocks.LOGGER_PARAMETERS.copy()
    data['_id'] = "123"
    create_submission(db, data)
    # create the export
    export_obj = create_export(db, BLUEBEAM_USERNAME)
    # mock all responses for expected requests
    with patch('service.resources.bluebeam.requests.request') as mock_post:
        fake_post_responses = []
        # create project
        fake_post_responses.append(Mock())
        fake_post_responses[
            0].json.return_value = mocks.CREATE_PROJECT_RESPONSE
        fake_post_responses[0].status_code = 200
        # create folders
        i = 1
        while i < 7:
            fake_post_responses.append(Mock())
            fake_post_responses[
                i].json.return_value = mocks.CREATE_FOLDER_RESPONSE
            i += 1
        # get folders
        fake_post_responses.append(Mock())
        fake_post_responses[7].json.return_value = mocks.GET_FOLDERS_RESPONSE
        # create folders
        fake_post_responses.append(Mock())
        fake_post_responses[8].json.return_value = mocks.CREATE_FOLDER_RESPONSE
        # initiate upload
        fake_post_responses.append(Mock())
        fake_post_responses[
            9].json.return_value = mocks.INIT_FILE_UPLOAD_RESPONSE
        # upload
        fake_post_responses.append(Mock())
        fake_post_responses[10].return_value.status_code = 200
        # confirm upload
        fake_post_responses.append(Mock())
        fake_post_responses[11].status_code = 204

        mock_post.side_effect = fake_post_responses

        with patch('tasks.requests.patch') as mock_patch:
            mock_patch.status_code = 200

            bluebeam_export.s(export_obj=export_obj,
                              access_code=BLUEBEAM_ACCESS_CODE).apply()

            db.refresh(export_obj)

        assert export_obj.date_finished is not None
        assert len(export_obj.result['success']) > 0
        assert len(export_obj.result['failure']) == 0

    # clear out the queue
    queue.control.purge()
def test_export_task_resubmission_log_status_error(mock_env_access_key):
    # pylint: disable=unused-argument
    """Test the export resubmission task with an error when logging status"""
    # don't include previous submission
    finish_submissions_exports()
    # create a resubmission so there's something to export
    data = mocks.RESUBMISSION_POST_DATA.copy()
    data['logger'] = mocks.LOGGER_PARAMETERS.copy()
    data['_id'] = "123"
    create_submission(db, data)

    # create the export
    export_obj = create_export(db, BLUEBEAM_USERNAME)
    # mock all responses for expected requests
    with patch('service.resources.bluebeam.requests.request') as mock_reqs:
        fake_responses = []
        # project exists
        fake_responses.append(Mock())
        fake_responses[0].status_code = 200
        # get folders
        fake_responses.append(Mock())
        fake_responses[1].json.return_value = mocks.GET_FOLDERS_RESPONSE
        # get folders
        fake_responses.append(Mock())
        fake_responses[2].json.return_value = mocks.GET_FOLDERS_RESPONSE
        # create folders
        fake_responses.append(Mock())
        fake_responses[3].json.return_value = mocks.CREATE_FOLDER_RESPONSE
        # initiate upload
        fake_responses.append(Mock())
        fake_responses[4].json.return_value = mocks.INIT_FILE_UPLOAD_RESPONSE
        # upload
        fake_responses.append(Mock())
        fake_responses[5].return_value.status_code = 200
        # confirm upload
        fake_responses.append(Mock())
        fake_responses[6].status_code = 204

        mock_reqs.side_effect = fake_responses

        with patch('tasks.requests.patch') as mock_patch:
            mock_patch.side_effect = Exception("Patch error")

            bluebeam_export.s(export_obj=export_obj,
                              access_code=BLUEBEAM_ACCESS_CODE).apply()

            db.refresh(export_obj)

        assert len(export_obj.result['failure']) > 0

    # clear out the queue
    queue.control.purge()
def test_export_task_no_upload_folder(mock_env_access_key):
    # pylint: disable=unused-argument
    """Test the export task when there is no dir set as the uploads dir"""
    # don't include previous submission
    finish_submissions_exports()
    # create a submission so there's something to export
    create_submission(db, mocks.SUBMISSION_POST_DATA)
    # create the export
    export_obj = create_export(db, BLUEBEAM_USERNAME)
    # mock all responses for expected outbound requests
    with patch('service.resources.bluebeam.requests.request') as mock_post:
        fake_post_responses = []
        # create project
        fake_post_responses.append(Mock())
        fake_post_responses[
            0].json.return_value = mocks.CREATE_PROJECT_RESPONSE
        fake_post_responses[0].status_code = 200
        # create folders
        i = 1
        while i < 8:
            fake_post_responses.append(Mock())
            fake_post_responses[
                i].json.return_value = mocks.CREATE_FOLDER_RESPONSE
            i += 1
        # delete project
        fake_post_responses.append(Mock())
        fake_post_responses[8].status_code = 204

        mock_post.side_effect = fake_post_responses

        with patch('service.resources.bluebeam.DIRECTORY_STRUCTURE'
                   ) as mock_dir_structure:
            mock_dir_structure.return_value = [{"name": "CCSF EPR"}]

            bluebeam_export.s(export_obj=export_obj,
                              access_code=BLUEBEAM_ACCESS_CODE).apply()

            db.refresh(export_obj)
            assert export_obj.date_finished is not None
            assert len(export_obj.result['failure']) > 0
            assert export_obj.result['failure'][-1]['err'] == ERR_UPLOAD_FAIL

    # clear out the queue
    queue.control.purge()
def test_export_task_resubmission_no_upload_dir(mock_env_access_key):
    # pylint: disable=unused-argument
    """
        Test the export resubmission task when cannot find upload dir
        in preexisting bluebeam project
    """
    # don't include previous submission
    finish_submissions_exports()
    # create a resubmission so there's something to export
    create_submission(db, mocks.RESUBMISSION_POST_DATA)
    # create the export
    export_obj = create_export(db, BLUEBEAM_USERNAME)
    # mock all responses for expected requests
    with patch('service.resources.bluebeam.requests.request') as mock_reqs:
        fake_responses = []
        # project exists
        fake_responses.append(Mock())
        fake_responses[0].status_code = 200
        # get folders
        fake_responses.append(Mock())
        fake_responses[
            1].json.return_value = mocks.GET_FOLDERS_RESPONSE_NO_UPLOAD

        mock_reqs.side_effect = fake_responses

        bluebeam_export.s(export_obj=export_obj,
                          access_code=BLUEBEAM_ACCESS_CODE).apply()

        db.refresh(export_obj)

        assert export_obj.date_finished is not None
        assert len(export_obj.result['success']) == 0
        assert len(export_obj.result['failure']) > 0

    # clear out the queue
    queue.control.purge()
def test_export(mock_env_access_key, client):
    # pylint: disable=unused-argument
    """
        tests the export ui
    """
    # clear up entries in db
    finish_submissions_exports()

    # Nothing to export
    response = client.simulate_get('/export')
    assert response.status_code == 200
    assert 'No records to export today' in response.text

    # Submissions exist to export
    create_submission(db, mocks.SUBMISSION_POST_DATA)
    response = client.simulate_get('/export')
    assert response.status_code == 200
    assert 'Export form submissions to Bluebeam' in response.text

    # Redirect back from authserver with invalid grant
    with patch(
            'service.resources.bluebeam.requests.request') as mock_auth_post:
        mock_auth_post.return_value.json.return_value = mocks.INVALID_GRANT_RESPONSE

        response = client.simulate_get('/export?code=super-secrete-code')
        assert response.status_code == 500
        assert 'Export Error' in response.text

        exports_in_progress = db.query(ExportStatusModel).filter(
            ExportStatusModel.date_finished.is_(None))
        assert exports_in_progress.count() == 0

    # Error when scheduling with celery
    with patch(
            'service.resources.bluebeam.requests.request') as mock_auth_post:
        mock_auth_post.return_value.json.return_value = mocks.ACCESS_TOKEN_RESPONSE

        with patch('tasks.bluebeam_export.apply_async') as mock_schedule:
            mock_schedule.side_effect = Exception("Couldn't schedule")

            response = client.simulate_get('/export?code=schedule-error')
            assert response.status_code == 500
            assert 'Export Error' in response.text

            exports_in_progress = db.query(ExportStatusModel).filter(
                ExportStatusModel.date_finished.is_(None))
            assert exports_in_progress.count() == 0

    # Redirect back from authserver with valid code
    with patch(
            'service.resources.bluebeam.requests.request') as mock_auth_post:
        mock_auth_post.return_value.json.return_value = mocks.ACCESS_TOKEN_RESPONSE

        response = client.simulate_get('/export?code=super-secret-code')
        assert response.status_code == 200
        assert 'Exporting' in response.text

        exports_in_progress = db.query(ExportStatusModel).filter(
            ExportStatusModel.date_finished.is_(None))
        assert exports_in_progress.count() == 1

    # export already in progress
    response = client.simulate_get('/export')
    assert response.status_code == 200
    assert 'Exporting' in response.text

    # clear out the queue
    queue.control.purge()