You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

138 lines
4.5 KiB

from __future__ import annotations
import csv
from pathlib import Path
from uuid import uuid4
from playwright.sync_api import Page, expect
from tests.e2e.helpers import download_via_action, expect_flash, expect_path, login, upload_file
def _unique_suffix() -> str:
return uuid4().hex[:8]
def _read_csv_text(file_path: Path) -> str:
return file_path.read_text(encoding="utf-8-sig")
def test_admin_can_download_export_preview_and_confirm_csv_import(
page: Page,
base_url: str,
admin_credentials: dict[str, str],
tmp_path: Path,
) -> None:
suffix = _unique_suffix()
household_code = f"CSV-{suffix}".upper()
head_name = f"CSV导入户{suffix}"
login(
page,
base_url,
username=admin_credentials["username"],
password=admin_credentials["password"],
expected_path="/",
)
template_path = tmp_path / f"template-{suffix}.csv"
download_via_action(
page,
lambda: page.get_by_role("link", name="下载 CSV 模板").click(),
template_path,
)
template_content = _read_csv_text(template_path)
assert "household_code,head_name,phone,side,invite_status" in template_content
export_all_path = tmp_path / f"export-all-{suffix}.csv"
download_via_action(
page,
lambda: page.get_by_role("link", name="导出全部").click(),
export_all_path,
)
export_all_content = _read_csv_text(export_all_path)
assert "李阿姨" in export_all_content
assert "陈老师" in export_all_content
page.locator("#main-search").fill("李阿姨")
page.locator("#main-search").press("Enter")
export_filtered_path = tmp_path / f"export-filtered-{suffix}.csv"
download_via_action(
page,
lambda: page.get_by_role("link", name="导出当前筛选").click(),
export_filtered_path,
)
export_filtered_content = _read_csv_text(export_filtered_path)
assert "李阿姨" in export_filtered_content
assert "陈老师" not in export_filtered_content
page.get_by_role("link", name="导入 CSV").click()
expect_path(page, base_url, "/csv/households/import")
expect(page.get_by_role("heading", name="CSV 导入导出")).to_be_visible()
import_file_path = tmp_path / f"import-{suffix}.csv"
with import_file_path.open("w", encoding="utf-8", newline="") as csv_file:
writer = csv.writer(csv_file)
writer.writerow(
[
"household_code",
"head_name",
"phone",
"side",
"invite_status",
"attendance_status",
"expected_attendee_count",
"actual_attendee_count",
"child_count",
"red_packet_child_count",
"total_gift_amount",
"gift_method_option_code",
"gift_scene_option_code",
"favor_status",
"candy_status",
"child_red_packet_status",
"note",
],
)
writer.writerow(
[
household_code,
head_name,
"13600136000",
"groom_side",
"confirmed",
"attending",
"4",
"4",
"1",
"1",
"999.00",
"cash",
"wedding_day",
"given",
"given",
"partial",
"CSV 导入创建",
],
)
upload_file(page, "#csv-file", import_file_path)
page.get_by_role("button", name="生成导入预览").click()
expect_flash(page, "CSV 预览已生成,请先检查无效行和冲突行。")
expect(page.get_by_role("heading", name="导入预览")).to_be_visible()
expect(page.get_by_text(head_name)).to_be_visible()
expect(page.get_by_text(household_code)).to_be_visible()
expect(page.get_by_text("新增候选")).to_be_visible()
page.locator("#conflict-mode").select_option("update_by_code")
page.get_by_role("button", name="确认导入").click()
expect_path(page, base_url, "/")
expect_flash(page, "CSV 导入完成:新增 1 户,更新 0 户,跳过 0 行,无效 0 行。")
page.locator("#main-search").fill(head_name)
page.locator("#main-search").press("Enter")
results_table = page.locator("#household-results-region table")
expect(results_table.get_by_text(head_name)).to_be_visible()
expect(results_table.get_by_text(household_code)).to_be_visible()