mirror of
https://github.com/bitwarden/browser
synced 2025-12-30 15:13:32 +00:00
Apply Prettier (#581)
This commit is contained in:
@@ -1,61 +1,71 @@
|
||||
import { Arg, Substitute, SubstituteOf } from '@fluffy-spoon/substitute';
|
||||
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
|
||||
|
||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
||||
import { FileUploadService } from 'jslib-common/abstractions/fileUpload.service';
|
||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
import { LogService } from 'jslib-common/abstractions/log.service';
|
||||
import { SearchService } from 'jslib-common/abstractions/search.service';
|
||||
import { SettingsService } from 'jslib-common/abstractions/settings.service';
|
||||
import { StateService } from 'jslib-common/abstractions/state.service';
|
||||
import { ApiService } from "jslib-common/abstractions/api.service";
|
||||
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
||||
import { FileUploadService } from "jslib-common/abstractions/fileUpload.service";
|
||||
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
||||
import { LogService } from "jslib-common/abstractions/log.service";
|
||||
import { SearchService } from "jslib-common/abstractions/search.service";
|
||||
import { SettingsService } from "jslib-common/abstractions/settings.service";
|
||||
import { StateService } from "jslib-common/abstractions/state.service";
|
||||
|
||||
import { Utils } from 'jslib-common/misc/utils';
|
||||
import { Cipher } from 'jslib-common/models/domain/cipher';
|
||||
import { EncArrayBuffer } from 'jslib-common/models/domain/encArrayBuffer';
|
||||
import { EncString } from 'jslib-common/models/domain/encString';
|
||||
import { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';
|
||||
import { Utils } from "jslib-common/misc/utils";
|
||||
import { Cipher } from "jslib-common/models/domain/cipher";
|
||||
import { EncArrayBuffer } from "jslib-common/models/domain/encArrayBuffer";
|
||||
import { EncString } from "jslib-common/models/domain/encString";
|
||||
import { SymmetricCryptoKey } from "jslib-common/models/domain/symmetricCryptoKey";
|
||||
|
||||
import { CipherService } from 'jslib-common/services/cipher.service';
|
||||
import { CipherService } from "jslib-common/services/cipher.service";
|
||||
|
||||
const ENCRYPTED_TEXT = 'This data has been encrypted';
|
||||
const ENCRYPTED_TEXT = "This data has been encrypted";
|
||||
const ENCRYPTED_BYTES = new EncArrayBuffer(Utils.fromUtf8ToArray(ENCRYPTED_TEXT).buffer);
|
||||
|
||||
describe('Cipher Service', () => {
|
||||
let cryptoService: SubstituteOf<CryptoService>;
|
||||
let stateService: SubstituteOf<StateService>;
|
||||
let settingsService: SubstituteOf<SettingsService>;
|
||||
let apiService: SubstituteOf<ApiService>;
|
||||
let fileUploadService: SubstituteOf<FileUploadService>;
|
||||
let i18nService: SubstituteOf<I18nService>;
|
||||
let searchService: SubstituteOf<SearchService>;
|
||||
let logService: SubstituteOf<LogService>;
|
||||
describe("Cipher Service", () => {
|
||||
let cryptoService: SubstituteOf<CryptoService>;
|
||||
let stateService: SubstituteOf<StateService>;
|
||||
let settingsService: SubstituteOf<SettingsService>;
|
||||
let apiService: SubstituteOf<ApiService>;
|
||||
let fileUploadService: SubstituteOf<FileUploadService>;
|
||||
let i18nService: SubstituteOf<I18nService>;
|
||||
let searchService: SubstituteOf<SearchService>;
|
||||
let logService: SubstituteOf<LogService>;
|
||||
|
||||
let cipherService: CipherService;
|
||||
let cipherService: CipherService;
|
||||
|
||||
beforeEach(() => {
|
||||
cryptoService = Substitute.for<CryptoService>();
|
||||
stateService = Substitute.for<StateService>();
|
||||
settingsService = Substitute.for<SettingsService>();
|
||||
apiService = Substitute.for<ApiService>();
|
||||
fileUploadService = Substitute.for<FileUploadService>();
|
||||
i18nService = Substitute.for<I18nService>();
|
||||
searchService = Substitute.for<SearchService>();
|
||||
logService = Substitute.for<LogService>();
|
||||
beforeEach(() => {
|
||||
cryptoService = Substitute.for<CryptoService>();
|
||||
stateService = Substitute.for<StateService>();
|
||||
settingsService = Substitute.for<SettingsService>();
|
||||
apiService = Substitute.for<ApiService>();
|
||||
fileUploadService = Substitute.for<FileUploadService>();
|
||||
i18nService = Substitute.for<I18nService>();
|
||||
searchService = Substitute.for<SearchService>();
|
||||
logService = Substitute.for<LogService>();
|
||||
|
||||
cryptoService.encryptToBytes(Arg.any(), Arg.any()).resolves(ENCRYPTED_BYTES);
|
||||
cryptoService.encrypt(Arg.any(), Arg.any()).resolves(new EncString(ENCRYPTED_TEXT));
|
||||
cryptoService.encryptToBytes(Arg.any(), Arg.any()).resolves(ENCRYPTED_BYTES);
|
||||
cryptoService.encrypt(Arg.any(), Arg.any()).resolves(new EncString(ENCRYPTED_TEXT));
|
||||
|
||||
cipherService = new CipherService(cryptoService, settingsService, apiService, fileUploadService,
|
||||
i18nService, () => searchService, logService, stateService);
|
||||
});
|
||||
cipherService = new CipherService(
|
||||
cryptoService,
|
||||
settingsService,
|
||||
apiService,
|
||||
fileUploadService,
|
||||
i18nService,
|
||||
() => searchService,
|
||||
logService,
|
||||
stateService
|
||||
);
|
||||
});
|
||||
|
||||
it('attachments upload encrypted file contents', async () => {
|
||||
const fileName = 'filename';
|
||||
const fileData = new Uint8Array(10).buffer;
|
||||
cryptoService.getOrgKey(Arg.any()).resolves(new SymmetricCryptoKey(new Uint8Array(32).buffer));
|
||||
it("attachments upload encrypted file contents", async () => {
|
||||
const fileName = "filename";
|
||||
const fileData = new Uint8Array(10).buffer;
|
||||
cryptoService.getOrgKey(Arg.any()).resolves(new SymmetricCryptoKey(new Uint8Array(32).buffer));
|
||||
|
||||
await cipherService.saveAttachmentRawWithServer(new Cipher(), fileName, fileData);
|
||||
await cipherService.saveAttachmentRawWithServer(new Cipher(), fileName, fileData);
|
||||
|
||||
fileUploadService.received(1).uploadCipherAttachment(Arg.any(), Arg.any(), new EncString(ENCRYPTED_TEXT), ENCRYPTED_BYTES);
|
||||
});
|
||||
fileUploadService
|
||||
.received(1)
|
||||
.uploadCipherAttachment(Arg.any(), Arg.any(), new EncString(ENCRYPTED_TEXT), ENCRYPTED_BYTES);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ConsoleLogService } from 'jslib-common/services/consoleLog.service';
|
||||
import { ConsoleLogService } from "jslib-common/services/consoleLog.service";
|
||||
|
||||
const originalConsole = console;
|
||||
let caughtMessage: any;
|
||||
@@ -6,90 +6,97 @@ let caughtMessage: any;
|
||||
declare var console: any;
|
||||
|
||||
export function interceptConsole(interceptions: any): object {
|
||||
console = {
|
||||
// tslint:disable-next-line
|
||||
log: function () {
|
||||
interceptions.log = arguments;
|
||||
},
|
||||
// tslint:disable-next-line
|
||||
warn: function () {
|
||||
interceptions.warn = arguments;
|
||||
},
|
||||
// tslint:disable-next-line
|
||||
error: function () {
|
||||
interceptions.error = arguments;
|
||||
},
|
||||
};
|
||||
return interceptions;
|
||||
console = {
|
||||
// tslint:disable-next-line
|
||||
log: function () {
|
||||
interceptions.log = arguments;
|
||||
},
|
||||
// tslint:disable-next-line
|
||||
warn: function () {
|
||||
interceptions.warn = arguments;
|
||||
},
|
||||
// tslint:disable-next-line
|
||||
error: function () {
|
||||
interceptions.error = arguments;
|
||||
},
|
||||
};
|
||||
return interceptions;
|
||||
}
|
||||
|
||||
export function restoreConsole() {
|
||||
console = originalConsole;
|
||||
console = originalConsole;
|
||||
}
|
||||
|
||||
describe('ConsoleLogService', () => {
|
||||
let logService: ConsoleLogService;
|
||||
beforeEach(() => {
|
||||
caughtMessage = {};
|
||||
interceptConsole(caughtMessage);
|
||||
logService = new ConsoleLogService(true);
|
||||
describe("ConsoleLogService", () => {
|
||||
let logService: ConsoleLogService;
|
||||
beforeEach(() => {
|
||||
caughtMessage = {};
|
||||
interceptConsole(caughtMessage);
|
||||
logService = new ConsoleLogService(true);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
restoreConsole();
|
||||
});
|
||||
|
||||
it("filters messages below the set threshold", () => {
|
||||
logService = new ConsoleLogService(true, (level) => true);
|
||||
logService.debug("debug");
|
||||
logService.info("info");
|
||||
logService.warning("warning");
|
||||
logService.error("error");
|
||||
|
||||
expect(caughtMessage).toEqual({});
|
||||
});
|
||||
it("only writes debug messages in dev mode", () => {
|
||||
logService = new ConsoleLogService(false);
|
||||
|
||||
logService.debug("debug message");
|
||||
expect(caughtMessage.log).toBeUndefined();
|
||||
});
|
||||
|
||||
it("writes debug/info messages to console.log", () => {
|
||||
logService.debug("this is a debug message");
|
||||
expect(caughtMessage).toEqual({
|
||||
log: jasmine.arrayWithExactContents(["this is a debug message"]),
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
restoreConsole();
|
||||
logService.info("this is an info message");
|
||||
expect(caughtMessage).toEqual({
|
||||
log: jasmine.arrayWithExactContents(["this is an info message"]),
|
||||
});
|
||||
|
||||
it('filters messages below the set threshold', () => {
|
||||
logService = new ConsoleLogService(true, level => true);
|
||||
logService.debug('debug');
|
||||
logService.info('info');
|
||||
logService.warning('warning');
|
||||
logService.error('error');
|
||||
|
||||
expect(caughtMessage).toEqual({});
|
||||
});
|
||||
it("writes warning messages to console.warn", () => {
|
||||
logService.warning("this is a warning message");
|
||||
expect(caughtMessage).toEqual({
|
||||
warn: jasmine.arrayWithExactContents(["this is a warning message"]),
|
||||
});
|
||||
it('only writes debug messages in dev mode', () => {
|
||||
logService = new ConsoleLogService(false);
|
||||
|
||||
logService.debug('debug message');
|
||||
expect(caughtMessage.log).toBeUndefined();
|
||||
});
|
||||
it("writes error messages to console.error", () => {
|
||||
logService.error("this is an error message");
|
||||
expect(caughtMessage).toEqual({
|
||||
error: jasmine.arrayWithExactContents(["this is an error message"]),
|
||||
});
|
||||
});
|
||||
|
||||
it("times with output to info", async () => {
|
||||
logService.time();
|
||||
await new Promise((r) => setTimeout(r, 250));
|
||||
const duration = logService.timeEnd();
|
||||
expect(duration[0]).toBe(0);
|
||||
expect(duration[1]).toBeGreaterThan(0);
|
||||
expect(duration[1]).toBeLessThan(500 * 10e6);
|
||||
|
||||
it('writes debug/info messages to console.log', () => {
|
||||
logService.debug('this is a debug message');
|
||||
expect(caughtMessage).toEqual({ log: jasmine.arrayWithExactContents(['this is a debug message']) });
|
||||
expect(caughtMessage).toEqual(jasmine.arrayContaining([]));
|
||||
expect(caughtMessage.log.length).toBe(1);
|
||||
expect(caughtMessage.log[0]).toEqual(jasmine.stringMatching(/^default: \d+\.?\d*ms$/));
|
||||
});
|
||||
|
||||
logService.info('this is an info message');
|
||||
expect(caughtMessage).toEqual({ log: jasmine.arrayWithExactContents(['this is an info message']) });
|
||||
});
|
||||
it('writes warning messages to console.warn', () => {
|
||||
logService.warning('this is a warning message');
|
||||
expect(caughtMessage).toEqual({ warn: jasmine.arrayWithExactContents(['this is a warning message']) });
|
||||
});
|
||||
it('writes error messages to console.error', () => {
|
||||
logService.error('this is an error message');
|
||||
expect(caughtMessage).toEqual({ error: jasmine.arrayWithExactContents(['this is an error message']) });
|
||||
});
|
||||
it("filters time output", async () => {
|
||||
logService = new ConsoleLogService(true, (level) => true);
|
||||
logService.time();
|
||||
logService.timeEnd();
|
||||
|
||||
it('times with output to info', async () => {
|
||||
logService.time();
|
||||
await new Promise(r => setTimeout(r, 250));
|
||||
const duration = logService.timeEnd();
|
||||
expect(duration[0]).toBe(0);
|
||||
expect(duration[1]).toBeGreaterThan(0);
|
||||
expect(duration[1]).toBeLessThan(500 * 10e6);
|
||||
|
||||
expect(caughtMessage).toEqual(jasmine.arrayContaining([]));
|
||||
expect(caughtMessage.log.length).toBe(1);
|
||||
expect(caughtMessage.log[0]).toEqual(jasmine.stringMatching(/^default: \d+\.?\d*ms$/));
|
||||
});
|
||||
|
||||
it('filters time output', async () => {
|
||||
logService = new ConsoleLogService(true, level => true);
|
||||
logService.time();
|
||||
logService.timeEnd();
|
||||
|
||||
expect(caughtMessage).toEqual({});
|
||||
});
|
||||
expect(caughtMessage).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,123 +1,135 @@
|
||||
import { Substitute, SubstituteOf } from '@fluffy-spoon/substitute';
|
||||
import { Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
|
||||
|
||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { CipherService } from 'jslib-common/abstractions/cipher.service';
|
||||
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
||||
import { FolderService } from 'jslib-common/abstractions/folder.service';
|
||||
import { ApiService } from "jslib-common/abstractions/api.service";
|
||||
import { CipherService } from "jslib-common/abstractions/cipher.service";
|
||||
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
||||
import { FolderService } from "jslib-common/abstractions/folder.service";
|
||||
|
||||
import { ExportService } from 'jslib-common/services/export.service';
|
||||
import { ExportService } from "jslib-common/services/export.service";
|
||||
|
||||
import { Cipher } from 'jslib-common/models/domain/cipher';
|
||||
import { EncString } from 'jslib-common/models/domain/encString';
|
||||
import { Login } from 'jslib-common/models/domain/login';
|
||||
import { CipherWithIds as CipherExport } from 'jslib-common/models/export/cipherWithIds';
|
||||
import { Cipher } from "jslib-common/models/domain/cipher";
|
||||
import { EncString } from "jslib-common/models/domain/encString";
|
||||
import { Login } from "jslib-common/models/domain/login";
|
||||
import { CipherWithIds as CipherExport } from "jslib-common/models/export/cipherWithIds";
|
||||
|
||||
import { CipherType } from 'jslib-common/enums/cipherType';
|
||||
import { CipherView } from 'jslib-common/models/view/cipherView';
|
||||
import { LoginView } from 'jslib-common/models/view/loginView';
|
||||
import { CipherType } from "jslib-common/enums/cipherType";
|
||||
import { CipherView } from "jslib-common/models/view/cipherView";
|
||||
import { LoginView } from "jslib-common/models/view/loginView";
|
||||
|
||||
import { BuildTestObject, GetUniqueString } from '../../utils';
|
||||
import { BuildTestObject, GetUniqueString } from "../../utils";
|
||||
|
||||
const UserCipherViews = [
|
||||
generateCipherView(false),
|
||||
generateCipherView(false),
|
||||
generateCipherView(true),
|
||||
generateCipherView(false),
|
||||
generateCipherView(false),
|
||||
generateCipherView(true),
|
||||
];
|
||||
|
||||
const UserCipherDomains = [
|
||||
generateCipherDomain(false),
|
||||
generateCipherDomain(false),
|
||||
generateCipherDomain(true),
|
||||
generateCipherDomain(false),
|
||||
generateCipherDomain(false),
|
||||
generateCipherDomain(true),
|
||||
];
|
||||
|
||||
function generateCipherView(deleted: boolean) {
|
||||
return BuildTestObject({
|
||||
id: GetUniqueString('id'),
|
||||
notes: GetUniqueString('notes'),
|
||||
type: CipherType.Login,
|
||||
login: BuildTestObject<LoginView>({
|
||||
username: GetUniqueString('username'),
|
||||
password: GetUniqueString('password'),
|
||||
}, LoginView),
|
||||
collectionIds: null,
|
||||
deletedDate: deleted ? new Date() : null,
|
||||
}, CipherView);
|
||||
return BuildTestObject(
|
||||
{
|
||||
id: GetUniqueString("id"),
|
||||
notes: GetUniqueString("notes"),
|
||||
type: CipherType.Login,
|
||||
login: BuildTestObject<LoginView>(
|
||||
{
|
||||
username: GetUniqueString("username"),
|
||||
password: GetUniqueString("password"),
|
||||
},
|
||||
LoginView
|
||||
),
|
||||
collectionIds: null,
|
||||
deletedDate: deleted ? new Date() : null,
|
||||
},
|
||||
CipherView
|
||||
);
|
||||
}
|
||||
|
||||
function generateCipherDomain(deleted: boolean) {
|
||||
return BuildTestObject({
|
||||
id: GetUniqueString('id'),
|
||||
notes: new EncString(GetUniqueString('notes')),
|
||||
type: CipherType.Login,
|
||||
login: BuildTestObject<Login>({
|
||||
username: new EncString(GetUniqueString('username')),
|
||||
password: new EncString(GetUniqueString('password')),
|
||||
}, Login),
|
||||
collectionIds: null,
|
||||
deletedDate: deleted ? new Date() : null,
|
||||
}, Cipher);
|
||||
return BuildTestObject(
|
||||
{
|
||||
id: GetUniqueString("id"),
|
||||
notes: new EncString(GetUniqueString("notes")),
|
||||
type: CipherType.Login,
|
||||
login: BuildTestObject<Login>(
|
||||
{
|
||||
username: new EncString(GetUniqueString("username")),
|
||||
password: new EncString(GetUniqueString("password")),
|
||||
},
|
||||
Login
|
||||
),
|
||||
collectionIds: null,
|
||||
deletedDate: deleted ? new Date() : null,
|
||||
},
|
||||
Cipher
|
||||
);
|
||||
}
|
||||
|
||||
function expectEqualCiphers(ciphers: CipherView[] | Cipher[], jsonResult: string) {
|
||||
const actual = JSON.stringify(JSON.parse(jsonResult).items);
|
||||
const items: CipherExport[] = [];
|
||||
ciphers.forEach((c: CipherView | Cipher) => {
|
||||
const item = new CipherExport();
|
||||
item.build(c);
|
||||
items.push(item);
|
||||
});
|
||||
const actual = JSON.stringify(JSON.parse(jsonResult).items);
|
||||
const items: CipherExport[] = [];
|
||||
ciphers.forEach((c: CipherView | Cipher) => {
|
||||
const item = new CipherExport();
|
||||
item.build(c);
|
||||
items.push(item);
|
||||
});
|
||||
|
||||
expect(actual).toEqual(JSON.stringify(items));
|
||||
expect(actual).toEqual(JSON.stringify(items));
|
||||
}
|
||||
|
||||
describe('ExportService', () => {
|
||||
let exportService: ExportService;
|
||||
let apiService: SubstituteOf<ApiService>;
|
||||
let cipherService: SubstituteOf<CipherService>;
|
||||
let folderService: SubstituteOf<FolderService>;
|
||||
let cryptoService: SubstituteOf<CryptoService>;
|
||||
describe("ExportService", () => {
|
||||
let exportService: ExportService;
|
||||
let apiService: SubstituteOf<ApiService>;
|
||||
let cipherService: SubstituteOf<CipherService>;
|
||||
let folderService: SubstituteOf<FolderService>;
|
||||
let cryptoService: SubstituteOf<CryptoService>;
|
||||
|
||||
beforeEach(() => {
|
||||
apiService = Substitute.for<ApiService>();
|
||||
cipherService = Substitute.for<CipherService>();
|
||||
folderService = Substitute.for<FolderService>();
|
||||
cryptoService = Substitute.for<CryptoService>();
|
||||
beforeEach(() => {
|
||||
apiService = Substitute.for<ApiService>();
|
||||
cipherService = Substitute.for<CipherService>();
|
||||
folderService = Substitute.for<FolderService>();
|
||||
cryptoService = Substitute.for<CryptoService>();
|
||||
|
||||
folderService.getAllDecrypted().resolves([]);
|
||||
folderService.getAll().resolves([]);
|
||||
folderService.getAllDecrypted().resolves([]);
|
||||
folderService.getAll().resolves([]);
|
||||
|
||||
exportService = new ExportService(folderService, cipherService, apiService, cryptoService);
|
||||
});
|
||||
exportService = new ExportService(folderService, cipherService, apiService, cryptoService);
|
||||
});
|
||||
|
||||
it('exports unecrypted user ciphers', async () => {
|
||||
cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1));
|
||||
it("exports unecrypted user ciphers", async () => {
|
||||
cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1));
|
||||
|
||||
const actual = await exportService.getExport('json');
|
||||
const actual = await exportService.getExport("json");
|
||||
|
||||
expectEqualCiphers(UserCipherViews.slice(0, 1), actual);
|
||||
});
|
||||
expectEqualCiphers(UserCipherViews.slice(0, 1), actual);
|
||||
});
|
||||
|
||||
it('exports encrypted json user ciphers', async () => {
|
||||
cipherService.getAll().resolves(UserCipherDomains.slice(0, 1));
|
||||
it("exports encrypted json user ciphers", async () => {
|
||||
cipherService.getAll().resolves(UserCipherDomains.slice(0, 1));
|
||||
|
||||
const actual = await exportService.getExport('encrypted_json');
|
||||
const actual = await exportService.getExport("encrypted_json");
|
||||
|
||||
expectEqualCiphers(UserCipherDomains.slice(0, 1), actual);
|
||||
});
|
||||
expectEqualCiphers(UserCipherDomains.slice(0, 1), actual);
|
||||
});
|
||||
|
||||
it('does not unecrypted export trashed user items', async () => {
|
||||
cipherService.getAllDecrypted().resolves(UserCipherViews);
|
||||
it("does not unecrypted export trashed user items", async () => {
|
||||
cipherService.getAllDecrypted().resolves(UserCipherViews);
|
||||
|
||||
const actual = await exportService.getExport('json');
|
||||
const actual = await exportService.getExport("json");
|
||||
|
||||
expectEqualCiphers(UserCipherViews.slice(0, 2), actual);
|
||||
});
|
||||
expectEqualCiphers(UserCipherViews.slice(0, 2), actual);
|
||||
});
|
||||
|
||||
it('does not encrypted export trashed user items', async () => {
|
||||
cipherService.getAll().resolves(UserCipherDomains);
|
||||
it("does not encrypted export trashed user items", async () => {
|
||||
cipherService.getAll().resolves(UserCipherDomains);
|
||||
|
||||
const actual = await exportService.getExport('encrypted_json');
|
||||
const actual = await exportService.getExport("encrypted_json");
|
||||
|
||||
expectEqualCiphers(UserCipherDomains.slice(0, 2), actual);
|
||||
});
|
||||
expectEqualCiphers(UserCipherDomains.slice(0, 2), actual);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user