Explorar el Código

task-7137997996:燃油系数维护MCP(地址库、燃油系数)-调整限制

chenxj hace 4 días
padre
commit
8f24ea8cf6

+ 17 - 0
tests/test_fuel_rate_tools.py

@@ -92,6 +92,23 @@ class FuelRateToolTest(unittest.TestCase):
         self.assertEqual('销售燃油', client.calls[0][2]['price_type'])
         self.assertEqual(1, len(client.calls[0][2]['items']))
 
+    def test_save_rejects_invalid_fuel_ratio(self):
+        tool = SaveFuelRateTool(api_client=FakeClient())
+        item = {
+            'conditions': [{
+                'condition': '物流产品',
+                'group': '1',
+                'condition_value': '美国专线',
+            }],
+        }
+        for ratio in ('abc', '1.2', '0.12345', True):
+            with self.assertRaises(ValueError):
+                tool.call(
+                    price_type=1,
+                    start_date='2026-10-22',
+                    items=[dict(item, fuel_ratio=ratio)],
+                )
+
     def test_save_edit_rejects_multiple_items(self):
         tool = SaveFuelRateTool(api_client=FakeClient())
         item = {

+ 25 - 0
tests/test_remote_address_tools.py

@@ -101,6 +101,31 @@ class RemoteAddressToolTest(unittest.TestCase):
             }],
         }, client.calls[0][2])
 
+    def test_save_rejects_end_postcode_without_start(self):
+        tool = SaveRemoteAddressTool(api_client=FakeClient())
+        with self.assertRaises(ValueError):
+            tool.call(
+                remote_name='美西偏远',
+                status=1,
+                details=[{'country': 'US', 'end_postcode': '90099'}],
+            )
+
+    def test_save_rejects_non_ascii_postcode(self):
+        tool = SaveRemoteAddressTool(api_client=FakeClient())
+        with self.assertRaises(ValueError):
+            tool.call(
+                remote_name='美西偏远',
+                status=1,
+                details=[{'country': 'US', 'start_postcode': '九万'}],
+            )
+
+    def test_query_rejects_overlong_text(self):
+        tool = QueryRemoteAddressListTool(api_client=FakeClient())
+        with self.assertRaises(ValueError):
+            tool.call(address_no='P' * 21)
+        with self.assertRaises(ValueError):
+            tool.call(country='USUSUSUSUSU')
+
     def test_save_edit_rejects_details(self):
         tool = SaveRemoteAddressTool(api_client=FakeClient())
         with self.assertRaises(ValueError):

+ 10 - 0
tools/query_remote_address_list.py

@@ -100,12 +100,22 @@ class QueryRemoteAddressListTool:
             'city': city,
             'postcode': postcode,
         }
+        limits = {
+            'address_no': 20,
+            'remote_name': 100,
+            'country': 10,
+            'province': 50,
+            'city': 50,
+            'postcode': 20,
+        }
         for key, value in text_fields.items():
             if value is None:
                 continue
             if not isinstance(value, str):
                 raise ValueError(key + ' is invalid')
             value = value.strip()
+            if len(value) > limits[key]:
+                raise ValueError(key + ' is invalid')
             if value:
                 payload[key] = value
         if status is not None:

+ 21 - 2
tools/save_fuel_rate.py

@@ -163,9 +163,11 @@ def _items(items):
         if not isinstance(item, dict) or set(item) - {'fuel_ratio', 'conditions'}:
             raise ValueError('items is invalid')
         ratio = item.get('fuel_ratio')
-        if isinstance(ratio, bool) or isinstance(ratio, int) or isinstance(ratio, float):
+        if isinstance(ratio, bool):
+            raise ValueError('fuel_ratio is invalid')
+        if isinstance(ratio, (int, float)):
             ratio = '{0:.4f}'.format(ratio)
-        if not isinstance(ratio, str) or not ratio.strip() or len(ratio.strip()) > 10:
+        if not isinstance(ratio, str) or not _fuel_ratio(ratio):
             raise ValueError('fuel_ratio is invalid')
         rows.append({
             'fuel_ratio': ratio.strip(),
@@ -196,6 +198,23 @@ def _conditions(conditions):
     return rows
 
 
+def _fuel_ratio(value):
+    value = value.strip()
+    if not value or value.count('.') > 1:
+        return False
+    if '.' not in value:
+        return value in ('0', '1')
+    whole, fraction = value.split('.', 1)
+    if whole not in ('0', '1') or not fraction or len(fraction) > 4:
+        return False
+    for character in fraction:
+        if character < '0' or character > '9':
+            return False
+    if whole == '1' and fraction.strip('0') != '':
+        return False
+    return True
+
+
 def _text(value, max_length, key):
     if not isinstance(value, str) or not value.strip() or len(value.strip()) > max_length:
         raise ValueError(key + ' is invalid')

+ 5 - 1
tools/save_remote_address.py

@@ -137,13 +137,17 @@ class SaveRemoteAddressTool:
                     row[field] = value
             if not row.get('shipper_country') and not row.get('country'):
                 raise ValueError('details is invalid')
+            if row.get('shipper_end_postcode') and not row.get('shipper_start_postcode'):
+                raise ValueError('details is invalid')
+            if row.get('end_postcode') and not row.get('start_postcode'):
+                raise ValueError('details is invalid')
             rows.append(row)
         return rows
 
 
 def _postcode(value):
     for character in value:
-        if character.isalnum() or character in ' -':
+        if ('0' <= character <= '9') or ('A' <= character <= 'Z') or ('a' <= character <= 'z') or character in ' -':
             continue
         return False
     return True