Skip to content

Commit

Permalink
fix: consolidate the display of promotion messages (#448)
Browse files Browse the repository at this point in the history
  • Loading branch information
SGrueber authored Nov 4, 2020
1 parent dc3a206 commit ce3cfb7
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 10 deletions.
25 changes: 24 additions & 1 deletion e2e/cypress/integration/pages/checkout/cart.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ export class CartPage {
this.addBasketToOrderTemplateButton().click();
}

collapsePromotionForm() {
return cy.get('[data-testing-id="promo-collapse-link"]').click();
}

submitPromotionCode(code: string) {
cy.get('[data-testing-id="promo-code-form"] input').clear().type(code);
return cy.get('[data-testing-id="promo-code-form"] button').click();
}

removePromotionCode() {
return cy.get('[data-testing-id="promo-remove-link"]').click();
}

lineItem(idx: number) {
return {
quantity: {
Expand All @@ -70,6 +83,10 @@ export class CartPage {
return cy.get('[data-testing-id="basket-tax"]');
}

get promotion() {
return cy.get('.cost-summary ish-basket-promotion');
}

get lineItemInfoMessage() {
return {
message: cy.get('ish-line-item-list').find('.alert-info'),
Expand All @@ -78,7 +95,13 @@ export class CartPage {

get errorMessage() {
return {
message: cy.get('ish-error-message').find('.alert-error'),
message: cy.get('#toast-container').find('.toast-error'),
};
}

get successMessage() {
return {
message: cy.get('#toast-container').find('.toast-message'),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { at } from '../../framework';
import { CartPage } from '../../pages/checkout/cart.page';
import { ProductDetailPage } from '../../pages/shopping/product-detail.page';

const _ = {
productSku: '201807171',
};

describe('Promotion Handling in Cart', () => {
before(() => {
ProductDetailPage.navigateTo(_.productSku);
});

it('user adds a promotion code that cannot applied yet', () => {
at(ProductDetailPage, page => {
page.addProductToCart().its('status').should('equal', 201);
page.header.miniCart.goToCart();
});
at(CartPage, page => {
page.lineItems.should('have.length', 1);
page.collapsePromotionForm();
page.submitPromotionCode('INTERSHOP');
page.errorMessage.message.should('contain', 'promotion code');
page.promotion.should('not.exist');
});
});

it('user adds a promotion code that can be applied yet', () => {
at(CartPage, page => {
page.lineItem(0).quantity.set(2);
cy.wait(1000);
page.submitPromotionCode('INTERSHOP');
page.successMessage.message.should('contain', 'applied');
page.promotion.should('exist');
});
});

it('user removes a promotion code', () => {
at(CartPage, page => {
page.removePromotionCode();
page.promotion.should('not.exist');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ <h3>{{ 'checkout.payment.method.select.heading' | translate }}</h3>
<div class="col-md-12 col-lg-4 order-summary">
<h2>{{ 'checkout.order_details.heading' | translate }}</h2>

<ish-basket-promotion-code></ish-basket-promotion-code>
<ish-basket-promotion-code [toast]="false"></ish-basket-promotion-code>

<ish-basket-address-summary [basket]="basket"></ish-basket-address-summary>
<ish-basket-items-summary [basket]="basket"></ish-basket-items-summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
'shopping_cart.promotional_code.heading' | translate
}}</a>

<ish-error-message [error]="promotionError$ | async"></ish-error-message>
<ish-error-message [error]="promotionError$ | async" [toast]="toast"></ish-error-message>

<div *ngIf="displaySuccessMessage" class="alert alert-success" role="alert">
{{ 'shopping_cart.promotion.qualified_promo.text' | translate }}
</div>
<ish-success-message
*ngIf="displaySuccessMessage"
message="shopping_cart.promotion.qualified_promo.text"
[toast]="toast"
></ish-success-message>

<div class="form-inline" [ngbCollapse]="isCollapsed">
<div class="form-inline" [ngbCollapse]="isCollapsed" data-testing-id="promo-code-form">
<input
[formControl]="codeInput"
(keydown.enter)="submitPromotionCode()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { instance, mock, when } from 'ts-mockito';

import { CheckoutFacade } from 'ish-core/facades/checkout.facade';
import { ErrorMessageComponent } from 'ish-shared/components/common/error-message/error-message.component';
import { SuccessMessageComponent } from 'ish-shared/components/common/success-message/success-message.component';

import { BasketPromotionCodeComponent } from './basket-promotion-code.component';

Expand All @@ -22,7 +23,12 @@ describe('Basket Promotion Code Component', () => {

await TestBed.configureTestingModule({
imports: [ReactiveFormsModule, TranslateModule.forRoot()],
declarations: [BasketPromotionCodeComponent, MockComponent(ErrorMessageComponent), MockComponent(NgbCollapse)],
declarations: [
BasketPromotionCodeComponent,
MockComponent(ErrorMessageComponent),
MockComponent(NgbCollapse),
MockComponent(SuccessMessageComponent),
],
providers: [{ provide: CheckoutFacade, useFactory: () => instance(checkoutFacade) }],
}).compileComponents();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
Expand All @@ -21,9 +21,10 @@ import { whenTruthy } from 'ish-core/utils/operators';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BasketPromotionCodeComponent implements OnInit, OnDestroy {
@Input() toast = true;

basket$: Observable<BasketView>;
promotionError$: Observable<HttpError>;

codeInput: FormControl;
isCollapsed = true;
codeMaxLength = 128;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div *ngIf="message && !toast" class="alert alert-success" role="alert">
{{ message | translate }}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { anything, instance, mock, verify } from 'ts-mockito';

import { MessageFacade } from 'ish-core/facades/message.facade';

import { SuccessMessageComponent } from './success-message.component';

describe('Success Message Component', () => {
let component: SuccessMessageComponent;
let fixture: ComponentFixture<SuccessMessageComponent>;
let element: HTMLElement;
let messageFacade: MessageFacade;

beforeEach(async () => {
messageFacade = mock(MessageFacade);
await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
declarations: [SuccessMessageComponent],
providers: [{ provide: MessageFacade, useFactory: () => instance(messageFacade) }],
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(SuccessMessageComponent);
component = fixture.componentInstance;
element = fixture.nativeElement;
});

it('should be created', () => {
expect(component).toBeTruthy();
expect(element).toBeTruthy();
expect(() => fixture.detectChanges()).not.toThrow();
});

it('should not render a message if no message occurs', () => {
fixture.detectChanges();
expect(element.querySelector('[role="alert"]')).toBeFalsy();
});

it('should render a message if a message occurs and toast is false', () => {
component.message = 'Test Message';
component.toast = false;

component.ngOnChanges();
fixture.detectChanges();
expect(element.querySelector('[role="alert"]')).toBeTruthy();
});

it('should trigger success toast if a message occurs and toast is true', () => {
component.message = 'Test Message';
component.toast = true;

component.ngOnChanges();
fixture.detectChanges();
verify(messageFacade.success(anything())).once();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';

import { MessageFacade } from 'ish-core/facades/message.facade';

@Component({
selector: 'ish-success-message',
templateUrl: './success-message.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SuccessMessageComponent implements OnChanges {
/** key or message is accepted */
@Input() message: string;
@Input() toast = true;

constructor(private messagesFacade: MessageFacade) {}

ngOnChanges() {
if (this.toast) {
this.displayToast();
}
}

private displayToast() {
if (this.message) {
this.messagesFacade.success({
message: this.message,
});
}
}
}
2 changes: 2 additions & 0 deletions src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import { InplaceEditComponent } from './components/common/inplace-edit/inplace-e
import { LoadingComponent } from './components/common/loading/loading.component';
import { ModalDialogLinkComponent } from './components/common/modal-dialog-link/modal-dialog-link.component';
import { ModalDialogComponent } from './components/common/modal-dialog/modal-dialog.component';
import { SuccessMessageComponent } from './components/common/success-message/success-message.component';
import { FilterCheckboxComponent } from './components/filter/filter-checkbox/filter-checkbox.component';
import { FilterCollapsableComponent } from './components/filter/filter-collapsable/filter-collapsable.component';
import { FilterDropdownComponent } from './components/filter/filter-dropdown/filter-dropdown.component';
Expand Down Expand Up @@ -215,6 +216,7 @@ const exportedComponents = [
PromotionDetailsComponent,
PromotionRemoveComponent,
RecentlyViewedComponent,
SuccessMessageComponent,
];

@NgModule({
Expand Down

0 comments on commit ce3cfb7

Please sign in to comment.