github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/tests/integration/components/fs/file-test.js (about)

     1  import { module, test } from 'qunit';
     2  import { setupRenderingTest } from 'ember-qunit';
     3  import { find, click, render, settled } from '@ember/test-helpers';
     4  import hbs from 'htmlbars-inline-precompile';
     5  import Pretender from 'pretender';
     6  import { logEncode } from '../../../../mirage/data/logs';
     7  import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
     8  
     9  const { assign } = Object;
    10  const HOST = '1.1.1.1:1111';
    11  
    12  module('Integration | Component | fs/file', function(hooks) {
    13    setupRenderingTest(hooks);
    14  
    15    hooks.beforeEach(function() {
    16      this.server = new Pretender(function() {
    17        this.get('/v1/agent/members', () => [
    18          200,
    19          {},
    20          JSON.stringify({ ServerRegion: 'default', Members: [] }),
    21        ]);
    22        this.get('/v1/regions', () => [200, {}, JSON.stringify(['default', 'region-2'])]);
    23        this.get('/v1/client/fs/stream/:alloc_id', () => [200, {}, logEncode(['Hello World'], 0)]);
    24        this.get('/v1/client/fs/cat/:alloc_id', () => [200, {}, 'Hello World']);
    25        this.get('/v1/client/fs/readat/:alloc_id', () => [200, {}, 'Hello World']);
    26      });
    27      this.system = this.owner.lookup('service:system');
    28    });
    29  
    30    hooks.afterEach(function() {
    31      this.server.shutdown();
    32      window.localStorage.clear();
    33    });
    34  
    35    const commonTemplate = hbs`
    36      <Fs::File @allocation={{allocation}} @taskState={{taskState}} @file={{file}} @stat={{stat}} />
    37    `;
    38  
    39    const fileStat = (type, size = 0) => ({
    40      stat: {
    41        Size: size,
    42        ContentType: type,
    43      },
    44    });
    45    const makeProps = (props = {}) =>
    46      assign(
    47        {},
    48        {
    49          allocation: {
    50            id: 'alloc-1',
    51            node: {
    52              httpAddr: HOST,
    53            },
    54          },
    55          taskState: {
    56            name: 'task-name',
    57          },
    58          file: 'path/to/file',
    59          stat: {
    60            Size: 12345,
    61            ContentType: 'text/plain',
    62          },
    63        },
    64        props
    65      );
    66  
    67    test('When a file is text-based, the file mode is streaming', async function(assert) {
    68      const props = makeProps(fileStat('text/plain', 500));
    69      this.setProperties(props);
    70  
    71      await render(commonTemplate);
    72  
    73      assert.ok(
    74        find('[data-test-file-box] [data-test-log-cli]'),
    75        'The streaming file component was rendered'
    76      );
    77      assert.notOk(
    78        find('[data-test-file-box] [data-test-image-file]'),
    79        'The image file component was not rendered'
    80      );
    81  
    82      await componentA11yAudit(this.element, assert);
    83    });
    84  
    85    test('When a file is an image, the file mode is image', async function(assert) {
    86      const props = makeProps(fileStat('image/png', 1234));
    87      this.setProperties(props);
    88  
    89      await render(commonTemplate);
    90  
    91      assert.ok(
    92        find('[data-test-file-box] [data-test-image-file]'),
    93        'The image file component was rendered'
    94      );
    95      assert.notOk(
    96        find('[data-test-file-box] [data-test-log-cli]'),
    97        'The streaming file component was not rendered'
    98      );
    99  
   100      await componentA11yAudit(this.element, assert);
   101    });
   102  
   103    test('When the file is neither text-based or an image, the unsupported file type empty state is shown', async function(assert) {
   104      const props = makeProps(fileStat('wat/ohno', 1234));
   105      this.setProperties(props);
   106  
   107      await render(commonTemplate);
   108  
   109      assert.notOk(
   110        find('[data-test-file-box] [data-test-image-file]'),
   111        'The image file component was not rendered'
   112      );
   113      assert.notOk(
   114        find('[data-test-file-box] [data-test-log-cli]'),
   115        'The streaming file component was not rendered'
   116      );
   117      assert.ok(find('[data-test-unsupported-type]'), 'Unsupported file type message is shown');
   118      await componentA11yAudit(this.element, assert);
   119    });
   120  
   121    test('The unsupported file type empty state includes a link to the raw file', async function(assert) {
   122      const props = makeProps(fileStat('wat/ohno', 1234));
   123      this.setProperties(props);
   124  
   125      await render(commonTemplate);
   126  
   127      assert.ok(
   128        find('[data-test-unsupported-type] [data-test-log-action="raw"]'),
   129        'Unsupported file type message includes a link to the raw file'
   130      );
   131  
   132      assert.notOk(
   133        find('[data-test-header] [data-test-log-action="raw"]'),
   134        'Raw link is no longer in the header'
   135      );
   136    });
   137  
   138    test('The view raw button goes to the correct API url', async function(assert) {
   139      const props = makeProps(fileStat('image/png', 1234));
   140      this.setProperties(props);
   141  
   142      await render(commonTemplate);
   143      click('[data-test-log-action="raw"]');
   144      await settled();
   145      assert.ok(
   146        this.server.handledRequests.find(
   147          ({ url: url }) =>
   148            url ===
   149            `/v1/client/fs/cat/${props.allocation.id}?path=${encodeURIComponent(
   150              `${props.taskState.name}/${props.file}`
   151            )}`
   152        ),
   153        'Request to file is made'
   154      );
   155    });
   156  
   157    test('The view raw button respects the active region', async function(assert) {
   158      const region = 'region-2';
   159      window.localStorage.nomadActiveRegion = region;
   160  
   161      const props = makeProps(fileStat('image/png', 1234));
   162      this.setProperties(props);
   163  
   164      await this.system.get('regions');
   165      await render(commonTemplate);
   166  
   167      click('[data-test-log-action="raw"]');
   168      await settled();
   169      assert.ok(
   170        this.server.handledRequests.find(
   171          ({ url: url }) =>
   172            url ===
   173            `/v1/client/fs/cat/${props.allocation.id}?path=${encodeURIComponent(
   174              `${props.taskState.name}/${props.file}`
   175            )}&region=${region}`
   176        ),
   177        'Request to file is made with region'
   178      );
   179    });
   180  
   181    test('The head and tail buttons are not shown when the file is small', async function(assert) {
   182      const props = makeProps(fileStat('application/json', 5000));
   183      this.setProperties(props);
   184  
   185      await render(commonTemplate);
   186  
   187      assert.notOk(find('[data-test-log-action="head"]'), 'No head button');
   188      assert.notOk(find('[data-test-log-action="tail"]'), 'No tail button');
   189  
   190      this.set('stat.Size', 100000);
   191  
   192      await settled();
   193  
   194      assert.ok(find('[data-test-log-action="head"]'), 'Head button is shown');
   195      assert.ok(find('[data-test-log-action="tail"]'), 'Tail button is shown');
   196    });
   197  
   198    test('The  head and tail buttons are not shown for an image file', async function(assert) {
   199      const props = makeProps(fileStat('image/svg', 5000));
   200      this.setProperties(props);
   201  
   202      await render(commonTemplate);
   203  
   204      assert.notOk(find('[data-test-log-action="head"]'), 'No head button');
   205      assert.notOk(find('[data-test-log-action="tail"]'), 'No tail button');
   206  
   207      this.set('stat.Size', 100000);
   208  
   209      await settled();
   210  
   211      assert.notOk(find('[data-test-log-action="head"]'), 'Still no head button');
   212      assert.notOk(find('[data-test-log-action="tail"]'), 'Still no tail button');
   213    });
   214  
   215    test('Yielded content goes in the top-left header area', async function(assert) {
   216      const props = makeProps(fileStat('image/svg', 5000));
   217      this.setProperties(props);
   218  
   219      await render(hbs`
   220        <Fs::File @allocation={{allocation}} @taskState={{taskState}} @file={{file}} @stat={{stat}}>
   221          <div data-test-yield-spy>Yielded content</div>
   222        </Fs::File>
   223      `);
   224  
   225      assert.ok(
   226        find('[data-test-header] [data-test-yield-spy]'),
   227        'Yielded content shows up in the header'
   228      );
   229  
   230      await componentA11yAudit(this.element, assert);
   231    });
   232  
   233    test('The body is full-bleed and dark when the file is streaming', async function(assert) {
   234      const props = makeProps(fileStat('application/json', 5000));
   235      this.setProperties(props);
   236  
   237      await render(commonTemplate);
   238  
   239      const classes = Array.from(find('[data-test-file-box]').classList);
   240      assert.ok(classes.includes('is-dark'), 'Body is dark');
   241      assert.ok(classes.includes('is-full-bleed'), 'Body is full-bleed');
   242    });
   243  
   244    test('The body has padding and a light background when the file is not streaming', async function(assert) {
   245      const props = makeProps(fileStat('image/jpeg', 5000));
   246      this.setProperties(props);
   247  
   248      await render(commonTemplate);
   249  
   250      let classes = Array.from(find('[data-test-file-box]').classList);
   251      assert.notOk(classes.includes('is-dark'), 'Body is not dark');
   252      assert.notOk(classes.includes('is-full-bleed'), 'Body is not full-bleed');
   253  
   254      this.set('stat.ContentType', 'something/unknown');
   255  
   256      await settled();
   257  
   258      classes = Array.from(find('[data-test-file-box]').classList);
   259      assert.notOk(classes.includes('is-dark'), 'Body is still not dark');
   260      assert.notOk(classes.includes('is-full-bleed'), 'Body is still not full-bleed');
   261    });
   262  });