-
Notifications
You must be signed in to change notification settings - Fork 384
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: As an assisted service agent, I want to view list of coupons pa…
…rticularly for customer support (#17703) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
- Loading branch information
1 parent
ef8200e
commit 4370f73
Showing
24 changed files
with
1,040 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
...0/components/asm-customer-promotion-listing/asm-customer-promotion-listing.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<div class="cx-asm-customer-promotion-listing-heading" *ngIf="headerText"> | ||
<h4 class="cx-asm-customer-promotion-listing-heading-text"> | ||
{{ headerText }} | ||
</h4> | ||
</div> | ||
<div class="message-container"> | ||
<cx-message | ||
*ngIf="showAlert" | ||
[text]="'customer360.alertErrorMessage' | cxTranslate" | ||
[type]="globalMessageType.MSG_TYPE_ERROR" | ||
(closeMessage)="removeAlert.emit()" | ||
></cx-message> | ||
<cx-message | ||
*ngIf="showAlertForApplyAction" | ||
[text]="'customer360.applyActionAlter' | cxTranslate" | ||
[type]="globalMessageType.MSG_TYPE_ERROR" | ||
(closeMessage)="removeAlertForApplyAction.emit()" | ||
></cx-message> | ||
</div> | ||
<table class="cx-asm-customer-promotion-listing"> | ||
<ng-container *ngFor="let entry of entries"> | ||
<tr class="cx-asm-customer-promotion-listing-row"> | ||
<td> | ||
<tr class="cx-asm-customer-promotion-listing-subheader" tabindex="-1"> | ||
{{ | ||
entry.code | ||
}} | ||
</tr> | ||
<tr class="cx-asm-customer-promotion-listing-description"> | ||
{{ | ||
entry.name | ||
}} | ||
</tr> | ||
</td> | ||
<td> | ||
<ng-container *ngIf="!entry.applied"> | ||
<button | ||
*ngIf="showApplyButton" | ||
class="cx-asm-customer-promotion-listing-apply-button" | ||
(click)="apply.emit(entry)" | ||
> | ||
{{ applyButtonText }} | ||
</button> | ||
</ng-container> | ||
<ng-container *ngIf="entry.applied"> | ||
<tr class="cx-asm-customer-promotion-listing-action"> | ||
<td> | ||
<cx-icon class="success" type="SUCCESS"></cx-icon> | ||
</td> | ||
<td class="cx-asm-customer-promotion-listing-applied"> | ||
{{ applied }} | ||
</td> | ||
<td | ||
*ngIf="showRemoveButton" | ||
class="cx-asm-customer-promotion-listing-action-separator" | ||
> | ||
| | ||
</td> | ||
<td *ngIf="showRemoveButton"> | ||
<button | ||
class="cx-asm-customer-promotion-listing-remove-button" | ||
(click)="remove.emit(entry)" | ||
> | ||
{{ removeButtonText }} | ||
</button> | ||
</td> | ||
</tr> | ||
</ng-container> | ||
</td> | ||
</tr> | ||
</ng-container> | ||
</table> | ||
<hr | ||
class="cx-asm-customer-promotion-listing-separator" | ||
aria-hidden="true" | ||
*ngIf="!showAlert" | ||
/> | ||
<div | ||
class="cx-asm-customer-promotion-listing-empty" | ||
*ngIf="entries?.length === 0 && !showAlert" | ||
> | ||
{{ emptyStateText }} | ||
</div> |
143 changes: 143 additions & 0 deletions
143
...omponents/asm-customer-promotion-listing/asm-customer-promotion-listing.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import { Component, DebugElement, Input } from '@angular/core'; | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { AsmCustomerPromotionListingComponent } from './asm-customer-promotion-listing.component'; | ||
import { I18nTestingModule } from '@spartacus/core'; | ||
import { By } from '@angular/platform-browser'; | ||
import { PromotionListEntry } from './asm-customer-promotion-listing.model'; | ||
|
||
describe('AsmCustomerPromotionListingComponent', () => { | ||
const mockEntries: Array<PromotionListEntry> = [ | ||
{ | ||
code: 'COUPON_1', | ||
name: 'NAME OF COUPON_1', | ||
applied: true, | ||
}, | ||
{ | ||
code: 'COUPON_2', | ||
name: 'NAME OF COUPON_2', | ||
applied: false, | ||
}, | ||
{ | ||
code: 'COUPON_3', | ||
name: 'NAME OF COUPON_3', | ||
applied: false, | ||
}, | ||
]; | ||
|
||
const mockEmptyText = 'empty list'; | ||
const mockHeaderText = 'Header Text'; | ||
|
||
@Component({ | ||
selector: 'cx-test-host', | ||
template: ` | ||
<cx-asm-customer-promotion-listing | ||
[emptyStateText]="emptyStateText" | ||
[headerText]="headerText" | ||
[entries]="entries" | ||
[showAlert]="showAlert" | ||
[showAlertForApplyAction]="showAlertForApplyAction" | ||
(apply)="applyCouponToCustomer($event)" | ||
(remove)="removeCouponToCustomer($event)" | ||
(removeAlert)="closeErrorAlert()" | ||
(removeAlertForApplyAction)="closeErrorAlertForApplyAction()" | ||
[applyButtonText]="applyButtonText" | ||
[applied]="applied" | ||
[removeButtonText]="removeButtonText" | ||
[showRemoveButton]="true" | ||
[showApplyButton]="true" | ||
> | ||
</cx-asm-customer-promotion-listing> | ||
`, | ||
}) | ||
class TestHostComponent { | ||
@Input() headerText: string; | ||
@Input() emptyStateText: string; | ||
@Input() applyButtonText: string; | ||
@Input() applied: string; | ||
@Input() removeButtonText: string; | ||
@Input() entries: Array<PromotionListEntry> | null; | ||
@Input() showAlert: boolean | null; | ||
@Input() showAlertForApplyAction: boolean | null; | ||
@Input() showRemoveButton: boolean; | ||
@Input() showApplyButton: boolean; | ||
apply = void {}; | ||
remove = void {}; | ||
removeAlert = void {}; | ||
removeAlertForApplyAction = void {}; | ||
} | ||
|
||
let component: AsmCustomerPromotionListingComponent; | ||
let fixture: ComponentFixture<TestHostComponent>; | ||
let testHost: TestHostComponent; | ||
let el: DebugElement; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [I18nTestingModule], | ||
declarations: [TestHostComponent, AsmCustomerPromotionListingComponent], | ||
}).compileComponents(); | ||
}); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(TestHostComponent); | ||
testHost = fixture.componentInstance; | ||
component = fixture.debugElement.query( | ||
By.directive(AsmCustomerPromotionListingComponent) | ||
).componentInstance; | ||
el = fixture.debugElement; | ||
}); | ||
|
||
it('should create', () => { | ||
fixture.detectChanges(); | ||
expect(component).toBeTruthy(); | ||
}); | ||
|
||
it('should display header text', () => { | ||
testHost.headerText = mockHeaderText; | ||
fixture.detectChanges(); | ||
|
||
const header = el.query( | ||
By.css('.cx-asm-customer-promotion-listing-heading-text') | ||
); | ||
expect(header.nativeElement.innerText).toBe(mockHeaderText); | ||
}); | ||
|
||
it('should display entries list', () => { | ||
testHost.entries = mockEntries; | ||
fixture.detectChanges(); | ||
|
||
const entriesList = el.query(By.css('.cx-asm-customer-promotion-listing')); | ||
expect(entriesList).toBeTruthy(); | ||
|
||
const listTableBody = el.query(By.css('table')); | ||
|
||
const rows = listTableBody.queryAll( | ||
By.css('.cx-asm-customer-promotion-listing-row') | ||
); | ||
expect(rows.length).toBe(mockEntries.length); | ||
}); | ||
|
||
it('should display empty message when entries is empty', () => { | ||
testHost.emptyStateText = mockEmptyText; | ||
testHost.entries = []; | ||
fixture.detectChanges(); | ||
|
||
const emptyMessage = el.query( | ||
By.css('.cx-asm-customer-promotion-listing-empty') | ||
); | ||
|
||
expect(emptyMessage).toBeTruthy(); | ||
}); | ||
|
||
it('should show meaasge when entries loaded failed', () => { | ||
testHost.showAlert = true; | ||
fixture.detectChanges(); | ||
expect(el.query(By.css('cx-message'))).not.toBeNull(); | ||
}); | ||
|
||
it('should show meaasge when action perform failed', () => { | ||
testHost.showAlertForApplyAction = true; | ||
fixture.detectChanges(); | ||
expect(el.query(By.css('cx-message'))).not.toBeNull(); | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
...360/components/asm-customer-promotion-listing/asm-customer-promotion-listing.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <[email protected]> | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { | ||
ChangeDetectionStrategy, | ||
Component, | ||
EventEmitter, | ||
Input, | ||
Output, | ||
} from '@angular/core'; | ||
import { GlobalMessageType } from '@spartacus/core'; | ||
import { PromotionListEntry } from './asm-customer-promotion-listing.model'; | ||
@Component({ | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
selector: 'cx-asm-customer-promotion-listing', | ||
templateUrl: './asm-customer-promotion-listing.component.html', | ||
}) | ||
export class AsmCustomerPromotionListingComponent { | ||
@Input() headerText: string; | ||
@Input() emptyStateText: string; | ||
@Input() applyButtonText: string; | ||
@Input() applied: string; | ||
@Input() removeButtonText: string; | ||
@Input() entries: Array<PromotionListEntry> | null; | ||
@Input() showAlert: boolean | null; | ||
@Input() showAlertForApplyAction: boolean | null; | ||
@Input() showRemoveButton: boolean; | ||
@Input() showApplyButton: boolean; | ||
@Output() apply = new EventEmitter<PromotionListEntry>(); | ||
@Output() remove = new EventEmitter<PromotionListEntry>(); | ||
@Output() removeAlert = new EventEmitter(); | ||
@Output() removeAlertForApplyAction = new EventEmitter(); | ||
globalMessageType = GlobalMessageType; | ||
} |
15 changes: 15 additions & 0 deletions
15
...mer-360/components/asm-customer-promotion-listing/asm-customer-promotion-listing.model.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <[email protected]> | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
export interface PromotionListEntry { | ||
[key: string]: string | boolean | undefined; | ||
} | ||
|
||
export interface GeneralEntry extends PromotionListEntry { | ||
applied: boolean; | ||
code: string; | ||
name?: string; | ||
} |
30 changes: 30 additions & 0 deletions
30
...er-360/components/asm-customer-promotion-listing/asm-customer-promotion-listing.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <[email protected]> | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { CommonModule } from '@angular/common'; | ||
import { NgModule } from '@angular/core'; | ||
import { ArgsModule } from '@spartacus/asm/core'; | ||
import { I18nModule } from '@spartacus/core'; | ||
import { | ||
StarRatingModule, | ||
IconModule, | ||
MessageComponentModule, | ||
} from '@spartacus/storefront'; | ||
import { AsmCustomerPromotionListingComponent } from './asm-customer-promotion-listing.component'; | ||
|
||
@NgModule({ | ||
declarations: [AsmCustomerPromotionListingComponent], | ||
exports: [AsmCustomerPromotionListingComponent], | ||
imports: [ | ||
CommonModule, | ||
I18nModule, | ||
ArgsModule, | ||
StarRatingModule, | ||
MessageComponentModule, | ||
IconModule, | ||
], | ||
}) | ||
export class AsmCustomerPromotionListingModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.