github.com/hernad/nomad@v1.6.112/ui/tests/integration/components/image-file-test.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 import { find, render } from '@ember/test-helpers'; 7 import { module, test } from 'qunit'; 8 import { setupRenderingTest } from 'ember-qunit'; 9 import hbs from 'htmlbars-inline-precompile'; 10 import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit'; 11 import sinon from 'sinon'; 12 import RSVP from 'rsvp'; 13 import { formatBytes } from 'nomad-ui/utils/units'; 14 15 module('Integration | Component | image file', function (hooks) { 16 setupRenderingTest(hooks); 17 18 const commonTemplate = hbs` 19 <ImageFile @src={{src}} @alt={{alt}} @size={{size}} /> 20 `; 21 22 const commonProperties = { 23 src: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 24 alt: 'This is the alt text', 25 size: 123456, 26 }; 27 28 test('component displays the image', async function (assert) { 29 assert.expect(3); 30 31 this.setProperties(commonProperties); 32 33 await render(commonTemplate); 34 35 assert.ok(find('img'), 'Image is in the DOM'); 36 assert.equal( 37 find('img').getAttribute('src'), 38 commonProperties.src, 39 `src is ${commonProperties.src}` 40 ); 41 42 await componentA11yAudit(this.element, assert); 43 }); 44 45 test('the image is wrapped in an anchor that links directly to the image', async function (assert) { 46 this.setProperties(commonProperties); 47 48 await render(commonTemplate); 49 50 assert.ok(find('a'), 'Anchor'); 51 assert.ok(find('a > img'), 'Image in anchor'); 52 assert.equal( 53 find('a').getAttribute('href'), 54 commonProperties.src, 55 `href is ${commonProperties.src}` 56 ); 57 assert.equal( 58 find('a').getAttribute('target'), 59 '_blank', 60 'Anchor opens to a new tab' 61 ); 62 assert.equal( 63 find('a').getAttribute('rel'), 64 'noopener noreferrer', 65 'Anchor rel correctly bars openers and referrers' 66 ); 67 }); 68 69 test('component updates image meta when the image loads', async function (assert) { 70 const { spy, wrapper, notifier } = notifyingSpy(); 71 72 this.setProperties(commonProperties); 73 this.set('spy', wrapper); 74 75 render(hbs` 76 <ImageFile @src={{src}} @alt={{alt}} @size={{size}} @updateImageMeta={{spy}} /> 77 `); 78 79 await notifier; 80 assert.ok(spy.calledOnce); 81 }); 82 83 test('component shows the width, height, and size of the image', async function (assert) { 84 this.setProperties(commonProperties); 85 86 await render(commonTemplate); 87 88 const statsEl = find('[data-test-file-stats]'); 89 assert.ok( 90 /\d+px \u00d7 \d+px/.test(statsEl.textContent), 91 'Width and height are formatted correctly' 92 ); 93 assert.ok( 94 statsEl.textContent 95 .trim() 96 .endsWith(formatBytes(commonProperties.size) + ')'), 97 'Human-formatted size is included' 98 ); 99 }); 100 }); 101 102 function notifyingSpy() { 103 // The notifier must resolve when the spy wrapper is called 104 let dispatch; 105 const notifier = new RSVP.Promise((resolve) => { 106 dispatch = resolve; 107 }); 108 109 const spy = sinon.spy(); 110 111 // The spy wrapper must call the spy, passing all arguments through, and it must 112 // call dispatch in order to resolve the promise. 113 const wrapper = (...args) => { 114 spy(...args); 115 dispatch(); 116 }; 117 118 // All three pieces are required to wire up a component, pause test execution, and 119 // write assertions. 120 return { spy, wrapper, notifier }; 121 }