github.com/hernad/nomad@v1.6.112/ui/tests/integration/components/task-group-row-test.js (about)

     1  /**
     2   * Copyright (c) HashiCorp, Inc.
     3   * SPDX-License-Identifier: MPL-2.0
     4   */
     5  
     6  import { module, test } from 'qunit';
     7  import { setupRenderingTest } from 'ember-qunit';
     8  import { click, find, render, settled, waitUntil } from '@ember/test-helpers';
     9  import hbs from 'htmlbars-inline-precompile';
    10  import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
    11  import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer';
    12  import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
    13  
    14  const jobName = 'test-job';
    15  const jobId = JSON.stringify([jobName, 'default']);
    16  
    17  const countChange = () => {
    18    const initial = find('[data-test-task-group-count]').textContent;
    19    return () => find('[data-test-task-group-count]').textContent !== initial;
    20  };
    21  
    22  let managementToken;
    23  let clientToken;
    24  
    25  const makeJob = (server, props = {}) => {
    26    // These tests require a job with particular task groups. This requires
    27    // mild Mirage surgery.
    28    const job = server.create('job', {
    29      id: jobName,
    30      groupCount: 0,
    31      createAllocations: false,
    32      shallow: true,
    33      ...props,
    34    });
    35    const noScalingGroup = server.create('task-group', {
    36      job,
    37      name: 'no-scaling',
    38      shallow: true,
    39      withScaling: false,
    40    });
    41    const scalingGroup = server.create('task-group', {
    42      job,
    43      count: 2,
    44      name: 'scaling',
    45      shallow: true,
    46      withScaling: true,
    47    });
    48    job.update({
    49      taskGroupIds: [noScalingGroup.id, scalingGroup.id],
    50    });
    51  };
    52  
    53  module('Integration | Component | task group row', function (hooks) {
    54    setupRenderingTest(hooks);
    55  
    56    hooks.beforeEach(async function () {
    57      fragmentSerializerInitializer(this.owner);
    58      this.store = this.owner.lookup('service:store');
    59      this.token = this.owner.lookup('service:token');
    60      this.server = startMirage();
    61      this.server.create('node-pool');
    62      this.server.create('node');
    63  
    64      managementToken = this.server.create('token');
    65      clientToken = this.server.create('token');
    66      window.localStorage.nomadTokenSecret = managementToken.secretId;
    67    });
    68  
    69    hooks.afterEach(function () {
    70      this.server.shutdown();
    71      window.localStorage.clear();
    72    });
    73  
    74    const commonTemplate = hbs`
    75      <TaskGroupRow @taskGroup={{group}} />
    76    `;
    77  
    78    test('Task group row conditionally shows scaling buttons based on the presence of the scaling attr on the task group', async function (assert) {
    79      assert.expect(3);
    80  
    81      makeJob(this.server, { noActiveDeployment: true });
    82      this.token.fetchSelfTokenAndPolicies.perform();
    83      await settled();
    84  
    85      const job = await this.store.find('job', jobId);
    86      this.set('group', job.taskGroups.findBy('name', 'no-scaling'));
    87  
    88      await render(commonTemplate);
    89      assert.notOk(find('[data-test-scale]'));
    90  
    91      this.set('group', job.taskGroups.findBy('name', 'scaling'));
    92  
    93      await settled();
    94      assert.ok(find('[data-test-scale]'));
    95  
    96      await componentA11yAudit(this.element, assert);
    97    });
    98  
    99    test('Clicking scaling buttons immediately updates the rendered count but debounces the scaling API request', async function (assert) {
   100      makeJob(this.server, { noActiveDeployment: true });
   101      this.token.fetchSelfTokenAndPolicies.perform();
   102      await settled();
   103  
   104      const job = await this.store.find('job', jobId);
   105      this.set('group', job.taskGroups.findBy('name', 'scaling'));
   106  
   107      await render(commonTemplate);
   108      assert.equal(find('[data-test-task-group-count]').textContent, 2);
   109  
   110      click('[data-test-scale="increment"]');
   111      await waitUntil(countChange());
   112      assert.equal(find('[data-test-task-group-count]').textContent, 3);
   113  
   114      click('[data-test-scale="increment"]');
   115      await waitUntil(countChange());
   116      assert.equal(find('[data-test-task-group-count]').textContent, 4);
   117  
   118      assert.notOk(
   119        server.pretender.handledRequests.find(
   120          (req) => req.method === 'POST' && req.url.endsWith('/scale')
   121        )
   122      );
   123  
   124      await settled();
   125      const scaleRequests = server.pretender.handledRequests.filter(
   126        (req) => req.method === 'POST' && req.url.endsWith('/scale')
   127      );
   128      assert.equal(scaleRequests.length, 1);
   129      assert.equal(JSON.parse(scaleRequests[0].requestBody).Count, 4);
   130    });
   131  
   132    test('When the current count is equal to the max count, the increment count button is disabled', async function (assert) {
   133      assert.expect(2);
   134  
   135      makeJob(this.server, { noActiveDeployment: true });
   136      this.token.fetchSelfTokenAndPolicies.perform();
   137      await settled();
   138  
   139      const job = await this.store.find('job', jobId);
   140      const group = job.taskGroups.findBy('name', 'scaling');
   141      group.set('count', group.scaling.max);
   142      this.set('group', group);
   143  
   144      await render(commonTemplate);
   145      assert.ok(find('[data-test-scale="increment"]:disabled'));
   146  
   147      await componentA11yAudit(this.element, assert);
   148    });
   149  
   150    test('When the current count is equal to the min count, the decrement count button is disabled', async function (assert) {
   151      assert.expect(2);
   152  
   153      makeJob(this.server, { noActiveDeployment: true });
   154      this.token.fetchSelfTokenAndPolicies.perform();
   155      await settled();
   156  
   157      const job = await this.store.find('job', jobId);
   158      const group = job.taskGroups.findBy('name', 'scaling');
   159      group.set('count', group.scaling.min);
   160      this.set('group', group);
   161  
   162      await render(commonTemplate);
   163      assert.ok(find('[data-test-scale="decrement"]:disabled'));
   164  
   165      await componentA11yAudit(this.element, assert);
   166    });
   167  
   168    test('When there is an active deployment, both scale buttons are disabled', async function (assert) {
   169      assert.expect(3);
   170  
   171      makeJob(this.server, { activeDeployment: true });
   172      this.token.fetchSelfTokenAndPolicies.perform();
   173      await settled();
   174  
   175      const job = await this.store.find('job', jobId);
   176      this.set('group', job.taskGroups.findBy('name', 'scaling'));
   177  
   178      await render(commonTemplate);
   179      assert.ok(find('[data-test-scale="increment"]:disabled'));
   180      assert.ok(find('[data-test-scale="decrement"]:disabled'));
   181  
   182      await componentA11yAudit(this.element, assert);
   183    });
   184  
   185    test('When the current ACL token does not have the namespace:scale-job or namespace:submit-job policy rule', async function (assert) {
   186      makeJob(this.server, { noActiveDeployment: true });
   187      window.localStorage.nomadTokenSecret = clientToken.secretId;
   188      this.token.fetchSelfTokenAndPolicies.perform();
   189      await settled();
   190  
   191      const job = await this.store.find('job', jobId);
   192      this.set('group', job.taskGroups.findBy('name', 'scaling'));
   193  
   194      await render(commonTemplate);
   195      assert.ok(find('[data-test-scale="increment"]:disabled'));
   196      assert.ok(find('[data-test-scale="decrement"]:disabled'));
   197      assert.ok(
   198        find('[data-test-scale-controls]')
   199          .getAttribute('aria-label')
   200          .includes("You aren't allowed")
   201      );
   202    });
   203  });