Skip to content

Commit

Permalink
Merge branch 'develop-6.6.x' into epic/opf
Browse files Browse the repository at this point in the history
  • Loading branch information
FollowTheFlo committed Oct 25, 2023
2 parents 2aed8f0 + 29fd483 commit 8331f9f
Show file tree
Hide file tree
Showing 435 changed files with 22,657 additions and 515 deletions.
5 changes: 5 additions & 0 deletions .env-cmdrc
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,10 @@
"pdf-invoices": {
"CX_BASE_URL": "https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud",
"CX_PDF_INVOICES": "true"
},
"my-account-v2":{
"CX_BASE_URL": "https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud",
"CX_PDF_INVOICES": "true",
"CX_MY_ACCOUNT_V2": "true"
}
}
10 changes: 5 additions & 5 deletions core-libs/setup/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@spartacus/setup",
"version": "6.5.0",
"version": "6.6.0-1",
"description": "Includes features that makes Spartacus and it's setup easier and streamlined.",
"keywords": [
"spartacus",
Expand All @@ -20,10 +20,10 @@
},
"peerDependencies": {
"@angular/core": "^15.2.9",
"@spartacus/cart": "6.5.0",
"@spartacus/core": "6.5.0",
"@spartacus/order": "6.5.0",
"@spartacus/user": "6.5.0"
"@spartacus/cart": "6.6.0-1",
"@spartacus/core": "6.6.0-1",
"@spartacus/order": "6.6.0-1",
"@spartacus/user": "6.6.0-1"
},
"optionalDependencies": {
"@angular/platform-server": "^15.2.9",
Expand Down
8 changes: 7 additions & 1 deletion core-libs/setup/tsconfig.lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@
"@spartacus/user/profile": ["dist/user/profile"],
"@spartacus/user/profile/occ": ["dist/user/profile/occ"],
"@spartacus/user/profile/root": ["dist/user/profile/root"],
"@spartacus/storefront": ["dist/storefrontlib"]
"@spartacus/storefront": ["dist/storefrontlib"],
"@spartacus/pdf-invoices/assets": ["dist/pdf-invoices/assets"],
"@spartacus/pdf-invoices/components": ["dist/pdf-invoices/components"],
"@spartacus/pdf-invoices/core": ["dist/pdf-invoices/core"],
"@spartacus/pdf-invoices": ["dist/pdf-invoices"],
"@spartacus/pdf-invoices/occ": ["dist/pdf-invoices/occ"],
"@spartacus/pdf-invoices/root": ["dist/pdf-invoices/root"]
}
},
"angularCompilerOptions": {
Expand Down
18 changes: 18 additions & 0 deletions core-libs/setup/tsconfig.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,24 @@
"../../feature-libs/asm/components/public_api"
],
"@spartacus/asm/core": ["../../feature-libs/asm/core/public_api"],
"@spartacus/asm/customer-360/assets": [
"../../feature-libs/asm/customer-360/assets/public_api"
],
"@spartacus/asm/customer-360/components": [
"../../feature-libs/asm/customer-360/components/public_api"
],
"@spartacus/asm/customer-360/core": [
"../../feature-libs/asm/customer-360/core/public_api"
],
"@spartacus/asm/customer-360": [
"../../feature-libs/asm/customer-360/public_api"
],
"@spartacus/asm/customer-360/occ": [
"../../feature-libs/asm/customer-360/occ/public_api"
],
"@spartacus/asm/customer-360/root": [
"../../feature-libs/asm/customer-360/root/public_api"
],
"@spartacus/asm": ["../../feature-libs/asm/public_api"],
"@spartacus/asm/occ": ["../../feature-libs/asm/occ/public_api"],
"@spartacus/asm/root": ["../../feature-libs/asm/root/public_api"],
Expand Down
2 changes: 2 additions & 0 deletions feature-libs/asm/_index.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
@import '@spartacus/styles/scss/core';
@import './styles/index';

