Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(snack-bar): complete onAction observable on close #8183

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/lib/snack-bar/snack-bar-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export class MatSnackBarRef<T> {
/** Cleans up the DOM after closing. */
private _finishDismiss(): void {
this._overlayRef.dispose();

if (!this._onAction.closed) {
this._onAction.complete();
}

this._afterClosed.next();
this._afterClosed.complete();
}
Expand Down
99 changes: 48 additions & 51 deletions src/lib/snack-bar/snack-bar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,20 @@ describe('MatSnackBar', () => {

it('should dismiss the snack bar and remove itself from the view', async(() => {
let config: MatSnackBarConfig = {viewContainerRef: testViewContainerRef};
let dismissObservableCompleted = false;
let dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');

let snackBarRef = snackBar.open(simpleMessage, undefined, config);
viewContainerFixture.detectChanges();
expect(overlayContainerElement.childElementCount)
.toBeGreaterThan(0, 'Expected overlay container element to have at least one child');

snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
dismissObservableCompleted = true;
});
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);

snackBarRef.dismiss();
viewContainerFixture.detectChanges(); // Run through animations for dismissal

viewContainerFixture.whenStable().then(() => {
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
expect(dismissCompleteSpy).toHaveBeenCalled();
expect(overlayContainerElement.childElementCount)
.toBe(0, 'Expected the overlay container element to have no child elements');
});
Expand Down Expand Up @@ -204,7 +202,7 @@ describe('MatSnackBar', () => {
state to visible on entry of new snack bar`, async(() => {
let config: MatSnackBarConfig = {viewContainerRef: testViewContainerRef};
let snackBarRef = snackBar.open(simpleMessage, undefined, config);
let dismissObservableCompleted = false;
let dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');

viewContainerFixture.detectChanges();
expect(snackBarRef.containerInstance._animationState)
Expand All @@ -214,12 +212,10 @@ describe('MatSnackBar', () => {
let snackBarRef2 = snackBar.open(simpleMessage, undefined, config2);

viewContainerFixture.detectChanges();
snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
dismissObservableCompleted = true;
});
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);

viewContainerFixture.whenStable().then(() => {
expect(dismissObservableCompleted).toBe(true);
expect(dismissCompleteSpy).toHaveBeenCalled();
expect(snackBarRef.containerInstance._animationState)
.toBe('hidden-bottom', `Expected the animation state would be 'hidden-bottom'.`);
expect(snackBarRef2.containerInstance._animationState)
Expand Down Expand Up @@ -282,70 +278,75 @@ describe('MatSnackBar', () => {

it('should dismiss the snackbar when the action is called, notifying of both action and dismiss',
fakeAsync(() => {
let dismissObservableCompleted = false;
let actionObservableCompleted = false;
let snackBarRef = snackBar.open('Some content', 'Dismiss');
viewContainerFixture.detectChanges();

snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
dismissObservableCompleted = true;
});
snackBarRef.onAction().subscribe(undefined, undefined, () => {
actionObservableCompleted = true;
});
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
const actionCompleteSpy = jasmine.createSpy('action complete spy');
const snackBarRef = snackBar.open('Some content', 'Dismiss');
viewContainerFixture.detectChanges();

snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);

let actionButton =
const actionButton =
overlayContainerElement.querySelector('.mat-simple-snackbar-action') as HTMLButtonElement;
actionButton.click();
viewContainerFixture.detectChanges();
tick();

expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
expect(actionObservableCompleted).toBeTruthy('Expected the snack bar to notify of action');
expect(dismissCompleteSpy).toHaveBeenCalled();
expect(actionCompleteSpy).toHaveBeenCalled();

tick(500);
}));

it('should allow manually closing with an action', fakeAsync(() => {
let dismissObservableCompleted = false;
let actionObservableCompleted = false;
let snackBarRef = snackBar.open('Some content');
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
const actionCompleteSpy = jasmine.createSpy('action complete spy');
const snackBarRef = snackBar.open('Some content');
viewContainerFixture.detectChanges();

snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
dismissObservableCompleted = true;
});
snackBarRef.onAction().subscribe(undefined, undefined, () => {
actionObservableCompleted = true;
});
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);

snackBarRef.closeWithAction();
viewContainerFixture.detectChanges();
tick();

expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
expect(actionObservableCompleted).toBeTruthy('Expected the snack bar to notify of action');
expect(dismissCompleteSpy).toHaveBeenCalled();
expect(actionCompleteSpy).toHaveBeenCalled();

tick(500);
}));

it('should complete the onAction stream when not closing via an action', fakeAsync(() => {
const actionCompleteSpy = jasmine.createSpy('action complete spy');
const snackBarRef = snackBar.open('Some content');
viewContainerFixture.detectChanges();

snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);
snackBarRef.dismiss();
viewContainerFixture.detectChanges();
tick();

expect(actionCompleteSpy).toHaveBeenCalled();

tick(500);
}));

it('should dismiss automatically after a specified timeout', fakeAsync(() => {
let dismissObservableCompleted = false;
let config = new MatSnackBarConfig();
config.duration = 250;
let snackBarRef = snackBar.open('content', 'test', config);
snackBarRef.afterDismissed().subscribe(() => {
dismissObservableCompleted = true;
});
let afterDismissSpy = jasmine.createSpy('after dismiss spy');
snackBarRef.afterDismissed().subscribe(afterDismissSpy);

viewContainerFixture.detectChanges();
tick();
expect(dismissObservableCompleted).toBeFalsy('Expected the snack bar not to be dismissed');
expect(afterDismissSpy).not.toHaveBeenCalled();

tick(1000);
viewContainerFixture.detectChanges();
tick();
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
expect(afterDismissSpy).toHaveBeenCalled();
}));

it('should clear the dismiss timeout when dismissed before timeout expiration', fakeAsync(() => {
Expand Down Expand Up @@ -411,24 +412,20 @@ describe('MatSnackBar', () => {
});

it('should allow manually closing with an action', fakeAsync(() => {
let dismissObservableCompleted = false;
let actionObservableCompleted = false;
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
const actionCompleteSpy = jasmine.createSpy('action complete spy');
const snackBarRef = snackBar.openFromComponent(BurritosNotification);
viewContainerFixture.detectChanges();

snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
dismissObservableCompleted = true;
});
snackBarRef.onAction().subscribe(undefined, undefined, () => {
actionObservableCompleted = true;
});
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);

snackBarRef.closeWithAction();
viewContainerFixture.detectChanges();
tick();

expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
expect(actionObservableCompleted).toBeTruthy('Expected the snack bar to notify of action');
expect(dismissCompleteSpy).toHaveBeenCalled();
expect(actionCompleteSpy).toHaveBeenCalled();

tick(500);
}));
Expand Down