diff --git a/CHANGELOG.md b/CHANGELOG.md index b08472c1..da50f2ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# 5.1.0 (2018-05-19) +### FEATURES +* **toaster.service:** If a toastId is provided, that toastId is used instead of auto-generating +a toastId. Thanks to @sherlock1982 for his work on +[#158](https://github.com/Stabzs/Angular2-Toaster/pull/158). + +### BUG FIXES +* **toaster-container.component:** Mouseover functionality would incorrectly remove a toast when +the toast's timeout was set to 0 and the container's configuration was set to a value other than +0. Closes [#164](https://github.com/Stabzs/Angular2-Toaster/issues/164). + + # 5.0.1 (2018-03-16) ### BUG FIXES * **toaster-container.component:** Typescript compilation was failing for implicit any conversions diff --git a/README.md b/README.md index e4d77dfa..0dd9b003 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,14 @@ **angular2-toaster** is an asynchronous, non-blocking, Ahead of Time Compilation-supported Angular Toaster Notification library largely based off of [AngularJS-Toaster](https://github.com/jirikavi/AngularJS-Toaster). -[![npm](https://img.shields.io/npm/v/angular2-toaster.svg?maxAge=3600?cache=true)](https://www.npmjs.com/package/angular2-toaster) -[![npm](https://img.shields.io/npm/dt/angular2-toaster.svg?cache=true)](https://www.npmjs.com/package/angular2-toaster) +[![npm](https://img.shields.io/npm/v/angular2-toaster.svg?maxAge=3600?cached=true)](https://www.npmjs.com/package/angular2-toaster) +[![npm](https://img.shields.io/npm/dt/angular2-toaster.svg?cached=true)](https://www.npmjs.com/package/angular2-toaster) [![Build Status](https://travis-ci.org/Stabzs/Angular2-Toaster.svg?branch=master)](https://travis-ci.org/Stabzs/Angular2-Toaster) -[![Coverage Status](https://coveralls.io/repos/github/Stabzs/Angular2-Toaster/badge.svg?branch=master&b=5.0.1)](https://coveralls.io/github/Stabzs/Angular2-Toaster?branch=master) +[![Coverage Status](https://coveralls.io/repos/github/Stabzs/Angular2-Toaster/badge.svg?branch=master&b=5.1.0)](https://coveralls.io/github/Stabzs/Angular2-Toaster?branch=master) -Version ^ 5.0.0 requires either `.forRoot()` or `.forChild()` `ToasterModule` inclusion. Please -read the 5.x.x release notes the `Getting Started` section before upgraded. +Version ^5.0.0 requires either `.forRoot()` or `.forChild()` `ToasterModule` inclusion. Please +read the 5.x.x release notes and the `Getting Started` section before upgraded. Version ^4.0.0 now supports @angular/animations, which is a breaking change. Please read both the Getting Started and Animations sections before upgrading. diff --git a/package.json b/package.json index e1c2b05d..e661151c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular2-toaster", - "version": "5.0.1", + "version": "5.1.0", "description": "An Angular Toaster Notification library based on AngularJS-Toaster", "main": "bundles/angular2-toaster.umd.js", "module": "angular2-toaster.js", diff --git a/src/toaster-container.component.spec.ts b/src/toaster-container.component.spec.ts index 30a71d0d..a6bf373e 100644 --- a/src/toaster-container.component.spec.ts +++ b/src/toaster-container.component.spec.ts @@ -1,7 +1,6 @@ import {Component, NgModule} from '@angular/core'; -import {TestBed} from '@angular/core/testing'; +import {TestBed, tick, fakeAsync} from '@angular/core/testing'; import {ComponentFixture} from '@angular/core/testing'; - import {Toast, ClickHandler} from './toast'; import {ToasterService} from './toaster.service'; import {ToasterContainerComponent} from './toaster-container.component'; @@ -303,7 +302,7 @@ describe('ToasterContainerComponent with sync ToasterService', () => { expect((map.size)).toBe(0); }); - it('restartTimer should not restart timer if mouseOverTimerStop is false', () => { + it('restartTimer should not restart timer if mouseOverTimerStop is false', fakeAsync(() => { toasterContainer.toasterconfig = new ToasterConfig({ timeout: 1 }); toasterContainer.ngOnInit(); @@ -318,10 +317,46 @@ describe('ToasterContainerComponent with sync ToasterService', () => { toasterContainer.restartTimer(toast); - setTimeout(() => { - expect((map.size)).toBe(0); - }, 2) - }); + // should not remove toast because a timeout is inherited from + // toasterconfig. + // should not restart timer because mouseOverTimerStop is set + // to false. + expect(toasterContainer.toasts.length).toBe(1); + + fixture.detectChanges(); + tick(2); + + expect((map.size)).toBe(0); + expect(toasterContainer.toasts.length).toBe(0); + })); + + it('restartTimer should not restart timer if mouseOverTimerStop is false and toast.timeout is 0', fakeAsync(() => { + toasterContainer.toasterconfig = new ToasterConfig({ timeout: 1, toastContainerId: 53 }); + toasterContainer.ngOnInit(); + + const toastToPop: Toast = { type: 'success', timeout: 0, toastContainerId: 53 }; + toasterService.pop(toastToPop); + const toast = toasterContainer.toasts[0]; + + expect(toasterContainer.toasterconfig.mouseoverTimerStop).toBe(false); + expect(toast).toBeDefined(); + expect(toast.timeout).toBe(0); + + let map = (>toasterContainer['timeoutIds']); + expect((map.size)).toBe(0); + + toasterContainer.restartTimer(toast); + + // should not remove toast because a timeout of 0 is applied directly + // to the toast instance and the toast should be fully sticky. + expect(toasterContainer.toasts.length).toBe(1); + + fixture.detectChanges(); + tick(2); + + expect((map.size)).toBe(0); + expect(toasterContainer.toasts.length).toBe(1); + })); it('restartTimer should remove toast if mouseOverTimerStop is false and timeoutId is null and timeout has value', () => { toasterContainer.toasterconfig = new ToasterConfig({ timeout: 1000 }); @@ -389,11 +424,11 @@ describe('ToasterContainerComponent with sync ToasterService', () => { }); it('addToast should not add toast if preventDuplicates and the same toastId exists', () => { - toasterContainer.toasterconfig = new ToasterConfig({ preventDuplicates: true }); + toasterContainer.toasterconfig = new ToasterConfig({ preventDuplicates: true, toastContainerId: 30 }); toasterContainer.ngOnInit(); - const toast: Toast = { type: 'info' }; + const toast: Toast = { type: 'info', toastContainerId: 30 }; toasterService.pop(toast); - + expect(toasterContainer.toasts.length).toBe(1); toasterService.pop(toast); expect(toasterContainer.toasts.length).toBe(1); @@ -541,10 +576,8 @@ describe('ToasterContainerComponent with sync ToasterService', () => { expect(toasterContainer.toasts.length).toBe(1); setTimeout(() => { - fixture.whenStable().then(() => { - expect(toasterContainer.toasts.length).toBe(0); - expect((map.size)).toBe(0); - }); + expect(toasterContainer.toasts.length).toBe(0); + expect((map.size)).toBe(0); }, 2); }); @@ -665,20 +698,6 @@ describe('ToasterContainerComponent with sync ToasterService', () => { expect(toasterContainer.toasts.length).toBe(0); }); - it('clearToasts will not clear toasts from specified container if toastContainerId does not match', () => { - toasterContainer.toasterconfig = new ToasterConfig({ toastContainerId: 1 }); - toasterContainer.ngOnInit(); - - const toast: Toast = { type: 'info', toastContainerId: 1 }; - - toasterService.pop(toast); - - expect(toasterContainer.toasts.length).toBe(1); - - toasterService.clear(null, 2); - expect(toasterContainer.toasts.length).toBe(1); - }); - it('createGuid should create unique Guids', () => { toasterContainer.toasterconfig = new ToasterConfig({ toastContainerId: 1 }); toasterContainer.ngOnInit(); @@ -728,6 +747,16 @@ describe('ToasterContainerComponent with sync ToasterService', () => { expect(toastId).toBe(''); }); + + it('should use toast.toastId parameter if passed', () => { + toasterContainer.ngOnInit(); + + let toast: Toast = { type: 'success', title: '', body: '', toastId: '12345' }; + toasterService.pop(toast); + + expect(toasterContainer.toasts.length).toBe(1); + expect(toasterContainer.toasts[0].toastId).toBe('12345'); + }); }); @@ -765,6 +794,20 @@ describe('ToasterContainerComponent with sync ToasterService', () => { toasterService.pop(toast); expect(toasterContainer.toasts[0].data).toBe(1); }); + + it('clearToasts will not clear toasts from specified container if toastContainerId does not match', () => { + toasterContainer.toasterconfig = new ToasterConfig({ toastContainerId: 1 }); + toasterContainer.ngOnInit(); + + const toast: Toast = { type: 'info', toastContainerId: 1 }; + + toasterService.pop(toast); + + expect(toasterContainer.toasts.length).toBe(1); + + toasterService.clear(null, 2); + expect(toasterContainer.toasts.length).toBe(1); + }); }); describe('ToasterContainerComponent when included as a component', () => { diff --git a/src/toaster-container.component.ts b/src/toaster-container.component.ts index e4a0b797..c6e89149 100644 --- a/src/toaster-container.component.ts +++ b/src/toaster-container.component.ts @@ -146,7 +146,7 @@ export class ToasterContainerComponent implements OnInit, OnDestroy { if (!timeoutId) { this.configureTimer(toast); } - } else if (!timeoutId && this.toasterconfig.timeout) { + } else if (toast.timeout !== 0 && !timeoutId && this.toasterconfig.timeout) { this.removeToast(toast); } }