@import './customer-360/index';
1 change: 1 addition & 0 deletions feature-libs/asm/assets/translations/en/asm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const asm = {
logout: 'Sign Out',
hideUi: 'Close ASM',
customers: 'Customers',
asmCustomer360Button: '360 Customer View',
createCustomerSuccessfullyAlert:
'The customer account has been created and the customer session has started.',
saveInactiveCartAlertInfo:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
<label class="cx-asm-uid">{{ customer?.uid }}</label>
</div>
<cx-asm-bind-cart></cx-asm-bind-cart>
<ng-container *cxFeatureLevel="'6.6'">
<button
*ngIf="isAsmCustomer360Configured && customer"
#asmCustomer360Launcher
class="cx-360-button"
(click)="openAsmCustomer360()"
>
{{ 'asm.asmCustomer360Button' | cxTranslate }}
</button>
</ng-container>
<button formcontrolname="logoutCustomer" (click)="logoutCustomer()">
{{ 'asm.endEmulation' | cxTranslate }}
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,78 @@
import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { I18nTestingModule, User } from '@spartacus/core';
import {
FeatureModulesService,
FeaturesConfig,
FeaturesConfigModule,
I18nTestingModule,
User,
} from '@spartacus/core';
import { LaunchDialogService, LAUNCH_CALLER } from '@spartacus/storefront';
import { UserAccountFacade } from '@spartacus/user/account/root';
import { MockFeatureLevelDirective } from 'projects/storefrontlib/shared/test/mock-feature-level-directive';
import { Observable, of } from 'rxjs';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { AsmComponentService } from '../services/asm-component.service';
import { CustomerEmulationComponent } from './customer-emulation.component';

class MockUserAccountFacade implements Partial<UserAccountFacade> {
get(): Observable<User> {
return of({});
describe('CustomerEmulationComponent', () => {
class MockUserAccountFacade implements Partial<UserAccountFacade> {
get(): Observable<User> {
return of({});
}
}
}

class MockAsmComponentService {
logoutCustomer(): void {}
isCustomerEmulationSessionInProgress(): Observable<boolean> {
return of(true);
class MockAsmComponentService {
logoutCustomer(): void {}
isCustomerEmulationSessionInProgress(): Observable<boolean> {
return of(true);
}
handleAsmDialogAction(): void {}
}

const dialogClose$ = new BehaviorSubject<any>('');
class MockLaunchDialogService implements Partial<LaunchDialogService> {
openDialogAndSubscribe() {}
get dialogClose() {
return dialogClose$.asObservable();
}
}

class mockFeatureModulesService implements Partial<FeatureModulesService> {
isConfigured(): boolean {
return true;
}
resolveFeature(featureName: string): Observable<any> {
return of(featureName);
}
}
}

describe('CustomerEmulationComponent', () => {
let component: CustomerEmulationComponent;
let fixture: ComponentFixture<CustomerEmulationComponent>;
let userAccountFacade: UserAccountFacade;
let asmComponentService: AsmComponentService;
let el: DebugElement;
let featureModulesService: FeatureModulesService;

beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [I18nTestingModule],
imports: [I18nTestingModule, FeaturesConfigModule],
declarations: [CustomerEmulationComponent, MockFeatureLevelDirective],
providers: [
{
provide: FeatureModulesService,
useClass: mockFeatureModulesService,
},
{ provide: UserAccountFacade, useClass: MockUserAccountFacade },
{ provide: AsmComponentService, useClass: MockAsmComponentService },
{ provide: LaunchDialogService, useClass: MockLaunchDialogService },
{
provide: FeaturesConfig,
useValue: {
features: { level: '6.3' },
},
},
],
}).compileComponents();
})
Expand All @@ -47,6 +84,7 @@ describe('CustomerEmulationComponent', () => {
fixture.detectChanges();
userAccountFacade = TestBed.inject(UserAccountFacade);
asmComponentService = TestBed.inject(AsmComponentService);
featureModulesService = TestBed.inject(FeatureModulesService);
el = fixture.debugElement;
});

Expand Down Expand Up @@ -89,4 +127,54 @@ describe('CustomerEmulationComponent', () => {
//assert
expect(asmComponentService.logoutCustomer).toHaveBeenCalled();
});

it('should open customer 360 dialog', () => {
const launchDialogService = TestBed.inject(LaunchDialogService);

spyOn(launchDialogService, 'openDialogAndSubscribe').and.stub();

spyOn(asmComponentService, 'handleAsmDialogAction').and.stub();

component.openAsmCustomer360();

expect(launchDialogService.openDialogAndSubscribe).toHaveBeenCalledTimes(1);
const [caller, , data] = (<jasmine.Spy>(
launchDialogService.openDialogAndSubscribe
)).calls.argsFor(0);
expect(caller).toBe(LAUNCH_CALLER.ASM_CUSTOMER_360);
expect(data).toEqual({ customer: {} });

expect(asmComponentService.handleAsmDialogAction).not.toHaveBeenCalled();

dialogClose$.next({});

expect(asmComponentService.handleAsmDialogAction).toHaveBeenCalledTimes(1);
expect(asmComponentService.handleAsmDialogAction).toHaveBeenCalledWith(
{} as any
);
});

it('should display customer 360 button if asm customer360 is configured.', () => {
spyOn(featureModulesService, 'isConfigured').and.returnValue(true);
spyOn(userAccountFacade, 'get').and.returnValue(
of({ uid: '[email protected]', name: 'Test User' })
);
component.ngOnInit();
fixture.detectChanges();

expect(component.isAsmCustomer360Configured).toBeTruthy();
expect(el.query(By.css('.cx-360-button'))).toBeTruthy();
});

it('should not display customer 360 button if asm customer360 is not configured.', () => {
spyOn(featureModulesService, 'isConfigured').and.returnValue(false);
spyOn(userAccountFacade, 'get').and.returnValue(
of({ uid: '[email protected]', name: 'Test User' })
);
component.ngOnInit();
fixture.detectChanges();

expect(component.isAsmCustomer360Configured).toBeFalsy();
expect(el.query(By.css('.cx-360-button'))).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { Component, OnDestroy, OnInit } from '@angular/core';
import { User } from '@spartacus/core';
import {
Component,
ElementRef,
OnDestroy,
OnInit,
Optional,
ViewChild,
} from '@angular/core';
import { AsmDialogActionEvent } from '@spartacus/asm/customer-360/root';
import { FeatureModulesService, User } from '@spartacus/core';
import { LaunchDialogService, LAUNCH_CALLER } from '@spartacus/storefront';
import { UserAccountFacade } from '@spartacus/user/account/root';
import { Observable, Subscription } from 'rxjs';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';
import { AsmComponentService } from '../services/asm-component.service';

@Component({
Expand All @@ -17,14 +27,47 @@ import { AsmComponentService } from '../services/asm-component.service';
export class CustomerEmulationComponent implements OnInit, OnDestroy {
customer: User;
isCustomerEmulationSessionInProgress$: Observable<boolean>;

isAsmCustomer360Configured: boolean | undefined = false;
isAsmCustomer360Loaded$ = new BehaviorSubject<boolean>(false);

@ViewChild('asmCustomer360Launcher')
asmCustomer360LauncherElement: ElementRef;

protected subscription = new Subscription();

constructor(
asmComponentService: AsmComponentService,
userAccountFacade: UserAccountFacade,
// eslint-disable-next-line @typescript-eslint/unified-signatures
launchDialogService: LaunchDialogService,
featureModules: FeatureModulesService
);
/**
* @deprecated since 7.0
*/
constructor(
asmComponentService: AsmComponentService,
userAccountFacade: UserAccountFacade
);
constructor(
protected asmComponentService: AsmComponentService,
protected userAccountFacade: UserAccountFacade
protected userAccountFacade: UserAccountFacade,
// TODO(CXSPA-3090): Remove optional flag in 7.0
@Optional() protected launchDialogService?: LaunchDialogService,
@Optional() protected featureModules?: FeatureModulesService
) {}

ngOnInit() {
this.isAsmCustomer360Configured =
this.featureModules?.isConfigured('asmCustomer360');
if (this.isAsmCustomer360Configured) {
// trigger lazy loading of the Customer 360 feature:
this.featureModules?.resolveFeature('asmCustomer360').subscribe(() => {
this.isAsmCustomer360Loaded$.next(true);
});
}

this.subscription.add(
this.userAccountFacade.get().subscribe((user) => {
if (user) {
Expand All @@ -40,6 +83,29 @@ export class CustomerEmulationComponent implements OnInit, OnDestroy {
this.asmComponentService.logoutCustomer();
}

openAsmCustomer360() {
this.subscription.add(
this.isAsmCustomer360Loaded$
.pipe(filter((isReady) => Boolean(isReady)))
.subscribe(() => {
const data = { customer: this.customer };
this.launchDialogService?.openDialogAndSubscribe(
LAUNCH_CALLER.ASM_CUSTOMER_360,
this.asmCustomer360LauncherElement,
data
);

this.subscription.add(
this.launchDialogService?.dialogClose
.pipe(filter((result) => Boolean(result)))
.subscribe((event: AsmDialogActionEvent) => {
this.asmComponentService.handleAsmDialogAction(event);
})
);
})
);
}

ngOnDestroy(): void {
this.subscription.unsubscribe();
}
Expand Down
Loading

0 comments on commit 8331f9f

Please sign in to comment.