Merge branch 'master' into fix-boards-webapp-unit-tests

Этот коммит содержится в:
Caleb Roseland
2023-03-29 09:37:24 -05:00
родитель 4331ad24d3 c78d6d47ac
Коммит 6da94c769c
1364 изменённых файлов: 4408 добавлений и 4279 удалений

Просмотреть файл

@@ -46,7 +46,6 @@
"glob-parent": "6.0.2",
"lodash": "^4.17.21",
"marked": "4.0.17",
"mattermost-redux": "5.33.1",
"mini-create-react-context": "^0.4.1",
"moment": "^2.29.1",
"nanoevents": "^5.1.13",

Просмотреть файл

@@ -96,3 +96,9 @@ exports[`components/boardsUnfurl/BoardsUnfurl renders when limited 1`] = `
</a>
</div>
`;
exports[`components/boardsUnfurl/BoardsUnfurl test invalid card, invalid block 1`] = `<div />`;
exports[`components/boardsUnfurl/BoardsUnfurl test invalid card, valid block 1`] = `<div />`;
exports[`components/boardsUnfurl/BoardsUnfurl test no card 1`] = `<div />`;

Просмотреть файл

@@ -16,6 +16,8 @@ import {createBoard} from 'src/blocks/board'
import octoClient from 'src/octoClient'
import {wrapIntl} from 'src/testUtils'
import {createBoardView} from 'src/blocks/boardView'
import BoardsUnfurl from './boardsUnfurl'
jest.mock('src/octoClient')
@@ -114,5 +116,118 @@ describe('components/boardsUnfurl/BoardsUnfurl', () => {
expect(container).toMatchSnapshot()
})
it('test no card', async () => {
const mockStore = configureStore([])
const store = mockStore({
language: {
value: 'en',
},
teams: {
allTeams: [team],
current: team,
},
})
const board = {...createBoard(), title: 'test board'}
// mockedOctoClient.getBoard.mockResolvedValueOnce(board)
const component = (
<ReduxProvider store={store}>
{wrapIntl(
<BoardsUnfurl
embed={{data: JSON.stringify({workspaceID: 'foo', cardID: '', boardID: board.id, readToken: 'abc', originalPath: '/test'})}}
/>,
)}
</ReduxProvider>
)
let container: Element | DocumentFragment | null = null
await act(async () => {
const result = render(component)
container = result.container
})
expect(container).toMatchSnapshot()
})
it('test invalid card, valid block', async () => {
const mockStore = configureStore([])
const store = mockStore({
language: {
value: 'en',
},
teams: {
allTeams: [team],
current: team,
},
})
const cards = [{...createBoardView(), title: 'test view', updateAt: 12345}]
const board = {...createBoard(), title: 'test board'}
mockedOctoClient.getBlocksWithBlockID.mockResolvedValueOnce(cards)
mockedOctoClient.getBoard.mockResolvedValueOnce(board)
const component = (
<ReduxProvider store={store}>
{wrapIntl(
<BoardsUnfurl
embed={{data: JSON.stringify({workspaceID: 'foo', cardID: cards[0].id, boardID: board.id, readToken: 'abc', originalPath: '/test'})}}
/>,
)}
</ReduxProvider>
)
let container: Element | DocumentFragment | null = null
await act(async () => {
const result = render(component)
container = result.container
})
expect(mockedOctoClient.getBoard).toBeCalledWith(board.id)
expect(mockedOctoClient.getBlocksWithBlockID).toBeCalledWith(cards[0].id, board.id, 'abc')
expect(container).toMatchSnapshot()
})
it('test invalid card, invalid block', async () => {
const mockStore = configureStore([])
const store = mockStore({
language: {
value: 'en',
},
teams: {
allTeams: [team],
current: team,
},
})
const board = {...createBoard(), title: 'test board'}
mockedOctoClient.getBlocksWithBlockID.mockResolvedValueOnce([])
mockedOctoClient.getBoard.mockResolvedValueOnce(board)
const component = (
<ReduxProvider store={store}>
{wrapIntl(
<BoardsUnfurl
embed={{data: JSON.stringify({workspaceID: 'foo', cardID: 'invalidCard', boardID: board.id, readToken: 'abc', originalPath: '/test'})}}
/>,
)}
</ReduxProvider>
)
let container: Element | DocumentFragment | null = null
await act(async () => {
const result = render(component)
container = result.container
})
expect(mockedOctoClient.getBoard).toBeCalledWith(board.id)
expect(mockedOctoClient.getBlocksWithBlockID).toBeCalledWith('invalidCard', board.id, 'abc')
expect(container).toMatchSnapshot()
})
})

Просмотреть файл

