diff --git a/packages/block-library/src/audio/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/audio/test/__snapshots__/transforms.native.js.snap
new file mode 100644
index 00000000000000..fab0ae01a55f8c
--- /dev/null
+++ b/packages/block-library/src/audio/test/__snapshots__/transforms.native.js.snap
@@ -0,0 +1,25 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Audio block transformations to Columns block 1`] = `
+"
+
+"
+`;
+
+exports[`Audio block transformations to File block 1`] = `
+"
+
+"
+`;
+
+exports[`Audio block transformations to Group block 1`] = `
+"
+
+"
+`;
diff --git a/packages/block-library/src/audio/test/transforms.native.js b/packages/block-library/src/audio/test/transforms.native.js
new file mode 100644
index 00000000000000..0ed1a1f6306fbf
--- /dev/null
+++ b/packages/block-library/src/audio/test/transforms.native.js
@@ -0,0 +1,42 @@
+/**
+ * External dependencies
+ */
+import {
+ getEditorHtml,
+ initializeEditor,
+ setupCoreBlocks,
+ transformBlock,
+ getBlockTransformOptions,
+} from 'test/helpers';
+
+const block = 'Audio';
+const initialHtml = `
+
+
+`;
+
+const tranformsWithInnerBlocks = [ 'Columns', 'Group' ];
+const blockTransforms = [ 'File', ...tranformsWithInnerBlocks ];
+
+setupCoreBlocks();
+
+describe( `${ block } block transformations`, () => {
+ test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => {
+ const screen = await initializeEditor( { initialHtml } );
+ const newBlock = await transformBlock( screen, block, blockTransform, {
+ isMediaBlock: false,
+ hasInnerBlocks: tranformsWithInnerBlocks.includes( blockTransform ),
+ } );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ } );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( { initialHtml } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength( blockTransforms.length );
+ } );
+} );
diff --git a/packages/block-library/src/cover/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/cover/test/__snapshots__/transforms.native.js.snap
new file mode 100644
index 00000000000000..252edf24172231
--- /dev/null
+++ b/packages/block-library/src/cover/test/__snapshots__/transforms.native.js.snap
@@ -0,0 +1,73 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Cover block transformations with Image to Columns block 1`] = `
+"
+
+"
+`;
+
+exports[`Cover block transformations with Image to Group block 1`] = `
+"
+
+"
+`;
+
+exports[`Cover block transformations with Image to Image block 1`] = `
+"
+
+"
+`;
+
+exports[`Cover block transformations with Image to Media & Text block 1`] = `
+"
+
+"
+`;
+
+exports[`Cover block transformations with Video to Columns block 1`] = `
+"
+
+"
+`;
+
+exports[`Cover block transformations with Video to Group block 1`] = `
+"
+
+"
+`;
+
+exports[`Cover block transformations with Video to Media & Text block 1`] = `
+"
+
+"
+`;
+
+exports[`Cover block transformations with Video to Video block 1`] = `
+"
+
+"
+`;
diff --git a/packages/block-library/src/cover/test/transforms.native.js b/packages/block-library/src/cover/test/transforms.native.js
new file mode 100644
index 00000000000000..ad3a951a7e9f6d
--- /dev/null
+++ b/packages/block-library/src/cover/test/transforms.native.js
@@ -0,0 +1,112 @@
+/**
+ * External dependencies
+ */
+import {
+ getEditorHtml,
+ initializeEditor,
+ setupCoreBlocks,
+ transformBlock,
+ getBlockTransformOptions,
+} from 'test/helpers';
+
+const block = 'Cover';
+const initialHtmlWithImage = `
+
+
+`;
+const initialHtmlWithVideo = `
+
+
+`;
+
+const tranformsWithInnerBlocks = [ 'Columns', 'Group' ];
+const blockTransformsWithImage = [
+ 'Image',
+ 'Media & Text',
+ ...tranformsWithInnerBlocks,
+];
+const blockTransformsWithVideo = [
+ 'Video',
+ 'Media & Text',
+ ...tranformsWithInnerBlocks,
+];
+
+setupCoreBlocks();
+
+describe( `${ block } block transformations`, () => {
+ describe( 'with Image', () => {
+ test.each( blockTransformsWithImage )(
+ 'to %s block',
+ async ( blockTransform ) => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithImage,
+ } );
+ const newBlock = await transformBlock(
+ screen,
+ block,
+ blockTransform,
+ {
+ isMediaBlock: true,
+ hasInnerBlocks:
+ tranformsWithInnerBlocks.includes( blockTransform ),
+ }
+ );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ }
+ );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithImage,
+ } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength(
+ blockTransformsWithImage.length
+ );
+ } );
+ } );
+
+ describe( 'with Video', () => {
+ test.each( blockTransformsWithVideo )(
+ 'to %s block',
+ async ( blockTransform ) => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithVideo,
+ } );
+ const newBlock = await transformBlock(
+ screen,
+ block,
+ blockTransform,
+ {
+ isMediaBlock: true,
+ hasInnerBlocks:
+ tranformsWithInnerBlocks.includes( blockTransform ),
+ }
+ );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ }
+ );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithVideo,
+ } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength(
+ blockTransformsWithVideo.length
+ );
+ } );
+ } );
+} );
diff --git a/packages/block-library/src/file/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/file/test/__snapshots__/transforms.native.js.snap
new file mode 100644
index 00000000000000..a9b6d4d57037d3
--- /dev/null
+++ b/packages/block-library/src/file/test/__snapshots__/transforms.native.js.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`File block transformations to Columns block 1`] = `
+"
+
+"
+`;
+
+exports[`File block transformations to Group block 1`] = `
+"
+
+"
+`;
diff --git a/packages/block-library/src/file/test/transforms.native.js b/packages/block-library/src/file/test/transforms.native.js
new file mode 100644
index 00000000000000..efaa507348c1cb
--- /dev/null
+++ b/packages/block-library/src/file/test/transforms.native.js
@@ -0,0 +1,42 @@
+/**
+ * External dependencies
+ */
+import {
+ getEditorHtml,
+ initializeEditor,
+ setupCoreBlocks,
+ transformBlock,
+ getBlockTransformOptions,
+} from 'test/helpers';
+
+const block = 'File';
+const initialHtml = `
+
+
+`;
+
+const tranformsWithInnerBlocks = [ 'Columns', 'Group' ];
+const blockTransforms = [ ...tranformsWithInnerBlocks ];
+
+setupCoreBlocks();
+
+describe( `${ block } block transformations`, () => {
+ test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => {
+ const screen = await initializeEditor( { initialHtml } );
+ const newBlock = await transformBlock( screen, block, blockTransform, {
+ isMediaBlock: false,
+ hasInnerBlocks: tranformsWithInnerBlocks.includes( blockTransform ),
+ } );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ } );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( { initialHtml } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength( blockTransforms.length );
+ } );
+} );
diff --git a/packages/block-library/src/gallery/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/gallery/test/__snapshots__/transforms.native.js.snap
new file mode 100644
index 00000000000000..5c9c04e137dea4
--- /dev/null
+++ b/packages/block-library/src/gallery/test/__snapshots__/transforms.native.js.snap
@@ -0,0 +1,53 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Gallery block transformations to Columns block 1`] = `
+"
+
+
+
+
Paragraph
+
+
+
+
Heading
+
+
+
+
Subheading
+
+
+
+"
+`;
+
+exports[`Gallery block transformations to Group block 1`] = `
+"
+
+
+
Paragraph
+
+
+
+
Heading
+
+
+
+
Subheading
+
+
+"
+`;
+
+exports[`Gallery block transformations to Image block 1`] = `
+"
+
Paragraph
+
+
+
+
Heading
+
+
+
+
Subheading
+"
+`;
diff --git a/packages/block-library/src/gallery/test/transforms.native.js b/packages/block-library/src/gallery/test/transforms.native.js
new file mode 100644
index 00000000000000..d155c1bc01064d
--- /dev/null
+++ b/packages/block-library/src/gallery/test/transforms.native.js
@@ -0,0 +1,52 @@
+/**
+ * External dependencies
+ */
+import {
+ getEditorHtml,
+ initializeEditor,
+ setupCoreBlocks,
+ transformBlock,
+ getBlockTransformOptions,
+} from 'test/helpers';
+
+const block = 'Gallery';
+const initialHtml = `
+
+
+
Paragraph
+
+
+
+
Heading
+
+
+
+
Subheading
+
+`;
+
+const tranformsWithInnerBlocks = [ 'Columns', 'Group' ];
+const blockTransforms = [ 'Image', ...tranformsWithInnerBlocks ];
+
+setupCoreBlocks();
+
+describe( `${ block } block transformations`, () => {
+ test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => {
+ const screen = await initializeEditor( { initialHtml } );
+ const newBlock = await transformBlock( screen, block, blockTransform, {
+ isMediaBlock: true,
+ hasInnerBlocks: tranformsWithInnerBlocks.includes( blockTransform ),
+ } );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ } );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( { initialHtml } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength( blockTransforms.length );
+ } );
+} );
diff --git a/packages/block-library/src/image/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/image/test/__snapshots__/transforms.native.js.snap
new file mode 100644
index 00000000000000..61c8de02bd03a2
--- /dev/null
+++ b/packages/block-library/src/image/test/__snapshots__/transforms.native.js.snap
@@ -0,0 +1,49 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Image block transformations to Columns block 1`] = `
+"
+
+
+
Mountain
+
+
+"
+`;
+
+exports[`Image block transformations to Cover block 1`] = `
+"
+
+"
+`;
+
+exports[`Image block transformations to File block 1`] = `
+"
+
+"
+`;
+
+exports[`Image block transformations to Gallery block 1`] = `
+"
+
+
Mountain
+
+"
+`;
+
+exports[`Image block transformations to Group block 1`] = `
+"
+
+
Mountain
+
+"
+`;
+
+exports[`Image block transformations to Media & Text block 1`] = `
+"
+
+"
+`;
diff --git a/packages/block-library/src/image/test/transforms.native.js b/packages/block-library/src/image/test/transforms.native.js
new file mode 100644
index 00000000000000..f5b7bcdab97587
--- /dev/null
+++ b/packages/block-library/src/image/test/transforms.native.js
@@ -0,0 +1,48 @@
+/**
+ * External dependencies
+ */
+import {
+ getEditorHtml,
+ initializeEditor,
+ setupCoreBlocks,
+ transformBlock,
+ getBlockTransformOptions,
+} from 'test/helpers';
+
+const block = 'Image';
+const initialHtml = `
+
+
Mountain
+`;
+
+const tranformsWithInnerBlocks = [ 'Gallery', 'Columns', 'Group' ];
+const nonMediaTransforms = [ 'File' ];
+const blockTransforms = [
+ 'Cover',
+ 'Media & Text',
+ ...tranformsWithInnerBlocks,
+ ...nonMediaTransforms,
+];
+
+setupCoreBlocks();
+
+describe( `${ block } block transformations`, () => {
+ test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => {
+ const screen = await initializeEditor( { initialHtml } );
+ const newBlock = await transformBlock( screen, block, blockTransform, {
+ isMediaBlock: ! nonMediaTransforms.includes( blockTransform ),
+ hasInnerBlocks: tranformsWithInnerBlocks.includes( blockTransform ),
+ } );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ } );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( { initialHtml } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength( blockTransforms.length );
+ } );
+} );
diff --git a/packages/block-library/src/media-text/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/media-text/test/__snapshots__/transforms.native.js.snap
new file mode 100644
index 00000000000000..a5731d607fa318
--- /dev/null
+++ b/packages/block-library/src/media-text/test/__snapshots__/transforms.native.js.snap
@@ -0,0 +1,73 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Media & Text block transformations with Image to Columns block 1`] = `
+"
+
+"
+`;
+
+exports[`Media & Text block transformations with Image to Cover block 1`] = `
+"
+
+"
+`;
+
+exports[`Media & Text block transformations with Image to Group block 1`] = `
+"
+
+"
+`;
+
+exports[`Media & Text block transformations with Image to Image block 1`] = `
+"
+
+"
+`;
+
+exports[`Media & Text block transformations with Video to Columns block 1`] = `
+"
+
+"
+`;
+
+exports[`Media & Text block transformations with Video to Cover block 1`] = `
+"
+
+"
+`;
+
+exports[`Media & Text block transformations with Video to Group block 1`] = `
+"
+
+"
+`;
+
+exports[`Media & Text block transformations with Video to Video block 1`] = `
+"
+
+"
+`;
diff --git a/packages/block-library/src/media-text/test/transforms.native.js b/packages/block-library/src/media-text/test/transforms.native.js
new file mode 100644
index 00000000000000..10e3f08410d6e9
--- /dev/null
+++ b/packages/block-library/src/media-text/test/transforms.native.js
@@ -0,0 +1,112 @@
+/**
+ * External dependencies
+ */
+import {
+ getEditorHtml,
+ initializeEditor,
+ setupCoreBlocks,
+ transformBlock,
+ getBlockTransformOptions,
+} from 'test/helpers';
+
+const block = 'Media & Text';
+const initialHtmlWithImage = `
+
+
+`;
+const initialHtmlWithVideo = `
+
+
+`;
+
+const tranformsWithInnerBlocks = [ 'Columns', 'Group' ];
+const blockTransformsWithImage = [
+ 'Image',
+ 'Cover',
+ ...tranformsWithInnerBlocks,
+];
+const blockTransformsWithVideo = [
+ 'Video',
+ 'Cover',
+ ...tranformsWithInnerBlocks,
+];
+
+setupCoreBlocks();
+
+describe( `${ block } block transformations`, () => {
+ describe( 'with Image', () => {
+ test.each( blockTransformsWithImage )(
+ 'to %s block',
+ async ( blockTransform ) => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithImage,
+ } );
+ const newBlock = await transformBlock(
+ screen,
+ block,
+ blockTransform,
+ {
+ isMediaBlock: true,
+ hasInnerBlocks:
+ tranformsWithInnerBlocks.includes( blockTransform ),
+ }
+ );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ }
+ );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithImage,
+ } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength(
+ blockTransformsWithImage.length
+ );
+ } );
+ } );
+
+ describe( 'with Video', () => {
+ test.each( blockTransformsWithVideo )(
+ 'to %s block',
+ async ( blockTransform ) => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithVideo,
+ } );
+ const newBlock = await transformBlock(
+ screen,
+ block,
+ blockTransform,
+ {
+ isMediaBlock: true,
+ hasInnerBlocks:
+ tranformsWithInnerBlocks.includes( blockTransform ),
+ }
+ );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ }
+ );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( {
+ initialHtml: initialHtmlWithVideo,
+ } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength(
+ blockTransformsWithVideo.length
+ );
+ } );
+ } );
+} );
diff --git a/packages/block-library/src/video/test/__snapshots__/transforms.native.js.snap b/packages/block-library/src/video/test/__snapshots__/transforms.native.js.snap
new file mode 100644
index 00000000000000..7833f8bf6ff5fe
--- /dev/null
+++ b/packages/block-library/src/video/test/__snapshots__/transforms.native.js.snap
@@ -0,0 +1,41 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Video block transforms to Columns block 1`] = `
+"
+
+"
+`;
+
+exports[`Video block transforms to Cover block 1`] = `
+"
+
+"
+`;
+
+exports[`Video block transforms to File block 1`] = `
+"
+
+"
+`;
+
+exports[`Video block transforms to Group block 1`] = `
+"
+
+Cloudup video
+
+"
+`;
+
+exports[`Video block transforms to Media & Text block 1`] = `
+"
+
+"
+`;
diff --git a/packages/block-library/src/video/test/transforms.native.js b/packages/block-library/src/video/test/transforms.native.js
new file mode 100644
index 00000000000000..1655c04e2eb219
--- /dev/null
+++ b/packages/block-library/src/video/test/transforms.native.js
@@ -0,0 +1,48 @@
+/**
+ * External dependencies
+ */
+import {
+ getEditorHtml,
+ initializeEditor,
+ setupCoreBlocks,
+ transformBlock,
+ getBlockTransformOptions,
+} from 'test/helpers';
+
+const block = 'Video';
+const initialHtml = `
+
+Cloudup video
+`;
+
+const tranformsWithInnerBlocks = [ 'Columns', 'Group' ];
+const nonMediaTransforms = [ 'File' ];
+const blockTransforms = [
+ 'Cover',
+ 'Media & Text',
+ ...tranformsWithInnerBlocks,
+ ...nonMediaTransforms,
+];
+
+setupCoreBlocks();
+
+describe( `${ block } block transforms`, () => {
+ test.each( blockTransforms )( 'to %s block', async ( blockTransform ) => {
+ const screen = await initializeEditor( { initialHtml } );
+ const newBlock = await transformBlock( screen, block, blockTransform, {
+ isMediaBlock: ! nonMediaTransforms.includes( blockTransform ),
+ hasInnerBlocks: tranformsWithInnerBlocks.includes( blockTransform ),
+ } );
+ expect( newBlock ).toBeVisible();
+ expect( getEditorHtml() ).toMatchSnapshot();
+ } );
+
+ it( 'matches expected transformation options', async () => {
+ const screen = await initializeEditor( { initialHtml } );
+ const transformOptions = await getBlockTransformOptions(
+ screen,
+ block
+ );
+ expect( transformOptions ).toHaveLength( blockTransforms.length );
+ } );
+} );
diff --git a/test/native/__mocks__/styleMock.js b/test/native/__mocks__/styleMock.js
index 4d86ffd36d09f1..7fd1637e07ba75 100644
--- a/test/native/__mocks__/styleMock.js
+++ b/test/native/__mocks__/styleMock.js
@@ -175,4 +175,7 @@ module.exports = {
innerAppender: {
marginLeft: 8,
},
+ mediaAreaPadding: {
+ width: 12,
+ },
};
diff --git a/test/native/setup.js b/test/native/setup.js
index 5f1801a338985f..3b083facb5e8f8 100644
--- a/test/native/setup.js
+++ b/test/native/setup.js
@@ -132,6 +132,15 @@ jest.mock( 'react-native-svg', () => {
};
} );
+jest.mock(
+ 'react-native-video',
+ () => {
+ const { forwardRef } = require( 'react' );
+ return forwardRef( mockComponent( 'ReactNativeVideo' ) );
+ },
+ { virtual: true }
+);
+
jest.mock( 'react-native-safe-area', () => {
const addEventListener = jest.fn();
addEventListener.mockReturnValue( { remove: () => {} } );