Skip to content

Commit

Permalink
Merge pull request #144 from bcgov/development
Browse files Browse the repository at this point in the history
Merge from development to master
  • Loading branch information
sumesh-aot authored Jan 10, 2020
2 parents 7df1b25 + cbbcbef commit 8fd4d91
Show file tree
Hide file tree
Showing 20 changed files with 64 additions and 39 deletions.
2 changes: 1 addition & 1 deletion jobs/update-stale-payment/update_stale_payment_records.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def update_stale_payments(app):
app.logger.info(
'Stale Transaction Job found records.Payment Id: {}, Transaction Id : {}'.format(transaction.payment_id,
transaction.id))
TransactionService.update_transaction(transaction.payment_id, transaction.id, '', skip_auth_check=True)
TransactionService.update_transaction(transaction.payment_id, transaction.id, '')
app.logger.info(
'Stale Transaction Job Updated records.Payment Id: {}, Transaction Id : {}'.format(
transaction.payment_id, transaction.id))
Expand Down
10 changes: 5 additions & 5 deletions pay-api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ Flask==1.1.1
Jinja2==2.10.3
Mako==1.1.0
MarkupSafe==1.1.1
SQLAlchemy==1.3.11
SQLAlchemy==1.3.12
Werkzeug==0.16.0
alembic==1.3.1
alembic==1.3.2
aniso8601==8.0.0
asyncio-nats-client==0.10.0
asyncio-nats-streaming==0.4.0
attrs==19.1.0
blinker==1.4
certifi==2019.11.28
chardet==3.0.4
croniter==0.3.30
ecdsa==0.14.1
croniter==0.3.31
ecdsa==0.15
flask-jwt-oidc==0.1.5
flask-marshmallow==0.10.1
flask-restplus==0.13.0
Expand All @@ -30,7 +30,7 @@ jsonschema==3.2.0
marshmallow-sqlalchemy==0.21.0
marshmallow==3.0.0rc7
more-itertools==8.0.2
protobuf==3.11.1
protobuf==3.11.2
psycopg2-binary==2.8.4
pyasn1==0.4.8
pyrsistent==0.15.6
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def create_app(run_mode=os.getenv('FLASK_ENV', 'production')):
app.config.from_object(config.CONFIGURATION[run_mode])

