import Foundation import XCTest import VelodyDomain @testable import VelodyNetworking final class RemoteLibraryDTOTests: XCTestCase { func testRemoteTrackDTOMapsToRemoteTrack() { let dto = RemoteTrackDTO( trackId: "track-123", title: "Remote Title", artist: "Remote Artist", durationSeconds: 245, sha256: String(repeating: "a", count: 64), assetId: "asset-456", createdAt: "2026-05-29T08:00:00.000Z", updatedAt: "2026-05-29T08:05:00.000Z", artwork: RemoteArtworkDTO( artworkId: "artwork-789", sha256: String(repeating: "b", count: 64), mimeType: "image/png", width: 512, height: 512 ) ) let track = dto.remoteTrack XCTAssertEqual(track.trackId, "track-123") XCTAssertEqual(track.title, "Remote Title") XCTAssertEqual(track.artist, "Remote Artist") XCTAssertEqual(track.durationSeconds, 245) XCTAssertEqual(track.sha256, String(repeating: "a", count: 64)) XCTAssertEqual(track.assetId, "asset-456") XCTAssertEqual( track.artwork, RemoteArtwork( artworkId: "artwork-789", sha256: String(repeating: "b", count: 64), mimeType: "image/png", width: 512, height: 512 ) ) } func testRemoteLibraryResponseDTODecodesFromAPIResponse() throws { let data = Data( """ { "tracks": [ { "trackId": "track-123", "title": "Remote Title", "artist": "Remote Artist", "durationSeconds": 245, "sha256": "\(String(repeating: "a", count: 64))", "assetId": "asset-456", "createdAt": "2026-05-29T08:00:00.000Z", "updatedAt": "2026-05-29T08:05:00.000Z", "artwork": { "artworkId": "artwork-789", "sha256": "\(String(repeating: "b", count: 64))", "mimeType": "image/png", "width": 512, "height": 512 } } ] } """.utf8 ) let decoded = try JSONDecoder().decode(RemoteLibraryResponseDTO.self, from: data) XCTAssertEqual(decoded.tracks.count, 1) XCTAssertEqual(decoded.tracks.first?.trackId, "track-123") XCTAssertEqual(decoded.tracks.first?.durationSeconds, 245) XCTAssertEqual(decoded.tracks.first?.artwork?.artworkId, "artwork-789") } func testSyncChangesResponseDecodesTrackPayloadAndCursor() throws { let data = Data( """ { "nextCursor": "12", "hasMore": false, "requiresBootstrap": false, "events": [ { "cursor": "12", "entityType": "TRACK", "entityId": "track-123", "action": "UPDATED", "track": { "trackId": "track-123", "title": "Remote Title", "artist": "Remote Artist", "durationSeconds": 245, "sha256": "\(String(repeating: "a", count: 64))", "assetId": "asset-456", "createdAt": "2026-06-15T12:00:00.000Z", "updatedAt": "2026-06-15T12:05:00.000Z", "artwork": null }, "deletedTrackId": null, "createdAt": "2026-06-15T12:05:00.000Z" } ], "serverTime": "2026-06-15T12:05:00.000Z" } """.utf8 ) let decoded = try JSONDecoder().decode(SyncChangesResponse.self, from: data) XCTAssertEqual(decoded.nextCursor.value, "12") XCTAssertFalse(decoded.hasMore) XCTAssertFalse(decoded.requiresBootstrap) XCTAssertEqual(decoded.events.first?.cursor.value, "12") XCTAssertEqual(decoded.events.first?.track?.trackId, "track-123") } }