648 lines
22 KiB
TypeScript
648 lines
22 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import {General, Permissions} from '@constants';
|
|
import DatabaseManager from '@database/manager';
|
|
import TestHelper from '@test/test_helper';
|
|
|
|
import {
|
|
queryRoles,
|
|
getRoleById,
|
|
queryRolesByNames,
|
|
observePermissionForChannel,
|
|
observePermissionForTeam,
|
|
observePermissionForPost,
|
|
observeCanManageChannelMembers,
|
|
observeCanManageChannelSettings,
|
|
observeCanManageChannelAutotranslations,
|
|
} from './role';
|
|
|
|
import type ServerDataOperator from '@database/operator/server_data_operator';
|
|
import type {Database} from '@nozbe/watermelondb';
|
|
|
|
describe('Role Queries', () => {
|
|
const serverUrl = 'baseHandler.test.com';
|
|
let database: Database;
|
|
let operator: ServerDataOperator;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
const serverDatabaseAndOperator = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
|
|
database = serverDatabaseAndOperator.database;
|
|
operator = serverDatabaseAndOperator.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
describe('queryRoles', () => {
|
|
it('should query all roles', async () => {
|
|
await operator.handleRole({
|
|
roles: [
|
|
{
|
|
id: 'role1',
|
|
name: 'admin',
|
|
permissions: [Permissions.MANAGE_SYSTEM],
|
|
},
|
|
{
|
|
id: 'role2',
|
|
name: 'user',
|
|
permissions: [Permissions.CREATE_POST],
|
|
},
|
|
],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const roles = await queryRoles(database).fetch();
|
|
expect(roles.length).toBe(2);
|
|
});
|
|
});
|
|
|
|
describe('getRoleById', () => {
|
|
it('should get role by id', async () => {
|
|
await operator.handleRole({
|
|
roles: [{
|
|
id: 'role1',
|
|
name: 'admin',
|
|
permissions: [Permissions.MANAGE_SYSTEM],
|
|
}],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const role = await getRoleById(database, 'role1');
|
|
expect(role?.name).toBe('admin');
|
|
});
|
|
|
|
it('should return undefined for non-existent role', async () => {
|
|
const role = await getRoleById(database, 'nonexistent');
|
|
expect(role).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('queryRolesByNames', () => {
|
|
it('should query roles by names', async () => {
|
|
await operator.handleRole({
|
|
roles: [
|
|
{
|
|
id: 'role1',
|
|
name: 'admin',
|
|
permissions: [Permissions.MANAGE_SYSTEM],
|
|
},
|
|
{
|
|
id: 'role2',
|
|
name: 'user',
|
|
permissions: [Permissions.CREATE_POST],
|
|
},
|
|
],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const roles = await queryRolesByNames(database, ['admin']).fetch();
|
|
expect(roles.length).toBe(1);
|
|
expect(roles[0].name).toBe('admin');
|
|
});
|
|
});
|
|
|
|
describe('observePermissionForChannel', () => {
|
|
it('should observe channel permissions', (done) => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'system_user',
|
|
});
|
|
|
|
const mockChannel = TestHelper.fakeChannelModel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
teamId: 'team1',
|
|
});
|
|
|
|
operator.handleRole({
|
|
roles: [{
|
|
id: 'system_user',
|
|
name: 'system_user',
|
|
permissions: [Permissions.CREATE_POST],
|
|
}],
|
|
prepareRecordsOnly: false,
|
|
}).then(() => {
|
|
observePermissionForChannel(
|
|
database,
|
|
mockChannel,
|
|
mockUser,
|
|
Permissions.CREATE_POST,
|
|
false,
|
|
).subscribe({
|
|
next: (hasPermission) => {
|
|
expect(hasPermission).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should return default value when no user', (done) => {
|
|
observePermissionForChannel(
|
|
database,
|
|
TestHelper.fakeChannelModel(),
|
|
undefined,
|
|
Permissions.CREATE_POST,
|
|
true,
|
|
).subscribe({
|
|
next: (hasPermission) => {
|
|
expect(hasPermission).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('observePermissionForTeam', () => {
|
|
it('should observe team permissions', (done) => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'system_user',
|
|
});
|
|
|
|
const mockTeam = TestHelper.fakeTeamModel({
|
|
id: 'team1',
|
|
});
|
|
|
|
const myTeams: MyTeam[] = [{
|
|
id: mockTeam.id,
|
|
roles: 'team_user',
|
|
}];
|
|
|
|
Promise.all([
|
|
operator.handleMyTeam({myTeams, prepareRecordsOnly: false}),
|
|
operator.handleRole({
|
|
roles: [
|
|
{
|
|
id: 'system_user',
|
|
name: 'system_user',
|
|
permissions: [Permissions.CREATE_POST],
|
|
},
|
|
{
|
|
id: 'team_user',
|
|
name: 'team_user',
|
|
permissions: [Permissions.MANAGE_TEAM],
|
|
},
|
|
],
|
|
prepareRecordsOnly: false,
|
|
})],
|
|
).then(() => {
|
|
observePermissionForTeam(
|
|
database,
|
|
mockTeam,
|
|
mockUser,
|
|
Permissions.MANAGE_TEAM,
|
|
false,
|
|
).subscribe({
|
|
next: (hasPermission) => {
|
|
expect(hasPermission).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should return default value when no team', (done) => {
|
|
observePermissionForTeam(
|
|
database,
|
|
undefined,
|
|
TestHelper.fakeUserModel(),
|
|
Permissions.MANAGE_TEAM,
|
|
true,
|
|
).subscribe({
|
|
next: (hasPermission) => {
|
|
expect(hasPermission).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('observeCanManageChannelMembers', () => {
|
|
it('should observe manage members permission for public channel', (done) => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'system_admin',
|
|
});
|
|
|
|
Promise.all([
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleRole({
|
|
roles: [{
|
|
id: 'system_admin',
|
|
name: 'system_admin',
|
|
permissions: [Permissions.MANAGE_PUBLIC_CHANNEL_MEMBERS],
|
|
}],
|
|
prepareRecordsOnly: false,
|
|
})]).then(() => {
|
|
observeCanManageChannelMembers(
|
|
database,
|
|
'channel1',
|
|
mockUser,
|
|
).subscribe({
|
|
next: (canManage) => {
|
|
expect(canManage).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not allow managing default channel members', (done) => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'system_admin',
|
|
});
|
|
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
name: General.DEFAULT_CHANNEL,
|
|
type: General.OPEN_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}).then(() => {
|
|
observeCanManageChannelMembers(
|
|
database,
|
|
'channel1',
|
|
mockUser,
|
|
).subscribe({
|
|
next: (canManage) => {
|
|
expect(canManage).toBe(false);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('observePermissionForPost', () => {
|
|
it('should observe post permissions', (done) => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'system_user',
|
|
});
|
|
|
|
const mockPost = TestHelper.fakePostModel({
|
|
id: 'post1',
|
|
channelId: 'channel1',
|
|
});
|
|
|
|
Promise.all([
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
team_id: 'team1',
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleRole({
|
|
roles: [{
|
|
id: 'system_user',
|
|
name: 'system_user',
|
|
permissions: [Permissions.CREATE_POST],
|
|
}],
|
|
prepareRecordsOnly: false,
|
|
})],
|
|
).then(() => {
|
|
observePermissionForPost(
|
|
database,
|
|
mockPost,
|
|
mockUser,
|
|
Permissions.CREATE_POST,
|
|
false,
|
|
).subscribe({
|
|
next: (hasPermission) => {
|
|
expect(hasPermission).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should return default value when no channel exists', (done) => {
|
|
const mockPost = TestHelper.fakePostModel({
|
|
id: 'post1',
|
|
channelId: 'nonexistent',
|
|
});
|
|
|
|
observePermissionForPost(
|
|
database,
|
|
mockPost,
|
|
undefined,
|
|
Permissions.CREATE_POST,
|
|
true,
|
|
).subscribe({
|
|
next: (hasPermission) => {
|
|
expect(hasPermission).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('observeCanManageChannelSettings', () => {
|
|
it('should observe manage settings permission', (done) => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'system_admin',
|
|
});
|
|
|
|
Promise.all([
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleRole({
|
|
roles: [{
|
|
id: 'system_admin',
|
|
name: 'system_admin',
|
|
permissions: [Permissions.MANAGE_PUBLIC_CHANNEL_PROPERTIES],
|
|
}],
|
|
prepareRecordsOnly: false,
|
|
})],
|
|
).then(() => {
|
|
observeCanManageChannelSettings(
|
|
database,
|
|
'channel1',
|
|
mockUser,
|
|
).subscribe({
|
|
next: (canManage) => {
|
|
expect(canManage).toBe(true);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not allow managing deleted channel settings', (done) => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'system_admin',
|
|
});
|
|
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
delete_at: 123,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}).then(() => {
|
|
observeCanManageChannelSettings(
|
|
database,
|
|
'channel1',
|
|
mockUser,
|
|
).subscribe({
|
|
next: (canManage) => {
|
|
expect(canManage).toBe(false);
|
|
done();
|
|
},
|
|
error: done,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('observeCanManageChannelAutotranslations', () => {
|
|
it('should emit false when EnableAutoTranslation is false', async () => {
|
|
const mockUser = TestHelper.fakeUserModel({id: 'user1', roles: 'system_user'});
|
|
|
|
await Promise.all([
|
|
operator.handleConfigs({
|
|
configs: [
|
|
{id: 'EnableAutoTranslation', value: 'false'},
|
|
{id: 'RestrictDMAndGMAutotranslation', value: 'false'},
|
|
],
|
|
configsToDelete: [],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
]);
|
|
|
|
const subscriptionNext = jest.fn();
|
|
const result = observeCanManageChannelAutotranslations(database, 'channel1', mockUser);
|
|
result.subscribe({next: subscriptionNext});
|
|
|
|
expect(subscriptionNext).toHaveBeenCalledWith(false);
|
|
});
|
|
|
|
it('should emit false when channel is not found', async () => {
|
|
const mockUser = TestHelper.fakeUserModel({id: 'user1', roles: 'system_user'});
|
|
|
|
await operator.handleConfigs({
|
|
configs: [
|
|
{id: 'EnableAutoTranslation', value: 'true'},
|
|
{id: 'RestrictDMAndGMAutotranslation', value: 'false'},
|
|
],
|
|
configsToDelete: [],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const subscriptionNext = jest.fn();
|
|
const result = observeCanManageChannelAutotranslations(database, 'nonexistent', mockUser);
|
|
result.subscribe({next: subscriptionNext});
|
|
|
|
expect(subscriptionNext).toHaveBeenCalledWith(false);
|
|
});
|
|
|
|
it('should emit false when channel is deleted', async () => {
|
|
const mockUser = TestHelper.fakeUserModel({id: 'user1', roles: 'system_user'});
|
|
|
|
await Promise.all([
|
|
operator.handleConfigs({
|
|
configs: [
|
|
{id: 'EnableAutoTranslation', value: 'true'},
|
|
{id: 'RestrictDMAndGMAutotranslation', value: 'false'},
|
|
],
|
|
configsToDelete: [],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
delete_at: 123,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
]);
|
|
|
|
const subscriptionNext = jest.fn();
|
|
const result = observeCanManageChannelAutotranslations(database, 'channel1', mockUser);
|
|
result.subscribe({next: subscriptionNext});
|
|
|
|
expect(subscriptionNext).toHaveBeenCalledWith(false);
|
|
});
|
|
|
|
it('should emit false when channel is DM and RestrictDMAndGMAutotranslation is true', async () => {
|
|
const mockUser = TestHelper.fakeUserModel({id: 'user1', roles: 'system_user'});
|
|
|
|
await Promise.all([
|
|
operator.handleConfigs({
|
|
configs: [
|
|
{id: 'EnableAutoTranslation', value: 'true'},
|
|
{id: 'RestrictDMAndGMAutotranslation', value: 'true'},
|
|
],
|
|
configsToDelete: [],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.DM_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
]);
|
|
|
|
const subscriptionNext = jest.fn();
|
|
const result = observeCanManageChannelAutotranslations(database, 'channel1', mockUser);
|
|
result.subscribe({next: subscriptionNext});
|
|
|
|
expect(subscriptionNext).toHaveBeenCalledWith(false);
|
|
});
|
|
|
|
it('should emit true when channel is DM and RestrictDMAndGMAutotranslation is false', async () => {
|
|
const mockUser = TestHelper.fakeUserModel({id: 'user1', roles: 'system_user'});
|
|
|
|
await Promise.all([
|
|
operator.handleConfigs({
|
|
configs: [
|
|
{id: 'EnableAutoTranslation', value: 'true'},
|
|
{id: 'RestrictDMAndGMAutotranslation', value: 'false'},
|
|
],
|
|
configsToDelete: [],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.DM_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
]);
|
|
|
|
const subscriptionNext = jest.fn();
|
|
const result = observeCanManageChannelAutotranslations(database, 'channel1', mockUser);
|
|
result.subscribe({next: subscriptionNext});
|
|
|
|
expect(subscriptionNext).toHaveBeenCalledWith(true);
|
|
});
|
|
|
|
it('should emit true for open channel when user has MANAGE_PUBLIC_CHANNEL_AUTO_TRANSLATION', async () => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'channel_admin',
|
|
});
|
|
|
|
await Promise.all([
|
|
operator.handleConfigs({
|
|
configs: [
|
|
{id: 'EnableAutoTranslation', value: 'true'},
|
|
{id: 'RestrictDMAndGMAutotranslation', value: 'false'},
|
|
],
|
|
configsToDelete: [],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.OPEN_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleRole({
|
|
roles: [{
|
|
id: 'channel_admin',
|
|
name: 'channel_admin',
|
|
permissions: [Permissions.MANAGE_PUBLIC_CHANNEL_AUTO_TRANSLATION],
|
|
}],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
]);
|
|
|
|
const subscriptionNext = jest.fn();
|
|
const result = observeCanManageChannelAutotranslations(database, 'channel1', mockUser);
|
|
result.subscribe({next: subscriptionNext});
|
|
|
|
expect(subscriptionNext).toHaveBeenCalledWith(true);
|
|
});
|
|
|
|
it('should emit true for private channel when user has MANAGE_PRIVATE_CHANNEL_AUTO_TRANSLATION', async () => {
|
|
const mockUser = TestHelper.fakeUserModel({
|
|
id: 'user1',
|
|
roles: 'channel_admin',
|
|
});
|
|
|
|
await Promise.all([
|
|
operator.handleConfigs({
|
|
configs: [
|
|
{id: 'EnableAutoTranslation', value: 'true'},
|
|
{id: 'RestrictDMAndGMAutotranslation', value: 'false'},
|
|
],
|
|
configsToDelete: [],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleChannel({
|
|
channels: [TestHelper.fakeChannel({
|
|
id: 'channel1',
|
|
type: General.PRIVATE_CHANNEL,
|
|
delete_at: 0,
|
|
})],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
operator.handleRole({
|
|
roles: [{
|
|
id: 'channel_admin',
|
|
name: 'channel_admin',
|
|
permissions: [Permissions.MANAGE_PRIVATE_CHANNEL_AUTO_TRANSLATION],
|
|
}],
|
|
prepareRecordsOnly: false,
|
|
}),
|
|
]);
|
|
|
|
const subscriptionNext = jest.fn();
|
|
const result = observeCanManageChannelAutotranslations(database, 'channel1', mockUser);
|
|
result.subscribe({next: subscriptionNext});
|
|
|
|
expect(subscriptionNext).toHaveBeenCalledWith(true);
|
|
});
|
|
});
|
|
});
|