|
@@ -163,6 +163,171 @@ class RemoteAddressToolTest(unittest.TestCase):
|
|
|
})
|
|
})
|
|
|
self.assertIn('地址库没有详情,请导入', str(result))
|
|
self.assertIn('地址库没有详情,请导入', str(result))
|
|
|
|
|
|
|
|
|
|
+ def test_tools_expose_metadata_and_reject_bad_input(self):
|
|
|
|
|
+ self.assertIn('address_no', QueryRemoteAddressListTool().metadata()['input_schema']['properties'])
|
|
|
|
|
+ self.assertIn('address_no', MaintainRemoteAddressTool().metadata()['input_schema']['properties'])
|
|
|
|
|
+ self.assertIn('details', SaveRemoteAddressTool().metadata()['input_schema']['properties'])
|
|
|
|
|
+ with self.assertRaises(RuntimeError):
|
|
|
|
|
+ QueryRemoteAddressListTool().call()
|
|
|
|
|
+ with self.assertRaises(RuntimeError):
|
|
|
|
|
+ MaintainRemoteAddressTool().call()
|
|
|
|
|
+ with self.assertRaises(RuntimeError):
|
|
|
|
|
+ SaveRemoteAddressTool().call(remote_name='美西', status=1, details=[{'country': 'US'}])
|
|
|
|
|
+
|
|
|
|
|
+ query = QueryRemoteAddressListTool(api_client=FakeClient())
|
|
|
|
|
+ for kwargs in (
|
|
|
|
|
+ {'country': 1},
|
|
|
|
|
+ {'status': True},
|
|
|
|
|
+ {'status': 2},
|
|
|
|
|
+ {'page': True},
|
|
|
|
|
+ {'page': 0},
|
|
|
|
|
+ {'limit': 101},
|
|
|
|
|
+ ):
|
|
|
|
|
+ with self.assertRaises(ValueError):
|
|
|
|
|
+ query.call(**kwargs)
|
|
|
|
|
+ query.call(province='CA', city='LA', remote_name=' ')
|
|
|
|
|
+
|
|
|
|
|
+ maintain = MaintainRemoteAddressTool(api_client=FakeClient())
|
|
|
|
|
+ with self.assertRaises(ValueError):
|
|
|
|
|
+ maintain.call(address_no=12)
|
|
|
|
|
+ with self.assertRaises(ValueError):
|
|
|
|
|
+ maintain.call(page=True)
|
|
|
|
|
+ with self.assertRaises(ValueError):
|
|
|
|
|
+ maintain.call(limit=0)
|
|
|
|
|
+ maintain.call(address_no=' ')
|
|
|
|
|
+ maintain.call(address_no=' PY12 ')
|
|
|
|
|
+
|
|
|
|
|
+ save = SaveRemoteAddressTool(api_client=FakeClient())
|
|
|
|
|
+ detail = {'country': 'US', 'province': '', 'start_postcode': 'A 1-b'}
|
|
|
|
|
+ for kwargs in (
|
|
|
|
|
+ {'remote_name': 1, 'status': 1, 'details': [detail]},
|
|
|
|
|
+ {'remote_name': ' ', 'status': 1, 'details': [detail]},
|
|
|
|
|
+ {'remote_name': '名' * 101, 'status': 1, 'details': [detail]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': True, 'details': [detail]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 2, 'details': [detail]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'address_no': 1, 'details': [detail]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'address_no': 'P' * 21, 'details': [detail]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': 'US'},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': []},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': [{'country': 'US'}] * 201},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': ['US']},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': [{'country': 'US', 'extra': '1'}]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': [{'country': 1}]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': [{'country': 'U' * 51}]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': [{'province': 'CA'}]},
|
|
|
|
|
+ {'remote_name': '美西', 'status': 1, 'details': [{'shipper_country': 'CN', 'shipper_end_postcode': '518099'}]},
|
|
|
|
|
+ ):
|
|
|
|
|
+ with self.assertRaises(ValueError):
|
|
|
|
|
+ save.call(**kwargs)
|
|
|
|
|
+ client = FakeClient()
|
|
|
|
|
+ SaveRemoteAddressTool(api_client=client).call(
|
|
|
|
|
+ remote_name='美西',
|
|
|
|
|
+ status=1,
|
|
|
|
|
+ address_no=' ',
|
|
|
|
|
+ details=[detail],
|
|
|
|
|
+ )
|
|
|
|
|
+ self.assertNotIn('address_no', client.calls[0][2])
|
|
|
|
|
+ SaveRemoteAddressTool(api_client=client).call(
|
|
|
|
|
+ address_no='PY12',
|
|
|
|
|
+ remote_name='美西',
|
|
|
|
|
+ status=0,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ def test_presenter_rejects_bad_maintain_and_save_payloads(self):
|
|
|
|
|
+ presenter = OutputPresenter()
|
|
|
|
|
+ columns = [
|
|
|
|
|
+ {'key': key, 'name': name}
|
|
|
|
|
+ for key, name in OutputPresenter.REMOTE_ADDRESS_DETAIL_COLUMNS
|
|
|
|
|
+ ]
|
|
|
|
|
+ record = {key: '' for key, _name in OutputPresenter.REMOTE_ADDRESS_DETAIL_COLUMNS}
|
|
|
|
|
+ base = {
|
|
|
|
|
+ 'summary': '准备新增地址库',
|
|
|
|
|
+ 'mode_text': '新增',
|
|
|
|
|
+ 'address_no': '',
|
|
|
|
|
+ 'remote_name': '',
|
|
|
|
|
+ 'status_text': '',
|
|
|
|
|
+ 'temp_key': 'temp',
|
|
|
|
|
+ 'columns': columns,
|
|
|
|
|
+ 'records': [record],
|
|
|
|
|
+ }
|
|
|
|
|
+ bad_payloads = [None, dict(base, extra=1), dict(base, mode_text='查看')]
|
|
|
|
|
+ missing = dict(base)
|
|
|
|
|
+ missing.pop('summary')
|
|
|
|
|
+ bad_payloads.append(missing)
|
|
|
|
|
+ bad_payloads.append(dict(base, summary=1))
|
|
|
|
|
+ bad_payloads.append(dict(base, columns=[]))
|
|
|
|
|
+ bad_payloads.append(dict(base, records={}))
|
|
|
|
|
+ bad_columns = [dict(column) for column in columns]
|
|
|
|
|
+ bad_columns[0] = {'key': 'other', 'name': columns[0]['name']}
|
|
|
|
|
+ bad_payloads.append(dict(base, columns=bad_columns))
|
|
|
|
|
+ bad_payloads.append(dict(base, records=[{}]))
|
|
|
|
|
+ for data in bad_payloads:
|
|
|
|
|
+ result = presenter.present('maintain_remote_address', {
|
|
|
|
|
+ 'code': 'MCP_0000',
|
|
|
|
|
+ 'msg': 'success',
|
|
|
|
|
+ 'data': data,
|
|
|
|
|
+ 'meta': {'request_id': 'rq_maintain'},
|
|
|
|
|
+ })
|
|
|
|
|
+ self.assertIn('格式异常', str(result))
|
|
|
|
|
+
|
|
|
|
|
+ tipped = dict(base, tips=['该地址库还没有地址明细'])
|
|
|
|
|
+ tipped_result = presenter.present('maintain_remote_address', {
|
|
|
|
|
+ 'code': 'MCP_0000',
|
|
|
|
|
+ 'msg': 'success',
|
|
|
|
|
+ 'data': tipped,
|
|
|
|
|
+ 'meta': {'request_id': 'rq_maintain'},
|
|
|
|
|
+ })
|
|
|
|
|
+ self.assertIn('该地址库还没有地址明细', str(tipped_result))
|
|
|
|
|
+
|
|
|
|
|
+ saved = {
|
|
|
|
|
+ 'summary': '已新增地址库 PY12 美西,状态启用',
|
|
|
|
|
+ 'mode_text': '新增',
|
|
|
|
|
+ 'address_no': 'PY12',
|
|
|
|
|
+ 'remote_name': '美西',
|
|
|
|
|
+ 'status_text': '启用',
|
|
|
|
|
+ }
|
|
|
|
|
+ for data in (
|
|
|
|
|
+ dict(saved, extra=1),
|
|
|
|
|
+ dict(saved, mode_text='查看'),
|
|
|
|
|
+ dict(saved, status_text='草稿'),
|
|
|
|
|
+ dict(saved, address_no='12'),
|
|
|
|
|
+ dict(saved, remote_name=' '),
|
|
|
|
|
+ dict(saved, summary=1),
|
|
|
|
|
+ ):
|
|
|
|
|
+ result = presenter.present('save_remote_address', {
|
|
|
|
|
+ 'code': 'MCP_0000',
|
|
|
|
|
+ 'msg': 'success',
|
|
|
|
|
+ 'data': data,
|
|
|
|
|
+ 'meta': {'request_id': 'rq_save_remote'},
|
|
|
|
|
+ })
|
|
|
|
|
+ self.assertIn('格式异常', str(result))
|
|
|
|
|
+
|
|
|
|
|
+ for message in (
|
|
|
|
|
+ '一次最多保存200条地址明细',
|
|
|
|
|
+ '第1条收件人邮编不正确',
|
|
|
|
|
+ '不能保存',
|
|
|
|
|
+ ):
|
|
|
|
|
+ result = presenter.present('save_remote_address', {
|
|
|
|
|
+ 'code': 'MCP_1401',
|
|
|
|
|
+ 'msg': message,
|
|
|
|
|
+ 'data': {},
|
|
|
|
|
+ 'meta': {'request_id': 'rq_save_remote'},
|
|
|
|
|
+ })
|
|
|
|
|
+ rendered = str(result)
|
|
|
|
|
+ if message == '不能保存':
|
|
|
|
|
+ self.assertIn('参数不正确', rendered)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.assertIn(message, rendered)
|
|
|
|
|
+ for tool_name in ('maintain_remote_address', 'save_remote_address'):
|
|
|
|
|
+ result = presenter.present(tool_name, {
|
|
|
|
|
+ 'code': 'MCP_1501',
|
|
|
|
|
+ 'msg': '地址库不存在',
|
|
|
|
|
+ 'data': {},
|
|
|
|
|
+ 'meta': {'request_id': 'rq_missing'},
|
|
|
|
|
+ })
|
|
|
|
|
+ self.assertIn('地址库不存在', str(result))
|
|
|
|
|
+
|
|
|
|
|
|
|
|
class FakeClient:
|
|
class FakeClient:
|
|
|
def __init__(self):
|
|
def __init__(self):
|