def test_business_comment_json_output(session, client, jwt): """Assert the json output of a comment is correctly formatted.""" identifier = 'CP7654321' b = factory_business(identifier) u = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') u.save() now = datetime.datetime(1970, 1, 1, 0, 0).replace(tzinfo=datetime.timezone.utc) with freeze_time(now): factory_business_comment(b, 'some specific text', u) rv = client.get(f'/api/v2/businesses/{identifier}/comments', headers=create_header(jwt, [STAFF_ROLE])) assert HTTPStatus.OK == rv.status_code assert 'some specific text' == rv.json.get('comments')[0].get( 'comment').get('comment') assert 'firstname lastname' == rv.json.get('comments')[0].get( 'comment').get('submitterDisplayName') assert now.isoformat() == rv.json.get('comments')[0].get( 'comment').get('timestamp')
def test_comment_json_output(session, client, jwt): """Assert the json output of a comment is correctly formatted.""" identifier = 'CP7654321' b = factory_business(identifier) f = factory_filing(b, ANNUAL_REPORT) u = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') u.save() c = factory_comment(b, f, 'some specific text', u) system_timezone = datetime.datetime.now().astimezone().tzinfo expected_timestamp = \ datetime.datetime(1970, 1, 1, 0, 0).replace(tzinfo=datetime.timezone.utc).astimezone(tz=system_timezone) rv = client.get( f'/api/v1/businesses/{identifier}/filings/{f.id}/comments/{c.id}', headers=create_header(jwt, [STAFF_ROLE])) assert HTTPStatus.OK == rv.status_code assert 'some specific text' == rv.json.get('comment').get('comment') assert 'firstname lastname' == rv.json.get('comment').get( 'submitterDisplayName') assert expected_timestamp.isoformat() == rv.json.get('comment').get( 'timestamp')
def test_create_from_invalid_jwt_token_no_token(session): """Assert User is not created from an empty token.""" token = b'invalidtoken' with pytest.raises(AttributeError) as excinfo: User.create_from_jwt_token(token) assert excinfo.value.args[0] == "'bytes' object has no attribute 'get'"
def test_get_or_create_user_by_jwt_invlaid_jwt(session): """Assert User is created from the JWT fields.""" token = b'invalidtoken' with pytest.raises(BusinessException) as excinfo: User.get_or_create_user_by_jwt(token) assert excinfo.value.error == 'unable_to_get_or_create_user'
def test_find_by_sub(session): """Assert find User by the unique sub key.""" user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') session.add(user) session.commit() u = User.find_by_sub('sub') assert u.id is not None
def test_find_by_username(session): """Assert User can be found by the most current username.""" user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') session.add(user) session.commit() u = User.find_by_username('username') assert u.id is not None
def test_user_save(session): """Assert User record is saved.""" user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') user.save() assert user.id is not None
def test_user_find_by_jwt_token(session): """Assert that a User can be stored in the service. Start with a blank database. """ user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') session.add(user) session.commit() token = {'sub': 'sub'} u = User.find_by_jwt_token(token) assert u.id is not None
def create_user(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss'): """Create a user.""" from legal_api.models import User new_user = User( username=username, firstname=firstname, lastname=lastname, sub=sub, iss=iss, ) new_user.save() return new_user
def test_flag_bool_unique_user(): """Assert that a unique user can retrieve a flag, when using the local Flag.json file.""" app = Flask(__name__) app.env = 'development' app.config['LD_SDK_KEY'] = 'https://no.flag/avail' user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') app_env = app.env try: with app.app_context(): flags = Flags() flags.init_app(app) app.env = 'development' val = flags.value('bool-flag', user) flag_on = flags.is_on('bool-flag', user) assert val assert flag_on except: # pylint: disable=bare-except; # noqa: B901, E722 # for tests we don't care assert False finally: app.env = app_env
async def test_correction_filing(app, session): """Assert we can process a correction filing.""" # vars payment_id = str(random.SystemRandom().getrandbits(0x58)) identifier = 'CP1111111' correction_filing_comment = 'We need to fix directors' # get a fixed datetime to use in comparisons, in "local" (Pacific) timezone local_timezone = pytz.timezone('US/Pacific') correction_filing_date = \ datetime.datetime(2019, 9, 17, 0, 0).replace(tzinfo=datetime.timezone.utc).astimezone(tz=local_timezone) # setup - create business, staff user, and original filing to be corrected business_id = create_business(identifier).id staff_user_id = create_user(username='******').id original_filing_id = create_filing(payment_id, copy.deepcopy(ANNUAL_REPORT), business_id).id # setup - create correction filing filing = copy.deepcopy(CORRECTION_AR) filing['filing']['header']['identifier'] = identifier filing['filing']['correction']['comment'] = correction_filing_comment filing['filing']['correction']['correctedFilingId'] = original_filing_id correction_filing = create_filing(payment_id, filing, business_id, filing_date=correction_filing_date) correction_filing.submitter_id = staff_user_id correction_filing.save() correction_filing_id = correction_filing.id filing_msg = {'filing': {'id': correction_filing_id}} # TEST await process_filing(filing_msg, app) # Get modified data original_filing = Filing.find_by_id(original_filing_id) correction_filing = Filing.find_by_id(correction_filing_id) staff_user = User.find_by_username('staff_user') # check that the correction filing is linked to the original filing assert original_filing.parent_filing assert original_filing.parent_filing == correction_filing # check that the correction comment has been added to the correction filing assert 0 < len(correction_filing.comments.all()) assert correction_filing_comment == correction_filing.comments.all()[-1].comment assert staff_user.id == correction_filing.comments.all()[-1].staff.id # check that the correction filing is PENDING_CORRECTION assert correction_filing.status == 'PENDING_CORRECTION' # check that the original filing is marked as corrected # assert True is original_filing.is_corrected # check that the original filing has the new comment assert 0 < len(original_filing.comments.all()) assert f'This filing was corrected on {correction_filing_date.date().isoformat()}.' == \ original_filing.comments.all()[-1].comment assert staff_user.id == original_filing.comments.all()[-1].staff.id
def factory_user(username: str, firstname: str = None, lastname: str = None): user = User() user.username = username user.firstname = firstname user.lastname = lastname user.save() return user
def put(identifier, filing_id): # pylint: disable=too-many-return-statements """Modify an incomplete filing for the business.""" # basic checks err_msg, err_code = ListFilingResource._put_basic_checks(identifier, filing_id, request) if err_msg: return jsonify({'errors': [err_msg, ]}), err_code json_input = request.get_json() # check authorization if not authorized(identifier, jwt, action=['edit']): return jsonify({'message': f'You are not authorized to submit a filing for {identifier}.'}), \ HTTPStatus.UNAUTHORIZED draft = (request.args.get('draft', None).lower() == 'true') \ if request.args.get('draft', None) else False only_validate = (request.args.get('only_validate', None).lower() == 'true') \ if request.args.get('only_validate', None) else False # validate filing if not draft: business = Business.find_by_identifier(identifier) err = validate(business, json_input) # err_msg, err_code = ListFilingResource._validate_filing_json(request) if err or only_validate: if err: json_input['errors'] = err.msg return jsonify(json_input), err.code return jsonify(json_input), HTTPStatus.OK # save filing, if it's draft only then bail user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) business, filing, err_msg, err_code = ListFilingResource._save_filing(request, identifier, user, filing_id) if err_msg or draft: reply = filing.json if filing else json_input reply['errors'] = [err_msg, ] return jsonify(reply), err_code or \ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED) # if filing is from COLIN, place on queue and return if jwt.validate_roles([COLIN_SVC_ROLE]): err_msg, err_code = ListFilingResource._process_colin_filing(identifier, json_input) return jsonify(err_msg), err_code # create invoice ?? if not draft: filing_types = ListFilingResource._get_filing_types(filing.filing_json) err_msg, err_code = ListFilingResource._create_invoice(business, filing, filing_types, jwt) if err_code: reply = filing.json reply['errors'] = [err_msg, ] return jsonify(reply), err_code # all done return jsonify(filing.json),\ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED)
def test_get_or_create_user_by_jwt(session): """Assert User is created from the JWT fields.""" token = {'username': '******', 'given_name': 'given_name', 'family_name': 'family_name', 'iss': 'iss', 'sub': 'sub' } u = User.get_or_create_user_by_jwt(token) assert u.id is not None
def test_user_display_name(session, test_description, username, firstname, lastname, display_name): """Assert the User record is deleted.""" user = User(username=username, firstname=firstname, lastname=lastname, sub='sub', iss='iss') assert display_name == user.display_name
def test_user(session): """Assert that a User can be stored in the service. Start with a blank database. """ user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') session.add(user) session.commit() assert user.id is not None
def post(identifier, filing_id): """Create a new comment for the filing.""" # basic checks err_msg, err_code = CommentResource._basic_checks( identifier, filing_id, request) if err_msg: return jsonify(err_msg), err_code json_input = request.get_json() # check authorization if not authorized(identifier, jwt, action=['add_comment']): return jsonify({'message': f'You are not authorized to submit a comment for {identifier}.'}), \ HTTPStatus.UNAUTHORIZED # validate comment err = validate(json_input, True) if err: json_input['errors'] = err.msg return jsonify(json_input), err.code # confirm that the filing ID in the URL is the same as in the json if json_input['comment']['filingId'] != filing_id: json_input['errors'] = [ { 'error': 'Invalid filingId in request' }, ] return jsonify(json_input), HTTPStatus.BAD_REQUEST # save comment user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) try: comment = Comment() comment.comment = json_input['comment']['comment'] comment.staff_id = user.id comment.filing_id = filing_id comment.timestamp = datetime.datetime.utcnow() comment.save() except BusinessException as err: reply = json_input reply['errors'] = [ { 'error': err.error }, ] return jsonify(reply), err.status_code or \ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED) # all done return jsonify(comment.json), HTTPStatus.CREATED
def set_source(mapper, connection, target): # pylint: disable=unused-argument; SQLAlchemy callback signature """Set the source of the filing to COLIN if it has a colin event id set.""" # imported User here to avoid conflict with filing_submitter relationship. # needed because the relationship hasn't been set yet for this filing. from legal_api.models import User filing = target user = User.find_by_id(filing.submitter_id) # if it is an epoch filing and there is no user then it was applied by the data-loader if (filing.filing_type == 'lear_epoch' and not user) or (user and user.username == 'coops-updater-job'): filing._source = Filing.Source.COLIN.value # pylint: disable=protected-access else: filing._source = Filing.Source.LEAR.value # pylint: disable=protected-access
def load_historic_filings(corp_num: str, business: Business, legal_type: str): """Load historic filings for a business.""" try: # get historic filings r = requests.get( f'{COLIN_API}/api/v1/businesses/{legal_type}/{corp_num}/filings/historic', timeout=TIMEOUT) if r.status_code != HTTPStatus.OK or not r.json(): print( f'skipping history for {corp_num} historic filings not found') else: for historic_filing in r.json(): uow = versioning_manager.unit_of_work(db.session) transaction = uow.create_transaction(db.session) filing = Filing() filing_date = historic_filing['filing']['header']['date'] filing.filing_date = datetime.datetime.strptime( filing_date, '%Y-%m-%d') filing.business_id = business.id filing.filing_json = historic_filing for colin_id in filing.filing_json['filing']['header'][ 'colinIds']: colin_event_id = ColinEventId() colin_event_id.colin_event_id = colin_id filing.colin_event_ids.append(colin_event_id) filing.transaction_id = transaction.id filing._filing_type = historic_filing['filing']['header'][ 'name'] filing.paper_only = True filing.effective_date = datetime.datetime.strptime( historic_filing['filing']['header']['effectiveDate'], '%Y-%m-%d') updater_user = User.find_by_username(UPDATER_USERNAME) filing.submitter_id = updater_user.id filing.source = Filing.Source.COLIN.value db.session.add(filing) # only commit after all historic filings were added successfully db.session.commit() LOADED_FILING_HISTORY.append(corp_num) except requests.exceptions.Timeout: print('rolling back partial changes...') db.session.rollback() FAILED_FILING_HISTORY.append(corp_num) print('colin_api request timed out getting historic filings.') except Exception as err: print('rolling back partial changes...') db.session.rollback() FAILED_FILING_HISTORY.append(corp_num) raise err
def test_save_filing_with_colin_id(session): """Assert that saving a filing from the coops-updater-job user is set to paid and source is colin.""" from legal_api.models import Filing # setup filing = Filing() filing.filing_json = ANNUAL_REPORT user = User.create_from_jwt_token({'username': '******', 'iss': 'test', 'sub': 'test'}) filing.submitter_id = user.id filing.save() # test assert filing.source == Filing.Source.COLIN.value assert filing.status == Filing.Status.PAID.value
def test_filing_dump_json(session): """Assert the filing json serialization works correctly.""" import copy identifier = 'CP7654321' b = factory_business(identifier) # Check base JSON filings = factory_filing(b, ANNUAL_REPORT) assert filings.json['filing']['business'] == ANNUAL_REPORT['filing'][ 'business'] assert filings.json['filing']['annualReport'] == ANNUAL_REPORT['filing'][ 'annualReport'] # Check payment token ar = copy.deepcopy(ANNUAL_REPORT) token = 'token' ar['filing']['header']['paymentToken'] = token filings = factory_filing(b, ar) assert filings.json['filing']['header']['paymentToken'] == token # check submitter u = User() u.username = '******' u.save() ar = copy.deepcopy(ANNUAL_REPORT) filings = factory_filing(b, ar) filings.submitter_id = u.id filings.save() assert filings.json['filing']['header']['submitter'] == u.username # check Exception ar = copy.deepcopy(ANNUAL_REPORT) filings = factory_filing(b, ar) filings.save() filings.submitter_id = -1 # some bogus id to throw an error with pytest.raises(KeyError): filings.json()
def test_flag_bool_unique_user(app): """Assert that a unique user can retrieve a flag.""" from legal_api import flags user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') with app.app_context(): val = flags.value('bool-flag', user) on = flags.is_on('bool-flag', user) assert val assert on
def post(identifier): """Create a new comment for the business.""" # basic checks business = Business.find_by_identifier(identifier) err_msg, err_code = BusinessCommentResource._basic_checks( identifier, business, request) if err_msg: return jsonify(err_msg), err_code json_input = request.get_json() # check authorization if not authorized(identifier, jwt, action=['add_comment']): return jsonify({'message': f'You are not authorized to submit a comment for {identifier}.'}), \ HTTPStatus.UNAUTHORIZED # validate comment err = validate(json_input, False) if err: json_input['errors'] = err.msg return jsonify(json_input), err.code # save comment user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) try: comment = Comment() comment.comment = json_input['comment']['comment'] comment.staff_id = user.id comment.business_id = business.id comment.timestamp = datetime.datetime.utcnow() comment.save() except BusinessException as err: reply = json_input reply['errors'] = [ { 'error': err.error }, ] return jsonify(reply), err.status_code # all done return jsonify(comment.json), HTTPStatus.CREATED
def post(): """Create a business from an incorporation filing, return the filing.""" draft = (request.args.get('draft', None).lower() == 'true') \ if request.args.get('draft', None) else False json_input = request.get_json() # validate filing err = validate(None, json_input) if err: json_input['errors'] = err.msg return jsonify(json_input), err.code # create business business, err_msg, err_code = BusinessResource._create_business(json_input, request) if err_msg: if isinstance(err_msg, list): json_input['errors'] = [err for err in err_msg] elif err_msg: json_input['errors'] = [err_msg, ] return jsonify(json_input), err_code # create filing user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) business, filing, err_msg, err_code = ListFilingResource._save_filing( # pylint: disable=protected-access request, business.identifier, user, None) if err_msg or draft: reply = filing.json if filing else json_input reply['errors'] = [err_msg, ] return jsonify(reply), err_code or HTTPStatus.CREATED # complete filing response, response_code = ListFilingResource.complete_filing(business, filing, draft) if response: return response, response_code # all done return jsonify(filing.json), HTTPStatus.CREATED
def test_flag_bool_unique_user(app): """Assert that a unique user can retrieve a flag, when using the local Flag.json file.""" from legal_api import flags user = User(username='******', firstname='firstname', lastname='lastname', sub='sub', iss='iss') app_env = app.env try: with app.app_context(): app.env = 'development' val = flags.value('bool-flag', user) flag_on = flags.is_on('bool-flag', user) assert val assert flag_on except: # pylint: disable=bare-except; # noqa: B901, E722 # for tests we don't care assert False finally: app.env = app_env
def put(identifier, filing_id): # pylint: disable=too-many-return-statements """Modify an incomplete filing for the business.""" # basic checks err_msg, err_code = ListFilingResource._put_basic_checks( identifier, filing_id, request) if err_msg: return jsonify({'errors': [ err_msg, ]}), err_code json_input = request.get_json() # check authorization if not authorized(identifier, jwt, action=['edit']): return jsonify({'message': f'You are not authorized to submit a filing for {identifier}.'}), \ HTTPStatus.UNAUTHORIZED # get query params draft = (request.args.get('draft', None).lower() == 'true') \ if request.args.get('draft', None) else False only_validate = (request.args.get('only_validate', None).lower() == 'true') \ if request.args.get('only_validate', None) else False # validate filing if not draft and not ListFilingResource._is_before_epoch_filing( json_input, Business.find_by_identifier(identifier)): if identifier.startswith('T'): business_validate = RegistrationBootstrap.find_by_identifier( identifier) else: business_validate = Business.find_by_identifier(identifier) err = validate(business_validate, json_input) # err_msg, err_code = ListFilingResource._validate_filing_json(request) if err or only_validate: if err: json_input['errors'] = err.msg return jsonify(json_input), err.code return jsonify(json_input), HTTPStatus.OK # save filing, if it's draft only then bail user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) try: business, filing, err_msg, err_code = ListFilingResource._save_filing( request, identifier, user, filing_id) if err_msg or draft: reply = filing.json if filing else json_input reply['errors'] = [ err_msg, ] return jsonify(reply), err_code or \ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED) except Exception as err: print(err) # complete filing response, response_code = ListFilingResource.complete_filing( business, filing, draft) if response: return response, response_code # all done return jsonify(filing.json),\ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED)
def put(identifier, filing_id): # pylint: disable=too-many-return-statements,too-many-locals """Modify an incomplete filing for the business.""" # basic checks err_msg, err_code = ListFilingResource._put_basic_checks( identifier, filing_id, request) if err_msg: return jsonify({'errors': [ err_msg, ]}), err_code json_input = request.get_json() # check authorization response, response_code = ListFilingResource._check_authorization( identifier, json_input) if response: return response, response_code # get query params draft = (request.args.get('draft', None).lower() == 'true') \ if request.args.get('draft', None) else False only_validate = (request.args.get('only_validate', None).lower() == 'true') \ if request.args.get('only_validate', None) else False # get header params payment_account_id = request.headers.get('accountId', None) if not draft \ and not ListFilingResource._is_historical_colin_filing(json_input) \ and not ListFilingResource._is_before_epoch_filing(json_input, Business.find_by_identifier(identifier)): if identifier.startswith('T'): business_validate = RegistrationBootstrap.find_by_identifier( identifier) else: business_validate = Business.find_by_identifier(identifier) err = validate(business_validate, json_input) # err_msg, err_code = ListFilingResource._validate_filing_json(request) if err or only_validate: if err: json_input['errors'] = err.msg return jsonify(json_input), err.code return jsonify(json_input), HTTPStatus.OK # save filing, if it's draft only then bail user = User.get_or_create_user_by_jwt(g.jwt_oidc_token_info) try: business, filing, err_msg, err_code = ListFilingResource._save_filing( request, identifier, user, filing_id) if err_msg or draft: reply = filing.json if filing else json_input reply['errors'] = [ err_msg, ] return jsonify(reply), err_code or \ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED) except Exception as err: print(err) # complete filing response, response_code = ListFilingResource.complete_filing( business, filing, draft, payment_account_id) if response and (response_code != HTTPStatus.CREATED or filing.source == Filing.Source.COLIN.value): return response, response_code # all done filing_json = filing.json if response: filing_json['filing']['header'].update(response) return jsonify(filing_json),\ (HTTPStatus.CREATED if (request.method == 'POST') else HTTPStatus.ACCEPTED)
'header']['colinIds']: colin_event_id = ColinEventId() colin_event_id.colin_event_id = colin_id filing.colin_event_ids.append( colin_event_id) filing.transaction_id = transaction.id filing_type = historic_filing['filing'][ 'header']['name'] filing.paper_only = True filing.effective_date = datetime.datetime.strptime( historic_filing['filing']['header'] ['effectiveDate'], '%Y-%m-%d') # set user id to updater-job id (this will ensure that filing source is set to COLIN) updater_user = User.find_by_username( UPDATER_USERNAME) filing.submitter_id = updater_user.id db.session.add(filing) db.session.commit() LOADED_COOPS_HISTORY.append(row["CORP_NUM"]) except requests.exceptions.Timeout as timeout: LOADED_COOPS_HISTORY.append(row["CORP_NUM"]) print( 'colin_api request timed out getting historic filings.' ) else: print( '->historic filings already exist - skipping history load'
def create_user(user_name: str): """Return a new user model.""" user = User() user.username = user_name user.save() return user
def test_create_from_jwt_token_no_token(session): """Assert User is not created from an empty token.""" token = None u = User.create_from_jwt_token(token) assert u is None