Add scenic application flow aligned with Android.
Implement scenic apply models, API, upload, UI, and tests; wire entry from permission apply pages and include related permission/scenic selection UI fixes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
107
suixinkanTests/ScenicApplicationViewModelTests.swift
Normal file
107
suixinkanTests/ScenicApplicationViewModelTests.swift
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// ScenicApplicationViewModelTests.swift
|
||||
// suixinkanTests
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import suixinkan
|
||||
|
||||
@MainActor
|
||||
/// 景区申请 ViewModel 测试。
|
||||
final class ScenicApplicationViewModelTests: XCTestCase {
|
||||
|
||||
func testCanSubmitRequiresRequiredFields() {
|
||||
let viewModel = ScenicApplicationViewModel()
|
||||
XCTAssertFalse(viewModel.canSubmit)
|
||||
|
||||
viewModel.onProvinceSelected("浙江省")
|
||||
viewModel.onCitySelected("杭州市")
|
||||
viewModel.onRemarksChange("合作备注")
|
||||
XCTAssertFalse(viewModel.canSubmit)
|
||||
|
||||
viewModel.toggleAgreement()
|
||||
XCTAssertTrue(viewModel.canSubmit)
|
||||
}
|
||||
|
||||
func testRemarksMaxLengthShowsMessage() {
|
||||
let viewModel = ScenicApplicationViewModel()
|
||||
var message: String?
|
||||
viewModel.onShowMessage = { message = $0 }
|
||||
|
||||
let longText = String(repeating: "a", count: 51)
|
||||
viewModel.onRemarksChange(longText)
|
||||
|
||||
XCTAssertEqual(viewModel.remarks.count, 0)
|
||||
XCTAssertEqual(message, "备注信息最多50字")
|
||||
}
|
||||
|
||||
func testProvinceSelectionClearsCity() {
|
||||
let viewModel = ScenicApplicationViewModel()
|
||||
viewModel.onProvinceSelected("浙江省")
|
||||
viewModel.onCitySelected("杭州市")
|
||||
XCTAssertEqual(viewModel.selectedCity, "杭州市")
|
||||
|
||||
viewModel.onProvinceSelected("江苏省")
|
||||
XCTAssertEqual(viewModel.selectedProvince, "江苏省")
|
||||
XCTAssertEqual(viewModel.selectedCity, "")
|
||||
}
|
||||
|
||||
func testInitWithPendingApplicationStatus1() async throws {
|
||||
let pendingJSON = """
|
||||
{"code":100000,"msg":"success","data":{"items":[{"id":1,"scenic_name":"测试景区","scenic_images":"https://a.com/1.jpg,https://a.com/2.jpg","scenic_province":"浙江省","scenic_city":"杭州市","coop_type":2,"remark":"备注","status":1}]}}
|
||||
""".data(using: .utf8)!
|
||||
let areasJSON = """
|
||||
{"code":100000,"msg":"success","data":[{"id":1,"name":"浙江省","children":[{"id":2,"name":"杭州市"}]}]}
|
||||
""".data(using: .utf8)!
|
||||
let homeAPI = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [pendingJSON])))
|
||||
let profileAPI = ProfileAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [areasJSON])))
|
||||
let viewModel = ScenicApplicationViewModel()
|
||||
|
||||
await viewModel.loadAreas(profileAPI: profileAPI)
|
||||
await viewModel.loadPendingApplication(homeAPI: homeAPI)
|
||||
|
||||
XCTAssertEqual(viewModel.scenicName, "测试景区")
|
||||
XCTAssertEqual(viewModel.selectedProvince, "浙江省")
|
||||
XCTAssertEqual(viewModel.selectedCity, "杭州市")
|
||||
XCTAssertEqual(viewModel.selectedCooperationType, .resourceProvider)
|
||||
XCTAssertEqual(viewModel.remarks, "备注")
|
||||
XCTAssertEqual(viewModel.selectedImages.count, 2)
|
||||
XCTAssertTrue(viewModel.isReadOnly)
|
||||
XCTAssertTrue(viewModel.shouldShowAuditCard)
|
||||
}
|
||||
|
||||
func testSubmitValidationShowsIncompleteMessage() async {
|
||||
let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [])))
|
||||
let viewModel = ScenicApplicationViewModel()
|
||||
var message: String?
|
||||
viewModel.onShowMessage = { message = $0 }
|
||||
|
||||
await viewModel.submit(homeAPI: api)
|
||||
XCTAssertEqual(message, "请完善必填信息")
|
||||
}
|
||||
|
||||
func testSubmitSuccessCallsCallback() async throws {
|
||||
let submitJSON = """
|
||||
{"code":100000,"msg":"success","data":{}}
|
||||
""".data(using: .utf8)!
|
||||
let pendingJSON = """
|
||||
{"code":100000,"msg":"success","data":{"items":[]}}
|
||||
""".data(using: .utf8)!
|
||||
let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [submitJSON, pendingJSON])))
|
||||
let viewModel = ScenicApplicationViewModel()
|
||||
viewModel.onProvinceSelected("浙江省")
|
||||
viewModel.onCitySelected("杭州市")
|
||||
viewModel.onRemarksChange("合作")
|
||||
viewModel.toggleAgreement()
|
||||
|
||||
var didSubmit = false
|
||||
viewModel.onSubmitSuccess = { didSubmit = true }
|
||||
var messages: [String] = []
|
||||
viewModel.onShowMessage = { messages.append($0) }
|
||||
|
||||
await viewModel.submit(homeAPI: api)
|
||||
|
||||
XCTAssertTrue(didSubmit)
|
||||
XCTAssertEqual(messages.first, "提交成功")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user