164 lines
4.9 KiB
Python
164 lines
4.9 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
HTML_PATH = Path("apps/web/vue3/index.html")
|
|
|
|
|
|
def _source_block(source: str, start: str, end: str) -> str:
|
|
return source[source.index(start) : source.index(end)]
|
|
|
|
|
|
def _run_node(script: str) -> dict:
|
|
completed = subprocess.run(
|
|
["node", "-e", script],
|
|
check=True,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
return json.loads(completed.stdout.strip())
|
|
|
|
|
|
def _progress_state_script(body: str) -> str:
|
|
html = HTML_PATH.read_text(encoding="utf-8")
|
|
updater = _source_block(
|
|
html,
|
|
"const updateReferenceBundleDownloadProgress =",
|
|
"const pollReferenceBundleDownloadTask =",
|
|
)
|
|
return f"""
|
|
const referenceBundleDownloadState = {{value: {{
|
|
visible: false, taskId: '', speciesLabel: '', message: '',
|
|
percentage: 0, indeterminate: true, status: '',
|
|
bytesDownloaded: 0, totalBytes: 0
|
|
}}}};
|
|
{updater}
|
|
{body}
|
|
"""
|
|
|
|
|
|
def test_unknown_total_keeps_indeterminate_progress_and_reports_downloaded_bytes() -> None:
|
|
result = _run_node(
|
|
_progress_state_script(
|
|
"""
|
|
updateReferenceBundleDownloadProgress({
|
|
id: 'task-download', status: 'running',
|
|
progress: {bytes_downloaded: 8388608, total_bytes: 0, indeterminate: true}
|
|
}, {species_name: 'Spinacia oleracea'});
|
|
console.log(JSON.stringify(referenceBundleDownloadState.value));
|
|
"""
|
|
)
|
|
)
|
|
|
|
assert result["visible"] is True
|
|
assert result["speciesLabel"] == "Spinacia oleracea"
|
|
assert result["bytesDownloaded"] == 8388608
|
|
assert result["totalBytes"] == 0
|
|
assert result["indeterminate"] is True
|
|
|
|
|
|
def test_failure_without_new_progress_preserves_last_downloaded_bytes() -> None:
|
|
result = _run_node(
|
|
_progress_state_script(
|
|
"""
|
|
updateReferenceBundleDownloadProgress({
|
|
id: 'task-download', status: 'running',
|
|
progress: {bytes_downloaded: 8388608, total_bytes: 0, indeterminate: true}
|
|
}, {species_name: 'Spinacia oleracea'});
|
|
updateReferenceBundleDownloadProgress({
|
|
status: 'failed', message: 'IncompleteRead(726589 bytes read)'
|
|
}, {species_name: 'Spinacia oleracea'});
|
|
console.log(JSON.stringify(referenceBundleDownloadState.value));
|
|
"""
|
|
)
|
|
)
|
|
|
|
assert result["status"] == "failed"
|
|
assert result["message"] == "IncompleteRead(726589 bytes read)"
|
|
assert result["bytesDownloaded"] == 8388608
|
|
assert result["totalBytes"] == 0
|
|
|
|
|
|
def test_clear_resets_terminal_download_state() -> None:
|
|
result = _run_node(
|
|
_progress_state_script(
|
|
"""
|
|
updateReferenceBundleDownloadProgress({
|
|
id: 'task-download', status: 'failed', message: 'download failed',
|
|
progress: {bytes_downloaded: 4096, total_bytes: 0, indeterminate: true}
|
|
}, {species_name: 'Spinacia oleracea'});
|
|
clearReferenceBundleDownloadProgress();
|
|
console.log(JSON.stringify(referenceBundleDownloadState.value));
|
|
"""
|
|
)
|
|
)
|
|
|
|
assert result == {
|
|
"visible": False,
|
|
"taskId": "",
|
|
"speciesLabel": "",
|
|
"message": "",
|
|
"percentage": 0,
|
|
"indeterminate": True,
|
|
"status": "",
|
|
"bytesDownloaded": 0,
|
|
"totalBytes": 0,
|
|
}
|
|
|
|
|
|
def test_download_indicator_is_beside_tip_and_not_inside_batch_dialog() -> None:
|
|
html = HTML_PATH.read_text(encoding="utf-8")
|
|
toolbar = _source_block(
|
|
html,
|
|
"<!-- 使用小Tip hover弹出 -->",
|
|
"<!-- Upload hover弹出已上传文件 -->",
|
|
)
|
|
batch_dialog = _source_block(
|
|
html,
|
|
"<!-- 批量执行确认对话框 -->",
|
|
"<!-- 阶段确认对话框(批量执行用) -->",
|
|
)
|
|
|
|
assert 'class="reference-download-progress"' in toolbar
|
|
assert "referenceBundleDownloadState.visible" in toolbar
|
|
assert "PPI and Ka/Ks Reference Species Data Download" in toolbar
|
|
assert ':show-text="!referenceBundleDownloadState.indeterminate"' in toolbar
|
|
assert 'class="reference-download-progress"' not in batch_dialog
|
|
assert "referenceBundleDownloadState.visible" not in batch_dialog
|
|
|
|
|
|
def test_download_byte_formatter_uses_binary_units() -> None:
|
|
html = HTML_PATH.read_text(encoding="utf-8")
|
|
assert "const formatReferenceDownloadBytes =" in html
|
|
formatter = _source_block(
|
|
html,
|
|
"const formatReferenceDownloadBytes =",
|
|
"const updateReferenceBundleDownloadProgress =",
|
|
)
|
|
result = _run_node(
|
|
formatter
|
|
+ """
|
|
console.log(JSON.stringify({
|
|
zero: formatReferenceDownloadBytes(0),
|
|
mib: formatReferenceDownloadBytes(8388608)
|
|
}));
|
|
"""
|
|
)
|
|
|
|
assert result == {"zero": "", "mib": "8.0 MB"}
|
|
|
|
|
|
def test_monitor_retains_success_and_passes_failed_task_progress() -> None:
|
|
html = HTML_PATH.read_text(encoding="utf-8")
|
|
monitor = _source_block(
|
|
html,
|
|
"const monitorPpiReferenceBundleDownload =",
|
|
"const ppiHasNearReferenceBeforeArabidopsis =",
|
|
)
|
|
|
|
assert "clearReferenceBundleDownloadProgress();" not in monitor
|
|
assert "err?.task" in monitor
|