diff --git a/dist/angular-zendesk-widget.js b/dist/angular-zendesk-widget.js index 640c54f..70fb68b 100644 --- a/dist/angular-zendesk-widget.js +++ b/dist/angular-zendesk-widget.js @@ -1,46 +1,6 @@ (function(angular) { - angular.module('zendeskWidget', []) - .run([ - '$window', - 'zendeskWidgetSettings', - function($window, zendeskWidgetSettings) { - if (!zendeskWidgetSettings.accountUrl) { - throw new Error('Missing accountUrl. Please set in app config via ZendeskWidgetProvider'); - } - - var window = $window; - - // Following is essentially a copy paste of JS portion of the Zendesk embed code - // with our settings subbed in. For more info, see: - // https://support.zendesk.com/hc/en-us/articles/203908456-Using-Web-Widget-to-embed-customer-service-in-your-website - - /*eslint-disable */ - - window.zEmbed || function(e, t) { - var n, o, d, i, s, a = [], - r = document.createElement("iframe"); - window.zEmbed = function() { - a.push(arguments) - }, window.zE = window.zE || window.zEmbed, r.src = "javascript:false", r.title = "", r.role = "presentation", (r.frameElement || r).style.cssText = "display: none", d = document.getElementsByTagName("script"), d = d[d.length - 1], d.parentNode.insertBefore(r, d), i = r.contentWindow, s = i.document; - try { - o = s - } catch (c) { - n = document.domain, r.src = 'javascript:var d=document.open();d.domain="' + n + '";void(0);', o = s - } - o.open()._l = function() { - var o = this.createElement("script"); - n && (this.domain = n), o.id = "js-iframe-async", o.src = e, this.t = +new Date, this.zendeskHost = t, this.zEQueue = a, this.body.appendChild(o) - }, o.write(''), o.close() - }("https://assets.zendesk.com/embeddable_framework/main.js", zendeskWidgetSettings.accountUrl); - - /*eslint-enable */ - - $window.zE(function() { - zendeskWidgetSettings.beforePageLoad($window.zE); - }); - } - ]); + angular.module('zendeskWidget', []); })(angular); @@ -98,3 +58,49 @@ }]); })(angular); + +(function(angular) { + + angular.module('zendeskWidget') + .run([ + '$window', + 'zendeskWidgetSettings', + function($window, zendeskWidgetSettings) { + if (!zendeskWidgetSettings.accountUrl) { + throw new Error('Missing accountUrl. Please set in app config via ZendeskWidgetProvider'); + } + + var window = $window; + + // Following is essentially a copy paste of JS portion of the Zendesk embed code + // with our settings subbed in. For more info, see: + // https://support.zendesk.com/hc/en-us/articles/203908456-Using-Web-Widget-to-embed-customer-service-in-your-website + + /*eslint-disable */ + + window.zEmbed || function(e, t) { + var n, o, d, i, s, a = [], + r = document.createElement("iframe"); + window.zEmbed = function() { + a.push(arguments) + }, window.zE = window.zE || window.zEmbed, r.src = "javascript:false", r.title = "", r.role = "presentation", (r.frameElement || r).style.cssText = "display: none", d = document.getElementsByTagName("script"), d = d[d.length - 1], d.parentNode.insertBefore(r, d), i = r.contentWindow, s = i.document; + try { + o = s + } catch (c) { + n = document.domain, r.src = 'javascript:var d=document.open();d.domain="' + n + '";void(0);', o = s + } + o.open()._l = function() { + var o = this.createElement("script"); + n && (this.domain = n), o.id = "js-iframe-async", o.src = e, this.t = +new Date, this.zendeskHost = t, this.zEQueue = a, this.body.appendChild(o) + }, o.write(''), o.close() + }("https://assets.zendesk.com/embeddable_framework/main.js", zendeskWidgetSettings.accountUrl); + + /*eslint-enable */ + + $window.zE(function() { + zendeskWidgetSettings.beforePageLoad($window.zE); + }); + } + ]); + +})(angular); diff --git a/dist/angular-zendesk-widget.min.js b/dist/angular-zendesk-widget.min.js index 1efd06a..4cb22e5 100644 --- a/dist/angular-zendesk-widget.min.js +++ b/dist/angular-zendesk-widget.min.js @@ -1 +1 @@ -!function(e){e.module("zendeskWidget",[]).run(["$window","zendeskWidgetSettings",function(e,n){if(!n.accountUrl)throw new Error("Missing accountUrl. Please set in app config via ZendeskWidgetProvider");var t=e;t.zEmbed||function(e,n){var i,o,a,d,s,r=[],c=document.createElement("iframe");t.zEmbed=function(){r.push(arguments)},t.zE=t.zE||t.zEmbed,c.src="javascript:false",c.title="",c.role="presentation",(c.frameElement||c).style.cssText="display: none",a=document.getElementsByTagName("script"),a=a[a.length-1],a.parentNode.insertBefore(c,a),d=c.contentWindow,s=d.document;try{o=s}catch(u){i=document.domain,c.src='javascript:var d=document.open();d.domain="'+i+'";void(0);',o=s}o.open()._l=function(){var t=this.createElement("script");i&&(this.domain=i),t.id="js-iframe-async",t.src=e,this.t=+new Date,this.zendeskHost=n,this.zEQueue=r,this.body.appendChild(t)},o.write(''),o.close()}("https://assets.zendesk.com/embeddable_framework/main.js",n.accountUrl),e.zE(function(){n.beforePageLoad(e.zE)})}])}(angular),function(e){var n={accountUrl:"",beforePageLoad:e.noop},t=["setLocale","identify","hide","show","activate"];e.module("zendeskWidget").value("zendeskWidgetSettings",n).provider("ZendeskWidget",[function(){this.init=function(t){e.extend(n,t)},this.$get=["$window",function(n){function i(){}return e.forEach(t,function(e){i.prototype[e]=function(){n.zE[e].apply(n.zE,arguments)}}),new i}]}])}(angular); \ No newline at end of file +!function(e){e.module("zendeskWidget",[])}(angular),function(e){var n={accountUrl:"",beforePageLoad:e.noop},t=["setLocale","identify","hide","show","activate"];e.module("zendeskWidget").value("zendeskWidgetSettings",n).provider("ZendeskWidget",[function(){this.init=function(t){e.extend(n,t)},this.$get=["$window",function(n){function i(){}return e.forEach(t,function(e){i.prototype[e]=function(){n.zE[e].apply(n.zE,arguments)}}),new i}]}])}(angular),function(e){e.module("zendeskWidget").run(["$window","zendeskWidgetSettings",function(e,n){if(!n.accountUrl)throw new Error("Missing accountUrl. Please set in app config via ZendeskWidgetProvider");var t=e;t.zEmbed||function(e,n){var i,o,a,d,s,r=[],c=document.createElement("iframe");t.zEmbed=function(){r.push(arguments)},t.zE=t.zE||t.zEmbed,c.src="javascript:false",c.title="",c.role="presentation",(c.frameElement||c).style.cssText="display: none",a=document.getElementsByTagName("script"),a=a[a.length-1],a.parentNode.insertBefore(c,a),d=c.contentWindow,s=d.document;try{o=s}catch(u){i=document.domain,c.src='javascript:var d=document.open();d.domain="'+i+'";void(0);',o=s}o.open()._l=function(){var t=this.createElement("script");i&&(this.domain=i),t.id="js-iframe-async",t.src=e,this.t=+new Date,this.zendeskHost=n,this.zEQueue=r,this.body.appendChild(t)},o.write(''),o.close()}("https://assets.zendesk.com/embeddable_framework/main.js",n.accountUrl),e.zE(function(){n.beforePageLoad(e.zE)})}])}(angular); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 2fecf86..6e7a125 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -19,12 +19,14 @@ var rootDirectory = path.resolve('./'); var sourceDirectory = path.join(rootDirectory, './src'); var sourceFiles = [ - - // Make sure module files are handled first + // Load angular module files first path.join(sourceDirectory, '/**/*.module.js'), - // Then add all JavaScript files - path.join(sourceDirectory, '/**/*.js') + // Next, add all angular services and providers + path.join(sourceDirectory, '/**/*.service.js'), + + // Then the angular run files last + path.join(sourceDirectory, '/**/*.run.js') ]; var lintFiles = [ @@ -47,7 +49,7 @@ gulp.task('build', function() { * Process */ gulp.task('process-all', function (done) { - runSequence('lint', 'test-src', 'build', done); + runSequence('lint', 'test-src', 'build', 'test-dist-concatenated', 'test-dist-minified', done); }); /** diff --git a/karma-dist-concatenated.conf.js b/karma-dist-concatenated.conf.js index 9dbe80d..fea5522 100644 --- a/karma-dist-concatenated.conf.js +++ b/karma-dist-concatenated.conf.js @@ -24,7 +24,7 @@ module.exports = function(config) { 'bower/angular/angular.js', 'bower/angular-mocks/angular-mocks.js', 'dist/angular-zendesk-widget.js', - 'test/unit/**/*.js' + 'test/integration/**/*Spec.js' ], diff --git a/karma-dist-minified.conf.js b/karma-dist-minified.conf.js index 62981da..29212c2 100644 --- a/karma-dist-minified.conf.js +++ b/karma-dist-minified.conf.js @@ -24,7 +24,7 @@ module.exports = function(config) { 'bower/angular/angular.js', 'bower/angular-mocks/angular-mocks.js', 'dist/angular-zendesk-widget.min.js', - 'test/unit/**/*.js' + 'test/integration/**/*Spec.js' ], diff --git a/karma-src.conf.js b/karma-src.conf.js index 5ebae22..f33fb7e 100644 --- a/karma-src.conf.js +++ b/karma-src.conf.js @@ -16,7 +16,8 @@ module.exports = function(config) { 'karma-jasmine', 'karma-sinon-chai', 'karma-chrome-launcher', - 'karma-spec-reporter' + 'karma-spec-reporter', + 'karma-coverage' ], // list of files / patterns to load in the browser @@ -25,25 +26,32 @@ module.exports = function(config) { 'bower/angular-mocks/angular-mocks.js', 'src/**/*.module.js', 'src/**/*.js', - 'test/unit/**/*.js' + 'test/unit/**/*Spec.js' ], // list of files to exclude exclude: [ + 'src/**/*.run.js' ], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { + 'src/**/*.js': ['coverage'] }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress', 'spec'], + reporters: ['spec', 'coverage'], + + + coverageReporter: { + type: 'text' + }, // web server port diff --git a/package.json b/package.json index aa2153b..344d0db 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "karma-chai": "^0.1.0", "karma-chai-jquery": "^1.0.0", "karma-chrome-launcher": "^0.1.4", + "karma-coverage": "^1.0.0", "karma-jasmine": "^0.3.6", "karma-jquery": "^0.1.0", "karma-sinon-chai": "^0.2.0", diff --git a/src/angular-zendesk-widget/zendeskWidget.module.js b/src/angular-zendesk-widget/zendeskWidget.module.js index 80b5a23..fd560ff 100644 --- a/src/angular-zendesk-widget/zendeskWidget.module.js +++ b/src/angular-zendesk-widget/zendeskWidget.module.js @@ -1,45 +1,5 @@ (function(angular) { - angular.module('zendeskWidget', []) - .run([ - '$window', - 'zendeskWidgetSettings', - function($window, zendeskWidgetSettings) { - if (!zendeskWidgetSettings.accountUrl) { - throw new Error('Missing accountUrl. Please set in app config via ZendeskWidgetProvider'); - } - - var window = $window; - - // Following is essentially a copy paste of JS portion of the Zendesk embed code - // with our settings subbed in. For more info, see: - // https://support.zendesk.com/hc/en-us/articles/203908456-Using-Web-Widget-to-embed-customer-service-in-your-website - - /*eslint-disable */ - - window.zEmbed || function(e, t) { - var n, o, d, i, s, a = [], - r = document.createElement("iframe"); - window.zEmbed = function() { - a.push(arguments) - }, window.zE = window.zE || window.zEmbed, r.src = "javascript:false", r.title = "", r.role = "presentation", (r.frameElement || r).style.cssText = "display: none", d = document.getElementsByTagName("script"), d = d[d.length - 1], d.parentNode.insertBefore(r, d), i = r.contentWindow, s = i.document; - try { - o = s - } catch (c) { - n = document.domain, r.src = 'javascript:var d=document.open();d.domain="' + n + '";void(0);', o = s - } - o.open()._l = function() { - var o = this.createElement("script"); - n && (this.domain = n), o.id = "js-iframe-async", o.src = e, this.t = +new Date, this.zendeskHost = t, this.zEQueue = a, this.body.appendChild(o) - }, o.write(''), o.close() - }("https://assets.zendesk.com/embeddable_framework/main.js", zendeskWidgetSettings.accountUrl); - - /*eslint-enable */ - - $window.zE(function() { - zendeskWidgetSettings.beforePageLoad($window.zE); - }); - } - ]); + angular.module('zendeskWidget', []); })(angular); diff --git a/src/angular-zendesk-widget/zendeskWidget.run.js b/src/angular-zendesk-widget/zendeskWidget.run.js new file mode 100644 index 0000000..d5ab8bc --- /dev/null +++ b/src/angular-zendesk-widget/zendeskWidget.run.js @@ -0,0 +1,45 @@ +(function(angular) { + + angular.module('zendeskWidget') + .run([ + '$window', + 'zendeskWidgetSettings', + function($window, zendeskWidgetSettings) { + if (!zendeskWidgetSettings.accountUrl) { + throw new Error('Missing accountUrl. Please set in app config via ZendeskWidgetProvider'); + } + + var window = $window; + + // Following is essentially a copy paste of JS portion of the Zendesk embed code + // with our settings subbed in. For more info, see: + // https://support.zendesk.com/hc/en-us/articles/203908456-Using-Web-Widget-to-embed-customer-service-in-your-website + + /*eslint-disable */ + + window.zEmbed || function(e, t) { + var n, o, d, i, s, a = [], + r = document.createElement("iframe"); + window.zEmbed = function() { + a.push(arguments) + }, window.zE = window.zE || window.zEmbed, r.src = "javascript:false", r.title = "", r.role = "presentation", (r.frameElement || r).style.cssText = "display: none", d = document.getElementsByTagName("script"), d = d[d.length - 1], d.parentNode.insertBefore(r, d), i = r.contentWindow, s = i.document; + try { + o = s + } catch (c) { + n = document.domain, r.src = 'javascript:var d=document.open();d.domain="' + n + '";void(0);', o = s + } + o.open()._l = function() { + var o = this.createElement("script"); + n && (this.domain = n), o.id = "js-iframe-async", o.src = e, this.t = +new Date, this.zendeskHost = t, this.zEQueue = a, this.body.appendChild(o) + }, o.write(''), o.close() + }("https://assets.zendesk.com/embeddable_framework/main.js", zendeskWidgetSettings.accountUrl); + + /*eslint-enable */ + + $window.zE(function() { + zendeskWidgetSettings.beforePageLoad($window.zE); + }); + } + ]); + +})(angular); diff --git a/src/angular-zendesk-widget/services/zendeskWidgetProvider.js b/src/angular-zendesk-widget/zendeskWidget.service.js similarity index 100% rename from src/angular-zendesk-widget/services/zendeskWidgetProvider.js rename to src/angular-zendesk-widget/zendeskWidget.service.js diff --git a/test/integration/zendeskWidgetSpec.js b/test/integration/zendeskWidgetSpec.js new file mode 100644 index 0000000..c73095c --- /dev/null +++ b/test/integration/zendeskWidgetSpec.js @@ -0,0 +1,11 @@ +describe('zendeskWidget', function() { + 'use strict'; + + beforeEach(module('zendeskWidget')); + + it('throws an error when `accountUrl` is blank', function() { + expect(function() { inject() }).toThrowError( + 'Missing accountUrl. Please set in app config via ZendeskWidgetProvider' + ); + }); +}); diff --git a/test/unit/angular-zendesk-widget/zendeskWidgetSpec.js b/test/unit/angular-zendesk-widget/zendeskWidgetSpec.js deleted file mode 100644 index 2cedd2c..0000000 --- a/test/unit/angular-zendesk-widget/zendeskWidgetSpec.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -describe('Angular Zendesk Widget', function() { - - describe('Module bootstrap', function() { - - it('should throw if no accountUrl provided', function() { - module('zendeskWidget'); - expect(function() { - inject() - }).toThrowError('Missing accountUrl. Please set in app config via ZendeskWidgetProvider'); - }); - - }); - -}); diff --git a/test/unit/services/zendeskWidgetProviderSpec.js b/test/unit/services/zendeskWidgetProviderSpec.js new file mode 100644 index 0000000..9f1d86d --- /dev/null +++ b/test/unit/services/zendeskWidgetProviderSpec.js @@ -0,0 +1,35 @@ +describe('ZendeskWidgetProvider', function() { + 'use strict'; + + var subject, mockService, $window; + + beforeEach(module('zendeskWidget')); + beforeEach(inject(function(_$window_, _ZendeskWidget_) { + subject = _ZendeskWidget_; + $window = _$window_; + })); + + describe('a set of API methods', function() { + beforeEach(function() { + var apiMethods = ['setLocale', 'identify', 'hide', 'show', 'activate']; + mockService = jasmine.createSpyObj('MockZendeskWebWidgetAPI', apiMethods); + $window.zE = mockService; + }); + + it("delegates to Zendesk's Web Widget API", function() { + var anyArgs = ['foo', 'bar', 'baz']; + + subject.identify(anyArgs); + subject.hide(anyArgs); + subject.show(anyArgs); + subject.activate(anyArgs); + subject.setLocale(anyArgs); + + expect(mockService.identify).toHaveBeenCalledWith(anyArgs); + expect(mockService.hide).toHaveBeenCalledWith(anyArgs); + expect(mockService.show).toHaveBeenCalledWith(anyArgs); + expect(mockService.activate).toHaveBeenCalledWith(anyArgs); + expect(mockService.setLocale).toHaveBeenCalledWith(anyArgs); + }); + }); +}) diff --git a/test/unit/services/zendeskWidgetSettingsSpec.js b/test/unit/services/zendeskWidgetSettingsSpec.js new file mode 100644 index 0000000..785acc0 --- /dev/null +++ b/test/unit/services/zendeskWidgetSettingsSpec.js @@ -0,0 +1,20 @@ +describe('zendeskWidgetSettings', function() { + 'use strict'; + + var subject; + + beforeEach(module('zendeskWidget')); + beforeEach(inject(function(_zendeskWidgetSettings_) { + subject = _zendeskWidgetSettings_; + })); + + describe('by default', function() { + it('has a blank `accountUrl`', function() { + expect(subject['accountUrl']).toEqual(''); + }); + + it('does a no-op on `beforePageLoad`', function() { + expect(subject['beforePageLoad']).toEqual(angular.noop); + }); + }); +})