Feature metadata (#1661)
* feat: 🎸 load edition from controller-metadata.json * refactor: 💡 rename edition and add licensed features support * chore: 🤖 support dev toggling of licensed features * chore: 🤖 rename ent edition * Update ui/admin/app/services/feature-edition.js * Update ui/admin/app/instance-initializers/feature-edition.js Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com> * chore: 🤖 cleanup * chore: 🤖 feature edition disabled in tests / fix test cases * test: 💍 remove feature disable calls in tests * test: 💍 fix broken tests * fix: 🐛 fix config bug * fix: 🐛 fix broken test due to feature flags --------- Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>
This commit is contained in:
1 parent
ee1cd4100c
commit
7350c0e08c
27 files changed
+250
-127
No files matched your search
@@ -35,6 +35,21 @@ function routes() {
|
|||||||
|
|
||||||
// make this `http://localhost:8080`, for example, if your API is on a different server
|
// make this `http://localhost:8080`, for example, if your API is on a different server
|
||||||
// this.urlPrefix = '';
|
// this.urlPrefix = '';
|
||||||
|
|
||||||
|
this.get('/metadata.json', () => {
|
||||||
|
// this configuration is optional
|
||||||
|
const licensedFeatures = environmentConfig?.features?.licensedFeatures;
|
||||||
|
const edition = licensedFeatures ? 'enterprise' : 'oss';
|
||||||
|
const features = licensedFeatures ? Object.keys(licensedFeatures) : [];
|
||||||
|
const metadata = {
|
||||||
|
license: {
|
||||||
|
edition,
|
||||||
|
features,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return metadata;
|
||||||
|
});
|
||||||
|
|
||||||
// make this `/api`, for example, if your API is namespaced
|
// make this `/api`, for example, if your API is namespaced
|
||||||
this.namespace = environmentConfig.api.namespace;
|
this.namespace = environmentConfig.api.namespace;
|
||||||
// delay for each request, automatically set to 0 during testing
|
// delay for each request, automatically set to 0 during testing
|
||||||
|
|||||||
@@ -47,3 +47,4 @@ remove-resources: Remove resources and save
|
|||||||
do-this-later: Do this later
|
do-this-later: Do this later
|
||||||
toggle-color-theme: Toggle Color Theme
|
toggle-color-theme: Toggle Color Theme
|
||||||
toggle-feature-edition: Toggle Feature Edition
|
toggle-feature-edition: Toggle Feature Edition
|
||||||
|
toggle-licensed-features: Toggle Licensed Features
|
||||||
@@ -38,11 +38,6 @@ titles:
|
|||||||
create-resources: Create Resources
|
create-resources: Create Resources
|
||||||
choose-an-option: Choose an option
|
choose-an-option: Choose an option
|
||||||
feature-edition: 'Edition: {edition}'
|
feature-edition: 'Edition: {edition}'
|
||||||
editions:
|
|
||||||
oss: OSS
|
|
||||||
ent: Enterprise
|
|
||||||
enterprise: Enterprise
|
|
||||||
hcp: HCP
|
|
||||||
descriptions:
|
descriptions:
|
||||||
empty-set: There are no items to display yet. You may be able to add items or try back later.
|
empty-set: There are no items to display yet. You may be able to add items or try back later.
|
||||||
cluster-url-initialization: To get started, please enter your cluster URL
|
cluster-url-initialization: To get started, please enter your cluster URL
|
||||||
|
|||||||
@@ -3,9 +3,37 @@
|
|||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function initialize(owner) {
|
import fetch from 'fetch';
|
||||||
|
|
||||||
|
async function autoInitializeFeatureEdition(owner) {
|
||||||
const service = owner.lookup('service:feature-edition');
|
const service = owner.lookup('service:feature-edition');
|
||||||
service.initialize();
|
const url = '/metadata.json';
|
||||||
|
let edition;
|
||||||
|
let features;
|
||||||
|
|
||||||
|
// Attempt to load edition for the metadata JSON
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
const json = await response.json();
|
||||||
|
edition = json?.license?.edition;
|
||||||
|
features = json?.license?.features;
|
||||||
|
} catch (e) {
|
||||||
|
// if the request fails, the service will initialize the default edition
|
||||||
|
// as specified in the config
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the feature edition and its associated features
|
||||||
|
service.initialize(edition, features);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function initialize(owner) {
|
||||||
|
const config = owner.resolveRegistration('config:environment');
|
||||||
|
const isTesting = config.environment === 'test';
|
||||||
|
// Do not auto-init in a test environment.
|
||||||
|
// Tests should explicitly enable editions and features as needed.
|
||||||
|
if (!isTesting) {
|
||||||
|
await autoInitializeFeatureEdition(owner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export default class ApplicationRoute extends Route {
|
|||||||
@service confirm;
|
@service confirm;
|
||||||
@service router;
|
@service router;
|
||||||
@service intl;
|
@service intl;
|
||||||
|
@service features;
|
||||||
@service featureEdition;
|
@service featureEdition;
|
||||||
|
|
||||||
// =attributes
|
// =attributes
|
||||||
@@ -132,4 +133,13 @@ export default class ApplicationRoute extends Route {
|
|||||||
toggleEdition(edition) {
|
toggleEdition(edition) {
|
||||||
this.featureEdition.setEdition(edition);
|
this.featureEdition.setEdition(edition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
toggleFeature(feature) {
|
||||||
|
if (this.features.isEnabled(feature)) {
|
||||||
|
this.features.disable(feature);
|
||||||
|
} else {
|
||||||
|
this.features.enable(feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,6 @@ import { inject as service } from '@ember/service';
|
|||||||
import { tracked } from '@glimmer/tracking';
|
import { tracked } from '@glimmer/tracking';
|
||||||
import config from 'admin/config/environment';
|
import config from 'admin/config/environment';
|
||||||
|
|
||||||
const { selectedEdition, featureEditions } = config;
|
|
||||||
|
|
||||||
export default class FeatureEditionService extends Service {
|
export default class FeatureEditionService extends Service {
|
||||||
// =services
|
// =services
|
||||||
|
|
||||||
@@ -17,24 +15,34 @@ export default class FeatureEditionService extends Service {
|
|||||||
|
|
||||||
// =attributes
|
// =attributes
|
||||||
|
|
||||||
|
licensedFeatures = Object.keys(config.features.licensedFeatures);
|
||||||
|
|
||||||
@tracked edition;
|
@tracked edition;
|
||||||
|
|
||||||
// array of edition strings
|
// array of edition strings
|
||||||
get editions() {
|
get editions() {
|
||||||
return Object.keys(featureEditions);
|
return Object.keys(config.features.featureEditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =methods
|
// =methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the selected edition from the config.
|
* Initializes the selected edition from the config.
|
||||||
|
* @param {string} edition
|
||||||
|
* @param {?string[]} enabledFeatures - list of extra features to enable
|
||||||
*/
|
*/
|
||||||
initialize() {
|
initialize(edition, enabledFeatures) {
|
||||||
this.setEdition(selectedEdition);
|
this.setEdition(edition || config.features.defaultEdition, enabledFeatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
setEdition(edition) {
|
/**
|
||||||
const editionFlags = featureEditions[edition];
|
* Enables the specified edition.
|
||||||
|
* @param {string} edition
|
||||||
|
* @param {?string[]} enabledFeatures - list of extra features to enable
|
||||||
|
*/
|
||||||
|
setEdition(edition, enabledFeatures) {
|
||||||
|
this.edition = edition;
|
||||||
|
const editionFlags = config.features.featureEditions[edition];
|
||||||
Object.keys(editionFlags).forEach((flag) => {
|
Object.keys(editionFlags).forEach((flag) => {
|
||||||
if (editionFlags[flag]) {
|
if (editionFlags[flag]) {
|
||||||
this.features.enable(flag);
|
this.features.enable(flag);
|
||||||
@@ -42,6 +50,8 @@ export default class FeatureEditionService extends Service {
|
|||||||
this.features.disable(flag);
|
this.features.disable(flag);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.edition = edition;
|
if (enabledFeatures) {
|
||||||
|
enabledFeatures.forEach((flag) => this.features.enable(flag));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
data-test-dev-edition-toggle
|
data-test-dev-edition-toggle
|
||||||
@text={{t
|
@text={{t
|
||||||
'titles.feature-edition'
|
'titles.feature-edition'
|
||||||
edition=(t (concat 'editions.' this.featureEdition.edition))
|
edition=this.featureEdition.edition
|
||||||
}}
|
}}
|
||||||
@icon='flight-icons/svg/layers-16'
|
@icon='flight-icons/svg/layers-16'
|
||||||
as |dropdown|
|
as |dropdown|
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
{{#each this.featureEdition.editions as |edition|}}
|
{{#each this.featureEdition.editions as |edition|}}
|
||||||
<dropdown.item>
|
<dropdown.item>
|
||||||
<radioGroup.radio
|
<radioGroup.radio
|
||||||
@label={{t (concat 'editions.' edition)}}
|
@label={{edition}}
|
||||||
@value={{edition}}
|
@value={{edition}}
|
||||||
/>
|
/>
|
||||||
</dropdown.item>
|
</dropdown.item>
|
||||||
@@ -97,6 +97,20 @@
|
|||||||
</form.radioGroup>
|
</form.radioGroup>
|
||||||
</Rose::Form>
|
</Rose::Form>
|
||||||
</dropdown.section>
|
</dropdown.section>
|
||||||
|
<dropdown.separator />
|
||||||
|
<dropdown.section @title={{t 'actions.toggle-licensed-features'}}>
|
||||||
|
<Rose::Form as |form|>
|
||||||
|
{{#each this.featureEdition.licensedFeatures as |feature|}}
|
||||||
|
<dropdown.item>
|
||||||
|
<form.checkbox
|
||||||
|
@label={{feature}}
|
||||||
|
@checked={{feature-flag feature}}
|
||||||
|
@onChange={{route-action 'toggleFeature' feature}}
|
||||||
|
/>
|
||||||
|
</dropdown.item>
|
||||||
|
{{/each}}
|
||||||
|
</Rose::Form>
|
||||||
|
</dropdown.section>
|
||||||
</utilities.dropdown>
|
</utilities.dropdown>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,27 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const features = require('./features');
|
const v8 = require('v8');
|
||||||
|
const {
|
||||||
|
defaultEdition,
|
||||||
|
featureEditions,
|
||||||
|
licensedFeatures,
|
||||||
|
} = require('./features');
|
||||||
|
|
||||||
const APP_NAME = process.env.APP_NAME || 'Boundary';
|
const APP_NAME = process.env.APP_NAME || 'Boundary';
|
||||||
const API_HOST = process.env.API_HOST || '';
|
const API_HOST = process.env.API_HOST || '';
|
||||||
|
|
||||||
|
const clone = (obj) => v8.deserialize(v8.serialize(obj));
|
||||||
|
|
||||||
module.exports = function (environment) {
|
module.exports = function (environment) {
|
||||||
|
// Start with a fresh copy of the features config every run, since it
|
||||||
|
// could be modified by an environment.
|
||||||
|
const features = {
|
||||||
|
defaultEdition,
|
||||||
|
featureEditions: clone(featureEditions),
|
||||||
|
licensedFeatures: clone(licensedFeatures),
|
||||||
|
};
|
||||||
|
|
||||||
let ENV = {
|
let ENV = {
|
||||||
modulePrefix: 'admin',
|
modulePrefix: 'admin',
|
||||||
environment,
|
environment,
|
||||||
@@ -98,8 +113,7 @@ module.exports = function (environment) {
|
|||||||
timeout: 4000,
|
timeout: 4000,
|
||||||
},
|
},
|
||||||
|
|
||||||
selectedEdition: features.selectedEdition,
|
features: features,
|
||||||
featureEditions: features.featureEditions,
|
|
||||||
featureFlags: {},
|
featureFlags: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -125,14 +139,16 @@ module.exports = function (environment) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Default edition in development
|
// Default edition in development
|
||||||
ENV.selectedEdition = 'enterprise';
|
ENV.features.defaultEdition = 'enterprise';
|
||||||
features.enableFeaturesInAllEditions(
|
// Enable development-only features
|
||||||
{
|
ENV.features.featureEditions.oss['dev-edition-toggle'] = true;
|
||||||
// Show edition toggle in UI in development
|
ENV.features.featureEditions.enterprise['dev-edition-toggle'] = true;
|
||||||
'dev-edition-toggle': true,
|
ENV.features.featureEditions.hcp['dev-edition-toggle'] = true;
|
||||||
},
|
// Enable licensed features by default in enterprise and hcp
|
||||||
ENV
|
Object.keys(ENV.features.licensedFeatures).forEach((feature) => {
|
||||||
);
|
ENV.features.featureEditions.enterprise[feature] = true;
|
||||||
|
ENV.features.featureEditions.hcp[feature] = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (environment === 'test') {
|
if (environment === 'test') {
|
||||||
@@ -150,16 +166,6 @@ module.exports = function (environment) {
|
|||||||
ENV.flashMessageDefaults.timeout = 0;
|
ENV.flashMessageDefaults.timeout = 0;
|
||||||
|
|
||||||
ENV.enableConfirmService = false;
|
ENV.enableConfirmService = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable additional features for testing purposes.
|
|
||||||
* [TODO] Tests should be refactored such that each test case
|
|
||||||
* explicitly enables the features and/or edition that it needs.
|
|
||||||
* By default, tests should have no features enabled. This explicit
|
|
||||||
* approach ensures that test cases are easy to read and understand,
|
|
||||||
* since their feature requirements are embedded.
|
|
||||||
*/
|
|
||||||
ENV.selectedEdition = 'enterprise';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (environment === 'production') {
|
if (environment === 'production') {
|
||||||
|
|||||||
+12
-15
@@ -5,14 +5,22 @@
|
|||||||
|
|
||||||
const EDITION = process.env.EDITION || 'oss'; // Default edition is OSS
|
const EDITION = process.env.EDITION || 'oss'; // Default edition is OSS
|
||||||
|
|
||||||
const selectedEdition = EDITION;
|
const defaultEdition = EDITION;
|
||||||
|
|
||||||
|
const devFeatures = {
|
||||||
|
'dev-edition-toggle': false,
|
||||||
|
};
|
||||||
|
const licensedFeatures = {
|
||||||
|
'multi-hop-sessions': false,
|
||||||
|
'ssh-target': false,
|
||||||
|
};
|
||||||
// Base edition declares available features, disabled by default.
|
// Base edition declares available features, disabled by default.
|
||||||
const baseEdition = {
|
const baseEdition = {
|
||||||
|
...devFeatures,
|
||||||
|
...licensedFeatures,
|
||||||
byow: false,
|
byow: false,
|
||||||
'byow-pki-hcp-cluster-id': false,
|
'byow-pki-hcp-cluster-id': false,
|
||||||
'json-credentials': false,
|
'json-credentials': false,
|
||||||
'ssh-target': false,
|
|
||||||
'static-credentials': false,
|
'static-credentials': false,
|
||||||
'target-worker-filters-v2': false,
|
'target-worker-filters-v2': false,
|
||||||
'target-worker-filters-v2-ingress': false,
|
'target-worker-filters-v2-ingress': false,
|
||||||
@@ -32,7 +40,6 @@ featureEditions.oss = {
|
|||||||
};
|
};
|
||||||
featureEditions.enterprise = {
|
featureEditions.enterprise = {
|
||||||
...featureEditions.oss,
|
...featureEditions.oss,
|
||||||
'ssh-target': true,
|
|
||||||
'target-worker-filters-v2-ingress': true,
|
'target-worker-filters-v2-ingress': true,
|
||||||
'vault-worker-filter': true,
|
'vault-worker-filter': true,
|
||||||
};
|
};
|
||||||
@@ -42,18 +49,8 @@ featureEditions.hcp = {
|
|||||||
'target-worker-filters-v2-hcp': true,
|
'target-worker-filters-v2-hcp': true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes a set of features and enables them in all editions.
|
|
||||||
* For use in development and testing only.
|
|
||||||
*/
|
|
||||||
const enableFeaturesInAllEditions = (features = {}, ENV) => {
|
|
||||||
Object.entries(featureEditions).forEach(
|
|
||||||
([key, edition]) => (ENV.featureEditions[key] = { ...features, ...edition })
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
featureEditions,
|
featureEditions,
|
||||||
selectedEdition,
|
defaultEdition,
|
||||||
enableFeaturesInAllEditions,
|
licensedFeatures,
|
||||||
};
|
};
|
||||||
@@ -23,6 +23,7 @@ module('Acceptance | credential-libraries | create', function (hooks) {
|
|||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
setupMirage(hooks);
|
setupMirage(hooks);
|
||||||
|
|
||||||
|
let featuresService;
|
||||||
let getCredentialLibraryCount;
|
let getCredentialLibraryCount;
|
||||||
|
|
||||||
const instances = {
|
const instances = {
|
||||||
@@ -76,6 +77,7 @@ module('Acceptance | credential-libraries | create', function (hooks) {
|
|||||||
getCredentialLibraryCount = () =>
|
getCredentialLibraryCount = () =>
|
||||||
this.server.schema.credentialLibraries.all().models.length;
|
this.server.schema.credentialLibraries.all().models.length;
|
||||||
authenticateSession({});
|
authenticateSession({});
|
||||||
|
featuresService = this.owner.lookup('service:features');
|
||||||
});
|
});
|
||||||
test('visiting credential libraries', async function (assert) {
|
test('visiting credential libraries', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
@@ -98,6 +100,7 @@ module('Acceptance | credential-libraries | create', function (hooks) {
|
|||||||
|
|
||||||
test('can create a new credential library of type vault ssh cert', async function (assert) {
|
test('can create a new credential library of type vault ssh cert', async function (assert) {
|
||||||
assert.expect(12);
|
assert.expect(12);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
const count = getCredentialLibraryCount();
|
const count = getCredentialLibraryCount();
|
||||||
await visit(urls.newCredentialLibrary);
|
await visit(urls.newCredentialLibrary);
|
||||||
await click('[value="vault-ssh-certificate"]');
|
await click('[value="vault-ssh-certificate"]');
|
||||||
@@ -156,6 +159,7 @@ module('Acceptance | credential-libraries | create', function (hooks) {
|
|||||||
|
|
||||||
test('ecdsa and rsa key types bring up a key bits field', async function (assert) {
|
test('ecdsa and rsa key types bring up a key bits field', async function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(3);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
await visit(urls.newCredentialLibrary);
|
await visit(urls.newCredentialLibrary);
|
||||||
await click('[value="vault-ssh-certificate"]');
|
await click('[value="vault-ssh-certificate"]');
|
||||||
await select('[name="key_type"]', 'ed25519');
|
await select('[name="key_type"]', 'ed25519');
|
||||||
@@ -224,11 +228,9 @@ module('Acceptance | credential-libraries | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot select vault ssh cert when feature is disabled', async function (assert) {
|
test('cannot select vault ssh cert when feature is disabled', async function (assert) {
|
||||||
const featuresService = this.owner.lookup('service:features');
|
assert.expect(2);
|
||||||
featuresService.disable('ssh-target');
|
|
||||||
assert.expect(1);
|
|
||||||
await visit(urls.newCredentialLibrary);
|
await visit(urls.newCredentialLibrary);
|
||||||
|
assert.false(featuresService.isEnabled('ssh-target'));
|
||||||
assert.dom('[value="vault-ssh-certificate"]').doesNotExist();
|
assert.dom('[value="vault-ssh-certificate"]').doesNotExist();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -85,7 +85,7 @@ module('Acceptance | credential-libraries | read', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot navigate to vault ssh cert form when feature is not enabled', async function (assert) {
|
test('cannot navigate to vault ssh cert form when feature is not enabled', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(2);
|
||||||
instances.credentialLibrary = this.server.create('credential-library', {
|
instances.credentialLibrary = this.server.create('credential-library', {
|
||||||
scope: instances.scopes.project,
|
scope: instances.scopes.project,
|
||||||
credentialStore: instances.credentialStore,
|
credentialStore: instances.credentialStore,
|
||||||
@@ -94,10 +94,9 @@ module('Acceptance | credential-libraries | read', function (hooks) {
|
|||||||
await visit(
|
await visit(
|
||||||
`${urls.credentialLibraries}/${instances.credentialLibrary.id}`
|
`${urls.credentialLibraries}/${instances.credentialLibrary.id}`
|
||||||
);
|
);
|
||||||
const featuresService = this.owner.lookup('service:features');
|
|
||||||
featuresService.disable('ssh-target');
|
|
||||||
await visit(urls.credentialLibraries);
|
await visit(urls.credentialLibraries);
|
||||||
|
const featuresService = this.owner.lookup('service:features');
|
||||||
|
assert.false(featuresService.isEnabled('ssh-target'));
|
||||||
assert.dom('.rose-table-body tr:nth-of-type(2) a').doesNotExist();
|
assert.dom('.rose-table-body tr:nth-of-type(2) a').doesNotExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ module('Acceptance | credential-stores | create', function (hooks) {
|
|||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
setupMirage(hooks);
|
setupMirage(hooks);
|
||||||
|
|
||||||
|
let featuresService;
|
||||||
let getCredentialStoresCount;
|
let getCredentialStoresCount;
|
||||||
let getStaticCredentialStoresCount;
|
let getStaticCredentialStoresCount;
|
||||||
let getVaultCredentialStoresCount;
|
let getVaultCredentialStoresCount;
|
||||||
@@ -62,10 +63,12 @@ module('Acceptance | credential-stores | create', function (hooks) {
|
|||||||
.length;
|
.length;
|
||||||
};
|
};
|
||||||
authenticateSession({});
|
authenticateSession({});
|
||||||
|
featuresService = this.owner.lookup('service:features');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Users can create a new credential store of default type static', async function (assert) {
|
test('Users can create a new credential store of default type static', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('static-credentials');
|
||||||
const count = getStaticCredentialStoresCount();
|
const count = getStaticCredentialStoresCount();
|
||||||
await visit(urls.newCredentialStore);
|
await visit(urls.newCredentialStore);
|
||||||
await fillIn('[name="name"]', 'random string');
|
await fillIn('[name="name"]', 'random string');
|
||||||
@@ -75,6 +78,7 @@ module('Acceptance | credential-stores | create', function (hooks) {
|
|||||||
|
|
||||||
test('Users can create a new credential store of type vault', async function (assert) {
|
test('Users can create a new credential store of type vault', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('static-credentials');
|
||||||
const count = getVaultCredentialStoresCount();
|
const count = getVaultCredentialStoresCount();
|
||||||
await visit(urls.newCredentialStore);
|
await visit(urls.newCredentialStore);
|
||||||
await fillIn('[name="name"]', 'random string');
|
await fillIn('[name="name"]', 'random string');
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ module(
|
|||||||
|
|
||||||
test('users can create a new json credential', async function (assert) {
|
test('users can create a new json credential', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('json-credentials');
|
||||||
const credentialsCount = getCredentialsCount();
|
const credentialsCount = getCredentialsCount();
|
||||||
const jsonCredentialCount = getJsonCredentialCount();
|
const jsonCredentialCount = getJsonCredentialCount();
|
||||||
await visit(urls.credentials);
|
await visit(urls.credentials);
|
||||||
@@ -159,6 +160,7 @@ module(
|
|||||||
|
|
||||||
test('users can cancel create new json credential', async function (assert) {
|
test('users can cancel create new json credential', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('json-credentials');
|
||||||
const credentialsCount = getCredentialsCount();
|
const credentialsCount = getCredentialsCount();
|
||||||
await visit(urls.credentials);
|
await visit(urls.credentials);
|
||||||
|
|
||||||
@@ -173,6 +175,7 @@ module(
|
|||||||
|
|
||||||
test('users can switch away from JSON type credentials and the json_object value will be cleared', async function (assert) {
|
test('users can switch away from JSON type credentials and the json_object value will be cleared', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('json-credentials');
|
||||||
const editorSelector = '[data-test-code-editor-field-editor]';
|
const editorSelector = '[data-test-code-editor-field-editor]';
|
||||||
const newSecret = '{"test": "value"}';
|
const newSecret = '{"test": "value"}';
|
||||||
|
|
||||||
@@ -191,6 +194,7 @@ module(
|
|||||||
|
|
||||||
test('users cannot navigate to new credential route without proper authorization', async function (assert) {
|
test('users cannot navigate to new credential route without proper authorization', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('static-credentials');
|
||||||
instances.staticCredentialStore.authorized_collection_actions.credentials =
|
instances.staticCredentialStore.authorized_collection_actions.credentials =
|
||||||
instances.staticCredentialStore.authorized_collection_actions.credentials.filter(
|
instances.staticCredentialStore.authorized_collection_actions.credentials.filter(
|
||||||
(item) => {
|
(item) => {
|
||||||
@@ -282,6 +286,7 @@ module(
|
|||||||
|
|
||||||
test('saving a new json credential with invalid fields displays error messages', async function (assert) {
|
test('saving a new json credential with invalid fields displays error messages', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('json-credentials');
|
||||||
await visit(urls.credentials);
|
await visit(urls.credentials);
|
||||||
this.server.post('/credentials', () => {
|
this.server.post('/credentials', () => {
|
||||||
return new Response(
|
return new Response(
|
||||||
@@ -313,12 +318,11 @@ module(
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot navigate to json credential when feature is disabled', async function (assert) {
|
test('cannot navigate to json credential when feature is disabled', async function (assert) {
|
||||||
featuresService.disable('json-credentials');
|
assert.expect(5);
|
||||||
assert.expect(4);
|
|
||||||
await visit(urls.credentials);
|
await visit(urls.credentials);
|
||||||
|
|
||||||
await click(`[href="${urls.newCredential}"]`);
|
await click(`[href="${urls.newCredential}"]`);
|
||||||
|
assert.false(featuresService.isEnabled('json-credentials'));
|
||||||
assert.true(
|
assert.true(
|
||||||
instances.staticCredentialStore.authorized_collection_actions.credentials.includes(
|
instances.staticCredentialStore.authorized_collection_actions.credentials.includes(
|
||||||
'create'
|
'create'
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) {
|
|||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
setupMirage(hooks);
|
setupMirage(hooks);
|
||||||
|
|
||||||
|
let featuresService;
|
||||||
|
|
||||||
const instances = {
|
const instances = {
|
||||||
scopes: {
|
scopes: {
|
||||||
org: null,
|
org: null,
|
||||||
@@ -75,6 +77,7 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) {
|
|||||||
urls.jsonCredential = `${urls.credentials}/${instances.jsonCredential.id}`;
|
urls.jsonCredential = `${urls.credentials}/${instances.jsonCredential.id}`;
|
||||||
urls.unknownCredential = `${urls.credentials}/foo`;
|
urls.unknownCredential = `${urls.credentials}/foo`;
|
||||||
authenticateSession({});
|
authenticateSession({});
|
||||||
|
featuresService = this.owner.lookup('service:features');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('visiting username & password credential', async function (assert) {
|
test('visiting username & password credential', async function (assert) {
|
||||||
@@ -101,6 +104,7 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) {
|
|||||||
|
|
||||||
test('visiting JSON credential', async function (assert) {
|
test('visiting JSON credential', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('json-credentials');
|
||||||
await visit(urls.staticCredentialStore);
|
await visit(urls.staticCredentialStore);
|
||||||
await click(`[href="${urls.credentials}"]`);
|
await click(`[href="${urls.credentials}"]`);
|
||||||
await a11yAudit();
|
await a11yAudit();
|
||||||
@@ -141,10 +145,9 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot navigate to a JSON credential form when feature not enabled', async function (assert) {
|
test('cannot navigate to a JSON credential form when feature not enabled', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(2);
|
||||||
const featuresService = this.owner.lookup('service:features');
|
|
||||||
featuresService.disable('json-credentials');
|
|
||||||
await visit(urls.credentials);
|
await visit(urls.credentials);
|
||||||
|
assert.false(featuresService.isEnabled('json-credentials'));
|
||||||
assert.dom('.rose-table-body tr:nth-child(3) a').doesNotExist();
|
assert.dom('.rose-table-body tr:nth-child(3) a').doesNotExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ module('Acceptance | credential-stores | read', function (hooks) {
|
|||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
setupMirage(hooks);
|
setupMirage(hooks);
|
||||||
|
|
||||||
|
let featuresService;
|
||||||
|
|
||||||
const instances = {
|
const instances = {
|
||||||
scopes: {
|
scopes: {
|
||||||
global: null,
|
global: null,
|
||||||
@@ -63,10 +65,12 @@ module('Acceptance | credential-stores | read', function (hooks) {
|
|||||||
urls.unknownCredentialStore = `${urls.credentialStores}/foo`;
|
urls.unknownCredentialStore = `${urls.credentialStores}/foo`;
|
||||||
|
|
||||||
authenticateSession({});
|
authenticateSession({});
|
||||||
|
featuresService = this.owner.lookup('service:features');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('visiting static credential store', async function (assert) {
|
test('visiting static credential store', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('static-credentials');
|
||||||
await visit(urls.credentialStores);
|
await visit(urls.credentialStores);
|
||||||
await a11yAudit();
|
await a11yAudit();
|
||||||
assert.strictEqual(currentURL(), urls.credentialStores);
|
assert.strictEqual(currentURL(), urls.credentialStores);
|
||||||
@@ -104,6 +108,7 @@ module('Acceptance | credential-stores | read', function (hooks) {
|
|||||||
|
|
||||||
test('cannot navigate to a vault credential store form without proper authorization', async function (assert) {
|
test('cannot navigate to a vault credential store form without proper authorization', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('static-credentials');
|
||||||
await visit(urls.projectScope);
|
await visit(urls.projectScope);
|
||||||
instances.vaultCredentialStore.authorized_actions =
|
instances.vaultCredentialStore.authorized_actions =
|
||||||
instances.vaultCredentialStore.authorized_actions.filter(
|
instances.vaultCredentialStore.authorized_actions.filter(
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ module('Acceptance | develop', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('edition toggle is hidden when `dev-edition-toggle` is false', async function (assert) {
|
test('edition toggle is hidden when `dev-edition-toggle` is false', async function (assert) {
|
||||||
|
assert.expect(2);
|
||||||
await visit('/');
|
await visit('/');
|
||||||
assert.false(featuresService.isEnabled('dev-edition-toggle'));
|
assert.false(featuresService.isEnabled('dev-edition-toggle'));
|
||||||
assert.dom('data-dev-edition-toggle').doesNotExist();
|
assert.dom('data-dev-edition-toggle').doesNotExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('edition toggle is visible when `dev-edition-toggle` is true', async function (assert) {
|
test('edition toggle is visible when `dev-edition-toggle` is true', async function (assert) {
|
||||||
|
assert.expect(2);
|
||||||
assert.false(featuresService.isEnabled('dev-edition-toggle'));
|
assert.false(featuresService.isEnabled('dev-edition-toggle'));
|
||||||
featuresService.enable('dev-edition-toggle');
|
featuresService.enable('dev-edition-toggle');
|
||||||
await visit('/');
|
await visit('/');
|
||||||
|
|||||||
@@ -148,14 +148,13 @@ module('Acceptance | targets | brokered credential sources', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot navigate to a json type credential when feature is disabled', async function (assert) {
|
test('cannot navigate to a json type credential when feature is disabled', async function (assert) {
|
||||||
featuresService.disable('json-credentials');
|
assert.expect(3);
|
||||||
assert.expect(2);
|
|
||||||
const jsonCredential = instances.credentials[2];
|
const jsonCredential = instances.credentials[2];
|
||||||
instances.target.update({
|
instances.target.update({
|
||||||
brokeredCredentialSourceIds: [...randomlySelectedCredentials],
|
brokeredCredentialSourceIds: [...randomlySelectedCredentials],
|
||||||
});
|
});
|
||||||
await visit(urls.brokeredCredentialSources);
|
await visit(urls.brokeredCredentialSources);
|
||||||
|
assert.false(featuresService.isEnabled('json-credentials'));
|
||||||
assert
|
assert
|
||||||
.dom('.rose-table-row:nth-child(3)')
|
.dom('.rose-table-row:nth-child(3)')
|
||||||
.includesText(jsonCredential.name);
|
.includesText(jsonCredential.name);
|
||||||
|
|||||||
@@ -85,13 +85,17 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
|
|
||||||
test('defaults to type `ssh` when no query param provided', async function (assert) {
|
test('defaults to type `ssh` when no query param provided', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
await visit(urls.newTarget);
|
await visit(urls.newTarget);
|
||||||
assert.strictEqual(find('[name="type"]:checked').value, TYPE_TARGET_SSH);
|
assert.strictEqual(find('[name="type"]:checked').value, TYPE_TARGET_SSH);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can create type `ssh` when `target-worker-filters-v2` is disabled', async function (assert) {
|
test('can create type `ssh` when `target-worker-filters-v2` is disabled', async function (assert) {
|
||||||
featuresService.disable('target-worker-filters-v2');
|
assert.expect(5);
|
||||||
assert.expect(4);
|
featuresService.enable('ssh-target');
|
||||||
|
|
||||||
|
assert.false(featuresService.isEnabled('target-worker-filters-v2'));
|
||||||
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
const sshTargetCount = getSSHTargetCount();
|
const sshTargetCount = getSSHTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
@@ -116,8 +120,10 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can create type `ssh` when `target-worker-filters-v2` is enabled', async function (assert) {
|
test('can create type `ssh` when `target-worker-filters-v2` is enabled', async function (assert) {
|
||||||
featuresService.enable('target-worker-filters-v2');
|
|
||||||
assert.expect(4);
|
assert.expect(4);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
|
featuresService.enable('target-worker-filters-v2');
|
||||||
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
const sshTargetCount = getSSHTargetCount();
|
const sshTargetCount = getSSHTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
@@ -146,8 +152,11 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can create type `tcp` when `target-worker-filters-v2` is disabled', async function (assert) {
|
test('can create type `tcp` when `target-worker-filters-v2` is disabled', async function (assert) {
|
||||||
featuresService.disable('target-worker-filters-v2');
|
assert.expect(5);
|
||||||
assert.expect(4);
|
featuresService.enable('ssh-target');
|
||||||
|
|
||||||
|
assert.false(featuresService.isEnabled('target-worker-filters-v2'));
|
||||||
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
const tcpTargetCount = getTCPTargetCount();
|
const tcpTargetCount = getTCPTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
@@ -172,8 +181,10 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can create type `tcp` when `target-worker-filters-v2` is enabled', async function (assert) {
|
test('can create type `tcp` when `target-worker-filters-v2` is enabled', async function (assert) {
|
||||||
featuresService.enable('target-worker-filters-v2');
|
|
||||||
assert.expect(4);
|
assert.expect(4);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
|
featuresService.enable('target-worker-filters-v2');
|
||||||
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
const tcpTargetCount = getTCPTargetCount();
|
const tcpTargetCount = getTCPTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
@@ -203,9 +214,11 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can create type `tcp` when `target-worker-filters-v2` and `target-worker-filters-v2-ingress` is enabled', async function (assert) {
|
test('can create type `tcp` when `target-worker-filters-v2` and `target-worker-filters-v2-ingress` is enabled', async function (assert) {
|
||||||
|
assert.expect(4);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
featuresService.enable('target-worker-filters-v2');
|
featuresService.enable('target-worker-filters-v2');
|
||||||
featuresService.enable('target-worker-filters-v2-ingress');
|
featuresService.enable('target-worker-filters-v2-ingress');
|
||||||
assert.expect(4);
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
const tcpTargetCount = getTCPTargetCount();
|
const tcpTargetCount = getTCPTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
@@ -239,15 +252,16 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
|
|
||||||
test('default port is not marked required for SSH targets', async function (assert) {
|
test('default port is not marked required for SSH targets', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
await visit(urls.newTarget);
|
await visit(urls.newTarget);
|
||||||
assert.dom('[data-test-default-port-label]').includesText('Optional');
|
assert.dom('[data-test-default-port-label]').includesText('Optional');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('default port is marked required for TCP targets', async function (assert) {
|
test('default port is marked required for TCP targets', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
await visit(urls.newTarget);
|
await visit(urls.newTarget);
|
||||||
await click('[value="tcp"]');
|
await click('[value="tcp"]');
|
||||||
|
|
||||||
assert.dom('[data-test-default-port-label]').includesText('Required');
|
assert.dom('[data-test-default-port-label]').includesText('Required');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -284,12 +298,11 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot navigate to new SSH targets route when ssh feature is disabled', async function (assert) {
|
test('cannot navigate to new SSH targets route when ssh feature is disabled', async function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(4);
|
||||||
featuresService.disable('ssh-target');
|
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
|
|
||||||
await click(`[href="${urls.newTarget}"]`);
|
await click(`[href="${urls.newTarget}"]`);
|
||||||
|
assert.false(featuresService.isEnabled('ssh-target'));
|
||||||
assert.true(
|
assert.true(
|
||||||
instances.scopes.project.authorized_collection_actions.targets.includes(
|
instances.scopes.project.authorized_collection_actions.targets.includes(
|
||||||
'create'
|
'create'
|
||||||
@@ -301,6 +314,9 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
|
|
||||||
test('can cancel create new TCP target', async function (assert) {
|
test('can cancel create new TCP target', async function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(3);
|
||||||
|
featuresService.enable('target-worker-filters-v2');
|
||||||
|
featuresService.enable('target-worker-filters-v2-ingress');
|
||||||
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
const tcpTargetCount = getTCPTargetCount();
|
const tcpTargetCount = getTCPTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
@@ -321,6 +337,10 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
|
|
||||||
test('can cancel create new SSH target', async function (assert) {
|
test('can cancel create new SSH target', async function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(3);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
|
featuresService.enable('target-worker-filters-v2');
|
||||||
|
featuresService.enable('target-worker-filters-v2-ingress');
|
||||||
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
const sshTargetCount = getSSHTargetCount();
|
const sshTargetCount = getSSHTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
@@ -398,10 +418,13 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
|
|
||||||
test('can save address', async function (assert) {
|
test('can save address', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('target-network-address');
|
||||||
|
|
||||||
const targetCount = getTargetCount();
|
const targetCount = getTargetCount();
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
|
|
||||||
await click(`[href="${urls.newTarget}"]`);
|
await click(`[href="${urls.newTarget}"]`);
|
||||||
|
|
||||||
await fillIn('[name="name"]', 'random string');
|
await fillIn('[name="name"]', 'random string');
|
||||||
await fillIn('[name="address"]', '0.0.0.0');
|
await fillIn('[name="address"]', '0.0.0.0');
|
||||||
await click('[type="submit"]');
|
await click('[type="submit"]');
|
||||||
@@ -414,12 +437,10 @@ module('Acceptance | targets | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('address field does not exist when target network address feature is disabled', async function (assert) {
|
test('address field does not exist when target network address feature is disabled', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(2);
|
||||||
featuresService.disable('target-network-address');
|
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
|
|
||||||
await click(`[href="${urls.newTarget}"]`);
|
await click(`[href="${urls.newTarget}"]`);
|
||||||
|
assert.false(featuresService.isEnabled('target-network-address'));
|
||||||
assert.dom('[name="address"]').doesNotExist();
|
assert.dom('[name="address"]').doesNotExist();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -74,6 +74,8 @@ module('Acceptance | targets | read', function (hooks) {
|
|||||||
|
|
||||||
test('visiting ssh target', async function (assert) {
|
test('visiting ssh target', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
|
|
||||||
await visit(urls.targets);
|
await visit(urls.targets);
|
||||||
await a11yAudit();
|
await a11yAudit();
|
||||||
assert.strictEqual(currentURL(), urls.targets);
|
assert.strictEqual(currentURL(), urls.targets);
|
||||||
@@ -132,23 +134,22 @@ module('Acceptance | targets | read', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('visiting an ssh target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) {
|
test('visiting an ssh target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) {
|
||||||
featuresService.disable('target-worker-filters-v2');
|
assert.expect(2);
|
||||||
assert.expect(1);
|
|
||||||
await visit(urls.sshTarget);
|
await visit(urls.sshTarget);
|
||||||
|
assert.false(featuresService.isEnabled('target-worker-filters-v2'));
|
||||||
assert.dom('.hds-alert').doesNotExist();
|
assert.dom('.hds-alert').doesNotExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('visiting a tcp target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) {
|
test('visiting a tcp target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) {
|
||||||
featuresService.disable('target-worker-filters-v2');
|
assert.expect(2);
|
||||||
assert.expect(1);
|
|
||||||
await visit(urls.tcpTarget);
|
await visit(urls.tcpTarget);
|
||||||
|
assert.false(featuresService.isEnabled('target-worker-filters-v2'));
|
||||||
assert.dom('.hds-alert').doesNotExist();
|
assert.dom('.hds-alert').doesNotExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cannot navigate to a ssh target form without proper authorization', async function (assert) {
|
test('cannot navigate to an ssh target form without proper authorization', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
await visit(urls.projectScope);
|
await visit(urls.projectScope);
|
||||||
instances.sshTarget.authorized_actions =
|
instances.sshTarget.authorized_actions =
|
||||||
instances.sshTarget.authorized_actions.filter((item) => item !== 'read');
|
instances.sshTarget.authorized_actions.filter((item) => item !== 'read');
|
||||||
@@ -161,6 +162,7 @@ module('Acceptance | targets | read', function (hooks) {
|
|||||||
|
|
||||||
test('cannot navigate to a tcp target form without proper authorization', async function (assert) {
|
test('cannot navigate to a tcp target form without proper authorization', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
await visit(urls.projectScope);
|
await visit(urls.projectScope);
|
||||||
instances.tcpTarget.authorized_actions =
|
instances.tcpTarget.authorized_actions =
|
||||||
instances.tcpTarget.authorized_actions.filter((item) => item !== 'read');
|
instances.tcpTarget.authorized_actions.filter((item) => item !== 'read');
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ module('Acceptance | targets | update', function (hooks) {
|
|||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
featuresService = this.owner.lookup('service:features');
|
featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.disable('target-worker-filters-v2');
|
|
||||||
// Generate resources
|
// Generate resources
|
||||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||||
instances.scopes.org = this.server.create('scope', {
|
instances.scopes.org = this.server.create('scope', {
|
||||||
@@ -96,10 +95,9 @@ module('Acceptance | targets | update', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('updating a target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) {
|
test('updating a target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) {
|
||||||
featuresService.disable('target-worker-filters-v2');
|
assert.expect(2);
|
||||||
assert.expect(1);
|
|
||||||
await visit(urls.target);
|
await visit(urls.target);
|
||||||
|
assert.false(featuresService.isEnabled('target-worker-filters-v2'));
|
||||||
assert.dom('.hds-alert').doesNotExist();
|
assert.dom('.hds-alert').doesNotExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -366,6 +364,8 @@ module('Acceptance | targets | update', function (hooks) {
|
|||||||
|
|
||||||
test('saving address with existing host sources brings up confirmation modal and removes host sources', async function (assert) {
|
test('saving address with existing host sources brings up confirmation modal and removes host sources', async function (assert) {
|
||||||
assert.expect(4);
|
assert.expect(4);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
|
featuresService.enable('target-network-address');
|
||||||
const confirmService = this.owner.lookup('service:confirm');
|
const confirmService = this.owner.lookup('service:confirm');
|
||||||
confirmService.enabled = true;
|
confirmService.enabled = true;
|
||||||
this.server.createList(
|
this.server.createList(
|
||||||
@@ -410,6 +410,8 @@ module('Acceptance | targets | update', function (hooks) {
|
|||||||
|
|
||||||
test('saving address with existing host sources brings up confirmation modal and can cancel', async function (assert) {
|
test('saving address with existing host sources brings up confirmation modal and can cancel', async function (assert) {
|
||||||
assert.expect(4);
|
assert.expect(4);
|
||||||
|
featuresService.enable('ssh-target');
|
||||||
|
featuresService.enable('target-network-address');
|
||||||
const confirmService = this.owner.lookup('service:confirm');
|
const confirmService = this.owner.lookup('service:confirm');
|
||||||
confirmService.enabled = true;
|
confirmService.enabled = true;
|
||||||
this.server.createList(
|
this.server.createList(
|
||||||
|
|||||||
@@ -54,21 +54,21 @@ module('Acceptance | workers | create', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('initial upstreams input field is visible for `oss` binary', async function (assert) {
|
test('initial upstreams input field is visible for `oss` binary', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(3);
|
||||||
const featuresService = this.owner.lookup('service:features');
|
const featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.disable('byow-pki-hcp-cluster-id');
|
|
||||||
await visit(newWorkerURL);
|
await visit(newWorkerURL);
|
||||||
const labels = findAll('label.rose-form-label');
|
const labels = findAll('label.rose-form-label');
|
||||||
|
assert.false(featuresService.isEnabled('byow-pki-hcp-cluster-id'));
|
||||||
assert.dom(labels[0]).doesNotIncludeText('Boundary Cluster ID');
|
assert.dom(labels[0]).doesNotIncludeText('Boundary Cluster ID');
|
||||||
assert.dom(labels[2]).hasText('Initial Upstreams');
|
assert.dom(labels[2]).hasText('Initial Upstreams');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('download and install step shows correct oss instructions', async function (assert) {
|
test('download and install step shows correct oss instructions', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(3);
|
||||||
const featuresService = this.owner.lookup('service:features');
|
const featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.disable('byow-pki-hcp-cluster-id');
|
|
||||||
await visit(newWorkerURL);
|
await visit(newWorkerURL);
|
||||||
const createSection = findAll('.worker-create-section');
|
const createSection = findAll('.worker-create-section');
|
||||||
|
assert.false(featuresService.isEnabled('byow-pki-hcp-cluster-id'));
|
||||||
assert.dom(createSection[1]).includesText('curl -fsSL');
|
assert.dom(createSection[1]).includesText('curl -fsSL');
|
||||||
assert.dom(createSection[1]).doesNotIncludeText('wget -q');
|
assert.dom(createSection[1]).doesNotIncludeText('wget -q');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ module('Acceptance | workers | list', function (hooks) {
|
|||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
setupMirage(hooks);
|
setupMirage(hooks);
|
||||||
|
|
||||||
|
let featuresService;
|
||||||
|
|
||||||
const instances = {
|
const instances = {
|
||||||
scopes: {
|
scopes: {
|
||||||
global: null,
|
global: null,
|
||||||
@@ -31,14 +33,15 @@ module('Acceptance | workers | list', function (hooks) {
|
|||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||||
|
|
||||||
urls.globalScope = `/scopes/global/scopes`;
|
urls.globalScope = `/scopes/global/scopes`;
|
||||||
urls.workers = `/scopes/global/workers`;
|
urls.workers = `/scopes/global/workers`;
|
||||||
authenticateSession({});
|
authenticateSession({});
|
||||||
|
featuresService = this.owner.lookup('service:features');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Users can navigate to workers with proper authorization', async function (assert) {
|
test('Users can navigate to workers with proper authorization', async function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
featuresService.enable('byow');
|
||||||
await visit(urls.globalScope);
|
await visit(urls.globalScope);
|
||||||
assert.ok(
|
assert.ok(
|
||||||
instances.scopes.global.authorized_collection_actions.workers.includes(
|
instances.scopes.global.authorized_collection_actions.workers.includes(
|
||||||
@@ -50,6 +53,7 @@ module('Acceptance | workers | list', function (hooks) {
|
|||||||
|
|
||||||
test('Users cannot navigate to workers without list or create permissions', async function (assert) {
|
test('Users cannot navigate to workers without list or create permissions', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('byow');
|
||||||
instances.scopes.global.authorized_collection_actions.workers = [];
|
instances.scopes.global.authorized_collection_actions.workers = [];
|
||||||
|
|
||||||
await visit(urls.globalScope);
|
await visit(urls.globalScope);
|
||||||
@@ -58,6 +62,7 @@ module('Acceptance | workers | list', function (hooks) {
|
|||||||
|
|
||||||
test('Users can navigate to workers with only create permission', async function (assert) {
|
test('Users can navigate to workers with only create permission', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('byow');
|
||||||
instances.scopes.global.authorized_collection_actions.workers = [
|
instances.scopes.global.authorized_collection_actions.workers = [
|
||||||
'create:worker-led',
|
'create:worker-led',
|
||||||
];
|
];
|
||||||
@@ -68,6 +73,7 @@ module('Acceptance | workers | list', function (hooks) {
|
|||||||
|
|
||||||
test('Users can navigate to workers with only list permission', async function (assert) {
|
test('Users can navigate to workers with only list permission', async function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
featuresService.enable('byow');
|
||||||
instances.scopes.global.authorized_collection_actions.workers = ['list'];
|
instances.scopes.global.authorized_collection_actions.workers = ['list'];
|
||||||
|
|
||||||
await visit(urls.globalScope);
|
await visit(urls.globalScope);
|
||||||
|
|||||||
@@ -16,13 +16,11 @@ module(
|
|||||||
setupIntl(hooks);
|
setupIntl(hooks);
|
||||||
|
|
||||||
let featuresService;
|
let featuresService;
|
||||||
const targetWorkerFilterIngress = 'target-worker-filters-v2-ingress';
|
|
||||||
const targetWorkerFilterHCP = 'target-worker-filters-v2-hcp';
|
const targetWorkerFilterHCP = 'target-worker-filters-v2-hcp';
|
||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
featuresService = this.owner.lookup('service:features');
|
featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.enable(targetWorkerFilterHCP);
|
featuresService.enable(targetWorkerFilterHCP);
|
||||||
featuresService.disable(targetWorkerFilterIngress);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders the correct diagram when egress and ingress filter is false', async function (assert) {
|
test('it renders the correct diagram when egress and ingress filter is false', async function (assert) {
|
||||||
|
|||||||
@@ -17,12 +17,10 @@ module(
|
|||||||
|
|
||||||
let featuresService;
|
let featuresService;
|
||||||
const targetWorkerFilterIngress = 'target-worker-filters-v2-ingress';
|
const targetWorkerFilterIngress = 'target-worker-filters-v2-ingress';
|
||||||
const targetWorkerFilterHCP = 'target-worker-filters-v2-hcp';
|
|
||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
featuresService = this.owner.lookup('service:features');
|
featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.enable(targetWorkerFilterIngress);
|
featuresService.enable(targetWorkerFilterIngress);
|
||||||
featuresService.disable(targetWorkerFilterHCP);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders the correct diagram when egress and ingress filter is false', async function (assert) {
|
test('it renders the correct diagram when egress and ingress filter is false', async function (assert) {
|
||||||
|
|||||||
@@ -19,31 +19,32 @@ module('Integration | Component | worker-diagram/index', function (hooks) {
|
|||||||
|
|
||||||
test('it renders a single filter diagram', async function (assert) {
|
test('it renders a single filter diagram', async function (assert) {
|
||||||
featuresService = this.owner.lookup('service:features');
|
featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.disable(targetWorkerFilterIngress);
|
assert.expect(3);
|
||||||
featuresService.disable(targetWorkerFilterHCP);
|
|
||||||
assert.expect(1);
|
|
||||||
await render(hbs`<WorkerDiagram />`);
|
await render(hbs`<WorkerDiagram />`);
|
||||||
|
assert.false(featuresService.isEnabled(targetWorkerFilterIngress));
|
||||||
|
assert.false(featuresService.isEnabled(targetWorkerFilterHCP));
|
||||||
assert.dom('[data-test-single-filter-egress-off]').isVisible();
|
assert.dom('[data-test-single-filter-egress-off]').isVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders a dual filter diagram when `target-worker-filters-v2-ingress` is enabled', async function (assert) {
|
test('it renders a dual filter diagram when `target-worker-filters-v2-ingress` is enabled', async function (assert) {
|
||||||
featuresService = this.owner.lookup('service:features');
|
featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.enable(targetWorkerFilterIngress);
|
featuresService.enable(targetWorkerFilterIngress);
|
||||||
featuresService.disable(targetWorkerFilterHCP);
|
assert.expect(3);
|
||||||
assert.expect(1);
|
assert.true(featuresService.isEnabled(targetWorkerFilterIngress));
|
||||||
|
assert.false(featuresService.isEnabled(targetWorkerFilterHCP));
|
||||||
await render(hbs`<WorkerDiagram />`);
|
await render(hbs`<WorkerDiagram />`);
|
||||||
|
|
||||||
assert.dom('[data-test-dual-filter-egress-off-ingress-off]').isVisible();
|
assert.dom('[data-test-dual-filter-egress-off-ingress-off]').isVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders a HCP dual filter diagram when `target-worker-filters-v2-hcp` is enabled', async function (assert) {
|
test('it renders an HCP dual filter diagram when `target-worker-filters-v2-hcp` is enabled', async function (assert) {
|
||||||
featuresService = this.owner.lookup('service:features');
|
featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.enable(targetWorkerFilterIngress);
|
featuresService.enable(targetWorkerFilterIngress);
|
||||||
featuresService.enable(targetWorkerFilterHCP);
|
featuresService.enable(targetWorkerFilterHCP);
|
||||||
assert.expect(1);
|
assert.expect(3);
|
||||||
await render(hbs`<WorkerDiagram />`);
|
await render(hbs`<WorkerDiagram />`);
|
||||||
|
assert.true(featuresService.isEnabled(targetWorkerFilterIngress));
|
||||||
|
assert.true(featuresService.isEnabled(targetWorkerFilterHCP));
|
||||||
assert
|
assert
|
||||||
.dom('[data-test-dual-filter-hcp-egress-off-ingress-off]')
|
.dom('[data-test-dual-filter-hcp-egress-off-ingress-off]')
|
||||||
.isVisible();
|
.isVisible();
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ module('Unit | Abilities | credential-library', function (hooks) {
|
|||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
features = this.owner.lookup('service:features');
|
features = this.owner.lookup('service:features');
|
||||||
features.enable('ssh-target');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can read credential library type when authorized and feature is enabled', function (assert) {
|
test('can read credential library type when authorized and feature is enabled', function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
features.enable('ssh-target');
|
||||||
const canService = this.owner.lookup('service:can');
|
const canService = this.owner.lookup('service:can');
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const credentialLibrary = store.createRecord('credential-library', {
|
const credentialLibrary = store.createRecord('credential-library', {
|
||||||
@@ -35,6 +35,7 @@ module('Unit | Abilities | credential-library', function (hooks) {
|
|||||||
|
|
||||||
test('cannot read credential library type when unauthorized and feature is enabled', function (assert) {
|
test('cannot read credential library type when unauthorized and feature is enabled', function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
features.enable('ssh-target');
|
||||||
const canService = this.owner.lookup('service:can');
|
const canService = this.owner.lookup('service:can');
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const credentialLibrary = store.createRecord('credential-library', {
|
const credentialLibrary = store.createRecord('credential-library', {
|
||||||
@@ -47,30 +48,30 @@ module('Unit | Abilities | credential-library', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot read credential library type when unauthorized and feature is disabled', function (assert) {
|
test('cannot read credential library type when unauthorized and feature is disabled', function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(3);
|
||||||
const canService = this.owner.lookup('service:can');
|
const canService = this.owner.lookup('service:can');
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const featuresService = this.owner.lookup('service:features');
|
const featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.disable('ssh-target');
|
|
||||||
const credentialLibrary = store.createRecord('credential-library', {
|
const credentialLibrary = store.createRecord('credential-library', {
|
||||||
authorized_actions: [],
|
authorized_actions: [],
|
||||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
||||||
});
|
});
|
||||||
|
assert.false(featuresService.isEnabled('ssh-target'));
|
||||||
assert.false(canService.can('read credential-library', credentialLibrary));
|
assert.false(canService.can('read credential-library', credentialLibrary));
|
||||||
credentialLibrary.type = TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC;
|
credentialLibrary.type = TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC;
|
||||||
assert.false(canService.can('read credential-library', credentialLibrary));
|
assert.false(canService.can('read credential-library', credentialLibrary));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can read vault-generic but not vault-ssh-certificate when authorized and feature is disabled', function (assert) {
|
test('can read vault-generic but not vault-ssh-certificate when authorized and feature is disabled', function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(3);
|
||||||
const canService = this.owner.lookup('service:can');
|
const canService = this.owner.lookup('service:can');
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const featuresService = this.owner.lookup('service:features');
|
const featuresService = this.owner.lookup('service:features');
|
||||||
featuresService.disable('ssh-target');
|
|
||||||
const credentialLibrary = store.createRecord('credential-library', {
|
const credentialLibrary = store.createRecord('credential-library', {
|
||||||
authorized_actions: ['read'],
|
authorized_actions: ['read'],
|
||||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
||||||
});
|
});
|
||||||
|
assert.false(featuresService.isEnabled('ssh-target'));
|
||||||
assert.false(canService.can('read credential-library', credentialLibrary));
|
assert.false(canService.can('read credential-library', credentialLibrary));
|
||||||
credentialLibrary.type = TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC;
|
credentialLibrary.type = TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC;
|
||||||
assert.true(canService.can('read credential-library', credentialLibrary));
|
assert.true(canService.can('read credential-library', credentialLibrary));
|
||||||
|
|||||||
@@ -9,16 +9,16 @@ import { setupTest } from 'ember-qunit';
|
|||||||
module('Unit | Abilities | credential', function (hooks) {
|
module('Unit | Abilities | credential', function (hooks) {
|
||||||
setupTest(hooks);
|
setupTest(hooks);
|
||||||
|
|
||||||
let features;
|
let featuresService;
|
||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
// Enable json-credentials feature by default
|
// Enable json-credentials feature by default
|
||||||
features = this.owner.lookup('service:features');
|
featuresService = this.owner.lookup('service:features');
|
||||||
features.enable('json-credentials');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can read credentials, including JSON credentials, when authorized and json-credentials feature is enabled', function (assert) {
|
test('can read credentials, including JSON credentials, when authorized and json-credentials feature is enabled', function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(3);
|
||||||
|
featuresService.enable('json-credentials');
|
||||||
const service = this.owner.lookup('service:can');
|
const service = this.owner.lookup('service:can');
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const credential = store.createRecord('credential', {
|
const credential = store.createRecord('credential', {
|
||||||
@@ -34,6 +34,7 @@ module('Unit | Abilities | credential', function (hooks) {
|
|||||||
|
|
||||||
test('cannot read credentials, including JSON credentials, when unauthorized and json-credentials feature is enabled', function (assert) {
|
test('cannot read credentials, including JSON credentials, when unauthorized and json-credentials feature is enabled', function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(3);
|
||||||
|
featuresService.enable('json-credentials');
|
||||||
const service = this.owner.lookup('service:can');
|
const service = this.owner.lookup('service:can');
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const credential = store.createRecord('credential', {
|
const credential = store.createRecord('credential', {
|
||||||
@@ -48,15 +49,14 @@ module('Unit | Abilities | credential', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('cannot read credentials, including JSON credentials, when unauthorized and json-credentials feature is disabled', function (assert) {
|
test('cannot read credentials, including JSON credentials, when unauthorized and json-credentials feature is disabled', function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(4);
|
||||||
const service = this.owner.lookup('service:can');
|
const service = this.owner.lookup('service:can');
|
||||||
const featuresService = this.owner.lookup('service:features');
|
|
||||||
featuresService.disable('json-credentials');
|
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const credential = store.createRecord('credential', {
|
const credential = store.createRecord('credential', {
|
||||||
authorized_actions: [],
|
authorized_actions: [],
|
||||||
type: 'json',
|
type: 'json',
|
||||||
});
|
});
|
||||||
|
assert.false(featuresService.isEnabled('json-credentials'));
|
||||||
assert.false(service.can('read credential', credential));
|
assert.false(service.can('read credential', credential));
|
||||||
credential.type = 'username_password';
|
credential.type = 'username_password';
|
||||||
assert.false(service.can('read credential', credential));
|
assert.false(service.can('read credential', credential));
|
||||||
@@ -65,14 +65,14 @@ module('Unit | Abilities | credential', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can read credentials, excepting JSON credentials, when authorized and json-credentials feature is disabled', function (assert) {
|
test('can read credentials, excepting JSON credentials, when authorized and json-credentials feature is disabled', function (assert) {
|
||||||
assert.expect(3);
|
assert.expect(4);
|
||||||
features.disable('json-credentials');
|
|
||||||
const service = this.owner.lookup('service:can');
|
const service = this.owner.lookup('service:can');
|
||||||
const store = this.owner.lookup('service:store');
|
const store = this.owner.lookup('service:store');
|
||||||
const credential = store.createRecord('credential', {
|
const credential = store.createRecord('credential', {
|
||||||
authorized_actions: ['read'],
|
authorized_actions: ['read'],
|
||||||
type: 'json',
|
type: 'json',
|
||||||
});
|
});
|
||||||
|
assert.false(featuresService.isEnabled('json-credentials'));
|
||||||
assert.false(service.can('read credential', credential));
|
assert.false(service.can('read credential', credential));
|
||||||
credential.type = 'username_password';
|
credential.type = 'username_password';
|
||||||
assert.true(service.can('read credential', credential));
|
assert.true(service.can('read credential', credential));
|
||||||
|
|||||||
Reference in new issue
Block a user