From a4ed681edaebfe0cdd96d08f63cb117e80128702 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 14 Jul 2023 13:06:37 -0400 Subject: [PATCH 1/9] add error handling on paymentTypes --- .../checkout-payment-type.component.ts | 39 ++++++++++++++++--- .../facade/checkout-payment-type.service.ts | 14 +++++-- .../core/src/util/occ-http-error-constants.ts | 1 + 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts index 859cf31e525..5c3e99788f7 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts @@ -18,9 +18,22 @@ import { } from '@spartacus/checkout/b2b/root'; import { CheckoutStepService } from '@spartacus/checkout/base/components'; import { CheckoutStepType } from '@spartacus/checkout/base/root'; -import { getLastValueSync, isNotUndefined } from '@spartacus/core'; -import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; -import { distinctUntilChanged, filter, map, tap } from 'rxjs/operators'; +import { + GlobalMessageService, + GlobalMessageType, + HttpErrorModel, + OccHttpErrorType, + getLastValueSync, + isNotUndefined, +} from '@spartacus/core'; +import { BehaviorSubject, Observable, combineLatest, throwError } from 'rxjs'; +import { + catchError, + distinctUntilChanged, + filter, + map, + tap, +} from 'rxjs/operators'; @Component({ selector: 'cx-payment-type', @@ -45,8 +58,21 @@ export class CheckoutPaymentTypeComponent { distinctUntilChanged() ); - paymentTypes$: Observable = - this.checkoutPaymentTypeFacade.getPaymentTypes(); + paymentTypes$: Observable = this.checkoutPaymentTypeFacade + .getPaymentTypes() + .pipe( + catchError((error: HttpErrorModel) => { + if ( + error.details?.[0]?.type === OccHttpErrorType.CLASS_MISMATCH_ERROR + ) { + this.globalMessageService.add( + error.details?.[0]?.message ?? '', + GlobalMessageType.MSG_TYPE_ERROR + ); + } + return throwError(error); + }) + ); typeSelected$: Observable = combineLatest([ this.checkoutPaymentTypeFacade.getSelectedPaymentTypeState().pipe( @@ -108,7 +134,8 @@ export class CheckoutPaymentTypeComponent { constructor( protected checkoutPaymentTypeFacade: CheckoutPaymentTypeFacade, protected checkoutStepService: CheckoutStepService, - protected activatedRoute: ActivatedRoute + protected activatedRoute: ActivatedRoute, + protected globalMessageService: GlobalMessageService ) {} changeType(code: string): void { diff --git a/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts b/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts index a78be7f3333..5eb31eaff2b 100644 --- a/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts +++ b/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts @@ -19,6 +19,7 @@ import { CommandService, CommandStrategy, EventService, + HttpErrorModel, OCC_USER_ID_ANONYMOUS, Query, QueryNotifier, @@ -26,8 +27,8 @@ import { QueryState, UserIdService, } from '@spartacus/core'; -import { combineLatest, Observable } from 'rxjs'; -import { filter, map, switchMap, take, tap } from 'rxjs/operators'; +import { Observable, combineLatest, of, throwError } from 'rxjs'; +import { concatMap, filter, map, switchMap, take, tap } from 'rxjs/operators'; import { CheckoutPaymentTypeConnector } from '../connectors/checkout-payment-type/checkout-payment-type.connector'; @Injectable() @@ -119,7 +120,14 @@ export class CheckoutPaymentTypeService implements CheckoutPaymentTypeFacade { } getPaymentTypes(): Observable { - return this.getPaymentTypesState().pipe(map((state) => state.data ?? [])); + return this.getPaymentTypesState().pipe( + concatMap((queryState) => + (queryState?.error as HttpErrorModel) + ? throwError(queryState.error as HttpErrorModel) + : of(queryState) + ), + map((state) => state.data ?? []) + ); } setPaymentType( diff --git a/projects/core/src/util/occ-http-error-constants.ts b/projects/core/src/util/occ-http-error-constants.ts index b491c68ad07..bd8d4efc6c8 100644 --- a/projects/core/src/util/occ-http-error-constants.ts +++ b/projects/core/src/util/occ-http-error-constants.ts @@ -8,6 +8,7 @@ export declare const enum OccHttpErrorType { NOT_FOUND_ERROR = 'NotFoundError', + CLASS_MISMATCH_ERROR = 'ClassMismatchError', } export declare const enum OccHttpErrorReason { From fc38ae3b18a973edb3f2e47117ef3055bcba721e Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 14 Jul 2023 13:43:12 -0400 Subject: [PATCH 2/9] keep same paymentType output --- .../checkout-payment-type.component.ts | 4 ++-- .../b2b/core/facade/checkout-payment-type.service.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts index 5c3e99788f7..bac25fa0cc5 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts @@ -26,7 +26,7 @@ import { getLastValueSync, isNotUndefined, } from '@spartacus/core'; -import { BehaviorSubject, Observable, combineLatest, throwError } from 'rxjs'; +import { BehaviorSubject, Observable, combineLatest, of } from 'rxjs'; import { catchError, distinctUntilChanged, @@ -70,7 +70,7 @@ export class CheckoutPaymentTypeComponent { GlobalMessageType.MSG_TYPE_ERROR ); } - return throwError(error); + return of([]); }) ); diff --git a/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts b/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts index 5eb31eaff2b..5cb0805efb0 100644 --- a/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts +++ b/feature-libs/checkout/b2b/core/facade/checkout-payment-type.service.ts @@ -121,10 +121,10 @@ export class CheckoutPaymentTypeService implements CheckoutPaymentTypeFacade { getPaymentTypes(): Observable { return this.getPaymentTypesState().pipe( - concatMap((queryState) => - (queryState?.error as HttpErrorModel) - ? throwError(queryState.error as HttpErrorModel) - : of(queryState) + concatMap((state) => + (state?.error as HttpErrorModel) + ? throwError(state.error as HttpErrorModel) + : of(state) ), map((state) => state.data ?? []) ); From a4bdc7aa737db5de7e71d167bed725277e1596c2 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 14 Jul 2023 14:05:41 -0400 Subject: [PATCH 3/9] change global message with more Authorization context --- .../checkout-payment-type/checkout-payment-type.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts index bac25fa0cc5..5da08bb350f 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts @@ -66,7 +66,7 @@ export class CheckoutPaymentTypeComponent { error.details?.[0]?.type === OccHttpErrorType.CLASS_MISMATCH_ERROR ) { this.globalMessageService.add( - error.details?.[0]?.message ?? '', + { key: 'httpHandlers.forbidden' }, GlobalMessageType.MSG_TYPE_ERROR ); } From 177edf3444723de87e92c5696663b1700a3ec1b7 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Mon, 17 Jul 2023 16:41:32 -0400 Subject: [PATCH 4/9] use an error flag to control ui --- .../checkout-payment-type.component.html | 134 +++++++++--------- .../checkout-payment-type.component.ts | 3 + 2 files changed, 72 insertions(+), 65 deletions(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html index baf15c7bd01..df65450343c 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html @@ -3,79 +3,83 @@

- -
-
-
- -
-
- -
-
-
-
-
- +
+
+ +
-
- + +
+
+ +
+
+ +
-
+ -
diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts index 5da08bb350f..d5dd0263efb 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts @@ -47,6 +47,7 @@ export class CheckoutPaymentTypeComponent { protected busy$ = new BehaviorSubject(false); typeSelected?: string; + paymentTypesError = false; isUpdating$ = combineLatest([ this.busy$, @@ -61,6 +62,7 @@ export class CheckoutPaymentTypeComponent { paymentTypes$: Observable = this.checkoutPaymentTypeFacade .getPaymentTypes() .pipe( + tap(() => (this.paymentTypesError = false)), catchError((error: HttpErrorModel) => { if ( error.details?.[0]?.type === OccHttpErrorType.CLASS_MISMATCH_ERROR @@ -69,6 +71,7 @@ export class CheckoutPaymentTypeComponent { { key: 'httpHandlers.forbidden' }, GlobalMessageType.MSG_TYPE_ERROR ); + this.paymentTypesError = true; } return of([]); }) From 7c8875579ac34eb7cc95ab7f67601cf302ce48d2 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Mon, 17 Jul 2023 21:41:23 -0400 Subject: [PATCH 5/9] add optional service - hide spinner on condition --- .../checkout-payment-type.component.html | 2 +- .../checkout-payment-type.component.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html index df65450343c..8701ccb6b83 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html @@ -81,7 +81,7 @@

-
+
diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts index d5dd0263efb..547d5f639a2 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts @@ -8,6 +8,7 @@ import { ChangeDetectionStrategy, Component, ElementRef, + Optional, ViewChild, } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @@ -65,7 +66,8 @@ export class CheckoutPaymentTypeComponent { tap(() => (this.paymentTypesError = false)), catchError((error: HttpErrorModel) => { if ( - error.details?.[0]?.type === OccHttpErrorType.CLASS_MISMATCH_ERROR + error.details?.[0]?.type === OccHttpErrorType.CLASS_MISMATCH_ERROR && + this.globalMessageService ) { this.globalMessageService.add( { key: 'httpHandlers.forbidden' }, @@ -138,7 +140,7 @@ export class CheckoutPaymentTypeComponent { protected checkoutPaymentTypeFacade: CheckoutPaymentTypeFacade, protected checkoutStepService: CheckoutStepService, protected activatedRoute: ActivatedRoute, - protected globalMessageService: GlobalMessageService + @Optional() protected globalMessageService?: GlobalMessageService ) {} changeType(code: string): void { From 0737b3a312b933cbdd0e4b90d199c5887fc9c485 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Mon, 17 Jul 2023 22:08:27 -0400 Subject: [PATCH 6/9] add deprecated constructor --- .../checkout-payment-type.component.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts index 547d5f639a2..3684d266db0 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts @@ -136,6 +136,23 @@ export class CheckoutPaymentTypeComponent { distinctUntilChanged() ); + constructor( + checkoutPaymentTypeFacade: CheckoutPaymentTypeFacade, + checkoutStepService: CheckoutStepService, + activatedRoute: ActivatedRoute, + // eslint-disable-next-line @typescript-eslint/unified-signatures + globalMessageService?: GlobalMessageService + ); + /** + * @depreccated since 6.3 + */ + constructor( + checkoutPaymentTypeFacade: CheckoutPaymentTypeFacade, + checkoutStepService: CheckoutStepService, + activatedRoute: ActivatedRoute, + globalMessageService: GlobalMessageService + ); + constructor( protected checkoutPaymentTypeFacade: CheckoutPaymentTypeFacade, protected checkoutStepService: CheckoutStepService, From 981fe84a15da6037e40a5e9fcd9dc85c2db87b52 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Mon, 17 Jul 2023 22:22:25 -0400 Subject: [PATCH 7/9] revert --- .../checkout-payment-type.component.html | 134 +++++++++--------- 1 file changed, 65 insertions(+), 69 deletions(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html index 8701ccb6b83..e4707e495c3 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.html @@ -3,83 +3,79 @@

- - -
-
-
-
-
-
- -
+
+
+
- -
-
- -
-
- -
+
+
- +
+
From 8b98c78d5142515caecb615bcb4395e5c4848dd1 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Tue, 18 Jul 2023 11:16:58 -0400 Subject: [PATCH 8/9] add comments --- .../checkout-payment-type/checkout-payment-type.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts index 3684d266db0..55069a21be2 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.ts @@ -136,6 +136,7 @@ export class CheckoutPaymentTypeComponent { distinctUntilChanged() ); + // TODO(CXSPA-3334): make globalMessageService a required dependency constructor( checkoutPaymentTypeFacade: CheckoutPaymentTypeFacade, checkoutStepService: CheckoutStepService, @@ -143,8 +144,9 @@ export class CheckoutPaymentTypeComponent { // eslint-disable-next-line @typescript-eslint/unified-signatures globalMessageService?: GlobalMessageService ); + /** - * @depreccated since 6.3 + * @deprecated since 6.3 */ constructor( checkoutPaymentTypeFacade: CheckoutPaymentTypeFacade, From 795d3f85bf46b308e86f246e878e1c2a441f9ec9 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Tue, 18 Jul 2023 12:51:31 -0400 Subject: [PATCH 9/9] fix unit test by addimg GlobalMessageService --- .../checkout-payment-type.component.spec.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.spec.ts b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.spec.ts index 505e8782429..432275a3cc0 100644 --- a/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.spec.ts +++ b/feature-libs/checkout/b2b/components/checkout-payment-type/checkout-payment-type.component.spec.ts @@ -6,7 +6,11 @@ import { PaymentType } from '@spartacus/cart/base/root'; import { CheckoutPaymentTypeFacade } from '@spartacus/checkout/b2b/root'; import { CheckoutStepService } from '@spartacus/checkout/base/components'; import { CheckoutStepType } from '@spartacus/checkout/base/root'; -import { I18nTestingModule, QueryState } from '@spartacus/core'; +import { + GlobalMessageService, + I18nTestingModule, + QueryState, +} from '@spartacus/core'; import { BehaviorSubject, of } from 'rxjs'; import { take } from 'rxjs/operators'; import { CheckoutPaymentTypeComponent } from './checkout-payment-type.component'; @@ -18,6 +22,9 @@ import createSpy = jasmine.createSpy; }) class MockSpinnerComponent {} +class MockGlobalMessageService { + add = createSpy(); +} class MockCheckoutPaymentTypeService implements Partial { @@ -92,6 +99,10 @@ describe('CheckoutOnePaymentTypeComponent', () => { useClass: MockCheckoutStepService, }, { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { + provide: GlobalMessageService, + useClass: MockGlobalMessageService, + }, ], }).compileComponents(); @@ -145,6 +156,10 @@ describe('CheckoutPaymentTypeComponent', () => { useClass: MockCheckoutStepService, }, { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { + provide: GlobalMessageService, + useClass: MockGlobalMessageService, + }, ], }).compileComponents();