Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RNMobile] Remove upload options for users who lack upload permission #39769

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions packages/block-editor/src/components/media-upload/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ import { __ } from '@wordpress/i18n';
import { Picker } from '@wordpress/components';
import {
getOtherMediaOptions,
requestMediaPicker,
mediaSources,
requestMediaPicker,
} from '@wordpress/react-native-bridge';
import {
capturePhoto,
captureVideo,
globe,
image,
wordpress,
mobile,
globe,
wordpress,
} from '@wordpress/icons';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { compose } from '@wordpress/compose';
Expand Down Expand Up @@ -144,26 +144,38 @@ export class MediaUpload extends Component {
allowedTypes = [],
__experimentalOnlyMediaLibrary,
isAudioBlockMediaUploadEnabled,
canUploadMedia,
} = this.props;

return this.getAllSources()
.filter( ( source ) => {
if ( __experimentalOnlyMediaLibrary ) {
return source.mediaLibrary;
} else if (
allowedTypes.every(
( allowedType ) =>
allowedType === MEDIA_TYPE_AUDIO &&
source.types.includes( allowedType )
) &&
source.id !== URL_MEDIA_SOURCE
) {
return isAudioBlockMediaUploadEnabled === true;
}

return allowedTypes.some( ( allowedType ) =>
const sourceIsAllowed = allowedTypes.some( ( allowedType ) =>
source.types.includes( allowedType )
);
if ( ! sourceIsAllowed ) {
return false;
}

if ( ! canUploadMedia ) {
// If the user can't upload media, they can only select media
// that has already been uploaded
return source.id === mediaSources.siteMediaLibrary;
}

const onlyAudioAllowed = allowedTypes.every(
( allowedType ) =>
allowedType === MEDIA_TYPE_AUDIO &&
source.types.includes( allowedType )
);
if ( onlyAudioAllowed && source.id !== URL_MEDIA_SOURCE ) {
return isAudioBlockMediaUploadEnabled === true;
}

return true;
} )
.map( ( source ) => {
return {
Expand Down Expand Up @@ -311,6 +323,9 @@ export default compose( [
isAudioBlockMediaUploadEnabled:
select( blockEditorStore ).getSettings( 'capabilities' )
.isAudioBlockMediaUploadEnabled === true,
canUploadMedia:
select( blockEditorStore ).getSettings( 'capabilities' )
.canUploadMedia === true,
};
} ),
] )( MediaUpload );
137 changes: 90 additions & 47 deletions packages/block-editor/src/components/media-upload/test/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe( 'MediaUpload component', () => {
const wrapper = render(
<MediaUpload
allowedTypes={ [ mediaType ] }
canUploadMedia={ true }
render={ ( { open, getMediaOptions } ) => {
return (
<>
Expand All @@ -59,13 +60,9 @@ describe( 'MediaUpload component', () => {
expectOptionForMediaType( MEDIA_TYPE_AUDIO, OPTION_INSERT_FROM_URL );
} );

const expectMediaPickerForOption = (
option,
allowMultiple,
requestFunction
) => {
function openMediaPicker( requestFunction, allowMultiple, canUploadMedia ) {
requestFunction.mockImplementation(
( source, mediaTypes, multiple, callback ) => {
( _source, mediaTypes, multiple, callback ) => {
expect( mediaTypes[ 0 ] ).toEqual( MEDIA_TYPE_VIDEO );
if ( multiple ) {
callback( [ { id: MEDIA_ID, url: MEDIA_URL } ] );
Expand All @@ -82,6 +79,7 @@ describe( 'MediaUpload component', () => {
allowedTypes={ [ MEDIA_TYPE_VIDEO ] }
onSelect={ onSelect }
multiple={ allowMultiple }
canUploadMedia={ canUploadMedia }
render={ ( { open, getMediaOptions } ) => {
return (
<>
Expand All @@ -94,51 +92,96 @@ describe( 'MediaUpload component', () => {
} }
/>
);
fireEvent.press( wrapper.getByText( 'Open Picker' ) );
fireEvent.press( wrapper.getByText( option ) );
const media = { id: MEDIA_ID, url: MEDIA_URL };

expect( requestFunction ).toHaveBeenCalledTimes( 1 );

expect( onSelect ).toHaveBeenCalledTimes( 1 );
expect( onSelect ).toHaveBeenCalledWith(
allowMultiple ? [ media ] : media
);
};

it( 'can select media from device library', () => {
expectMediaPickerForOption(
'Choose from device',
false,
requestMediaPicker
);
} );
fireEvent.press( wrapper.getByText( 'Open Picker' ) );
return { onSelect, wrapper };
}

describe( 'selecting media', () => {
const expectMediaPickerForOption = (
option,
allowMultiple,
canUploadMedia,
exists
) => {
const { onSelect, wrapper } = openMediaPicker(
requestMediaPicker,
allowMultiple,
canUploadMedia
);

it( 'can select media from WP media library', () => {
expectMediaPickerForOption(
'WordPress Media Library',
false,
requestMediaPicker
);
} );
const optionInstance = wrapper.queryByText( option );
if ( exists ) {
expect( optionInstance ).toBeDefined();
fireEvent.press( optionInstance );
const media = { id: MEDIA_ID, url: MEDIA_URL };

it( 'can select media by capturing', () => {
expectMediaPickerForOption( 'Take a Video', false, requestMediaPicker );
} );
expect( requestMediaPicker ).toHaveBeenCalledTimes( 1 );

it( 'can select multiple media from device library', () => {
expectMediaPickerForOption(
'Choose from device',
true,
requestMediaPicker
);
} );
expect( onSelect ).toHaveBeenCalledTimes( 1 );
expect( onSelect ).toHaveBeenCalledWith(
allowMultiple ? [ media ] : media
);
} else {
expect( optionInstance ).toBeNull();
}
};

it( 'can select multiple media from WP media library', () => {
expectMediaPickerForOption(
'WordPress Media Library',
true,
requestMediaPicker
);
describe( 'when uploads are enabled', () => {
const expectWhenUploadsEnabled = ( option, allowMultiple ) => {
expectMediaPickerForOption( option, allowMultiple, true, true );
};

it( 'from WP media library', () => {
expectWhenUploadsEnabled( 'WordPress Media Library', true );
} );

it( 'can select media from device library', () => {
expectWhenUploadsEnabled( 'Choose from device', false );
} );

it( 'can select media by capturing', () => {
expectWhenUploadsEnabled( 'Take a Video', false );
} );

it( 'can select multiple media from device library', () => {
expectWhenUploadsEnabled( 'Choose from device', true );
} );
} );

describe( 'when uploads are disabled', () => {
const expectWhenUploadsDisabled = (
option,
allowMultiple,
exists
) => {
expectMediaPickerForOption(
option,
allowMultiple,
false,
exists
);
};

it( 'from WP media library', () => {
expectWhenUploadsDisabled(
'WordPress Media Library',
true,
true
);
} );

it( 'can select media from device library', () => {
expectWhenUploadsDisabled( 'Choose from device', false, false );
} );

it( 'can select media by capturing', () => {
expectWhenUploadsDisabled( 'Take a Video', false, false );
} );

it( 'can select multiple media from device library', () => {
expectWhenUploadsDisabled( 'Choose from device', true, false );
} );
} );
} );
} );
7 changes: 6 additions & 1 deletion packages/block-library/src/gallery/test/helpers.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,12 @@ export const initializeWithGalleryBlock = async ( {
generateGalleryBlock( numberOfItems, media, {
useLocalUrl,
} );
const screen = await initializeEditor( { initialHtml } );
const screen = await initializeEditor( {
initialHtml,
capabilities: {
canUploadMedia: true,
},
} );
const { getByA11yLabel } = screen;

const galleryBlock = getByA11yLabel( /Gallery Block\. Row 1/ );
Expand Down
4 changes: 4 additions & 0 deletions packages/react-native-bridge/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

## 1.73.0

- [**] Remove upload options for users without permission to upload media [#39769]

## 1.70.1

- [***] Fix launching video preview on Android 11+ [#38377]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data class GutenbergProps @JvmOverloads constructor(
val enableXPosts: Boolean,
val enableUnsupportedBlockEditor: Boolean,
val canEnableUnsupportedBlockEditor: Boolean,
val canUploadMedia: Boolean,
val isAudioBlockMediaUploadEnabled: Boolean,
val enableReusableBlock: Boolean,
val localeSlug: String,
Expand Down Expand Up @@ -62,7 +63,10 @@ data class GutenbergProps @JvmOverloads constructor(
putBoolean(PROP_CAPABILITIES_MEDIAFILES_COLLECTION_BLOCK, enableMediaFilesCollectionBlocks)
putBoolean(PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR, enableUnsupportedBlockEditor)
putBoolean(PROP_CAPABILITIES_CAN_ENABLE_UNSUPPORTED_BLOCK_EDITOR, canEnableUnsupportedBlockEditor)
putBoolean(PROP_CAPABILITIES_IS_AUDIO_BLOCK_MEDIA_UPLOAD_ENABLED, isAudioBlockMediaUploadEnabled)
putBoolean(PROP_CAPABILITIES_CAN_UPLOAD_MEDIA, canUploadMedia)
putBoolean(PROP_CAPABILITIES_IS_AUDIO_BLOCK_MEDIA_UPLOAD_ENABLED,
isAudioBlockMediaUploadEnabled
)
putBoolean(PROP_CAPABILITIES_REUSABLE_BLOCK, enableReusableBlock)
putBoolean(PROP_CAPABILITIES_FACEBOOK_EMBED_BLOCK, enableFacebookEmbed)
putBoolean(PROP_CAPABILITIES_INSTAGRAM_EMBED_BLOCK, enableInstagramEmbed)
Expand Down Expand Up @@ -105,6 +109,7 @@ data class GutenbergProps @JvmOverloads constructor(
const val PROP_CAPABILITIES_XPOSTS = "xposts"
const val PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR = "unsupportedBlockEditor"
const val PROP_CAPABILITIES_CAN_ENABLE_UNSUPPORTED_BLOCK_EDITOR = "canEnableUnsupportedBlockEditor"
const val PROP_CAPABILITIES_CAN_UPLOAD_MEDIA = "canUploadMedia"
const val PROP_CAPABILITIES_IS_AUDIO_BLOCK_MEDIA_UPLOAD_ENABLED = "isAudioBlockMediaUploadEnabled"
const val PROP_CAPABILITIES_REUSABLE_BLOCK = "reusableBlock"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public enum Capabilities: String {
case xposts
case unsupportedBlockEditor
case canEnableUnsupportedBlockEditor
case canUploadMedia
case isAudioBlockMediaUploadEnabled
case reusableBlock
case facebookEmbed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ protected Bundle getLaunchOptions() {
capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_XPOSTS, true);
capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR, true);
capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_REUSABLE_BLOCK, false);
capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_CAN_UPLOAD_MEDIA, true);
capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_IS_AUDIO_BLOCK_MEDIA_UPLOAD_ENABLED, true);
capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_TILED_GALLERY_BLOCK, true);
capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_FACEBOOK_EMBED_BLOCK, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ extension GutenbergViewController: GutenbergBridgeDataSource {
.canEnableUnsupportedBlockEditor: unsupportedBlockCanBeActivated,
.mediaFilesCollectionBlock: true,
.tiledGalleryBlock: true,
.canUploadMedia: true,
.isAudioBlockMediaUploadEnabled: true,
.reusableBlock: false,
.facebookEmbed: true,
Expand Down