feat: 完善相册 AI 修图模板选择流程
This commit is contained in:
@@ -250,7 +250,8 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
|
||||
api.aiRetouchTemplatesResponse = TravelAlbumAIRetouchTemplatesResponse(
|
||||
refinedTemplates: [TravelAlbumAIRetouchTemplate(id: 1, name: "清透", previewURL: "")],
|
||||
atmosphereTemplates: [TravelAlbumAIRetouchTemplate(id: 2, name: "暖阳", previewURL: "")],
|
||||
coverTemplates: [TravelAlbumAIRetouchTemplate(id: 3, name: "杂志", previewURL: "")]
|
||||
coverTemplates: [TravelAlbumAIRetouchTemplate(id: 3, name: "杂志", previewURL: "")],
|
||||
remainingQuota: 8
|
||||
)
|
||||
let viewModel = TravelAlbumAIRetouchTemplateViewModel(
|
||||
albumId: 9,
|
||||
@@ -308,7 +309,8 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
|
||||
api.aiRetouchTemplatesResponse = TravelAlbumAIRetouchTemplatesResponse(
|
||||
refinedTemplates: [TravelAlbumAIRetouchTemplate(id: 1, name: "清透", previewURL: "")],
|
||||
atmosphereTemplates: [TravelAlbumAIRetouchTemplate(id: 2, name: "暖阳", previewURL: "")],
|
||||
coverTemplates: [TravelAlbumAIRetouchTemplate(id: 3, name: "杂志", previewURL: "")]
|
||||
coverTemplates: [TravelAlbumAIRetouchTemplate(id: 3, name: "杂志", previewURL: "")],
|
||||
remainingQuota: 8
|
||||
)
|
||||
let viewModel = TravelAlbumAIRetouchTemplateViewModel(
|
||||
albumId: 9,
|
||||
@@ -330,9 +332,13 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
|
||||
XCTAssertTrue(accessibleLabels.contains("氛围感修图,选填"))
|
||||
XCTAssertTrue(accessibleLabels.contains("封面风格模板"))
|
||||
|
||||
let modeCell = TravelAlbumAIRetouchModeCell(frame: .zero)
|
||||
modeCell.apply()
|
||||
XCTAssertEqual(modeCell.accessibilityLabel, "AI精修,按张收费,剩余张数暂不可用")
|
||||
let quotaLabel = try XCTUnwrap(
|
||||
controller.view.findSubview {
|
||||
$0.accessibilityIdentifier == "travelAlbum.aiRetouchRemainingQuotaLabel"
|
||||
} as? UILabel
|
||||
)
|
||||
XCTAssertEqual(quotaLabel.text, "剩余 8 次")
|
||||
XCTAssertEqual(quotaLabel.accessibilityLabel, "剩余8次修图额度")
|
||||
}
|
||||
|
||||
func testAIRetouchTemplateCellExposesSelectedState() {
|
||||
@@ -358,7 +364,8 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
|
||||
let api = TravelAlbumMockAPI()
|
||||
api.aiRetouchTemplatesResponse = TravelAlbumAIRetouchTemplatesResponse(
|
||||
refinedTemplates: [TravelAlbumAIRetouchTemplate(id: 11, name: "清透", previewURL: "")],
|
||||
atmosphereTemplates: [TravelAlbumAIRetouchTemplate(id: 21, name: "暖阳", previewURL: "")]
|
||||
atmosphereTemplates: [TravelAlbumAIRetouchTemplate(id: 21, name: "暖阳", previewURL: "")],
|
||||
remainingQuota: 8
|
||||
)
|
||||
let project = TravelAlbumPreviewProject(
|
||||
originalMaterialId: 7,
|
||||
@@ -451,10 +458,11 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
|
||||
projects: [TravelAlbumPreviewProject(originalMaterialId: 7, assets: [original, retouched])],
|
||||
totalCount: 1,
|
||||
startProjectIndex: 0,
|
||||
reload: {
|
||||
reload: { materialId in
|
||||
XCTAssertEqual(materialId, 7)
|
||||
reloadCount += 1
|
||||
let assets = reloadCount == 1 ? [original, retouched] : [original]
|
||||
return ([TravelAlbumPreviewProject(originalMaterialId: 7, assets: assets)], 1)
|
||||
return TravelAlbumPreviewProject(originalMaterialId: 7, assets: assets)
|
||||
}
|
||||
)
|
||||
controller.loadViewIfNeeded()
|
||||
@@ -487,6 +495,43 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
|
||||
XCTAssertTrue(controller.view.allLabels().contains { $0.text == "原图.jpg" })
|
||||
}
|
||||
|
||||
func testPreviewRefreshUsesGlobalLoadingWithoutToast() async throws {
|
||||
GlobalLoadingManager.shared.hideAll()
|
||||
defer { GlobalLoadingManager.shared.hideAll() }
|
||||
let original = TravelAlbumPreviewAsset(
|
||||
id: "original-7",
|
||||
kind: .original,
|
||||
fileURL: "",
|
||||
coverURL: "",
|
||||
fileName: "原图.jpg",
|
||||
fileSize: 0
|
||||
)
|
||||
let project = TravelAlbumPreviewProject(originalMaterialId: 7, assets: [original])
|
||||
let controller = TravelAlbumPhotoPreviewViewController(
|
||||
projects: [project],
|
||||
totalCount: 1,
|
||||
startProjectIndex: 0,
|
||||
reload: { _ in
|
||||
try await Task.sleep(nanoseconds: 50_000_000)
|
||||
return project
|
||||
}
|
||||
)
|
||||
controller.loadViewIfNeeded()
|
||||
let refreshButton = try XCTUnwrap(
|
||||
controller.view.findSubview {
|
||||
$0.accessibilityIdentifier == "travelAlbum.previewRefreshButton"
|
||||
} as? UIButton
|
||||
)
|
||||
|
||||
refreshButton.sendActions(for: .touchUpInside)
|
||||
|
||||
XCTAssertTrue(GlobalLoadingManager.shared.isShowing)
|
||||
await waitUntil { !GlobalLoadingManager.shared.isShowing && refreshButton.isEnabled }
|
||||
XCTAssertFalse(GlobalLoadingManager.shared.isShowing)
|
||||
XCTAssertFalse(controller.view.allLabels().contains { $0.text == "刷新成功" })
|
||||
XCTAssertFalse(controller.view.allLabels().contains { $0.text == "刷新失败" })
|
||||
}
|
||||
|
||||
func testMaterialCellShowsSemanticStatusBadgeWithoutOverlappingSelectionCheck() throws {
|
||||
let cases: [(TravelAlbumMaterial, String, UInt)] = [
|
||||
(TravelAlbumMaterial(isPurchased: true), "已购", 0x475569),
|
||||
|
||||
Reference in New Issue
Block a user