@@ -43,6 +43,10 @@ final class CardPresentPaymentStoreTests: XCTestCase {
4343 ///
4444 private let sampleChargeID = " ch_3KMVap2EdyGr1FMV1uKJEWtg "
4545
46+ /// Testing Charge ID for card transaction
47+ ///
48+ private let sampleCardChargeID = " ch_3KMuym2EdyGr1FMV0uQZeFqm "
49+
4650 /// Testing Charge ID for error
4751 ///
4852 private let sampleErrorChargeID = " ch_3KMVapErrorERROR "
@@ -432,6 +436,96 @@ final class CardPresentPaymentStoreTests: XCTestCase {
432436 XCTAssertEqual ( charge. id, sampleChargeID)
433437 }
434438
439+ func test_fetchWCPayCharge_inserts_charge_in_storage( ) throws {
440+ let store = CardPresentPaymentStore ( dispatcher: dispatcher,
441+ storageManager: storageManager,
442+ network: network,
443+ cardReaderService: mockCardReaderService,
444+ allowStripeIPP: false )
445+
446+ network. simulateResponse ( requestUrlSuffix: " payments/charges/ \( sampleChargeID) " ,
447+ filename: " wcpay-charge-card-present " )
448+
449+ let result : Result < Yosemite . WCPayCharge , Error > = waitFor { [ self ] promise in
450+ let action = CardPresentPaymentAction . fetchWCPayCharge ( siteID: self . sampleSiteID, chargeID: self . sampleChargeID, onCompletion: { result in
451+ promise ( result)
452+ } )
453+ store. onAction ( action)
454+ }
455+ XCTAssertTrue ( result. isSuccess)
456+
457+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCharge. self, matching: nil ) == 1 )
458+
459+ let storageCharge = viewStorage. loadWCPayCharge ( siteID: sampleSiteID, chargeID: sampleChargeID)
460+
461+ XCTAssertEqual ( storageCharge? . siteID, sampleSiteID)
462+ XCTAssertEqual ( storageCharge? . chargeID, sampleChargeID)
463+ XCTAssertEqual ( storageCharge? . status, " succeeded " )
464+ }
465+
466+ func test_fetchWCPayCharge_inserts_card_present_charge_details_in_storage( ) throws {
467+ let store = CardPresentPaymentStore ( dispatcher: dispatcher,
468+ storageManager: storageManager,
469+ network: network,
470+ cardReaderService: mockCardReaderService,
471+ allowStripeIPP: false )
472+
473+ network. simulateResponse ( requestUrlSuffix: " payments/charges/ \( sampleChargeID) " ,
474+ filename: " wcpay-charge-card-present " )
475+
476+ let result : Result < Yosemite . WCPayCharge , Error > = waitFor { [ self ] promise in
477+ let action = CardPresentPaymentAction . fetchWCPayCharge ( siteID: self . sampleSiteID, chargeID: self . sampleChargeID, onCompletion: { result in
478+ promise ( result)
479+ } )
480+ store. onAction ( action)
481+ }
482+ XCTAssertTrue ( result. isSuccess)
483+
484+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCharge. self, matching: nil ) == 1 )
485+
486+ let storageCharge = viewStorage. loadWCPayCharge ( siteID: sampleSiteID, chargeID: sampleChargeID)
487+
488+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCardPaymentDetails. self, matching: nil ) == 0 )
489+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCardPresentPaymentDetails. self, matching: nil ) == 1 )
490+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCardPresentReceiptDetails. self, matching: nil ) == 1 )
491+
492+ let storedDetails = storageCharge? . cardPresentDetails
493+ XCTAssertEqual ( storedDetails? . receipt? . applicationPreferredName, " Stripe Credit " )
494+ XCTAssertEqual ( storedDetails? . last4, " 9969 " )
495+ XCTAssertNil ( storageCharge? . cardDetails)
496+ }
497+
498+ func test_fetchWCPayCharge_inserts_card_charge_details_in_storage( ) throws {
499+ let store = CardPresentPaymentStore ( dispatcher: dispatcher,
500+ storageManager: storageManager,
501+ network: network,
502+ cardReaderService: mockCardReaderService,
503+ allowStripeIPP: false )
504+
505+ network. simulateResponse ( requestUrlSuffix: " payments/charges/ \( sampleCardChargeID) " ,
506+ filename: " wcpay-charge-card " )
507+
508+ let result : Result < Yosemite . WCPayCharge , Error > = waitFor { [ self ] promise in
509+ let action = CardPresentPaymentAction . fetchWCPayCharge ( siteID: self . sampleSiteID, chargeID: self . sampleCardChargeID, onCompletion: { result in
510+ promise ( result)
511+ } )
512+ store. onAction ( action)
513+ }
514+ XCTAssertTrue ( result. isSuccess)
515+
516+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCharge. self, matching: nil ) == 1 )
517+
518+ let storageCharge = viewStorage. loadWCPayCharge ( siteID: sampleSiteID, chargeID: sampleCardChargeID)
519+
520+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCardPaymentDetails. self, matching: nil ) == 1 )
521+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCardPresentPaymentDetails. self, matching: nil ) == 0 )
522+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCardPresentReceiptDetails. self, matching: nil ) == 0 )
523+
524+ let storedDetails = storageCharge? . cardDetails
525+ XCTAssertEqual ( storedDetails? . last4, " 1111 " )
526+ XCTAssertNil ( storageCharge? . cardPresentDetails)
527+ }
528+
435529 /// Verifies that the store hits the network when fetching a charge, and propagates errors.
436530 ///
437531 func test_fetchWCPayCharge_returns_error_on_failure( ) {
@@ -442,7 +536,7 @@ final class CardPresentPaymentStoreTests: XCTestCase {
442536 allowStripeIPP: false )
443537
444538 network. simulateResponse ( requestUrlSuffix: " payments/charges/ \( sampleErrorChargeID) " ,
445- filename: " wcpay-customer -error " )
539+ filename: " wcpay-charge -error " )
446540 let result : Result < Yosemite . WCPayCharge , Error > = waitFor { [ self ] promise in
447541 let action = CardPresentPaymentAction . fetchWCPayCharge ( siteID: self . sampleSiteID, chargeID: self . sampleErrorChargeID, onCompletion: { result in
448542 promise ( result)
@@ -451,4 +545,63 @@ final class CardPresentPaymentStoreTests: XCTestCase {
451545 }
452546 XCTAssertTrue ( result. isFailure)
453547 }
548+
549+ /// Verifies that the store deletes the charge if it's gone from the remote.
550+ ///
551+ func test_fetchWCPayCharge_deletes_existing_charge_on_no_such_charge_failure( ) {
552+ let charge = viewStorage. insertNewObject ( ofType: Storage . WCPayCharge. self)
553+ let networkCharge = WCPayCharge . fake ( ) . copy ( siteID: sampleSiteID, id: sampleErrorChargeID)
554+ charge. update ( with: networkCharge)
555+ let otherCharge = viewStorage. insertNewObject ( ofType: Storage . WCPayCharge. self)
556+ let otherNetworkCharge = WCPayCharge . fake ( ) . copy ( siteID: sampleSiteID, id: sampleChargeID)
557+ otherCharge. update ( with: otherNetworkCharge)
558+
559+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCharge. self, matching: nil ) == 2 )
560+ let store = CardPresentPaymentStore ( dispatcher: dispatcher,
561+ storageManager: storageManager,
562+ network: network,
563+ cardReaderService: mockCardReaderService,
564+ allowStripeIPP: false )
565+
566+ network. simulateResponse ( requestUrlSuffix: " payments/charges/ \( sampleErrorChargeID) " ,
567+ filename: " wcpay-charge-error " )
568+ let _: Result < Yosemite . WCPayCharge , Error > = waitFor { [ self ] promise in
569+ let action = CardPresentPaymentAction . fetchWCPayCharge ( siteID: self . sampleSiteID, chargeID: self . sampleErrorChargeID, onCompletion: { result in
570+ promise ( result)
571+ } )
572+ store. onAction ( action)
573+ }
574+ XCTAssertEqual ( viewStorage. countObjects ( ofType: Storage . WCPayCharge. self, matching: nil ) , 1 )
575+
576+ let storageCharge = viewStorage. firstObject ( ofType: Storage . WCPayCharge. self)
577+ XCTAssertEqual ( storageCharge, otherCharge)
578+ }
579+
580+ /// Verifies that the store doesn't delete charges just for any old error.
581+ ///
582+ func test_fetchWCPayCharge_does_not_delete_existing_charge_on_unknown_failure( ) {
583+ let charge = viewStorage. insertNewObject ( ofType: Storage . WCPayCharge. self)
584+ let networkCharge = WCPayCharge . fake ( ) . copy ( siteID: sampleSiteID, id: sampleErrorChargeID)
585+ charge. update ( with: networkCharge)
586+ let otherCharge = viewStorage. insertNewObject ( ofType: Storage . WCPayCharge. self)
587+ let otherNetworkCharge = WCPayCharge . fake ( ) . copy ( siteID: sampleSiteID, id: sampleChargeID)
588+ otherCharge. update ( with: otherNetworkCharge)
589+
590+ XCTAssert ( viewStorage. countObjects ( ofType: Storage . WCPayCharge. self, matching: nil ) == 2 )
591+ let store = CardPresentPaymentStore ( dispatcher: dispatcher,
592+ storageManager: storageManager,
593+ network: network,
594+ cardReaderService: mockCardReaderService,
595+ allowStripeIPP: false )
596+ network. simulateError ( requestUrlSuffix: " payments/charges/ \( sampleErrorChargeID) " ,
597+ error: DotcomError . unknown ( code: " beep " , message: " boop " ) )
598+
599+ let _: Result < Yosemite . WCPayCharge , Error > = waitFor { [ self ] promise in
600+ let action = CardPresentPaymentAction . fetchWCPayCharge ( siteID: self . sampleSiteID, chargeID: self . sampleErrorChargeID, onCompletion: { result in
601+ promise ( result)
602+ } )
603+ store. onAction ( action)
604+ }
605+ XCTAssertEqual ( viewStorage. countObjects ( ofType: Storage . WCPayCharge. self, matching: nil ) , 2 )
606+ }
454607}
0 commit comments