为旅拍 OTG 上传增加 client_photo_id,并按服务端已登记 ID 同步本地上传状态。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -483,6 +483,37 @@ final class WiredCameraTransferViewModelTests: XCTestCase {
|
||||
XCTAssertEqual(Set(result.importedPhotoIds), Set(records.map(\.id)))
|
||||
XCTAssertEqual(Set(records.map(\.status)), [.uploaded])
|
||||
XCTAssertEqual(Set(records.map(\.fileName)).count, 2)
|
||||
XCTAssertEqual(Set(records.map(\.clientPhotoId)).count, 2)
|
||||
XCTAssertTrue(records.allSatisfy { UUID(uuidString: $0.clientPhotoId) != nil })
|
||||
}
|
||||
|
||||
func testStartSynchronizesPersistedUploadStatusesFromServerClientPhotoIds() async {
|
||||
let context = makeOTGTestContext()
|
||||
let api = TravelAlbumMockAPI()
|
||||
api.materialClientPhotoIdsResponse = TravelAlbumMaterialClientPhotoIDsResponse(
|
||||
clientPhotoIds: ["server-id"]
|
||||
)
|
||||
let records = [
|
||||
makeOTGRecord(id: "matched", capturedAt: "2026-07-16 12:00:00", status: .failed)
|
||||
.withClientPhotoId("server-id"),
|
||||
makeOTGRecord(id: "missing", capturedAt: "2026-07-16 12:01:00", status: .uploaded)
|
||||
.withClientPhotoId("missing-id"),
|
||||
]
|
||||
context.store.save(records, albumId: 9)
|
||||
let viewModel = makeWiredViewModel(
|
||||
context: context,
|
||||
manager: MockWiredCameraConnectionManager(driver: MockCameraDriver(objects: [])),
|
||||
api: api
|
||||
)
|
||||
|
||||
viewModel.start()
|
||||
await waitUntil {
|
||||
let byId = Dictionary(uniqueKeysWithValues: context.store.load(albumId: 9).map { ($0.id, $0) })
|
||||
return byId["matched"]?.status == .uploaded && byId["missing"]?.status == .pending
|
||||
}
|
||||
viewModel.stop()
|
||||
|
||||
XCTAssertEqual(api.materialClientPhotoIdsCallCount, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -683,6 +714,7 @@ private func makeWiredViewModel(
|
||||
context: OTGTestContext,
|
||||
manager: MockWiredCameraConnectionManager,
|
||||
uploader: MockTravelAlbumOTGUploader? = nil,
|
||||
api: TravelAlbumMockAPI? = nil,
|
||||
userDefaults: UserDefaults = makeOTGTestDefaults()
|
||||
) -> WiredCameraTransferViewModel {
|
||||
prepareAppStoreForOTGTests()
|
||||
@ -693,10 +725,19 @@ private func makeWiredViewModel(
|
||||
connectionManager: manager,
|
||||
storage: context.store,
|
||||
uploader: uploader ?? MockTravelAlbumOTGUploader(),
|
||||
api: api ?? TravelAlbumMockAPI(),
|
||||
userDefaults: userDefaults
|
||||
)
|
||||
}
|
||||
|
||||
private extension TravelAlbumOTGPhotoRecord {
|
||||
func withClientPhotoId(_ value: String) -> TravelAlbumOTGPhotoRecord {
|
||||
var copy = self
|
||||
copy.clientPhotoId = value
|
||||
return copy
|
||||
}
|
||||
}
|
||||
|
||||
private func makeOTGPhotoItem(
|
||||
id: String,
|
||||
capturedAt: String,
|
||||
@ -914,6 +955,7 @@ final class TravelAlbumMockAPI: TravelAlbumServing {
|
||||
var infoResponse = TravelAlbum()
|
||||
var materialListResponses: [TravelAlbumListResponse<TravelAlbumMaterial>] = []
|
||||
var uploadMaterialResponse = TravelAlbumMaterial()
|
||||
var materialClientPhotoIdsResponse = TravelAlbumMaterialClientPhotoIDsResponse(clientPhotoIds: [])
|
||||
var mpCodeResponse = TravelAlbumMpCodeResponse(mpCodeOssUrl: "")
|
||||
var createError: Error?
|
||||
|
||||
@ -921,6 +963,7 @@ final class TravelAlbumMockAPI: TravelAlbumServing {
|
||||
private(set) var createRequests: [TravelAlbumCreateRequest] = []
|
||||
private(set) var materialRequests: [MaterialRequest] = []
|
||||
private(set) var uploadMaterialRequests: [TravelAlbumUploadMaterialRequest] = []
|
||||
private(set) var materialClientPhotoIdsCallCount = 0
|
||||
private(set) var deletedAlbumIds: [Int] = []
|
||||
private(set) var deletedMaterialIds: [Int] = []
|
||||
|
||||
@ -968,6 +1011,11 @@ final class TravelAlbumMockAPI: TravelAlbumServing {
|
||||
return uploadMaterialResponse
|
||||
}
|
||||
|
||||
func materialClientPhotoIds(userEquityTravelId: Int) async throws -> TravelAlbumMaterialClientPhotoIDsResponse {
|
||||
materialClientPhotoIdsCallCount += 1
|
||||
return materialClientPhotoIdsResponse
|
||||
}
|
||||
|
||||
func deleteAlbum(id: Int) async throws {
|
||||
deletedAlbumIds.append(id)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user