Fetch playbooks when we reconnect and we are on a channel (#8993)
* Fetch playbooks when we reconnect and we are on a channel * Fix test * Address feedback
This commit is contained in:
parent
394b441874
commit
5a034aa51f
12 changed files with 272 additions and 83 deletions
|
|
@ -13,7 +13,7 @@ import {loadConfigAndCalls} from '@calls/actions/calls';
|
|||
import {isSupportedServerCalls} from '@calls/utils';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import AppsManager from '@managers/apps_manager';
|
||||
import {updatePlaybooksVersion} from '@playbooks/actions/remote/version';
|
||||
import {handlePlaybookReconnect} from '@playbooks/actions/websocket/reconnect';
|
||||
import {getActiveServerUrl} from '@queries/app/servers';
|
||||
import {getLastPostInThread} from '@queries/servers/post';
|
||||
import {getConfig, getCurrentChannelId, getCurrentTeamId, setLastFullSync} from '@queries/servers/system';
|
||||
|
|
@ -49,7 +49,7 @@ jest.mock('@utils/helpers', () => ({
|
|||
isTablet: jest.fn().mockReturnValue(false),
|
||||
}));
|
||||
|
||||
jest.mock('@playbooks/actions/remote/version');
|
||||
jest.mock('@playbooks/actions/websocket/reconnect');
|
||||
|
||||
describe('WebSocket Index Actions', () => {
|
||||
const serverUrl = 'baseHandler.test.com';
|
||||
|
|
@ -104,7 +104,7 @@ describe('WebSocket Index Actions', () => {
|
|||
expect(setLastFullSync).toHaveBeenCalled();
|
||||
expect(loadConfigAndCalls).toHaveBeenCalled();
|
||||
expect(deferredAppEntryActions).toHaveBeenCalled();
|
||||
expect(updatePlaybooksVersion).toHaveBeenCalledWith(serverUrl);
|
||||
expect(handlePlaybookReconnect).toHaveBeenCalledWith(serverUrl);
|
||||
});
|
||||
|
||||
it('should handle error when server database not found', async () => {
|
||||
|
|
@ -159,7 +159,7 @@ describe('WebSocket Index Actions', () => {
|
|||
expect(openAllUnreadChannels).toHaveBeenCalled();
|
||||
expect(dataRetentionCleanup).toHaveBeenCalled();
|
||||
expect(AppsManager.refreshAppBindings).toHaveBeenCalled();
|
||||
expect(updatePlaybooksVersion).toHaveBeenCalledWith(serverUrl);
|
||||
expect(handlePlaybookReconnect).toHaveBeenCalledWith(serverUrl);
|
||||
});
|
||||
|
||||
it('should fetch posts for channel screen', async () => {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {isSupportedServerCalls} from '@calls/utils';
|
|||
import {Screens} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import AppsManager from '@managers/apps_manager';
|
||||
import {updatePlaybooksVersion} from '@playbooks/actions/remote/version';
|
||||
import {handlePlaybookReconnect} from '@playbooks/actions/websocket/reconnect';
|
||||
import {getActiveServerUrl} from '@queries/app/servers';
|
||||
import {getLastPostInThread} from '@queries/servers/post';
|
||||
import {
|
||||
|
|
@ -92,8 +92,7 @@ async function doReconnect(serverUrl: string, groupLabel?: BaseRequestGroupLabel
|
|||
const license = await getLicense(database);
|
||||
const config = await getConfig(database);
|
||||
|
||||
// Set the version of the playbooks plugin to the systems table
|
||||
updatePlaybooksVersion(serverUrl);
|
||||
handlePlaybookReconnect(serverUrl);
|
||||
|
||||
if (isSupportedServerCalls(config?.Version)) {
|
||||
loadConfigAndCalls(serverUrl, currentUserId, groupLabel);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import WebSocketClient from '@client/websocket';
|
|||
import DatabaseManager from '@database/manager';
|
||||
import {getCurrentUserId} from '@queries/servers/system';
|
||||
import {queryAllUsers} from '@queries/servers/user';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import TestHelper from '@test/test_helper';
|
||||
import {logError} from '@utils/log';
|
||||
|
||||
|
|
@ -31,7 +30,6 @@ jest.mock('@database/manager');
|
|||
jest.mock('@queries/servers/system');
|
||||
jest.mock('@queries/servers/user');
|
||||
jest.mock('@utils/log');
|
||||
jest.mock('@store/ephemeral_store');
|
||||
|
||||
describe('WebsocketManager', () => {
|
||||
let manager: typeof WebsocketManager;
|
||||
|
|
@ -125,17 +123,6 @@ describe('WebsocketManager', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('proper callbacks set', () => {
|
||||
it('should remove playbooks when the reconnect callback is called', () => {
|
||||
const client = manager.createClient(mockServerUrl, mockToken);
|
||||
expect(client).toBeDefined();
|
||||
|
||||
expect(client.setReconnectCallback).toHaveBeenCalled();
|
||||
jest.mocked(client.setReconnectCallback).mock.calls[0][0]();
|
||||
expect(EphemeralStore.clearChannelPlaybooksSynced).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('connection handling', () => {
|
||||
beforeEach(async () => {
|
||||
await manager.init(mockCredentials);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import {General} from '@constants';
|
|||
import DatabaseManager from '@database/manager';
|
||||
import {getCurrentUserId} from '@queries/servers/system';
|
||||
import {queryAllUsers} from '@queries/servers/user';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import {toMilliseconds} from '@utils/datetime';
|
||||
import {isMainActivity} from '@utils/helpers';
|
||||
import {logError} from '@utils/log';
|
||||
|
|
@ -180,11 +179,6 @@ class WebsocketManagerSingleton {
|
|||
this.startPeriodicStatusUpdates(serverUrl);
|
||||
this.getConnectedSubject(serverUrl).next('connected');
|
||||
|
||||
// Clear playbooks synced state on reconnect.
|
||||
// This is done to avoid clearing it on spotty connections
|
||||
// with reliable websockets.
|
||||
EphemeralStore.clearChannelPlaybooksSynced(serverUrl);
|
||||
|
||||
const error = await handleReconnect(serverUrl);
|
||||
if (error) {
|
||||
this.getClient(serverUrl)?.close(false);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import NetworkManager from '@managers/network_manager';
|
|||
import {updateLastPlaybookRunsFetchAt} from '@playbooks/actions/local/channel';
|
||||
import {handlePlaybookRuns} from '@playbooks/actions/local/run';
|
||||
import {getLastPlaybookRunsFetchAt} from '@playbooks/database/queries/run';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import TestHelper from '@test/test_helper';
|
||||
|
||||
import {fetchPlaybookRunsForChannel, fetchFinishedRunsForChannel} from './runs';
|
||||
|
|
@ -118,6 +119,32 @@ describe('fetchPlaybookRunsForChannel', () => {
|
|||
expect(result.runs).toEqual([mockPlaybookRun]);
|
||||
expect(handlePlaybookRuns).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update the channel in the ephemeral store', async () => {
|
||||
mockClient.fetchPlaybookRuns.mockResolvedValueOnce({
|
||||
items: [mockPlaybookRun],
|
||||
has_more: false,
|
||||
});
|
||||
|
||||
EphemeralStore.clearChannelPlaybooksSynced(serverUrl);
|
||||
|
||||
expect(EphemeralStore.getChannelPlaybooksSynced(serverUrl, channelId)).toBe(false);
|
||||
await fetchPlaybookRunsForChannel(serverUrl, channelId);
|
||||
expect(EphemeralStore.getChannelPlaybooksSynced(serverUrl, channelId)).toBe(true);
|
||||
});
|
||||
|
||||
it('should not update the channel in the ephemeral store if fetchOnly is true', async () => {
|
||||
mockClient.fetchPlaybookRuns.mockResolvedValueOnce({
|
||||
items: [mockPlaybookRun],
|
||||
has_more: false,
|
||||
});
|
||||
|
||||
EphemeralStore.clearChannelPlaybooksSynced(serverUrl);
|
||||
|
||||
expect(EphemeralStore.getChannelPlaybooksSynced(serverUrl, channelId)).toBe(false);
|
||||
await fetchPlaybookRunsForChannel(serverUrl, channelId, true);
|
||||
expect(EphemeralStore.getChannelPlaybooksSynced(serverUrl, channelId)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchFinishedRunsForChannel', () => {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {updateLastPlaybookRunsFetchAt} from '@playbooks/actions/local/channel';
|
|||
import {handlePlaybookRuns} from '@playbooks/actions/local/run';
|
||||
import {getLastPlaybookRunsFetchAt} from '@playbooks/database/queries/run';
|
||||
import {getMaxRunUpdateAt} from '@playbooks/utils/run';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import {getFullErrorMessage} from '@utils/errors';
|
||||
import {logDebug} from '@utils/log';
|
||||
|
||||
|
|
@ -50,6 +51,7 @@ export const fetchPlaybookRunsForChannel = async (serverUrl: string, channelId:
|
|||
updateLastPlaybookRunsFetchAt(serverUrl, channelId, getMaxRunUpdateAt(allRuns));
|
||||
|
||||
if (!fetchOnly) {
|
||||
EphemeralStore.setChannelPlaybooksSynced(serverUrl, channelId);
|
||||
handlePlaybookRuns(serverUrl, allRuns, false, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
103
app/products/playbooks/actions/websocket/reconnect.test.ts
Normal file
103
app/products/playbooks/actions/websocket/reconnect.test.ts
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Screens} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {fetchPlaybookRunsForChannel} from '@playbooks/actions/remote/runs';
|
||||
import {updatePlaybooksVersion} from '@playbooks/actions/remote/version';
|
||||
import {fetchIsPlaybooksEnabled} from '@playbooks/database/queries/version';
|
||||
import {getCurrentChannelId} from '@queries/servers/system';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import NavigationStore from '@store/navigation_store';
|
||||
|
||||
import {handlePlaybookReconnect} from './reconnect';
|
||||
|
||||
const serverUrl = 'test-server.com';
|
||||
|
||||
jest.mock('@playbooks/actions/remote/runs');
|
||||
jest.mock('@playbooks/actions/remote/version');
|
||||
jest.mock('@playbooks/database/queries/version');
|
||||
jest.mock('@queries/servers/system');
|
||||
|
||||
describe('handlePlaybookReconnect', () => {
|
||||
const mockCurrentChannelId = 'channel-123';
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
await DatabaseManager.init([serverUrl]);
|
||||
|
||||
jest.mocked(updatePlaybooksVersion).mockResolvedValue({data: true});
|
||||
jest.mocked(fetchIsPlaybooksEnabled).mockResolvedValue(false);
|
||||
jest.mocked(getCurrentChannelId).mockResolvedValue(mockCurrentChannelId);
|
||||
jest.mocked(fetchPlaybookRunsForChannel).mockResolvedValue({runs: []});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await DatabaseManager.deleteServerDatabase(serverUrl);
|
||||
});
|
||||
|
||||
it('should return early when database is not found', async () => {
|
||||
const clearSpy = jest.spyOn(EphemeralStore, 'clearChannelPlaybooksSynced');
|
||||
const getScreensSpy = jest.spyOn(NavigationStore, 'getScreensInStack');
|
||||
await DatabaseManager.deleteServerDatabase(serverUrl);
|
||||
|
||||
await handlePlaybookReconnect(serverUrl);
|
||||
|
||||
expect(clearSpy).not.toHaveBeenCalled();
|
||||
expect(updatePlaybooksVersion).not.toHaveBeenCalled();
|
||||
expect(getScreensSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should clear channel playbooks synced state', async () => {
|
||||
const clearSpy = jest.spyOn(EphemeralStore, 'clearChannelPlaybooksSynced');
|
||||
|
||||
await handlePlaybookReconnect(serverUrl);
|
||||
|
||||
expect(clearSpy).toHaveBeenCalledWith(serverUrl);
|
||||
expect(clearSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should update playbooks version', async () => {
|
||||
await handlePlaybookReconnect(serverUrl);
|
||||
|
||||
expect(updatePlaybooksVersion).toHaveBeenCalledWith(serverUrl);
|
||||
expect(updatePlaybooksVersion).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not fetch playbook runs when not on channel screen', async () => {
|
||||
const getScreensSpy = jest.spyOn(NavigationStore, 'getScreensInStack').mockReturnValue([Screens.HOME, Screens.THREAD]);
|
||||
|
||||
await handlePlaybookReconnect(serverUrl);
|
||||
|
||||
expect(getScreensSpy).toHaveBeenCalled();
|
||||
expect(fetchIsPlaybooksEnabled).not.toHaveBeenCalled();
|
||||
expect(getCurrentChannelId).not.toHaveBeenCalled();
|
||||
expect(fetchPlaybookRunsForChannel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not fetch playbook runs when playbooks are disabled', async () => {
|
||||
const getScreensSpy = jest.spyOn(NavigationStore, 'getScreensInStack').mockReturnValue([Screens.HOME, Screens.CHANNEL, Screens.THREAD]);
|
||||
jest.mocked(fetchIsPlaybooksEnabled).mockResolvedValue(false);
|
||||
|
||||
await handlePlaybookReconnect(serverUrl);
|
||||
|
||||
expect(getScreensSpy).toHaveBeenCalled();
|
||||
expect(fetchIsPlaybooksEnabled).toHaveBeenCalled();
|
||||
expect(getCurrentChannelId).not.toHaveBeenCalled();
|
||||
expect(fetchPlaybookRunsForChannel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should fetch playbook runs when on channel screen and playbooks are enabled', async () => {
|
||||
const getScreensSpy = jest.spyOn(NavigationStore, 'getScreensInStack').mockReturnValue([Screens.CHANNEL]);
|
||||
jest.mocked(fetchIsPlaybooksEnabled).mockResolvedValue(true);
|
||||
|
||||
await handlePlaybookReconnect(serverUrl);
|
||||
|
||||
expect(getScreensSpy).toHaveBeenCalled();
|
||||
expect(fetchIsPlaybooksEnabled).toHaveBeenCalled();
|
||||
expect(getCurrentChannelId).toHaveBeenCalled();
|
||||
expect(fetchPlaybookRunsForChannel).toHaveBeenCalledWith(serverUrl, mockCurrentChannelId);
|
||||
expect(fetchPlaybookRunsForChannel).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
40
app/products/playbooks/actions/websocket/reconnect.ts
Normal file
40
app/products/playbooks/actions/websocket/reconnect.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Screens} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {fetchPlaybookRunsForChannel} from '@playbooks/actions/remote/runs';
|
||||
import {updatePlaybooksVersion} from '@playbooks/actions/remote/version';
|
||||
import {fetchIsPlaybooksEnabled} from '@playbooks/database/queries/version';
|
||||
import {getCurrentChannelId} from '@queries/servers/system';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import NavigationStore from '@store/navigation_store';
|
||||
import {logDebug} from '@utils/log';
|
||||
|
||||
export async function handlePlaybookReconnect(serverUrl: string) {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear playbooks synced state on reconnect.
|
||||
// This is done to avoid clearing it on spotty connections
|
||||
// with reliable websockets.
|
||||
EphemeralStore.clearChannelPlaybooksSynced(serverUrl);
|
||||
|
||||
// Set the version of the playbooks plugin to the systems table
|
||||
const updateResult = await updatePlaybooksVersion(serverUrl);
|
||||
if (updateResult.error) {
|
||||
logDebug('Error updating playbooks version on reconnect', updateResult.error);
|
||||
}
|
||||
|
||||
if (NavigationStore.getScreensInStack().includes(Screens.CHANNEL)) {
|
||||
const isPlaybooksEnabled = await fetchIsPlaybooksEnabled(database);
|
||||
if (isPlaybooksEnabled) {
|
||||
const currentChannelId = await getCurrentChannelId(database);
|
||||
const fetchResult = await fetchPlaybookRunsForChannel(serverUrl, currentChannelId);
|
||||
if (fetchResult.error) {
|
||||
logDebug('Error fetching playbook runs on reconnect', fetchResult.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import {SYSTEM_IDENTIFIERS} from '@constants/database';
|
|||
import DatabaseManager from '@database/manager';
|
||||
import {MINIMUM_MAJOR_VERSION, MINIMUM_MINOR_VERSION, MINIMUM_PATCH_VERSION} from '@playbooks/constants/version';
|
||||
|
||||
import {observeIsPlaybooksEnabled} from './version';
|
||||
import {fetchIsPlaybooksEnabled, observeIsPlaybooksEnabled} from './version';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
|
||||
|
|
@ -151,4 +151,75 @@ describe('Playbook Version Queries', () => {
|
|||
expect(subscriptionNext).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchIsPlaybooksEnabled', () => {
|
||||
it('should return false when no playbooks version is set', async () => {
|
||||
const result = await fetchIsPlaybooksEnabled(operator.database);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it(`should return true when playbooks version meets minimum requirements (${MINIMUM_VERSION})`, async () => {
|
||||
await operator.handleSystem({
|
||||
systems: [{id: SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION, value: MINIMUM_VERSION}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
const result = await fetchIsPlaybooksEnabled(operator.database);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when playbooks version has higher major version', async () => {
|
||||
const higherVersion = `${MINIMUM_MAJOR_VERSION + 1}.0.0`;
|
||||
await operator.handleSystem({
|
||||
systems: [{id: SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION, value: higherVersion}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
const result = await fetchIsPlaybooksEnabled(operator.database);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when playbooks version has higher minor version', async () => {
|
||||
const higherVersion = `${MINIMUM_MAJOR_VERSION}.${MINIMUM_MINOR_VERSION + 1}.${MINIMUM_PATCH_VERSION}`;
|
||||
await operator.handleSystem({
|
||||
systems: [{id: SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION, value: higherVersion}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
const result = await fetchIsPlaybooksEnabled(operator.database);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when playbooks version has higher patch version', async () => {
|
||||
const higherVersion = `${MINIMUM_MAJOR_VERSION}.${MINIMUM_MINOR_VERSION}.${MINIMUM_PATCH_VERSION + 1}`;
|
||||
await operator.handleSystem({
|
||||
systems: [{id: SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION, value: higherVersion}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
const result = await fetchIsPlaybooksEnabled(operator.database);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle empty version string', async () => {
|
||||
await operator.handleSystem({
|
||||
systems: [{id: SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION, value: ''}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
const result = await fetchIsPlaybooksEnabled(operator.database);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when playbooks version is below minimum', async () => {
|
||||
const belowVersion = `${MINIMUM_MAJOR_VERSION - 1}.${MINIMUM_MINOR_VERSION}.${MINIMUM_PATCH_VERSION}`;
|
||||
await operator.handleSystem({
|
||||
systems: [{id: SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION, value: belowVersion}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
const result = await fetchIsPlaybooksEnabled(operator.database);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,17 +11,32 @@ import {isMinimumServerVersion} from '@utils/helpers';
|
|||
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
function queryPlaybooksVersion(database: Database) {
|
||||
return database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).query(
|
||||
Q.where('id', SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION),
|
||||
);
|
||||
}
|
||||
|
||||
function isPlaybooksEnabledFromSystemModel(systems: SystemModel[]) {
|
||||
const version = systems[0]?.value;
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isMinimumServerVersion(version, MINIMUM_MAJOR_VERSION, MINIMUM_MINOR_VERSION, MINIMUM_PATCH_VERSION);
|
||||
}
|
||||
|
||||
export async function fetchIsPlaybooksEnabled(database: Database) {
|
||||
const systems = await queryPlaybooksVersion(database).fetch();
|
||||
return isPlaybooksEnabledFromSystemModel(systems);
|
||||
}
|
||||
|
||||
export function observeIsPlaybooksEnabled(database: Database) {
|
||||
return database.get<SystemModel>(MM_TABLES.SERVER.SYSTEM).query(
|
||||
Q.where('id', SYSTEM_IDENTIFIERS.PLAYBOOKS_VERSION),
|
||||
).observeWithColumns(['value']).pipe(
|
||||
switchMap((systems) => {
|
||||
const version = systems[0]?.value;
|
||||
if (!version) {
|
||||
return of$(false);
|
||||
}
|
||||
|
||||
return of$(isMinimumServerVersion(version, MINIMUM_MAJOR_VERSION, MINIMUM_MINOR_VERSION, MINIMUM_PATCH_VERSION));
|
||||
return of$(isPlaybooksEnabledFromSystemModel(systems));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,31 +128,8 @@ describe('ChannelHeader', () => {
|
|||
expect(goToPlaybookRun).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set the ephemeral store when we fetch the playbook runs for the channel', async () => {
|
||||
const ephemeralGetSpy = jest.spyOn(EphemeralStore, 'getChannelPlaybooksSynced');
|
||||
const ephemeralSetSpy = jest.spyOn(EphemeralStore, 'setChannelPlaybooksSynced');
|
||||
|
||||
const props = getBaseProps();
|
||||
props.isPlaybooksEnabled = true;
|
||||
|
||||
ephemeralGetSpy.mockReturnValue(false);
|
||||
|
||||
jest.mocked(fetchPlaybookRunsForChannel).mockResolvedValue({
|
||||
runs: [],
|
||||
});
|
||||
|
||||
renderWithIntl(<ChannelHeader {...props}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ephemeralGetSpy).toHaveBeenCalledWith(serverUrl, 'channel-id');
|
||||
expect(fetchPlaybookRunsForChannel).toHaveBeenCalledWith(serverUrl, 'channel-id');
|
||||
expect(ephemeralSetSpy).toHaveBeenCalledWith(serverUrl, 'channel-id');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not fetch runs when playbooks are disabled', async () => {
|
||||
const ephemeralGetSpy = jest.spyOn(EphemeralStore, 'getChannelPlaybooksSynced');
|
||||
const ephemeralSetSpy = jest.spyOn(EphemeralStore, 'setChannelPlaybooksSynced');
|
||||
|
||||
const props = getBaseProps();
|
||||
props.isPlaybooksEnabled = false;
|
||||
|
|
@ -162,14 +139,12 @@ describe('ChannelHeader', () => {
|
|||
|
||||
await waitFor(() => {
|
||||
expect(ephemeralGetSpy).not.toHaveBeenCalled();
|
||||
expect(ephemeralSetSpy).not.toHaveBeenCalled();
|
||||
expect(fetchPlaybookRunsForChannel).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not fetch runs when we already have the runs synced', async () => {
|
||||
const ephemeralGetSpy = jest.spyOn(EphemeralStore, 'getChannelPlaybooksSynced');
|
||||
const ephemeralSetSpy = jest.spyOn(EphemeralStore, 'setChannelPlaybooksSynced');
|
||||
|
||||
const props = getBaseProps();
|
||||
props.isPlaybooksEnabled = true;
|
||||
|
|
@ -180,28 +155,7 @@ describe('ChannelHeader', () => {
|
|||
|
||||
await waitFor(() => {
|
||||
expect(ephemeralGetSpy).toHaveBeenCalledWith(serverUrl, 'channel-id');
|
||||
expect(ephemeralSetSpy).not.toHaveBeenCalled();
|
||||
expect(fetchPlaybookRunsForChannel).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not set the ephemeral store when there is an error fetching the runs', async () => {
|
||||
const ephemeralGetSpy = jest.spyOn(EphemeralStore, 'getChannelPlaybooksSynced');
|
||||
const ephemeralSetSpy = jest.spyOn(EphemeralStore, 'setChannelPlaybooksSynced');
|
||||
|
||||
const props = getBaseProps();
|
||||
props.isPlaybooksEnabled = true;
|
||||
|
||||
ephemeralGetSpy.mockReturnValue(false);
|
||||
|
||||
jest.mocked(fetchPlaybookRunsForChannel).mockResolvedValue({error: new Error('Error fetching runs')});
|
||||
|
||||
renderWithIntl(<ChannelHeader {...props}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ephemeralGetSpy).toHaveBeenCalledWith(serverUrl, 'channel-id');
|
||||
expect(ephemeralSetSpy).not.toHaveBeenCalled();
|
||||
expect(fetchPlaybookRunsForChannel).toHaveBeenCalledWith(serverUrl, 'channel-id');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -303,10 +303,7 @@ const ChannelHeader = ({
|
|||
useEffect(() => {
|
||||
const asyncEffect = async () => {
|
||||
if (isPlaybooksEnabled && !EphemeralStore.getChannelPlaybooksSynced(serverUrl, channelId)) {
|
||||
const res = await fetchPlaybookRunsForChannel(serverUrl, channelId);
|
||||
if (!('error' in res)) {
|
||||
EphemeralStore.setChannelPlaybooksSynced(serverUrl, channelId);
|
||||
}
|
||||
await fetchPlaybookRunsForChannel(serverUrl, channelId);
|
||||
}
|
||||
};
|
||||
asyncEffect();
|
||||
|
|
|
|||
Loading…
Reference in a new issue