更新登录页及优化相关功能
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
"""日期报表查询与响应回归,仅读取生成的查询,不连接数据库。"""
|
||||
|
||||
import unittest
|
||||
from datetime import date
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from common.vo import PageModel
|
||||
from module_business.dao.report_dao import ReportDao
|
||||
from module_business.domain.test_batch_scope import TestBatchScope
|
||||
from module_business.entity.vo.report_vo import (
|
||||
ConsumptionReportModel, ConsumptionReportQueryModel,
|
||||
PalletInventoryReportModel, PalletInventoryReportQueryModel,
|
||||
PalletTraceReportModel, PalletTraceReportQueryModel,
|
||||
ReturnReportModel, ReturnReportQueryModel,
|
||||
)
|
||||
from module_business.service.report_service import ReportService
|
||||
from tests.module_business.test_report_service import make_user, report_row
|
||||
from tests.module_business.test_report_tunnel import joins, sql
|
||||
|
||||
|
||||
REPORTS = (
|
||||
('pallet_inventory', PalletInventoryReportModel, PalletInventoryReportQueryModel, 'active_filling'),
|
||||
('consumption_report', ConsumptionReportModel, ConsumptionReportQueryModel, 'biz_filling_record'),
|
||||
('return_report', ReturnReportModel, ReturnReportQueryModel, 'return_filling'),
|
||||
('pallet_trace', PalletTraceReportModel, PalletTraceReportQueryModel, 'trace_filling'),
|
||||
)
|
||||
|
||||
|
||||
class TestReportDates(unittest.IsolatedAsyncioTestCase):
|
||||
async def statement(self, name, query, batch_id=None):
|
||||
page = PageModel(rows=[], total=0, pageNum=1, pageSize=10, hasNext=False)
|
||||
with patch.object(ReportDao, '_paginate', AsyncMock(return_value=page)) as paginate:
|
||||
await getattr(ReportDao, f'get_{name}_list')(
|
||||
None, query, TestBatchScope(batch_id, 'TEST' if batch_id else 'FORMAL', None, False),
|
||||
)
|
||||
return paginate.await_args.args[1]
|
||||
|
||||
async def test_dates_are_selected_from_the_referenced_filling_not_operation_time(self):
|
||||
for name, _, query_type, alias in REPORTS:
|
||||
with self.subTest(report=name):
|
||||
statement = await self.statement(name, query_type())
|
||||
for field in ('production_date', 'expiry_date'):
|
||||
self.assertIn(field, statement.selected_columns.keys())
|
||||
self.assertEqual(f'{alias}.{field}', sql(statement.selected_columns[field].element))
|
||||
if name != 'pallet_inventory':
|
||||
self.assertNotIn('biz_pallet_inventory', sql(statement))
|
||||
expected_join = {
|
||||
'pallet_inventory': 'active_filling.filling_id = biz_pallet_inventory.active_filling_id',
|
||||
'consumption_report': 'biz_filling_record.filling_id = biz_usage_record.active_filling_id',
|
||||
'return_report': 'return_filling.filling_id = biz_return_item.active_filling_id_snapshot',
|
||||
}.get(name)
|
||||
if expected_join:
|
||||
self.assertIn(expected_join, sql(statement))
|
||||
|
||||
async def test_trace_resolves_original_filling_by_event_source_and_same_pallet(self):
|
||||
statement = await self.statement('pallet_trace', PalletTraceReportQueryModel())
|
||||
self.assertIn('production_date', statement.selected_columns.keys())
|
||||
query = sql(statement)
|
||||
for source, reference in (
|
||||
('FILLING', 'biz_pallet_event.source_id'),
|
||||
('USAGE', 'trace_usage.active_filling_id'),
|
||||
('RETURN', 'trace_return_item.active_filling_id_snapshot'),
|
||||
('SHIPMENT', 'trace_shipment_item.active_filling_id'),
|
||||
):
|
||||
self.assertIn(f"WHEN (biz_pallet_event.source_type = '{source}') THEN {reference}", query)
|
||||
for alias, id_field in (('trace_usage', 'usage_id'), ('trace_shipment_item', 'shipment_id')):
|
||||
self.assertIn(f'{alias}.{id_field} = biz_pallet_event.source_id', query)
|
||||
self.assertIn(f'{alias}.pallet_id = biz_pallet_event.pallet_id', query)
|
||||
self.assertIn('trace_filling.pallet_id = biz_pallet_event.pallet_id', query)
|
||||
self.assertNotIn('biz_pallet_inventory', query)
|
||||
|
||||
async def test_tunnel_entry_resolves_prior_filling_event_not_later_refill(self):
|
||||
statement = await self.statement('pallet_trace', PalletTraceReportQueryModel())
|
||||
query = sql(statement)
|
||||
self.assertIn('SELECT prior_filling_event.source_id', query)
|
||||
self.assertIn('prior_filling_event.pallet_id = biz_pallet_event.pallet_id', query)
|
||||
self.assertIn('prior_filling_event.event_seq < biz_pallet_event.event_seq', query)
|
||||
self.assertIn("prior_filling_event.event_type = 'FILLING_CONFIRMED'", query)
|
||||
self.assertIn('ORDER BY prior_filling_event.event_seq DESC', query)
|
||||
self.assertIn('LIMIT 1', query)
|
||||
|
||||
async def test_trace_date_joins_are_optional_and_batch_isolated(self):
|
||||
for batch_id, predicate in ((None, 'IS NULL'), (41, '= 41')):
|
||||
with self.subTest(batch_id=batch_id):
|
||||
statement = await self.statement('pallet_trace', PalletTraceReportQueryModel(), batch_id)
|
||||
all_joins = {join.right.name: join for join in joins(statement)}
|
||||
for alias, key in (
|
||||
('trace_usage', 'usage_id'), ('trace_shipment_item', 'shipment_item_id'),
|
||||
('trace_filling', 'filling_id'),
|
||||
):
|
||||
self.assertIn(alias, all_joins)
|
||||
self.assertTrue(all_joins[alias].isouter)
|
||||
self.assertIn(f'({alias}.{key} IS NULL OR {alias}.test_batch_id {predicate})', sql(statement))
|
||||
self.assertIn(f'prior_filling_event.test_batch_id {predicate}', sql(statement))
|
||||
|
||||
async def test_response_preserves_original_date_and_null_as_iso_calendar_dates(self):
|
||||
for name, model_type, query_type, _ in REPORTS:
|
||||
for production, expiry, expected in (
|
||||
(date(2025, 12, 31), date(2026, 12, 31), ('2025-12-31', '2026-12-31')),
|
||||
(None, None, (None, None)),
|
||||
):
|
||||
with self.subTest(report=name, production=production):
|
||||
row = dict(report_row(model_type), production_date=production, expiry_date=expiry)
|
||||
page = PageModel(rows=[row], total=1, pageNum=1, pageSize=10, hasNext=False)
|
||||
with patch.object(ReportDao, f'get_{name}_list', AsyncMock(return_value=page)):
|
||||
result = await getattr(ReportService, f'get_{name}_list_services')(
|
||||
None, query_type(), make_user(1), TestBatchScope.formal(),
|
||||
)
|
||||
actual = result.rows[0].model_dump(mode='json', by_alias=True)
|
||||
self.assertIn('productionDate', actual)
|
||||
self.assertIn('expiryDate', actual)
|
||||
self.assertEqual(expected, (actual['productionDate'], actual['expiryDate']))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user