MM-31964 Set default value of bool form field to false (#5388)

* set bool default to false

* add tests

lint

* update tests

* import order

* import order
This commit is contained in:
Michael Kochell 2021-07-29 20:23:43 -04:00 committed by GitHub
parent 29fd07ede6
commit 0e0ed0b14b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 499 additions and 10 deletions

View file

@ -0,0 +1,349 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AppsForm should set match snapshot 1`] = `
<RNCSafeAreaView
style={
Object {
"backgroundColor": "rgba(61,60,64,0.03)",
}
}
testID="interactive_dialog.screen"
>
<ScrollView
style={
Object {
"marginBottom": 20,
"marginTop": 10,
}
}
>
<Connect(StatusBar) />
<DialogIntroductionText
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value="Header"
/>
<AppsFormField
field={
Object {
"name": "bool1",
"type": "bool",
}
}
key="bool1"
name="bool1"
onChange={[Function]}
performLookup={[Function]}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value={false}
/>
<AppsFormField
field={
Object {
"name": "bool2",
"type": "bool",
"value": false,
}
}
key="bool2"
name="bool2"
onChange={[Function]}
performLookup={[Function]}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value={false}
/>
<AppsFormField
field={
Object {
"name": "bool3",
"type": "bool",
"value": true,
}
}
key="bool3"
name="bool3"
onChange={[Function]}
performLookup={[Function]}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value={true}
/>
<AppsFormField
field={
Object {
"name": "text1",
"type": "text",
"value": "initial text",
}
}
key="text1"
name="text1"
onChange={[Function]}
performLookup={[Function]}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value="initial text"
/>
<AppsFormField
field={
Object {
"name": "select1",
"options": Array [
Object {
"label": "Label1",
"value": "Value1",
},
Object {
"label": "Label2",
"value": "Value2",
},
],
"type": "static_select",
"value": Object {
"label": "Label1",
"value": "Value1",
},
}
}
key="select1"
name="select1"
onChange={[Function]}
performLookup={[Function]}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
value={
Object {
"label": "Label1",
"value": "Value1",
}
}
/>
<View
style={
Object {
"marginHorizontal": 5,
}
}
>
<Button
containerStyle={
Object {
"alignItems": "center",
"alignSelf": "stretch",
"borderColor": "#2389D7",
"borderRadius": 3,
"borderWidth": 1,
"marginTop": 10,
"padding": 15,
}
}
key="Value3"
onPress={[Function]}
>
<Text
style={
Object {
"color": "#2389D7",
"fontSize": 17,
"textAlign": "center",
}
}
>
Label3
</Text>
</Button>
<Button
containerStyle={
Object {
"alignItems": "center",
"alignSelf": "stretch",
"borderColor": "#2389D7",
"borderRadius": 3,
"borderWidth": 1,
"marginTop": 10,
"padding": 15,
}
}
key="Value4"
onPress={[Function]}
>
<Text
style={
Object {
"color": "#2389D7",
"fontSize": 17,
"textAlign": "center",
}
}
>
Label4
</Text>
</Button>
</View>
</ScrollView>
</RNCSafeAreaView>
`;

View file

@ -0,0 +1,137 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {ShallowWrapper} from 'enzyme';
import React from 'react';
import {shallowWithIntl} from 'test/intl-test-helper';
import Preferences from '@mm-redux/constants/preferences';
import AppsFormComponent, {Props, State} from './apps_form_component';
describe('AppsForm', () => {
const baseProps: Props = {
actions: {
performLookupCall: jest.fn(),
refreshOnSelect: jest.fn(),
submit: jest.fn(),
},
call: {
context: {
app_id: 'app1',
},
path: '/create',
},
componentId: '',
form: {
title: 'Title',
footer: 'Footer',
header: 'Header',
icon: 'Icon',
submit_buttons: 'submit_buttons1',
fields: [
{
name: 'bool1',
type: 'bool',
},
{
name: 'bool2',
type: 'bool',
value: false,
},
{
name: 'bool3',
type: 'bool',
value: true,
},
{
name: 'text1',
type: 'text',
value: 'initial text',
},
{
name: 'select1',
type: 'static_select',
options: [
{label: 'Label1', value: 'Value1'},
{label: 'Label2', value: 'Value2'},
],
value: {label: 'Label1', value: 'Value1'},
},
{
name: 'submit_buttons1',
type: 'static_select',
options: [
{label: 'Label3', value: 'Value3'},
{label: 'Label4', value: 'Value4'},
],
value: null,
},
],
},
theme: Preferences.THEMES.default,
};
test('should set match snapshot', () => {
const wrapper: ShallowWrapper<Props, State, AppsFormComponent> = shallowWithIntl(
<AppsFormComponent
{...baseProps}
/>,
) as unknown as ShallowWrapper<Props, State, AppsFormComponent>;
expect(wrapper).toMatchSnapshot();
});
test('should set initial form values', () => {
const wrapper: ShallowWrapper<Props, State, AppsFormComponent> = shallowWithIntl(
<AppsFormComponent
{...baseProps}
/>,
) as unknown as ShallowWrapper<Props, State, AppsFormComponent>;
expect(wrapper.state().values).toEqual({
bool1: false,
bool2: false,
bool3: true,
text1: 'initial text',
select1: {label: 'Label1', value: 'Value1'},
submit_buttons1: null,
});
});
test('it should submit and close the modal', async () => {
const submit = jest.fn().mockResolvedValue({data: {type: 'ok'}});
const props: Props = {
...baseProps,
actions: {
...baseProps.actions,
submit,
},
};
const wrapper: ShallowWrapper<Props, State, AppsFormComponent> = shallowWithIntl(
<AppsFormComponent
{...props}
/>,
) as unknown as ShallowWrapper<Props, State, AppsFormComponent>;
const hide = jest.fn();
wrapper.instance().handleHide = hide;
await wrapper.instance().doSubmit();
expect(submit).toHaveBeenCalledWith({
values: {
bool1: false,
bool2: false,
bool3: true,
text1: 'initial text',
select1: {label: 'Label1', value: 'Value1'},
submit_buttons1: null,
},
});
expect(hide).toHaveBeenCalled();
});
});

View file

@ -7,16 +7,16 @@ import {ScrollView, Text, View} from 'react-native';
import Button from 'react-native-button';
import {EventSubscription, Navigation} from 'react-native-navigation';
import {SafeAreaView} from 'react-native-safe-area-context';
import {DoAppCallResult} from 'types/actions/apps';
import {dismissModal} from '@actions/navigation';
import Markdown from '@components/markdown';
import StatusBar from '@components/status_bar';
import {AppCallResponseTypes} from '@mm-redux/constants/apps';
import {AppCallResponseTypes, AppFieldTypes} from '@mm-redux/constants/apps';
import {AppCallRequest, AppField, AppForm, AppFormValue, AppFormValues, AppLookupResponse, AppSelectOption, FormResponseData} from '@mm-redux/types/apps';
import {DialogElement} from '@mm-redux/types/integrations';
import {Theme} from '@mm-redux/types/preferences';
import {checkDialogElementForError, checkIfErrorsMatchElements} from '@mm-redux/utils/integration_utils';
import {DoAppCallResult} from '@mm-types/actions/apps';
import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@ -31,9 +31,7 @@ export type Props = {
form: AppForm;
actions: {
submit: (submission: {
values: {
[name: string]: string;
};
values: AppFormValues;
}) => Promise<DoAppCallResult<FormResponseData>>;
performLookupCall: (field: AppField, values: AppFormValues, userInput: string) => Promise<DoAppCallResult<AppLookupResponse>>;
refreshOnSelect: (field: AppField, values: AppFormValues, value: AppFormValue) => Promise<DoAppCallResult<FormResponseData>>;
@ -42,18 +40,23 @@ export type Props = {
componentId: string;
}
type State = {
values: {[name: string]: string};
export type State = {
values: AppFormValues;
formError: string | null;
fieldErrors: {[name: string]: string};
form: AppForm;
}
const initFormValues = (form: AppForm): {[name: string]: string} => {
const values: {[name: string]: any} = {};
const initFormValues = (form: AppForm): AppFormValues => {
const values: AppFormValues = {};
if (form && form.fields) {
form.fields.forEach((f) => {
values[f.name] = f.value || null;
let defaultValue: AppFormValue = null;
if (f.type === AppFieldTypes.BOOL) {
defaultValue = false;
}
values[f.name] = f.value || defaultValue;
});
}