移除 ScenicPromotion 宣传页模块,并隐藏首页 promotion_page 入口。
删除 Mock 模块、图片资源与路由;从常用菜单白名单剔除该权限,后端仍下发时客户端静默忽略。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -272,6 +272,8 @@ final class HomeCommonMenuStoreTests: XCTestCase {
|
||||
/// 测试 report_photographer 属于 Android menuList 白名单,且可加入常用应用。
|
||||
func testPhotographerReportIsWhitelistedAndCanBeAddedToCommon() {
|
||||
XCTAssertTrue(HomeCommonMenuStore.androidHomeMenuURIs.contains("report_photographer"))
|
||||
XCTAssertFalse(HomeCommonMenuStore.androidHomeMenuURIs.contains("promotion_page"))
|
||||
XCTAssertTrue(HomeCommonMenuStore.hiddenHomeMenuURIs.contains("promotion_page"))
|
||||
|
||||
let store = HomeCommonMenuStore(defaults: makeIsolatedDefaults())
|
||||
let uris = store.add(
|
||||
@ -285,6 +287,30 @@ final class HomeCommonMenuStoreTests: XCTestCase {
|
||||
XCTAssertEqual(uris, ["location_report", "report_photographer"])
|
||||
}
|
||||
|
||||
/// 测试已移除的 promotion_page 不会出现在白名单,且会从已保存常用菜单中过滤。
|
||||
func testPromotionPageIsHiddenFromCommonMenu() {
|
||||
let defaults = makeIsolatedDefaults()
|
||||
defaults.set(
|
||||
["wallet", "promotion_page", "message_center"],
|
||||
forKey: HomeCommonMenuStore.storageKey(roleCode: "photographer", accountScope: "scenic_user_promotion")
|
||||
)
|
||||
let store = HomeCommonMenuStore(defaults: defaults)
|
||||
let menus = [
|
||||
menu("wallet"),
|
||||
menu("promotion_page"),
|
||||
menu("message_center")
|
||||
]
|
||||
|
||||
let uris = store.load(
|
||||
menuItems: menus,
|
||||
roleCode: "photographer",
|
||||
accountScope: "scenic_user_promotion",
|
||||
topLevelPermissionURIs: menus.map(\.uri)
|
||||
)
|
||||
|
||||
XCTAssertEqual(uris, ["wallet", "message_center"])
|
||||
}
|
||||
|
||||
/// 测试非白名单顶层项占用前 4 名额时,默认常用不会用后续白名单项补位。
|
||||
func testDefaultCommonDoesNotBackfillAfterNonCatalogSlots() {
|
||||
let uris = HomeCommonMenuStore.defaultCommonURIs(
|
||||
|
||||
@ -48,7 +48,6 @@ final class HomeMenuRouterTests: XCTestCase {
|
||||
("location_report", .destination(.locationReport)),
|
||||
("location_report_history", .destination(.locationReportHistory)),
|
||||
("report_photographer", .destination(.photographerReport)),
|
||||
("promotion_page", .destination(.scenicPromotion)),
|
||||
("pm", .destination(.projectManagement)),
|
||||
("project_edit", .destination(.projectManagement)),
|
||||
("pm_manager", .destination(.pmProjectManagement)),
|
||||
|
||||
@ -1,183 +0,0 @@
|
||||
//
|
||||
// ScenicPromotionTests.swift
|
||||
// suixinkanTests
|
||||
//
|
||||
// Created by Codex on 2026/7/2.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import suixinkan
|
||||
|
||||
/// 宣传页主页面 ViewModel 测试,覆盖加载、场景切换与素材选中逻辑。
|
||||
@MainActor
|
||||
final class ScenicPromotionViewModelTests: XCTestCase {
|
||||
/// 测试正常场景加载后进入 normal 状态并选中首个打卡点与素材。
|
||||
func testApplyNormalScenarioLoadsBoardAndSelection() {
|
||||
let viewModel = ScenicPromotionViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
|
||||
XCTAssertEqual(viewModel.pageState, .normal)
|
||||
XCTAssertNotNil(viewModel.board)
|
||||
XCTAssertEqual(viewModel.board?.scenicName, "那拉提景区")
|
||||
XCTAssertNotNil(viewModel.selectedSpot)
|
||||
XCTAssertNotNil(viewModel.selectedMedia)
|
||||
XCTAssertFalse(viewModel.mediaItems.isEmpty)
|
||||
}
|
||||
|
||||
/// 测试空数据场景清空看板并进入 empty 状态。
|
||||
func testApplyEmptyScenarioClearsBoard() {
|
||||
let viewModel = ScenicPromotionViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
viewModel.applyScenario(.empty)
|
||||
|
||||
XCTAssertEqual(viewModel.pageState, .empty)
|
||||
XCTAssertNil(viewModel.board)
|
||||
}
|
||||
|
||||
/// 测试异常场景进入 error 状态。
|
||||
func testApplyErrorScenarioSetsErrorState() {
|
||||
let viewModel = ScenicPromotionViewModel()
|
||||
viewModel.applyScenario(.error)
|
||||
|
||||
if case .error = viewModel.pageState {
|
||||
XCTAssertTrue(true)
|
||||
} else {
|
||||
XCTFail("Expected error page state")
|
||||
}
|
||||
}
|
||||
|
||||
/// 测试无媒体场景清空素材列表。
|
||||
func testNoMediaScenarioHidesMediaItems() {
|
||||
let viewModel = ScenicPromotionViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
viewModel.applyScenario(.noMedia)
|
||||
|
||||
XCTAssertTrue(viewModel.mediaItems.isEmpty)
|
||||
XCTAssertNil(viewModel.selectedMedia)
|
||||
}
|
||||
|
||||
/// 测试无排队场景隐藏排队信息。
|
||||
func testNoQueueScenarioHidesQueueInfo() {
|
||||
let viewModel = ScenicPromotionViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
viewModel.applyScenario(.noQueue)
|
||||
|
||||
XCTAssertNil(viewModel.queue)
|
||||
XCTAssertFalse(viewModel.hasQueueData)
|
||||
}
|
||||
|
||||
/// 测试切换打卡点与素材模式会更新选中素材。
|
||||
func testSelectSpotAndModeUpdatesSelectedMedia() {
|
||||
let viewModel = ScenicPromotionViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
|
||||
guard let board = viewModel.board, board.spots.count > 1 else {
|
||||
XCTFail("Expected multiple spots in mock board")
|
||||
return
|
||||
}
|
||||
|
||||
let secondSpot = board.spots[1]
|
||||
viewModel.selectSpot(secondSpot)
|
||||
XCTAssertEqual(viewModel.selectedSpot?.id, secondSpot.id)
|
||||
|
||||
viewModel.selectMode(.photo)
|
||||
XCTAssertEqual(viewModel.selectedMode, .photo)
|
||||
XCTAssertEqual(viewModel.selectedMedia?.mode, .photo)
|
||||
}
|
||||
|
||||
/// 测试左右切换素材循环选中。
|
||||
func testMoveMediaCyclesSelection() {
|
||||
let viewModel = ScenicPromotionViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
|
||||
guard viewModel.mediaItems.count > 1 else {
|
||||
XCTFail("Expected multiple media items")
|
||||
return
|
||||
}
|
||||
|
||||
let firstID = viewModel.selectedMedia?.id
|
||||
viewModel.moveMedia(1)
|
||||
XCTAssertNotEqual(viewModel.selectedMedia?.id, firstID)
|
||||
|
||||
viewModel.moveMedia(-1)
|
||||
XCTAssertEqual(viewModel.selectedMedia?.id, firstID)
|
||||
}
|
||||
}
|
||||
|
||||
/// 宣传页设置 ViewModel 测试,覆盖上传校验与提交规则。
|
||||
@MainActor
|
||||
final class ScenicPromotionSettingsViewModelTests: XCTestCase {
|
||||
/// 测试正常场景加载 Mock 配置数据。
|
||||
func testApplyNormalScenarioLoadsSettingsData() {
|
||||
let viewModel = ScenicPromotionSettingsViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
|
||||
XCTAssertEqual(viewModel.pageState, .normal)
|
||||
XCTAssertFalse(viewModel.queuePoints.isEmpty)
|
||||
XCTAssertFalse(viewModel.materialPoints.isEmpty)
|
||||
XCTAssertFalse(viewModel.selectedQueuePointIDs.isEmpty)
|
||||
}
|
||||
|
||||
/// 测试未选择素材点时上传会被拦截。
|
||||
func testAddMaterialFailsWithoutMaterialPoint() {
|
||||
let viewModel = ScenicPromotionSettingsViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
viewModel.selectedMaterialPointID = nil
|
||||
|
||||
XCTAssertFalse(viewModel.addMaterial(kind: .video))
|
||||
}
|
||||
|
||||
/// 测试选择素材点后可以 Mock 上传素材。
|
||||
func testAddMaterialSucceedsWithMaterialPoint() {
|
||||
let viewModel = ScenicPromotionSettingsViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
|
||||
guard let point = viewModel.materialPoints.first else {
|
||||
XCTFail("Expected material points")
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.selectMaterialPoint(point)
|
||||
let beforeCount = viewModel.materials(for: .video).count
|
||||
XCTAssertTrue(viewModel.addMaterial(kind: .video))
|
||||
XCTAssertEqual(viewModel.materials(for: .video).count, beforeCount + 1)
|
||||
}
|
||||
|
||||
/// 测试删除素材会从当前点位列表移除。
|
||||
func testDeleteMaterialRemovesItem() {
|
||||
let viewModel = ScenicPromotionSettingsViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
|
||||
guard let point = viewModel.materialPoints.first else {
|
||||
XCTFail("Expected material points")
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.selectMaterialPoint(point)
|
||||
guard viewModel.addMaterial(kind: .image),
|
||||
let material = viewModel.materials(for: .image).last else {
|
||||
XCTFail("Expected uploaded material")
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.deleteMaterial(material)
|
||||
XCTAssertFalse(viewModel.materials(for: .image).contains(where: { $0.id == material.id }))
|
||||
}
|
||||
|
||||
/// 测试未绑定排队点时提交失败。
|
||||
func testSubmitFailsWithoutQueuePoints() {
|
||||
let viewModel = ScenicPromotionSettingsViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
viewModel.selectedQueuePointIDs = []
|
||||
|
||||
XCTAssertFalse(viewModel.submit())
|
||||
}
|
||||
|
||||
/// 测试绑定排队点后提交成功。
|
||||
func testSubmitSucceedsWithQueuePoints() {
|
||||
let viewModel = ScenicPromotionSettingsViewModel()
|
||||
viewModel.applyScenario(.normal)
|
||||
|
||||
XCTAssertTrue(viewModel.submit())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user