示例#1
0
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)
示例#2
0
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)
示例#3
0
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')
示例#4
0
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()
示例#5
0
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'])
示例#6
0
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']
示例#7
0
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'
示例#8
0
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
示例#9
0
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
示例#10
0
    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)
示例#11
0
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)
示例#12
0
    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)
示例#13
0
    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)
示例#14
0
    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)