Chore/update model names (#125)

* chore: 🤖 Rename recording to session-recording

* chore: 🤖 Update names for connection models

* chore: 🤖 Update channel models to new name

* chore: 🤖 Update remaining models after merge conflict
This commit is contained in:
Zhihe Li authored and GitHub committed 2023-03-16 13:49:04 -04:00
1 parent 24f50b3e2d
commit d08ce29e5a
46 files changed
+442 -372

No files matched your search

@@ -8,7 +8,7 @@ import ModelAbility from './model';
/**
* Provides abilities for session recordings.
*/
export default class RecordingAbility extends ModelAbility {
export default class SessionRecordingAbility extends ModelAbility {
// =services
// =permissions
@@ -9,7 +9,7 @@ import { attr } from '@ember-data/model';
/**
* A channel contains data for a single channel within a connection.
*/
export default class GeneratedChannelModel extends BaseModel {
export default class GeneratedChannelRecordingModel extends BaseModel {
// =attributes
@attr('string', {
@@ -9,7 +9,7 @@ import { attr } from '@ember-data/model';
/**
* A connection contains data for a boundary connection within a session.
*/
export default class GeneratedConnectionModel extends BaseModel {
export default class GeneratedConnectionRecordingModel extends BaseModel {
// =attributes
@attr('number', {
@@ -7,9 +7,9 @@ import BaseModel from '../../models/base';
import { attr } from '@ember-data/model';
/**
* A recording contains all data related to session recordings
* A session recording contains all data related to session recordings
*/
export default class GeneratedRecordingModel extends BaseModel {
export default class GeneratedSessionRecordingModel extends BaseModel {
// =attributes
@attr('string', {
@@ -0,0 +1,27 @@
import GeneratedChannelRecordingModel from '../generated/models/channel-recording';
import { belongsTo } from '@ember-data/model';
export const TYPE_CHANNEL_RECORDING_SESSION = 'session';
export const TYPES_CHANNEL_RECORDING = Object.freeze([
TYPE_CHANNEL_RECORDING_SESSION,
]);
export default class ChannelRecordingModel extends GeneratedChannelRecordingModel {
@belongsTo('connection-recording') connection_recording;
/**
* True if the channel type is `session`.
* @type {boolean}
*/
get isSession() {
return this.type === TYPE_CHANNEL_RECORDING_SESSION;
}
/**
* True if the channel is an unknown type.
* @type {boolean}
*/
get isUnknown() {
return !TYPES_CHANNEL_RECORDING.includes(this.type);
}
}
-25
View File
@@ -1,25 +0,0 @@
import GeneratedChannelModel from '../generated/models/channel';
import { belongsTo } from '@ember-data/model';
export const TYPE_CHANNEL_SESSION = 'session';
export const TYPES_CHANNEL = Object.freeze([TYPE_CHANNEL_SESSION]);
export default class ChannelModel extends GeneratedChannelModel {
@belongsTo('connection') connection;
/**
* True if the channel type is `session`.
* @type {boolean}
*/
get isSession() {
return this.type === TYPE_CHANNEL_SESSION;
}
/**
* True if the channel is an unknown type.
* @type {boolean}
*/
get isUnknown() {
return !TYPES_CHANNEL.includes(this.type);
}
}
@@ -0,0 +1,7 @@
import GeneratedConnectionRecordingModel from '../generated/models/connection-recording';
import { belongsTo, hasMany } from '@ember-data/model';
export default class ConnectionRecordingModel extends GeneratedConnectionRecordingModel {
@belongsTo('session-recording') session_recording;
@hasMany('channel-recording') channel_recordings;
}
-7
View File
@@ -1,7 +0,0 @@
import GeneratedConnectionModel from '../generated/models/connection';
import { belongsTo, hasMany } from '@ember-data/model';
export default class ConnectionModel extends GeneratedConnectionModel {
@belongsTo('recording') recording;
@hasMany('channel') channels;
}
-25
View File
@@ -1,25 +0,0 @@
import GeneratedRecordingModel from '../generated/models/recording';
import { hasMany } from '@ember-data/model';
export const TYPE_RECORDING_SSH = 'ssh';
export const TYPES_RECORDING = Object.freeze([TYPE_RECORDING_SSH]);
export default class RecordingModel extends GeneratedRecordingModel {
@hasMany('connection') connections;
/**
* True if the recording type is `ssh`.
* @type {boolean}
*/
get isSSH() {
return this.type === TYPE_RECORDING_SSH;
}
/**
* True if the recording is an unknown type.
* @type {boolean}
*/
get isUnknown() {
return !TYPES_RECORDING.includes(this.type);
}
}
@@ -0,0 +1,44 @@
import GeneratedSessionRecordingModel from '../generated/models/session-recording';
import { hasMany } from '@ember-data/model';
import { inject as service } from '@ember/service';
export const TYPE_SESSION_RECORDING_SSH = 'ssh';
export const TYPES_SESSION_RECORDING = Object.freeze([
TYPE_SESSION_RECORDING_SSH,
]);
export default class SessionRecordingModel extends GeneratedSessionRecordingModel {
@hasMany('connection-recording') connection_recordings;
@service store;
/**
* True if the session recording type is `ssh`.
* @type {boolean}
*/
get isSSH() {
return this.type === TYPE_SESSION_RECORDING_SSH;
}
/**
* True if the session recording is an unknown type.
* @type {boolean}
*/
get isUnknown() {
return !TYPES_SESSION_RECORDING.includes(this.type);
}
getAsciiCast({ connectionId, channelId, mimeType }) {
const adapter = this.store.adapterFor('application');
const options = { adapterOptions: { method: 'download' } };
const url = adapter.buildURL(
'session-recording',
this.id,
options,
'findRecord'
);
return adapter.ajax(url, 'GET', {
data: { connectionId, channelId, mimeType },
});
}
}
@@ -5,6 +5,6 @@ export default class ConnectionSerializer extends ApplicationSerializer.extend(
EmbeddedRecordsMixin
) {
attrs = {
channels: { embedded: 'always' },
channel_recordings: { embedded: 'always' },
};
}
@@ -4,6 +4,6 @@ export default class RecordingSerializer extends ApplicationSerializer.extend(
EmbeddedRecordsMixin
) {
attrs = {
connections: { embedded: 'always' },
connection_recordings: { embedded: 'always' },
};
}
@@ -0,0 +1 @@
export { default } from 'api/models/channel-recording';
-1
View File
@@ -1 +0,0 @@
export { default } from 'api/models/channel';
@@ -0,0 +1 @@
export { default } from 'api/models/connection-recording';
-1
View File
@@ -1 +0,0 @@
export { default } from 'api/models/connection';
-1
View File
@@ -1 +0,0 @@
export { default } from 'api/models/recording';
@@ -0,0 +1 @@
export { default } from 'api/models/session-recording';
@@ -0,0 +1 @@
export { default } from 'api/serializers/connection-recording';
-1
View File
@@ -1 +0,0 @@
export { default } from 'api/serializers/connection';
-1
View File
@@ -1 +0,0 @@
export { default } from 'api/serializers/recording';
@@ -0,0 +1 @@
export { default } from 'api/serializers/session-recording';
+4 -4
View File
@@ -688,12 +688,12 @@ function routes() {
// session recordings
this.get(
'/recordings',
({ recordings }, { queryParams: { scope_id: scopeId } }) => {
return recordings.where({ scopeId });
'/session-recordings',
({ sessionRecordings }, { queryParams: { scope_id: scopeId } }) => {
return sessionRecordings.where({ scopeId });
}
);
this.get('/recordings/:id');
this.get('/session-recordings/:id');
/* Uncomment the following line and the Response import above
* Then change the response code to simulate error responses.
@@ -3,9 +3,9 @@
* SPDX-License-Identifier: MPL-2.0
*/
import factory from '../generated/factories/channel';
import factory from '../generated/factories/channel-recording';
import generateId from '../helpers/id';
import { TYPES_CHANNEL as types } from 'api/models/channel';
import { TYPES_CHANNEL_RECORDING as types } from 'api/models/channel-recording';
export default factory.extend({
id: () => generateId('srcc_'),
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: MPL-2.0
*/
import factory from '../generated/factories/connection';
import factory from '../generated/factories/connection-recording';
import generateId from '../helpers/id';
export default factory.extend({
+1 -1
View File
@@ -40,7 +40,7 @@ export default factory.extend({
// Session recording resources are only available on global or org scope
if (this.type === 'global' || this.type === 'org') {
collectionActions['storage-buckets'] = ['create', 'list'];
collectionActions.recordings = ['list'];
collectionActions['session-recordings'] = ['list'];
}
return collectionActions;
@@ -3,12 +3,12 @@
* SPDX-License-Identifier: MPL-2.0
*/
import factory from '../generated/factories/recording';
import factory from '../generated/factories/session-recording';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
import { faker } from '@faker-js/faker';
import { trait } from 'miragejs';
import { TYPES_RECORDING as types } from 'api/models/recording';
import { TYPES_SESSION_RECORDING as types } from 'api/models/session-recording';
const pickRandomElement = (arr) => faker.helpers.arrayElement(arr);
export default factory.extend({
@@ -18,14 +18,14 @@ export default factory.extend({
type: (i) => types[i % types.length],
authorized_actions: () =>
permissions.authorizedActionsFor('recording') || [
permissions.authorizedActionsFor('session-recording') || [
'no-op',
'read',
'download',
],
withNonExistingUserAndTarget: trait({
afterCreate(recording, server) {
afterCreate(sessionRecording, server) {
const user = pickRandomElement(server.schema.users.all().models);
user.id = 'deleted_user';
const session = pickRandomElement(server.schema.sessions.all().models);
@@ -33,7 +33,7 @@ export default factory.extend({
const target = session.target;
target.id = 'deleted_target';
recording.update({
sessionRecording.update({
user,
target,
session,
@@ -42,12 +42,12 @@ export default factory.extend({
}),
withExistingUserAndTarget: trait({
afterCreate(recording, server) {
afterCreate(sessionRecording, server) {
const user = pickRandomElement(server.schema.users.all().models);
const session = pickRandomElement(server.schema.sessions.all().models);
const target = session.target;
recording.update({
sessionRecording.update({
user,
target,
session,
@@ -56,11 +56,11 @@ export default factory.extend({
}),
withConnectionAndChannels: trait({
afterCreate(recording, server) {
afterCreate(session_recording, server) {
server
.createList('connection', 3, { recording })
.forEach((connection) => {
server.createList('channel', 3, { connection });
.createList('connection-recording', 3, { session_recording })
.forEach((connection_recording) => {
server.createList('channel-recording', 3, { connection_recording });
});
},
}),
@@ -7,7 +7,7 @@ import { Factory } from 'miragejs';
import { faker } from '@faker-js/faker';
/**
* GeneratedChannelModelFactory
* GeneratedChannelRecordingModelFactory
*/
export default Factory.extend({
bytes_up: () => faker.datatype.number(),
@@ -7,7 +7,7 @@ import { Factory } from 'miragejs';
import { faker } from '@faker-js/faker';
/**
* GeneratedConnectionModelFactory
* GeneratedConnectionRecordingModelFactory
*/
export default Factory.extend({
bytes_up: () => faker.datatype.number(),
@@ -7,7 +7,7 @@ import { Factory } from 'miragejs';
import { faker } from '@faker-js/faker';
/**
* GeneratedRecordModelFactory
* GeneratedSessionRecordingModelFactory
*/
export default Factory.extend({
bytes_up: () => faker.datatype.number(),
@@ -6,5 +6,5 @@
import { belongsTo, Model } from 'miragejs';
export default Model.extend({
connection: belongsTo(),
connection_recording: belongsTo(),
});
@@ -6,6 +6,6 @@
import { belongsTo, hasMany, Model } from 'miragejs';
export default Model.extend({
recording: belongsTo(),
channels: hasMany(),
session_recording: belongsTo(),
channel_recordings: hasMany(),
});
@@ -10,5 +10,5 @@ export default Model.extend({
user: belongsTo(),
session: belongsTo(),
target: belongsTo(),
connections: hasMany(),
connection_recordings: hasMany(),
});
+3 -3
View File
@@ -114,20 +114,20 @@ export default function (server) {
server.createList('storage-bucket', 3, { scope: globalScope });
server.createList('storage-bucket', 2, { scope: orgScope });
server.createList(
'recording',
'session-recording',
3,
{ scope: globalScope },
'withConnectionAndChannels',
'withExistingUserAndTarget'
);
server.create(
'recording',
'session-recording',
{ scope: globalScope },
'withConnectionAndChannels',
'withNonExistingUserAndTarget'
);
server.createList(
'recording',
'session-recording',
2,
{ scope: orgScope },
'withConnectionAndChannels',
@@ -6,5 +6,5 @@
import ApplicationSerializer from './application';
export default ApplicationSerializer.extend({
modelName: 'channel',
modelName: 'channel-recording',
});
@@ -4,19 +4,19 @@
*/
import ApplicationSerializer from './application';
import ChannelSerializer from './channel';
import ChannelSerializer from './channel-recording';
export default ApplicationSerializer.extend({
modelName: 'connection',
modelName: 'connection-recording',
_hashForModel(model) {
const json = ApplicationSerializer.prototype._hashForModel.apply(
this,
arguments
);
const { channels } = this.schema;
if (model.channelIds) {
json.channels = model.channelIds.map((id) => {
const channel = channels.find(id);
const { channelRecordings } = this.schema;
if (model.channelRecordingIds) {
json.channel_recordings = model.channelRecordingIds.map((id) => {
const channel = channelRecordings.find(id);
return ChannelSerializer.prototype._hashForModel.apply(this, [channel]);
});
}
@@ -4,26 +4,27 @@
*/
import ApplicationSerializer from './application';
import ConnectionSerializer from './connection';
import ConnectionRecordingSerializer from './connection-recording';
import UserSerializer from './user';
import TargetSerializer from './target';
export default ApplicationSerializer.extend({
modelName: 'recording',
modelName: 'session-recording',
_hashForModel(model) {
const json = ApplicationSerializer.prototype._hashForModel.apply(
this,
arguments
);
const { connections, users, targets } = this.schema;
const { connectionRecordings, users, targets } = this.schema;
// Manually map our models to the actual embedded json representation
if (model.connectionIds) {
json.connections = model.connectionIds.map((id) => {
const connection = connections.find(id);
return ConnectionSerializer.prototype._hashForModel.apply(this, [
connection,
]);
if (model.connectionRecordingIds) {
json.connection_recordings = model.connectionRecordingIds.map((id) => {
const connection = connectionRecordings.find(id);
return ConnectionRecordingSerializer.prototype._hashForModel.apply(
this,
[connection]
);
});
}
if (model.userId) {
@@ -1,23 +1,23 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { TYPE_CHANNEL_SESSION } from 'api/models/channel';
import { TYPE_CHANNEL_RECORDING_SESSION } from 'api/models/channel-recording';
module('Unit | Model | channel', function (hooks) {
module('Unit | Model | channel-recording', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('channel', {});
let model = store.createRecord('channel-recording', {});
assert.ok(model);
});
test('it has isUnknown property and returns the expected values', async function (assert) {
assert.expect(2);
const store = this.owner.lookup('service:store');
const modelA = store.createRecord('channel', {
type: TYPE_CHANNEL_SESSION,
const modelA = store.createRecord('channel-recording', {
type: TYPE_CHANNEL_RECORDING_SESSION,
});
const modelB = store.createRecord('channel', {
const modelB = store.createRecord('channel-recording', {
type: 'no-such-type',
});
assert.false(modelA.isUnknown);
@@ -27,10 +27,10 @@ module('Unit | Model | channel', function (hooks) {
test('it has isSession property and returns the expected values', async function (assert) {
assert.expect(2);
const store = this.owner.lookup('service:store');
const modelA = store.createRecord('channel', {
type: TYPE_CHANNEL_SESSION,
const modelA = store.createRecord('channel-recording', {
type: TYPE_CHANNEL_RECORDING_SESSION,
});
const modelB = store.createRecord('channel', {
const modelB = store.createRecord('channel-recording', {
type: 'random',
});
assert.true(modelA.isSession);
@@ -1,23 +1,23 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Model | connection', function (hooks) {
module('Unit | Model | connection-recording', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('connection', {});
let model = store.createRecord('connection-recording', {});
assert.ok(model);
});
test('it has channels as a relationship', async function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const model = store.createRecord('connection', {
channels: [store.createRecord('channel')],
const model = store.createRecord('connection-recording', {
channel_recordings: [store.createRecord('channel-recording')],
});
const channels = await model.channels;
assert.strictEqual(channels.length, 1);
const channel_recordings = await model.channel_recordings;
assert.strictEqual(channel_recordings.length, 1);
});
});
@@ -1,25 +1,25 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { TYPE_RECORDING_SSH } from 'api/models/recording';
import { TYPE_SESSION_RECORDING_SSH } from 'api/models/session-recording';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
module('Unit | Model | recording', function (hooks) {
module('Unit | Model | session-recording', function (hooks) {
setupTest(hooks);
setupMirage(hooks);
test('it exists', function (assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('recording', {});
let model = store.createRecord('session-recording', {});
assert.ok(model);
});
test('it has isUnknown property and returns the expected values', async function (assert) {
assert.expect(2);
const store = this.owner.lookup('service:store');
const modelA = store.createRecord('recording', {
type: TYPE_RECORDING_SSH,
const modelA = store.createRecord('session-recording', {
type: TYPE_SESSION_RECORDING_SSH,
});
const modelB = store.createRecord('recording', {
const modelB = store.createRecord('session-recording', {
type: 'no-such-type',
});
assert.false(modelA.isUnknown);
@@ -29,10 +29,10 @@ module('Unit | Model | recording', function (hooks) {
test('it has isSSH property and returns the expected values', async function (assert) {
assert.expect(2);
const store = this.owner.lookup('service:store');
const modelA = store.createRecord('recording', {
type: TYPE_RECORDING_SSH,
const modelA = store.createRecord('session-recording', {
type: TYPE_SESSION_RECORDING_SSH,
});
const modelB = store.createRecord('recording', {
const modelB = store.createRecord('session-recording', {
type: 'random',
});
assert.true(modelA.isSSH);
@@ -42,12 +42,12 @@ module('Unit | Model | recording', function (hooks) {
test('it has connections as a relationship', async function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const model = store.createRecord('recording', {
type: TYPE_RECORDING_SSH,
connections: [store.createRecord('connection')],
const model = store.createRecord('session-recording', {
type: TYPE_SESSION_RECORDING_SSH,
connection_recordings: [store.createRecord('connection-recording')],
});
const connections = await model.connections;
assert.strictEqual(connections.length, 1);
const connection_recordings = await model.connection_recordings;
assert.strictEqual(connection_recordings.length, 1);
});
});
@@ -1,20 +1,20 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Serializer | recording', function (hooks) {
module('Unit | Serializer | connection-recording-recording', function (hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function (assert) {
let store = this.owner.lookup('service:store');
let serializer = store.serializerFor('recording');
let serializer = store.serializerFor('connection-recording');
assert.ok(serializer);
});
test('it serializes records', function (assert) {
let store = this.owner.lookup('service:store');
let record = store.createRecord('recording', {});
let record = store.createRecord('connection-recording', {});
let serializedRecord = record.serialize();
@@ -1,20 +1,20 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Serializer | connection', function (hooks) {
module('Unit | Serializer | session-recording', function (hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function (assert) {
let store = this.owner.lookup('service:store');
let serializer = store.serializerFor('connection');
let serializer = store.serializerFor('session-recording');
assert.ok(serializer);
});
test('it serializes records', function (assert) {
let store = this.owner.lookup('service:store');
let record = store.createRecord('connection', {});
let record = store.createRecord('session-recording', {});
let serializedRecord = record.serialize();
@@ -3,10 +3,10 @@
* SPDX-License-Identifier: MPL-2.0
*/
import RecordingAbility from 'api/abilities/recording';
import SessionRecordingAbility from 'api/abilities/session-recording';
import { inject as service } from '@ember/service';
export default class OverrideRecordingAbility extends RecordingAbility {
export default class OverrideSessionRecordingAbility extends SessionRecordingAbility {
// =service
@service features;
@@ -1,221 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { TYPE_RECORDING_SSH } from 'api/models/recording';
module('Unit | Abilities | session-recording', function (hooks) {
setupTest(hooks);
let features;
let canService;
let store;
hooks.beforeEach(function () {
features = this.owner.lookup('service:features');
features.enable('session-recording');
canService = this.owner.lookup('service:can');
store = this.owner.lookup('service:store');
});
test('can read session recording feature is enabled', function (assert) {
assert.expect(2);
const recordingWithAuthorizedAction = store.createRecord('recording', {
authorized_actions: ['read'],
type: TYPE_RECORDING_SSH,
});
const recordingWithoutAuthorizedAction = store.createRecord('recording', {
authorized_actions: [],
type: TYPE_RECORDING_SSH,
});
assert.true(
canService.can('read recording', recordingWithAuthorizedAction)
);
assert.false(
canService.can('read recording', recordingWithoutAuthorizedAction)
);
});
test('cannot read session recording when feature is disabled', function (assert) {
assert.expect(2);
features.disable('session-recording');
const recordingWithAuthorizedAction = store.createRecord('recording', {
authorized_actions: ['read'],
type: TYPE_RECORDING_SSH,
});
const recordingWithoutAuthorizedAction = store.createRecord('recording', {
authorized_actions: [],
type: TYPE_RECORDING_SSH,
});
assert.false(
canService.can('read recording', recordingWithAuthorizedAction)
);
assert.false(
canService.can('read recording', recordingWithoutAuthorizedAction)
);
});
test('can list session recording when in global scope', function (assert) {
assert.expect(2);
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: ['list'] },
type: 'global',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: [] },
type: 'global',
id: 'second',
});
assert.true(
canService.can('list recording', scopeModelWithAuthorizedAction, {
collection: 'recordings',
})
);
assert.false(
canService.can('list recording', scopeModelWithoutAuthorizedAction, {
collection: 'recordings',
})
);
});
test('cannot list session recording when in org scope', function (assert) {
assert.expect(2);
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: ['list'] },
type: 'org',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: [] },
type: 'org',
id: 'second',
});
assert.false(
canService.can('list recording', scopeModelWithAuthorizedAction, {
collection: 'recordings',
})
);
assert.false(
canService.can('list recording', scopeModelWithoutAuthorizedAction, {
collection: 'recordings',
})
);
});
test('can navigate to session recording when feature is enabled', function (assert) {
assert.expect(2);
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: ['list'] },
type: 'global',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: [] },
type: 'global',
id: 'second',
});
assert.true(
canService.can('navigate recording', scopeModelWithAuthorizedAction, {
collection: 'recordings',
})
);
assert.false(
canService.can('navigate recording', scopeModelWithoutAuthorizedAction, {
collection: 'recordings',
})
);
});
test('cannot navigate to session recording when feature is disabled', function (assert) {
assert.expect(2);
features.disable('session-recording');
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: ['list'] },
type: 'global',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { recordings: [] },
type: 'global',
id: 'second',
});
assert.false(
canService.can('navigate recording', scopeModelWithAuthorizedAction, {
collection: 'recordings',
})
);
assert.false(
canService.can('navigate recording', scopeModelWithoutAuthorizedAction, {
collection: 'recordings',
})
);
});
test('can download asciicast when an ssh recording has download authorization', function (assert) {
assert.expect(2);
const recordingWithAuthorizedAction = store.createRecord('recording', {
authorized_actions: ['download'],
type: TYPE_RECORDING_SSH,
});
const recordingWithoutAuthorizedAction = store.createRecord('recording', {
authorized_actions: [],
type: TYPE_RECORDING_SSH,
});
assert.true(
canService.can(
'downloadAsciiCast recording',
recordingWithAuthorizedAction
)
);
assert.false(
canService.can(
'downloadAsciiCast recording',
recordingWithoutAuthorizedAction
)
);
});
test('cannot download asciicast when a recording is not ssh type', function (assert) {
assert.expect(2);
const recordingWithAuthorizedAction = store.createRecord('recording', {
authorized_actions: ['download'],
type: 'unknown',
});
const recordingWithoutAuthorizedAction = store.createRecord('recording', {
authorized_actions: [],
type: 'unknown',
});
assert.false(
canService.can(
'downloadAsciiCast recording',
recordingWithAuthorizedAction
)
);
assert.false(
canService.can(
'downloadAsciiCast recording',
recordingWithoutAuthorizedAction
)
);
});
});
@@ -0,0 +1,269 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { TYPE_SESSION_RECORDING_SSH } from 'api/models/session-recording';
module('Unit | Abilities | session-recording', function (hooks) {
setupTest(hooks);
let features;
let canService;
let store;
hooks.beforeEach(function () {
features = this.owner.lookup('service:features');
features.enable('session-recording');
canService = this.owner.lookup('service:can');
store = this.owner.lookup('service:store');
});
test('can read session recording feature is enabled', function (assert) {
assert.expect(2);
const recordingWithAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: ['read'],
type: TYPE_SESSION_RECORDING_SSH,
}
);
const recordingWithoutAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: [],
type: TYPE_SESSION_RECORDING_SSH,
}
);
assert.true(
canService.can('read session-recording', recordingWithAuthorizedAction)
);
assert.false(
canService.can('read session-recording', recordingWithoutAuthorizedAction)
);
});
test('cannot read session recording when feature is disabled', function (assert) {
assert.expect(2);
features.disable('session-recording');
const recordingWithAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: ['read'],
type: TYPE_SESSION_RECORDING_SSH,
}
);
const recordingWithoutAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: [],
type: TYPE_SESSION_RECORDING_SSH,
}
);
assert.false(
canService.can('read session-recording', recordingWithAuthorizedAction)
);
assert.false(
canService.can('read session-recording', recordingWithoutAuthorizedAction)
);
});
test('can list session recording when in global scope', function (assert) {
assert.expect(2);
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: ['list'] },
type: 'global',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: [] },
type: 'global',
id: 'second',
});
assert.true(
canService.can('list session-recording', scopeModelWithAuthorizedAction, {
collection: 'session-recordings',
})
);
assert.false(
canService.can(
'list session-recording',
scopeModelWithoutAuthorizedAction,
{
collection: 'session-recordings',
}
)
);
});
test('cannot list session recording when in org scope', function (assert) {
assert.expect(2);
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: ['list'] },
type: 'org',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: [] },
type: 'org',
id: 'second',
});
assert.false(
canService.can('list session-recording', scopeModelWithAuthorizedAction, {
collection: 'session-recordings',
})
);
assert.false(
canService.can(
'list session-recording',
scopeModelWithoutAuthorizedAction,
{
collection: 'session-recordings',
}
)
);
});
test('can navigate to session recording when feature is enabled', function (assert) {
assert.expect(2);
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: ['list'] },
type: 'global',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: [] },
type: 'global',
id: 'second',
});
assert.true(
canService.can(
'navigate session-recording',
scopeModelWithAuthorizedAction,
{
collection: 'session-recordings',
}
)
);
assert.false(
canService.can(
'navigate session-recording',
scopeModelWithoutAuthorizedAction,
{
collection: 'session-recordings',
}
)
);
});
test('cannot navigate to session recording when feature is disabled', function (assert) {
assert.expect(2);
features.disable('session-recording');
const scopeModelWithAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: ['list'] },
type: 'global',
id: 'first',
});
const scopeModelWithoutAuthorizedAction = store.createRecord('scope', {
authorized_collection_actions: { ['session-recordings']: [] },
type: 'global',
id: 'second',
});
assert.false(
canService.can(
'navigate session-recording',
scopeModelWithAuthorizedAction,
{
collection: 'session-recordings',
}
)
);
assert.false(
canService.can(
'navigate session-recording',
scopeModelWithoutAuthorizedAction,
{
collection: 'session-recordings',
}
)
);
});
test('can download asciicast when an ssh recording has download authorization', function (assert) {
assert.expect(2);
const recordingWithAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: ['download'],
type: TYPE_SESSION_RECORDING_SSH,
}
);
const recordingWithoutAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: [],
type: TYPE_SESSION_RECORDING_SSH,
}
);
assert.true(
canService.can(
'downloadAsciiCast session-recording',
recordingWithAuthorizedAction
)
);
assert.false(
canService.can(
'downloadAsciiCast session-recording',
recordingWithoutAuthorizedAction
)
);
});
test('cannot download asciicast when a recording is not ssh type', function (assert) {
assert.expect(2);
const recordingWithAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: ['download'],
type: 'unknown',
}
);
const recordingWithoutAuthorizedAction = store.createRecord(
'session-recording',
{
authorized_actions: [],
type: 'unknown',
}
);
assert.false(
canService.can(
'downloadAsciiCast session-recording',
recordingWithAuthorizedAction
)
);
assert.false(
canService.can(
'downloadAsciiCast session-recording',
recordingWithoutAuthorizedAction
)
);
});
});