@@ -3,6 +3,7 @@ import Foundation
33@testable import WooCommerce
44import struct Yosemite. POSVariableParentProduct
55import enum Yosemite. POSItem
6+ import enum Yosemite. PointOfSaleItemServiceError
67import Observation
78
89final class PointOfSaleItemsControllerTests {
@@ -238,7 +239,7 @@ final class PointOfSaleItemsControllerTests {
238239 await sut. loadItems ( base: . root)
239240 await sut. loadItems ( base: baseItem)
240241
241- itemProvider. shouldThrowError = true
242+ itemProvider. errorToThrow = MockError . requestFailed
242243
243244 // When
244245 await sut. loadNextItems ( base: baseItem)
@@ -275,7 +276,7 @@ final class PointOfSaleItemsControllerTests {
275276 let itemProvider = MockPointOfSaleItemService ( )
276277 let sut = PointOfSaleItemsController ( itemProvider: itemProvider)
277278
278- itemProvider. shouldThrowError = true
279+ itemProvider. errorToThrow = MockError . requestFailed
279280 let expectedError = PointOfSaleErrorState ( title: " Error loading products " ,
280281 subtitle: " Give it another go? " ,
281282 buttonText: " Retry " )
@@ -299,7 +300,7 @@ final class PointOfSaleItemsControllerTests {
299300 itemProvider. shouldSimulateTwoPages = true
300301 await sut. loadItems ( base: . root)
301302
302- itemProvider. shouldThrowError = true
303+ itemProvider. errorToThrow = MockError . requestFailed
303304
304305 // When
305306 await sut. loadNextItems ( base: . root)
@@ -315,6 +316,57 @@ final class PointOfSaleItemsControllerTests {
315316 #expect( errorState == PointOfSaleErrorState . errorOnLoadingProductsNextPage ( ) )
316317 }
317318
319+ @available ( iOS 17 . 0 , * )
320+ @Test func loadItems_when_request_is_cancelled_then_state_is_loaded( ) async throws {
321+ // Given
322+ let itemProvider = MockPointOfSaleItemService ( )
323+ let sut = PointOfSaleItemsController ( itemProvider: itemProvider)
324+
325+ itemProvider. errorToThrow = PointOfSaleItemServiceError . requestCancelled
326+ try #require( sut. itemsViewState. containerState == . loading)
327+
328+ // When
329+ await sut. loadItems ( base: . root)
330+
331+ // Then
332+ guard case . loaded( let items, let hasMoreItems) = sut. itemsViewState. itemsStack. root else {
333+ Issue . record ( " Expected loaded ItemList state, but got \( sut. itemsViewState. itemsStack. root) " )
334+ return
335+ }
336+ #expect( items. count == 0 )
337+ #expect( hasMoreItems)
338+ }
339+
340+ @available ( iOS 17 . 0 , * )
341+ @Test func loadNextItems_when_request_is_cancelled_then_state_is_loaded( ) async throws {
342+ // Given
343+ let itemProvider = MockPointOfSaleItemService ( )
344+ let sut = PointOfSaleItemsController ( itemProvider: itemProvider)
345+
346+ itemProvider. shouldSimulateTwoPages = true
347+ await sut. loadItems ( base: . root)
348+
349+ guard case . loaded = sut. itemsViewState. itemsStack. root else {
350+ Issue . record ( " Expected loaded ItemList state, but got \( sut. itemsViewState. itemsStack. root) " )
351+ return
352+ }
353+
354+ itemProvider. errorToThrow = PointOfSaleItemServiceError . requestCancelled
355+
356+ // When
357+ await sut. loadNextItems ( base: . root)
358+
359+ // Then
360+ #expect( sut. itemsViewState. containerState == . content)
361+
362+ guard case . loaded( let items, let hasMoreItems) = sut. itemsViewState. itemsStack. root else {
363+ Issue . record ( " Expected loaded ItemList state, but got \( sut. itemsViewState. itemsStack. root) " )
364+ return
365+ }
366+ #expect( items. count == 2 )
367+ #expect( hasMoreItems)
368+ }
369+
318370 @available ( iOS 17 . 0 , * )
319371 @Test func loadNextItems_after_itemProvider_throws_error_then_the_same_page_is_requested_next( ) async throws {
320372 // Given
@@ -324,7 +376,7 @@ final class PointOfSaleItemsControllerTests {
324376 itemProvider. shouldSimulateTwoPages = true
325377 await sut. loadItems ( base: . root)
326378
327- itemProvider. shouldThrowError = true
379+ itemProvider. errorToThrow = MockError . requestFailed
328380 await sut. loadNextItems ( base: . root)
329381 try #require( itemProvider. spyLastRequestedPageNumber == 2 )
330382 itemProvider. spyLastRequestedPageNumber = 0
@@ -505,4 +557,67 @@ final class PointOfSaleItemsControllerTests {
505557 await sut. loadItems ( base: baseItem)
506558 }
507559 }
560+
561+ @available ( iOS 17 . 0 , * )
562+ @Test func loadChildItems_when_request_is_cancelled_then_state_is_loaded( ) async throws {
563+ // Given
564+ let itemProvider = MockPointOfSaleItemService ( )
565+ let sut = PointOfSaleItemsController ( itemProvider: itemProvider)
566+
567+ let parentItem = POSItem . variableParentProduct ( POSVariableParentProduct ( id: UUID ( ) ,
568+ name: " Parent product " ,
569+ productImageSource: nil ,
570+ productID: 125 ) )
571+ let baseItem = ItemListBaseItem . parent ( parentItem)
572+
573+ itemProvider. errorToThrow = PointOfSaleItemServiceError . requestCancelled
574+ try #require( sut. itemsViewState. containerState == . loading)
575+
576+ // When
577+ await sut. loadItems ( base: baseItem)
578+
579+ // Then
580+ guard case . loaded( let items, let hasMoreItems) = sut. itemsViewState. itemsStack. itemStates [ parentItem] else {
581+ Issue . record ( " Expected loaded ItemList state, but got \( String ( describing: sut. itemsViewState. itemsStack. itemStates [ parentItem] ) ) " )
582+ return
583+ }
584+ #expect( items. count == 0 )
585+ #expect( hasMoreItems)
586+ }
587+
588+ @available ( iOS 17 . 0 , * )
589+ @Test func loadNextChildItems_when_request_is_cancelled_then_state_is_loaded( ) async throws {
590+ // Given
591+ let itemProvider = MockPointOfSaleItemService ( )
592+ let sut = PointOfSaleItemsController ( itemProvider: itemProvider)
593+
594+ let parentItem = POSItem . variableParentProduct ( POSVariableParentProduct ( id: UUID ( ) ,
595+ name: " Parent product " ,
596+ productImageSource: nil ,
597+ productID: 125 ) )
598+ let baseItem = ItemListBaseItem . parent ( parentItem)
599+
600+ itemProvider. shouldSimulateTwoPagesOfVariations = true
601+ await sut. loadItems ( base: baseItem)
602+
603+ itemProvider. errorToThrow = PointOfSaleItemServiceError . requestCancelled
604+
605+ // When
606+ await sut. loadNextItems ( base: baseItem)
607+
608+ // Then
609+ #expect( sut. itemsViewState. containerState == . content)
610+
611+ guard case . loaded( let items, let hasMoreItems) = sut. itemsViewState. itemsStack. itemStates [ parentItem] else {
612+ Issue . record ( " Expected loaded ItemList state, but got \( String ( describing: sut. itemsViewState. itemsStack. itemStates [ parentItem] ) ) " )
613+ return
614+ }
615+ #expect( items. count == 2 )
616+ #expect( hasMoreItems)
617+ }
618+
619+
620+ enum MockError : Error {
621+ case requestFailed
622+ }
508623}
0 commit comments