github.com/hernad/nomad@v1.6.112/ui/tests/unit/adapters/volume-test.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 import { next } from '@ember/runloop'; 7 import { settled } from '@ember/test-helpers'; 8 import { setupTest } from 'ember-qunit'; 9 import { module, test } from 'qunit'; 10 import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; 11 import { AbortController } from 'fetch'; 12 13 module('Unit | Adapter | Volume', function (hooks) { 14 setupTest(hooks); 15 16 hooks.beforeEach(async function () { 17 this.store = this.owner.lookup('service:store'); 18 this.subject = () => this.store.adapterFor('volume'); 19 20 window.sessionStorage.clear(); 21 window.localStorage.clear(); 22 23 this.server = startMirage(); 24 25 this.initializeUI = async () => { 26 this.server.create('namespace'); 27 this.server.create('namespace', { id: 'some-namespace' }); 28 this.server.create('node-pool'); 29 this.server.create('node'); 30 this.server.create('job', { id: 'job-1', namespaceId: 'default' }); 31 this.server.create('csi-plugin', 2); 32 this.server.create('csi-volume', { 33 id: 'volume-1', 34 namespaceId: 'some-namespace', 35 }); 36 37 this.server.create('region', { id: 'region-1' }); 38 this.server.create('region', { id: 'region-2' }); 39 40 this.system = this.owner.lookup('service:system'); 41 42 // Namespace, default region, and all regions are requests that all 43 // job requests depend on. Fetching them ahead of time means testing 44 // job adapter behavior in isolation. 45 await this.system.get('namespaces'); 46 this.system.get('shouldIncludeRegion'); 47 await this.system.get('defaultRegion'); 48 49 // Reset the handledRequests array to avoid accounting for this 50 // namespaces request everywhere. 51 this.server.pretender.handledRequests.length = 0; 52 }; 53 }); 54 55 hooks.afterEach(function () { 56 this.server.shutdown(); 57 }); 58 59 test('The volume endpoint can be queried by type', async function (assert) { 60 const { pretender } = this.server; 61 62 await this.initializeUI(); 63 64 this.subject().query( 65 this.store, 66 { modelName: 'volume' }, 67 { type: 'csi' }, 68 null, 69 {} 70 ); 71 await settled(); 72 73 assert.deepEqual(pretender.handledRequests.mapBy('url'), [ 74 '/v1/volumes?type=csi', 75 ]); 76 }); 77 78 test('When the volume has a namespace other than default, it is in the URL', async function (assert) { 79 const { pretender } = this.server; 80 const volumeName = 'csi/volume-1'; 81 const volumeNamespace = 'some-namespace'; 82 const volumeId = JSON.stringify([volumeName, volumeNamespace]); 83 84 await this.initializeUI(); 85 86 this.subject().findRecord(this.store, { modelName: 'volume' }, volumeId); 87 await settled(); 88 89 assert.deepEqual(pretender.handledRequests.mapBy('url'), [ 90 `/v1/volume/${encodeURIComponent( 91 volumeName 92 )}?namespace=${volumeNamespace}`, 93 ]); 94 }); 95 96 test('query can be watched', async function (assert) { 97 await this.initializeUI(); 98 99 const { pretender } = this.server; 100 101 const request = () => 102 this.subject().query( 103 this.store, 104 { modelName: 'volume' }, 105 { type: 'csi' }, 106 null, 107 { 108 reload: true, 109 adapterOptions: { watch: true }, 110 } 111 ); 112 113 request(); 114 assert.equal( 115 pretender.handledRequests[0].url, 116 '/v1/volumes?type=csi&index=1' 117 ); 118 119 await settled(); 120 request(); 121 assert.equal( 122 pretender.handledRequests[1].url, 123 '/v1/volumes?type=csi&index=2' 124 ); 125 126 await settled(); 127 }); 128 129 test('query can be canceled', async function (assert) { 130 await this.initializeUI(); 131 132 const { pretender } = this.server; 133 const controller = new AbortController(); 134 135 pretender.get('/v1/volumes', () => [200, {}, '[]'], true); 136 137 this.subject() 138 .query(this.store, { modelName: 'volume' }, { type: 'csi' }, null, { 139 reload: true, 140 adapterOptions: { watch: true, abortController: controller }, 141 }) 142 .catch(() => {}); 143 144 const { request: xhr } = pretender.requestReferences[0]; 145 assert.equal(xhr.status, 0, 'Request is still pending'); 146 147 // Schedule the cancelation before waiting 148 next(() => { 149 controller.abort(); 150 }); 151 152 await settled(); 153 assert.ok(xhr.aborted, 'Request was aborted'); 154 }); 155 156 test('query and findAll have distinct watchList entries', async function (assert) { 157 await this.initializeUI(); 158 159 const { pretender } = this.server; 160 161 const request = () => 162 this.subject().query( 163 this.store, 164 { modelName: 'volume' }, 165 { type: 'csi' }, 166 null, 167 { 168 reload: true, 169 adapterOptions: { watch: true }, 170 } 171 ); 172 173 const findAllRequest = () => 174 this.subject().findAll(null, { modelName: 'volume' }, null, { 175 reload: true, 176 adapterOptions: { watch: true }, 177 }); 178 179 request(); 180 assert.equal( 181 pretender.handledRequests[0].url, 182 '/v1/volumes?type=csi&index=1' 183 ); 184 185 await settled(); 186 request(); 187 assert.equal( 188 pretender.handledRequests[1].url, 189 '/v1/volumes?type=csi&index=2' 190 ); 191 192 await settled(); 193 findAllRequest(); 194 assert.equal(pretender.handledRequests[2].url, '/v1/volumes?index=1'); 195 }); 196 });