Skip to content

Commit

Permalink
feat(components/toast): add toast and toaster harness (#3141) (#3147)
Browse files Browse the repository at this point in the history
  • Loading branch information
Blackbaud-SandhyaRajasabeson and Sandhya Adhirvuh authored Feb 12, 2025
1 parent fb9557f commit 02caf83
Show file tree
Hide file tree
Showing 19 changed files with 524 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { SkyToastType } from '@skyux/toast';
import { SkyToasterHarness } from '@skyux/toast/testing';

import { DemoComponent } from './demo.component';

describe('Basic toast demo', () => {
let fixture: ComponentFixture<DemoComponent>;
let loader: HarnessLoader;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [DemoComponent, NoopAnimationsModule],
});

fixture = TestBed.createComponent(DemoComponent);
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
});

async function setupTest(): Promise<{
toasterHarness: SkyToasterHarness;
}> {
fixture.componentInstance.openToast();
fixture.detectChanges();

const toasterHarness: SkyToasterHarness =
await loader.getHarness(SkyToasterHarness);

return { toasterHarness };
}

it('should open success toasts', async () => {
const { toasterHarness } = await setupTest();

fixture.componentInstance.openToast();
fixture.detectChanges();

await expectAsync(toasterHarness.getNumberOfToasts()).toBeResolvedTo(2);

const toast = await toasterHarness.getToastByMessage(
'This is a sample toast message.',
);

await expectAsync(toast.getType()).toBeResolvedTo(SkyToastType.Success);
});

