def test_search_invalid(session, desc, json_data, search_id, has_history, statement_type): """Assert that search detail results on invalid requests returns the expected result.""" # test with pytest.raises(BusinessException) as bad_request_err: SearchResult.validate_search_select(json_data, search_id) # check assert bad_request_err assert bad_request_err.value.status_code == HTTPStatus.BAD_REQUEST print(bad_request_err.value.error)
def test_search_id_date_invalid(session, client, jwt): """Assert that finding by search ID with a date check on an old date works as expected.""" # no setup # test with pytest.raises(BusinessException) as bad_request_err: SearchResult.find_by_search_id(200000006, True) # check assert bad_request_err assert bad_request_err.value.status_code == HTTPStatus.BAD_REQUEST print(bad_request_err.value.error)
def test_search_detail_full_create(session, client, jwt): """Assert that submitting a new search and selecting the detail results works as expected.""" # setup json_data = { 'type': 'SERIAL_NUMBER', 'criteria': { 'value': 'JU622994' }, 'clientReferenceId': 'T-SR-SS-1001' } search_query = SearchClient.create_from_json(json_data, 'PS12345') # test search_query.search() query_json = search_query.json # print(query_json) search_detail = SearchResult.create_from_search_query(search_query) search_detail.save() # check assert search_detail.search_id == search_query.search_id assert not search_detail.search_select assert search_detail.exact_match_count > 0 assert search_detail.similar_match_count > 0 exact_count = search_detail.exact_match_count similar_count = search_detail.similar_match_count # Search step 2: modify search selection and update. # setup query_results_json = query_json['results'] select_json = [] for result in query_results_json: if result['matchType'] == 'EXACT': select_json.append(result) elif result['baseRegistrationNumber'] not in ('TEST0002', 'TEST0003'): select_json.append(result) # test search_detail2 = SearchResult.validate_search_select( select_json, search_detail.search_id) search_detail2.update_selection(select_json) # check # print(search_detail2.search_select) assert search_detail2.search_select assert exact_count == search_detail2.exact_match_count assert similar_count > search_detail2.similar_match_count details_json = search_detail2.json # print(details_json) for detail in details_json['details']: assert detail['financingStatement']['baseRegistrationNumber'] not in ( 'TEST0002', 'TEST0003')
def test_get_search_report(session): """Assert that config to get a google storage token works as expected.""" # setup json_data = { 'type': 'SERIAL_NUMBER', 'criteria': { 'value': 'JU622994' }, 'clientReferenceId': 'UT-SS-1001' } search_query = SearchRequest.create_from_json(json_data, 'PS12345') search_query.search() query_json = search_query.json search_detail = SearchResult.create_from_search_query(search_query) search_detail.save() select_json = query_json['results'] search_detail.update_selection(select_json, 'UNIT TEST INC.') # test raw_data, status_code, headers = get_search_report( str(search_detail.search_id)) print(status_code) # check assert raw_data assert status_code assert headers assert len(raw_data) > 0 with open(TEST_SEARCH_REPORT_FILE, "wb") as pdf_file: pdf_file.write(raw_data) pdf_file.close()
def test_valid_callback_search_report(session, client, jwt): """Assert that a valid callback request returns a 200 status.""" # setup json_data = { 'type': 'SERIAL_NUMBER', 'criteria': { 'value': 'JU622994' }, 'clientReferenceId': 'UT-SS-1001' } search_query = SearchRequest.create_from_json(json_data, 'PS12345') search_query.search() query_json = search_query.json search_detail = SearchResult.create_from_search_query(search_query) search_detail.save() select_json = query_json['results'] search_detail.update_selection(select_json, 'UNIT TEST INC.', 'CALLBACK_URL') # test rv = client.post('/api/v1/search-results/callback/' + str(search_detail.search_id), headers=None) # check print(rv.json) assert rv.status_code == HTTPStatus.OK response = rv.json assert response['name'] assert response['selfLink'] GoogleStorageService.delete_document(response['name'])
def test_search(session, desc, json_data, search_id, has_history, statement_type): """Assert that search detail results on registration matches returns the expected result.""" # test search_detail = SearchResult.validate_search_select(json_data, search_id) search_detail.update_selection(json_data) result = search_detail.json # check # print(result) assert result['searchDateTime'] assert result['exactResultsSize'] == 1 assert result['similarResultsSize'] == 0 assert result['totalResultsSize'] == 1 assert result['searchQuery'] assert result['details'] assert len(result['details']) == 1 assert result['details'][0]['financingStatement'] if has_history: assert 'changes' in result['details'][0]['financingStatement'] assert len(result['details'][0]['financingStatement']['changes']) > 0 if statement_type: assert result['details'][0]['financingStatement']['changes'][0][ 'statementType'] == statement_type else: assert 'changes' not in result['details'][0]['financingStatement']
def test_search_history_sort(session, client, jwt): """Assert that search results history sort order works as expected.""" # setup json_data = { 'type': 'REGISTRATION_NUMBER', 'criteria': { 'value': 'TEST0001' } } search_query = SearchClient.create_from_json(json_data, 'PS12345') # test search_query.search() search_detail = SearchResult.create_from_search_query(search_query) search_detail.save() # check assert search_detail.search_id == search_query.search_id result = search_detail.json # print(details_json) history = result[0]['financingStatement']['changes'] assert len(history) == 4 assert history[0]['changeRegistrationNumber'] == 'TEST0009' assert history[1]['changeRegistrationNumber'] == 'TEST0008' assert history[2]['amendmentRegistrationNumber'] == 'TEST0007' assert history[3]['changeRegistrationNumber'] == 'TEST0010'
def test_search_id_date_valid(session, client, jwt): """Assert that finding by search ID with a date check on a valid date works as expected.""" # no setup # test search_detail = SearchResult.find_by_search_id(200000005, True) # check assert search_detail
def staff_search(req: request, request_json, account_id: str): """Execute a staff search with special payment validation and methods.""" payment_info = build_staff_payment(req, account_id) # bcol help is no fee; reg staff can be no fee. # FAS is routing slip only. # BCOL is dat number (optional) and BCOL account number (mandatory). # All staff roles including SBC can submit no fee searches. if ROUTING_SLIP_PARAM in payment_info and BCOL_NUMBER_PARAM in payment_info: return resource_utils.staff_payment_bcol_fas() if CERTIFIED_PARAM in payment_info: request_json['certified'] = True query: SearchRequest = SearchRequest.create_from_json( request_json, account_id, g.jwt_oidc_token_info.get('username', None)) # Always create a payment transaction. invoice_id = None payment = Payment(jwt=jwt.get_token_auth_header(), account_id=account_id, details=get_payment_details(query, request_json['type'])) # staff payment pay_ref = payment.create_payment_staff_search(payment_info, query.client_reference_id) invoice_id = pay_ref['invoiceId'] query.pay_invoice_id = int(invoice_id) query.pay_path = pay_ref['receipt'] # Execute the search query: treat no results as a success. try: query.search() # Now save the initial detail results in the search_result table with no # search selection criteria (the absence indicates an incomplete search). search_result = SearchResult.create_from_search_query(query) search_result.save() except Exception as db_exception: # noqa: B902; handle all db related errors. current_app.logger.error( SAVE_ERROR_MESSAGE.format(account_id, repr(db_exception))) if invoice_id is not None: current_app.logger.info( PAY_REFUND_MESSAGE.format(account_id, invoice_id)) try: payment.cancel_payment(invoice_id) except Exception as cancel_exception: # noqa: B902; log exception current_app.logger.error( PAY_REFUND_ERROR.format(account_id, invoice_id, repr(cancel_exception))) raise db_exception return query.json, HTTPStatus.CREATED
def post(search_id): """Execute a search detail request using selection choices in the request body.""" try: if search_id is None: return resource_utils.path_param_error_response('search ID') # Quick check: must be staff or provide an account ID. account_id = resource_utils.get_account_id(request) if not is_staff(jwt) and account_id is None: return resource_utils.account_required_response() # Verify request JWT and account ID if not authorized(account_id, jwt): return resource_utils.unauthorized_error_response(account_id) request_json = request.get_json(silent=True) # Validate schema. valid_format, errors = schema_utils.validate( request_json, 'searchSummary', 'ppr') if not valid_format: return resource_utils.validation_error_response( errors, VAL_ERROR) # Perform any extra data validation such as start and end dates here search_detail = SearchResult.validate_search_select( request_json, search_id) # Save the search query selection and details that match the selection. search_detail.update_selection(request_json) if not search_detail.search_response: return resource_utils.unprocessable_error_response( 'search result details') response_data = search_detail.json if resource_utils.is_pdf(request): token = g.jwt_oidc_token_info # Return report if request header Accept MIME type is application/pdf. return get_pdf(response_data, account_id, ReportTypes.SEARCH_DETAIL_REPORT.value, token['name']) return jsonify(response_data), HTTPStatus.OK except BusinessException as exception: return resource_utils.business_exception_response(exception) except Exception as default_exception: # noqa: B902; return nicer default error return resource_utils.default_exception_response(default_exception)
def get_search_report(search_id: str): """Generate a search result report.""" current_app.logger.info('Search report request id=' + search_id) search_detail = SearchResult.find_by_search_id(int(search_id), False) if search_detail is None: current_app.logger.info('No search report data found for id=' + search_id) raise ReportDataException('No search report data found for id=' + search_id) try: report_data = search_detail.json account_id = search_detail.search.account_id account_name = search_detail.account_name token = SBCPaymentClient.get_sa_token() return get_callback_pdf(report_data, account_id, ReportTypes.SEARCH_DETAIL_REPORT.value, token, account_name) except Exception as err: # pylint: disable=broad-except # noqa F841; current_app.logger.error('Search report generation failed for id=' + search_id) current_app.logger.error(repr(err)) raise ReportException('Search report generation failed for id=' + search_id)
def get(search_id): """Get search detail information for a previous search.""" try: if search_id is None: return resource_utils.path_param_error_response('search ID') # Quick check: must have an account ID. account_id = resource_utils.get_account_id(request) if account_id is None: return resource_utils.account_required_response() # Verify request JWT and account ID if not authorized(account_id, jwt): return resource_utils.unauthorized_error_response(account_id) # Try to fetch search detail by search id. current_app.logger.info(f'Fetching search detail for {search_id}.') search_detail = SearchResult.find_by_search_id(search_id, True) if not search_detail: return resource_utils.not_found_error_response( 'searchId', search_id) response_data = search_detail.json if resource_utils.is_pdf(request): token = g.jwt_oidc_token_info # Return report if request header Accept MIME type is application/pdf. return get_pdf(response_data, account_id, ReportTypes.SEARCH_DETAIL_REPORT.value, token['name']) return jsonify(response_data), HTTPStatus.OK except BusinessException as exception: return resource_utils.business_exception_response(exception) except Exception as default_exception: # noqa: B902; return nicer default error return resource_utils.default_exception_response(default_exception)
def post(): # pylint: disable=too-many-branches """Execute a new search request using criteria in the request body.""" try: # Quick check: must be staff or provide an account ID. account_id = resource_utils.get_account_id(request) if not account_id: return resource_utils.account_required_response() # Verify request JWT and account ID if not authorized(account_id, jwt): return resource_utils.unauthorized_error_response(account_id) request_json = request.get_json(silent=True) # Validate request against the schema. valid_format, errors = schema_utils.validate( request_json, 'searchQuery', 'ppr') if not valid_format: return resource_utils.validation_error_response( errors, VAL_ERROR) # Perform any extra data validation such as start and end dates here SearchRequest.validate_query(request_json) # Staff has special payment rules and setup. if is_staff_account(account_id) or is_bcol_help(account_id): return staff_search(request, request_json, account_id) query = SearchRequest.create_from_json( request_json, account_id, g.jwt_oidc_token_info.get('username', None)) # Charge a search fee. invoice_id = None payment = Payment(jwt=jwt.get_token_auth_header(), account_id=account_id, details=get_payment_details( query, request_json['type'])) pay_ref = payment.create_payment(TransactionTypes.SEARCH.value, 1, None, query.client_reference_id) invoice_id = pay_ref['invoiceId'] query.pay_invoice_id = int(invoice_id) query.pay_path = pay_ref['receipt'] # Execute the search query: treat no results as a success. try: query.search() # Now save the initial detail results in the search_result table with no # search selection criteria (the absence indicates an incomplete search). search_result = SearchResult.create_from_search_query(query) search_result.save() except Exception as db_exception: # noqa: B902; handle all db related errors. current_app.logger.error( SAVE_ERROR_MESSAGE.format(account_id, repr(db_exception))) if invoice_id is not None: current_app.logger.info( PAY_REFUND_MESSAGE.format(account_id, invoice_id)) try: payment.cancel_payment(invoice_id) except Exception as cancel_exception: # noqa: B902; log exception current_app.logger.error( PAY_REFUND_ERROR.format(account_id, invoice_id, repr(cancel_exception))) raise db_exception return query.json, HTTPStatus.CREATED except SBCPaymentException as pay_exception: return resource_utils.pay_exception_response(pay_exception) except BusinessException as exception: return resource_utils.business_exception_response(exception) except Exception as default_exception: # noqa: B902; return nicer default error return resource_utils.default_exception_response(default_exception)
def post(): """Execute a new search request using criteria in the request body.""" try: # Quick check: must be staff or provide an account ID. account_id = resource_utils.get_account_id(request) if not is_staff(jwt) and account_id is None: return resource_utils.account_required_response() # Verify request JWT and account ID if not authorized(account_id, jwt): return resource_utils.unauthorized_error_response(account_id) request_json = request.get_json(silent=True) # Validate request against the schema. valid_format, errors = schema_utils.validate( request_json, 'searchQuery', 'ppr') if not valid_format: return resource_utils.validation_error_response( errors, VAL_ERROR) # Perform any extra data validation such as start and end dates here SearchClient.validate_query(request_json) query = SearchClient.create_from_json(request_json, account_id) # Charge a search fee. if account_id: payment = Payment(jwt=jwt.get_token_auth_header(), account_id=account_id) pay_ref = payment.create_payment(TransactionTypes.SEARCH.value, 1, None, query.client_reference_id) invoice_id = pay_ref['invoiceId'] query.pay_invoice_id = int(invoice_id) query.pay_path = pay_ref['receipt'] # Execute the search query: treat no results as a success. try: query.search() # if not query.search_response or query.returned_results_size == 0: # return resource_utils.unprocessable_error_response('search query') # Now save the initial detail results in the search_result table with no # search selection criteria (the absence indicates an incomplete search). search_result = SearchResult.create_from_search_query(query) search_result.save() except Exception as db_exception: # noqa: B902; handle all db related errors. current_app.logger.error( f'Search {account_id} db save failed: ' + repr(db_exception)) current_app.logger.error( f'Search {account_id} rolling back payment for invoice {invoice_id}.' ) try: payment.cancel_payment(invoice_id) except Exception as cancel_exception: # noqa: B902; log exception current_app.logger.error( f'Search {account_id} payment refund failed for invoice {invoice_id}: ' + repr(cancel_exception)) raise db_exception return query.json, HTTPStatus.CREATED except SBCPaymentException as pay_exception: return resource_utils.pay_exception_response(pay_exception) except BusinessException as exception: return resource_utils.business_exception_response(exception) except Exception as default_exception: # noqa: B902; return nicer default error return resource_utils.default_exception_response(default_exception)