class AsyncTest(TestCase): def setUp(self): self.now = datetime.now() self.u1 = User(username='******', display='用户1') self.u1.save() self.wf1 = SqlWorkflow(workflow_name='some_name2', group_id=1, group_name='g1', engineer=self.u1.username, engineer_display=self.u1.display, audit_auth_groups='some_group', create_time=self.now - timedelta(days=1), status='workflow_executing', is_backup='是', instance_name='some_instance', db_name='some_db', sql_content='some_sql', sql_syntax=1, execute_result='') self.wf1.save() # 初始化工单执行返回对象 self.task_result = MagicMock() self.task_result.args = [self.wf1.id] self.task_result.success = True self.task_result.stopped = self.now self.task_result.result.json.return_value = json.dumps([{ 'id': 1, 'sql': 'some_content' }]) self.task_result.result.warning = '' self.task_result.result.error = '' def tearDown(self): self.wf1.delete() self.u1.delete() self.task_result = None @patch('sql.utils.execute_sql.notify_for_execute') @patch('sql.utils.execute_sql.Audit') def test_call_back(self, mock_audit, mock_notify): mock_audit.detail_by_workflow_id.return_value.audit_id = 123 mock_audit.add_log.return_value = 'any thing' execute_callback(self.task_result) mock_audit.detail_by_workflow_id.assert_called_with( workflow_id=self.wf1.id, workflow_type=ANY) mock_audit.add_log.assert_called_with( audit_id=123, operation_type=ANY, operation_type_desc=ANY, operation_info="执行结果:已正常结束", operator=ANY, operator_display=ANY, ) mock_notify.assert_called_once()
class WorkflowViewTest(TestCase): def setUp(self): self.now = datetime.now() self.u1 = User(username='******', display='用户1') self.u1.save() self.superuser1 = User(username='******', is_superuser=True) self.superuser1.save() self.wf1 = SqlWorkflow( workflow_name='some_name', group_id=1, group_name='g1', engineer=self.u1.username, engineer_display=self.u1.display, audit_auth_groups='some_group', create_time=self.now - timedelta(days=1), status='workflow_finish', is_backup='是', instance_name='some_instance', db_name='some_db', sql_content='some_sql', sql_syntax=1, execute_result=json.dumps([{ 'id': 1, 'sql': 'some_content' }]) ) self.wf1.save() self.wf2 = SqlWorkflow( workflow_name='some_name2', group_id=1, group_name='g1', engineer=self.u1.username, engineer_display=self.u1.display, audit_auth_groups='some_group', create_time=self.now - timedelta(days=1), status='workflow_manreviewing', is_backup='是', instance_name='some_instance', db_name='some_db', sql_content='some_sql', sql_syntax=1, execute_result=json.dumps([{ 'id': 1, 'sql': 'some_content' }]) ) self.wf2.save() def tearDown(self): self.u1.delete() self.superuser1.delete() self.wf1.delete() self.wf2.delete() def testWorkflowStatus(self): c = Client(header={}) c.force_login(self.u1) r = c.post('/getWorkflowStatus/', {'workflow_id': self.wf1.id}) r_json = r.json() self.assertEqual(r_json['status'], 'workflow_finish') @patch('sql.utils.workflow_audit.Audit.review_info') @patch('sql.utils.workflow_audit.Audit.can_review') def testWorkflowDetailView(self, _can_review, _review_info): _review_info.return_value = ('some_auth_group', 'current_auth_group') _can_review.return_value = False c = Client() c.force_login(self.u1) r = c.get('/detail/{}/'.format(self.wf1.id)) expected_status_display = r"""id="workflow_detail_disaply">已正常结束""" self.assertContains(r, expected_status_display) exepcted_status = r"""id="workflow_detail_status">workflow_finish""" self.assertContains(r, exepcted_status) def testWorkflowListView(self): c = Client() c.force_login(self.superuser1) r = c.post('/sqlworkflow_list/', {'limit': 10, 'offset': 0, 'navStatus': 'all'}) r_json = r.json() self.assertEqual(r_json['total'], 2) # 列表按创建时间倒序排列, 第二个是wf1 , 是已正常结束 self.assertEqual(r_json['rows'][1]['status'], 'workflow_finish') @patch('sql.utils.workflow_audit.Audit.detail_by_workflow_id') @patch('sql.utils.workflow_audit.Audit.audit') @patch('sql.utils.workflow_audit.Audit.can_review') def testWorkflowPassedView(self, _can_review, _audit, _detail_by_id): c = Client() c.force_login(self.superuser1) r = c.post('/passed/') self.assertContains(r, 'workflow_id参数为空.') _can_review.return_value = False r = c.post('/passed/', {'workflow_id': self.wf1.id}) self.assertContains(r, '你无权操作当前工单!') _can_review.return_value = True _detail_by_id.return_value.audit_id = 123 _audit.return_value = { "data": { "workflow_status": 1 # TODO 改为audit_success } } r = c.post('/passed/', data={'workflow_id': self.wf1.id, 'audit_remark': 'some_audit'}, follow=False) self.assertRedirects(r, '/detail/{}/'.format(self.wf1.id), fetch_redirect_response=False) self.wf1.refresh_from_db() self.assertEqual(self.wf1.status, 'workflow_review_pass') self.assertEqual(self.wf1.audit_remark, 'some_audit') @patch('sql.sql_workflow.Audit.add_log') @patch('sql.sql_workflow.Audit.detail_by_workflow_id') @patch('sql.sql_workflow.Audit.audit') # patch view里的can_cancel 而不是原始位置的can_cancel ,因为在调用时, 已经 import 了真的 can_cancel ,会导致mock失效 # 在import 静态函数时需要注意这一点, 动态对象因为每次都会重新生成,也可以 mock 原函数/方法/对象 # 参见 : https://docs.python.org/3/library/unittest.mock.html#where-to-patch @patch('sql.sql_workflow.can_cancel') def testWorkflowCancelView(self, _can_cancel, _audit, _detail_by_id, _add_log): c = Client() c.force_login(self.u1) r = c.post('/cancel/') self.assertContains(r, 'workflow_id参数为空.') r = c.post('/cancel/', data={'workflow_id': self.wf2.id}) self.assertContains(r, '终止原因不能为空') _can_cancel.return_value = False r = c.post('/cancel/', data={'workflow_id': self.wf2.id, 'cancel_remark': 'some_reason'}) self.assertContains(r, '你无权操作当前工单!') _can_cancel.return_value = True _detail_by_id = 123 r = c.post('/cancel/', data={'workflow_id': self.wf2.id, 'cancel_remark': 'some_reason'}) self.wf2.refresh_from_db() self.assertEqual('workflow_abort', self.wf2.status)