# Configure Sentry
if app.config.get('SENTRY_DSN', None):
if app.config.get('SENTRY_DSN', None): # pragma: no cover
sentry_sdk.init(
dsn=app.config.get('SENTRY_DSN'),
integrations=[FlaskIntegration()]
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/jwt_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class JWTWrapper: # pylint: disable=too-few-public-methods
@staticmethod
def get_instance():
"""Retrieve singleton JwtManager."""
if JWTWrapper.__instance is None:
if JWTWrapper.__instance is None: # pragma: no cover
JWTWrapper()
return JWTWrapper.__instance

Expand Down
5 changes: 5 additions & 0 deletions pay-api/src/pay_api/models/payment_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ def find_by_payment_id(cls, payment_id: int):
"""Return Payment Transactions by payment identifier."""
return cls.query.filter_by(payment_id=payment_id).all()

@classmethod
def find_active_by_payment_id(cls, payment_id: int):
"""Return Active Payment Transactions by payment identifier."""
return cls.query.filter_by(payment_id=payment_id).filter_by(status_code=Status.CREATED.value).one_or_none()

@classmethod
def find_by_id_and_payment_id(cls, identifier: uuid, payment_id: int):
"""Return Payment Transactions by payment identifier."""
Expand Down
2 changes: 0 additions & 2 deletions pay-api/src/pay_api/resources/payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,5 @@ def delete(payment_id):

except BusinessException as exception:
response, status = {'code': exception.code, 'message': exception.message}, exception.status
except ServiceUnavailableException as exception:
response, status = {'code': exception.status_code}, HTTPStatus.BAD_REQUEST
current_app.logger.debug('>Payment.delete')
return jsonify(response), status
11 changes: 5 additions & 6 deletions pay-api/src/pay_api/services/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ def check_auth(business_identifier: str, **kwargs):
auth_url = current_app.config.get('AUTH_API_ENDPOINT') + f'entities/{business_identifier}/authorizations'
auth_response = RestService.get(auth_url, bearer_token, AuthHeaderType.BEARER, ContentType.JSON)

if auth_response:
roles: list = auth_response.json().get('roles', [])
if kwargs.get('one_of_roles', None):
is_authorized = list(set(kwargs.get('one_of_roles')) & set(roles)) != []
if kwargs.get('contains_role', None):
is_authorized = kwargs.get('contains_role') in roles
roles: list = auth_response.json().get('roles', [])
if kwargs.get('one_of_roles', None):
is_authorized = list(set(kwargs.get('one_of_roles')) & set(roles)) != []
if kwargs.get('contains_role', None):
is_authorized = kwargs.get('contains_role') in roles

if not is_authorized:
abort(403)
2 changes: 0 additions & 2 deletions pay-api/src/pay_api/services/bcol_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ def create_invoice(self, payment_account: PaymentAccount, line_items: [PaymentLi
}
pay_response = self.post(pay_endpoint, kwargs.get('jwt'), AuthHeaderType.BEARER, ContentType.JSON,
payload).json()
if int(pay_response.get('totalAmount', 0)) == 0:
raise BusinessException(Error.PAY021)

invoice = {
'invoice_number': pay_response.get('key'),
Expand Down
4 changes: 0 additions & 4 deletions pay-api/src/pay_api/services/invoice_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ def save(self):
"""Save the information to the DB."""
return self._dao.save()

def flush(self):
"""Save the information to the DB."""
return self._dao.flush()

@staticmethod
def create(invoice_id: int, invoice_number: str, reference_number: str):
"""Create invoice reference record."""
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/services/payment_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,8 @@ def _complete_post_payment(pay_service: PaymentSystemService, payment: Payment):

def _update_active_transactions(payment_id):
# get existing payment transaction
current_app.logger.debug('<_update_active_transactions')
transaction: PaymentTransaction = PaymentTransaction.find_active_by_payment_id(payment_id)
current_app.logger.debug(transaction)
if transaction:
# check existing payment status in PayBC;
PaymentTransaction.update_transaction(payment_id, transaction.id, None)
Expand Down
12 changes: 4 additions & 8 deletions pay-api/src/pay_api/services/payment_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ def asdict(self):
@staticmethod
def populate(value):
"""Pouplate the service."""
if not value:
return None
transaction: PaymentTransaction = PaymentTransaction()
transaction._dao = value # pylint: disable=protected-access
return transaction
Expand Down Expand Up @@ -253,15 +255,9 @@ def find_by_id(payment_identifier: int, transaction_id: uuid):
@staticmethod
def find_active_by_payment_id(payment_identifier: int):
"""Find active transaction by id."""
existing_transactions = PaymentTransactionModel.find_by_payment_id(payment_identifier)
transaction: PaymentTransaction = None
if existing_transactions:
for existing_transaction in existing_transactions:
if existing_transaction.status_code not in (Status.COMPLETED.value, Status.CANCELLED.value):
transaction = existing_transaction

current_app.logger.debug('>find_active_by_payment_id')
return transaction
active_transaction = PaymentTransactionModel.find_active_by_payment_id(payment_identifier)
return PaymentTransaction.populate(active_transaction)

@staticmethod
def update_transaction(payment_identifier: int, transaction_id: uuid, # pylint: disable=too-many-locals
Expand Down
4 changes: 2 additions & 2 deletions pay-api/src/pay_api/utils/user_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ def wrapper(*func_args, **func_kwargs):


def _get_token_info() -> Dict:
return g.jwt_oidc_token_info if 'jwt_oidc_token_info' in g else {}
return g.jwt_oidc_token_info if g and 'jwt_oidc_token_info' in g else {}


def _get_token() -> str:
token: str = request.headers['Authorization'] if 'Authorization' in request.headers else None
token: str = request.headers['Authorization'] if request and 'Authorization' in request.headers else None
return token.replace('Bearer ', '') if token else None
6 changes: 6 additions & 0 deletions pay-api/tests/unit/factory/test_payment_system_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from pay_api.services.base_payment_system import PaymentSystemService
from pay_api.services.internal_pay_service import InternalPayService
from pay_api.services.bcol_service import BcolService
from pay_api.services.paybc_service import PaybcService
from pay_api.utils.enums import PaymentSystem
from pay_api.utils.errors import Error
Expand Down Expand Up @@ -50,6 +51,11 @@ def test_paybc_system_factory(session, public_user_mock):
assert isinstance(instance, InternalPayService)
assert isinstance(instance, PaymentSystemService)

# Test for BCOL Service
instance = PaymentSystemFactory.create_from_system_code(PaymentSystem.BCOL.value)
assert isinstance(instance, BcolService)
assert isinstance(instance, PaymentSystemService)


def test_internal_staff_factory(session, staff_user_mock):
"""Test payment system creation for staff users."""
Expand Down
14 changes: 14 additions & 0 deletions pay-api/tests/unit/models/test_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from datetime import datetime

from pay_api.models import Payment
from pay_api.utils.enums import Status


def factory_payment(payment_system_code: str = 'PAYBC', payment_method_code='CC', payment_status_code='DRAFT'):
Expand All @@ -36,3 +37,16 @@ def test_payment(session):
payment = factory_payment()
payment.save()
assert payment.id is not None


def test_payments_marked_for_delete(session):
"""Assert a payment is stored.
Start with a blank database.
"""
payment = factory_payment()
payment.payment_status_code = Status.DELETE_ACCEPTED.value
payment.save()
assert payment.id is not None
payments = Payment.find_payments_marked_for_delete()
assert len(payments) == 1
15 changes: 14 additions & 1 deletion pay-api/tests/unit/services/test_fee_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import pytest

from pay_api import services
from pay_api.models import CorpType, FeeCode, FilingType
from pay_api.models import CorpType, FeeCode, FilingType, FeeSchedule as FeesScheduleModel
from pay_api.utils.errors import Error


Expand Down Expand Up @@ -138,6 +138,19 @@ def test_find_by_corp_type_and_filing_type_and_invalid_date(session):

assert excinfo.value.status == Error.PAY002.status

def test_fee_schedule_with_priority_and_future_effective_filing_rates(session):
"""Assert that the fee schedule is saved to the table."""
create_linked_data(FILING_TYPE_CODE, CORP_TYPE_CODE, FEE_CODE, priority_fee='PR001', future_effective_fee='FU001')
FeesScheduleModel(filing_type_code = FILING_TYPE_CODE,
corp_type_code = CORP_TYPE_CODE,
fee_code = FEE_CODE,
future_effective_fee_code = 'FU001',
priority_fee_code = 'PR001').save()

fee_schedule = services.FeeSchedule.find_by_corp_type_and_filing_type(CORP_TYPE_CODE, FILING_TYPE_CODE, None, is_priority=True, is_future_effective=True)

assert fee_schedule is not None


def create_linked_data(
filing_type_code: str,
Expand Down
1 change: 1 addition & 0 deletions pay-api/tests/unit/services/test_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def test_invoice_saved_from_new(session):
assert invoice.paid is None
assert invoice.account_id is not None
assert invoice.payment_line_items is not None
assert invoice.folio_number is None


def test_invoice_invalid_lookup(session):
Expand Down
1 change: 1 addition & 0 deletions pay-api/tests/unit/services/test_invoice_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def test_invoice_saved_from_new(session):
assert invoice_reference is not None
assert invoice_reference.id is not None
assert invoice_reference.invoice_id == i.id
assert invoice_reference.status_code == Status.CREATED.value


def test_invoice_invalid_lookup(session):
Expand Down
2 changes: 2 additions & 0 deletions pay-api/tests/unit/services/test_payment_line_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ def test_line_saved_from_new(session):
assert p.gst is None
assert p.pst is None
assert p.line_item_status_code is not None
assert p.priority_fees is None
assert p.future_effective_fees is None
invoice = Invoice.find_by_id(invoice.id)
schema = InvoiceSchema()
d = schema.dump(invoice)
Expand Down
4 changes: 0 additions & 4 deletions pay-api/tests/unit/services/test_payment_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,6 @@ def test_update_payment_record_rollback(session, public_user_mock):
PaymentService.update_payment(payment.id, get_payment_request())
assert excinfo.type == Exception

# reset transaction
transaction = factory_payment_transaction(payment.id)
transaction.save()

with patch('pay_api.services.payment.Payment.save', side_effect=Exception('mocked error')):
with pytest.raises(Exception) as excinfo:
PaymentService.update_payment(payment.id, get_payment_request())
Expand Down
2 changes: 1 addition & 1 deletion pay-api/tests/utilities/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def factory_payment_line_item(invoice_id: str, fee_schedule_id: int, filing_fees

def factory_payment_transaction(
payment_id: str,
status_code: str = 'DRAFT',
status_code: str = 'CREATED',
client_system_url: str = 'http://google.com/',
pay_system_url: str = 'http://google.com',
transaction_start_time: datetime = datetime.now(),
Expand Down

0 comments on commit 8fd4d91

Please sign in to comment.