github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/tests/integration/components/attributes-table-test.js (about) 1 import { find, findAll, render } from '@ember/test-helpers'; 2 import { module, test } from 'qunit'; 3 import { setupRenderingTest } from 'ember-qunit'; 4 import hbs from 'htmlbars-inline-precompile'; 5 import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit'; 6 import flat from 'flat'; 7 8 const { flatten } = flat; 9 10 module('Integration | Component | attributes table', function (hooks) { 11 setupRenderingTest(hooks); 12 13 const commonAttributes = { 14 key: 'value', 15 nested: { 16 props: 'are', 17 supported: 'just', 18 fine: null, 19 }, 20 so: { 21 are: { 22 deeply: { 23 nested: 'properties', 24 like: 'these ones', 25 }, 26 }, 27 }, 28 }; 29 30 test('should render a row for each key/value pair in a deep object', async function (assert) { 31 assert.expect(2); 32 33 this.set('attributes', commonAttributes); 34 await render(hbs`<AttributesTable @attributePairs={{attributes}} />`); 35 36 const rowsCount = Object.keys(flatten(commonAttributes)).length; 37 assert.equal( 38 this.element.querySelectorAll( 39 '[data-test-attributes-section] [data-test-value]' 40 ).length, 41 rowsCount, 42 `Table has ${rowsCount} rows with values` 43 ); 44 45 await componentA11yAudit(this.element, assert); 46 }); 47 48 test('should render the full path of key/value pair from the root of the object', async function (assert) { 49 this.set('attributes', commonAttributes); 50 await render(hbs`<AttributesTable @attributePairs={{attributes}} />`); 51 52 assert.equal( 53 find('[data-test-key]').textContent.trim(), 54 'key', 55 'Row renders the key' 56 ); 57 assert.equal( 58 find('[data-test-value]').textContent.trim(), 59 'value', 60 'Row renders the value' 61 ); 62 63 const deepRow = findAll('[data-test-attributes-section]')[8]; 64 assert.equal( 65 deepRow.querySelector('[data-test-key]').textContent.trim(), 66 'so.are.deeply.nested', 67 'Complex row renders the full path to the key' 68 ); 69 assert.equal( 70 deepRow.querySelector('[data-test-prefix]').textContent.trim(), 71 'so.are.deeply.', 72 'The prefix is faded to put emphasis on the attribute' 73 ); 74 assert.equal( 75 deepRow.querySelector('[data-test-value]').textContent.trim(), 76 'properties' 77 ); 78 }); 79 80 test('should render a row for key/value pairs even when the value is another object', async function (assert) { 81 this.set('attributes', commonAttributes); 82 await render(hbs`<AttributesTable @attributePairs={{attributes}} />`); 83 84 const countOfParentRows = countOfParentKeys(commonAttributes); 85 assert.equal( 86 findAll('[data-test-heading]').length, 87 countOfParentRows, 88 'Each key for a nested object gets a row with no value' 89 ); 90 }); 91 92 function countOfParentKeys(obj) { 93 return Object.keys(obj).reduce((count, key) => { 94 const value = obj[key]; 95 return isObject(value) ? count + 1 + countOfParentKeys(value) : count; 96 }, 0); 97 } 98 99 function isObject(value) { 100 return !Array.isArray(value) && value != null && typeof value === 'object'; 101 } 102 });