def assign_contract_to_company(contracts_list): for ix, contract in enumerate(contracts_list): if isinstance(contract, ContractBase): pass elif isinstance(contract, int): contracts_list[ix] = get_one_contract(contract) else: raise Exception('Contract must be a Contract object or a contract id') return contracts_list
def assign_contract_to_company(contracts_list): for ix, contract in enumerate(contracts_list): if isinstance(contract, ContractBase): pass elif isinstance(contract, int): contracts_list[ix] = get_one_contract(contract) else: raise Exception( 'Contract must be a Contract object or a contract id') return contracts_list
def test_feedback(self): ''' Test wexplorer contract feedback mechanism ''' self.assert200(self.client.get('/wexplorer/contracts/1/feedback')) self.assert_template_used('wexplorer/feedback.html') self.assert404(self.client.get('/wexplorer/contracts/1000/feedback')) contract = get_one_contract(1) # assert data validation bad_post = self.client.post('/wexplorer/contracts/1/feedback', data=dict(sender='JUNK')) self.assert200(bad_post) # correct template self.assert_template_used('wexplorer/feedback.html') # two alerts self.assertTrue(bad_post.data.count('alert-danger'), 2) # feedback is required self.assertTrue(bad_post.data.count('field is required'), 1) # email must be email self.assertTrue(bad_post.data.count('Invalid'), 1) # assert email works properly self.login_user(self.admin_user) with mail.record_messages() as outbox: success_post = self.client.post('/wexplorer/contracts/1/feedback', data=dict(body='test')) # the mail sent self.assertEquals(len(outbox), 1) # it went to the right place self.assertTrue( current_app.config['ADMIN_EMAIL'] in outbox[0].send_to) # assert the subject is right self.assertTrue(str(contract.id) in outbox[0].subject) self.assertTrue(contract.description in outbox[0].subject) # the message body contains the right email address self.assertTrue(self.admin_user.email in outbox[0].html) # it redirects and flashes correctly self.assertEquals(success_post.status_code, 302) self.assertEquals(success_post.location, 'http://localhost/wexplorer/contracts/1') self.assert_flashes('Thank you for your feedback!', 'alert-success')
def contract(contract_id): contract = get_one_contract(contract_id) if contract: current_app.logger.info('WEXCONTRACT - Viewed contract page {}'.format( contract.description)) departments = set([i.department for i in contract.followers]) return dict(contract=contract, departments=departments, choices=DEPARTMENT_CHOICES[1:], path='{path}?{query}'.format(path=request.path, query=request.query_string)) abort(404)
def test_feedback(self): ''' Test wexplorer contract feedback mechanism ''' self.assert200(self.client.get('/wexplorer/contracts/1/feedback')) self.assert_template_used('wexplorer/feedback.html') self.assert404(self.client.get('/wexplorer/contracts/1000/feedback')) contract = get_one_contract(1) # assert data validation bad_post = self.client.post('/wexplorer/contracts/1/feedback', data=dict( sender='JUNK' )) self.assert200(bad_post) # correct template self.assert_template_used('wexplorer/feedback.html') # two alerts self.assertTrue(bad_post.data.count('alert-danger'), 2) # feedback is required self.assertTrue(bad_post.data.count('field is required'), 1) # email must be email self.assertTrue(bad_post.data.count('Invalid'), 1) # assert email works properly self.login_user(self.admin_user) with mail.record_messages() as outbox: success_post = self.client.post('/wexplorer/contracts/1/feedback', data=dict( body='test' )) # the mail sent self.assertEquals(len(outbox), 1) # it went to the right place self.assertTrue(current_app.config['ADMIN_EMAIL'] in outbox[0].send_to) # assert the subject is right self.assertTrue(str(contract.id) in outbox[0].subject) self.assertTrue(contract.description in outbox[0].subject) # the message body contains the right email address self.assertTrue(self.admin_user.email in outbox[0].html) # it redirects and flashes correctly self.assertEquals(success_post.status_code, 302) self.assertEquals(success_post.location, 'http://localhost/wexplorer/contracts/1') self.assert_flashes('Thank you for your feedback!', 'alert-success')
def feedback(contract_id): ''' Allow user to send feedback on the data present in a specific contract ''' contract = get_one_contract(contract_id) search_form = SearchForm() if contract: form = FeedbackForm() if not current_user.is_anonymous(): form.sender.data = current_user.email if form.validate_on_submit(): current_app.logger.info( 'WEXFEEDBACK - Feedback from {email} about {contract}'.format( email=form.sender.data, contract=contract.description)) feedback_sent = wexplorer_feedback(contract, form.data.get('sender'), form.data.get('body')) if feedback_sent: flash('Thank you for your feedback!', 'alert-success') else: flash('Oh no! Something went wrong. We are looking into it.', 'alert-danger') return redirect( url_for('wexplorer.contract', contract_id=contract.id)) return render_template('wexplorer/feedback.html', search_form=search_form, contract=contract, choices=DEPARTMENT_CHOICES[1:], feedback_form=form) abort(404)
def transition_stage(contract_id, destination=None, contract=None, stages=None, user=None): '''Transitions a contract from one stage to another Stages are organized a bit like a finite state machine. The "flow" dictates the order of the states. Because these are linear, we can get everything that we need out of the properties of the contract. If there is a "destination" stage, then we need to transition all the way to that stage, marking everything in-between as complete. Otherwise, if the contract doesn't have a current stage, it should enter the first stage of its flow. If it does, then it should exit that and and move into the next stage. If we are trying to transition out of the final stage of the flow, then we need to create a clone of the contract. Optionally, takes the actual contract object and stages. We can always grab the objects if we need them, but they are optional to increase speed. ''' # grab the contract contract = contract if contract else get_one_contract(contract_id) stages = stages if stages else contract.flow.stage_order # implement the case where we have a final destination in mind if destination: current_stage_idx = stages.index(contract.current_stage_id) destination_idx = stages.index(destination) # if its next, just transition as if it were normal if destination_idx == current_stage_idx + 1: return transition_stage(contract_id, contract=contract, stages=stages) # if it is greater, raise an error. you can't skip stages. elif destination_idx > current_stage_idx: raise Exception('You cannot skip multiple stages') # if it is less, we have to revert stages else: reversion = _perform_revert(contract, stages, current_stage_idx, destination_idx, user) db.session.commit() return reversion, contract, False # implement first case -- current stage is none elif contract.current_stage_id is None: try: transition = _perform_transition(contract, stages=[stages[0]], single_enter=True) db.session.commit() return transition[0], contract, False except Exception: db.session.rollback() raise # implement the second case -- current stage is last stage elif contract.current_stage_id == contract.flow.stage_order[-1]: # complete the contract current_stage_idx = stages.index(contract.current_stage_id) try: transition = _perform_transition( contract, stages=[stages[current_stage_idx]], single_enter=False) new_contract = clone_a_contract(contract) return transition[0], new_contract, True except Exception: raise db.session.rollback() # implement final case -- transitioning to new stage else: current_stage_idx = stages.index(contract.current_stage_id) try: transition = _perform_transition(contract, stages=[ stages[current_stage_idx], stages[current_stage_idx + 1] ]) db.session.commit() return transition[1], contract, False except Exception: db.session.rollback() raise
def transition_stage(contract_id, destination=None, contract=None, stages=None, user=None): '''Transitions a contract from one stage to another Stages are organized a bit like a finite state machine. The "flow" dictates the order of the states. Because these are linear, we can get everything that we need out of the properties of the contract. If there is a "destination" stage, then we need to transition all the way to that stage, marking everything in-between as complete. Otherwise, if the contract doesn't have a current stage, it should enter the first stage of its flow. If it does, then it should exit that and and move into the next stage. If we are trying to transition out of the final stage of the flow, then we need to create a clone of the contract. Optionally, takes the actual contract object and stages. We can always grab the objects if we need them, but they are optional to increase speed. ''' # grab the contract contract = contract if contract else get_one_contract(contract_id) stages = stages if stages else contract.flow.stage_order # implement the case where we have a final destination in mind if destination: current_stage_idx = stages.index(contract.current_stage_id) destination_idx = stages.index(destination) # if its next, just transition as if it were normal if destination_idx == current_stage_idx + 1: return transition_stage(contract_id, contract=contract, stages=stages) # if it is greater, raise an error. you can't skip stages. elif destination_idx > current_stage_idx: raise Exception('You cannot skip multiple stages') # if it is less, we have to revert stages else: reversion = _perform_revert( contract, stages, current_stage_idx, destination_idx, user ) db.session.commit() return reversion, contract, False # implement first case -- current stage is none elif contract.current_stage_id is None: try: transition = _perform_transition( contract, stages=[stages[0]], single_enter=True ) db.session.commit() return transition[0], contract, False except Exception: db.session.rollback() raise # implement the second case -- current stage is last stage elif contract.current_stage_id == contract.flow.stage_order[-1]: # complete the contract current_stage_idx = stages.index(contract.current_stage_id) try: transition = _perform_transition( contract, stages=[stages[current_stage_idx]], single_enter=False ) new_contract = clone_a_contract(contract) return transition[0], new_contract, True except Exception: raise db.session.rollback() # implement final case -- transitioning to new stage else: current_stage_idx = stages.index(contract.current_stage_id) try: transition = _perform_transition( contract, stages=[ stages[current_stage_idx], stages[current_stage_idx + 1] ] ) db.session.commit() return transition[1], contract, False except Exception: db.session.rollback() raise