@@ -373,4 +373,108 @@ struct POSCatalogSyncRemoteTests {
373373 try await remote. checkCatalogStatus ( for: sampleSiteID, jobID: jobID)
374374 }
375375 }
376+
377+ // MARK: - Download Catalog Tests
378+
379+ @Test func downloadCatalog_returns_parsed_catalog_with_products_and_variations( ) async throws {
380+ // Given
381+ let remote = POSCatalogSyncRemote ( network: network)
382+ let downloadURL = " https://example.com/catalog.json "
383+
384+ // When
385+ network. simulateResponse ( requestUrlSuffix: " " , filename: " pos-catalog-download-mixed " )
386+ let catalog = try await remote. downloadCatalog ( for: sampleSiteID, downloadURL: downloadURL)
387+
388+ // Then
389+ #expect( catalog. products. count == 2 )
390+ #expect( catalog. variations. count == 2 )
391+
392+ let simpleProduct = try #require( catalog. products. first { $0. productType == . simple } )
393+ #expect( simpleProduct. siteID == sampleSiteID)
394+ #expect( simpleProduct. productID == 48 )
395+ #expect( simpleProduct. sku == " synergistic-copper-clock-61732018 " )
396+ #expect( simpleProduct. globalUniqueID == " 61732018 " )
397+ #expect( simpleProduct. name == " Synergistic Copper Clock " )
398+ #expect( simpleProduct. price == " 220 " )
399+ #expect( simpleProduct. regularPrice == " 230.04 " )
400+ #expect( simpleProduct. onSale == true )
401+ #expect( simpleProduct. images. count == 1 )
402+ #expect( simpleProduct. images. first? . src == " https://example.com/wp-content/uploads/2025/08/img-ad.png " )
403+
404+ let variableProduct = try #require( catalog. products. first { $0. productType == . variable } )
405+ #expect( variableProduct. siteID == sampleSiteID)
406+ #expect( variableProduct. productID == 31 )
407+ #expect( variableProduct. sku == " incredible-silk-chair-13060312 " )
408+ #expect( variableProduct. globalUniqueID == " " )
409+ #expect( variableProduct. name == " Incredible Silk Chair " )
410+ #expect( variableProduct. price == " 134.58 " )
411+ #expect( variableProduct. regularPrice == " " )
412+ #expect( variableProduct. onSale == false )
413+ #expect( variableProduct. images. count == 1 )
414+ #expect( variableProduct. images. first? . src == " https://example.com/wp-content/uploads/2025/08/img-harum.png " )
415+ #expect( variableProduct. attributes == [
416+ . init( siteID: sampleSiteID, attributeID: 1 , name: " Size " , position: 0 , visible: true , variation: true , options: [ " Earum " ] ) ,
417+ . init( siteID: sampleSiteID, attributeID: 0 , name: " Ab " , position: 1 , visible: true , variation: true , options: [ " deserunt " , " ea " , " ut " ] ) ,
418+ . init( siteID: sampleSiteID,
419+ attributeID: 2 ,
420+ name: " Numeric Size " ,
421+ position: 2 ,
422+ visible: true ,
423+ variation: true ,
424+ options: [ " 19 " , " 8 " , " 9 " , " At " , " Reiciendis " ] )
425+ ] )
426+
427+ let variation = try #require( catalog. variations. first)
428+ #expect( variation. siteID == sampleSiteID)
429+ #expect( variation. productVariationID == 32 )
430+ #expect( variation. productID == 31 )
431+ #expect( variation. sku == " " )
432+ #expect( variation. globalUniqueID == " " )
433+ #expect( variation. price == " 330.34 " )
434+ #expect( variation. regularPrice == " 330.34 " )
435+ #expect( variation. onSale == false )
436+ #expect( variation. attributes. count == 3 )
437+ #expect( variation. image? . src == " https://example.com/wp-content/uploads/2025/08/img-quae.png " )
438+ #expect( variation. attributes == [
439+ . init( id: 1 , name: " Size " , option: " Earum " ) ,
440+ . init( id: 0 , name: " ab " , option: " deserunt " ) ,
441+ . init( id: 2 , name: " Numeric Size " , option: " 19 " )
442+ ] )
443+ }
444+
445+ @Test func downloadCatalog_handles_empty_catalog( ) async throws {
446+ // Given
447+ let remote = POSCatalogSyncRemote ( network: network)
448+ let downloadURL = " https://example.com/catalog.json "
449+
450+ // When
451+ network. simulateResponse ( requestUrlSuffix: " " , filename: " empty-data-array " )
452+ let catalog = try await remote. downloadCatalog ( for: sampleSiteID, downloadURL: downloadURL)
453+
454+ // Then
455+ #expect( catalog. products. count == 0 )
456+ #expect( catalog. variations. count == 0 )
457+ }
458+
459+ @Test func downloadCatalog_throws_error_for_empty_url( ) async throws {
460+ // Given
461+ let remote = POSCatalogSyncRemote ( network: network)
462+ let emptyURL = " "
463+
464+ // When/Then
465+ await #expect( throws: NetworkError . invalidURL) {
466+ try await remote. downloadCatalog ( for: sampleSiteID, downloadURL: emptyURL)
467+ }
468+ }
469+
470+ @Test func downloadCatalog_relays_networking_error( ) async throws {
471+ // Given
472+ let remote = POSCatalogSyncRemote ( network: network)
473+ let downloadURL = " https://example.com/catalog.json "
474+
475+ // When/Then
476+ await #expect( throws: NetworkError . notFound ( ) ) {
477+ try await remote. downloadCatalog ( for: sampleSiteID, downloadURL: downloadURL)
478+ }
479+ }
376480}
0 commit comments