Files
upstream-mirror 30810eecd7
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Code scanning - action / CodeQL-Build (push) Failing after 2s
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

727 lines
24 KiB
TypeScript

import type { Credentials } from '@rocket.chat/api-client';
import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings';
import { expect } from 'chai';
import { before, describe, after, it } from 'mocha';
import { getCredentials, api, request, credentials, methodCall } from '../../data/api-data';
import { sendSimpleMessage } from '../../data/chat.helper';
import { updatePermission, updateSetting } from '../../data/permissions.helper';
import { createRoom, deleteRoom } from '../../data/rooms.helper';
import { password } from '../../data/user';
import type { TestUser } from '../../data/users.helper';
import { createUser, deleteUser, login } from '../../data/users.helper';
const resetAutoTranslateDefaults = async () => {
await Promise.all([
updateSetting('AutoTranslate_Enabled', false),
updateSetting('AutoTranslate_AutoEnableOnJoinRoom', false),
updateSetting('Language', ''),
updatePermission('auto-translate', ['admin']),
]);
};
const resetE2EDefaults = async () => {
await Promise.all([updateSetting('E2E_Enabled_Default_PrivateRooms', false), updateSetting('E2E_Enable', false)]);
};
describe('AutoTranslate', () => {
before((done) => getCredentials(done));
describe('[AutoTranslate]', () => {
describe('[/autotranslate.getSupportedLanguages', () => {
before(() => resetAutoTranslateDefaults());
after(() => resetAutoTranslateDefaults());
it('should throw an error when the "AutoTranslate_Enabled" setting is disabled', async () => {
const res = await request
.get(api('autotranslate.getSupportedLanguages'))
.set(credentials)
.query({
targetLanguage: 'en',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
expect(res.body.error).to.be.equal('AutoTranslate is disabled.');
});
it('should throw an error when the user does not have the "auto-translate" permission', async () => {
await updateSetting('AutoTranslate_Enabled', true);
await updatePermission('auto-translate', []);
const res = await request
.get(api('autotranslate.getSupportedLanguages'))
.set(credentials)
.query({
targetLanguage: 'en',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
expect(res.body.errorType).to.be.equal('error-action-not-allowed');
expect(res.body.error).to.be.equal('Auto-Translate is not allowed [error-action-not-allowed]');
});
it('should return a list of languages', async () => {
await updatePermission('auto-translate', ['admin']);
await request
.get(api('autotranslate.getSupportedLanguages'))
.set(credentials)
.query({
targetLanguage: 'en',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body.languages).to.be.an('array');
});
});
});
describe('[/autotranslate.saveSettings', () => {
let testGroupId: IRoom['_id'];
let testChannelId: IRoom['_id'];
before(async () => {
await Promise.all([
resetAutoTranslateDefaults(),
updateSetting('E2E_Enable', true),
updateSetting('E2E_Enabled_Default_PrivateRooms', true),
]);
testGroupId = (await createRoom({ type: 'p', name: `e2etest-autotranslate-${Date.now()}` })).body.group._id;
testChannelId = (await createRoom({ type: 'c', name: `test-autotranslate-${Date.now()}` })).body.channel._id;
});
after(async () => {
await Promise.all([
resetAutoTranslateDefaults(),
resetE2EDefaults(),
deleteRoom({ type: 'p', roomId: testGroupId }),
deleteRoom({ type: 'c', roomId: testChannelId }),
]);
});
it('should throw an error when the "AutoTranslate_Enabled" setting is disabled', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
field: 'autoTranslate',
defaultLanguage: 'en',
value: true,
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
expect(res.body.error).to.be.equal('AutoTranslate is disabled.');
});
it('should throw an error when the user does not have the "auto-translate" permission', async () => {
await updateSetting('AutoTranslate_Enabled', true);
await updatePermission('auto-translate', []);
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
defaultLanguage: 'en',
field: 'autoTranslateLanguage',
value: 'en',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
expect(res.body.errorType).to.be.equal('error-action-not-allowed');
expect(res.body.error).to.be.equal('Auto-Translate is not allowed [error-action-not-allowed]');
});
it('should throw an error when the bodyParam "roomId" is not provided', async () => {
await updatePermission('auto-translate', ['admin']);
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
});
it('should throw an error when the bodyParam "field" is not provided', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
});
it('should throw an error when the bodyParam "value" is not provided', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
field: 'autoTranslate',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
});
it('should throw an error when the bodyParam "autoTranslate" is not a boolean', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
field: 'autoTranslate',
value: 'test',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
});
it('should throw an error when the bodyParam "autoTranslateLanguage" is not a string', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
field: 'autoTranslateLanguage',
value: 12,
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
});
it('should throw an error when the bodyParam "field" is invalid', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
field: 'invalid',
value: 12,
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
});
it('should throw an error when the bodyParam "roomId" is invalid or the user is not subscribed', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: 'invalid',
field: 'autoTranslateLanguage',
value: 'en',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-subscription');
expect(res.body.error).to.be.equal('Invalid subscription [error-invalid-subscription]');
});
it('should throw an error when E2E encryption is enabled', async () => {
await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testGroupId,
field: 'autoTranslate',
defaultLanguage: 'en',
value: true,
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-e2e-enabled');
});
});
it('should return success when the setting is saved correctly', async () => {
const res = await request
.post(api('autotranslate.saveSettings'))
.set(credentials)
.send({
roomId: testChannelId,
field: 'autoTranslateLanguage',
value: 'en',
})
.expect('Content-Type', 'application/json')
.expect(200);
expect(res.body).to.have.a.property('success', true);
});
});
describe('[/autotranslate.translateMessage', () => {
let messageSent: IMessage;
let testChannelId: IRoom['_id'];
before(async () => {
await resetAutoTranslateDefaults();
testChannelId = (await createRoom({ type: 'c', name: `test-autotranslate-message-${Date.now()}` })).body.channel._id;
const res = await sendSimpleMessage({
roomId: testChannelId,
text: 'Isso é um teste',
});
messageSent = res.body.message;
});
after(async () => {
await Promise.all([resetAutoTranslateDefaults(), deleteRoom({ type: 'c', roomId: testChannelId })]);
});
it('should throw an error when the "AutoTranslate_Enabled" setting is disabled', async () => {
const res = await request
.post(api('autotranslate.translateMessage'))
.set(credentials)
.send({
messageId: 'test',
targetLanguage: 'en',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
expect(res.body.error).to.be.equal('AutoTranslate is disabled.');
});
it('should throw an error when the bodyParam "messageId" is not provided', async () => {
await updateSetting('AutoTranslate_Enabled', true);
await updatePermission('auto-translate', ['admin']);
const res = await request
.post(api('autotranslate.translateMessage'))
.set(credentials)
.send({})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
});
it('should throw an error when the bodyParam "messageId" is invalid', async () => {
const res = await request
.post(api('autotranslate.translateMessage'))
.set(credentials)
.send({
messageId: 'invalid',
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
expect(res.body.error).to.be.equal('Message not found.');
});
it('should return success when the translate is successful', async () => {
const res = await request
.post(api('autotranslate.translateMessage'))
.set(credentials)
.send({
messageId: messageSent._id,
})
.expect('Content-Type', 'application/json')
.expect(200);
expect(res.body).to.have.a.property('success', true);
});
describe('room access check', () => {
let userA: TestUser<IUser>;
let userB: TestUser<IUser>;
let credA: Credentials;
let credB: Credentials;
let privateRoom: IRoom;
let privateMessage: IMessage;
before(async () => {
await updateSetting('AutoTranslate_Enabled', true);
userA = await createUser();
userB = await createUser();
credA = await login(userA.username, password);
credB = await login(userB.username, password);
privateRoom = (
await createRoom({
type: 'p',
name: `test-autotranslate-access-${Date.now()}`,
credentials: credA,
})
).body.group;
const msgRes = await sendSimpleMessage({
roomId: privateRoom._id,
text: 'Isso é um teste',
userCredentials: credA,
});
privateMessage = msgRes.body.message;
});
after(async () => {
await Promise.all([
updateSetting('AutoTranslate_Enabled', false),
deleteUser(userA),
deleteUser(userB),
deleteRoom({ type: 'p', roomId: privateRoom._id }),
]);
});
it('should return 403 forbidden when the user is not a member of the room', async () => {
const res = await request
.post(api('autotranslate.translateMessage'))
.set(credB)
.send({
messageId: privateMessage._id,
})
.expect('Content-Type', 'application/json')
.expect(403);
expect(res.body).to.have.a.property('success', false);
});
});
});
describe('[autoTranslate.translateMessage method]', () => {
let userA: TestUser<IUser>;
let userB: TestUser<IUser>;
let credA: Credentials;
let credB: Credentials;
let privateRoom: IRoom;
let privateMessage: IMessage;
before(async () => {
await updateSetting('AutoTranslate_Enabled', true);
userA = await createUser();
userB = await createUser();
credA = await login(userA.username, password);
credB = await login(userB.username, password);
privateRoom = (
await createRoom({
type: 'p',
name: `test-autotranslate-method-${Date.now()}`,
credentials: credA,
})
).body.group;
const msgRes = await sendSimpleMessage({
roomId: privateRoom._id,
text: 'Isso é um teste',
userCredentials: credA,
});
privateMessage = msgRes.body.message;
});
after(async () => {
await Promise.all([
updateSetting('AutoTranslate_Enabled', false),
deleteUser(userA),
deleteUser(userB),
deleteRoom({ type: 'p', roomId: privateRoom._id }),
]);
});
it('should fail when messageId is not a string', async () => {
const res = await request
.post(methodCall('autoTranslate.translateMessage'))
.set(credA)
.send({
message: JSON.stringify({
msg: 'method',
id: 'id',
method: 'autoTranslate.translateMessage',
params: [{ _id: { $gt: '' } }, 'en'],
}),
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
const parsedBody = JSON.parse(res.body.message);
expect(parsedBody).to.have.a.property('error');
});
it('should return error-not-allowed when the caller is not a member of the room', async () => {
const res = await request
.post(methodCall('autoTranslate.translateMessage'))
.set(credB)
.send({
message: JSON.stringify({
msg: 'method',
id: 'id',
method: 'autoTranslate.translateMessage',
params: [{ _id: privateMessage._id }, 'en'],
}),
})
.expect('Content-Type', 'application/json')
.expect(400);
expect(res.body).to.have.a.property('success', false);
const parsedBody = JSON.parse(res.body.message);
expect(parsedBody).to.have.a.property('error');
expect(parsedBody.error).to.have.a.property('error', 'error-not-allowed');
});
});
describe('Autoenable setting', () => {
let userA: TestUser<IUser>;
let userB: TestUser<IUser>;
let credA: Credentials;
let credB: Credentials;
let channel: IRoom;
const channelsToRemove: IRoom[] = [];
const createChannel = async (members: string[] | undefined, cred: Credentials) =>
(await createRoom({ type: 'c', members, name: `channel-test-${Date.now()}`, credentials: cred })).body.channel;
const setLanguagePref = async (language: string, cred: Credentials) => {
await request
.post(api('users.setPreferences'))
.set(cred)
.send({ data: { language } })
.expect(200)
.expect('Content-Type', 'application/json')
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
};
const getSub = async (roomId: IRoom['_id'], cred: Credentials) =>
(
await request
.get(api('subscriptions.getOne'))
.set(cred)
.query({
roomId,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('subscription').and.to.be.an('object');
})
).body.subscription;
before(async () => {
await Promise.all([
updateSetting('AutoTranslate_Enabled', true),
updateSetting('AutoTranslate_AutoEnableOnJoinRoom', true),
updateSetting('Language', 'pt-BR'),
]);
userA = await createUser();
userB = await createUser();
credA = await login(userA.username, password);
credB = await login(userB.username, password);
channel = await createChannel(undefined, credA);
await setLanguagePref('en', credB);
channelsToRemove.push(channel);
});
after(async () => {
await Promise.all([
updateSetting('AutoTranslate_AutoEnableOnJoinRoom', false),
updateSetting('AutoTranslate_Enabled', false),
updateSetting('Language', ''),
deleteUser(userA),
deleteUser(userB),
channelsToRemove.map(() => deleteRoom({ type: 'c', roomId: channel._id })),
]);
});
it("should do nothing if the user hasn't changed his language preference", async () => {
const sub = await getSub(channel._id, credA);
expect(sub).to.not.have.property('autoTranslate');
expect(sub).to.not.have.property('autoTranslateLanguage');
});
it("should do nothing if the user changed his language preference to be the same as the server's", async () => {
await setLanguagePref('pt-BR', credA);
const sub = await getSub(channel._id, credA);
expect(sub).to.not.have.property('autoTranslate');
expect(sub).to.not.have.property('autoTranslateLanguage');
});
it('should enable autotranslate with the correct language when joining a room', async () => {
await request
.post(api('channels.join'))
.set(credB)
.send({
roomId: channel._id,
})
.expect('Content-Type', 'application/json')
.expect(200);
const sub = await getSub(channel._id, credB);
expect(sub).to.have.property('autoTranslate');
expect(sub).to.have.property('autoTranslateLanguage').and.to.be.equal('en');
});
it('should enable autotranslate with the correct language when creating a new room', async () => {
await setLanguagePref('en', credA);
const newChannel = await createChannel(undefined, credA);
const sub = await getSub(newChannel._id, credA);
expect(sub).to.have.property('autoTranslate');
expect(sub).to.have.property('autoTranslateLanguage').and.to.be.equal('en');
channelsToRemove.push(newChannel);
});
it('should enable autotranslate for all the members added to the room upon creation', async () => {
const newChannel = await createChannel([userA.username, userB.username], credA);
const subA = await getSub(newChannel._id, credA);
expect(subA).to.have.property('autoTranslate');
expect(subA).to.have.property('autoTranslateLanguage').and.to.be.equal('en');
const subB = await getSub(newChannel._id, credB);
expect(subB).to.have.property('autoTranslate');
expect(subB).to.have.property('autoTranslateLanguage').and.to.be.equal('en');
channelsToRemove.push(newChannel);
});
it('should enable autotranslate with the correct language when added to a room', async () => {
const newChannel = await createChannel(undefined, credA);
await request
.post(api('channels.invite'))
.set(credA)
.send({
roomId: newChannel._id,
userId: userB._id,
})
.expect('Content-Type', 'application/json')
.expect(200);
const sub = await getSub(newChannel._id, credB);
expect(sub).to.have.property('autoTranslate');
expect(sub).to.have.property('autoTranslateLanguage').and.to.be.equal('en');
channelsToRemove.push(newChannel);
});
it('should change the auto translate language when the user changes his language preference', async () => {
await setLanguagePref('es', credA);
const newChannel = await createChannel(undefined, credA);
const subscription = await getSub(newChannel._id, credA);
expect(subscription).to.have.property('autoTranslate', true);
expect(subscription).to.have.property('autoTranslateLanguage', 'es');
channelsToRemove.push(newChannel);
});
it('should enable autotranslate on existing subscriptions when user changes from workspace language to a different one', async () => {
await setLanguagePref('pt-BR', credA);
const newChannel = await createChannel(undefined, credA);
channelsToRemove.push(newChannel);
const subBefore = await getSub(newChannel._id, credA);
expect(subBefore).to.not.have.property('autoTranslate');
expect(subBefore).to.not.have.property('autoTranslateLanguage');
await setLanguagePref('en', credA);
const subAfter = await getSub(newChannel._id, credA);
expect(subAfter).to.have.property('autoTranslate', true);
expect(subAfter).to.have.property('autoTranslateLanguage', 'en');
});
it("should enable autotranslate on existing subscriptions when user changes from 'default' language to a non-workspace language", async () => {
await setLanguagePref('default', credA);
const newChannel = await createChannel(undefined, credA);
channelsToRemove.push(newChannel);
const subBefore = await getSub(newChannel._id, credA);
expect(subBefore).to.not.have.property('autoTranslate');
expect(subBefore).to.not.have.property('autoTranslateLanguage');
await setLanguagePref('en', credA);
const subAfter = await getSub(newChannel._id, credA);
expect(subAfter).to.have.property('autoTranslate', true);
expect(subAfter).to.have.property('autoTranslateLanguage', 'en');
});
it('should disable autotranslate on existing subscriptions when user changes language to default', async () => {
await setLanguagePref('en', credA);
const newChannel = await createChannel(undefined, credA);
channelsToRemove.push(newChannel);
const subBefore = await getSub(newChannel._id, credA);
expect(subBefore).to.have.property('autoTranslate', true);
await setLanguagePref('default', credA);
const subAfter = await getSub(newChannel._id, credA);
expect(subAfter).to.not.have.property('autoTranslate');
expect(subAfter).to.not.have.property('autoTranslateLanguage');
});
it('should disable autotranslate on existing subscriptions when user changes language to the workspace default', async () => {
await setLanguagePref('en', credA);
const newChannel = await createChannel(undefined, credA);
channelsToRemove.push(newChannel);
const subBefore = await getSub(newChannel._id, credA);
expect(subBefore).to.have.property('autoTranslate', true);
await setLanguagePref('pt-BR', credA);
const subAfter = await getSub(newChannel._id, credA);
expect(subAfter).to.not.have.property('autoTranslate');
expect(subAfter).to.not.have.property('autoTranslateLanguage');
});
it('should not re-enable autotranslate for rooms where the user has explicitly opted out', async () => {
await updatePermission('auto-translate', ['admin', 'user']);
await setLanguagePref('en', credA);
const newChannel = await createChannel(undefined, credA);
channelsToRemove.push(newChannel);
const subEnabled = await getSub(newChannel._id, credA);
expect(subEnabled).to.have.property('autoTranslate', true);
await request
.post(api('autotranslate.saveSettings'))
.set(credA)
.send({ roomId: newChannel._id, field: 'autoTranslate', value: false, defaultLanguage: 'en' })
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
const subOptedOut = await getSub(newChannel._id, credA);
expect(subOptedOut).to.have.property('autoTranslate', false);
await setLanguagePref('es', credA);
const subAfterLangChange = await getSub(newChannel._id, credA);
expect(subAfterLangChange).to.have.property('autoTranslate', false);
});
});
});
});