Compare commits
18 Commits
v1.11.10
...
t3chguy/no
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a52d4aed9f | ||
|
|
66798c75b5 | ||
|
|
2ef6abbfb8 | ||
|
|
326a1a9056 | ||
|
|
341b0b469e | ||
|
|
0e8e472138 | ||
|
|
44eeb6fddc | ||
|
|
8383c021f1 | ||
|
|
7afa416ed5 | ||
|
|
d1f7454dc0 | ||
|
|
3bf3237774 | ||
|
|
f0e6673fec | ||
|
|
8891698745 | ||
|
|
ec4cc52b7e | ||
|
|
fb686ec5b6 | ||
|
|
1d86a75a29 | ||
|
|
ee5b20e12e | ||
|
|
c8184e2497 |
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@@ -18,6 +18,7 @@ jobs:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
1
.github/workflows/build_develop.yml
vendored
1
.github/workflows/build_develop.yml
vendored
@@ -22,6 +22,7 @@ jobs:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
4
.github/workflows/static_analysis.yaml
vendored
4
.github/workflows/static_analysis.yaml
vendored
@@ -19,6 +19,7 @@ jobs:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
@@ -39,6 +40,7 @@ jobs:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
@@ -56,6 +58,7 @@ jobs:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
# Needs branch matching as it inherits .stylelintrc.js from matrix-react-sdk
|
||||
- name: Install Dependencies
|
||||
@@ -73,6 +76,7 @@ jobs:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Deps
|
||||
run: "scripts/layered.sh"
|
||||
|
||||
1
.github/workflows/tests.yaml
vendored
1
.github/workflows/tests.yaml
vendored
@@ -21,6 +21,7 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
"preferred_domain": "meet.element.io"
|
||||
},
|
||||
"element_call": {
|
||||
"url": "https://call.element.io"
|
||||
"url": "https://call.element.io",
|
||||
"participant_limit": 8,
|
||||
"brand": "Element Call"
|
||||
},
|
||||
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
|
||||
}
|
||||
|
||||
@@ -323,6 +323,10 @@ The VoIP and Jitsi options are:
|
||||
and may be removed at any time without notice. Defaults to `https://call.element.io`.
|
||||
- `use_exclusively`: A boolean specifying whether Element Call should be used exclusively as the only VoIP stack in
|
||||
the app, removing the ability to start legacy 1:1 calls or Jitsi calls. Defaults to `false`.
|
||||
- `participant_limit`: The maximum number of users who can join a call; if
|
||||
this number is exceeded, the user will not be able to join a given call.
|
||||
- `brand`: Optional name for the app. Defaults to `Element Call`. This is
|
||||
used throughout the application in various strings/locations.
|
||||
|
||||
## Bug reporting
|
||||
|
||||
|
||||
10
package.json
10
package.json
@@ -61,8 +61,8 @@
|
||||
"gfm.css": "^1.1.2",
|
||||
"jsrsasign": "^10.5.25",
|
||||
"katex": "^0.16.0",
|
||||
"matrix-js-sdk": "20.1.0",
|
||||
"matrix-react-sdk": "3.58.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-react-sdk": "github:matrix-org/matrix-react-sdk#develop",
|
||||
"matrix-widget-api": "^1.1.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "17.0.2",
|
||||
@@ -119,18 +119,19 @@
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"fake-indexeddb": "^3.1.2",
|
||||
"fetch-mock-jest": "^1.5.1",
|
||||
"file-loader": "^5.1.0",
|
||||
"fs-extra": "^0.30.0",
|
||||
"html-webpack-plugin": "^4.5.2",
|
||||
"jest": "^29.0.0",
|
||||
"jest-canvas-mock": "^2.3.0",
|
||||
"jest-environment-jsdom": "^29.0.0",
|
||||
"jest-mock": "^27.5.1",
|
||||
"jest-mock": "^29.0.0",
|
||||
"jest-raw-loader": "^1.0.1",
|
||||
"jest-sonar-reporter": "^2.0.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"loader-utils": "^1.4.0",
|
||||
"matrix-mock-request": "^2.0.0",
|
||||
"matrix-mock-request": "^2.5.0",
|
||||
"matrix-react-test-utils": "^0.2.3",
|
||||
"matrix-web-i18n": "^1.3.0",
|
||||
"mini-css-extract-plugin": "^1",
|
||||
@@ -188,7 +189,6 @@
|
||||
"\\.(gif|png|ttf|woff2)$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/imageMock.js",
|
||||
"\\.svg$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/svg.js",
|
||||
"\\$webapp/i18n/languages.json": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/languages.json",
|
||||
"^browser-request$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/browser-request.js",
|
||||
"^react$": "<rootDir>/node_modules/react",
|
||||
"^react-dom$": "<rootDir>/node_modules/react-dom",
|
||||
"^matrix-js-sdk$": "<rootDir>/node_modules/matrix-js-sdk/src",
|
||||
|
||||
@@ -36,10 +36,12 @@ limitations under the License.
|
||||
"Apple Color Emoji",
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol";
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
color: #000;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.mx_ErrorView_container {
|
||||
max-width: 680px;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# the branch the current checkout is on, use that branch. Otherwise,
|
||||
# use develop.
|
||||
|
||||
set -ex
|
||||
set -x
|
||||
|
||||
GIT_CLONE_ARGS=("$@")
|
||||
[ -z "$defbranch" ] && defbranch="develop"
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
# all phonenumber.js-supported country flags (as SVGs) into
|
||||
# PNGs that can be used by CountryDropdown.js.
|
||||
|
||||
set -e
|
||||
|
||||
# Allow CTRL+C to terminate the script
|
||||
trap "echo Exited!; exit;" SIGINT SIGTERM
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# Echoes a version based on the git hashes of the element-web, react-sdk & js-sdk checkouts, for the case where
|
||||
# these dependencies are git checkouts.
|
||||
|
||||
set -e
|
||||
|
||||
# Since the deps are fetched from git, we can rev-parse
|
||||
REACT_SHA=$(git -C node_modules/matrix-react-sdk rev-parse --short=12 HEAD)
|
||||
JSSDK_SHA=$(git -C node_modules/matrix-js-sdk rev-parse --short=12 HEAD)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
set -ex
|
||||
|
||||
# Creates a layered environment with the full repo for the app and SDKs cloned
|
||||
# and linked. This gives an element-web dev environment ready to build with
|
||||
|
||||
@@ -12,8 +12,7 @@ then
|
||||
exit
|
||||
fi
|
||||
|
||||
set -e
|
||||
set -x
|
||||
set -ex
|
||||
|
||||
tmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'icontmp'`
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# If $1 looks like v1.2.3 or v1.2.3-foo, strip the leading v, then print it to stdout
|
||||
if [[ $1 =~ ^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(-.+)?$ ]]; then
|
||||
echo ${1:1}
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
"Download Completed": "Download Completed",
|
||||
"Open": "Open",
|
||||
"Dismiss": "Dismiss",
|
||||
"%(brand)s Desktop (%(platformName)s)": "%(brand)s Desktop (%(platformName)s)",
|
||||
"%(brand)s Desktop: %(platformName)s": "%(brand)s Desktop: %(platformName)s",
|
||||
"Go to your browser to complete Sign In": "Go to your browser to complete Sign In",
|
||||
"Unknown device": "Unknown device",
|
||||
"%(appName)s (%(browserName)s, %(osName)s)": "%(appName)s (%(browserName)s, %(osName)s)",
|
||||
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s: %(browserName)s on %(osName)s",
|
||||
"Powered by Matrix": "Powered by Matrix",
|
||||
"Use %(brand)s on mobile": "Use %(brand)s on mobile",
|
||||
"Unsupported browser": "Unsupported browser",
|
||||
|
||||
@@ -18,8 +18,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// To ensure we load the browser-request version
|
||||
import "matrix-js-sdk"; // eslint-disable-line no-restricted-imports
|
||||
// To ensure we load the browser-matrix version first
|
||||
import "matrix-js-sdk/src/browser-index";
|
||||
|
||||
import React from 'react';
|
||||
import PlatformPeg from 'matrix-react-sdk/src/PlatformPeg';
|
||||
|
||||
@@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import request from 'browser-request';
|
||||
|
||||
import type { IConfigOptions } from "matrix-react-sdk/src/IConfigOptions";
|
||||
|
||||
// Load the config file. First try to load up a domain-specific config of the
|
||||
@@ -32,44 +30,28 @@ export async function getVectorConfig(relativeLocation=''): Promise<IConfigOptio
|
||||
if (Object.keys(configJson).length === 0) {
|
||||
throw new Error(); // throw to enter the catch
|
||||
}
|
||||
return configJson as IConfigOptions;
|
||||
return configJson;
|
||||
} catch (e) {
|
||||
return await generalConfigPromise as IConfigOptions;
|
||||
return generalConfigPromise;
|
||||
}
|
||||
}
|
||||
|
||||
function getConfig(configJsonFilename: string): Promise<{}> {
|
||||
return new Promise(function(resolve, reject) {
|
||||
request(
|
||||
{ method: "GET", url: configJsonFilename, qs: { cachebuster: Date.now() } },
|
||||
(err, response, body) => {
|
||||
try {
|
||||
if (err || response.status < 200 || response.status >= 300) {
|
||||
// Lack of a config isn't an error, we should
|
||||
// just use the defaults.
|
||||
// Also treat a blank config as no config, assuming
|
||||
// the status code is 0, because we don't get 404s
|
||||
// from file: URIs so this is the only way we can
|
||||
// not fail if the file doesn't exist when loading
|
||||
// from a file:// URI.
|
||||
if (response) {
|
||||
if (response.status == 404 || (response.status == 0 && body == '')) {
|
||||
resolve({});
|
||||
}
|
||||
}
|
||||
reject({ err: err, response: response });
|
||||
return;
|
||||
}
|
||||
|
||||
// We parse the JSON ourselves rather than use the JSON
|
||||
// parameter, since this throws a parse error on empty
|
||||
// which breaks if there's no config.json and we're
|
||||
// loading from the filesystem (see above).
|
||||
resolve(JSON.parse(body));
|
||||
} catch (e) {
|
||||
reject({ err: e });
|
||||
}
|
||||
},
|
||||
);
|
||||
async function getConfig(configJsonFilename: string): Promise<IConfigOptions> {
|
||||
const url = new URL(configJsonFilename, window.location.href);
|
||||
url.searchParams.set("cachebuster", Date.now().toString());
|
||||
const res = await fetch(url, {
|
||||
cache: "no-cache",
|
||||
method: "GET",
|
||||
});
|
||||
|
||||
if (res.status === 404 || res.status === 0) {
|
||||
// Lack of a config isn't an error, we should just use the defaults.
|
||||
// Also treat a blank config as no config, assuming the status code is 0, because we don't get 404s from file:
|
||||
// URIs so this is the only way we can not fail if the file doesn't exist when loading from a file:// URI.
|
||||
return {} as IConfigOptions;
|
||||
}
|
||||
|
||||
if (res.ok) {
|
||||
return res.json();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ import VectorBasePlatform from './VectorBasePlatform';
|
||||
import { SeshatIndexManager } from "./SeshatIndexManager";
|
||||
import { IPCManager } from "./IPCManager";
|
||||
|
||||
const electron = window.electron;
|
||||
const isMac = navigator.platform.toUpperCase().includes('MAC');
|
||||
|
||||
function platformFriendlyName(): string {
|
||||
@@ -70,7 +69,7 @@ function platformFriendlyName(): string {
|
||||
function onAction(payload: ActionPayload): void {
|
||||
// Whitelist payload actions, no point sending most across
|
||||
if (['call_state'].includes(payload.action)) {
|
||||
electron.send('app_onAction', payload);
|
||||
window.electron.send('app_onAction', payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +102,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||
false if there is not
|
||||
or the error if one is encountered
|
||||
*/
|
||||
electron.on('check_updates', (event, status) => {
|
||||
window.electron.on('check_updates', (event, status) => {
|
||||
dis.dispatch<CheckUpdatesPayload>({
|
||||
action: Action.CheckUpdates,
|
||||
...getUpdateCheckStatus(status),
|
||||
@@ -111,27 +110,27 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||
});
|
||||
|
||||
// try to flush the rageshake logs to indexeddb before quit.
|
||||
electron.on('before-quit', function() {
|
||||
window.electron.on('before-quit', function() {
|
||||
logger.log('element-desktop closing');
|
||||
rageshake.flush();
|
||||
});
|
||||
|
||||
electron.on('update-downloaded', this.onUpdateDownloaded);
|
||||
window.electron.on('update-downloaded', this.onUpdateDownloaded);
|
||||
|
||||
electron.on('preferences', () => {
|
||||
window.electron.on('preferences', () => {
|
||||
dis.fire(Action.ViewUserSettings);
|
||||
});
|
||||
|
||||
electron.on('userDownloadCompleted', (ev, { id, name }) => {
|
||||
window.electron.on('userDownloadCompleted', (ev, { id, name }) => {
|
||||
const key = `DOWNLOAD_TOAST_${id}`;
|
||||
|
||||
const onAccept = () => {
|
||||
electron.send('userDownloadAction', { id, open: true });
|
||||
window.electron.send('userDownloadAction', { id, open: true });
|
||||
ToastStore.sharedInstance().dismissToast(key);
|
||||
};
|
||||
|
||||
const onDismiss = () => {
|
||||
electron.send('userDownloadAction', { id });
|
||||
window.electron.send('userDownloadAction', { id });
|
||||
};
|
||||
|
||||
ToastStore.sharedInstance().addOrReplaceToast({
|
||||
@@ -187,7 +186,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||
if (this.notificationCount === count) return;
|
||||
super.setNotificationCount(count);
|
||||
|
||||
electron.send('setBadgeCount', count);
|
||||
window.electron.send('setBadgeCount', count);
|
||||
}
|
||||
|
||||
public supportsNotifications(): boolean {
|
||||
@@ -233,7 +232,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||
}
|
||||
|
||||
public loudNotification(ev: MatrixEvent, room: Room) {
|
||||
electron.send('loudNotification');
|
||||
window.electron.send('loudNotification');
|
||||
}
|
||||
|
||||
public needsUrlTooltips(): boolean {
|
||||
@@ -269,19 +268,19 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||
|
||||
public startUpdateCheck() {
|
||||
super.startUpdateCheck();
|
||||
electron.send('check_updates');
|
||||
window.electron.send('check_updates');
|
||||
}
|
||||
|
||||
public installUpdate() {
|
||||
// IPC to the main process to install the update, since quitAndInstall
|
||||
// doesn't fire the before-quit event so the main process needs to know
|
||||
// it should exit.
|
||||
electron.send('install_update');
|
||||
window.electron.send('install_update');
|
||||
}
|
||||
|
||||
public getDefaultDeviceDisplayName(): string {
|
||||
const brand = SdkConfig.get().brand;
|
||||
return _t('%(brand)s Desktop (%(platformName)s)', {
|
||||
return _t('%(brand)s Desktop: %(platformName)s', {
|
||||
brand,
|
||||
platformName: platformFriendlyName(),
|
||||
});
|
||||
|
||||
@@ -19,8 +19,6 @@ import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { ElectronChannel } from "../../@types/global";
|
||||
|
||||
const electron = window.electron;
|
||||
|
||||
interface IPCPayload {
|
||||
id?: number;
|
||||
error?: string;
|
||||
@@ -35,7 +33,7 @@ export class IPCManager {
|
||||
private readonly sendChannel: ElectronChannel = "ipcCall",
|
||||
private readonly recvChannel: ElectronChannel = "ipcReply",
|
||||
) {
|
||||
electron.on(this.recvChannel, this.onIpcReply);
|
||||
window.electron.on(this.recvChannel, this.onIpcReply);
|
||||
}
|
||||
|
||||
public async call(name: string, ...args: any[]): Promise<any> {
|
||||
|
||||
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { UpdateCheckStatus, UpdateStatus } from "matrix-react-sdk/src/BasePlatform";
|
||||
import request from 'browser-request';
|
||||
import dis from 'matrix-react-sdk/src/dispatcher/dispatcher';
|
||||
import { _t } from 'matrix-react-sdk/src/languageHandler';
|
||||
import { hideToast as hideUpdateToast, showToast as showUpdateToast } from "matrix-react-sdk/src/toasts/UpdateToast";
|
||||
@@ -87,31 +86,18 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||
});
|
||||
}
|
||||
|
||||
private getMostRecentVersion(): Promise<string> {
|
||||
// We add a cachebuster to the request to make sure that we know about
|
||||
// the most recent version on the origin server. That might not
|
||||
// actually be the version we'd get on a reload (particularly in the
|
||||
// presence of intermediate caching proxies), but still: we're trying
|
||||
// to tell the user that there is a new version.
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
method: "GET",
|
||||
url: "version",
|
||||
qs: { cachebuster: Date.now() },
|
||||
},
|
||||
(err, response, body) => {
|
||||
if (err || response.status < 200 || response.status >= 300) {
|
||||
if (err === null) err = { status: response.status };
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(getNormalizedAppVersion(body.trim()));
|
||||
},
|
||||
);
|
||||
private async getMostRecentVersion(): Promise<string> {
|
||||
const res = await fetch("version", {
|
||||
method: "GET",
|
||||
cache: "no-cache",
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const text = await res.text();
|
||||
return getNormalizedAppVersion(text.trim());
|
||||
}
|
||||
|
||||
return Promise.reject({ status: res.status });
|
||||
}
|
||||
|
||||
public getAppVersion(): Promise<string> {
|
||||
@@ -210,7 +196,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||
let osName = ua.getOS().name || "unknown OS";
|
||||
// Stylise the value from the parser to match Apple's current branding.
|
||||
if (osName === "Mac OS") osName = "macOS";
|
||||
return _t('%(appName)s (%(browserName)s, %(osName)s)', {
|
||||
return _t('%(appName)s: %(browserName)s on %(osName)s', {
|
||||
appName,
|
||||
browserName,
|
||||
osName,
|
||||
|
||||
@@ -41,6 +41,7 @@ import { RoomView as RoomViewClass } from 'matrix-react-sdk/src/components/struc
|
||||
import LoginComponent from 'matrix-react-sdk/src/components/structures/auth/Login';
|
||||
import WelcomeComponent from "matrix-react-sdk/src/components/views/auth/Welcome";
|
||||
import EmbeddedPage from "matrix-react-sdk/src/components/structures/EmbeddedPage";
|
||||
import { AutoDiscovery } from 'matrix-js-sdk/src/matrix';
|
||||
|
||||
const DEFAULT_HS_URL='http://my_server';
|
||||
const DEFAULT_IS_URL='http://my_is';
|
||||
@@ -60,7 +61,7 @@ describe('loading:', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
httpBackend = new MockHttpBackend();
|
||||
jssdk.request(httpBackend.requestFn);
|
||||
window.fetch = httpBackend.fetchFn;
|
||||
parentDiv = document.createElement('div');
|
||||
|
||||
// uncomment this to actually add the div to the UI, to help with
|
||||
@@ -73,21 +74,25 @@ describe('loading:', function() {
|
||||
|
||||
afterEach(async function() {
|
||||
console.log(`${Date.now()}: loading: afterEach`);
|
||||
if (parentDiv) {
|
||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||
parentDiv.remove();
|
||||
parentDiv = null;
|
||||
try {
|
||||
if (matrixChat) {
|
||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||
parentDiv.remove();
|
||||
parentDiv = null;
|
||||
}
|
||||
|
||||
// unmounting should have cleared the MatrixClientPeg
|
||||
expect(MatrixClientPeg.get()).toBe(null);
|
||||
|
||||
// clear the indexeddbs so we can start from a clean slate next time.
|
||||
await Promise.all([
|
||||
test_utils.deleteIndexedDB('matrix-js-sdk:crypto'),
|
||||
test_utils.deleteIndexedDB('matrix-js-sdk:riot-web-sync'),
|
||||
]);
|
||||
cleanLocalstorage();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// unmounting should have cleared the MatrixClientPeg
|
||||
expect(MatrixClientPeg.get()).toBe(null);
|
||||
|
||||
// clear the indexeddbs so we can start from a clean slate next time.
|
||||
await Promise.all([
|
||||
test_utils.deleteIndexedDB('matrix-js-sdk:crypto'),
|
||||
test_utils.deleteIndexedDB('matrix-js-sdk:riot-web-sync'),
|
||||
]);
|
||||
cleanLocalstorage();
|
||||
console.log(`${Date.now()}: loading: afterEach complete`);
|
||||
});
|
||||
|
||||
@@ -421,7 +426,6 @@ describe('loading:', function() {
|
||||
|
||||
describe('Guest auto-registration:', function() {
|
||||
it('shows a welcome page by default', function() {
|
||||
|
||||
loadApp();
|
||||
|
||||
return sleep(1).then(() => {
|
||||
|
||||
@@ -14,14 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import request from 'browser-request';
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
|
||||
import { getVectorConfig } from "../../../src/vector/getconfig";
|
||||
|
||||
describe('getVectorConfig()', () => {
|
||||
const setRequestMockImplementationOnce = (err?: unknown, response?: { status: number }, body?: string) =>
|
||||
request.mockImplementationOnce((_opts, callback) => callback(err, response, body));
|
||||
fetchMock.config.overwriteRoutes = true;
|
||||
|
||||
describe('getVectorConfig()', () => {
|
||||
const prevDocumentDomain = document.domain;
|
||||
const elementDomain = 'app.element.io';
|
||||
const now = 1234567890;
|
||||
@@ -38,6 +37,7 @@ describe('getVectorConfig()', () => {
|
||||
// stable value for cachebuster
|
||||
jest.spyOn(Date, 'now').mockReturnValue(now);
|
||||
jest.clearAllMocks();
|
||||
fetchMock.mockClear();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
@@ -46,85 +46,67 @@ describe('getVectorConfig()', () => {
|
||||
});
|
||||
|
||||
it('requests specific config for document domain', async () => {
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(specificConfig))
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", specificConfig);
|
||||
fetchMock.getOnce("express:/config.json", generalConfig);
|
||||
|
||||
await getVectorConfig();
|
||||
|
||||
expect(request.mock.calls[0][0]).toEqual({ method: "GET", url: 'config.app.element.io.json', qs: { cachebuster: now } })
|
||||
await expect(getVectorConfig()).resolves.toEqual(specificConfig);
|
||||
});
|
||||
|
||||
it('adds trailing slash to relativeLocation when not an empty string', async () => {
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(specificConfig))
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
fetchMock.getOnce("express:../config.app.element.io.json", specificConfig);
|
||||
fetchMock.getOnce("express:../config.json", generalConfig);
|
||||
|
||||
await getVectorConfig('..');
|
||||
|
||||
expect(request.mock.calls[0][0]).toEqual(expect.objectContaining({ url: '../config.app.element.io.json' }))
|
||||
expect(request.mock.calls[1][0]).toEqual(expect.objectContaining({ url: '../config.json' }))
|
||||
});
|
||||
|
||||
it('returns parsed specific config when it is non-empty', async () => {
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(specificConfig))
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
|
||||
const result = await getVectorConfig();
|
||||
expect(result).toEqual(specificConfig);
|
||||
await expect(getVectorConfig("..")).resolves.toEqual(specificConfig);
|
||||
});
|
||||
|
||||
it('returns general config when specific config succeeds but is empty', async () => {
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify({}))
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", {});
|
||||
fetchMock.getOnce("express:/config.json", generalConfig);
|
||||
|
||||
const result = await getVectorConfig();
|
||||
expect(result).toEqual(generalConfig);
|
||||
await expect(getVectorConfig()).resolves.toEqual(generalConfig);
|
||||
});
|
||||
|
||||
it('returns general config when specific config 404s', async () => {
|
||||
setRequestMockImplementationOnce(undefined, { status: 404 })
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", { status: 404 });
|
||||
fetchMock.getOnce("express:/config.json", generalConfig);
|
||||
|
||||
const result = await getVectorConfig();
|
||||
expect(result).toEqual(generalConfig);
|
||||
await expect(getVectorConfig()).resolves.toEqual(generalConfig);
|
||||
});
|
||||
|
||||
it('returns general config when specific config is fetched from a file and is empty', async () => {
|
||||
setRequestMockImplementationOnce(undefined, { status: 0 }, '')
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", 0);
|
||||
fetchMock.getOnce("express:/config.json", generalConfig);
|
||||
|
||||
const result = await getVectorConfig();
|
||||
expect(result).toEqual(generalConfig);
|
||||
await expect(getVectorConfig()).resolves.toEqual(generalConfig);
|
||||
});
|
||||
|
||||
it('returns general config when specific config returns a non-200 status', async () => {
|
||||
setRequestMockImplementationOnce(undefined, { status: 401 })
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", { status: 401 });
|
||||
fetchMock.getOnce("express:/config.json", generalConfig);
|
||||
|
||||
const result = await getVectorConfig();
|
||||
expect(result).toEqual(generalConfig);
|
||||
await expect(getVectorConfig()).resolves.toEqual(generalConfig);
|
||||
});
|
||||
|
||||
it('returns general config when specific config returns an error', async () => {
|
||||
setRequestMockImplementationOnce('err1')
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, JSON.stringify(generalConfig))
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", { throws: "err1" });
|
||||
fetchMock.getOnce("express:/config.json", generalConfig);
|
||||
|
||||
const result = await getVectorConfig();
|
||||
expect(result).toEqual(generalConfig);
|
||||
await expect(getVectorConfig()).resolves.toEqual(generalConfig);
|
||||
});
|
||||
|
||||
it('rejects with an error when general config rejects', async () => {
|
||||
setRequestMockImplementationOnce('err-specific');
|
||||
setRequestMockImplementationOnce('err-general');
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", { throws: "err-specific" });
|
||||
fetchMock.getOnce("express:/config.json", { throws: "err-general" });
|
||||
|
||||
await expect(() => getVectorConfig()).rejects.toEqual({"err": "err-general", "response": undefined});
|
||||
await expect(getVectorConfig()).rejects.toBe("err-general");
|
||||
});
|
||||
|
||||
it('rejects with an error when config is invalid JSON', async () => {
|
||||
setRequestMockImplementationOnce('err-specific');
|
||||
setRequestMockImplementationOnce(undefined, { status: 200 }, '{"invalid": "json",}');
|
||||
fetchMock.getOnce("express:/config.app.element.io.json", { throws: "err-specific" });
|
||||
fetchMock.getOnce("express:/config.json", '{"invalid": "json",}');
|
||||
|
||||
await expect(() => getVectorConfig()).rejects.toEqual({
|
||||
err: new SyntaxError("Unexpected token } in JSON at position 19"),
|
||||
});
|
||||
// We can't assert it'll be a SyntaxError as node-fetch behaves differently
|
||||
// https://github.com/wheresrhys/fetch-mock/issues/270
|
||||
await expect(getVectorConfig()).rejects.toThrow("Unexpected token } in JSON at position 19");
|
||||
});
|
||||
});
|
||||
|
||||
279
test/unit-tests/vector/platform/ElectronPlatform-test.ts
Normal file
279
test/unit-tests/vector/platform/ElectronPlatform-test.ts
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import request from 'browser-request';
|
||||
import EventEmitter from 'events';
|
||||
import { logger } from 'matrix-js-sdk/src/logger';
|
||||
import { MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk/src/matrix';
|
||||
import { UpdateCheckStatus } from 'matrix-react-sdk/src/BasePlatform';
|
||||
import { Action } from 'matrix-react-sdk/src/dispatcher/actions';
|
||||
import dispatcher from 'matrix-react-sdk/src/dispatcher/dispatcher';
|
||||
import { MatrixClientPeg } from 'matrix-react-sdk/src/MatrixClientPeg';
|
||||
import * as rageshake from 'matrix-react-sdk/src/rageshake/rageshake';
|
||||
|
||||
import ElectronPlatform from '../../../../src/vector/platform/ElectronPlatform';
|
||||
|
||||
jest.mock('matrix-react-sdk/src/rageshake/rageshake', () => ({
|
||||
flush: jest.fn()
|
||||
}))
|
||||
|
||||
|
||||
describe('ElectronPlatform', () => {
|
||||
const defaultUserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36';
|
||||
const mockElectron = {
|
||||
on: jest.fn(),
|
||||
send: jest.fn()
|
||||
};
|
||||
|
||||
const dispatchSpy = jest.spyOn(dispatcher, 'dispatch');
|
||||
const dispatchFireSpy = jest.spyOn(dispatcher, 'fire');
|
||||
const logSpy = jest.spyOn(logger, 'log').mockImplementation(() => {});
|
||||
|
||||
const userId = '@alice:server.org';
|
||||
const deviceId = 'device-id';
|
||||
|
||||
window.electron = mockElectron;
|
||||
beforeEach(() => {
|
||||
window.electron = mockElectron;
|
||||
jest.clearAllMocks();
|
||||
delete window.navigator;
|
||||
window.navigator = { userAgent: defaultUserAgent } as unknown as Navigator;
|
||||
});
|
||||
|
||||
const getElectronEventHandlerCall = (eventType: string): [type: string, handler: Function] | undefined =>
|
||||
mockElectron.on.mock.calls.find(([type]) => type === eventType);
|
||||
|
||||
it('flushes rageshake before quitting', () => {
|
||||
new ElectronPlatform();
|
||||
const [event, handler] = getElectronEventHandlerCall('before-quit');
|
||||
// correct event bound
|
||||
expect(event).toBeTruthy();
|
||||
|
||||
handler();
|
||||
|
||||
expect(logSpy).toHaveBeenCalled();
|
||||
expect(rageshake.flush).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('dispatches view settings action on preferences event', () => {
|
||||
new ElectronPlatform();
|
||||
const [event, handler] = getElectronEventHandlerCall('preferences');
|
||||
// correct event bound
|
||||
expect(event).toBeTruthy();
|
||||
|
||||
handler();
|
||||
|
||||
expect(dispatchFireSpy).toHaveBeenCalledWith(Action.ViewUserSettings);
|
||||
});
|
||||
|
||||
describe('updates', () => {
|
||||
it('dispatches on check updates action', () => {
|
||||
new ElectronPlatform();
|
||||
const [event, handler] = getElectronEventHandlerCall('check_updates');
|
||||
// correct event bound
|
||||
expect(event).toBeTruthy();
|
||||
|
||||
handler({}, true);
|
||||
expect(dispatchSpy).toHaveBeenCalledWith({
|
||||
action: Action.CheckUpdates,
|
||||
status: UpdateCheckStatus.Downloading
|
||||
})
|
||||
});
|
||||
|
||||
it('dispatches on check updates action when update not available', () => {
|
||||
new ElectronPlatform();
|
||||
const [, handler] = getElectronEventHandlerCall('check_updates');
|
||||
|
||||
handler({}, false);
|
||||
expect(dispatchSpy).toHaveBeenCalledWith({
|
||||
action: Action.CheckUpdates,
|
||||
status: UpdateCheckStatus.NotAvailable
|
||||
})
|
||||
});
|
||||
|
||||
it('starts update check', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
platform.startUpdateCheck();
|
||||
expect(mockElectron.send).toHaveBeenCalledWith('check_updates')
|
||||
});
|
||||
|
||||
it('installs update', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
platform.installUpdate();
|
||||
expect(mockElectron.send).toHaveBeenCalledWith('install_update')
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('returns human readable name', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.getHumanReadableName()).toEqual('Electron Platform');
|
||||
});
|
||||
|
||||
describe("getDefaultDeviceDisplayName", () => {
|
||||
it.each([[
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
|
||||
"Element Desktop: macOS",
|
||||
],
|
||||
[
|
||||
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) electron/1.0.0 Chrome/53.0.2785.113 Electron/1.4.3 Safari/537.36",
|
||||
"Element Desktop: Windows",
|
||||
],
|
||||
[
|
||||
"Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20100101 Firefox/21.0",
|
||||
"Element Desktop: Linux",
|
||||
],
|
||||
[
|
||||
"Mozilla/5.0 (X11; FreeBSD i686; rv:21.0) Gecko/20100101 Firefox/21.0",
|
||||
"Element Desktop: FreeBSD",
|
||||
],
|
||||
[
|
||||
"Mozilla/5.0 (X11; OpenBSD i686; rv:21.0) Gecko/20100101 Firefox/21.0",
|
||||
"Element Desktop: OpenBSD",
|
||||
],
|
||||
[
|
||||
"Mozilla/5.0 (X11; SunOS i686; rv:21.0) Gecko/20100101 Firefox/21.0",
|
||||
"Element Desktop: SunOS",
|
||||
],
|
||||
[
|
||||
"custom user agent",
|
||||
"Element Desktop: Unknown",
|
||||
],
|
||||
|
||||
])("%s = %s", (userAgent, result) => {
|
||||
delete window.navigator;
|
||||
window.navigator = { userAgent } as unknown as Navigator;
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.getDefaultDeviceDisplayName()).toEqual(result);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true for needsUrlTooltips', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.needsUrlTooltips()).toBe(true);
|
||||
});
|
||||
|
||||
it('should override browser shortcuts', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.overrideBrowserShortcuts()).toBe(true);
|
||||
});
|
||||
|
||||
it('allows overriding native context menus', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.allowOverridingNativeContextMenus()).toBe(true);
|
||||
});
|
||||
|
||||
it('indicates support for desktop capturer', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.supportsDesktopCapturer()).toBe(true);
|
||||
});
|
||||
|
||||
it('indicates no support for jitsi screensharing', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.supportsJitsiScreensharing()).toBe(false);
|
||||
});
|
||||
|
||||
describe('notifications', () => {
|
||||
it('indicates support for notifications', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.supportsNotifications()).toBe(true);
|
||||
});
|
||||
|
||||
it('may send notifications', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.maySendNotifications()).toBe(true);
|
||||
});
|
||||
|
||||
it('pretends to request notification permission', async () => {
|
||||
const platform = new ElectronPlatform();
|
||||
const result = await platform.requestNotificationPermission();
|
||||
expect(result).toEqual('granted');
|
||||
});
|
||||
|
||||
it('creates a loud notification', async () => {
|
||||
const platform = new ElectronPlatform();
|
||||
platform.loudNotification(new MatrixEvent(), new Room('!room:server', {} as any, userId));
|
||||
expect(mockElectron.send).toHaveBeenCalledWith('loudNotification');
|
||||
});
|
||||
|
||||
it('sets notification count when count is changing', async () => {
|
||||
const platform = new ElectronPlatform();
|
||||
platform.setNotificationCount(0);
|
||||
// not called because matches internal notificaiton count
|
||||
expect(mockElectron.send).not.toHaveBeenCalledWith('setBadgeCount', 0);
|
||||
platform.setNotificationCount(1);
|
||||
expect(mockElectron.send).toHaveBeenCalledWith('setBadgeCount', 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('spellcheck', () => {
|
||||
it('indicates support for spellcheck settings', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
expect(platform.supportsSpellCheckSettings()).toBe(true);
|
||||
});
|
||||
|
||||
it('gets available spellcheck languages', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
mockElectron.send.mockClear();
|
||||
platform.getAvailableSpellCheckLanguages();
|
||||
|
||||
const [channel, { name }] = mockElectron.send.mock.calls[0];
|
||||
expect(channel).toEqual("ipcCall");
|
||||
expect(name).toEqual('getAvailableSpellCheckLanguages')
|
||||
});
|
||||
});
|
||||
|
||||
describe('pickle key', () => {
|
||||
it('makes correct ipc call to get pickle key', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
mockElectron.send.mockClear();
|
||||
platform.getPickleKey(userId, deviceId);
|
||||
|
||||
const [, { name, args }] = mockElectron.send.mock.calls[0];
|
||||
expect(name).toEqual('getPickleKey')
|
||||
expect(args).toEqual([userId, deviceId])
|
||||
});
|
||||
|
||||
it('makes correct ipc call to create pickle key', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
mockElectron.send.mockClear();
|
||||
platform.createPickleKey(userId, deviceId);
|
||||
|
||||
const [, { name, args }] = mockElectron.send.mock.calls[0];
|
||||
expect(name).toEqual('createPickleKey')
|
||||
expect(args).toEqual([userId, deviceId])
|
||||
});
|
||||
|
||||
it('makes correct ipc call to destroy pickle key', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
mockElectron.send.mockClear();
|
||||
platform.destroyPickleKey(userId, deviceId);
|
||||
|
||||
const [, { name, args }] = mockElectron.send.mock.calls[0];
|
||||
expect(name).toEqual('destroyPickleKey')
|
||||
expect(args).toEqual([userId, deviceId])
|
||||
});
|
||||
});
|
||||
|
||||
describe('versions', () => {
|
||||
it('calls install update', () => {
|
||||
const platform = new ElectronPlatform();
|
||||
platform.installUpdate();
|
||||
|
||||
expect(mockElectron.send).toHaveBeenCalledWith('install_update');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import request from 'browser-request';
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
import { UpdateCheckStatus } from 'matrix-react-sdk/src/BasePlatform';
|
||||
import { MatrixClientPeg } from 'matrix-react-sdk/src/MatrixClientPeg';
|
||||
|
||||
import WebPlatform from '../../../../src/vector/platform/WebPlatform';
|
||||
|
||||
fetchMock.config.overwriteRoutes = true;
|
||||
|
||||
describe('WebPlatform', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
@@ -65,7 +67,7 @@ describe('WebPlatform', () => {
|
||||
it.each([[
|
||||
"https://develop.element.io/#/room/!foo:bar",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
|
||||
"develop.element.io (Chrome, macOS)",
|
||||
"develop.element.io: Chrome on macOS",
|
||||
]])("%s & %s = %s", (url, userAgent, result) => {
|
||||
delete window.navigator;
|
||||
window.navigator = { userAgent } as unknown as Navigator;
|
||||
@@ -120,9 +122,6 @@ describe('WebPlatform', () => {
|
||||
const envVersion = process.env.VERSION;
|
||||
const prodVersion = '1.10.13';
|
||||
|
||||
const setRequestMockImplementation = (err?: unknown, response?: { status: number }, body?: string) =>
|
||||
request.mockImplementation((_opts, callback) => callback(err, response, body));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(MatrixClientPeg, 'userRegisteredWithinLastHours').mockReturnValue(false);
|
||||
})
|
||||
@@ -157,7 +156,7 @@ describe('WebPlatform', () => {
|
||||
describe('pollForUpdate()', () => {
|
||||
it('should return not available and call showNoUpdate when current version matches most recent version', async () => {
|
||||
process.env.VERSION = prodVersion;
|
||||
setRequestMockImplementation(undefined, { status: 200}, prodVersion);
|
||||
fetchMock.getOnce("/version", prodVersion);
|
||||
const platform = new WebPlatform();
|
||||
|
||||
const showUpdate = jest.fn();
|
||||
@@ -171,7 +170,7 @@ describe('WebPlatform', () => {
|
||||
|
||||
it('should strip v prefix from versions before comparing', async () => {
|
||||
process.env.VERSION = prodVersion;
|
||||
setRequestMockImplementation(undefined, { status: 200}, `v${prodVersion}`);
|
||||
fetchMock.getOnce("/version", `v${prodVersion}`);
|
||||
const platform = new WebPlatform();
|
||||
|
||||
const showUpdate = jest.fn();
|
||||
@@ -186,7 +185,7 @@ describe('WebPlatform', () => {
|
||||
|
||||
it('should return ready and call showUpdate when current version differs from most recent version', async () => {
|
||||
process.env.VERSION = '0.0.0'; // old version
|
||||
setRequestMockImplementation(undefined, { status: 200}, prodVersion);
|
||||
fetchMock.getOnce("/version", prodVersion);
|
||||
const platform = new WebPlatform();
|
||||
|
||||
const showUpdate = jest.fn();
|
||||
@@ -201,7 +200,7 @@ describe('WebPlatform', () => {
|
||||
it('should return ready without showing update when user registered in last 24', async () => {
|
||||
process.env.VERSION = '0.0.0'; // old version
|
||||
jest.spyOn(MatrixClientPeg, 'userRegisteredWithinLastHours').mockReturnValue(true);
|
||||
setRequestMockImplementation(undefined, { status: 200}, prodVersion);
|
||||
fetchMock.getOnce("/version", prodVersion);
|
||||
const platform = new WebPlatform();
|
||||
|
||||
const showUpdate = jest.fn();
|
||||
@@ -214,7 +213,7 @@ describe('WebPlatform', () => {
|
||||
});
|
||||
|
||||
it('should return error when version check fails', async () => {
|
||||
setRequestMockImplementation('oups');
|
||||
fetchMock.getOnce("/version", { throws: "oups" });
|
||||
const platform = new WebPlatform();
|
||||
|
||||
const showUpdate = jest.fn();
|
||||
|
||||
Reference in New Issue
Block a user