mirror of
https://github.com/mattermost/mattermost.git
synced 2026-02-03 20:40:00 -05:00
MM-66972 Upgrade to node 24 and main dependencies with babel, webpack and jest (#34760)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* chore: upgrade to node 24 and dependencies mainly with babel, webpack and jest * fix components tests, make trial modal passed on all node 20-24 * fix cache for platform packages * updated test --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
92339d03ab
commit
dab04576a1
53 changed files with 5777 additions and 10651 deletions
3
.github/actions/webapp-setup/action.yml
vendored
3
.github/actions/webapp-setup/action.yml
vendored
|
|
@ -15,6 +15,9 @@ runs:
|
||||||
path: |
|
path: |
|
||||||
webapp/node_modules
|
webapp/node_modules
|
||||||
webapp/channels/node_modules
|
webapp/channels/node_modules
|
||||||
|
webapp/platform/client/node_modules
|
||||||
|
webapp/platform/components/node_modules
|
||||||
|
webapp/platform/types/node_modules
|
||||||
key: node-modules-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json') }}
|
key: node-modules-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json') }}
|
||||||
- name: ci/cache-platform-builds
|
- name: ci/cache-platform-builds
|
||||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||||
|
|
|
||||||
2
.github/workflows/api.yml
vendored
2
.github/workflows/api.yml
vendored
|
|
@ -20,7 +20,7 @@ jobs:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
|
|
|
||||||
10
.github/workflows/e2e-tests-ci-template.yml
vendored
10
.github/workflows/e2e-tests-ci-template.yml
vendored
|
|
@ -133,7 +133,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: ci/setup-node
|
- name: ci/setup-node
|
||||||
if: "${{ inputs.run_preflight_checks }}"
|
if: "${{ inputs.run_preflight_checks }}"
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
id: setup_node
|
id: setup_node
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
@ -164,7 +164,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: ci/setup-node
|
- name: ci/setup-node
|
||||||
if: "${{ inputs.run_preflight_checks }}"
|
if: "${{ inputs.run_preflight_checks }}"
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
id: setup_node
|
id: setup_node
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
@ -246,7 +246,7 @@ jobs:
|
||||||
ref: ${{ inputs.commit_sha }}
|
ref: ${{ inputs.commit_sha }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: ci/setup-node
|
- name: ci/setup-node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
id: setup_node
|
id: setup_node
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
@ -333,7 +333,7 @@ jobs:
|
||||||
ln -sfn /usr/local/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
|
ln -sfn /usr/local/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
|
||||||
sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
|
sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
|
||||||
- name: ci/setup-node
|
- name: ci/setup-node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
id: setup_node
|
id: setup_node
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
@ -412,7 +412,7 @@ jobs:
|
||||||
e2e-tests/${{ inputs.TEST }}/results/
|
e2e-tests/${{ inputs.TEST }}/results/
|
||||||
- name: ci/setup-node
|
- name: ci/setup-node
|
||||||
if: "${{ inputs.enable_reporting }}"
|
if: "${{ inputs.enable_reporting }}"
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
id: setup_node
|
id: setup_node
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
|
||||||
6
.github/workflows/server-ci.yml
vendored
6
.github/workflows/server-ci.yml
vendored
|
|
@ -282,6 +282,12 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout mattermost project
|
- name: Checkout mattermost project
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
- name: ci/setup-node
|
||||||
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
|
with:
|
||||||
|
node-version-file: ".nvmrc"
|
||||||
|
cache: "npm"
|
||||||
|
cache-dependency-path: "webapp/package-lock.json"
|
||||||
- name: Run setup-go-work
|
- name: Run setup-go-work
|
||||||
run: make setup-go-work
|
run: make setup-go-work
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|
|
||||||
2
.nvmrc
2
.nvmrc
|
|
@ -1 +1 @@
|
||||||
20.11
|
24.11
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,7 @@ $(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; t
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
echo '
|
echo '
|
||||||
webhook-interactions:
|
webhook-interactions:
|
||||||
image: mattermostdevelopment/mirrored-node:${NODE_VERSION_REQUIRED}
|
image: node:${NODE_VERSION_REQUIRED}
|
||||||
command: sh -c "npm install --global --legacy-peer-deps && exec node webhook_serve.js"
|
command: sh -c "npm install --global --legacy-peer-deps && exec node webhook_serve.js"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-s", "-o/dev/null", "127.0.0.1:3000"]
|
test: ["CMD", "curl", "-s", "-o/dev/null", "127.0.0.1:3000"]
|
||||||
|
|
@ -275,11 +275,21 @@ $(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; t
|
||||||
fi)
|
fi)
|
||||||
|
|
||||||
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
|
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
|
||||||
|
# shellcheck disable=SC2016
|
||||||
echo '
|
echo '
|
||||||
playwright:
|
playwright:
|
||||||
image: mcr.microsoft.com/playwright:v1.57.0-noble
|
image: mcr.microsoft.com/playwright:v1.57.0-noble
|
||||||
entrypoint: ["/bin/bash", "-c"]
|
entrypoint: ["/bin/bash", "-c"]
|
||||||
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
|
command:
|
||||||
|
- |
|
||||||
|
# Install Node.js based on .nvmrc
|
||||||
|
NODE_VERSION=$$(cat /mattermost/.nvmrc)
|
||||||
|
echo "Installing Node.js $${NODE_VERSION}..."
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_$${NODE_VERSION%%.*}.x | bash -
|
||||||
|
apt-get install -y nodejs
|
||||||
|
echo "Node.js version: $$(node --version)"
|
||||||
|
# Wait for termination signal
|
||||||
|
until [ -f /var/run/mm_terminate ]; do sleep 5; done
|
||||||
env_file:
|
env_file:
|
||||||
- "./.env.playwright"
|
- "./.env.playwright"
|
||||||
environment:
|
environment:
|
||||||
|
|
|
||||||
6
e2e-tests/playwright/package-lock.json
generated
6
e2e-tests/playwright/package-lock.json
generated
|
|
@ -5981,9 +5981,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/systeminformation": {
|
"node_modules/systeminformation": {
|
||||||
"version": "5.30.1",
|
"version": "5.30.2",
|
||||||
"resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.30.1.tgz",
|
"resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.30.2.tgz",
|
||||||
"integrity": "sha512-5zK8Sqqn71b0AoYKnj8nurrugOVogo4hBxAeQR9N0lbC5V+Fkw1hRBRWLaKxBmuvX8v4xH3cxifOJjlhQQW1lQ==",
|
"integrity": "sha512-Rrt5oFTWluUVuPlbtn3o9ja+nvjdF3Um4DG0KxqfYvpzcx7Q9plZBTjJiJy9mAouua4+OI7IUGBaG9Zyt9NgxA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"os": [
|
"os": [
|
||||||
"darwin",
|
"darwin",
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
save-exact=true
|
save-exact=true
|
||||||
engine-strict=true
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ jobs:
|
||||||
- name: Check out web app
|
- name: Check out web app
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
|
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version: 16.10.0
|
node-version-file: ".nvmrc"
|
||||||
|
|
||||||
- name: Download and install Cypress
|
- name: Download and install Cypress
|
||||||
uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
|
uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,8 @@
|
||||||
"imagemin-mozjpeg": "9.0.0",
|
"imagemin-mozjpeg": "9.0.0",
|
||||||
"jest": "30.1.3",
|
"jest": "30.1.3",
|
||||||
"jest-canvas-mock": "2.5.0",
|
"jest-canvas-mock": "2.5.0",
|
||||||
"jest-cli": "29.7.0",
|
"jest-cli": "30.1.3",
|
||||||
"jest-environment-jsdom": "29.7.0",
|
"jest-environment-jsdom": "30.1.0",
|
||||||
"jest-junit": "16.0.0",
|
"jest-junit": "16.0.0",
|
||||||
"jest-watch-typeahead": "3.0.1",
|
"jest-watch-typeahead": "3.0.1",
|
||||||
"nock": "13.2.8",
|
"nock": "13.2.8",
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,16 @@
|
||||||
|
|
||||||
import {jest} from '@jest/globals';
|
import {jest} from '@jest/globals';
|
||||||
|
|
||||||
const monacoMock = {
|
const monacoMock: {
|
||||||
|
editor: {
|
||||||
|
create: jest.Mock;
|
||||||
|
defineTheme: jest.Mock;
|
||||||
|
setTheme: jest.Mock;
|
||||||
|
};
|
||||||
|
languages: {
|
||||||
|
registerCompletionItemProvider: jest.Mock;
|
||||||
|
};
|
||||||
|
} = {
|
||||||
editor: {
|
editor: {
|
||||||
create: jest.fn(),
|
create: jest.fn(),
|
||||||
defineTheme: jest.fn(),
|
defineTheme: jest.fn(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import type {ReactNode} from 'react';
|
|
||||||
import {FormattedMessage, useIntl} from 'react-intl';
|
import {FormattedMessage, useIntl} from 'react-intl';
|
||||||
import {useDispatch, useSelector} from 'react-redux';
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
|
|
||||||
|
|
@ -108,7 +107,7 @@ const TrialBanner = ({
|
||||||
case TrialLoadStatus.Failed:
|
case TrialLoadStatus.Failed:
|
||||||
return formatMessage({id: 'start_trial.modal.failed', defaultMessage: 'Failed'});
|
return formatMessage({id: 'start_trial.modal.failed', defaultMessage: 'Failed'});
|
||||||
case TrialLoadStatus.Embargoed:
|
case TrialLoadStatus.Embargoed:
|
||||||
return formatMessage<ReactNode>(
|
return formatMessage(
|
||||||
{
|
{
|
||||||
id: 'admin.license.trial-request.embargoed',
|
id: 'admin.license.trial-request.embargoed',
|
||||||
defaultMessage: 'We were unable to process the request due to limitations for embargoed countries. <link>Learn more in our documentation</link>, or reach out to legal@mattermost.com for questions around export limitations.',
|
defaultMessage: 'We were unable to process the request due to limitations for embargoed countries. <link>Learn more in our documentation</link>, or reach out to legal@mattermost.com for questions around export limitations.',
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ exports[`components/admin_console/permission_schemes_settings/permission_descrip
|
||||||
<span>
|
<span>
|
||||||
Inherited from
|
Inherited from
|
||||||
<a
|
<a
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
>
|
>
|
||||||
All Members
|
All Members
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@import 'utils/mixins';
|
@use 'utils/mixins';
|
||||||
|
|
||||||
.channel-invite {
|
.channel-invite {
|
||||||
&__wrapper {
|
&__wrapper {
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
className="AlertBanner__footerMessage"
|
className="AlertBanner__footerMessage"
|
||||||
>
|
>
|
||||||
<FormattedList
|
<FormattedList
|
||||||
key=".0"
|
key="0/.0"
|
||||||
value={
|
value={
|
||||||
Array [
|
Array [
|
||||||
<Memo(Connect(Component))
|
<Memo(Connect(Component))
|
||||||
|
|
@ -299,7 +299,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
>
|
>
|
||||||
You can add
|
You can add
|
||||||
<FormattedList
|
<FormattedList
|
||||||
key=".1"
|
key="1/.1"
|
||||||
value={
|
value={
|
||||||
Array [
|
Array [
|
||||||
<Memo(Connect(Component))
|
<Memo(Connect(Component))
|
||||||
|
|
@ -343,7 +343,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
</FormattedList>
|
</FormattedList>
|
||||||
to this channel once they are members of the
|
to this channel once they are members of the
|
||||||
<strong
|
<strong
|
||||||
key=".3"
|
key="3/.3"
|
||||||
>
|
>
|
||||||
Team Name Display
|
Team Name Display
|
||||||
</strong>
|
</strong>
|
||||||
|
|
@ -549,7 +549,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
className="AlertBanner__footerMessage"
|
className="AlertBanner__footerMessage"
|
||||||
>
|
>
|
||||||
<Connect(Component)
|
<Connect(Component)
|
||||||
key=".$user-0"
|
key="0/.$user-0"
|
||||||
mentionName="user-0"
|
mentionName="user-0"
|
||||||
>
|
>
|
||||||
<Memo(AtMention)
|
<Memo(AtMention)
|
||||||
|
|
@ -563,7 +563,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
</Connect(Component)>
|
</Connect(Component)>
|
||||||
and
|
and
|
||||||
<WithTooltip
|
<WithTooltip
|
||||||
key=".2"
|
key="2/.2"
|
||||||
title="@user-1, @user-2, @user-3, @user-4, @user-5, @user-6, @user-7, @user-8, @user-9, @user-10"
|
title="@user-1, @user-2, @user-3, @user-4, @user-5, @user-6, @user-7, @user-8, @user-9, @user-10"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
|
|
@ -799,7 +799,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
>
|
>
|
||||||
You can add
|
You can add
|
||||||
<Connect(Component)
|
<Connect(Component)
|
||||||
key=".$user-0"
|
key="1/.$user-0"
|
||||||
mentionName="user-0"
|
mentionName="user-0"
|
||||||
>
|
>
|
||||||
<Memo(AtMention)
|
<Memo(AtMention)
|
||||||
|
|
@ -813,7 +813,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
</Connect(Component)>
|
</Connect(Component)>
|
||||||
and
|
and
|
||||||
<WithTooltip
|
<WithTooltip
|
||||||
key=".3"
|
key="3/.3"
|
||||||
title="@user-1, @user-2, @user-3, @user-4, @user-5, @user-6, @user-7, @user-8, @user-9, @user-10"
|
title="@user-1, @user-2, @user-3, @user-4, @user-5, @user-6, @user-7, @user-8, @user-9, @user-10"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
|
|
@ -843,7 +843,7 @@ exports[`components/channel_invite_modal/team_warning_banner should match snapsh
|
||||||
</WithTooltip>
|
</WithTooltip>
|
||||||
to this channel once they are members of the
|
to this channel once they are members of the
|
||||||
<strong
|
<strong
|
||||||
key=".5"
|
key="5/.5"
|
||||||
>
|
>
|
||||||
Team Name Display
|
Team Name Display
|
||||||
</strong>
|
</strong>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
@import "utils/_animations";
|
@use "utils/animations";
|
||||||
|
|
||||||
.ChannelSettingsModal__configurationTab {
|
.ChannelSettingsModal__configurationTab {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel_banner_section_body {
|
.channel_banner_section_body {
|
||||||
@include fade-in;
|
@include animations.fade-in;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,21 @@ import {fireEvent, render} from 'tests/react_testing_utils';
|
||||||
|
|
||||||
import Scrollbars from './scrollbars';
|
import Scrollbars from './scrollbars';
|
||||||
|
|
||||||
|
const originalGetComputedStyle = window.getComputedStyle;
|
||||||
|
beforeAll(() => {
|
||||||
|
window.getComputedStyle = (elt: Element, pseudoElt?: string | null) => {
|
||||||
|
if (pseudoElt) {
|
||||||
|
// Return an empty CSSStyleDeclaration-like object for pseudo elements
|
||||||
|
return {} as CSSStyleDeclaration;
|
||||||
|
}
|
||||||
|
return originalGetComputedStyle(elt);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
window.getComputedStyle = originalGetComputedStyle;
|
||||||
|
});
|
||||||
|
|
||||||
describe('Scrollbars', () => {
|
describe('Scrollbars', () => {
|
||||||
test('should attach scroll handler to the correct element', () => {
|
test('should attach scroll handler to the correct element', () => {
|
||||||
const onScroll = jest.fn();
|
const onScroll = jest.fn();
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ exports[`components/emoji_picker/EmojiPicker should match snapshot 1`] = `
|
||||||
role="grid"
|
role="grid"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style="position: relative; height: 100px; width: 100px; overflow: auto; will-change: transform; direction: ltr;"
|
style="position: relative; height: 100px; width: 100px; overflow: auto; -webkit-overflow-scrolling: touch; will-change: transform; direction: ltr;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style="height: 7740px; width: 100%;"
|
style="height: 7740px; width: 100%;"
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ exports[`FileAttachment should match snapshot, after change from file to image 1
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="post-image normal"
|
class="post-image normal"
|
||||||
style="background-image: url(thumbnail_id); background-size: cover;"
|
style="background-image: url(\\"thumbnail_id\\"); background-size: cover;"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ exports[`components/integrations/AbstractOutgoingOAuthConnection should match sn
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -478,7 +478,7 @@ exports[`components/integrations/AbstractOutgoingOAuthConnection should match sn
|
||||||
Get help with
|
Get help with
|
||||||
<a
|
<a
|
||||||
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
>
|
>
|
||||||
configuring outgoing OAuth connections
|
configuring outgoing OAuth connections
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -590,7 +590,7 @@ exports[`components/integrations/AbstractOutgoingOAuthConnection should match sn
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -1073,7 +1073,7 @@ exports[`components/integrations/AbstractOutgoingOAuthConnection should match sn
|
||||||
Get help with
|
Get help with
|
||||||
<a
|
<a
|
||||||
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
>
|
>
|
||||||
configuring outgoing OAuth connections
|
configuring outgoing OAuth connections
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ exports[`components/integrations/AddOutgoingOAuthConnection should match snapsho
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -467,7 +467,7 @@ exports[`components/integrations/AddOutgoingOAuthConnection should match snapsho
|
||||||
Get help with
|
Get help with
|
||||||
<a
|
<a
|
||||||
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
>
|
>
|
||||||
configuring outgoing OAuth connections
|
configuring outgoing OAuth connections
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ exports[`components/integrations/EditOutgoingOAuthConnection should match snapsh
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -643,7 +643,7 @@ https://myothersite.com/api/v2"
|
||||||
Get help with
|
Get help with
|
||||||
<a
|
<a
|
||||||
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
>
|
>
|
||||||
configuring outgoing OAuth connections
|
configuring outgoing OAuth connections
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -756,7 +756,7 @@ exports[`components/integrations/EditOutgoingOAuthConnection should match snapsh
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -1385,7 +1385,7 @@ https://myothersite.com/api/v2"
|
||||||
Get help with
|
Get help with
|
||||||
<a
|
<a
|
||||||
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
>
|
>
|
||||||
configuring outgoing OAuth connections
|
configuring outgoing OAuth connections
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -1498,7 +1498,7 @@ exports[`components/integrations/EditOutgoingOAuthConnection should match snapsh
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -2126,7 +2126,7 @@ https://myothersite.com/api/v2"
|
||||||
Get help with
|
Get help with
|
||||||
<a
|
<a
|
||||||
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
href="https://mattermost.com/pl/outgoing-oauth-connections"
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
>
|
>
|
||||||
configuring outgoing OAuth connections
|
configuring outgoing OAuth connections
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ exports[`components/integrations/InstalledOutgoingOAuthConnections should match
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -190,7 +190,7 @@ exports[`components/integrations/InstalledOutgoingOAuthConnections should match
|
||||||
Create
|
Create
|
||||||
<ForwardRef
|
<ForwardRef
|
||||||
href="https://mattermost.com/pl/setup-oauth-2.0"
|
href="https://mattermost.com/pl/setup-oauth-2.0"
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
location="installed_outgoing_oauth_connections"
|
location="installed_outgoing_oauth_connections"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ exports[`components/integrations/outgoing_oauth_connections/OAuthConnectionAudie
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -109,7 +109,7 @@ exports[`components/integrations/outgoing_oauth_connections/OAuthConnectionAudie
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -203,7 +203,7 @@ exports[`components/integrations/outgoing_oauth_connections/OAuthConnectionAudie
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -297,7 +297,7 @@ exports[`components/integrations/outgoing_oauth_connections/OAuthConnectionAudie
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -407,7 +407,7 @@ exports[`components/integrations/outgoing_oauth_connections/OAuthConnectionAudie
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -318,10 +318,8 @@ describe('components/login/Login', () => {
|
||||||
|
|
||||||
const button = screen.getByRole('link', {name: 'Gitlab Icon GitLab 2'});
|
const button = screen.getByRole('link', {name: 'Gitlab Icon GitLab 2'});
|
||||||
|
|
||||||
expect(button.style).toMatchObject({
|
expect(button.style.color).toBe('rgb(0, 255, 0)');
|
||||||
color: 'rgb(0, 255, 0)',
|
expect(button.style.borderColor).toBe('rgb(0, 255, 0)');
|
||||||
borderColor: '#00ff00',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should focus username field when there is an error', async () => {
|
it('should focus username field when there is an error', async () => {
|
||||||
|
|
@ -374,10 +372,8 @@ describe('components/login/Login', () => {
|
||||||
|
|
||||||
const button = screen.getByRole('link', {name: 'OpenID Icon OpenID 2'});
|
const button = screen.getByRole('link', {name: 'OpenID Icon OpenID 2'});
|
||||||
|
|
||||||
expect(button.style).toMatchObject({
|
expect(button.style.color).toBe('rgb(0, 255, 0)');
|
||||||
color: 'rgb(0, 255, 0)',
|
expect(button.style.borderColor).toBe('rgb(0, 255, 0)');
|
||||||
borderColor: '#00ff00',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should redirect on login', async () => {
|
it('should redirect on login', async () => {
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ exports[`components/marketplace/ doesn't show web marketplace banner in FeatureF
|
||||||
<span>
|
<span>
|
||||||
Error connecting to the marketplace server. Please check your settings in the
|
Error connecting to the marketplace server. Please check your settings in the
|
||||||
<Link
|
<Link
|
||||||
key=".1"
|
key="1/.1"
|
||||||
to="/admin_console/plugins/plugin_management"
|
to="/admin_console/plugins/plugin_management"
|
||||||
>
|
>
|
||||||
System Console
|
System Console
|
||||||
|
|
@ -204,7 +204,7 @@ exports[`components/marketplace/ hides search, shows web marketplace banner in F
|
||||||
<span>
|
<span>
|
||||||
Error connecting to the marketplace server. Please check your settings in the
|
Error connecting to the marketplace server. Please check your settings in the
|
||||||
<Link
|
<Link
|
||||||
key=".1"
|
key="1/.1"
|
||||||
to="/admin_console/plugins/plugin_management"
|
to="/admin_console/plugins/plugin_management"
|
||||||
>
|
>
|
||||||
System Console
|
System Console
|
||||||
|
|
@ -501,7 +501,7 @@ exports[`components/marketplace/ should render with error banner 1`] = `
|
||||||
<span>
|
<span>
|
||||||
Error connecting to the marketplace server. Please check your settings in the
|
Error connecting to the marketplace server. Please check your settings in the
|
||||||
<Link
|
<Link
|
||||||
key=".1"
|
key="1/.1"
|
||||||
to="/admin_console/plugins/plugin_management"
|
to="/admin_console/plugins/plugin_management"
|
||||||
>
|
>
|
||||||
System Console
|
System Console
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ exports[`InviteMembers component should match snapshot when it is cloud 1`] = `
|
||||||
id="react-select-2-input"
|
id="react-select-2-input"
|
||||||
role="combobox"
|
role="combobox"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,10 @@ describe('SelectPropertyRenderer', () => {
|
||||||
const element = screen.getByTestId('select-property');
|
const element = screen.getByTestId('select-property');
|
||||||
expect(element).toBeInTheDocument();
|
expect(element).toBeInTheDocument();
|
||||||
expect(element).toHaveTextContent('option1');
|
expect(element).toHaveTextContent('option1');
|
||||||
|
|
||||||
|
// Component applies inline styles via style prop
|
||||||
expect(element).toHaveStyle({
|
expect(element).toHaveStyle({
|
||||||
backgroundColor: 'rgba(var(--button-bg-rgb), 0.08)',
|
backgroundColor: 'var(--sidebar-text-active-border)',
|
||||||
color: '#FFF',
|
color: '#FFF',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import {checkIsFirstAdmin, getCurrentUser, isCurrentUserSystemAdmin} from 'matte
|
||||||
|
|
||||||
import {redirectUserToDefaultTeam, emitUserLoggedOutEvent} from 'actions/global_actions';
|
import {redirectUserToDefaultTeam, emitUserLoggedOutEvent} from 'actions/global_actions';
|
||||||
|
|
||||||
|
import {reloadPage} from 'utils/browser_utils';
|
||||||
import {ActionTypes, StoragePrefixes} from 'utils/constants';
|
import {ActionTypes, StoragePrefixes} from 'utils/constants';
|
||||||
import {doesCookieContainsMMUserId} from 'utils/utils';
|
import {doesCookieContainsMMUserId} from 'utils/utils';
|
||||||
|
|
||||||
|
|
@ -165,7 +166,7 @@ export function handleLoginLogoutSignal(e: StorageEvent): ThunkActionFunc<void>
|
||||||
|
|
||||||
// detected login from a different tab
|
// detected login from a different tab
|
||||||
function reloadOnFocus() {
|
function reloadOnFocus() {
|
||||||
location.reload();
|
reloadPage();
|
||||||
}
|
}
|
||||||
window.addEventListener('focus', reloadOnFocus);
|
window.addEventListener('focus', reloadOnFocus);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import * as GlobalActions from 'actions/global_actions';
|
||||||
|
|
||||||
import testConfigureStore from 'packages/mattermost-redux/test/test_store';
|
import testConfigureStore from 'packages/mattermost-redux/test/test_store';
|
||||||
import {renderWithContext, waitFor} from 'tests/react_testing_utils';
|
import {renderWithContext, waitFor} from 'tests/react_testing_utils';
|
||||||
|
import * as BrowserUtils from 'utils/browser_utils';
|
||||||
import {StoragePrefixes} from 'utils/constants';
|
import {StoragePrefixes} from 'utils/constants';
|
||||||
|
|
||||||
import {handleLoginLogoutSignal, redirectToOnboardingOrDefaultTeam} from './actions';
|
import {handleLoginLogoutSignal, redirectToOnboardingOrDefaultTeam} from './actions';
|
||||||
|
|
@ -26,6 +27,10 @@ jest.mock('utils/utils', () => ({
|
||||||
applyTheme: jest.fn(),
|
applyTheme: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('utils/browser_utils', () => ({
|
||||||
|
reloadPage: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock('actions/global_actions', () => ({
|
jest.mock('actions/global_actions', () => ({
|
||||||
redirectUserToDefaultTeam: jest.fn(),
|
redirectUserToDefaultTeam: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
@ -93,11 +98,9 @@ describe('components/Root', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
let originalMatchMedia: (query: string) => MediaQueryList;
|
let originalMatchMedia: (query: string) => MediaQueryList;
|
||||||
let originalReload: () => void;
|
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
originalMatchMedia = window.matchMedia;
|
originalMatchMedia = window.matchMedia;
|
||||||
originalReload = window.location.reload;
|
|
||||||
|
|
||||||
Object.defineProperty(window, 'matchMedia', {
|
Object.defineProperty(window, 'matchMedia', {
|
||||||
writable: true,
|
writable: true,
|
||||||
|
|
@ -106,22 +109,17 @@ describe('components/Root', () => {
|
||||||
media: query,
|
media: query,
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.defineProperty(window.location, 'reload', {
|
|
||||||
configurable: true,
|
|
||||||
writable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
window.location.reload = jest.fn();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
|
|
||||||
|
// Reset the reloadPage mock after each test
|
||||||
|
(BrowserUtils.reloadPage as jest.Mock).mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
window.matchMedia = originalMatchMedia;
|
window.matchMedia = originalMatchMedia;
|
||||||
window.location.reload = originalReload;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should load config and license on mount and redirect to sign-up page', async () => {
|
test('should load config and license on mount and redirect to sign-up page', async () => {
|
||||||
|
|
@ -228,7 +226,7 @@ describe('components/Root', () => {
|
||||||
window.dispatchEvent(new Event('focus'));
|
window.dispatchEvent(new Event('focus'));
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(window.location.reload).toHaveBeenCalledTimes(1);
|
expect(BrowserUtils.reloadPage).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e
|
||||||
Sign up at
|
Sign up at
|
||||||
<ForwardRef
|
<ForwardRef
|
||||||
href="https://mattermost.com/security-updates/"
|
href="https://mattermost.com/security-updates/"
|
||||||
key=".1"
|
key="1/.1"
|
||||||
location="signup"
|
location="signup"
|
||||||
>
|
>
|
||||||
https://mattermost.com/security-updates/
|
https://mattermost.com/security-updates/
|
||||||
|
|
@ -336,7 +336,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e
|
||||||
Sign up at
|
Sign up at
|
||||||
<ForwardRef
|
<ForwardRef
|
||||||
href="https://mattermost.com/security-updates/"
|
href="https://mattermost.com/security-updates/"
|
||||||
key=".1"
|
key="1/.1"
|
||||||
location="signup"
|
location="signup"
|
||||||
>
|
>
|
||||||
https://mattermost.com/security-updates/
|
https://mattermost.com/security-updates/
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ Object {
|
||||||
id="react-select-2-input"
|
id="react-select-2-input"
|
||||||
role="combobox"
|
role="combobox"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
|
|
@ -312,7 +312,7 @@ Object {
|
||||||
id="react-select-3-input"
|
id="react-select-3-input"
|
||||||
role="combobox"
|
role="combobox"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
|
|
|
||||||
|
|
@ -507,7 +507,7 @@ exports[`components/threading/channel_threads/thread_footer should report total
|
||||||
<span>
|
<span>
|
||||||
Last reply
|
Last reply
|
||||||
<Memo(SemanticTime)
|
<Memo(SemanticTime)
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
value={2019-04-01T23:31:44.000Z}
|
value={2019-04-01T23:31:44.000Z}
|
||||||
>
|
>
|
||||||
<time
|
<time
|
||||||
|
|
@ -1021,7 +1021,7 @@ exports[`components/threading/channel_threads/thread_footer should show unread i
|
||||||
<span>
|
<span>
|
||||||
Last reply
|
Last reply
|
||||||
<Memo(SemanticTime)
|
<Memo(SemanticTime)
|
||||||
key=".$.1"
|
key="1/.1"
|
||||||
value={2019-04-01T23:31:44.000Z}
|
value={2019-04-01T23:31:44.000Z}
|
||||||
>
|
>
|
||||||
<time
|
<time
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import isEmpty from 'lodash/isEmpty';
|
import isEmpty from 'lodash/isEmpty';
|
||||||
import React, {memo, useCallback, useEffect, useState} from 'react';
|
import React, {memo, useCallback, useEffect, useState} from 'react';
|
||||||
import type {ReactNode} from 'react';
|
|
||||||
import {useIntl} from 'react-intl';
|
import {useIntl} from 'react-intl';
|
||||||
import {useSelector, useDispatch, shallowEqual} from 'react-redux';
|
import {useSelector, useDispatch, shallowEqual} from 'react-redux';
|
||||||
import {Link, useRouteMatch} from 'react-router-dom';
|
import {Link, useRouteMatch} from 'react-router-dom';
|
||||||
|
|
@ -204,7 +203,7 @@ const GlobalThreads = () => {
|
||||||
id: 'globalThreads.threadPane.unselectedTitle',
|
id: 'globalThreads.threadPane.unselectedTitle',
|
||||||
defaultMessage: '{numUnread, plural, =0 {Looks like you’re all caught up} other {Catch up on your threads}}',
|
defaultMessage: '{numUnread, plural, =0 {Looks like you’re all caught up} other {Catch up on your threads}}',
|
||||||
}, {numUnread})}
|
}, {numUnread})}
|
||||||
subtitle={formatMessage<ReactNode>({
|
subtitle={formatMessage({
|
||||||
id: 'globalThreads.threadPane.unreadMessageLink',
|
id: 'globalThreads.threadPane.unreadMessageLink',
|
||||||
defaultMessage: 'You have {numUnread, plural, =0 {no unread threads} =1 {<link>{numUnread} thread</link>} other {<link>{numUnread} threads</link>}} {numUnread, plural, =0 {} other {with unread messages}}',
|
defaultMessage: 'You have {numUnread, plural, =0 {no unread threads} =1 {<link>{numUnread} thread</link>} other {<link>{numUnread} threads</link>}} {numUnread, plural, =0 {} other {with unread messages}}',
|
||||||
}, {
|
}, {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
|
||||||
|
|
||||||
exports[`components/three_days_left_trial_modal/three_days_left_trial_modal should match snapshot 1`] = `
|
|
||||||
"<ContextProvider value={{...}}>
|
|
||||||
<ThreeDaysLeftTrialModal onExited={[Function: mockConstructor] { _isMockFunction: true, getMockImplementation: [Function (anonymous)], mock: Object [Object: null prototype] { calls: [], contexts: [], instances: [], invocationCallOrder: [], results: [] }, mockClear: [Function (anonymous)], mockReset: [Function (anonymous)], mockRestore: [Function (anonymous)], mockReturnValueOnce: [Function (anonymous)], mockResolvedValueOnce: [Function (anonymous)], mockRejectedValueOnce: [Function (anonymous)], mockReturnValue: [Function (anonymous)], mockResolvedValue: [Function (anonymous)], mockRejectedValue: [Function (anonymous)], mockImplementationOnce: [Function (anonymous)], withImplementation: [Function: bound withImplementation], mockImplementation: [Function (anonymous)], mockReturnThis: [Function (anonymous)], mockName: [Function (anonymous)], getMockName: [Function (anonymous)] }} limitsOverpassed={false} />
|
|
||||||
</ContextProvider>"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`components/three_days_left_trial_modal/three_days_left_trial_modal should match snapshot when limits are overpassed and show the limits panel 1`] = `
|
|
||||||
"<ContextProvider value={{...}}>
|
|
||||||
<ThreeDaysLeftTrialModal onExited={[Function: mockConstructor] { _isMockFunction: true, getMockImplementation: [Function (anonymous)], mock: Object [Object: null prototype] { calls: [], contexts: [], instances: [], invocationCallOrder: [], results: [] }, mockClear: [Function (anonymous)], mockReset: [Function (anonymous)], mockRestore: [Function (anonymous)], mockReturnValueOnce: [Function (anonymous)], mockResolvedValueOnce: [Function (anonymous)], mockRejectedValueOnce: [Function (anonymous)], mockReturnValue: [Function (anonymous)], mockResolvedValue: [Function (anonymous)], mockRejectedValue: [Function (anonymous)], mockImplementationOnce: [Function (anonymous)], withImplementation: [Function: bound withImplementation], mockImplementation: [Function (anonymous)], mockReturnThis: [Function (anonymous)], mockName: [Function (anonymous)], getMockName: [Function (anonymous)] }} limitsOverpassed={true} />
|
|
||||||
</ContextProvider>"
|
|
||||||
`;
|
|
||||||
|
|
@ -1,20 +1,14 @@
|
||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {shallow} from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Provider} from 'react-redux';
|
|
||||||
|
|
||||||
import {GenericModal} from '@mattermost/components';
|
|
||||||
|
|
||||||
import ThreeDaysLeftTrialModal from 'components/three_days_left_trial_modal/three_days_left_trial_modal';
|
import ThreeDaysLeftTrialModal from 'components/three_days_left_trial_modal/three_days_left_trial_modal';
|
||||||
|
|
||||||
import TestHelper from 'packages/mattermost-redux/test/test_helper';
|
import TestHelper from 'packages/mattermost-redux/test/test_helper';
|
||||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
import {renderWithContext, screen, userEvent, waitFor} from 'tests/react_testing_utils';
|
||||||
import mockStore from 'tests/test_store';
|
|
||||||
|
|
||||||
describe('components/three_days_left_trial_modal/three_days_left_trial_modal', () => {
|
describe('components/three_days_left_trial_modal/three_days_left_trial_modal', () => {
|
||||||
// required state to mount using the provider
|
|
||||||
const user = TestHelper.fakeUserWithId();
|
const user = TestHelper.fakeUserWithId();
|
||||||
|
|
||||||
const profiles = {
|
const profiles = {
|
||||||
|
|
@ -73,70 +67,90 @@ describe('components/three_days_left_trial_modal/three_days_left_trial_modal', (
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const props = {
|
const defaultProps = {
|
||||||
onExited: jest.fn(),
|
onExited: jest.fn(),
|
||||||
limitsOverpassed: false,
|
limitsOverpassed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const store = mockStore(state);
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
test('should match snapshot', () => {
|
|
||||||
const wrapper = shallow(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ThreeDaysLeftTrialModal {...props}/>
|
|
||||||
</Provider>,
|
|
||||||
);
|
|
||||||
expect(wrapper.debug()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should match snapshot when limits are overpassed and show the limits panel', () => {
|
test('should render the modal with header, subtitle, feature cards, and view plans button', () => {
|
||||||
const wrapper = shallow(
|
renderWithContext(
|
||||||
<Provider store={store}>
|
<ThreeDaysLeftTrialModal {...defaultProps}/>,
|
||||||
<ThreeDaysLeftTrialModal
|
state,
|
||||||
{...props}
|
|
||||||
limitsOverpassed={true}
|
|
||||||
/>
|
|
||||||
</Provider>,
|
|
||||||
);
|
|
||||||
expect(wrapper.debug()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should show the three days left modal with the three cards', () => {
|
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ThreeDaysLeftTrialModal {...props}/>
|
|
||||||
</Provider>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper.find('ThreeDaysLeftTrialModal ThreeDaysLeftTrialCard')).toHaveLength(3);
|
// Header and subtitle
|
||||||
|
expect(screen.getByText('Your trial ends soon')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('There is still time to explore what our paid plans can help you accomplish.')).toBeInTheDocument();
|
||||||
|
|
||||||
|
// Three feature cards
|
||||||
|
expect(screen.getByText('Use SSO (with OpenID, SAML, Google, O365)')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Synchronize your Active Directory/LDAP groups')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Provide controlled access to the System Console')).toBeInTheDocument();
|
||||||
|
|
||||||
|
// View plans button
|
||||||
|
expect(screen.getByRole('button', {name: 'View plan options'})).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should show the workspace limits panel when limits are overpassed', () => {
|
test('should show limits overpassed content when limitsOverpassed is true', () => {
|
||||||
const wrapper = mountWithIntl(
|
renderWithContext(
|
||||||
<Provider store={store}>
|
<ThreeDaysLeftTrialModal
|
||||||
<ThreeDaysLeftTrialModal
|
{...defaultProps}
|
||||||
{...props}
|
limitsOverpassed={true}
|
||||||
limitsOverpassed={true}
|
/>,
|
||||||
/>
|
state,
|
||||||
</Provider>,
|
|
||||||
);
|
);
|
||||||
expect(wrapper.find('ThreeDaysLeftTrialModal WorkspaceLimitsPanel')).toHaveLength(1);
|
|
||||||
|
// Different header and subtitle
|
||||||
|
expect(screen.getByText('Upgrade before the trial ends')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('There are 3 days left on your trial. Upgrade to our Professional or Enterprise plan to avoid exceeding your data limits on the Free plan.')).toBeInTheDocument();
|
||||||
|
|
||||||
|
// Shows limits panel instead of feature cards
|
||||||
|
expect(screen.getByText('Limits')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Use SSO (with OpenID, SAML, Google, O365)')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should call on exited', () => {
|
test('should call onExited when modal is closed', async () => {
|
||||||
const mockOnExited = jest.fn();
|
const mockOnExited = jest.fn();
|
||||||
|
|
||||||
const wrapper = mountWithIntl(
|
renderWithContext(
|
||||||
<Provider store={store}>
|
<ThreeDaysLeftTrialModal
|
||||||
<ThreeDaysLeftTrialModal
|
{...defaultProps}
|
||||||
{...props}
|
onExited={mockOnExited}
|
||||||
onExited={mockOnExited}
|
/>,
|
||||||
/>
|
state,
|
||||||
</Provider>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find(GenericModal).props().onExited?.();
|
const closeButton = screen.getByLabelText('Close');
|
||||||
|
await userEvent.click(closeButton);
|
||||||
|
|
||||||
expect(mockOnExited).toHaveBeenCalled();
|
await waitFor(() => {
|
||||||
|
expect(mockOnExited).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not render when modal is not open', () => {
|
||||||
|
const closedState = {
|
||||||
|
...state,
|
||||||
|
views: {
|
||||||
|
modals: {
|
||||||
|
modalState: {
|
||||||
|
three_days_left_trial_modal: {
|
||||||
|
open: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
renderWithContext(
|
||||||
|
<ThreeDaysLeftTrialModal {...defaultProps}/>,
|
||||||
|
closedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.queryByText('Your trial ends soon')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ exports[`UserAccountNameMenuItem should not break if no props are passed 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<li
|
<li
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="MuiButtonBase-root-JvZdr dKFJFs MuiButtonBase-root MuiMenuItem-root MuiMenuItem-gutters MuiMenuItem-root-dXqYNm kIRdVO MuiMenuItem-root MuiMenuItem-gutters sc-gswNZR koIPww userAccountMenu_nameMenuItem"
|
class="MuiButtonBase-root-JDVeC cxEgXn MuiButtonBase-root MuiMenuItem-root MuiMenuItem-gutters MuiMenuItem-root-dXjcMb iLWjgG MuiMenuItem-root MuiMenuItem-gutters sc-grYavY jmUrfe userAccountMenu_nameMenuItem"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@import "utils/_mixins";
|
@use "utils/mixins";
|
||||||
|
|
||||||
#userAccountMenu {
|
#userAccountMenu {
|
||||||
.userAccountMenu_nameMenuItem {
|
.userAccountMenu_nameMenuItem {
|
||||||
|
|
@ -21,14 +21,14 @@
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
@include textEllipsis;
|
@include mixins.textEllipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.userAccountMenu_nameMenuItem_secondaryLabel {
|
span.userAccountMenu_nameMenuItem_secondaryLabel {
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
@include textEllipsis;
|
@include mixins.textEllipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
.label-elements {
|
.label-elements {
|
||||||
> span {
|
> span {
|
||||||
max-width: 196px;
|
max-width: 196px;
|
||||||
@include textEllipsis;
|
@include mixins.textEllipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||||
"listen": [Function],
|
"listen": [Function],
|
||||||
"location": Object {
|
"location": Object {
|
||||||
"hash": "",
|
"hash": "",
|
||||||
"pathname": "undefinedundefined",
|
"pathname": "/",
|
||||||
"search": "",
|
"search": "",
|
||||||
"state": undefined,
|
"state": undefined,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@import 'utils/mixins';
|
@use 'utils/mixins';
|
||||||
|
|
||||||
.AdvancedTextbox {
|
.AdvancedTextbox {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,9 @@ describe('components/Menu', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const menu = screen.getByRole('menu');
|
const menu = screen.getByRole('menu');
|
||||||
expect(menu).toHaveStyle({maxHeight: '200px', backgroundColor: 'red'});
|
|
||||||
|
expect(menu.style.maxHeight).toBe('200px');
|
||||||
|
expect(menu.style.backgroundColor).toBe('red');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should apply custom className to menu list', () => {
|
test('should apply custom className to menu list', () => {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type {ReactNode} from 'react';
|
|
||||||
import {defineMessage, useIntl} from 'react-intl';
|
import {defineMessage, useIntl} from 'react-intl';
|
||||||
|
|
||||||
import type {LimitSummary} from 'components/common/hooks/useGetHighestThresholdCloudLimit';
|
import type {LimitSummary} from 'components/common/hooks/useGetHighestThresholdCloudLimit';
|
||||||
|
|
@ -151,7 +150,7 @@ export default function useWords(highestLimit: LimitSummary | false, isAdminUser
|
||||||
id: 'workspace_limits.menu_limit.messages',
|
id: 'workspace_limits.menu_limit.messages',
|
||||||
defaultMessage: 'Total messages',
|
defaultMessage: 'Total messages',
|
||||||
}),
|
}),
|
||||||
description: intl.formatMessage<ReactNode>(
|
description: intl.formatMessage(
|
||||||
description,
|
description,
|
||||||
values,
|
values,
|
||||||
),
|
),
|
||||||
|
|
@ -196,7 +195,7 @@ export default function useWords(highestLimit: LimitSummary | false, isAdminUser
|
||||||
id: 'workspace_limits.menu_limit.file_storage',
|
id: 'workspace_limits.menu_limit.file_storage',
|
||||||
defaultMessage: 'File storage limit',
|
defaultMessage: 'File storage limit',
|
||||||
}),
|
}),
|
||||||
description: intl.formatMessage<ReactNode>(
|
description: intl.formatMessage(
|
||||||
description,
|
description,
|
||||||
values,
|
values,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ exports[`TooltipContent have correct structure with title and emoji 1`] = `
|
||||||
aria-label=":smile:"
|
aria-label=":smile:"
|
||||||
class="emoticon"
|
class="emoticon"
|
||||||
data-emoticon="smile"
|
data-emoticon="smile"
|
||||||
style="background-image: url(/static/emoji/1f604.png); background-size: contain; height: 16px; width: 16px; max-height: 16px; max-width: 16px; min-height: 16px; min-width: 16px; overflow: hidden;"
|
style="background-image: url(\\"/static/emoji/1f604.png\\"); background-size: contain; height: 16px; width: 16px; max-height: 16px; max-width: 16px; min-height: 16px; min-width: 16px; overflow: hidden;"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
|
@ -61,7 +61,7 @@ exports[`TooltipContent have correct structure with title and large emoji 1`] =
|
||||||
aria-label=":smile:"
|
aria-label=":smile:"
|
||||||
class="emoticon"
|
class="emoticon"
|
||||||
data-emoticon="smile"
|
data-emoticon="smile"
|
||||||
style="background-image: url(/static/emoji/1f604.png); background-size: contain; height: 48px; width: 48px; max-height: 48px; max-width: 48px; min-height: 48px; min-width: 48px; overflow: hidden;"
|
style="background-image: url(\\"/static/emoji/1f604.png\\"); background-size: contain; height: 48px; width: 48px; max-height: 48px; max-width: 48px; min-height: 48px; min-width: 48px; overflow: hidden;"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
|
@ -121,7 +121,7 @@ exports[`TooltipContent have correct structure with title, emoji and hint 1`] =
|
||||||
aria-label=":smile:"
|
aria-label=":smile:"
|
||||||
class="emoticon"
|
class="emoticon"
|
||||||
data-emoticon="smile"
|
data-emoticon="smile"
|
||||||
style="background-image: url(/static/emoji/1f604.png); background-size: contain; height: 16px; width: 16px; max-height: 16px; max-width: 16px; min-height: 16px; min-width: 16px; overflow: hidden;"
|
style="background-image: url(\\"/static/emoji/1f604.png\\"); background-size: contain; height: 16px; width: 16px; max-height: 16px; max-width: 16px; min-height: 16px; min-width: 16px; overflow: hidden;"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
|
|
||||||
|
|
@ -70,18 +70,15 @@ describe('selectors/i18n', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('locale from query parameter', () => {
|
describe('locale from query parameter', () => {
|
||||||
// Helper function to mock window.location.search with locale query parameter
|
|
||||||
const setWindowLocaleQueryParameter = (locale) => {
|
const setWindowLocaleQueryParameter = (locale) => {
|
||||||
window.location.search = `?locale=${locale}`;
|
const url = new URL(window.location.href);
|
||||||
};
|
url.searchParams.set('locale', locale);
|
||||||
|
window.history.replaceState({}, '', url.toString());
|
||||||
// Helper function to reset window.location.search
|
|
||||||
const resetWindowLocationSearch = () => {
|
|
||||||
window.location.search = '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
resetWindowLocationSearch();
|
// Reset the URL
|
||||||
|
window.history.replaceState({}, '', 'http://localhost:8065/');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns locale from query parameter if provided and not logged in', () => {
|
test('returns locale from query parameter if provided and not logged in', () => {
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,6 @@ module.exports = async () => {
|
||||||
configure({adapter: new Adapter()});
|
configure({adapter: new Adapter()});
|
||||||
|
|
||||||
global.window = Object.create(window);
|
global.window = Object.create(window);
|
||||||
Object.defineProperty(window, 'location', {
|
|
||||||
value: {
|
|
||||||
href: 'http://localhost:8065',
|
|
||||||
origin: 'http://localhost:8065',
|
|
||||||
port: '8065',
|
|
||||||
protocol: 'http:',
|
|
||||||
search: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// The current version of jsdom that's used by jest-environment-jsdom 29 doesn't support fetch, so we have to
|
// The current version of jsdom that's used by jest-environment-jsdom 29 doesn't support fetch, so we have to
|
||||||
// use node-fetch despite some mismatched parameters.
|
// use node-fetch despite some mismatched parameters.
|
||||||
|
|
@ -116,6 +107,12 @@ afterEach(() => {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jsdom doesn't implement navigation, but this is expected behavior in tests
|
||||||
|
const errorStr = call[0] instanceof Error ? call[0].message : String(call[0]);
|
||||||
|
if (errorStr.includes('Not implemented:')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
errors.push(call);
|
errors.push(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
9
webapp/channels/src/utils/browser_utils.ts
Normal file
9
webapp/channels/src/utils/browser_utils.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for window.location.reload to make it mockable in tests.
|
||||||
|
*/
|
||||||
|
export function reloadPage(): void {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
15991
webapp/package-lock.json
generated
15991
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -2,8 +2,8 @@
|
||||||
"name": "@mattermost/webapp",
|
"name": "@mattermost/webapp",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.10.0",
|
"node": "^20 || ^22 || ^24",
|
||||||
"npm": ">=9.0.0 <12.0.0"
|
"npm": "^10 || ^11"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "patch-package && npm run build --workspace=platform/types --workspace=platform/client --workspace=platform/components",
|
"postinstall": "patch-package && npm run build --workspace=platform/types --workspace=platform/client --workspace=platform/components",
|
||||||
|
|
@ -23,15 +23,16 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mattermost/compass-icons": "0.1.52",
|
"@mattermost/compass-icons": "0.1.52",
|
||||||
|
"react-intl": "7.1.14",
|
||||||
"typescript": "5.6.3"
|
"typescript": "5.6.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.22.0",
|
"@babel/core": "7.28.5",
|
||||||
"@babel/preset-env": "7.21.5",
|
"@babel/preset-env": "7.28.5",
|
||||||
"@babel/preset-react": "7.18.6",
|
"@babel/preset-react": "7.28.5",
|
||||||
"@babel/preset-typescript": "7.21.5",
|
"@babel/preset-typescript": "7.28.5",
|
||||||
"@formatjs/cli": "6.7.4",
|
"@formatjs/cli": "6.7.4",
|
||||||
"@types/node": "20.19.18",
|
"@types/node": "24.10.4",
|
||||||
"babel-loader": "9.1.2",
|
"babel-loader": "9.1.2",
|
||||||
"babel-plugin-formatjs": "10.5.1",
|
"babel-plugin-formatjs": "10.5.1",
|
||||||
"babel-plugin-typescript-to-proptypes": "2.1.0",
|
"babel-plugin-typescript-to-proptypes": "2.1.0",
|
||||||
|
|
@ -52,9 +53,9 @@
|
||||||
"strip-ansi": "7.1.0",
|
"strip-ansi": "7.1.0",
|
||||||
"style-loader": "4.0.0",
|
"style-loader": "4.0.0",
|
||||||
"typescript-eslint-language-service": "5.0.5",
|
"typescript-eslint-language-service": "5.0.5",
|
||||||
"webpack": "5.95.0",
|
"webpack": "5.103.0",
|
||||||
"webpack-cli": "5.1.4",
|
"webpack-cli": "6.0.1",
|
||||||
"webpack-dev-server": "5.1.0"
|
"webpack-dev-server": "5.2.2"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@deanwhillier/jest-matchmedia-mock": {
|
"@deanwhillier/jest-matchmedia-mock": {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
"target": "es2022",
|
"target": "es2022",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
"target": "es2022",
|
"target": "es2022",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-transform-runtime": "^7.17.0",
|
"@babel/plugin-transform-runtime": "^7.17.0",
|
||||||
|
"jest-environment-jsdom": "30.1.0",
|
||||||
"@rollup/plugin-babel": "^5.3.1",
|
"@rollup/plugin-babel": "^5.3.1",
|
||||||
"@rollup/plugin-commonjs": "^21.0.2",
|
"@rollup/plugin-commonjs": "^21.0.2",
|
||||||
"@rollup/plugin-node-resolve": "^13.1.3",
|
"@rollup/plugin-node-resolve": "^13.1.3",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue