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  });