dy-dashboard/tests/test_supplier_manual_code.py
2026-10-28 11:14:17 +08:00

108 lines
5.2 KiB
Python

"""Supplier creation requires a manually supplied supplier code."""
from pathlib import Path
import unittest
from unittest.mock import patch
from app import app
from routes import products
class SupplierManualCodeTest(unittest.TestCase):
def create(self, data, existing=None):
with app.test_request_context('/api/supplier/create', method='POST', json=data), \
patch.object(products, 'operation_required', return_value=True), \
patch.object(products, 'query', return_value=existing or []) as query, \
patch.object(products, 'add_operation_log'):
result = products.supplier_create.__wrapped__()
return result.get_json(), query
def test_manually_supplied_code_is_saved_without_contract_short_name(self):
payload, query = self.create({
'supplier_code': 'SUP-001',
'supplier_name': '测试供应商',
})
self.assertEqual(payload['code'], 0)
insert = next(call for call in query.call_args_list if 'INSERT INTO suppliers' in call.args[0])
self.assertEqual(insert.args[1][:2], ('SUP-001', '测试供应商'))
self.assertEqual(payload['data']['supplier_code'], 'SUP-001')
def test_code_is_required(self):
payload, query = self.create({'supplier_name': '测试供应商'})
self.assertEqual(payload['code'], 400)
self.assertIn('供应商编码不能为空', payload['msg'])
query.assert_not_called()
def test_duplicate_code_is_rejected(self):
payload, query = self.create(
{'supplier_code': 'SUP-001', 'supplier_name': '测试供应商'},
existing=[{'id': 12}],
)
self.assertEqual(payload['code'], 400)
self.assertIn('已存在', payload['msg'])
self.assertEqual(query.call_count, 1)
self.assertFalse(any('INSERT INTO suppliers' in call.args[0] for call in query.call_args_list))
def test_contract_short_name_remains_optional_and_uppercase_when_present(self):
payload, _ = self.create({
'supplier_code': 'SUP-002',
'supplier_name': '测试供应商',
'contract_short_name': 'ABC',
})
self.assertEqual(payload['code'], 0)
invalid, query = self.create({
'supplier_code': 'SUP-003',
'supplier_name': '测试供应商',
'contract_short_name': 'abc',
})
self.assertEqual(invalid['code'], 400)
query.assert_not_called()
def test_frontend_asks_for_manual_code(self):
source = (Path(__file__).resolve().parents[1] / 'static/js/app.js').read_text(encoding='utf-8')
self.assertIn('id="newSupCode"', source)
self.assertIn('supplier_code: code', source)
self.assertNotIn('供应商编码由系统自动生成', source)
self.assertNotIn('CGHTDY-合同简称-生成日期-6位随机码', source)
def test_edit_modal_exposes_supplier_code(self):
source = (Path(__file__).resolve().parents[1] / 'static/js/app.js').read_text(encoding='utf-8')
self.assertIn("{label:'供应商编码', id:'es_code', val:s.supplier_code || code, type:'text'}", source)
self.assertIn("supplier_code: newCode", source)
def test_code_change_updates_supplier_and_live_references_transactionally(self):
from unittest.mock import MagicMock
conn = MagicMock()
cur = conn.cursor.return_value.__enter__.return_value
cur.fetchone.side_effect = [{'id': 4}, None]
with app.test_request_context('/api/supplier/update', method='POST', json={
'supplier_code': 'OLD', 'fields': {'supplier_code': 'NEW', 'supplier_name': '供应商'}
}), patch.object(products, 'operation_required', return_value=True), \
patch.object(products, 'get_db', return_value=conn), \
patch.object(products, 'add_operation_log'):
response = products.supplier_update.__wrapped__().get_json()
self.assertEqual(response['code'], 0)
updates = [call.args for call in cur.execute.call_args_list]
self.assertIn(('UPDATE products SET supplier_code=%s WHERE supplier_code=%s', ('NEW', 'OLD')), updates)
self.assertIn(('UPDATE new_product_bom SET supplier_code=%s WHERE supplier_code=%s', ('NEW', 'OLD')), updates)
conn.commit.assert_called_once()
conn.close.assert_called_once()
def test_edit_rejects_duplicate_supplier_code_without_updates(self):
from unittest.mock import MagicMock
conn = MagicMock()
cur = conn.cursor.return_value.__enter__.return_value
cur.fetchone.side_effect = [{'id': 4}, {'id': 5}]
with app.test_request_context('/api/supplier/update', method='POST', json={
'supplier_code': 'OLD', 'fields': {'supplier_code': 'USED'}
}), patch.object(products, 'operation_required', return_value=True), \
patch.object(products, 'get_db', return_value=conn):
response = products.supplier_update.__wrapped__()
self.assertEqual(response.get_json()['code'], 400)
self.assertEqual(cur.execute.call_count, 2)
conn.rollback.assert_called_once()
conn.commit.assert_not_called()
if __name__ == '__main__':
unittest.main()