+ (Optional) Custom Certificate Authority certificates for the Elasticsearch server. Leave this empty to use the default CAs from the operating system.
+
+
+
+
+
+
+
+
+ (Optional) The client certificate for the connection to the Elasticsearch server in the PEM format.
+
+
+
+
+
+
+
+
+ (Optional) The key for the client certificate in the PEM format.
+
+
+
+
+
+
+
+
+
+ (Optional) The username to authenticate to the Elasticsearch server.
+
+
+
+
+
+
+
+
+ (Optional) The password to authenticate to the Elasticsearch server.
+
+
+
+
+
+
+
+
+
+
+ Tests if the Mattermost server can connect to the Elasticsearch server specified. Testing the connection only saves the configuration if the test is successful. A successful test will also re-initialize the client if you have started Elasticsearch after starting Mattermost. But this will not restart the workers. To do that, please toggle "Enable Elasticsearch Indexing".
+
+
+
+
+
+
+
+
+
+
+
+ This purges the channels index and re-indexes all channels in the database, from oldest to newest. Channel autocomplete is available during indexing but search results may be incomplete until the indexing job is complete.
+
+
+
+ Note- Please ensure no other indexing job is in progress in the table above.
+
+
+
+
+
+
+
+
+
+
+
+ Purging will entirely remove the indexes on the Elasticsearch server. Search results may be incomplete until a bulk index of the existing database is rebuilt.
+
+
+
+
+
+
+
+
+ When filled in, these indexes will be ignored during the purge, separated by commas.
+
+
+
+
+
+
-
+
+
+
+
+
-
-
+
+
`;
exports[`components/ElasticSearchSettings should match snapshot, enabled 1`] = `
-
+ (Optional) Custom Certificate Authority certificates for the Elasticsearch server. Leave this empty to use the default CAs from the operating system.
+
+
+
+
+
+
+
+
+ (Optional) The client certificate for the connection to the Elasticsearch server in the PEM format.
+
+
+
+
+
+
+
+
+ (Optional) The key for the client certificate in the PEM format.
+
+
+
+
+
+
+
+
+
+ (Optional) The username to authenticate to the Elasticsearch server.
+
+
+
+
+
+
+
+
+ (Optional) The password to authenticate to the Elasticsearch server.
+
+
+
+
+
+
+
+
+
+
+ Tests if the Mattermost server can connect to the Elasticsearch server specified. Testing the connection only saves the configuration if the test is successful. A successful test will also re-initialize the client if you have started Elasticsearch after starting Mattermost. But this will not restart the workers. To do that, please toggle "Enable Elasticsearch Indexing".
+
+
+
+
+
+
+
+
+
+
+
+ This purges the channels index and re-indexes all channels in the database, from oldest to newest. Channel autocomplete is available during indexing but search results may be incomplete until the indexing job is complete.
+
+
+
+ Note- Please ensure no other indexing job is in progress in the table above.
+
+
+
+
+
+
+
+
+
+
+
+ Purging will entirely remove the indexes on the Elasticsearch server. Search results may be incomplete until a bulk index of the existing database is rebuilt.
+
+
+
+
+
+
+
+
+ When filled in, these indexes will be ignored during the purge, separated by commas.
+
+
+
+
+
+
-
+
+
+
+
+
-
-
+
+
`;
diff --git a/webapp/channels/src/components/admin_console/brand_image_setting/brand_image_setting.test.tsx b/webapp/channels/src/components/admin_console/brand_image_setting/brand_image_setting.test.tsx
index 14145e821f0..6f65ef09781 100644
--- a/webapp/channels/src/components/admin_console/brand_image_setting/brand_image_setting.test.tsx
+++ b/webapp/channels/src/components/admin_console/brand_image_setting/brand_image_setting.test.tsx
@@ -1,24 +1,30 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {shallow} from 'enzyme';
import React from 'react';
-import {Client4} from 'mattermost-redux/client';
-
import {uploadBrandImage, deleteBrandImage} from 'actions/admin_actions.jsx';
+import {renderWithContext, screen, userEvent, waitFor} from 'tests/react_testing_utils';
+
import BrandImageSetting from './brand_image_setting';
+// Real implementations are async (await dispatch(...)); mocks must return Promises so handleSave can await them.
jest.mock('actions/admin_actions.jsx', () => ({
...jest.requireActual('actions/admin_actions.jsx'),
- uploadBrandImage: jest.fn(),
- deleteBrandImage: jest.fn(),
+ uploadBrandImage: jest.fn(async () => {}),
+ deleteBrandImage: jest.fn(async () => {}),
}));
-Client4.setUrl('http://localhost:8065');
-
describe('components/admin_console/brand_image_setting', () => {
+ beforeEach(() => {
+ jest.spyOn(global, 'fetch').mockResolvedValue({status: 404} as Response);
+ });
+
+ afterEach(() => {
+ jest.restoreAllMocks();
+ });
+
const baseProps = {
disabled: false,
setSaveNeeded: jest.fn(),
@@ -26,21 +32,71 @@ describe('components/admin_console/brand_image_setting', () => {
unRegisterSaveAction: jest.fn(),
};
- test('should have called deleteBrandImage or uploadBrandImage on save depending on component state', () => {
- const wrapper = shallow(
- ,
+ test('should have called deleteBrandImage or uploadBrandImage on save depending on component state', async () => {
+ let saveAction: (() => Promise) | undefined;
+ const registerSaveAction = jest.fn((fn: () => Promise) => {
+ saveAction = fn;
+ });
+
+ const {container, unmount} = renderWithContext(
+ ,
);
- const instance = wrapper.instance();
+ // Wait for componentDidMount fetch to resolve
+ await waitFor(() => {
+ expect(registerSaveAction).toHaveBeenCalled();
+ });
+ expect(saveAction).toBeDefined();
- wrapper.setState({deleteBrandImage: false, brandImage: new Blob(['brand_image_file'])});
- instance.handleSave();
+ // Simulate selecting a file via the file input to set brandImage
+ const file = new File(['brand_image_file'], 'brand.png', {type: 'image/png'});
+ const fileInput = container.querySelector('input[type="file"]');
+ expect(fileInput).toBeInTheDocument();
+ await userEvent.upload(fileInput as HTMLInputElement, file);
+
+ // Now call save - should call uploadBrandImage
+ await saveAction!();
expect(deleteBrandImage).toHaveBeenCalledTimes(0);
expect(uploadBrandImage).toHaveBeenCalledTimes(1);
- wrapper.setState({deleteBrandImage: true, brandImage: undefined});
- instance.handleSave();
+ // To test deleteBrandImage path, unmount then re-mount with fetch returning 200
+ unmount();
+ jest.clearAllMocks();
+ (global.fetch as jest.Mock).mockResolvedValueOnce({status: 200} as Response);
+
+ let saveAction2: (() => Promise) | undefined;
+ const registerSaveAction2 = jest.fn((fn: () => Promise) => {
+ saveAction2 = fn;
+ });
+
+ renderWithContext(
+ ,
+ );
+
+ await waitFor(() => {
+ expect(registerSaveAction2).toHaveBeenCalled();
+ });
+ expect(saveAction2).toBeDefined();
+
+ // Wait for the brand image to be detected and delete button to appear
+ await waitFor(() => {
+ expect(screen.getByText('Ć')).toBeInTheDocument();
+ });
+ const deleteButton = screen.getByText('Ć').closest('button')!;
+ await userEvent.click(deleteButton);
+
+ await waitFor(() => {
+ expect(screen.getByText('No brand image uploaded')).toBeInTheDocument();
+ });
+
+ await saveAction2!();
expect(deleteBrandImage).toHaveBeenCalledTimes(1);
- expect(uploadBrandImage).toHaveBeenCalledTimes(1);
+ expect(uploadBrandImage).toHaveBeenCalledTimes(0);
});
});
diff --git a/webapp/channels/src/components/admin_console/database/__snapshots__/migrations_table.test.tsx.snap b/webapp/channels/src/components/admin_console/database/__snapshots__/migrations_table.test.tsx.snap
index 899579e1a01..66f4be792b0 100644
--- a/webapp/channels/src/components/admin_console/database/__snapshots__/migrations_table.test.tsx.snap
+++ b/webapp/channels/src/components/admin_console/database/__snapshots__/migrations_table.test.tsx.snap
@@ -1,42 +1,35 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`components/MigrationsTable should match snapshot when there are no migrations 1`] = `
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ All applied migrations.
+
+
+
+
+
+
+ Version
+
+
+ Name
+
+
+
+
+
+
`;
diff --git a/webapp/channels/src/components/admin_console/database/migrations_table.test.tsx b/webapp/channels/src/components/admin_console/database/migrations_table.test.tsx
index dafd28c90e5..e9f16bccf72 100644
--- a/webapp/channels/src/components/admin_console/database/migrations_table.test.tsx
+++ b/webapp/channels/src/components/admin_console/database/migrations_table.test.tsx
@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import {act, screen, waitFor} from '@testing-library/react';
-import {shallow} from 'enzyme';
import React from 'react';
import {FormattedMessage} from 'react-intl';
@@ -34,13 +33,18 @@ describe('components/MigrationsTable', () => {
},
};
- test('should match snapshot when there are no migrations', () => {
- const wrapper = shallow(
+ test('should match snapshot when there are no migrations', async () => {
+ const {container} = renderWithContext(
);
+ />,
+ );
- expect(wrapper).toMatchSnapshot();
+ await waitFor(() => {
+ expect(baseProps.actions.getAppliedSchemaMigrations).toHaveBeenCalledTimes(1);
+ });
+
+ expect(container).toMatchSnapshot();
});
test('should have called actions.getAppliedSchemaMigrations only when first rendered', async () => {
diff --git a/webapp/channels/src/components/admin_console/database_settings.test.tsx b/webapp/channels/src/components/admin_console/database_settings.test.tsx
index 317c0a74020..29f2542e17b 100644
--- a/webapp/channels/src/components/admin_console/database_settings.test.tsx
+++ b/webapp/channels/src/components/admin_console/database_settings.test.tsx
@@ -1,11 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {shallow} from 'enzyme';
import React from 'react';
import DatabaseSettings from 'components/admin_console/database_settings';
+import {renderWithContext} from 'tests/react_testing_utils';
+
jest.mock('actions/admin_actions.jsx', () => {
const pingFn = () => {
return jest.fn(() => {
@@ -47,11 +48,11 @@ describe('components/DatabaseSettings', () => {
config,
isDisabled: false,
};
- const wrapper = shallow(
+ const {container} = renderWithContext(
,
);
- expect(wrapper).toMatchSnapshot();
+ expect(container).toMatchSnapshot();
});
});
diff --git a/webapp/channels/src/components/admin_console/elasticsearch_settings.test.tsx b/webapp/channels/src/components/admin_console/elasticsearch_settings.test.tsx
index f5f034715a7..43bfdc251fe 100644
--- a/webapp/channels/src/components/admin_console/elasticsearch_settings.test.tsx
+++ b/webapp/channels/src/components/admin_console/elasticsearch_settings.test.tsx
@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {shallow} from 'enzyme';
import React from 'react';
import type {AdminConfig} from '@mattermost/types/config';
import ElasticSearchSettings from 'components/admin_console/elasticsearch_settings';
-import SaveButton from 'components/save_button';
+
+import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
jest.mock('actions/admin_actions.jsx', () => {
return {
@@ -22,6 +22,7 @@ describe('components/ElasticSearchSettings', () => {
const config = {
ElasticsearchSettings: {
ConnectionURL: 'test',
+ Backend: '',
SkipTLSVerification: false,
CA: 'test.ca',
ClientCert: 'test.crt',
@@ -32,20 +33,24 @@ describe('components/ElasticSearchSettings', () => {
EnableIndexing: false,
EnableSearching: false,
EnableAutocomplete: false,
+ EnableSearchPublicChannelsWithoutMembership: false,
+ IgnoredPurgeIndexes: '',
},
};
- const wrapper = shallow(
+ const {container} = renderWithContext(
,
);
- expect(wrapper).toMatchSnapshot();
+ expect(container).toMatchSnapshot();
});
test('should match snapshot, enabled', () => {
const config = {
ElasticsearchSettings: {
ConnectionURL: 'test',
+ Backend: '',
SkipTLSVerification: false,
CA: 'test.ca',
ClientCert: 'test.crt',
@@ -56,43 +61,60 @@ describe('components/ElasticSearchSettings', () => {
EnableIndexing: true,
EnableSearching: false,
EnableAutocomplete: false,
+ EnableSearchPublicChannelsWithoutMembership: false,
+ IgnoredPurgeIndexes: '',
},
};
- const wrapper = shallow(
+ const {container} = renderWithContext(
,
);
- expect(wrapper).toMatchSnapshot();
+ expect(container).toMatchSnapshot();
});
- test('should maintain save disable until is tested', () => {
+ test('should maintain save disable until is tested', async () => {
const config = {
ElasticsearchSettings: {
ConnectionURL: 'test',
+ Backend: '',
SkipTLSVerification: false,
+ CA: '',
+ ClientCert: '',
+ ClientKey: '',
Username: 'test',
Password: 'test',
Sniff: false,
EnableIndexing: false,
EnableSearching: false,
EnableAutocomplete: false,
+ EnableSearchPublicChannelsWithoutMembership: false,
+ IgnoredPurgeIndexes: '',
},
};
- const wrapper = shallow(
+ renderWithContext(
,
);
- const instance = wrapper.instance() as any;
- expect(wrapper.find(SaveButton).prop('disabled')).toBe(true);
- instance.handleSettingChanged('enableIndexing', true);
- expect(wrapper.find(SaveButton).prop('disabled')).toBe(true);
- const success = jest.fn();
- const error = jest.fn();
- instance.doTestConfig(success, error);
- expect(success).toHaveBeenCalled();
- expect(error).not.toHaveBeenCalled();
- expect(wrapper.find(SaveButton).prop('disabled')).toBe(false);
+
+ // Save button should be disabled initially (no changes)
+ expect(screen.getByTestId('saveSetting')).toBeDisabled();
+
+ // Enable indexing by clicking the true radio for enableIndexing
+ const enableIndexingTrue = screen.getByTestId('enableIndexingtrue');
+ await userEvent.click(enableIndexingTrue);
+
+ // Save button should still be disabled because config hasn't been tested
+ expect(screen.getByTestId('saveSetting')).toBeDisabled();
+
+ // Click Test Connection button to test config
+ const testButton = screen.getByText('Test Connection');
+ await userEvent.click(testButton);
+
+ // After successful test, save button should be enabled
+ expect(screen.getByTestId('saveSetting')).not.toBeDisabled();
});
});
diff --git a/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/manage_teams_dropdown.test.tsx.snap b/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/manage_teams_dropdown.test.tsx.snap
index d340852f477..09dfa4b53d4 100644
--- a/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/manage_teams_dropdown.test.tsx.snap
+++ b/webapp/channels/src/components/admin_console/manage_teams_modal/__snapshots__/manage_teams_dropdown.test.tsx.snap
@@ -1,149 +1,73 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`ManageTeamsDropdown should match snapshot for guest 1`] = `
-
-
-
- Guest
-
-
-
-
-