refactor(admin,ui,test): 完善数据库迁移脚本,添加单元测试并调整前端配置
优化所有alembic迁移脚本的离线模式支持,添加已存在对象检查逻辑,避免重复执行出错。 为各个迁移脚本添加对应的单元测试,覆盖核心场景保障逻辑正确性。 修改前端配置文件,将默认API地址切换为线上服务器8.138.234.141:4000。 新增本地数据备份文件wonderq-local-data.dump和项目发布包wonderq-admin-release-20260823-01.tar。
This commit is contained in:
1 parent
d42f69bd47
commit
203781210c
17 files changed
+519
-120
No files matched your search
@@ -0,0 +1,14 @@
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MIGRATION_PATH = Path(__file__).parents[1] / "alembic" / "versions" / "0023_detail_concierge_advisor.py"
|
||||
SPEC = spec_from_file_location("detail_concierge_migration", MIGRATION_PATH)
|
||||
assert SPEC and SPEC.loader
|
||||
MIGRATION = module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(MIGRATION)
|
||||
|
||||
|
||||
def test_concierge_advisor_column_is_added_only_when_missing():
|
||||
assert MIGRATION.should_add_concierge_advisor_column(set())
|
||||
assert not MIGRATION.should_add_concierge_advisor_column({"id", "conciergeAdvisorId"})
|
||||
@@ -0,0 +1,38 @@
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MIGRATION_PATH = Path(__file__).parents[1] / "alembic" / "versions" / "0021_detail_records.py"
|
||||
SPEC = spec_from_file_location("detail_records_migration", MIGRATION_PATH)
|
||||
assert SPEC and SPEC.loader
|
||||
MIGRATION = module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(MIGRATION)
|
||||
|
||||
|
||||
def test_detail_record_indexes_are_created_only_when_missing():
|
||||
assert MIGRATION.missing_detail_record_indexes(set()) == {
|
||||
"ix_DetailRecord_isActive",
|
||||
"ix_DetailRecord_sortOrder",
|
||||
}
|
||||
assert MIGRATION.missing_detail_record_indexes({"ix_DetailRecord_isActive"}) == {
|
||||
"ix_DetailRecord_sortOrder",
|
||||
}
|
||||
assert MIGRATION.missing_detail_record_indexes(
|
||||
{"ix_DetailRecord_isActive", "ix_DetailRecord_sortOrder"}
|
||||
) == set()
|
||||
|
||||
|
||||
def test_detail_seed_rows_skip_existing_route_keys():
|
||||
routes = [
|
||||
{
|
||||
"id": "family-route",
|
||||
"title": "亲子路线",
|
||||
"subtitle": "贵州亲子慢游",
|
||||
"image": "https://example.test/family.jpg",
|
||||
"sortOrder": 0,
|
||||
}
|
||||
]
|
||||
rows = MIGRATION.build_detail_seed_rows(routes, set(), datetime(2026, 1, 1))
|
||||
assert rows[0]["key"] == "family-route"
|
||||
assert MIGRATION.build_detail_seed_rows(routes, {"family-route"}, datetime(2026, 1, 1)) == []
|
||||
@@ -0,0 +1,41 @@
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MIGRATION_PATH = Path(__file__).parents[1] / "alembic" / "versions" / "0017_home_content.py"
|
||||
SPEC = spec_from_file_location("home_content_migration", MIGRATION_PATH)
|
||||
assert SPEC and SPEC.loader
|
||||
MIGRATION = module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(MIGRATION)
|
||||
|
||||
|
||||
def test_team_building_seed_contains_detail_fallback_fields():
|
||||
for row in MIGRATION.SEED_TEAM_BUILDINGS:
|
||||
assert row["detailSubtitle"] == row["description"]
|
||||
assert row["detailParagraphs"] == [row["description"]]
|
||||
|
||||
|
||||
def test_wild_archive_seed_contains_detail_images_fallback():
|
||||
for row in MIGRATION.SEED_WILD_ARCHIVES:
|
||||
assert row["images"] == [row["image"]]
|
||||
|
||||
|
||||
def test_seed_rows_only_include_columns_available_in_existing_table():
|
||||
timestamp = datetime(2026, 1, 1)
|
||||
|
||||
rows_without_detail_columns = MIGRATION.prepare_seed_rows(
|
||||
MIGRATION.SEED_TEAM_BUILDINGS[:1],
|
||||
{"id", "description", "createdAt", "updatedAt"},
|
||||
timestamp,
|
||||
)
|
||||
assert "detailSubtitle" not in rows_without_detail_columns[0]
|
||||
assert "detailParagraphs" not in rows_without_detail_columns[0]
|
||||
|
||||
rows_with_detail_columns = MIGRATION.prepare_seed_rows(
|
||||
MIGRATION.SEED_TEAM_BUILDINGS[:1],
|
||||
{"id", "description", "detailSubtitle", "detailParagraphs", "createdAt", "updatedAt"},
|
||||
timestamp,
|
||||
)
|
||||
assert rows_with_detail_columns[0]["detailSubtitle"] == rows_with_detail_columns[0]["description"]
|
||||
assert rows_with_detail_columns[0]["detailParagraphs"] == [rows_with_detail_columns[0]["description"]]
|
||||
@@ -0,0 +1,18 @@
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MIGRATION_PATH = Path(__file__).parents[1] / "alembic" / "versions" / "0020_home_team_building_details.py"
|
||||
SPEC = spec_from_file_location("home_team_building_details_migration", MIGRATION_PATH)
|
||||
assert SPEC and SPEC.loader
|
||||
MIGRATION = module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(MIGRATION)
|
||||
|
||||
|
||||
def test_detail_columns_are_added_only_when_missing():
|
||||
assert MIGRATION.missing_detail_columns(set()) == {
|
||||
"detailSubtitle",
|
||||
"detailParagraphs",
|
||||
}
|
||||
assert MIGRATION.missing_detail_columns({"detailSubtitle"}) == {"detailParagraphs"}
|
||||
assert MIGRATION.missing_detail_columns({"detailSubtitle", "detailParagraphs"}) == set()
|
||||
@@ -0,0 +1,14 @@
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MIGRATION_PATH = Path(__file__).parents[1] / "alembic" / "versions" / "0019_home_wild_archive_images.py"
|
||||
SPEC = spec_from_file_location("home_wild_archive_images_migration", MIGRATION_PATH)
|
||||
assert SPEC and SPEC.loader
|
||||
MIGRATION = module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(MIGRATION)
|
||||
|
||||
|
||||
def test_images_column_is_added_only_when_missing():
|
||||
assert MIGRATION.should_add_images_column(set())
|
||||
assert not MIGRATION.should_add_images_column({"id", "image", "images"})
|
||||
@@ -0,0 +1,38 @@
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MIGRATION_PATH = Path(__file__).parents[1] / "alembic" / "versions" / "0024_vehicle_demand.py"
|
||||
SPEC = spec_from_file_location("vehicle_demand_migration", MIGRATION_PATH)
|
||||
assert SPEC and SPEC.loader
|
||||
MIGRATION = module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(MIGRATION)
|
||||
|
||||
|
||||
def test_vehicle_demand_columns_are_added_only_when_missing():
|
||||
assert MIGRATION.missing_lead_columns(set()) == {
|
||||
"leadType",
|
||||
"contactName",
|
||||
"customerId",
|
||||
"vehicleDemand",
|
||||
}
|
||||
assert MIGRATION.missing_lead_columns({"leadType", "contactName"}) == {
|
||||
"customerId",
|
||||
"vehicleDemand",
|
||||
}
|
||||
|
||||
|
||||
def test_vehicle_demand_indexes_and_foreign_key_are_only_added_when_missing():
|
||||
assert MIGRATION.missing_named_indexes(set(), MIGRATION.LEAD_INDEXES) == {
|
||||
"ix_Lead_leadType",
|
||||
"ix_Lead_customerId",
|
||||
}
|
||||
assert not MIGRATION.should_create_customer_fk(
|
||||
[
|
||||
{
|
||||
"referred_table": "Customer",
|
||||
"referred_columns": ["id"],
|
||||
"constrained_columns": ["customerId"],
|
||||
}
|
||||
]
|
||||
)
|
||||
Reference in new issue
Block a user