1
0
forked from erp-dev/erp
Files
erpnew/stateflow/tests/test_parameters.py

375 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
测试参数管理功能
包括必填参数验证、参数记录创建、回退后参数可见性等
"""
from django.test import TestCase
from django.contrib.auth import get_user_model
from stateflow import models, services
User = get_user_model()
class ParameterManagementTestCase(TestCase):
"""测试参数管理功能"""
def setUp(self):
"""设置测试数据"""
# 创建测试用户
self.user = User.objects.create_user(username='testuser', password='testpass')
# 创建状态
self.state1 = models.State.objects.create(name='状态1', description='第一个状态')
self.state2 = models.State.objects.create(name='状态2', description='第二个状态')
self.state3 = models.State.objects.create(name='状态3', description='第三个状态')
# 为状态1添加必填参数
self.required_param = models.StateParameter.objects.create(
key='temperature',
value='',
is_required=True,
description='温度(必填)'
)
self.optional_param = models.StateParameter.objects.create(
key='humidity',
value='',
is_required=False,
description='湿度(可选)'
)
self.state1.parameters.add(self.required_param, self.optional_param)
# 为状态2添加必填参数
self.required_param2 = models.StateParameter.objects.create(
key='pressure',
value='',
is_required=True,
description='压力(必填)'
)
self.state2.parameters.add(self.required_param2)
# 创建流程
self.process = models.Process.objects.create(name='测试流程')
models.ProcessNode.objects.create(process=self.process, state=self.state1, order=0)
models.ProcessNode.objects.create(process=self.process, state=self.state2, order=1)
models.ProcessNode.objects.create(process=self.process, state=self.state3, order=2)
# 创建业务对象
self.business_object = models.BusinessObject.objects.create(
name='测试业务对象',
process=self.process
)
def test_advance_without_required_parameter_fails(self):
"""测试不提供必填参数时推进失败"""
# 尝试推进但不提供必填参数
success, message, state_log = services.advance_to_next_state(
self.business_object,
self.user
)
# 应该失败
self.assertFalse(success)
self.assertIn('缺失必填参数', message)
self.assertIn('temperature', message)
self.assertIsNone(state_log)
# 验证状态未改变
current_state = services.get_business_object_current_state(self.business_object)
self.assertIsNone(current_state)
# 验证没有创建状态流转记录
self.assertEqual(self.business_object.state_logs.count(), 0)
def test_advance_with_only_required_parameter_succeeds(self):
"""测试只提供必填参数时推进成功"""
# 只提供必填参数
success, message, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5' # 只提供必填的
)
# 应该成功
self.assertTrue(success)
self.assertIsNotNone(state_log)
# 验证状态已推进
current_state = services.get_business_object_current_state(self.business_object)
self.assertEqual(current_state.name, self.state1.name)
# 验证参数记录已创建
self.assertEqual(state_log.parameter_records.count(), 1)
param_record = state_log.parameter_records.first()
self.assertEqual(param_record.parameters['temperature'], '25.5')
self.assertNotIn('humidity', param_record.parameters)
def test_advance_with_all_parameters(self):
"""测试提供所有参数时推进成功"""
success, message, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5',
humidity='60%'
)
# 应该成功
self.assertTrue(success)
self.assertIsNotNone(state_log)
# 验证参数记录包含所有提供的参数
param_record = state_log.parameter_records.first()
self.assertEqual(param_record.parameters['temperature'], '25.5')
self.assertEqual(param_record.parameters['humidity'], '60%')
def test_advance_with_extra_parameters(self):
"""测试提供额外参数时也能成功(不做验证)"""
success, message, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5',
humidity='60%',
operator='张三', # 额外参数
notes='测试备注' # 额外参数
)
# 应该成功(不验证参数是否在定义中)
self.assertTrue(success)
# 验证所有参数都被保存
param_record = state_log.parameter_records.first()
self.assertEqual(len(param_record.parameters), 4)
self.assertEqual(param_record.parameters['operator'], '张三')
self.assertEqual(param_record.parameters['notes'], '测试备注')
def test_add_parameters_after_advance(self):
"""测试推进后补充参数"""
# 先推进
success, message, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5'
)
self.assertTrue(success)
# 补充参数
new_record = services.add_parameters_to_state_log(
state_log,
remark='补充测量',
humidity='65%',
inspector='李四'
)
# 验证创建了新的参数记录
self.assertEqual(state_log.parameter_records.count(), 2)
self.assertEqual(new_record.parameters['humidity'], '65%')
self.assertEqual(new_record.parameters['inspector'], '李四')
self.assertEqual(new_record.remark, '补充测量')
def test_parameter_summary_with_updates(self):
"""测试参数汇总(包含更新的值)"""
# 推进并提供初始参数
success, message, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5',
humidity='60%'
)
# 补充参数(更新 temperature
services.add_parameters_to_state_log(
state_log,
temperature='26.0', # 重新测量
remark='温度重新测量'
)
# 获取参数汇总
summary = state_log.get_all_parameters_summary()
# 验证最新值
self.assertEqual(summary['temperature'], '26.0') # 应该是更新后的值
self.assertEqual(summary['humidity'], '60%') # 保持原值
def test_parameter_history(self):
"""测试参数历史记录"""
# 推进
success, message, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5'
)
# 多次更新同一个参数
services.add_parameters_to_state_log(
state_log,
temperature='26.0',
remark='第一次重测'
)
services.add_parameters_to_state_log(
state_log,
temperature='26.5',
remark='第二次重测'
)
# 获取历史
history = state_log.get_parameter_history('temperature')
# 验证历史记录
self.assertEqual(len(history), 3)
self.assertEqual(history[0]['value'], '25.5')
self.assertEqual(history[1]['value'], '26.0')
self.assertEqual(history[1]['remark'], '第一次重测')
self.assertEqual(history[2]['value'], '26.5')
self.assertEqual(history[2]['remark'], '第二次重测')
def test_step_back_excludes_cancelled_state_parameters(self):
"""测试回退后,默认情况下查询参数时应排除已撤销状态的参数"""
# 推进两次,每次都提供参数
success, msg, state_log1 = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5',
humidity='60%'
)
self.assertTrue(success)
success, msg, state_log2 = services.advance_to_next_state(
self.business_object,
self.user,
pressure='1013'
)
self.assertTrue(success)
# 验证两个状态都有参数记录
self.assertEqual(state_log1.parameter_records.count(), 1)
self.assertEqual(state_log2.parameter_records.count(), 1)
# 回退一步(撤销 state2
success, message = services.step_back_one_state(self.business_object, self.user)
self.assertTrue(success)
# 刷新 state_log2
state_log2.refresh_from_db()
self.assertTrue(state_log2.is_cancelled)
# 默认情况下,已撤销状态的参数不可见
summary = state_log2.get_all_parameters_summary()
self.assertEqual(len(summary), 0) # 应该返回空字典
# 使用 include_cancelled=True 可以查看已撤销状态的参数
summary_with_cancelled = state_log2.get_all_parameters_summary(include_cancelled=True)
self.assertEqual(len(summary_with_cancelled), 1)
self.assertEqual(summary_with_cancelled['pressure'], '1013')
# 验证 state_log1 的参数仍然可见(未撤销)
summary1 = state_log1.get_all_parameters_summary()
self.assertEqual(len(summary1), 2)
self.assertEqual(summary1['temperature'], '25.5')
self.assertEqual(summary1['humidity'], '60%')
def test_cancelled_state_parameter_history(self):
"""测试已撤销状态的参数历史记录不可见"""
# 推进并提供参数
success, msg, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5'
)
self.assertTrue(success)
# 补充参数
services.add_parameters_to_state_log(
state_log,
temperature='26.0',
remark='重新测量'
)
# 验证参数历史存在
history = state_log.get_parameter_history('temperature')
self.assertEqual(len(history), 2)
# 回退(撤销状态)
services.step_back_one_state(self.business_object, self.user)
state_log.refresh_from_db()
# 默认情况下,已撤销状态的参数历史不可见
history = state_log.get_parameter_history('temperature')
self.assertEqual(len(history), 0)
# 使用 include_cancelled=True 可以查看
history_with_cancelled = state_log.get_parameter_history('temperature', include_cancelled=True)
self.assertEqual(len(history_with_cancelled), 2)
def test_cancelled_state_get_latest_parameter(self):
"""测试已撤销状态无法获取最新参数值"""
# 推进并提供参数
success, msg, state_log = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5'
)
self.assertTrue(success)
# 验证可以获取参数
temp = state_log.get_latest_parameter('temperature')
self.assertEqual(temp, '25.5')
# 回退(撤销状态)
services.step_back_one_state(self.business_object, self.user)
state_log.refresh_from_db()
# 默认情况下返回默认值
temp = state_log.get_latest_parameter('temperature', default='N/A')
self.assertEqual(temp, 'N/A')
# 使用 include_cancelled=True 可以获取
temp_with_cancelled = state_log.get_latest_parameter('temperature', include_cancelled=True)
self.assertEqual(temp_with_cancelled, '25.5')
def test_multiple_states_with_different_required_parameters(self):
"""测试多个状态各自的必填参数验证"""
# 推进到 state1需要 temperature
success, msg, _ = services.advance_to_next_state(
self.business_object,
self.user,
temperature='25.5'
)
self.assertTrue(success)
# 尝试推进到 state2 但不提供 pressure
success, msg, _ = services.advance_to_next_state(
self.business_object,
self.user,
temperature='26.0' # 提供了 state1 的参数,但这是 state2
)
# 应该失败(缺少 state2 的必填参数 pressure
self.assertFalse(success)
self.assertIn('缺失必填参数', msg)
self.assertIn('pressure', msg)
# 提供正确的必填参数
success, msg, _ = services.advance_to_next_state(
self.business_object,
self.user,
pressure='1013'
)
self.assertTrue(success)
def test_state_without_required_parameters_allows_advance_without_params(self):
"""测试没有必填参数的状态允许不提供参数推进"""
# 先推进两次到达 state3没有任何参数要求
services.advance_to_next_state(self.business_object, self.user, temperature='25')
services.advance_to_next_state(self.business_object, self.user, pressure='1013')
# 推进到 state3不提供任何参数
success, msg, state_log = services.advance_to_next_state(
self.business_object,
self.user
)
# 应该成功
self.assertTrue(success)
self.assertIsNotNone(state_log)
# 验证没有创建参数记录
self.assertEqual(state_log.parameter_records.count(), 0)