feat: 品牌化那拉提景区收款页

This commit is contained in:
2026-07-23 15:39:34 +08:00
parent 74f7370aab
commit 787a166263
13 changed files with 840 additions and 31 deletions

View File

@ -79,6 +79,24 @@ final class PaymentCollectionDetailsViewModelTests: XCTestCase {
XCTAssertTrue(viewModel.isVoiceBroadcastOpen)
}
func testNalatiAccountInfoUsesLoggedInPhotographerAndAllPermissionStores() {
appStore.session.userName = ""
appStore.permissions.saveRolePermissionList([
RolePermissionResponse(
role: RoleInfo(id: 41, name: "", roleCode: "photographer"),
store: [
RolePermissionStoreInfo(id: 1, name: ""),
RolePermissionStoreInfo(id: 2, name: ""),
]
),
])
let viewModel = PaymentCollectionDetailsViewModel(appStore: appStore)
XCTAssertEqual(viewModel.displayPhotographerName, "")
XCTAssertEqual(viewModel.displayStoreNames, "")
}
func testLoadPayCodeClearsQRWhenScenicMissing() async {
appStore.session.currentScenicId = 0
let session = MockURLSession(responses: [])
@ -90,4 +108,74 @@ final class PaymentCollectionDetailsViewModelTests: XCTestCase {
XCTAssertFalse(viewModel.hasPayCode)
XCTAssertEqual(session.requests.count, 0)
}
func testNalatiLoadsCachedConfigBeforeRefreshingRemoteConfig() async throws {
let defaults = UserDefaults(suiteName: "PaymentCollectionDetailsViewModelTests.Config")!
defaults.removePersistentDomain(forName: "PaymentCollectionDetailsViewModelTests.Config")
let cache = PayPageConfigCache(defaults: defaults, environment: .testing)
let cached = PayPageConfig(
background: "https://cache.example.com/background.png",
logo: "https://cache.example.com/logo.png",
title: "缓存标题",
subtitle: "缓存副标题"
)
cache.save(cached, scenicId: 128)
appStore.session.currentScenicId = 128
appStore.session.currentScenicName = "那拉提景区"
let responseJSON = """
{"code":100000,"msg":"success","data":{
"background":"https://new.example.com/background.png",
"logo":"",
"title":"最新标题",
"subtitle":""
}}
""".data(using: .utf8)!
let session = MockURLSession(responses: [responseJSON])
let api = PaymentAPI(client: APIClient(environment: .testing, session: session))
let viewModel = PaymentCollectionDetailsViewModel(
appStore: appStore,
payPageConfigCache: cache
)
XCTAssertEqual(viewModel.payPageConfig, cached)
await viewModel.loadPayPageConfig(api: api)
XCTAssertEqual(viewModel.payPageConfig.background, "https://new.example.com/background.png")
XCTAssertEqual(viewModel.payPageConfig.logo, cached.logo)
XCTAssertEqual(viewModel.payPageConfig.title, "最新标题")
XCTAssertEqual(viewModel.payPageConfig.subtitle, cached.subtitle)
XCTAssertEqual(viewModel.brandingRefreshVersion, 1)
XCTAssertEqual(session.requests.first?.url?.path, "/api/yf-handset-app/photog/pay-page-config")
XCTAssertEqual(
URLComponents(url: try XCTUnwrap(session.requests.first?.url), resolvingAgainstBaseURL: false)?
.queryItems?
.first(where: { $0.name == "scenic_id" })?
.value,
"128"
)
}
func testNonNalatiDoesNotRequestPayPageConfig() async {
let session = MockURLSession(responses: [])
let api = PaymentAPI(client: APIClient(environment: .testing, session: session))
let viewModel = PaymentCollectionDetailsViewModel(appStore: appStore)
await viewModel.loadPayPageConfig(api: api)
XCTAssertFalse(viewModel.usesNalatiBranding)
XCTAssertEqual(session.requests.count, 0)
}
func testPayPageConfigCacheIsEnvironmentScoped() {
let defaults = UserDefaults(suiteName: "PaymentCollectionDetailsViewModelTests.Environment")!
defaults.removePersistentDomain(forName: "PaymentCollectionDetailsViewModelTests.Environment")
let production = PayPageConfigCache(defaults: defaults, environment: .production)
let testing = PayPageConfigCache(defaults: defaults, environment: .testing)
production.save(.nalatiDefault, scenicId: 128)
XCTAssertEqual(production.config(scenicId: 128), .nalatiDefault)
XCTAssertNil(testing.config(scenicId: 128))
}
}