Skip to content

Commit

Permalink
Merge branch 'develop-6.6.x' into epic/CXSPA-2897
Browse files Browse the repository at this point in the history
  • Loading branch information
pawelfras authored Oct 9, 2023
2 parents a2bfa27 + 0d36166 commit eb7351e
Show file tree
Hide file tree
Showing 15 changed files with 847 additions and 221 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
<div class="cx-order-items" *ngIf="order$ | async as order">
<div class="cx-review-summary" *ngIf="order.paymentInfo as paymentDetails">
<div class="cx-review-summary-card cx-review-summary-payment-card">
<cx-card
[content]="getPaymentMethodCard(paymentDetails) | async"
></cx-card>
</div>

<div class="cx-review-summary-card cx-review-summary-payment-card">
<cx-card
[content]="getBillingAddressCard(paymentDetails) | async"
></cx-card>
</div>
<ng-container *cxFeatureLevel="'!6.6'">
<div class="cx-review-summary-card cx-review-summary-payment-card">
<cx-card
[content]="getPaymentMethodCard(paymentDetails) | async"
></cx-card>
</div>
</ng-container>
<ng-container *cxFeatureLevel="'6.6'">
<div
class="cx-review-summary-card cx-review-summary-payment-card"
*ngIf="isPaymentInfoCardFull(paymentDetails)"
>
<cx-card
[content]="getPaymentMethodCard(paymentDetails) | async"
></cx-card>
</div>
</ng-container>
<ng-container *cxFeatureLevel="'!6.6'">
<div class="cx-review-summary-card cx-review-summary-payment-card">
<cx-card
[content]="getBillingAddressCard(paymentDetails) | async"
></cx-card>
</div>
</ng-container>
<ng-container *cxFeatureLevel="'6.6'">
<div
class="cx-review-summary-card cx-review-summary-payment-card"
*ngIf="paymentDetails?.billingAddress"
>
<cx-card
[content]="getBillingAddressCard(paymentDetails) | async"
></cx-card>
</div>
</ng-container>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,15 @@ describe('OrderDetailBillingComponent', () => {
]);
});
});

it('should be false when isPaymentInfoCardFull is called with partial card info', () => {
expect(
component.isPaymentInfoCardFull({
...mockPaymentDetails,
expiryMonth: '',
})
).toBeFalsy();

expect(component.isPaymentInfoCardFull(mockPaymentDetails)).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
import { PaymentDetails } from '@spartacus/cart/base/root';
import { TranslationService } from '@spartacus/core';
import {
billingAddressCard,
Order,
billingAddressCard,
paymentMethodCard,
} from '@spartacus/order/root';
import { Card } from '@spartacus/storefront';
import { combineLatest, Observable } from 'rxjs';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { OrderDetailsService } from '../order-details.service';

Expand Down Expand Up @@ -55,4 +55,10 @@ export class OrderDetailBillingComponent {
)
);
}

