mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-03 20:17:59 +00:00 
			
		
		
		
	UI/utils cleanup (#21863)
* key-utils: create core addon and tests * key-util: remove lib/key-utils and replace all imports with core util
This commit is contained in:
		@@ -7,11 +7,10 @@ import { inject as service } from '@ember/service';
 | 
			
		||||
import { alias, gt } from '@ember/object/computed';
 | 
			
		||||
import Component from '@ember/component';
 | 
			
		||||
import { computed } from '@ember/object';
 | 
			
		||||
import keyUtils from 'vault/lib/key-utils';
 | 
			
		||||
import pathToTree from 'vault/lib/path-to-tree';
 | 
			
		||||
import { task, timeout } from 'ember-concurrency';
 | 
			
		||||
import pathToTree from 'vault/lib/path-to-tree';
 | 
			
		||||
import { ancestorKeysForKey } from 'core/utils/key-utils';
 | 
			
		||||
 | 
			
		||||
const { ancestorKeysForKey } = keyUtils;
 | 
			
		||||
const DOT_REPLACEMENT = '☃';
 | 
			
		||||
const ANIMATION_DURATION = 250;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
import { computed } from '@ember/object';
 | 
			
		||||
import Controller, { inject as controller } from '@ember/controller';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import ListController from 'core/mixins/list-controller';
 | 
			
		||||
import { keyIsFolder } from 'core/utils/key-utils';
 | 
			
		||||
 | 
			
		||||
export default Controller.extend(ListController, {
 | 
			
		||||
  flashMessages: service(),
 | 
			
		||||
@@ -26,7 +26,7 @@ export default Controller.extend(ListController, {
 | 
			
		||||
  isLoading: false,
 | 
			
		||||
 | 
			
		||||
  filterIsFolder: computed('filter', function () {
 | 
			
		||||
    return !!utils.keyIsFolder(this.filter);
 | 
			
		||||
    return !!keyIsFolder(this.filter);
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  emptyTitle: computed('baseKey.id', 'filter', 'filterIsFolder', function () {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,10 +7,10 @@ import { or } from '@ember/object/computed';
 | 
			
		||||
import { computed } from '@ember/object';
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
import Controller from '@ember/controller';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import BackendCrumbMixin from 'vault/mixins/backend-crumb';
 | 
			
		||||
import WithNavToNearestAncestor from 'vault/mixins/with-nav-to-nearest-ancestor';
 | 
			
		||||
import ListController from 'core/mixins/list-controller';
 | 
			
		||||
import { keyIsFolder } from 'core/utils/key-utils';
 | 
			
		||||
 | 
			
		||||
export default Controller.extend(ListController, BackendCrumbMixin, WithNavToNearestAncestor, {
 | 
			
		||||
  flashMessages: service(),
 | 
			
		||||
@@ -19,7 +19,7 @@ export default Controller.extend(ListController, BackendCrumbMixin, WithNavToNea
 | 
			
		||||
  tab: '',
 | 
			
		||||
 | 
			
		||||
  filterIsFolder: computed('filter', function () {
 | 
			
		||||
    return !!utils.keyIsFolder(this.filter);
 | 
			
		||||
    return !!keyIsFolder(this.filter);
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  isConfigurableTab: or('isCertTab', 'isConfigure'),
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
 | 
			
		||||
import { computed } from '@ember/object';
 | 
			
		||||
import Mixin from '@ember/object/mixin';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import { keyIsFolder, keyPartsForKey, parentKeyForKey } from 'core/utils/key-utils';
 | 
			
		||||
 | 
			
		||||
export default Mixin.create({
 | 
			
		||||
  // what attribute has the path for the key
 | 
			
		||||
@@ -26,16 +26,16 @@ export default Mixin.create({
 | 
			
		||||
  // rather than using defineProperty for all of these,
 | 
			
		||||
  // we're just going to hardcode the known keys for the path ('id' and 'path')
 | 
			
		||||
  isFolder: computed('id', 'path', function () {
 | 
			
		||||
    return utils.keyIsFolder(this.pathVal());
 | 
			
		||||
    return keyIsFolder(this.pathVal());
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  keyParts: computed('id', 'path', function () {
 | 
			
		||||
    return utils.keyPartsForKey(this.pathVal());
 | 
			
		||||
    return keyPartsForKey(this.pathVal());
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  parentKey: computed('id', 'path', 'isCreating', {
 | 
			
		||||
    get: function () {
 | 
			
		||||
      return this.isCreating ? this.initialParentKey : utils.parentKeyForKey(this.pathVal());
 | 
			
		||||
      return this.isCreating ? this.initialParentKey : parentKeyForKey(this.pathVal());
 | 
			
		||||
    },
 | 
			
		||||
    set: function (_, value) {
 | 
			
		||||
      return value;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,8 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import Mixin from '@ember/object/mixin';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import { task } from 'ember-concurrency';
 | 
			
		||||
import { ancestorKeysForKey } from 'core/utils/key-utils';
 | 
			
		||||
 | 
			
		||||
// This mixin is currently used in a controller and a component, but we
 | 
			
		||||
// don't see cancellation of the task as the while loop runs in either
 | 
			
		||||
@@ -18,7 +18,7 @@ import { task } from 'ember-concurrency';
 | 
			
		||||
// the ancestors array and transitions to the root
 | 
			
		||||
export default Mixin.create({
 | 
			
		||||
  navToNearestAncestor: task(function* (key) {
 | 
			
		||||
    const ancestors = utils.ancestorKeysForKey(key);
 | 
			
		||||
    const ancestors = ancestorKeysForKey(key);
 | 
			
		||||
    let errored = false;
 | 
			
		||||
    let nearest = ancestors.pop();
 | 
			
		||||
    while (nearest) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,20 +3,20 @@
 | 
			
		||||
 * SPDX-License-Identifier: MPL-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { set } from '@ember/object';
 | 
			
		||||
import { hash } from 'rsvp';
 | 
			
		||||
import { set } from '@ember/object';
 | 
			
		||||
import Route from '@ember/routing/route';
 | 
			
		||||
import UnloadModelRoute from 'vault/mixins/unload-model-route';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
import { keyIsFolder, parentKeyForKey } from 'core/utils/key-utils';
 | 
			
		||||
import UnloadModelRoute from 'vault/mixins/unload-model-route';
 | 
			
		||||
 | 
			
		||||
export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
  store: service(),
 | 
			
		||||
 | 
			
		||||
  beforeModel() {
 | 
			
		||||
    const { lease_id: leaseId } = this.paramsFor(this.routeName);
 | 
			
		||||
    const parentKey = utils.parentKeyForKey(leaseId);
 | 
			
		||||
    if (utils.keyIsFolder(leaseId)) {
 | 
			
		||||
    const parentKey = parentKeyForKey(leaseId);
 | 
			
		||||
    if (keyIsFolder(leaseId)) {
 | 
			
		||||
      if (parentKey) {
 | 
			
		||||
        return this.transitionTo('vault.cluster.access.leases.list', parentKey);
 | 
			
		||||
      } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,8 @@
 | 
			
		||||
 * SPDX-License-Identifier: MPL-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { parentKeyForKey } from 'core/utils/key-utils';
 | 
			
		||||
import EditBase from './secret-edit';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
 | 
			
		||||
export default EditBase.extend({
 | 
			
		||||
  queryParams: {
 | 
			
		||||
@@ -17,7 +17,7 @@ export default EditBase.extend({
 | 
			
		||||
 | 
			
		||||
  beforeModel() {
 | 
			
		||||
    const { secret } = this.paramsFor(this.routeName);
 | 
			
		||||
    const parentKey = utils.parentKeyForKey(secret);
 | 
			
		||||
    const parentKey = parentKeyForKey(secret);
 | 
			
		||||
    const { backend } = this.paramsFor('vault.cluster.secrets.backend');
 | 
			
		||||
    if (this.backendType(backend) !== 'transit') {
 | 
			
		||||
      if (parentKey) {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,9 @@ import { set } from '@ember/object';
 | 
			
		||||
import { resolve } from 'rsvp';
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
import Route from '@ember/routing/route';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import UnloadModelRoute from 'vault/mixins/unload-model-route';
 | 
			
		||||
import { encodePath, normalizePath } from 'vault/utils/path-encoding-helpers';
 | 
			
		||||
import { keyIsFolder, parentKeyForKey } from 'core/utils/key-utils';
 | 
			
		||||
 | 
			
		||||
export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
  store: service(),
 | 
			
		||||
@@ -79,9 +79,9 @@ export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
  beforeModel({ to: { queryParams } }) {
 | 
			
		||||
    const secret = this.secretParam();
 | 
			
		||||
    return this.buildModel(secret, queryParams).then(() => {
 | 
			
		||||
      const parentKey = utils.parentKeyForKey(secret);
 | 
			
		||||
      const parentKey = parentKeyForKey(secret);
 | 
			
		||||
      const mode = this.routeName.split('.').pop();
 | 
			
		||||
      if (mode === 'edit' && utils.keyIsFolder(secret)) {
 | 
			
		||||
      if (mode === 'edit' && keyIsFolder(secret)) {
 | 
			
		||||
        if (parentKey) {
 | 
			
		||||
          return this.transitionTo('vault.cluster.secrets.backend.list', encodePath(parentKey));
 | 
			
		||||
        } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,10 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import Route from '@ember/routing/route';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import UnloadModelRoute from 'vault/mixins/unload-model-route';
 | 
			
		||||
import { normalizePath } from 'vault/utils/path-encoding-helpers';
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
import { parentKeyForKey } from 'core/utils/key-utils';
 | 
			
		||||
 | 
			
		||||
export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
  store: service(),
 | 
			
		||||
@@ -16,7 +16,7 @@ export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
  beforeModel() {
 | 
			
		||||
    const backendModel = this.modelFor('vault.cluster.secrets.backend');
 | 
			
		||||
    const { secret } = this.paramsFor(this.routeName);
 | 
			
		||||
    const parentKey = utils.parentKeyForKey(secret);
 | 
			
		||||
    const parentKey = parentKeyForKey(secret);
 | 
			
		||||
    if (backendModel.get('isV2KV')) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import Component from '@glimmer/component';
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import { ancestorKeysForKey, keyPartsForKey, keyWithoutParentKey } from 'core/utils/key-utils';
 | 
			
		||||
import { encodePath } from 'vault/utils/path-encoding-helpers';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -60,8 +60,8 @@ export default class KeyValueHeader extends Component {
 | 
			
		||||
    const path = this.args.path;
 | 
			
		||||
    const currentPath = this.currentPath;
 | 
			
		||||
    const showCurrent = this.showCurrent;
 | 
			
		||||
    const ancestors = utils.ancestorKeysForKey(baseKey);
 | 
			
		||||
    const parts = utils.keyPartsForKey(baseKey);
 | 
			
		||||
    const ancestors = ancestorKeysForKey(baseKey);
 | 
			
		||||
    const parts = keyPartsForKey(baseKey);
 | 
			
		||||
    if (ancestors.length === 0) {
 | 
			
		||||
      crumbs.push({
 | 
			
		||||
        label: baseKey,
 | 
			
		||||
@@ -87,8 +87,8 @@ export default class KeyValueHeader extends Component {
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    crumbs.push({
 | 
			
		||||
      label: utils.keyWithoutParentKey(baseKey),
 | 
			
		||||
      text: this.stripTrailingSlash(utils.keyWithoutParentKey(baseKey)),
 | 
			
		||||
      label: keyWithoutParentKey(baseKey),
 | 
			
		||||
      text: this.stripTrailingSlash(keyWithoutParentKey(baseKey)),
 | 
			
		||||
      path: currentPath,
 | 
			
		||||
      model: baseKeyModel,
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -3,17 +3,17 @@
 | 
			
		||||
 * SPDX-License-Identifier: MPL-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import Ember from 'ember';
 | 
			
		||||
import { debounce, later } from '@ember/runloop';
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
import { action } from '@ember/object';
 | 
			
		||||
import { guidFor } from '@ember/object/internals';
 | 
			
		||||
import Component from '@glimmer/component';
 | 
			
		||||
 | 
			
		||||
// TODO MOVE THESE TO THE ADDON
 | 
			
		||||
import utils from 'vault/lib/key-utils';
 | 
			
		||||
import keys from 'vault/lib/keycodes';
 | 
			
		||||
import { encodePath } from 'vault/utils/path-encoding-helpers';
 | 
			
		||||
import Ember from 'ember';
 | 
			
		||||
import { keyIsFolder, parentKeyForKey } from 'core/utils/key-utils';
 | 
			
		||||
// TODO MOVE THESE TO THE ADDON
 | 
			
		||||
import keys from 'vault/lib/keycodes';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @module NavigateInput
 | 
			
		||||
@@ -94,7 +94,7 @@ export default class NavigateInput extends Component {
 | 
			
		||||
    if (mode.startsWith('secrets') && (!val || val === baseKey)) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (this.args.filterMatchesKey && !utils.keyIsFolder(val)) {
 | 
			
		||||
    if (this.args.filterMatchesKey && !keyIsFolder(val)) {
 | 
			
		||||
      const params = [routeFor('show', mode, this.args.urls), extraParams, this.keyForNav(val)].compact();
 | 
			
		||||
      this.transitionToRoute(...params);
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -126,7 +126,7 @@ export default class NavigateInput extends Component {
 | 
			
		||||
 | 
			
		||||
  // pop to the nearest parentKey or to the root
 | 
			
		||||
  onEscape(val) {
 | 
			
		||||
    const key = utils.parentKeyForKey(val) || '';
 | 
			
		||||
    const key = parentKeyForKey(val) || '';
 | 
			
		||||
    this.args.filterDidChange(key);
 | 
			
		||||
    this.filterUpdated(key);
 | 
			
		||||
  }
 | 
			
		||||
@@ -150,11 +150,11 @@ export default class NavigateInput extends Component {
 | 
			
		||||
    }
 | 
			
		||||
    // select the key to nav to, assumed to be a folder
 | 
			
		||||
    let key = val ? val.trim() : '';
 | 
			
		||||
    const isFolder = utils.keyIsFolder(key);
 | 
			
		||||
    const isFolder = keyIsFolder(key);
 | 
			
		||||
 | 
			
		||||
    if (!isFolder) {
 | 
			
		||||
      // nav to the closest parentKey (or the root)
 | 
			
		||||
      key = utils.parentKeyForKey(val) || '';
 | 
			
		||||
      key = parentKeyForKey(val) || '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const pageFilter = val.replace(key, '');
 | 
			
		||||
@@ -167,7 +167,7 @@ export default class NavigateInput extends Component {
 | 
			
		||||
    if (key) {
 | 
			
		||||
      args.push(key);
 | 
			
		||||
    }
 | 
			
		||||
    if (pageFilter && !utils.keyIsFolder(pageFilter)) {
 | 
			
		||||
    if (pageFilter && !keyIsFolder(pageFilter)) {
 | 
			
		||||
      args.push({
 | 
			
		||||
        queryParams: {
 | 
			
		||||
          page: 1,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,37 +3,38 @@
 | 
			
		||||
 * SPDX-License-Identifier: MPL-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function keyIsFolder(key) {
 | 
			
		||||
export function keyIsFolder(key: string) {
 | 
			
		||||
  return key ? !!key.match(/\/$/) : false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function keyPartsForKey(key) {
 | 
			
		||||
export function keyPartsForKey(key: string) {
 | 
			
		||||
  if (!key) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
  var isFolder = keyIsFolder(key);
 | 
			
		||||
  var parts = key.split('/');
 | 
			
		||||
  const isFolder = keyIsFolder(key);
 | 
			
		||||
  const parts = key.split('/');
 | 
			
		||||
  if (isFolder) {
 | 
			
		||||
    // remove last item which is empty
 | 
			
		||||
    parts.pop();
 | 
			
		||||
  }
 | 
			
		||||
  return parts.length > 1 ? parts : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parentKeyForKey(key) {
 | 
			
		||||
  var parts = keyPartsForKey(key);
 | 
			
		||||
export function parentKeyForKey(key: string) {
 | 
			
		||||
  const parts = keyPartsForKey(key);
 | 
			
		||||
  if (!parts) {
 | 
			
		||||
    return null;
 | 
			
		||||
    return '';
 | 
			
		||||
  }
 | 
			
		||||
  return parts.slice(0, -1).join('/') + '/';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function keyWithoutParentKey(key) {
 | 
			
		||||
export function keyWithoutParentKey(key: string) {
 | 
			
		||||
  return key ? key.replace(parentKeyForKey(key), '') : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ancestorKeysForKey(key) {
 | 
			
		||||
  var ancestors = [],
 | 
			
		||||
    parentKey = parentKeyForKey(key);
 | 
			
		||||
export function ancestorKeysForKey(key: string) {
 | 
			
		||||
  const ancestors = [];
 | 
			
		||||
  let parentKey = parentKeyForKey(key);
 | 
			
		||||
 | 
			
		||||
  while (parentKey) {
 | 
			
		||||
    ancestors.unshift(parentKey);
 | 
			
		||||
@@ -42,11 +43,3 @@ function ancestorKeysForKey(key) {
 | 
			
		||||
 | 
			
		||||
  return ancestors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  keyIsFolder,
 | 
			
		||||
  keyPartsForKey,
 | 
			
		||||
  parentKeyForKey,
 | 
			
		||||
  keyWithoutParentKey,
 | 
			
		||||
  ancestorKeysForKey,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										7
									
								
								ui/lib/core/app/utils/key-utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								ui/lib/core/app/utils/key-utils.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
export {
 | 
			
		||||
  keyIsFolder,
 | 
			
		||||
  keyPartsForKey,
 | 
			
		||||
  parentKeyForKey,
 | 
			
		||||
  keyWithoutParentKey,
 | 
			
		||||
  ancestorKeysForKey,
 | 
			
		||||
} from 'core/utils/key-utils';
 | 
			
		||||
							
								
								
									
										62
									
								
								ui/tests/unit/utils/key-utils-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								ui/tests/unit/utils/key-utils-test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
import {
 | 
			
		||||
  ancestorKeysForKey,
 | 
			
		||||
  keyIsFolder,
 | 
			
		||||
  keyPartsForKey,
 | 
			
		||||
  keyWithoutParentKey,
 | 
			
		||||
  parentKeyForKey,
 | 
			
		||||
} from 'vault/utils/key-utils';
 | 
			
		||||
import { module, test } from 'qunit';
 | 
			
		||||
 | 
			
		||||
module('Unit | Utility | key-utils', function () {
 | 
			
		||||
  test('keyIsFolder', function (assert) {
 | 
			
		||||
    let result = keyIsFolder('foo');
 | 
			
		||||
    assert.false(result, 'not folder');
 | 
			
		||||
 | 
			
		||||
    result = keyIsFolder('foo/');
 | 
			
		||||
    assert.true(result, 'is folder');
 | 
			
		||||
 | 
			
		||||
    result = keyIsFolder('foo/bar');
 | 
			
		||||
    assert.false(result, 'not folder');
 | 
			
		||||
  });
 | 
			
		||||
  test('keyPartsForKey', function (assert) {
 | 
			
		||||
    let result = keyPartsForKey('');
 | 
			
		||||
    assert.strictEqual(result, null, 'falsy value returns null');
 | 
			
		||||
 | 
			
		||||
    result = keyPartsForKey('foo');
 | 
			
		||||
    assert.strictEqual(result, null, 'returns null if not a folder');
 | 
			
		||||
 | 
			
		||||
    result = keyPartsForKey('foo/bar');
 | 
			
		||||
    assert.deepEqual(result, ['foo', 'bar'], 'returns parts of key');
 | 
			
		||||
 | 
			
		||||
    result = keyPartsForKey('foo/bar/');
 | 
			
		||||
    assert.deepEqual(result, ['foo', 'bar'], 'returns parts of key when ends in slash');
 | 
			
		||||
  });
 | 
			
		||||
  test('parentKeyForKey', function (assert) {
 | 
			
		||||
    let result = parentKeyForKey('my/very/nested/secret/path');
 | 
			
		||||
    assert.strictEqual(result, 'my/very/nested/secret/', 'returns parent path for key');
 | 
			
		||||
 | 
			
		||||
    result = parentKeyForKey('my/nested/secret/');
 | 
			
		||||
    assert.strictEqual(result, 'my/nested/', 'returns correct parents');
 | 
			
		||||
 | 
			
		||||
    result = parentKeyForKey('my-secret');
 | 
			
		||||
    assert.strictEqual(result, '', 'returns empty string when no parents');
 | 
			
		||||
  });
 | 
			
		||||
  test('keyWithoutParentKey', function (assert) {
 | 
			
		||||
    let result = keyWithoutParentKey('my/very/nested/secret/path');
 | 
			
		||||
    assert.strictEqual(result, 'path', 'returns key without parent key');
 | 
			
		||||
 | 
			
		||||
    result = keyWithoutParentKey('my-secret');
 | 
			
		||||
    assert.strictEqual(result, 'my-secret', 'returns path when no parent');
 | 
			
		||||
 | 
			
		||||
    result = keyWithoutParentKey('folder/');
 | 
			
		||||
    assert.strictEqual(result, 'folder/', 'returns path as-is when folder without parent');
 | 
			
		||||
  });
 | 
			
		||||
  test('ancestorKeysForKey', function (assert) {
 | 
			
		||||
    const expected = ['my/', 'my/very/', 'my/very/nested/', 'my/very/nested/secret/'];
 | 
			
		||||
    let result = ancestorKeysForKey('my/very/nested/secret/path');
 | 
			
		||||
    assert.deepEqual(result, expected, 'returns array of ancestor paths');
 | 
			
		||||
 | 
			
		||||
    result = ancestorKeysForKey('foobar');
 | 
			
		||||
    assert.deepEqual(result, [], 'returns empty array for root path');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user