From 3988e64d22621a039a1ab6763b219ce359d7acd3 Mon Sep 17 00:00:00 2001 From: Ashish Bhate Date: Thu, 15 Oct 2020 16:27:28 +0000 Subject: [PATCH] MM-29039: unit and e2e tests for #4821 (#4879) * MM-29039: unit and e2e tests for #4821 * add e2e test * Apply suggestions from code review Co-authored-by: Joseph Baylon * use suggested test libs * move mock to test setup * update snapshot for new mock Co-authored-by: Joseph Baylon --- .../__snapshots__/long_post.test.js.snap | 4 +- .../select_server/select_server.test.js | 83 +++++++++++++++++++ ...on_settings_mentions_keywords.test.js.snap | 4 +- detox/e2e/test/on_boarding/login.e2e.js | 25 ++++++ test/setup.js | 4 +- 5 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 app/screens/select_server/select_server.test.js diff --git a/app/screens/long_post/__snapshots__/long_post.test.js.snap b/app/screens/long_post/__snapshots__/long_post.test.js.snap index 8ff6e8827..2fb5c941d 100644 --- a/app/screens/long_post/__snapshots__/long_post.test.js.snap +++ b/app/screens/long_post/__snapshots__/long_post.test.js.snap @@ -32,7 +32,9 @@ LongPost { "goToThread": [Function], "handleClose": [Function], "handlePress": [Function], - "navigationEventListener": undefined, + "navigationEventListener": Object { + "remove": [MockFunction], + }, "props": Object { "actions": Object { "getPostThread": [MockFunction], diff --git a/app/screens/select_server/select_server.test.js b/app/screens/select_server/select_server.test.js new file mode 100644 index 000000000..0d3e90bf2 --- /dev/null +++ b/app/screens/select_server/select_server.test.js @@ -0,0 +1,83 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import React from 'react'; + +import SelectServer from './select_server.js'; +import {renderWithReduxIntl} from 'test/testing_library'; +import {fireEvent, waitFor} from '@testing-library/react-native'; + +describe('SelectServer', () => { + const actions = { + getPing: jest.fn(), + handleServerUrlChanged: jest.fn(), + scheduleExpiredNotification: jest.fn(), + loadConfigAndLicense: jest.fn(), + login: jest.fn(), + resetPing: jest.fn(), + setLastUpgradeCheck: jest.fn(), + setServerVersion: jest.fn(), + }; + + const baseProps = { + actions, + hasConfigAndLicense: true, + serverUrl: '', + }; + + test('should match error when URL is empty string', async () => { + const {getByTestId, getByText} = renderWithReduxIntl( + , + ); + + const button = getByText('Connect'); + fireEvent.press(button); + + await waitFor(() => expect(getByTestId('error_text')).toBeTruthy()); + expect(getByText('Please enter a valid server URL')).toBeTruthy(); + }); + + test('should match error when URL is only spaces', async () => { + const {getByTestId, getByText} = renderWithReduxIntl( + , + ); + + const urlInput = getByTestId('server_url_input'); + fireEvent.changeText(urlInput, ' '); + + const button = getByText('Connect'); + fireEvent.press(button); + + await waitFor(() => expect(getByTestId('error_text')).toBeTruthy()); + expect(getByText('Please enter a valid server URL')).toBeTruthy(); + }); + + test('should match error when URL does not start with http:// or https://', async () => { + const {getByTestId, getByText} = renderWithReduxIntl( + , + ); + + const urlInput = getByTestId('server_url_input'); + fireEvent.changeText(urlInput, 'ht://invalid:8065'); + + const button = getByText('Connect'); + fireEvent.press(button); + + await waitFor(() => expect(getByTestId('error_text')).toBeTruthy()); + expect(getByText('URL must start with http:// or https://')).toBeTruthy(); + }); + + test('should not show error when valid URL is entered', async () => { + const {getByTestId, getByText, queryByTestId} = renderWithReduxIntl( + , + ); + + const urlInput = getByTestId('server_url_input'); + fireEvent.changeText(urlInput, 'http://localhost:8065'); + + const button = getByText('Connect'); + fireEvent.press(button); + + expect(queryByTestId('error_text')).toBeNull(); + await waitFor(() => expect(getByText('Connecting...')).toBeTruthy()); + }); +}); \ No newline at end of file diff --git a/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap b/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap index 593d4000a..c1c44a184 100644 --- a/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap +++ b/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap @@ -5,7 +5,9 @@ NotificationSettingsMentionsKeywords { "context": Object {}, "handleSubmit": [Function], "keywordsRef": [Function], - "navigationEventListener": undefined, + "navigationEventListener": Object { + "remove": [MockFunction], + }, "onKeywordsChangeText": [Function], "props": Object { "componentId": "component-id", diff --git a/detox/e2e/test/on_boarding/login.e2e.js b/detox/e2e/test/on_boarding/login.e2e.js index 2fdcef9e9..950825126 100644 --- a/detox/e2e/test/on_boarding/login.e2e.js +++ b/detox/e2e/test/on_boarding/login.e2e.js @@ -32,6 +32,31 @@ describe('On boarding', () => { await expect(element(by.id('connect_button'))).toBeVisible(); }); + it('MM-T3383 should show error on empty server URL', async () => { + await expect(element(by.id('select_server_screen'))).toBeVisible(); + + // # Enter an empty server URL + await element(by.id('server_url_input')).typeText(' '); + + // # Tap anywhere to hide keyboard + await element(by.text('Enter Server URL')).tap(); + + // * Verify that the error message does not exist + await waitFor(element(by.id('error_text'))).not.toExist().withTimeout(timeouts.HALF_SEC); + + // # Tap connect button + await element(by.id('connect_button')).tap(); + + // # Explicitly wait on Android before verifying error message + if (isAndroid()) { + await wait(timeouts.ONE_MIN); + } + + // * Verify error message + await waitFor(element(by.id('error_text'))).toBeVisible().withTimeout(timeouts.ONE_MIN); + await expect(element(by.id('error_text'))).toHaveText('Please enter a valid server URL'); + }); + it('should show error on invalid server URL', async () => { await expect(element(by.id('select_server_screen'))).toBeVisible(); diff --git a/test/setup.js b/test/setup.js index b718063a3..a3c8e12e9 100644 --- a/test/setup.js +++ b/test/setup.js @@ -188,7 +188,9 @@ jest.mock('react-native-navigation', () => { ...RNN.Navigation, events: () => ({ registerAppLaunchedListener: jest.fn(), - bindComponent: jest.fn(), + bindComponent: jest.fn(() => { + return {remove: jest.fn()}; + }), }), setRoot: jest.fn(), pop: jest.fn(),