功能:完善加氢站导航详情与缓存刷新

This commit is contained in:
lingniu
2026-09-02 14:05:49 +08:00
parent e7ee8583aa
commit a26179c8fe
5 changed files with 151 additions and 17 deletions
+48 -1
View File
@@ -63,6 +63,30 @@ vm.runInNewContext(`
assert.equal(sandbox.regionProvinceLabels, '广东,浙江');
assert.equal(sandbox.regionCityLabels, '佛山,广州');
assert.match(sandbox.regionSearchLabels, /嘉兴/);
vm.runInNewContext(`
state.stations = [
{ id: 'sh-hp', name: '上海黄浦站', province: '上海市', city: '上海市', district: '黄浦区', longitude: 121.5, latitude: 31.2, cooperative: true },
{ id: 'sh-pd', name: '上海浦东站', province: '上海市', city: '上海市', district: '浦东新区', longitude: 121.6, latitude: 31.2, cooperative: true },
{ id: 'gd-gz', name: '广州站', province: '广东省', city: '广州市', district: '天河区', longitude: 113.3, latitude: 23.1, cooperative: true },
{ id: 'zj-hz-1', name: '杭州站一', province: '浙江省', city: '杭州市', district: '西湖区', longitude: 120.1, latitude: 30.2, cooperative: true },
{ id: 'zj-hz-2', name: '杭州站二', province: '浙江省', city: '杭州市', district: '上城区', longitude: 120.2, latitude: 30.2, cooperative: true },
{ id: 'zj-hz-3', name: '杭州站三', province: '浙江省', city: '杭州市', district: '拱墅区', longitude: 120.3, latitude: 30.2, cooperative: true }
];
globalThis.shanghaiCityOption = stationLocationOptions().find(option => option.level === 'city' && option.province === '上海市');
state.regionPicker = { level: 'province', province: '', city: '', search: '', draft: [], options: [] };
globalThis.primaryRegionLabels = regionPickerOptions().map(option => option.label).join(',');
state.regionPicker = { level: 'city', province: '上海市', city: '', search: '', draft: [], options: [] };
globalThis.shanghaiDistrictLabels = regionPickerOptions().map(option => option.label).sort().join(',');
globalThis.shanghaiPath = compactPath(['上海市', '上海市', '黄浦区']);
globalThis.shanghaiRegion = stationRegion(state.stations[0]);
globalThis.directMunicipalityFlags = ['北京市', '上海市', '天津市', '重庆市'].map(isMunicipalityProvince).join(',');
`, sandbox);
assert.equal(sandbox.shanghaiCityOption, undefined);
assert.equal(sandbox.primaryRegionLabels, '浙江,上海,广东');
assert.equal(sandbox.shanghaiDistrictLabels, '浦东新区,黄浦区');
assert.equal(sandbox.shanghaiPath, '上海市 · 黄浦区');
assert.equal(sandbox.shanghaiRegion, '上海市 · 黄浦区');
assert.equal(sandbox.directMunicipalityFlags, 'true,true,true,true');
vm.runInNewContext(`
globalThis.inferredDistrict = stationDistrictName({ province: '浙江省', city: '嘉兴市', address: '嘉兴市海盐县海盐经济开发区' });
state.locationFilters = [];
@@ -87,6 +111,26 @@ vm.runInNewContext(`
`, sandbox);
assert.equal(sandbox.multiLocationMatches.join(','), 'true,true,false');
assert.ok(Math.abs(sandbox.distanceKm([113, 23], [114, 23]) - 102.4) < 1);
assert.equal(sandbox.stationUnitPrice({ unitPrice: 12.5 }), '¥12.50 / kg');
assert.equal(sandbox.stationUnitPrice({ unitPrice: 0 }), '');
assert.match(sandbox.detailPhoneField('联系方式', '138 0000 0000'), /href="tel:13800000000"/);
vm.runInNewContext(`
const detailNodes = {
detailName: { textContent: '' }, detailRegion: { textContent: '' },
detailType: { textContent: '', classList: { toggle() {} } },
detailFields: { innerHTML: '' }, stationDetail: { hidden: true }
};
document.getElementById = id => detailNodes[id] || null;
state.map = null; state.selected = null;
selectStation({ id: 'partner-detail', name: '合作站', cooperative: true, province: '广东省', city: '广州市', district: '黄埔区', longitude: 113.3, latitude: 23.1, contactPerson: '张工', contactPhone: '138 0000 0000', unitPrice: 12.5 });
globalThis.partnerDetailHtml = detailNodes.detailFields.innerHTML;
selectStation({ id: 'external-detail', name: '外部站', cooperative: false, province: '广东省', city: '广州市', district: '黄埔区', longitude: 113.4, latitude: 23.1, contactPerson: '李工', contactPhone: '13900000000', unitPrice: 10.5 });
globalThis.externalDetailHtml = detailNodes.detailFields.innerHTML;
`, sandbox);
assert.match(sandbox.partnerDetailHtml, /张工/);
assert.match(sandbox.partnerDetailHtml, /tel:13800000000/);
assert.match(sandbox.partnerDetailHtml, /¥12\.50 \/ kg/);
assert.doesNotMatch(sandbox.externalDetailHtml, /李工|13900000000|¥10\.50/);
assert.match(source, /zoom < 11\) return 'city'/);
assert.match(source, /state\.userLocation && left\.kind === 'station'/);
assert.doesNotMatch(source, /rankSecondaryTab|setRank\(/);
@@ -106,12 +150,15 @@ assert.match(source, /focusSearchResults\(\)/);
assert.match(source, /visibleOnly && !normalize\(state\.query\)/);
assert.match(source, /station-list-partner-tag/);
assert.match(source, /station-list-partner-tag\$\{node\.cooperative \? '' : ' is-placeholder'\}/);
assert.match(source, /node\.kind === 'station' \? '' : `\$\{formatNumber\(node\.count\)\} 座`/);
assert.match(source, /const rowValue = Number\.isFinite\(distance\)/);
assert.match(source, /node\.cooperative \? 'H₂ · 合作' : ''/);
assert.doesNotMatch(source, /在线 \$\{formatNumber\(node\.online\)\}/);
assert.doesNotMatch(source, /monthlyHydrogenKg|totalHydrogenKg|vehicle/);
assert.match(source, /uri\.amap\.com\/navigation/);
assert.match(source, /window\.open\('', '_blank'\)/);
assert.doesNotMatch(source, /window\.location\.assign/);
assert.equal((source.match(/function navigateToStation\(/g) || []).length, 1);
assert.match(source, /station-list-price/);
assert.match(styles, /station-summary-strip/);
assert.match(styles, /header-kpi-group,\n \.station-navigation-shell \.station-status-card/);
assert.match(styles, /theme-switcher-bw \.bw-btn span \{ display: none; \}/);
+25
View File
@@ -2,6 +2,8 @@ import importlib.util
import io
import json
from pathlib import Path
import threading
import time
import unittest
from unittest.mock import patch
@@ -49,6 +51,29 @@ class StationNavigationTest(unittest.TestCase):
self.assertEqual(calls, ["load"])
self.assertEqual(first, second)
def test_expired_directory_returns_stale_value_while_refreshing_in_background(self):
started = threading.Event()
release = threading.Event()
def loader():
started.set()
release.wait(1)
return {"version": 2}
cache = {"station-directory": (time.time() - 121, {"version": 1})}
with patch.object(server, "_cache", cache), \
patch.object(server, "_cache_refreshing", set()), \
patch.object(server, "_cache_load_locks", {}):
result = server._cached("station-directory", 120, loader)
self.assertEqual(result, {"version": 1})
self.assertTrue(started.wait(1))
release.set()
for _ in range(100):
if cache["station-directory"][1] == {"version": 2}:
break
time.sleep(0.01)
self.assertEqual(cache["station-directory"][1], {"version": 2})
if __name__ == "__main__":
unittest.main()