@@ -84,7 +84,7 @@ export const BoardsUnfurl = (props: Props): JSX.Element => {
],
)
const [firstCard] = cards as Card[]
if (!firstCard || !fetchedBoard) {
if (!firstCard || !fetchedBoard || firstCard.type !== 'card') {
setLoading(false)
return null
}
@@ -116,7 +116,7 @@ export const BoardsUnfurl = (props: Props): JSX.Element => {
useWebsockets(currentTeamId, (wsClient: WSClient) => {
const onChangeHandler = (_: WSClient, blocks: Block[]): void => {
const cardBlock: Block|undefined = blocks.find((b) => b.id === cardID)
if (cardBlock && !cardBlock.deleteAt) {
if (cardBlock && !cardBlock.deleteAt && cardBlock.type === 'card') {
setCard(cardBlock as Card)
}

Просмотреть файл

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React from 'react'
import {Post} from 'mattermost-redux/types/posts'
import {Post} from '@mattermost/types/posts'
const PostTypeCloudUpgradeNudge = (props: {post: Post}): JSX.Element => {
const ctaHandler = (e: React.MouseEvent) => {

Просмотреть файл

@@ -6,16 +6,14 @@ import {Store, Action} from 'redux'
import {Provider as ReduxProvider} from 'react-redux'
import {createBrowserHistory, History} from 'history'
import {rudderAnalytics, RudderTelemetryHandler} from 'mattermost-redux/client/rudder'
import {GlobalState} from 'mattermost-redux/types/store'
import {selectTeam} from 'mattermost-redux/actions/teams'
import {GlobalState} from '@mattermost/types/store'
import {SuiteWindow} from 'src/types/index'
import {PluginRegistry} from 'src/types/mattermost-webapp'
import {rudderAnalytics, RudderTelemetryHandler} from 'src/rudder'
import appBarIcon from 'static/app-bar-icon.png'
import {Constants} from 'src/constants'
@@ -85,7 +83,7 @@ function getSubpath(siteURL: string): string {
return url.pathname.replace(/\/+$/, '')
}
const TELEMETRY_RUDDER_KEY = 'placeholder_rudder_key'
const TELEMETRY_RUDDER_KEY = 'placeholder_boards_rudder_key'
const TELEMETRY_RUDDER_DATAPLANE_URL = 'placeholder_rudder_dataplane_url'
const TELEMETRY_OPTIONS = {
context: {
@@ -294,9 +292,13 @@ export default class Plugin {
const currentUserId = mmStore.getState().entities.users.currentUserId
if (currentTeamID !== fbPrevTeamID) {
fbPrevTeamID = currentTeamID
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mmStore.dispatch(selectTeam(currentTeamID))
mmStore.dispatch({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
type: 'SELECT_TEAM',
data: currentTeamID,
})
localStorage.setItem(`user_prev_team:${currentUserId}`, currentTeamID)
}
})

65
webapp/boards/src/rudder.ts Обычный файл
Просмотреть файл

@@ -0,0 +1,65 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// This file is duplicated from mattermost-redux in the web app with some slight modifications to make it standalone
// As per rudder-sdk-js documentation, import this only once and use like a singleton.
// See https://github.com/rudderlabs/rudder-sdk-js#step-1-install-rudderstack-using-the-code-snippet
import * as rudderAnalytics from 'rudder-sdk-js'
export {rudderAnalytics}
import {TelemetryHandler} from '@mattermost/client'
import {Utils} from 'src/utils'
export class RudderTelemetryHandler implements TelemetryHandler {
trackEvent(userId: string, userRoles: string, category: string, event: string, props?: any) {
const properties = Object.assign({
category,
type: event,
user_actual_role: getActualRoles(userRoles),
user_actual_id: userId,
}, props)
const options = {
context: {
ip: '0.0.0.0',
},
page: {
path: '',
referrer: '',
search: '',
title: '',
url: '',
},
anonymousId: '00000000000000000000000000',
}
rudderAnalytics.track('event', properties, options)
}
pageVisited(userId: string, userRoles: string, category: string, name: string) {
rudderAnalytics.page(
category,
name,
{
path: '',
referrer: '',
search: '',
title: '',
url: '',
user_actual_role: getActualRoles(userRoles),
user_actual_id: userId,
},
{
context: {
ip: '0.0.0.0',
},
anonymousId: '00000000000000000000000000',
},
)
}
}
function getActualRoles(userRoles: string) {
return userRoles && Utils.isSystemAdmin(userRoles) ? 'system_admin, system_user' : 'system_user'
}

Просмотреть файл

@@ -3,7 +3,7 @@
import type React from 'react'
import type {Channel, ChannelMembership} from 'mattermost-redux/types/channels'
import type {Channel, ChannelMembership} from '@mattermost/types/channels'
type ReactResolvable = React.ReactNode | React.ElementType

Просмотреть файл

@@ -53,8 +53,6 @@ const config = {
resolve: {
alias: {
src: path.resolve(__dirname, './src/'),
// 'mattermost-redux': path.resolve(__dirname, '../channels/src/packages/mattermost-redux/src/'),
// reselect: path.resolve(__dirname, '../channels/src/packages/reselect/src/index'),
'@mattermost/client': path.resolve(__dirname, '../platform/client/src/'),
'@mattermost/components': path.resolve(__dirname, '../platform/components/src/'),
},