diff --git a/.gitignore b/.gitignore
index bb41fbfd331d2ccfca2d18bb46c77a127c665223..012952ccf6c3542f9fc3a7eb89a47b82eae9ab3e 100755
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ phpunit.xml
 Thumbs.db
 wp-cli.local.yml
 node_modules/
+vendor/
 *.map
 *.sql
 *.tar.gz
diff --git a/tests/test-block-editor.php b/tests/test-block-editor.php
index 01b2bce02da895c504f059c32b69421645d2fed4..ee6c493a5e3e5152078a1f30a548fc30fccea772 100644
--- a/tests/test-block-editor.php
+++ b/tests/test-block-editor.php
@@ -5,6 +5,12 @@
  * @package WP_Revisions_Control
  */
 
+namespace WP_Revisions_Control\Tests;
+
+use WP_Revisions_Control\Block_Editor;
+use WP_UnitTestCase;
+use WP_REST_Request;
+
 /**
  * Class TestBlockEditor.
  *
@@ -17,7 +23,35 @@ class TestBlockEditor extends WP_UnitTestCase {
 	 * @covers ::action_rest_api_init()
 	 */
 	public function test_action_rest_api_init() {
-		$this->markTestIncomplete();
+		global $wp_meta_keys, $wp_rest_server;
+		$wp_meta_keys   = null;
+		$wp_rest_server = null;
+
+		$object_type    = 'post';
+		$object_subtype = 'post';
+
+		// Prevent `_doing_it_wrong()` notice from `register_rest_route()`.
+		remove_all_actions( 'rest_api_init' );
+		do_action( 'rest_api_init' );
+
+		$this->assertEmpty(
+			get_registered_meta_keys( $object_type, $object_subtype ),
+			'Failed to assert that no meta is registered at the outset.'
+		);
+
+		Block_Editor::get_instance()->action_rest_api_init();
+
+		$this->assertArrayHasKey(
+			WP_REVISIONS_CONTROL_LIMIT_META_KEY,
+			get_registered_meta_keys( $object_type, $object_subtype ),
+			'Failed to assert that meta is registered as expected.'
+		);
+
+		$this->assertArrayHasKey(
+			'/wp-revisions-control/v1/schedule/(?P<id>[\d]+)/(?P<limit_override>[\d]+)',
+			rest_get_server()->get_routes( 'wp-revisions-control/v1' ),
+			'Failed to assert that REST route is registered as expected.'
+		);
 	}
 
 	/**
@@ -26,16 +60,104 @@ class TestBlockEditor extends WP_UnitTestCase {
 	 * @covers ::rest_api_permission_callback()
 	 */
 	public function test_rest_api_permission_callback() {
-		$this->markTestIncomplete();
+		$editor  = $this->factory->user->create( array( 'role' => 'editor' ) );
+		$author  = $this->factory->user->create( array( 'role' => 'author' ) );
+		$post_id = $this->factory->post->create( array( 'post_author' => $editor ) );
+
+		$request = new WP_REST_Request();
+		$request->set_param( 'id', $post_id );
+
+		wp_set_current_user( $editor );
+
+		$this->assertTrue(
+			Block_Editor::get_instance()->rest_api_permission_callback( $request ),
+			'Failed to assert that editor can edit the post.'
+		);
+
+		wp_set_current_user( $author );
+
+		$this->assertFalse(
+			Block_Editor::get_instance()->rest_api_permission_callback( $request ),
+			'Failed to assert that another author cannot edit the post.'
+		);
+	}
+
+	/**
+	 * Test scheduling without limit override.
+	 *
+	 * @covers ::rest_api_schedule_purge()
+	 */
+	public function test_rest_api_schedule_purge_no_override() {
+		$post_id = $this->factory->post->create();
+		$request = new WP_REST_Request();
+		$request->set_param( 'id', $post_id );
+
+		_set_cron_array( [] );
+
+		$response = Block_Editor::get_instance()->rest_api_schedule_purge( $request );
+		$this->assertTrue(
+			$response->get_data(),
+			'Failed to assert that job was scheduled successfully.'
+		);
+
+		$crons = json_encode( _get_cron_array() );
+
+		$this->assertStringContainsString(
+			'wp_revisions_control_cron_purge',
+			$crons,
+			'Failed to assert that an entry exists for the expected job.'
+		);
+
+		$this->assertStringContainsString(
+			json_encode(
+				array(
+					'schedule' => false,
+					'args'     => array( $post_id, null ),
+				)
+			),
+			$crons,
+			'Failed to assert that expected arguments are set in cron.'
+		);
 	}
 
 	/**
-	 * Test scheduling.
+	 * Test scheduling with limit override.
 	 *
 	 * @covers ::rest_api_schedule_purge()
 	 */
