From 1263c79095c30fbdeecb26935aded531163c1b3e Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Tue, 19 Feb 2019 21:26:07 +0000 Subject: [PATCH] Add PersistentUserCallout factory method Use factory method to DRY safe instantiation. Add tests for PersistentUserCallout. --- .../javascripts/persistent_user_callout.js | 8 ++ .../persistent_user_callout_spec.js | 88 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 spec/javascripts/persistent_user_callout_spec.js diff --git a/app/assets/javascripts/persistent_user_callout.js b/app/assets/javascripts/persistent_user_callout.js index 1e34e74a152..4a08e158f6b 100644 --- a/app/assets/javascripts/persistent_user_callout.js +++ b/app/assets/javascripts/persistent_user_callout.js @@ -31,4 +31,12 @@ export default class PersistentUserCallout { Flash(__('An error occurred while dismissing the alert. Refresh the page and try again.')); }); } + + static factory(container) { + if (!container) { + return undefined; + } + + return new PersistentUserCallout(container); + } } diff --git a/spec/javascripts/persistent_user_callout_spec.js b/spec/javascripts/persistent_user_callout_spec.js new file mode 100644 index 00000000000..2fdfff3db03 --- /dev/null +++ b/spec/javascripts/persistent_user_callout_spec.js @@ -0,0 +1,88 @@ +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import PersistentUserCallout from '~/persistent_user_callout'; +import setTimeoutPromise from 'spec/helpers/set_timeout_promise_helper'; + +describe('PersistentUserCallout', () => { + const dismissEndpoint = '/dismiss'; + const featureName = 'feature'; + + function createFixture() { + const fixture = document.createElement('div'); + fixture.innerHTML = ` +
+ +
+ `; + + return fixture; + } + + describe('dismiss', () => { + let button; + let mockAxios; + let persistentUserCallout; + + beforeEach(() => { + const fixture = createFixture(); + const container = fixture.querySelector('.container'); + button = fixture.querySelector('.js-close'); + mockAxios = new MockAdapter(axios); + persistentUserCallout = new PersistentUserCallout(container); + spyOn(persistentUserCallout.container, 'remove'); + }); + + afterEach(() => { + mockAxios.restore(); + }); + + it('POSTs endpoint and removes container when clicking close', done => { + mockAxios.onPost(dismissEndpoint).replyOnce(200); + + button.click(); + + setTimeoutPromise() + .then(() => { + expect(persistentUserCallout.container.remove).toHaveBeenCalled(); + expect(mockAxios.history.post[0].data).toBe( + JSON.stringify({ feature_name: featureName }), + ); + }) + .then(done) + .catch(done.fail); + }); + + it('invokes Flash when the dismiss request fails', done => { + const Flash = spyOnDependency(PersistentUserCallout, 'Flash'); + mockAxios.onPost(dismissEndpoint).replyOnce(500); + + button.click(); + + setTimeoutPromise() + .then(() => { + expect(persistentUserCallout.container.remove).not.toHaveBeenCalled(); + expect(Flash).toHaveBeenCalledWith( + 'An error occurred while dismissing the alert. Refresh the page and try again.', + ); + }) + .then(done) + .catch(done.fail); + }); + }); + + describe('factory', () => { + it('returns an instance of PersistentUserCallout with the provided container property', () => { + const fixture = createFixture(); + + expect(PersistentUserCallout.factory(fixture) instanceof PersistentUserCallout).toBe(true); + }); + + it('returns undefined if container is falsey', () => { + expect(PersistentUserCallout.factory()).toBe(undefined); + }); + }); +});