diff --git a/app/components/__snapshots__/attachment_button.test.js.snap b/app/components/__snapshots__/attachment_button.test.js.snap
new file mode 100644
index 000000000..accd5a17b
--- /dev/null
+++ b/app/components/__snapshots__/attachment_button.test.js.snap
@@ -0,0 +1,28 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`AttachmentButton should match snapshot 1`] = `
+
+
+
+`;
diff --git a/app/components/__snapshots__/profile_picture_button.test.js.snap b/app/components/__snapshots__/profile_picture_button.test.js.snap
index 8f915b597..3cba2c9bd 100644
--- a/app/components/__snapshots__/profile_picture_button.test.js.snap
+++ b/app/components/__snapshots__/profile_picture_button.test.js.snap
@@ -53,5 +53,6 @@ exports[`profile_picture_button should match snapshot 1`] = `
}
}
uploadFiles={[MockFunction]}
+ validMimeTypes={Array []}
/>
`;
diff --git a/app/components/attachment_button.js b/app/components/attachment_button.js
index 4f39b0a2f..29bd3d0d0 100644
--- a/app/components/attachment_button.js
+++ b/app/components/attachment_button.js
@@ -17,6 +17,8 @@ import {DocumentPicker} from 'react-native-document-picker';
import ImagePicker from 'react-native-image-picker';
import Permissions from 'react-native-permissions';
+import {lookupMimeType} from 'mattermost-redux/utils/file_utils';
+
import {PermissionTypes} from 'app/constants';
import {changeOpacity} from 'app/utils/theme';
import {t} from 'app/utils/i18n';
@@ -27,6 +29,7 @@ export default class AttachmentButton extends PureComponent {
static propTypes = {
blurTextBox: PropTypes.func.isRequired,
browseFileTypes: PropTypes.string,
+ validMimeTypes: PropTypes.array,
canBrowseFiles: PropTypes.bool,
canBrowsePhotoLibrary: PropTypes.bool,
canBrowseVideoLibrary: PropTypes.bool,
@@ -39,6 +42,7 @@ export default class AttachmentButton extends PureComponent {
navigator: PropTypes.object.isRequired,
onShowFileMaxWarning: PropTypes.func,
onShowFileSizeWarning: PropTypes.func,
+ onShowUnsupportedMimeTypeWarning: PropTypes.func,
theme: PropTypes.object.isRequired,
uploadFiles: PropTypes.func.isRequired,
wrapper: PropTypes.bool,
@@ -47,6 +51,7 @@ export default class AttachmentButton extends PureComponent {
static defaultProps = {
browseFileTypes: Platform.OS === 'ios' ? 'public.item' : '*/*',
+ validMimeTypes: [],
canBrowseFiles: true,
canBrowsePhotoLibrary: true,
canBrowseVideoLibrary: true,
@@ -321,7 +326,14 @@ export default class AttachmentButton extends PureComponent {
file.fileName = fileInfo.filename;
}
- if (file.fileSize > this.props.maxFileSize) {
+ if (!file.type) {
+ file.type = lookupMimeType(file.fileName);
+ }
+
+ const {validMimeTypes} = this.props;
+ if (validMimeTypes.length && !validMimeTypes.includes(file.type)) {
+ this.props.onShowUnsupportedMimeTypeWarning();
+ } else if (file.fileSize > this.props.maxFileSize) {
this.props.onShowFileSizeWarning(file.fileName);
} else {
this.props.uploadFiles(files);
diff --git a/app/components/attachment_button.test.js b/app/components/attachment_button.test.js
new file mode 100644
index 000000000..e0ef3694a
--- /dev/null
+++ b/app/components/attachment_button.test.js
@@ -0,0 +1,71 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React from 'react';
+import {shallow} from 'enzyme';
+
+import Preferences from 'mattermost-redux/constants/preferences';
+
+import AttachmentButton from './attachment_button';
+
+jest.mock('react-intl');
+
+describe('AttachmentButton', () => {
+ const baseProps = {
+ theme: Preferences.THEMES.default,
+ navigator: {},
+ blurTextBox: jest.fn(),
+ maxFileSize: 10,
+ uploadFiles: jest.fn(),
+ };
+
+ test('should match snapshot', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.getElement()).toMatchSnapshot();
+ });
+
+ test('should not upload file with invalid MIME type', () => {
+ const props = {
+ ...baseProps,
+ validMimeTypes: ['image/jpeg'],
+ onShowUnsupportedMimeTypeWarning: jest.fn(),
+ };
+
+ const wrapper = shallow(
+
+ );
+
+ const file = {
+ type: 'image/gif',
+ fileSize: 10,
+ fileName: 'test',
+ };
+ wrapper.instance().uploadFiles([file]);
+ expect(props.onShowUnsupportedMimeTypeWarning).toHaveBeenCalled();
+ expect(props.uploadFiles).not.toHaveBeenCalled();
+ });
+
+ test('should upload file with valid MIME type', () => {
+ const props = {
+ ...baseProps,
+ validMimeTypes: ['image/jpeg'],
+ onShowUnsupportedMimeTypeWarning: jest.fn(),
+ };
+
+ const wrapper = shallow(
+
+ );
+
+ const file = {
+ type: 'image/jpeg',
+ fileSize: 10,
+ fileName: 'test',
+ };
+ wrapper.instance().uploadFiles([file]);
+ expect(props.onShowUnsupportedMimeTypeWarning).not.toHaveBeenCalled();
+ expect(props.uploadFiles).toHaveBeenCalled();
+ });
+});
diff --git a/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap b/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap
index c3f540b98..c2010d9ca 100644
--- a/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap
+++ b/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap
@@ -74,6 +74,7 @@ exports[`edit_profile should match snapshot 1`] = `
}
}
onShowFileSizeWarning={[Function]}
+ onShowUnsupportedMimeTypeWarning={[Function]}
removeProfileImage={[Function]}
theme={
Object {
@@ -104,6 +105,13 @@ exports[`edit_profile should match snapshot 1`] = `
}
}
uploadFiles={[Function]}
+ validMimeTypes={
+ Array [
+ "image/jpeg",
+ "image/png",
+ "image/bmp",
+ ]
+ }
wrapper={true}
>
{
+ const {formatMessage} = this.context.intl;
+ const fileTypeWarning = formatMessage({
+ id: 'mobile.file_upload.unsupportedMimeType',
+ defaultMessage: 'Only files of the following MIME type can be uploaded: {mimeTypes}',
+ }, {
+ mimeTypes: VALID_MIME_TYPES.join('\n'),
+ });
+
+ Alert.alert('', fileTypeWarning);
+ };
+
renderFirstNameSettings = () => {
const {formatMessage} = this.context.intl;
const {config, currentUser, theme} = this.props;
@@ -500,6 +517,8 @@ export default class EditProfile extends PureComponent {
uploadFiles={this.handleUploadProfileImage}
removeProfileImage={this.handleRemoveProfileImage}
onShowFileSizeWarning={this.onShowFileSizeWarning}
+ onShowUnsupportedMimeTypeWarning={this.onShowUnsupportedMimeTypeWarning}
+ validMimeTypes={VALID_MIME_TYPES}
>