test('when there is only one region, the region switcher is not shown in the nav bar', async function(assert) { server.create('region', { id: 'global' }); await JobsList.visit(); assert.notOk(PageLayout.navbar.regionSwitcher.isPresent, 'No region switcher'); });
test('the namespace switcher is not in the gutter menu', function(assert) { JobsList.visit(); andThen(() => { assert.notOk(JobsList.namespaceSwitcher.isPresent, 'No namespace switcher found'); }); });
test('changing the namespace refreshes the jobs list when on the jobs page', function(assert) { const namespace = server.db.namespaces[1]; JobsList.visit(); andThen(() => { const requests = server.pretender.handledRequests.filter(req => req.url.startsWith('/v1/jobs')); assert.equal(requests.length, 1, 'First request to jobs'); assert.equal( requests[0].queryParams.namespace, undefined, 'Namespace query param is defaulted to "default"/undefined' ); }); // TODO: handle this with Page Objects selectChoose('[data-test-namespace-switcher]', namespace.name); andThen(() => { const requests = server.pretender.handledRequests.filter(req => req.url.startsWith('/v1/jobs')); assert.equal(requests.length, 2, 'Second request to jobs'); assert.equal( requests[1].queryParams.namespace, namespace.name, 'Namespace query param on second request' ); }); });
test('when the only region is not named "global", the region switcher still is not shown', async function(assert) { server.create('region', { id: 'some-region' }); await JobsList.visit(); assert.notOk(PageLayout.navbar.regionSwitcher.isPresent, 'No region switcher'); });
test('each allocation should show job information even if the job is incomplete and already in the store', function(assert) { // First, visit clients to load the allocations for each visible node. // Don't load the job belongsTo of the allocation! Leave it unfulfilled. Clients.visit(); // Then, visit jobs to load all jobs, which should implicitly fulfill // the job belongsTo of each allocation pointed at each job. Jobs.visit(); // Finally, visit a node to assert that the job name and task group name are // present. This will require reloading the job, since task groups aren't a // part of the jobs list response. ClientDetail.visit({ id: node.id }); andThen(() => { const allocationRow = ClientDetail.allocations.objectAt(0); const allocation = server.db.allocations .where({ nodeId: node.id }) .sortBy('modifyIndex') .reverse()[0]; assert.equal(allocationRow.job, server.db.jobs.find(allocation.jobId).name, 'Job name'); assert.ok(allocationRow.taskGroup.includes(allocation.taskGroup), 'Task group name'); }); });
test('the jobs request is made with no query params', function(assert) { JobsList.visit(); andThen(() => { const request = server.pretender.handledRequests.findBy('url', '/v1/jobs'); assert.equal(request.queryParams.namespace, undefined, 'No namespace query param'); }); });
test('setting a token clears the store', async function(assert) { const { secretId } = clientToken; await Jobs.visit(); assert.ok(find('.job-row'), 'Jobs found'); await Tokens.visit(); await Tokens.secret(secretId).submit(); server.pretender.get('/v1/jobs', function() { return [200, {}, '[]']; }); await Jobs.visit(); // If jobs are lingering in the store, they would show up assert.notOk(find('[data-test-job-row]'), 'No jobs found'); });
test('transitioning away from an error page resets the global error', async function(assert) { server.pretender.get('/v1/nodes', () => [500, {}, null]); await ClientsList.visit(); assert.ok(ClientsList.error.isPresent, 'Application has errored'); await JobsList.visit(); assert.notOk(JobsList.error.isPresent, 'Application is no longer in an error state'); });
test('api requests do not include the region query param', async function(assert) { server.create('region', { id: 'global' }); await JobsList.visit(); await JobsList.jobs.objectAt(0).clickRow(); await PageLayout.gutter.visitClients(); await PageLayout.gutter.visitServers(); server.pretender.handledRequests.forEach(req => { assert.notOk(req.url.includes('region='), req.url); }); });
test('the no leader error state gets its own error message', async function(assert) { server.pretender.get('/v1/jobs', () => [500, {}, 'No cluster leader']); await JobsList.visit(); assert.ok(JobsList.error.isPresent, 'An error is shown'); assert.equal( JobsList.error.title, 'No Cluster Leader', 'The error is specifically for the lack of a cluster leader' ); });
test('switching regions sets localStorage and the region query param', async function(assert) { const newRegion = server.db.regions[1].id; await JobsList.visit(); await selectChoose('[data-test-region-switcher]', newRegion); assert.ok( currentURL().includes(`region=${newRegion}`), 'New region is the region query param value' ); assert.equal(window.localStorage.nomadActiveRegion, newRegion, 'New region in localStorage'); });
test('pages do not include the region query param', async function(assert) { server.create('region', { id: 'global' }); await JobsList.visit(); assert.equal(currentURL(), '/jobs', 'No region query param'); const jobId = JobsList.jobs.objectAt(0).id; await JobsList.jobs.objectAt(0).clickRow(); assert.equal(currentURL(), `/jobs/${jobId}`, 'No region query param'); await ClientsList.visit(); assert.equal(currentURL(), '/clients', 'No region query param'); });
test('changing the namespace sets the namespace in localStorage', function(assert) { const namespace = server.db.namespaces[1]; JobsList.visit(); selectChoose('[data-test-namespace-switcher]', namespace.name); andThen(() => { assert.equal( window.localStorage.nomadActiveNamespace, namespace.id, 'Active namespace was set' ); }); });
test('switching regions to the default region, unsets the region query param', async function(assert) { const startingRegion = server.db.regions[1].id; const defaultRegion = server.db.regions[0].id; await JobsList.visit({ region: startingRegion }); await selectChoose('[data-test-region-switcher]', defaultRegion); assert.notOk(currentURL().includes('region='), 'No region query param for the default region'); assert.equal( window.localStorage.nomadActiveRegion, defaultRegion, 'New region in localStorage' ); });
test('when the region is not the default region, all api requests include the region query param', async function(assert) { const region = server.db.regions[1].id; await JobsList.visit({ region }); await JobsList.jobs.objectAt(0).clickRow(); await PageLayout.gutter.visitClients(); await PageLayout.gutter.visitServers(); const [regionsRequest, defaultRegionRequest, ...appRequests] = server.pretender.handledRequests; assert.notOk( regionsRequest.url.includes('region='), 'The regions request is made without a region qp' ); assert.notOk( defaultRegionRequest.url.includes('region='), 'The default region request is made without a region qp' ); appRequests.forEach(req => { assert.ok(req.url.includes(`region=${region}`), req.url); }); });
test('the namespace switcher lists all namespaces', function(assert) { const namespaces = server.db.namespaces; JobsList.visit(); andThen(() => { assert.ok(JobsList.namespaceSwitcher.isPresent, 'Namespace switcher found'); }); andThen(() => { JobsList.namespaceSwitcher.open(); }); andThen(() => { // TODO this selector should be scoped to only the namespace switcher options, // but ember-wormhole makes that difficult. assert.equal( JobsList.namespaceSwitcher.options.length, namespaces.length, 'All namespaces are in the switcher' ); assert.equal( JobsList.namespaceSwitcher.options.objectAt(0).label, 'Default Namespace', 'The first namespace is always the default one' ); const sortedNamespaces = namespaces.slice(1).sortBy('name'); JobsList.namespaceSwitcher.options.forEach((option, index) => { // Default Namespace handled separately if (index === 0) return; const namespace = sortedNamespaces[index - 1]; assert.equal(option.label, namespace.name, `index ${index}: ${namespace.name}`); }); }); });
test('the region switcher is rendered in the nav bar', async function(assert) { await JobsList.visit(); assert.ok(PageLayout.navbar.regionSwitcher.isPresent, 'Region switcher is shown'); });
test('when on the default region, pages do not include the region query param', async function(assert) { await JobsList.visit(); assert.equal(currentURL(), '/jobs', 'No region query param'); assert.equal(window.localStorage.nomadActiveRegion, 'global', 'Region in localStorage'); });