test_query_track_tool.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import json
  2. import unittest
  3. from tools.query_track import QueryTrackTool
  4. class MockApiClient:
  5. def __init__(self, response=None):
  6. self.response = response or {}
  7. self.last_call = None
  8. def call_tool(self, tool_code, route_path, payload, request_id):
  9. self.last_call = {
  10. 'tool_code': tool_code,
  11. 'route_path': route_path,
  12. 'payload': payload,
  13. 'request_id': request_id,
  14. }
  15. return self.response
  16. class TestQueryTrackTool(unittest.TestCase):
  17. def test_metadata_structure(self):
  18. tool = QueryTrackTool()
  19. meta = tool.metadata()
  20. self.assertEqual(meta['name'], 'query_track')
  21. self.assertIn('description', meta)
  22. self.assertIn('input_schema', meta)
  23. schema = meta['input_schema']
  24. self.assertEqual(schema['type'], 'object')
  25. self.assertIn('order_id', schema['properties'])
  26. self.assertIn('order_number', schema['properties'])
  27. self.assertIn('tracking_number', schema['properties'])
  28. self.assertIn('page', schema['properties'])
  29. self.assertIn('limit', schema['properties'])
  30. self.assertIn('订单号或排舱单号', meta['description'])
  31. self.assertIn('跟踪号、柜号或快递单号', meta['description'])
  32. self.assertIn(
  33. '订单号、排舱单号、跟踪号、柜号还是快递单号',
  34. meta['description'],
  35. )
  36. self.assertIn(
  37. '订单号或排舱单号',
  38. schema['properties']['order_number']['description'],
  39. )
  40. self.assertIn(
  41. '跟踪号、柜号或快递单号',
  42. schema['properties']['tracking_number']['description'],
  43. )
  44. # order_id and order_number are optional but at least one is required
  45. def test_call_with_minimal_params(self):
  46. mock_response = {
  47. 'summary': 'Found 2 tracks',
  48. 'records': [],
  49. 'tips': [],
  50. 'meta': {'page': 1, 'limit': 5, 'total': 2},
  51. }
  52. client = MockApiClient(mock_response)
  53. tool = QueryTrackTool(api_client=client)
  54. result = tool.call(order_id=123)
  55. self.assertEqual(result, mock_response)
  56. self.assertEqual(client.last_call['tool_code'], 'query_track')
  57. self.assertEqual(client.last_call['route_path'], '/mcp/tools/queryTrack')
  58. self.assertEqual(client.last_call['payload']['order_id'], 123)
  59. self.assertEqual(client.last_call['payload']['page'], 1)
  60. self.assertEqual(client.last_call['payload']['limit'], 5)
  61. def test_call_with_order_number(self):
  62. mock_response = {'summary': 'ok'}
  63. client = MockApiClient(mock_response)
  64. tool = QueryTrackTool(api_client=client)
  65. result = tool.call(order_number='USC26070371955')
  66. self.assertEqual(client.last_call['payload']['order_number'], 'USC26070371955')
  67. self.assertNotIn('order_id', client.last_call['payload'])
  68. self.assertEqual(client.last_call['payload']['page'], 1)
  69. self.assertEqual(client.last_call['payload']['limit'], 5)
  70. def test_call_with_tracking_number(self):
  71. mock_response = {'summary': 'ok'}
  72. client = MockApiClient(mock_response)
  73. tool = QueryTrackTool(api_client=client)
  74. result = tool.call(tracking_number='1471904540000000301')
  75. self.assertEqual(result, mock_response)
  76. self.assertEqual(client.last_call['payload']['tracking_number'], '1471904540000000301')
  77. self.assertNotIn('order_id', client.last_call['payload'])
  78. self.assertNotIn('order_number', client.last_call['payload'])
  79. def test_call_with_all_params(self):
  80. mock_response = {'summary': 'ok'}
  81. client = MockApiClient(mock_response)
  82. tool = QueryTrackTool(api_client=client)
  83. result = tool.call(order_id=456, order_number='USC123', tracking_number='TN123', page=2, limit=10, request_id='rq_test')
  84. self.assertEqual(client.last_call['payload']['order_id'], 456)
  85. self.assertEqual(client.last_call['payload']['order_number'], 'USC123')
  86. self.assertEqual(client.last_call['payload']['tracking_number'], 'TN123')
  87. self.assertEqual(client.last_call['payload']['page'], 2)
  88. self.assertEqual(client.last_call['payload']['limit'], 10)
  89. self.assertEqual(client.last_call['request_id'], 'rq_test')
  90. def test_call_requires_api_client(self):
  91. tool = QueryTrackTool()
  92. with self.assertRaises(RuntimeError) as ctx:
  93. tool.call(order_id=123)
  94. self.assertIn('api client is required', str(ctx.exception))
  95. def test_call_requires_order_identifier(self):
  96. client = MockApiClient()
  97. tool = QueryTrackTool(api_client=client)
  98. with self.assertRaises(ValueError) as ctx:
  99. tool.call()
  100. self.assertIn('order_id, order_number or tracking_number is required', str(ctx.exception))
  101. def test_call_validates_order_id(self):
  102. client = MockApiClient()
  103. tool = QueryTrackTool(api_client=client)
  104. with self.assertRaises(ValueError) as ctx:
  105. tool.call(order_id=0)
  106. self.assertIn('must be greater than 0', str(ctx.exception))
  107. with self.assertRaises(ValueError) as ctx:
  108. tool.call(order_id=-1)
  109. self.assertIn('must be greater than 0', str(ctx.exception))
  110. def test_call_normalizes_page_and_limit(self):
  111. client = MockApiClient()
  112. tool = QueryTrackTool(api_client=client)
  113. tool.call(order_id=123, page=0, limit=200)
  114. self.assertEqual(client.last_call['payload']['page'], 1)
  115. self.assertEqual(client.last_call['payload']['limit'], 100)
  116. if __name__ == '__main__':
  117. unittest.main()