github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/ui/tests/integration/job-page/service-test.js (about)

     1  import { assign } from '@ember/polyfills';
     2  import { module, test } from 'qunit';
     3  import { setupRenderingTest } from 'ember-qunit';
     4  import { render, settled } from '@ember/test-helpers';
     5  import { click, find } from 'ember-native-dom-helpers';
     6  import hbs from 'htmlbars-inline-precompile';
     7  import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
     8  import { startJob, stopJob, expectError, expectDeleteRequest, expectStartRequest } from './helpers';
     9  import Job from 'nomad-ui/tests/pages/jobs/detail';
    10  import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer';
    11  
    12  module('Integration | Component | job-page/service', function(hooks) {
    13    setupRenderingTest(hooks);
    14  
    15    hooks.beforeEach(function() {
    16      Job.setContext(this);
    17      fragmentSerializerInitializer(this.owner);
    18      window.localStorage.clear();
    19      this.store = this.owner.lookup('service:store');
    20      this.server = startMirage();
    21      this.server.create('namespace');
    22    });
    23  
    24    hooks.afterEach(function() {
    25      Job.removeContext();
    26      this.server.shutdown();
    27      window.localStorage.clear();
    28    });
    29  
    30    const commonTemplate = hbs`
    31      {{job-page/service
    32        job=job
    33        sortProperty=sortProperty
    34        sortDescending=sortDescending
    35        currentPage=currentPage
    36        gotoJob=gotoJob}}
    37    `;
    38  
    39    const commonProperties = job => ({
    40      job,
    41      sortProperty: 'name',
    42      sortDescending: true,
    43      currentPage: 1,
    44      gotoJob() {},
    45    });
    46  
    47    const makeMirageJob = (server, props = {}) =>
    48      server.create(
    49        'job',
    50        assign(
    51          {
    52            type: 'service',
    53            createAllocations: false,
    54            status: 'running',
    55          },
    56          props
    57        )
    58      );
    59  
    60    test('Stopping a job sends a delete request for the job', function(assert) {
    61      let job;
    62  
    63      const mirageJob = makeMirageJob(this.server);
    64      this.store.findAll('job');
    65  
    66      return settled()
    67        .then(async () => {
    68          job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
    69  
    70          this.setProperties(commonProperties(job));
    71          await render(commonTemplate);
    72  
    73          return settled();
    74        })
    75        .then(stopJob)
    76        .then(() => expectDeleteRequest(assert, this.server, job));
    77    });
    78  
    79    test('Stopping a job without proper permissions shows an error message', function(assert) {
    80      this.server.pretender.delete('/v1/job/:id', () => [403, {}, null]);
    81  
    82      const mirageJob = makeMirageJob(this.server);
    83      this.store.findAll('job');
    84  
    85      return settled()
    86        .then(async () => {
    87          const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
    88  
    89          this.setProperties(commonProperties(job));
    90          await render(commonTemplate);
    91  
    92          return settled();
    93        })
    94        .then(stopJob)
    95        .then(expectError(assert, 'Could Not Stop Job'));
    96    });
    97  
    98    test('Starting a job sends a post request for the job using the current definition', function(assert) {
    99      let job;
   100  
   101      const mirageJob = makeMirageJob(this.server, { status: 'dead' });
   102      this.store.findAll('job');
   103  
   104      return settled()
   105        .then(async () => {
   106          job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
   107  
   108          this.setProperties(commonProperties(job));
   109          await render(commonTemplate);
   110  
   111          return settled();
   112        })
   113        .then(startJob)
   114        .then(() => expectStartRequest(assert, this.server, job));
   115    });
   116  
   117    test('Starting a job without proper permissions shows an error message', function(assert) {
   118      this.server.pretender.post('/v1/job/:id', () => [403, {}, null]);
   119  
   120      const mirageJob = makeMirageJob(this.server, { status: 'dead' });
   121      this.store.findAll('job');
   122  
   123      return settled()
   124        .then(async () => {
   125          const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
   126  
   127          this.setProperties(commonProperties(job));
   128          await render(commonTemplate);
   129  
   130          return settled();
   131        })
   132        .then(startJob)
   133        .then(expectError(assert, 'Could Not Start Job'));
   134    });
   135  
   136    test('Recent allocations shows allocations in the job context', function(assert) {
   137      let job;
   138  
   139      this.server.create('node');
   140      const mirageJob = makeMirageJob(this.server, { createAllocations: true });
   141      this.store.findAll('job');
   142  
   143      return settled()
   144        .then(async () => {
   145          job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
   146  
   147          this.setProperties(commonProperties(job));
   148          await render(commonTemplate);
   149  
   150          return settled();
   151        })
   152        .then(() => {
   153          const allocation = this.server.db.allocations.sortBy('modifyIndex').reverse()[0];
   154          const allocationRow = Job.allocations.objectAt(0);
   155  
   156          assert.equal(allocationRow.shortId, allocation.id.split('-')[0], 'ID');
   157          assert.equal(allocationRow.taskGroup, allocation.taskGroup, 'Task Group name');
   158        });
   159    });
   160  
   161    test('Recent allocations caps out at five', function(assert) {
   162      let job;
   163  
   164      this.server.create('node');
   165      const mirageJob = makeMirageJob(this.server);
   166      this.server.createList('allocation', 10);
   167  
   168      this.store.findAll('job');
   169  
   170      return settled().then(async () => {
   171        job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
   172  
   173        this.setProperties(commonProperties(job));
   174        await render(commonTemplate);
   175  
   176        return settled().then(() => {
   177          assert.equal(Job.allocations.length, 5, 'Capped at 5 allocations');
   178          assert.ok(
   179            Job.viewAllAllocations.includes(job.get('allocations.length') + ''),
   180            `View link mentions ${job.get('allocations.length')} allocations`
   181          );
   182        });
   183      });
   184    });
   185  
   186    test('Recent allocations shows an empty message when the job has no allocations', function(assert) {
   187      let job;
   188  
   189      this.server.create('node');
   190      const mirageJob = makeMirageJob(this.server);
   191  
   192      this.store.findAll('job');
   193  
   194      return settled()
   195        .then(async () => {
   196          job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
   197  
   198          this.setProperties(commonProperties(job));
   199          await render(commonTemplate);
   200  
   201          return settled();
   202        })
   203        .then(() => {
   204          assert.ok(
   205            Job.recentAllocationsEmptyState.headline.includes('No Allocations'),
   206            'No allocations empty message'
   207          );
   208        });
   209    });
   210  
   211    test('Active deployment can be promoted', function(assert) {
   212      let job;
   213      let deployment;
   214  
   215      this.server.create('node');
   216      const mirageJob = makeMirageJob(this.server, { activeDeployment: true });
   217  
   218      this.store.findAll('job');
   219  
   220      return settled()
   221        .then(async () => {
   222          job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
   223          deployment = job.get('latestDeployment');
   224  
   225          this.setProperties(commonProperties(job));
   226          await render(commonTemplate);
   227  
   228          return settled();
   229        })
   230        .then(() => {
   231          click('[data-test-promote-canary]');
   232          return settled();
   233        })
   234        .then(() => {
   235          const requests = this.server.pretender.handledRequests;
   236          assert.ok(
   237            requests
   238              .filterBy('method', 'POST')
   239              .findBy('url', `/v1/deployment/promote/${deployment.get('id')}`),
   240            'A promote POST request was made'
   241          );
   242        });
   243    });
   244  
   245    test('When promoting the active deployment fails, an error is shown', function(assert) {
   246      this.server.pretender.post('/v1/deployment/promote/:id', () => [403, {}, null]);
   247  
   248      let job;
   249  
   250      this.server.create('node');
   251      const mirageJob = makeMirageJob(this.server, { activeDeployment: true });
   252  
   253      this.store.findAll('job');
   254  
   255      return settled()
   256        .then(async () => {
   257          job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
   258  
   259          this.setProperties(commonProperties(job));
   260          await render(commonTemplate);
   261  
   262          return settled();
   263        })
   264        .then(() => {
   265          click('[data-test-promote-canary]');
   266          return settled();
   267        })
   268        .then(() => {
   269          assert.equal(
   270            find('[data-test-job-error-title]').textContent,
   271            'Could Not Promote Deployment',
   272            'Appropriate error is shown'
   273          );
   274          assert.ok(
   275            find('[data-test-job-error-body]').textContent.includes('ACL'),
   276            'The error message mentions ACLs'
   277          );
   278  
   279          click('[data-test-job-error-close]');
   280          assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
   281          return settled();
   282        });
   283    });
   284  });