def test_export_status(mock_env_access_key, client): # pylint: disable=unused-argument """ test the export status endpoint """ # clear up entries in db finish_submissions_exports() # no export id response = client.simulate_get('/export/status') assert response.status_code == 500 # nonexisting export id guid = uuid.uuid4() response = client.simulate_get('/export/status?export_id=' + str(guid)) assert response.status_code == 500 # invalid export id response = client.simulate_get('/export/status?export_id=123') assert response.status_code == 500 # export in progress export_obj = create_export(db, BLUEBEAM_USERNAME) response = client.simulate_get('/export/status?export_id=' + str(export_obj.guid)) assert response.status_code == 200 response_json = json.loads(response.text) assert not response_json['data']['is_finished'] # clear out the queue queue.control.purge()
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 finish_submissions_exports(): """ sets the date_exported on all existing submissions and date_finished on all export_status in the database """ export_obj = create_export(db, BLUEBEAM_USERNAME) with db_engine.connect() as con: sql = "UPDATE submission SET date_exported=now() at time zone 'utc', " +\ "export_guid='" + str(export_obj.guid) + "' " +\ "WHERE date_exported IS NULL" con.execute(sql) sql = "UPDATE export_status set date_finished=now() at time zone 'utc' " +\ "WHERE date_finished IS NULL" con.execute(sql)
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 on_get(self, _req, resp): """ handle export get requests """ resp.content_type = falcon.MEDIA_HTML if 'code' in _req.params: # handle redirect back from auth server export_obj = None try: # convert auth code to access token redirect_uri = self.create_redirect_url( _req.forwarded_scheme, _req.forwarded_host, _req.port) access_response = bluebeam.get_access_token_response( _req.params['code'], redirect_uri) # happy path # show spinner ui which will poll for export status export_obj = create_export(self.session, access_response['userName']) # pylint: disable=no-member resp.status = falcon.HTTP_200 template = Template(filename='templates/exporting.html') resp.body = template.render(export_id=export_obj.guid) bluebeam_export.apply_async( (export_obj, access_response['access_token']), serializer='pickle', ) except Exception as err: # pylint: disable=broad-except # error in scheduling err_string = "{0}".format(err) # finish this export if export_obj is not None: export_obj.date_finished = datetime.utcnow() export_obj.result = err_string self.session.commit() # pylint: disable=no-member # present error ui print("error:") print(err_string) resp.status = falcon.HTTP_500 template = Template(filename='templates/exporting_error.html') resp.body = template.render(error_message=err_string) else: resp.status = falcon.HTTP_200 # is there an export in progress? exports = self.session.query(ExportStatusModel).filter( # pylint: disable=no-member ExportStatusModel.date_finished.is_(None)) if exports.count() == 0: # is there something to export? submissions = self.session.query(SubmissionModel).filter( # pylint: disable=no-member SubmissionModel.date_exported.is_(None)) if submissions.count() > 0: # present ui to redirect to bluebeam for auth bluebeam_auth_url = create_url( bluebeam.BLUEBEAM_AUTHSERVER, bluebeam.BLUEBEAM_AUTH_PATH, { 'response_type': 'code', 'client_id': bluebeam.BLUEBEAM_CLIENT_ID, 'scope': 'full_user', 'redirect_uri': self.create_redirect_url(_req.forwarded_scheme, _req.forwarded_host, _req.port) }) template = Template(filename='templates/export.html') resp.body = template.render( bluebeam_auth_url=bluebeam_auth_url) else: # nothing to export template = Template( filename='templates/nothing_to_export.html') resp.body = template.render() else: export_obj = exports.first() template = Template(filename='templates/exporting.html') resp.body = template.render(export_id=export_obj.guid)