diff --git a/src/lib/viewers/image/ImageBaseViewer.js b/src/lib/viewers/image/ImageBaseViewer.js index c7797c268..5f764d49d 100644 --- a/src/lib/viewers/image/ImageBaseViewer.js +++ b/src/lib/viewers/image/ImageBaseViewer.js @@ -3,7 +3,6 @@ import Controls from '../../Controls'; import BaseViewer from '../BaseViewer'; import Browser from '../../Browser'; import { ICON_ZOOM_IN, ICON_ZOOM_OUT } from '../../icons/icons'; -import { get } from '../../util'; import { CLASS_INVISIBLE } from '../../constants'; @@ -44,17 +43,12 @@ class ImageBaseViewer extends BaseViewer { return; } - const loadOriginalDimensions = this.setOriginalImageSize(this.imageEl); - loadOriginalDimensions - .then(() => { - this.loadUI(); - this.zoom(); - - this.imageEl.classList.remove(CLASS_INVISIBLE); - this.loaded = true; - this.emit('load'); - }) - .catch(this.errorHandler); + this.loadUI(); + this.zoom(); + + this.imageEl.classList.remove(CLASS_INVISIBLE); + this.loaded = true; + this.emit('load'); } /** @@ -173,53 +167,6 @@ class ImageBaseViewer extends BaseViewer { this.bindControlListeners(); } - /** - * Sets the original image width and height on the img element. Can be removed when - * naturalHeight and naturalWidth attributes work correctly in IE 11. - * - * @private - * @param {HTMLElement} imageEl - The image to set the original size attributes on - * @return {Promise} A promise that is resolved if the original image dimensions were set. - */ - setOriginalImageSize(imageEl) { - const promise = new Promise((resolve) => { - // Do not bother loading a new image when the natural size attributes exist - if (imageEl.naturalWidth && imageEl.naturalHeight) { - imageEl.setAttribute('originalWidth', imageEl.naturalWidth); - imageEl.setAttribute('originalHeight', imageEl.naturalHeight); - resolve(); - } else { - // Case when natural dimensions are not assigned - // By default, assigned width and height in Chrome/Safari/Firefox will be 300x150. - // IE11 workaround. Dimensions only displayed if the image is attached to the document. - get(imageEl.src, {}, 'text') - .then((imageAsText) => { - const parser = new DOMParser(); - const svgEl = parser.parseFromString(imageAsText, 'image/svg+xml'); - - try { - // Assume svgEl is an instanceof an SVG with a viewBox and preserveAspectRatio of meet - // where the height is the limiting axis - const viewBox = svgEl.documentElement.getAttribute('viewBox'); - const [, , w, h] = viewBox.split(' '); - const aspectRatio = h ? w / h : w; - imageEl.setAttribute('originalWidth', Math.round(aspectRatio * 150)); - imageEl.setAttribute('originalHeight', 150); - } catch (e) { - // Assume 300x150 that chrome does by default - imageEl.setAttribute('originalWidth', 300); - imageEl.setAttribute('originalHeight', 150); - } finally { - resolve(); - } - }) - .catch(resolve); - } - }); - - return promise; - } - //-------------------------------------------------------------------------- // Event Listeners //-------------------------------------------------------------------------- diff --git a/src/lib/viewers/image/ImageViewer.js b/src/lib/viewers/image/ImageViewer.js index 1eedadade..2b0620492 100644 --- a/src/lib/viewers/image/ImageViewer.js +++ b/src/lib/viewers/image/ImageViewer.js @@ -3,7 +3,7 @@ import Browser from '../../Browser'; import ImageBaseViewer from './ImageBaseViewer'; import { ICON_FILE_IMAGE, ICON_FULLSCREEN_IN, ICON_FULLSCREEN_OUT, ICON_ROTATE_LEFT } from '../../icons/icons'; import { CLASS_INVISIBLE } from '../../constants'; -import { openContentInsideIframe } from '../../util'; +import { get, openContentInsideIframe } from '../../util'; import './Image.scss'; const CSS_CLASS_IMAGE = 'bp-image'; @@ -33,6 +33,21 @@ class ImageViewer extends ImageBaseViewer { this.currentRotationAngle = 0; } + /** + * @inheritdoc + * + * @return {void} + */ + finishLoading() { + if (this.isDestroyed()) { + return; + } + + this.setOriginalImageSize(this.imageEl) + .then(() => super.finishLoading()) + .catch(this.errorHandler); + } + /** * Loads an Image. * @@ -403,6 +418,49 @@ class ImageViewer extends ImageBaseViewer { rotationAngle: this.rotationAngle }); } + + /** + * Sets the original image width and height on the img element. Can be removed when + * naturalHeight and naturalWidth attributes work correctly in IE 11. + * + * @private + * @param {HTMLElement} imageEl - The image to set the original size attributes on + * @return {Promise} A promise that is resolved if the original image dimensions were set. + */ + setOriginalImageSize(imageEl) { + // Do not bother loading a new image when the natural size attributes exist + if (imageEl.naturalWidth && imageEl.naturalHeight) { + imageEl.setAttribute('originalWidth', imageEl.naturalWidth); + imageEl.setAttribute('originalHeight', imageEl.naturalHeight); + return Promise.resolve(); + } + + // Case when natural dimensions are not assigned + // By default, assigned width and height in Chrome/Safari/Firefox will be 300x150. + // IE11 workaround. Dimensions only displayed if the image is attached to the document. + return get(imageEl.src, {}, 'text') + .then((imageAsText) => { + const parser = new DOMParser(); + const svgEl = parser.parseFromString(imageAsText, 'image/svg+xml'); + + try { + // Assume svgEl is an instanceof an SVG with a viewBox and preserveAspectRatio of meet + // where the height is the limiting axis + const viewBox = svgEl.documentElement.getAttribute('viewBox'); + const [, , w, h] = viewBox.split(' '); + const aspectRatio = h ? w / h : w; + imageEl.setAttribute('originalWidth', Math.round(aspectRatio * 150)); + imageEl.setAttribute('originalHeight', 150); + } catch (e) { + // Assume 300x150 that chrome does by default + imageEl.setAttribute('originalWidth', 300); + imageEl.setAttribute('originalHeight', 150); + } finally { + Promise.resolve(); + } + }) + .catch(Promise.resolve); + } } export default ImageViewer; diff --git a/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js b/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js index a40751e85..c24e264da 100644 --- a/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js +++ b/src/lib/viewers/image/__tests__/ImageBaseViewer-test.js @@ -120,7 +120,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.updateCursor(); - expect(imageBase.isZoomable).to.have.been.false; + expect(imageBase.isZoomable).to.be.false; expect(imageBase.imageEl).to.have.class(CSS_CLASS_PANNABLE); expect(imageBase.imageEl).to.not.have.class(CSS_CLASS_ZOOMABLE); }); @@ -132,7 +132,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.updateCursor(); - expect(imageBase.isZoomable).to.have.been.true; + expect(imageBase.isZoomable).to.be.true; expect(imageBase.imageEl).to.have.class(CSS_CLASS_ZOOMABLE); expect(imageBase.imageEl).to.not.have.class(CSS_CLASS_PANNABLE); }); @@ -157,7 +157,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { expect(imageBase.isPanning).to.be.false; expect(imageBase.imageEl).to.not.have.class(CSS_CLASS_PANNING); - expect(imageBase.emit).to.not.have.been.calledWith('panstart'); + expect(imageBase.emit).to.not.be.calledWith('panstart'); }); it('should start panning, remove listeners, and fire "panstart" event', () => { @@ -168,7 +168,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { expect(imageBase.isPanning).to.be.true; expect(imageBase.imageEl).to.have.class(CSS_CLASS_PANNING); - expect(imageBase.emit).to.have.been.calledWith('panstart'); + expect(imageBase.emit).to.be.calledWith('panstart'); }); }); @@ -185,7 +185,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.pan({}); expect(imageBase.didPan).to.be.true; - expect(stubs.emit).to.have.been.calledWith('pan'); + expect(stubs.emit).to.be.calledWith('pan'); }); it('should not pan if the viewer is not already panning', () => { @@ -194,7 +194,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.pan({}); expect(imageBase.didPan).to.be.false; - expect(stubs.emit).to.not.have.been.calledWith('pan'); + expect(stubs.emit).to.not.be.calledWith('pan'); }); }); @@ -219,60 +219,6 @@ describe('lib/viewers/image/ImageBaseViewer', () => { }); }); - describe('setOriginalImageSize()', () => { - it('should use the naturalHeight and naturalWidth when available', (done) => { - const imageEl = { - naturalWidth: 100, - naturalHeight: 100, - setAttribute: (name, value) => { - imageEl[name] = value; - }, - getAttribute: (name) => imageEl[name] - }; - - const promise = imageBase.setOriginalImageSize(imageEl); - promise.should.be.fulfilled.then(() => { - expect(imageEl.getAttribute('originalWidth')).to.equal(imageEl.naturalWidth); - expect(imageEl.getAttribute('originalHeight')).to.equal(imageEl.naturalHeight); - done(); - }).catch(() => { - Assert.fail(); - }); - }); - - it('should default to 300x150 when naturalHeight and naturalWidth are 0x0', (done) => { - const imageEl = { - naturalWidth: 0, - naturalHeight: 0, - setAttribute: (name, value) => { - imageEl[name] = value; - }, - getAttribute: (name) => imageEl[name] - }; - - const getStub = sandbox.stub(util, 'get').returns(Promise.resolve('not real a image')); - const promise = imageBase.setOriginalImageSize(imageEl); - promise.should.be.fulfilled.then(() => { - expect(imageEl.getAttribute('originalWidth')).to.equal(300); - expect(imageEl.getAttribute('originalHeight')).to.equal(150); - done(); - }).catch(() => { - Assert.fail(); - }); - }); - - it('should resolve when the get call fails', (done) => { - const imageEl = {}; - const getStub = sandbox.stub(util, 'get').returns(Promise.reject()); - const promise = imageBase.setOriginalImageSize(imageEl); - promise.should.be.fulfilled.then(() => { - done(); - }).catch(() => { - Assert.fail(); - }); - }); - }); - describe('bindControlListeners()', () => { it('should add the correct controls', () => { imageBase.controls = { @@ -311,7 +257,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { event.ctrlKey = null; event.metaKey = 'blah'; imageBase.handleMouseDown(event); - expect(stubs.pan).to.not.have.been.called; + expect(stubs.pan).to.not.be.called; }); it('should start panning if correct click type', () => { @@ -324,7 +270,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { preventDefault: sandbox.stub() }; imageBase.handleMouseDown(event); - expect(stubs.pan).to.have.been.called; + expect(stubs.pan).to.be.called; }); }); @@ -351,7 +297,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { event.ctrlKey = null; event.metaKey = 'blah'; imageBase.handleMouseUp(event); - expect(stubs.zoom).to.not.have.been.called; + expect(stubs.zoom).to.not.be.called; }); it('should zoom in if zoomable but not pannable', () => { @@ -365,7 +311,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { }; imageBase.isZoomable = true; imageBase.handleMouseUp(event); - expect(stubs.zoom).to.have.been.calledWith('in'); + expect(stubs.zoom).to.be.calledWith('in'); }); it('should reset zoom if mouseup was not due to end of panning', () => { @@ -380,7 +326,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.isZoomable = false; imageBase.didPan = false; imageBase.handleMouseUp(event); - expect(stubs.zoom).to.have.been.calledWith('reset'); + expect(stubs.zoom).to.be.calledWith('reset'); }); it('should not zoom if mouse up was due to end of panning', () => { @@ -395,7 +341,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.isZoomable = false; imageBase.didPan = true; imageBase.handleMouseUp(event); - expect(stubs.zoom).to.not.have.been.called; + expect(stubs.zoom).to.not.be.called; }); }); @@ -468,24 +414,24 @@ describe('lib/viewers/image/ImageBaseViewer', () => { it('should bind all default image listeners', () => { imageBase.bindDOMListeners(); - expect(stubs.listeners).to.have.been.calledWith('mousedown', imageBase.handleMouseDown); - expect(stubs.listeners).to.have.been.calledWith('mouseup', imageBase.handleMouseUp); - expect(stubs.listeners).to.have.been.calledWith('dragstart', imageBase.cancelDragEvent); + expect(stubs.listeners).to.be.calledWith('mousedown', imageBase.handleMouseDown); + expect(stubs.listeners).to.be.calledWith('mouseup', imageBase.handleMouseUp); + expect(stubs.listeners).to.be.calledWith('dragstart', imageBase.cancelDragEvent); }); it('should bind all iOS listeners', () => { sandbox.stub(Browser, 'isIOS').returns(true); imageBase.bindDOMListeners(); - expect(stubs.listeners).to.have.been.calledWith('gesturestart', imageBase.mobileZoomStartHandler); - expect(stubs.listeners).to.have.been.calledWith('gestureend', imageBase.mobileZoomEndHandler); + expect(stubs.listeners).to.be.calledWith('gesturestart', imageBase.mobileZoomStartHandler); + expect(stubs.listeners).to.be.calledWith('gestureend', imageBase.mobileZoomEndHandler); }); it('should bind all mobile and non-iOS listeners', () => { sandbox.stub(Browser, 'isIOS').returns(false); imageBase.bindDOMListeners(); - expect(stubs.listeners).to.have.been.calledWith('touchstart', imageBase.mobileZoomStartHandler); - expect(stubs.listeners).to.have.been.calledWith('touchmove', imageBase.mobileZoomChangeHandler); - expect(stubs.listeners).to.have.been.calledWith('touchend', imageBase.mobileZoomEndHandler); + expect(stubs.listeners).to.be.calledWith('touchstart', imageBase.mobileZoomStartHandler); + expect(stubs.listeners).to.be.calledWith('touchmove', imageBase.mobileZoomChangeHandler); + expect(stubs.listeners).to.be.calledWith('touchend', imageBase.mobileZoomEndHandler); }); }); @@ -545,7 +491,7 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.errorHandler(err); err.displayMessage = 'We\'re sorry, the preview didn\'t load. Please refresh the page.'; - expect(stubs.emit).to.have.been.calledWith('error', err); + expect(stubs.emit).to.be.calledWith('error', err); }); }); @@ -554,7 +500,6 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.loaded = false; stubs.zoom = sandbox.stub(imageBase, 'zoom'); stubs.loadUI = sandbox.stub(imageBase, 'loadUI'); - stubs.setOriginalImageSize = sandbox.stub(imageBase, 'setOriginalImageSize'); stubs.errorHandler = sandbox.stub(imageBase, 'errorHandler'); }); @@ -564,26 +509,29 @@ describe('lib/viewers/image/ImageBaseViewer', () => { imageBase.finishLoading(); expect(imageBase.loaded).to.be.false; - expect(stubs.emit).to.not.have.been.called; - expect(stubs.zoom).to.not.have.been.called; - expect(stubs.setOriginalImageSize).to.not.have.been.called; - expect(stubs.loadUI).to.not.have.been.called; - expect(stubs.errorHandler).to.not.have.been.called; + expect(stubs.emit).to.not.be.called; + expect(stubs.zoom).to.not.be.called; + expect(stubs.loadUI).to.not.be.called; + expect(stubs.errorHandler).to.not.be.called; }); it('should load UI if not destroyed', (done) => { imageBase.on('load', () => { - expect(stubs.errorHandler).to.not.have.been.called; + expect(stubs.errorHandler).to.not.be.called; expect(imageBase.loaded).to.be.true; - expect(stubs.zoom).to.have.been.called; - expect(stubs.loadUI).to.have.been.called; + expect(stubs.zoom).to.be.called; + expect(stubs.loadUI).to.be.called; done(); }); - stubs.setOriginalImageSize.returns(Promise.resolve()); imageBase.destroyed = false; imageBase.finishLoading(); - expect(stubs.setOriginalImageSize).to.have.been.called; + expect(imageBase.loaded).to.be.false; + expect(stubs.emit).to.be.called; + expect(stubs.zoom).to.be.called; + expect(stubs.setOriginalImageSize).to.be.called; + expect(stubs.loadUI).to.be.called; + expect(stubs.errorHandler).to.be.called; }); }); diff --git a/src/lib/viewers/image/__tests__/ImageViewer-test.js b/src/lib/viewers/image/__tests__/ImageViewer-test.js index 734c1beed..d87754a78 100644 --- a/src/lib/viewers/image/__tests__/ImageViewer-test.js +++ b/src/lib/viewers/image/__tests__/ImageViewer-test.js @@ -1,11 +1,12 @@ /* eslint-disable no-unused-expressions */ import ImageViewer from '../ImageViewer'; -import BaseViewer from '../../BaseViewer'; +import ImageBaseViewer from '../ImageBaseViewer'; import Browser from '../../../Browser'; import * as util from '../../../util'; const CSS_CLASS_ZOOMABLE = 'zoomable'; const CSS_CLASS_PANNABLE = 'pannable'; +const CSS_CLASS_IMAGE = 'bp-image'; const sandbox = sinon.sandbox.create(); const imageUrl = @@ -13,17 +14,13 @@ const imageUrl = let image; let stubs = {}; let containerEl; -let clock; describe('lib/viewers/image/ImageViewer', () => { - const setupFunc = BaseViewer.prototype.setup; - before(() => { fixture.setBase('src/lib'); }); beforeEach(() => { - clock = sinon.useFakeTimers(); fixture.load('viewers/image/__tests__/ImageViewer-test.html'); containerEl = document.querySelector('.container'); image = new ImageViewer({ @@ -45,17 +42,12 @@ describe('lib/viewers/image/ImageViewer', () => { } }); - Object.defineProperty(BaseViewer.prototype, 'setup', { value: sandbox.stub() }); image.containerEl = containerEl; - image.setup(); }); afterEach(() => { sandbox.verifyAndRestore(); fixture.cleanup(); - clock.restore(); - - Object.defineProperty(BaseViewer.prototype, 'setup', { value: setupFunc }); if (image && typeof image.destroy === 'function') { image.destroy(); @@ -65,459 +57,590 @@ describe('lib/viewers/image/ImageViewer', () => { }); describe('setup()', () => { + const setupFunc = ImageBaseViewer.prototype.setup; + + afterEach(() => { + Object.defineProperty(ImageBaseViewer.prototype, 'setup', { value: setupFunc }); + }); + it('should set up layout', () => { + Object.defineProperty(ImageBaseViewer.prototype, 'setup', { value: sandbox.stub() }); + image.setup(); expect(image.wrapperEl).to.have.class('bp-image'); expect(image.imageEl).to.have.class('bp-is-invisible'); }); }); - describe('load()', () => { - it('should fetch the image URL and load an image', () => { - sandbox.stub(image, 'createContentUrlWithAuthParams').returns(imageUrl); - sandbox.stub(image, 'getRepStatus').returns({ getPromise: () => Promise.resolve() }); - stubs.event = sandbox.stub(image.imageEl, 'addEventListener'); - stubs.load = sandbox.stub(image, 'finishLoading'); - stubs.error = sandbox.stub(image, 'errorHandler'); - stubs.bind = sandbox.stub(image, 'bindDOMListeners'); - - // load the image - return image - .load(imageUrl) - .then(() => { - expect(image.bindDOMListeners).to.be.called; - expect(image.createContentUrlWithAuthParams).to.be.calledWith('foo', '1.png'); - }) - .catch(() => {}); - }); - }); + describe('After setup', () => { + const loadFunc = ImageBaseViewer.prototype.load; - describe('prefetch()', () => { - it('should prefetch content if content is true and representation is ready', () => { - sandbox.stub(image, 'isRepresentationReady').returns(true); - sandbox.stub(image, 'createContentUrlWithAuthParams').returns('somecontenturl'); - image.prefetch({ content: true }); - expect(image.createContentUrlWithAuthParams).to.be.calledWith('foo', '1.png'); + beforeEach(() => { + stubs.setup = sandbox.stub(image, 'setup'); + Object.defineProperty(ImageBaseViewer.prototype, 'load', { value: sandbox.stub() }); + image.wrapperEl = document.querySelector('.bp-container'); + image.wrapperEl.classList.add(CSS_CLASS_IMAGE); + + image.imageEl = image.wrapperEl.appendChild(document.createElement('img')); + image.imageEl.setAttribute('data-page-number', 1); }); - it('should not prefetch content if content is true but representation is not ready', () => { - sandbox.stub(image, 'isRepresentationReady').returns(false); - sandbox.stub(image, 'createContentUrlWithAuthParams'); - image.prefetch({ content: true }); - expect(image.createContentUrlWithAuthParams).to.not.be.called; + afterEach(() => { + Object.defineProperty(ImageBaseViewer.prototype, 'load', { value: loadFunc }); }); - it('should not prefetch content if file is watermarked', () => { - image.options.file.watermark_info = { - is_watermarked: true - }; - sandbox.stub(image, 'createContentUrlWithAuthParams'); + describe('finishLoading()', () => { + const finishFunc = ImageBaseViewer.prototype.finishLoading; + + beforeEach(() => { + stubs.destroyed = sandbox.stub(image, 'isDestroyed').returns(false); + stubs.setOriginalImageSize = sandbox.stub(image, 'setOriginalImageSize'); + Object.defineProperty(ImageBaseViewer.prototype, 'finishLoading', { value: sandbox.stub() }); + stubs.errorHandler = sandbox.stub(image, 'errorHandler'); + }); + + afterEach(() => { + Object.defineProperty(ImageBaseViewer.prototype, 'finishLoading', { value: finishFunc }); + }); + + it('should do nothing if already destroyed', () => { + stubs.destroyed.returns(true); + image.finishLoading(); + expect(stubs.setOriginalImageSize).to.not.have.been.called; + expect(stubs.errorHandler).to.not.have.been.called; + }); - image.prefetch({ content: true }); + it('should load UI if not destroyed', (done) => { + const promise = Promise.resolve(); + stubs.setOriginalImageSize.returns(promise); + promise.should.be.fulfilled.then(() => { + expect(stubs.errorHandler).to.not.have.been.called; + done(); + }).catch(() => { + Assert.fail(); + }); + + image.finishLoading(); + expect(stubs.setOriginalImageSize).to.have.been.called; + }); - expect(image.createContentUrlWithAuthParams).to.not.be.called; + it('should load call error handler if viewer cannot get original image size for scaling', (done) => { + const promise = Promise.reject(); + stubs.setOriginalImageSize.returns(promise); + promise.should.be.fulfilled.then(() => { + Assert.fail(); + }).catch(() => { + expect(stubs.errorHandler).to.have.been.called; + done(); + }); + + image.finishLoading(); + expect(stubs.setOriginalImageSize).to.have.been.called; + }); }); - }); - describe('updatePannability()', () => { - beforeEach(() => { - stubs.cursor = sandbox.stub(image, 'updateCursor'); - image.didPan = true; + describe('load()', () => { + + it('should fetch the image URL and load an image', () => { + sandbox.stub(image, 'createContentUrlWithAuthParams').returns(imageUrl); + sandbox.stub(image, 'getRepStatus').returns({ getPromise: () => Promise.resolve() }); + stubs.event = sandbox.stub(image.imageEl, 'addEventListener'); + stubs.load = sandbox.stub(image, 'finishLoading'); + stubs.error = sandbox.stub(image, 'errorHandler'); + stubs.bind = sandbox.stub(image, 'bindDOMListeners'); + + // load the image + return image + .load(imageUrl) + .then(() => { + expect(image.bindDOMListeners).to.be.called; + expect(image.createContentUrlWithAuthParams).to.be.calledWith('foo', '1.png'); + }) + .catch(() => {}); + }); }); - it('should ignore if image does not exist', () => { - stubs.imageEl = image.imageEl; - image.imageEl = null; + describe('prefetch()', () => { + it('should prefetch content if content is true and representation is ready', () => { + sandbox.stub(image, 'isRepresentationReady').returns(true); + sandbox.stub(image, 'createContentUrlWithAuthParams').returns('somecontenturl'); + image.prefetch({ content: true }); + expect(image.createContentUrlWithAuthParams).to.be.calledWith('foo', '1.png'); + }); + + it('should not prefetch content if content is true but representation is not ready', () => { + sandbox.stub(image, 'isRepresentationReady').returns(false); + sandbox.stub(image, 'createContentUrlWithAuthParams'); + image.prefetch({ content: true }); + expect(image.createContentUrlWithAuthParams).to.not.be.called; + }); - image.updatePannability(); + it('should not prefetch content if file is watermarked', () => { + image.options.file.watermark_info = { + is_watermarked: true + }; + sandbox.stub(image, 'createContentUrlWithAuthParams'); - expect(image.didPan).to.have.been.true; - expect(stubs.cursor).to.not.be.called; + image.prefetch({ content: true }); - image.imageEl = stubs.imageEl; + expect(image.createContentUrlWithAuthParams).to.not.be.called; + }); }); - it('should set pannability to true if rotated image is pannable', () => { - sandbox.stub(image, 'isRotated').returns(true); + describe('updatePannability()', () => { + beforeEach(() => { + stubs.cursor = sandbox.stub(image, 'updateCursor'); + image.didPan = true; + }); - image.imageEl.style.height = '50px'; - image.imageEl.style.width = '10px'; - image.wrapperEl.style.height = '10px'; - image.wrapperEl.style.width = '50px'; + it('should ignore if image does not exist', () => { + stubs.imageEl = image.imageEl; + image.imageEl = null; - image.updatePannability(); - expect(image.didPan).to.have.been.false; - expect(stubs.cursor).to.be.called; - }); + image.updatePannability(); - it('should set pannability to false if rotated image is not pannable', () => { - sandbox.stub(image, 'isRotated').returns(true); + expect(image.didPan).to.have.been.true; + expect(stubs.cursor).to.not.be.called; - image.imageEl.style.height = '10px'; - image.wrapperEl.style.height = '50px'; - image.imageEl.style.width = '10px'; - image.wrapperEl.style.width = '50px'; + image.imageEl = stubs.imageEl; + }); - image.updatePannability(); + it('should set pannability to true if rotated image is pannable', () => { + sandbox.stub(image, 'isRotated').returns(true); - expect(image.didPan).to.have.been.false; - expect(stubs.cursor).to.be.called; - }); + image.imageEl.style.height = '50px'; + image.imageEl.style.width = '10px'; + image.wrapperEl.style.height = '10px'; + image.wrapperEl.style.width = '50px'; - it('should set pannability to true if non-rotated image is pannable', () => { - sandbox.stub(image, 'isRotated').returns(false); + image.updatePannability(); + expect(image.didPan).to.have.been.false; + expect(stubs.cursor).to.be.called; + }); - image.imageEl.style.height = '50px'; - image.wrapperEl.style.height = '10px'; - image.imageEl.style.width = '50px'; - image.wrapperEl.style.width = '10px'; + it('should set pannability to false if rotated image is not pannable', () => { + sandbox.stub(image, 'isRotated').returns(true); - image.updatePannability(); + image.imageEl.style.height = '10px'; + image.wrapperEl.style.height = '50px'; + image.imageEl.style.width = '10px'; + image.wrapperEl.style.width = '50px'; - expect(image.didPan).to.have.been.false; - expect(stubs.cursor).to.be.called; - }); + image.updatePannability(); - it('should set pannability to false if non-rotated image is not pannable', () => { - sandbox.stub(image, 'isRotated').returns(false); + expect(image.didPan).to.have.been.false; + expect(stubs.cursor).to.be.called; + }); - image.imageEl.style.height = '10px'; - image.wrapperEl.style.height = '50px'; - image.imageEl.style.width = '10px'; - image.wrapperEl.style.width = '50px'; + it('should set pannability to true if non-rotated image is pannable', () => { + sandbox.stub(image, 'isRotated').returns(false); - image.updatePannability(); + image.imageEl.style.height = '50px'; + image.wrapperEl.style.height = '10px'; + image.imageEl.style.width = '50px'; + image.wrapperEl.style.width = '10px'; - expect(image.didPan).to.have.been.false; - expect(stubs.cursor).to.be.called; - }); - }); + image.updatePannability(); - describe('rotateLeft()', () => { - beforeEach(() => { - stubs.emit = sandbox.stub(image, 'emit'); - stubs.orientChange = sandbox.stub(image, 'handleOrientationChange'); - stubs.scale = sandbox.stub(image, 'setScale'); - image.currentRotationAngle = 0; + expect(image.didPan).to.have.been.false; + expect(stubs.cursor).to.be.called; + }); + + it('should set pannability to false if non-rotated image is not pannable', () => { + sandbox.stub(image, 'isRotated').returns(false); + + image.imageEl.style.height = '10px'; + image.wrapperEl.style.height = '50px'; + image.imageEl.style.width = '10px'; + image.wrapperEl.style.width = '50px'; + + image.updatePannability(); + + expect(image.didPan).to.have.been.false; + expect(stubs.cursor).to.be.called; + }); }); - it('should rotate the image 90 degrees to the left', () => { - image.rotateLeft(); + describe('rotateLeft()', () => { + beforeEach(() => { + stubs.emit = sandbox.stub(image, 'emit'); + stubs.orientChange = sandbox.stub(image, 'handleOrientationChange'); + stubs.scale = sandbox.stub(image, 'setScale'); + image.currentRotationAngle = 0; + }); + + it('should rotate the image 90 degrees to the left', () => { + image.rotateLeft(); - expect(image.currentRotationAngle).to.equal(-90); - expect(image.imageEl.getAttribute('data-rotation-angle')).to.equal('-90'); - expect(image.imageEl.style.transform).to.equal('rotate(-90deg)'); - expect(stubs.emit).to.be.calledWith('rotate'); - expect(stubs.orientChange).to.be.called; + expect(image.currentRotationAngle).to.equal(-90); + expect(image.imageEl.getAttribute('data-rotation-angle')).to.equal('-90'); + expect(image.imageEl.style.transform).to.equal('rotate(-90deg)'); + expect(stubs.emit).to.be.calledWith('rotate'); + expect(stubs.orientChange).to.be.called; + }); }); - }); - describe('zoom()', () => { - beforeEach(() => { - sandbox.stub(image, 'appendAuthParams').returns(imageUrl); - sandbox.stub(image, 'finishLoading'); + describe('zoom()', () => { + beforeEach(() => { + sandbox.stub(image, 'appendAuthParams').returns(imageUrl); + sandbox.stub(image, 'finishLoading'); - // Stub out methods called in zoom() - stubs.adjustZoom = sandbox.stub(image, 'adjustImageZoomPadding'); + // Stub out methods called in zoom() + stubs.adjustZoom = sandbox.stub(image, 'adjustImageZoomPadding'); - // Set image height & width - image.imageEl.style.width = '100px'; - image.imageEl.style.height = '100px'; - image.wrapperEl.style.width = '50px'; - image.wrapperEl.style.height = '50px'; + // Set image height & width + image.imageEl.style.width = '100px'; + image.imageEl.style.height = '100px'; + image.wrapperEl.style.width = '50px'; + image.wrapperEl.style.height = '50px'; - sandbox.stub(image, 'getRepStatus').returns({ getPromise: () => Promise.resolve() }); - image.load(imageUrl).catch(() => {}); - }); + sandbox.stub(image, 'getRepStatus').returns({ getPromise: () => Promise.resolve() }); + image.load(imageUrl).catch(() => {}); + }); - describe('should zoom in by modifying', () => { - it('width', () => { - image.imageEl.style.width = '200px'; + describe('should zoom in by modifying', () => { + it('width', () => { + image.imageEl.style.width = '200px'; + + const origImageSize = image.imageEl.getBoundingClientRect(); + image.zoom('in'); + const newImageSize = image.imageEl.getBoundingClientRect(); + expect(newImageSize.width).gt(origImageSize.width); + }); + + it('height', () => { + image.imageEl.style.height = '200px'; + + const origImageSize = image.imageEl.getBoundingClientRect(); + image.zoomIn(); + const newImageSize = image.imageEl.getBoundingClientRect(); + expect(newImageSize.height).gt(origImageSize.height); + expect(stubs.adjustZoom).to.be.called; + }); + }); - const origImageSize = image.imageEl.getBoundingClientRect(); - image.zoom('in'); - const newImageSize = image.imageEl.getBoundingClientRect(); - expect(newImageSize.width).gt(origImageSize.width); + describe('should zoom out by modifying', () => { + it('width', () => { + image.imageEl.style.width = '200px'; + + const origImageSize = image.imageEl.getBoundingClientRect(); + image.zoomOut(); + const newImageSize = image.imageEl.getBoundingClientRect(); + expect(newImageSize.width).lt(origImageSize.width); + expect(stubs.adjustZoom).to.be.called; + }); + + it('height', () => { + image.imageEl.style.height = '200px'; + + const origImageSize = image.imageEl.getBoundingClientRect(); + image.zoomOut(); + const newImageSize = image.imageEl.getBoundingClientRect(); + expect(newImageSize.height).lt(origImageSize.height); + expect(stubs.adjustZoom).to.be.called; + }); }); - it('height', () => { - image.imageEl.style.height = '200px'; + it('should swap height & width when image is rotated', () => { + sandbox.stub(image, 'isRotated').returns(true); + + image.load(imageUrl).catch(() => {}); + image.imageEl.style.width = '200px'; // ensures width > height const origImageSize = image.imageEl.getBoundingClientRect(); image.zoomIn(); const newImageSize = image.imageEl.getBoundingClientRect(); + expect(newImageSize.height).gt(origImageSize.height); expect(stubs.adjustZoom).to.be.called; }); - }); - describe('should zoom out by modifying', () => { - it('width', () => { - image.imageEl.style.width = '200px'; + it('should reset dimensions and adjust padding when called with reset', () => { + image.imageEl.style.width = '10px'; + image.imageEl.style.height = '20px'; + sandbox.spy(image, 'zoom'); - const origImageSize = image.imageEl.getBoundingClientRect(); - image.zoomOut(); - const newImageSize = image.imageEl.getBoundingClientRect(); - expect(newImageSize.width).lt(origImageSize.width); - expect(stubs.adjustZoom).to.be.called; - }); - - it('height', () => { - image.imageEl.style.height = '200px'; + image.zoom('reset'); - const origImageSize = image.imageEl.getBoundingClientRect(); - image.zoomOut(); - const newImageSize = image.imageEl.getBoundingClientRect(); - expect(newImageSize.height).lt(origImageSize.height); + expect(image.imageEl.style.width).to.equal(''); + expect(image.imageEl.style.height).to.equal(''); expect(stubs.adjustZoom).to.be.called; + expect(image.zoom).to.be.calledWith(); }); }); - it('should swap height & width when image is rotated', () => { - sandbox.stub(image, 'isRotated').returns(true); - - image.load(imageUrl).catch(() => {}); - image.imageEl.style.width = '200px'; // ensures width > height + describe('setScale()', () => { + it('should emit a scale event with current scale and rotationAngle', () => { + sandbox.stub(image, 'emit'); + image.currentRotationAngle = -90; + const [width, height] = [100, 100]; - const origImageSize = image.imageEl.getBoundingClientRect(); - image.zoomIn(); - const newImageSize = image.imageEl.getBoundingClientRect(); - - expect(newImageSize.height).gt(origImageSize.height); - expect(stubs.adjustZoom).to.be.called; + image.setScale(width, height); + expect(image.emit).to.be.calledWith('scale', { + scale: sinon.match.any, + rotationAngle: sinon.match.number + }); + }); }); - it('should reset dimensions and adjust padding when called with reset', () => { - image.imageEl.style.width = '10px'; - image.imageEl.style.height = '20px'; - sandbox.spy(image, 'zoom'); + describe('loadUI()', () => { + it('should load UI & controls for zoom', () => { + image.loadUI(); - image.zoom('reset'); - - expect(image.imageEl.style.width).to.equal(''); - expect(image.imageEl.style.height).to.equal(''); - expect(stubs.adjustZoom).to.be.called; - expect(image.zoom).to.be.calledWith(); + expect(image.controls).to.not.be.undefined; + expect(image.controls.buttonRefs.length).to.equal(5); + }); }); - }); - describe('setScale()', () => { - it('should emit a scale event with current scale and rotationAngle', () => { - sandbox.stub(image, 'emit'); - image.currentRotationAngle = -90; - const [width, height] = [100, 100]; + describe('print()', () => { + beforeEach(() => { + stubs.mockIframe = util.openContentInsideIframe(image.imageEl.outerHTML); + stubs.focus = sandbox.stub(stubs.mockIframe.contentWindow, 'focus'); + stubs.execCommand = sandbox.stub(stubs.mockIframe.contentWindow.document, 'execCommand'); + stubs.print = sandbox.stub(stubs.mockIframe.contentWindow, 'print'); - image.setScale(width, height); - expect(image.emit).to.be.calledWith('scale', { - scale: sinon.match.any, - rotationAngle: sinon.match.number + stubs.openContentInsideIframe = sandbox.stub(util, 'openContentInsideIframe').returns(stubs.mockIframe); + stubs.getName = sandbox.stub(Browser, 'getName'); }); - }); - }); - describe('loadUI()', () => { - it('should load UI & controls for zoom', () => { - image.loadUI(); + it('should open the content inside an iframe, center, and focus', () => { + image.print(); + expect(stubs.openContentInsideIframe).to.be.called; + expect(image.printImage.style.display).to.equal('block'); + expect(image.printImage.style.margin).to.equal('0px auto'); + expect(stubs.focus).to.be.called; + }); - expect(image.controls).to.not.be.undefined; - expect(image.controls.buttonRefs.length).to.equal(5); - }); - }); + it('should execute the print command if the browser is Explorer', () => { + stubs.getName.returns('Explorer'); - describe('print()', () => { - beforeEach(() => { - stubs.mockIframe = util.openContentInsideIframe(image.imageEl.outerHTML); - stubs.focus = sandbox.stub(stubs.mockIframe.contentWindow, 'focus'); - stubs.execCommand = sandbox.stub(stubs.mockIframe.contentWindow.document, 'execCommand'); - stubs.print = sandbox.stub(stubs.mockIframe.contentWindow, 'print'); + image.print(); + expect(stubs.execCommand).to.be.calledWith('print', false, null); + }); - stubs.openContentInsideIframe = sandbox.stub(util, 'openContentInsideIframe').returns(stubs.mockIframe); - stubs.getName = sandbox.stub(Browser, 'getName'); - }); + it('should execute the print command if the browser is Edge', () => { + stubs.getName.returns('Edge'); - it('should open the content inside an iframe, center, and focus', () => { - image.print(); - expect(stubs.openContentInsideIframe).to.be.called; - expect(image.printImage.style.display).to.equal('block'); - expect(image.printImage.style.margin).to.equal('0px auto'); - expect(stubs.focus).to.be.called; - }); + image.print(); + expect(stubs.execCommand).to.be.calledWith('print', false, null); + }); - it('should execute the print command if the browser is Explorer', () => { - stubs.getName.returns('Explorer'); + it('should call the contentWindow print for other browsers', () => { + stubs.getName.returns('Chrome'); - image.print(); - expect(stubs.execCommand).to.be.calledWith('print', false, null); + image.print(); + expect(stubs.print).to.be.called; + }); }); - it('should execute the print command if the browser is Edge', () => { - stubs.getName.returns('Edge'); + describe('isRotated()', () => { + it('should return false if image is not rotated', () => { + const result = image.isRotated(); + expect(result).to.be.false; + }); - image.print(); - expect(stubs.execCommand).to.be.calledWith('print', false, null); + it('should return true if image is rotated', () => { + image.currentRotationAngle = 90; + const result = image.isRotated(); + expect(result).to.be.true; + }); }); - it('should call the contentWindow print for other browsers', () => { - stubs.getName.returns('Chrome'); + describe('adjustImageZoomPadding()', () => { + beforeEach(() => { + // Set wrapper dimensions + image.wrapperEl.style.height = '200px'; + image.wrapperEl.style.width = '100px'; - image.print(); - expect(stubs.print).to.be.called; - }); - }); + // Set image dimensions + image.imageEl.style.height = '50px'; + image.imageEl.style.width = '25px'; + }); - describe('isRotated()', () => { - it('should return false if image is not rotated', () => { - const result = image.isRotated(); - expect(result).to.be.false; - }); + it('should adjust zoom padding accordingly if image is rotated', () => { + stubs.rotated = sandbox.stub(image, 'isRotated').returns(true); + image.adjustImageZoomPadding(); + expect(stubs.rotated).to.be.called; + expect(image.imageEl.style.left).to.equal('37.5px'); + expect(image.imageEl.style.top).to.equal('75px'); + }); - it('should return true if image is rotated', () => { - image.currentRotationAngle = 90; - const result = image.isRotated(); - expect(result).to.be.true; + it('should adjust zoom padding accordingly if image is not rotated', () => { + image.adjustImageZoomPadding(); + expect(image.imageEl.style.left).to.equal('37.5px'); + expect(image.imageEl.style.top).to.equal('75px'); + }); }); - }); - - describe('adjustImageZoomPadding()', () => { - beforeEach(() => { - // Set wrapper dimensions - image.wrapperEl.style.height = '200px'; - image.wrapperEl.style.width = '100px'; - // Set image dimensions - image.imageEl.style.height = '50px'; - image.imageEl.style.width = '25px'; - }); + describe('bindDOMListeners()', () => { + beforeEach(() => { + image.isMobile = true; + image.imageEl.addEventListener = sandbox.stub(); + stubs.listeners = image.imageEl.addEventListener; + }); - it('should adjust zoom padding accordingly if image is rotated', () => { - stubs.rotated = sandbox.stub(image, 'isRotated').returns(true); - image.adjustImageZoomPadding(); - expect(stubs.rotated).to.be.called; - expect(image.imageEl.style.left).to.equal('37.5px'); - expect(image.imageEl.style.top).to.equal('75px'); + it('should bind all mobile listeners', () => { + sandbox.stub(Browser, 'isIOS').returns(true); + image.bindDOMListeners(); + expect(stubs.listeners).to.have.been.calledWith('orientationchange', image.handleOrientationChange); + }); }); - it('should adjust zoom padding accordingly if image is not rotated', () => { - image.adjustImageZoomPadding(); - expect(image.imageEl.style.left).to.equal('37.5px'); - expect(image.imageEl.style.top).to.equal('75px'); - }); - }); + describe('unbindDOMListeners()', () => { + beforeEach(() => { + stubs.removeEventListener = sandbox.stub(document, 'removeEventListener'); + image.imageEl.removeEventListener = sandbox.stub(); + image.isMobile = true; + stubs.listeners = image.imageEl.removeEventListener; + }); - describe('bindDOMListeners()', () => { - beforeEach(() => { - image.isMobile = true; - image.imageEl.addEventListener = sandbox.stub(); - stubs.listeners = image.imageEl.addEventListener; - }); + it('should unbind all default image listeners', () => { + image.unbindDOMListeners(); + expect(stubs.listeners).to.have.been.calledWith('load', image.finishLoading); + expect(stubs.listeners).to.have.been.calledWith('error', image.errorHandler); + }); - it('should bind all mobile listeners', () => { - sandbox.stub(Browser, 'isIOS').returns(true); - image.bindDOMListeners(); - expect(stubs.listeners).to.have.been.calledWith('orientationchange', image.handleOrientationChange); + it('should unbind all mobile listeners', () => { + sandbox.stub(Browser, 'isIOS').returns(true); + image.unbindDOMListeners(); + expect(stubs.listeners).to.have.been.calledWith('orientationchange', image.handleOrientationChange); + }); }); - }); - describe('unbindDOMListeners()', () => { - beforeEach(() => { - stubs.removeEventListener = sandbox.stub(document, 'removeEventListener'); - image.imageEl.removeEventListener = sandbox.stub(); - image.isMobile = true; - stubs.listeners = image.imageEl.removeEventListener; - }); + describe('handleMouseUp()', () => { + beforeEach(() => { + stubs.pan = sandbox.stub(image, 'stopPanning'); + stubs.zoom = sandbox.stub(image, 'zoom'); + image.isPanning = false; + }); - it('should unbind all default image listeners', () => { - image.unbindDOMListeners(); - expect(stubs.listeners).to.have.been.calledWith('load', image.finishLoading); - expect(stubs.listeners).to.have.been.calledWith('error', image.errorHandler); - }); + it('should do nothing if incorrect click type', () => { + const event = { + button: 3, + ctrlKey: null, + metaKey: null, + clientX: 1, + clientY: 1, + preventDefault: sandbox.stub() + }; + image.handleMouseUp(event); + event.button = 1; + event.ctrlKey = 'blah'; + image.handleMouseUp(event); + event.ctrlKey = null; + event.metaKey = 'blah'; + image.handleMouseUp(event); + expect(stubs.zoom).to.not.be.called; + }); - it('should unbind all mobile listeners', () => { - sandbox.stub(Browser, 'isIOS').returns(true); - image.unbindDOMListeners(); - expect(stubs.listeners).to.have.been.calledWith('orientationchange', image.handleOrientationChange); - }); - }); + it('should zoom in if zoomable but not pannable', () => { + const event = { + button: 1, + ctrlKey: null, + metaKey: null, + clientX: 1, + clientY: 1, + preventDefault: sandbox.stub() + }; + image.isZoomable = true; + image.handleMouseUp(event); + expect(stubs.zoom).to.be.calledWith('in'); + }); - describe('handleMouseUp()', () => { - beforeEach(() => { - stubs.pan = sandbox.stub(image, 'stopPanning'); - stubs.zoom = sandbox.stub(image, 'zoom'); - image.isPanning = false; - }); + it('should reset zoom if mouseup was not due to end of panning', () => { + const event = { + button: 1, + ctrlKey: null, + metaKey: null, + clientX: 1, + clientY: 1, + preventDefault: sandbox.stub() + }; + image.isZoomable = false; + image.didPan = false; + image.handleMouseUp(event); + expect(stubs.zoom).to.be.calledWith('reset'); + }); - it('should do nothing if incorrect click type', () => { - const event = { - button: 3, - ctrlKey: null, - metaKey: null, - clientX: 1, - clientY: 1, - preventDefault: sandbox.stub() - }; - image.handleMouseUp(event); - event.button = 1; - event.ctrlKey = 'blah'; - image.handleMouseUp(event); - event.ctrlKey = null; - event.metaKey = 'blah'; - image.handleMouseUp(event); - expect(stubs.zoom).to.not.be.called; + it('should not zoom if mouse up was due to end of panning', () => { + const event = { + button: 1, + ctrlKey: null, + metaKey: null, + clientX: 1, + clientY: 1, + preventDefault: sandbox.stub() + }; + image.isZoomable = false; + image.didPan = true; + image.handleMouseUp(event); + expect(stubs.zoom).to.not.be.called; + }); }); - it('should zoom in if zoomable but not pannable', () => { - const event = { - button: 1, - ctrlKey: null, - metaKey: null, - clientX: 1, - clientY: 1, - preventDefault: sandbox.stub() - }; - image.isZoomable = true; - image.handleMouseUp(event); - expect(stubs.zoom).to.be.calledWith('in'); + describe('handleOrientationChange()', () => { + it('should adjust zoom padding and set scale', () => { + stubs.padding = sandbox.stub(image, 'adjustImageZoomPadding'); + sandbox.stub(image, 'emit'); + image.handleOrientationChange(); + expect(stubs.padding).to.be.called; + expect(image.emit).to.be.calledWith('scale', { + scale: sinon.match.any, + rotationAngle: sinon.match.number + }); + }); }); - it('should reset zoom if mouseup was not due to end of panning', () => { - const event = { - button: 1, - ctrlKey: null, - metaKey: null, - clientX: 1, - clientY: 1, - preventDefault: sandbox.stub() - }; - image.isZoomable = false; - image.didPan = false; - image.handleMouseUp(event); - expect(stubs.zoom).to.be.calledWith('reset'); - }); + describe('setOriginalImageSize()', () => { + it('should use the naturalHeight and naturalWidth when available', (done) => { + const imageEl = { + naturalWidth: 100, + naturalHeight: 100, + setAttribute: (name, value) => { + imageEl[name] = value; + }, + getAttribute: (name) => imageEl[name] + }; + + const promise = image.setOriginalImageSize(imageEl); + promise.should.be.fulfilled.then(() => { + expect(imageEl.getAttribute('originalWidth')).to.equal(imageEl.naturalWidth); + expect(imageEl.getAttribute('originalHeight')).to.equal(imageEl.naturalHeight); + done(); + }).catch(() => { + Assert.fail(); + }); + }); - it('should not zoom if mouse up was due to end of panning', () => { - const event = { - button: 1, - ctrlKey: null, - metaKey: null, - clientX: 1, - clientY: 1, - preventDefault: sandbox.stub() - }; - image.isZoomable = false; - image.didPan = true; - image.handleMouseUp(event); - expect(stubs.zoom).to.not.be.called; - }); - }); + it('should default to 300x150 when naturalHeight and naturalWidth are 0x0', (done) => { + const imageEl = { + naturalWidth: 0, + naturalHeight: 0, + setAttribute: (name, value) => { + imageEl[name] = value; + }, + getAttribute: (name) => imageEl[name] + }; + + const getStub = sandbox.stub(util, 'get').returns(Promise.resolve('not real a image')); + const promise = image.setOriginalImageSize(imageEl); + promise.should.be.fulfilled.then(() => { + expect(imageEl.getAttribute('originalWidth')).to.equal(300); + expect(imageEl.getAttribute('originalHeight')).to.equal(150); + done(); + }).catch(() => { + Assert.fail(); + }); + }); - describe('handleOrientationChange()', () => { - it('should adjust zoom padding and set scale', () => { - stubs.padding = sandbox.stub(image, 'adjustImageZoomPadding'); - sandbox.stub(image, 'emit'); - image.handleOrientationChange(); - expect(stubs.padding).to.be.called; - expect(image.emit).to.be.calledWith('scale', { - scale: sinon.match.any, - rotationAngle: sinon.match.number + it('should resolve when the get call fails', (done) => { + const imageEl = {}; + const getStub = sandbox.stub(util, 'get').returns(Promise.reject()); + const promise = image.setOriginalImageSize(imageEl); + promise.should.be.fulfilled.then(() => { + Assert.fail(); + }).catch(() => { + done(); + }); }); }); });