forked from erp-dev/erp
feat: stateflow v2 (params required)
This commit is contained in:
374
stateflow/tests/test_parameters.py
Normal file
374
stateflow/tests/test_parameters.py
Normal file
@@ -0,0 +1,374 @@
|
||||
"""
|
||||
测试参数管理功能
|
||||
包括必填参数验证、参数记录创建、回退后参数可见性等
|
||||
"""
|
||||
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)
|
||||
Reference in New Issue
Block a user