isPaymentInfoCardFull(payment: PaymentDetails): boolean {
return (
!!payment?.cardNumber && !!payment?.expiryMonth && !!payment?.expiryYear
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,17 @@
</ng-template>
</ng-container>
</div>
<cx-order-detail-billing></cx-order-detail-billing>
<ng-container *cxFeatureLevel="'!6.6'">
<cx-order-detail-billing></cx-order-detail-billing>
</ng-container>
<ng-container *cxFeatureLevel="'6.6'">
<cx-order-detail-billing
*ngIf="
isPaymentInfoCardFull(order?.paymentInfo) ||
order?.paymentInfo?.billingAddress
"
></cx-order-detail-billing>
</ng-container>
</div>
</ng-container>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
flex-grow: 1;

@include media-breakpoint-up(lg) {
border-inline-end: 1px solid var(--cx-color-text);
margin-inline-end: 10rem;
@include forVersion(1, 6.5) {
border-inline-end: 1px solid var(--cx-color-text);
margin-inline-end: 10rem;
}

cx-card {
padding: 10px 0;
Expand Down Expand Up @@ -106,6 +108,13 @@
flex-grow: 1;
margin-bottom: 0;

@include forVersion(6.6) {
@include media-breakpoint-up(lg) {
border-inline-start: 1px solid var(--cx-color-text);
padding-inline-start: 10rem;
}
}

.cx-review-summary {
flex-direction: column;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing';
import { inject, TestBed } from '@angular/core/testing';
import { defaultOccConfig } from '@spartacus/core';
import { TestBed, inject } from '@angular/core/testing';
import {
FeatureConfigService,
PageContext,
PageType,
RoutingService,
defaultOccConfig,
} from '@spartacus/core';
import { Observable, of } from 'rxjs';
import { SmartEditLauncherService } from '../services/smart-edit-launcher.service';
import { CmsTicketInterceptor } from './cms-ticket.interceptor';

Expand All @@ -16,10 +23,21 @@ class MockSmartEditLauncherService {
return this._cmsTicketId;
}
}
const mockPageContext = {
id: 'mockCode',
type: PageType.CATEGORY_PAGE,
};
class MockRoutingService implements Partial<RoutingService> {
getPageContext(): Observable<PageContext> {
return of(mockPageContext);
}
}

describe('CmsTicketInterceptor', () => {
let httpMock: HttpTestingController;
let service: SmartEditLauncherService;
let routingService: RoutingService;
let featureConfig: FeatureConfigService;

beforeEach(() => {
TestBed.configureTestingModule({
Expand All @@ -29,7 +47,10 @@ describe('CmsTicketInterceptor', () => {
provide: SmartEditLauncherService,
useClass: MockSmartEditLauncherService,
},

{
provide: RoutingService,
useClass: MockRoutingService,
},
{
provide: HTTP_INTERCEPTORS,
useClass: CmsTicketInterceptor,
Expand All @@ -40,6 +61,8 @@ describe('CmsTicketInterceptor', () => {

httpMock = TestBed.inject(HttpTestingController);
service = TestBed.inject(SmartEditLauncherService);
routingService = TestBed.inject(RoutingService);
featureConfig = TestBed.inject(FeatureConfigService);
});

afterEach(() => {
Expand Down Expand Up @@ -122,4 +145,61 @@ describe('CmsTicketInterceptor', () => {
mockReq.flush('somedata');
}
));

it('should add parameters for productList requests: cmsTicketId, pageType, code', inject(
[HttpClient],
(http: HttpClient) => {
spyOn(featureConfig, 'isLevel').and.returnValue(true);
spyOnProperty(service, 'cmsTicketId', 'get').and.returnValue(
'mockCmsTicketId'
);

http.get(`${OccUrl}/productList`).subscribe((result) => {
expect(result).toBeTruthy();
});
const mockReq = httpMock.expectOne((req) => {
return req.method === 'GET';
});

expect(mockReq.request.params.get('cmsTicketId')).toEqual(
'mockCmsTicketId'
);
expect(mockReq.request.params.get('pageType')).toEqual(
PageType.CATEGORY_PAGE
);
expect(mockReq.request.params.get('code')).toEqual('mockCode');
mockReq.flush('somedata');
}
));

it('should add only one parameter for productList requests when pageContext is partial: cmsTicketId', inject(
[HttpClient],
(http: HttpClient) => {
spyOn(featureConfig, 'isLevel').and.returnValue(true);
spyOn(routingService, 'getPageContext').and.returnValue(
of({
...mockPageContext,
id: '',
})
);

spyOnProperty(service, 'cmsTicketId', 'get').and.returnValue(
'mockCmsTicketId'
);

http.get(`${OccUrl}/productList`).subscribe((result) => {
expect(result).toBeTruthy();
});
const mockReq = httpMock.expectOne((req) => {
return req.method === 'GET';
});

expect(mockReq.request.params.get('cmsTicketId')).toEqual(
'mockCmsTicketId'
);
expect(mockReq.request.params.get('pageType')).toBeFalsy();
expect(mockReq.request.params.get('code')).toBeFalsy();
mockReq.flush('somedata');
}
));
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,72 @@ import {
HttpInterceptor,
HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import {
FeatureConfigService,
PageContext,
RoutingService,
} from '@spartacus/core';
import { Observable } from 'rxjs';
import { switchMap, take } from 'rxjs/operators';
import { SmartEditLauncherService } from '../services/smart-edit-launcher.service';

@Injectable({ providedIn: 'root' })
export class CmsTicketInterceptor implements HttpInterceptor {
constructor(private service: SmartEditLauncherService) {}
routingService = inject(RoutingService);
featureConfig = inject(FeatureConfigService);
constructor(protected service: SmartEditLauncherService) {}

intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const cmsTicketId = this.service.cmsTicketId;
if (!cmsTicketId) {
return next.handle(request);
}
if (
this.service.cmsTicketId &&
(request.url.includes('/cms/') || request.url.includes('/products/'))
this.featureConfig.isLevel('6.6') &&
request.url.includes('/productList')
) {
return this.setRequestForProductListPage(request, next, cmsTicketId);
}
if (request.url.includes('/cms/') || request.url.includes('/products/')) {
request = request.clone({
setParams: {
cmsTicketId: this.service.cmsTicketId,
cmsTicketId,
},
});
}

return next.handle(request);
}

protected setRequestForProductListPage(
request: HttpRequest<any>,
next: HttpHandler,
cmsTicketId: string
) {
return this.routingService.getPageContext().pipe(
take(1),
switchMap((pageContext: PageContext) => {
request = request.clone(
!!pageContext.id && !!pageContext.type
? {
setParams: {
cmsTicketId,
pageType: pageContext.type,
code: pageContext.id,
},
}
: {
setParams: {
cmsTicketId,
},
}
);
return next.handle(request);
})
);
}
}
31 changes: 28 additions & 3 deletions projects/core/src/cms/cms.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,32 @@
*/

import { ModuleWithProviders, NgModule } from '@angular/core';
import { provideDefaultConfig } from '../config/config-providers';
import { defaultCmsModuleConfig } from './config/default-cms-config';
import {
defaultCmsModuleConfig,
defaultUserCmsModuleConfig,
} from './config/default-cms-config';
import { CmsService } from './facade/cms.service';
import { PageMetaModule } from './page/page-meta.module';
import { CmsStoreModule } from './store/cms-store.module';
import { ConfigChunk, provideDefaultConfigFactory } from '../config';
import { USER_CMS_ENDPOINTS } from '../model';

function getDefaultCmsConfig(configChunk: any) {
let isUserCmsEndpoint = false;

configChunk.find((config: any) => {
const userCmsEndpoints = config.features?.[USER_CMS_ENDPOINTS];

if (Boolean(userCmsEndpoints)) {
isUserCmsEndpoint = userCmsEndpoints;
}
});

if (isUserCmsEndpoint) {
return defaultUserCmsModuleConfig;
}
return defaultCmsModuleConfig;
}

@NgModule({
imports: [CmsStoreModule, PageMetaModule.forRoot()],
Expand All @@ -18,7 +39,11 @@ export class CmsModule {
static forRoot(): ModuleWithProviders<CmsModule> {
return {
ngModule: CmsModule,
providers: [CmsService, provideDefaultConfig(defaultCmsModuleConfig)],
providers: [
CmsService,
// TODO: (CXSPA-4886) In the major change to provideDefaultConfig(defaultCmsModuleConfig)
provideDefaultConfigFactory(getDefaultCmsConfig, [ConfigChunk]),
],
};
}
}
Loading

0 comments on commit eb7351e

Please sign in to comment.