-	public function test_rest_api_schedule_purge() {
-		$this->markTestIncomplete();
+	public function test_rest_api_schedule_purge_with_override() {
+		$post_id        = $this->factory->post->create();
+		$limit_override = 3;
+		$request        = new WP_REST_Request();
+		$request->set_param( 'id', $post_id );
+		$request->set_param( 'limit_override', $limit_override );
+
+		_set_cron_array( [] );
+
+		$response = Block_Editor::get_instance()->rest_api_schedule_purge( $request );
+		$this->assertTrue(
+			$response->get_data(),
+			'Failed to assert that job was scheduled successfully.'
+		);
+
+		$crons = json_encode( _get_cron_array() );
+
+		$this->assertStringContainsString(
+			'wp_revisions_control_cron_purge',
+			$crons,
+			'Failed to assert that an entry exists for the expected job.'
+		);
+
+		$this->assertStringContainsString(
+			json_encode(
+				array(
+					'schedule' => false,
+					'args'     => array( $post_id, $limit_override ),
+				)
+			),
+			$crons,
+			'Failed to assert that expected arguments are set in cron.'
+		);
 	}
 
 	/**
@@ -44,6 +166,20 @@ class TestBlockEditor extends WP_UnitTestCase {
 	 * @covers ::filter_is_protected_meta()
 	 */
 	public function test_filter_is_protected_meta() {
-		$this->markTestIncomplete();
+		$this->assertFalse(
+			Block_Editor::get_instance()->filter_is_protected_meta(
+				true,
+				WP_REVISIONS_CONTROL_LIMIT_META_KEY
+			),
+			'Failed to assert that limit meta key is not protected.'
+		);
+
+		$this->assertTrue(
+			Block_Editor::get_instance()->filter_is_protected_meta(
+				true,
+				'_test'
+			),
+			'Failed to assert that random key is protected.'
+		);
 	}
 }
diff --git a/tests/test-hooks.php b/tests/test-hooks.php
index 57bde02b7f0b0de77873ec5501d31e97a2933473..920c9f602fbf8cc297c49a5a17318ca0c275609d 100755
--- a/tests/test-hooks.php
+++ b/tests/test-hooks.php
@@ -5,6 +5,11 @@
  * @package WP_Revisions_Control
  */
 
+namespace WP_Revisions_Control\Tests;
+
+use WP_Revisions_Control;
+use WP_UnitTestCase;
+
 /**
  * Class TestHooks.
  */
diff --git a/tests/test-misc.php b/tests/test-misc.php
index ec01dbb7b3c39255f6d06b043616eea66432795d..fcec10ea665d3d8f6bcc070fb7c3f89a8875a156 100755
--- a/tests/test-misc.php
+++ b/tests/test-misc.php
@@ -5,6 +5,11 @@
  * @package WP_Revisions_Control
  */
 
+namespace WP_Revisions_Control\Tests;
+
+use WP_Revisions_Control;
+use WP_UnitTestCase;
+
 /**
  * Class TestMisc.
  */
diff --git a/tests/test-purges.php b/tests/test-purges.php
index e7570715622e1f09bcd3df69b072871347c37694..234dd5e5f334473be990ac5b93489041e5838497 100755
--- a/tests/test-purges.php
+++ b/tests/test-purges.php
@@ -5,6 +5,11 @@
  * @package WP_Revisions_Control
  */
 
+namespace WP_Revisions_Control\Tests;
+
+use WP_Revisions_Control;
+use WP_UnitTestCase;
+
 /**
  * Class TestPurges.
  */
diff --git a/tests/test-ui.php b/tests/test-ui.php
index f634f057e29ebe96c8d48302ce64e6e82821b645..f6f79ee286719f5c233832c2c4568ea727e0984b 100755
--- a/tests/test-ui.php
+++ b/tests/test-ui.php
@@ -5,6 +5,11 @@
  * @package WP_Revisions_Control
  */
 
+namespace WP_Revisions_Control\Tests;
+
+use WP_Revisions_Control;
+use WP_UnitTestCase;
+
 /**
  * Class TestUI.
  */