it('should close all toasts', async () => {
fixture.componentInstance.openToast();
fixture.detectChanges();
fixture.componentInstance.closeAll();
fixture.detectChanges();

await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { SkyToastService, SkyToastType } from '@skyux/toast';
export class DemoComponent {
readonly #toastSvc = inject(SkyToastService);

protected openToast(): void {
public openToast(): void {
this.#toastSvc.openMessage('This is a sample toast message.', {
type: SkyToastType.Success,
});
}

protected closeAll(): void {
public closeAll(): void {
this.#toastSvc.closeAll();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ComponentHarness } from '@angular/cdk/testing';

export class CustomToastHarness extends ComponentHarness {
public static hostSelector = 'app-toast-content-demo';

public async getText(): Promise<string> {
return await (await this.host()).text();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { SkyToastType } from '@skyux/toast';
import { SkyToasterHarness } from '@skyux/toast/testing';

import { CustomToastHarness } from './custom-toast-harness';
import { DemoComponent } from './demo.component';

describe('Custom component toast demo', () => {
let fixture: ComponentFixture<DemoComponent>;
let loader: HarnessLoader;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [DemoComponent, NoopAnimationsModule],
});

fixture = TestBed.createComponent(DemoComponent);
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
});

async function setupTest(): Promise<{
toasterHarness: SkyToasterHarness;
}> {
fixture.componentInstance.openToast();
fixture.detectChanges();

const toasterHarness: SkyToasterHarness =
await loader.getHarness(SkyToasterHarness);

return { toasterHarness };
}

it('should open custom component in toast', async () => {
const { toasterHarness } = await setupTest();

const toasts = await toasterHarness.getToasts();
const customHarness = await toasts[0].queryHarness(CustomToastHarness);

await expectAsync(toasts[0].getType()).toBeResolvedTo(SkyToastType.Success);
await expectAsync(customHarness.getText()).toBeResolvedTo(
'Custom message: This toast has embedded a custom component for its content.',
);
});

it('should close all toasts', async () => {
fixture.componentInstance.openToast();
fixture.detectChanges();
fixture.componentInstance.closeAll();
fixture.detectChanges();

await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CustomToastComponent } from './custom-toast.component';
export class DemoComponent {
readonly #toastSvc = inject(SkyToastService);

protected openToast(): void {
public openToast(): void {
const context = new CustomToastContext(
'This toast has embedded a custom component for its content.',
);
Expand All @@ -31,7 +31,7 @@ export class DemoComponent {
);
}

protected closeAll(): void {
public closeAll(): void {
this.#toastSvc.closeAll();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { SkyToastType } from '@skyux/toast';
import { SkyToasterHarness } from '@skyux/toast/testing';

import { ToastBasicExampleComponent } from './example.component';

describe('Basic toast example', () => {
let fixture: ComponentFixture<ToastBasicExampleComponent>;
let loader: HarnessLoader;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [ToastBasicExampleComponent, NoopAnimationsModule],
});

fixture = TestBed.createComponent(ToastBasicExampleComponent);
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
});

async function setupTest(): Promise<{
toasterHarness: SkyToasterHarness;
}> {
fixture.componentInstance.openToast();
fixture.detectChanges();

const toasterHarness: SkyToasterHarness =
await loader.getHarness(SkyToasterHarness);

return { toasterHarness };
}

it('should open success toasts', async () => {
const { toasterHarness } = await setupTest();

fixture.componentInstance.openToast();
fixture.detectChanges();

await expectAsync(toasterHarness.getNumberOfToasts()).toBeResolvedTo(2);

const toast = await toasterHarness.getToastByMessage(
'This is a sample toast message.',
);

await expectAsync(toast.getType()).toBeResolvedTo(SkyToastType.Success);
});

it('should close all toasts', async () => {
fixture.componentInstance.openToast();
fixture.detectChanges();
fixture.componentInstance.closeAll();
fixture.detectChanges();

await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { SkyToastService, SkyToastType } from '@skyux/toast';
export class ToastBasicExampleComponent {
readonly #toastSvc = inject(SkyToastService);

protected openToast(): void {
public openToast(): void {
this.#toastSvc.openMessage('This is a sample toast message.', {
type: SkyToastType.Success,
});
}

protected closeAll(): void {
public closeAll(): void {
this.#toastSvc.closeAll();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ComponentHarness } from '@angular/cdk/testing';

export class CustomToastHarness extends ComponentHarness {
public static hostSelector = 'app-toast-content-example';

public async getText(): Promise<string> {
return await (await this.host()).text();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { SkyToastType } from '@skyux/toast';
import { SkyToasterHarness } from '@skyux/toast/testing';

import { CustomToastHarness } from './custom-toast-harness';
import { ToastCustomComponentExampleComponent } from './example.component';

describe('Custom component toast demo', () => {
let fixture: ComponentFixture<ToastCustomComponentExampleComponent>;
let loader: HarnessLoader;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [ToastCustomComponentExampleComponent, NoopAnimationsModule],
});

fixture = TestBed.createComponent(ToastCustomComponentExampleComponent);
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
});

async function setupTest(): Promise<{
toasterHarness: SkyToasterHarness;
}> {
fixture.componentInstance.openToast();
fixture.detectChanges();

const toasterHarness: SkyToasterHarness =
await loader.getHarness(SkyToasterHarness);

return { toasterHarness };
}

it('should open custom component in toast', async () => {
const { toasterHarness } = await setupTest();

const toasts = await toasterHarness.getToasts();
const customHarness = await toasts[0].queryHarness(CustomToastHarness);

await expectAsync(toasts[0].getType()).toBeResolvedTo(SkyToastType.Success);
await expectAsync(customHarness.getText()).toBeResolvedTo(
'Custom message: This toast has embedded a custom component for its content.',
);
});

it('should close all toasts', async () => {
fixture.componentInstance.openToast();
fixture.detectChanges();
fixture.componentInstance.closeAll();
fixture.detectChanges();

await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CustomToastComponent } from './custom-toast.component';
export class ToastCustomComponentExampleComponent {
readonly #toastSvc = inject(SkyToastService);

protected openToast(): void {
public openToast(): void {
const context = new CustomToastContext(
'This toast has embedded a custom component for its content.',
);
Expand All @@ -31,7 +31,7 @@ export class ToastCustomComponentExampleComponent {
);
}

protected closeAll(): void {
public closeAll(): void {
this.#toastSvc.closeAll();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { SkyHarnessFilters } from '../../shared/harness-filters';
import { BaseHarnessFilters } from '@angular/cdk/testing';

/**
* A set of criteria that can be used to filter a list of SkyOverlayHarness instances.
* @internal
*/
// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type
export interface SkyOverlayHarnessFilters extends SkyHarnessFilters {}
export interface SkyOverlayHarnessFilters extends BaseHarnessFilters {}
1 change: 1 addition & 0 deletions libs/components/toast/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"homepage": "https://github.com/blackbaud/skyux#readme",
"peerDependencies": {
"@angular/animations": "^19.0.5",
"@angular/cdk": "^19.0.4",
"@angular/common": "^19.0.5",
"@angular/core": "^19.0.5",
"@angular/platform-browser": "^19.0.5",
Expand Down
2 changes: 1 addition & 1 deletion libs/components/toast/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"dependsOn": [
"^build",
{
"projects": ["testing"],
"projects": ["core", "testing"],
"target": "build"
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SkyToastType } from './toast-type';
*/
export interface SkyToastConfig {
/**
* The `SkyToastType` type that determines the color and icon for the toast. This property defaults to `SkyToastType.Info`.
* The `SkyToastType` type that determines the color and icon for the toast. This property defaults to `Info`.
*/
type?: SkyToastType;

Expand Down
12 changes: 12 additions & 0 deletions libs/components/toast/testing/src/modules/toast-harness-filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { BaseHarnessFilters } from '@angular/cdk/testing';

/**
* A set of criteria that can be used to filter a list of `SkyToastHarness` instances.
*/
// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type
export interface SkyToastHarnessFilters extends BaseHarnessFilters {
/**
* Finds toasts with the matching text.
*/
message?: string;
}
Loading

0 comments on commit 02caf83

Please sign in to comment.