Skip to content

Commit

Permalink
Add DatasourceCrud tests (#45)
Browse files Browse the repository at this point in the history
* Add DatasourceCrud tests

* ayo

* lint

* fix this

* This too

* Bleh

* Better here

* Split valid and invalids

* And lint

* maybe
  • Loading branch information
mhsdef authored Sep 13, 2024
1 parent d1d9d2c commit 8526923
Show file tree
Hide file tree
Showing 4 changed files with 374 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class GoogleServiceAccountKey {
* @param array $raw_service_account The raw service account data to validate.
* @return true|WP_Error Returns true if validation passes, or a WP_Error array if validation fails.
*/
public static function validate( array $raw_service_account_key ): WP_Error|true {
public static function validate( array $raw_service_account_key ): WP_Error|bool {
if ( ! isset( $raw_service_account_key['type'] ) ) {
return new WP_Error( 'missing_type', __( 'type is required', 'remote-data-blocks' ) );
}
Expand Down
18 changes: 7 additions & 11 deletions inc/rest/datasource-crud/datasource-crud.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ class DatasourceCRUD {
const CONFIG_OPTION_NAME = 'remote_data_blocks_config';
const DATA_SOURCE_TYPES = [ 'airtable', 'shopify', 'google-sheets' ];

public static function is_uuid4( string $maybe_uuid ) {
return preg_match( '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/', $maybe_uuid );
}

/**
* Validate the slug to verify
* - is not empty
Expand All @@ -23,7 +19,7 @@ public static function is_uuid4( string $maybe_uuid ) {
* @param string [$uuid] The UUID of the data source to exclude from the check.
* @return WP_Error|true Returns true if the slug is valid, or a WP_Error object if not.
*/
public static function validate_slug( string $slug, string $uuid = '' ): WP_Error|true {
public static function validate_slug( string $slug, string $uuid = '' ): WP_Error|bool {
if ( empty( $slug ) ) {
return new WP_Error( 'missing_slug', __( 'Missing slug.', 'remote-data-blocks' ) );
}
Expand All @@ -48,7 +44,7 @@ public static function validate_slug( string $slug, string $uuid = '' ): WP_Erro
return true;
}

private static function validate_airtable_source( $source ) {
public static function validate_airtable_source( $source ) {
if ( empty( $source->token ) ) {
return new WP_Error( 'missing_token', __( 'Missing token.', 'remote-data-blocks' ) );
}
Expand Down Expand Up @@ -142,8 +138,8 @@ public static function validate_source( $source ) {
return new WP_Error( 'missing_uuid', __( 'Missing UUID.', 'remote-data-blocks' ) );
}

if ( ! self::is_uuid4( $source->uuid ) ) {

if ( ! wp_is_uuid( $source->uuid ) ) {
return new WP_Error( 'invalid_uuid', __( 'Invalid UUID.', 'remote-data-blocks' ) );
}

Expand Down Expand Up @@ -203,9 +199,9 @@ public static function get_data_sources( string $service = '' ) {
$data_sources = self::get_config();

if ( $service ) {
return array_filter( $data_sources, function ( $config ) use ( $service ) {
return array_values( array_filter($data_sources, function ( $config ) use ( $service ) {
return $config->service === $service;
} );
} ) );
}

return $data_sources;
Expand Down Expand Up @@ -235,7 +231,7 @@ public static function update_item_by_uuid( string $uuid, $new_item ) {
return $new_item;
}

public static function delete_item_by_uuid( $uuid ) {
public static function delete_item_by_uuid( string $uuid ): WP_Error|bool {
$data_sources = self::get_data_sources();
$data_sources = array_filter( $data_sources, function ( $source ) use ( $uuid ) {
return $source->uuid !== $uuid;
Expand Down
299 changes: 299 additions & 0 deletions tests/inc/rest/DatasourceCrudTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
<?php

use PHPUnit\Framework\TestCase;
use RemoteDataBlocks\REST\DatasourceCRUD;
use RemoteDataBlocks\Config\Auth\GoogleServiceAccountKey;

class DatasourceCrudTest extends TestCase {
protected function tearDown(): void {
clear_mocked_options();
}

public function test_validate_slug_with_valid_input() {
$this->assertTrue( DatasourceCRUD::validate_slug( 'valid-slug' ) );
}

public function test_validate_slug_with_invalid_input() {
$this->assertInstanceOf( WP_Error::class, DatasourceCRUD::validate_slug( '' ) );
$this->assertInstanceOf( WP_Error::class, DatasourceCRUD::validate_slug( 'INVALID_SLUG' ) );
}

public function test_validate_airtable_source_with_valid_input() {
$valid_source = (object) [
'uuid' => '123e4567-e89b-12d3-a456-426614174000',
'token' => 'valid_token',
'service' => 'airtable',
'base' => [
'id' => 'base_id',
'name' => 'Base Name',
],
'table' => [
'id' => 'table_id',
'name' => 'Table Name',
],
'slug' => 'valid-slug',
];

$result = DatasourceCRUD::validate_airtable_source( $valid_source );
$this->assertIsObject( $result );
$this->assertEquals( $valid_source->uuid, $result->uuid );
}

public function test_validate_airtable_source_with_invalid_input() {
$invalid_source = (object) [
'uuid' => '123e4567-e89b-12d3-a456-426614174000',
'service' => 'airtable',
'slug' => 'valid-slug',
];

$this->assertInstanceOf( WP_Error::class, DatasourceCRUD::validate_airtable_source( $invalid_source ) );
}

public function test_validate_shopify_source_with_valid_input() {
$valid_source = (object) [
'uuid' => '123e4567-e89b-12d3-a456-426614174000',
'token' => 'valid_token',
'service' => 'shopify',
'store' => 'mystore.myshopify.com',
'slug' => 'valid-slug',
];

$result = DatasourceCRUD::validate_shopify_source( $valid_source );
$this->assertIsObject( $result );
$this->assertEquals( $valid_source->uuid, $result->uuid );
}

public function test_validate_shopify_source_with_invalid_input() {
$invalid_source = (object) [
'uuid' => '123e4567-e89b-12d3-a456-426614174000',
'service' => 'shopify',
'slug' => 'valid-slug',
];

$this->assertInstanceOf( WP_Error::class, DatasourceCRUD::validate_shopify_source( $invalid_source ) );
}

public function test_validate_google_sheets_source_with_valid_input() {
$valid_credentials = [
'type' => 'service_account',
'project_id' => 'test-project',
'private_key_id' => '1234567890abcdef',
'private_key' => '-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7/jHh2Wo0zkA5\n-----END PRIVATE KEY-----\n',
'client_email' => '[email protected]',
'client_id' => '123456789012345678901',
'auth_uri' => 'https://accounts.google.com/o/oauth2/auth',
'token_uri' => 'https://oauth2.googleapis.com/token',
'auth_provider_x509_cert_url' => 'https://www.googleapis.com/oauth2/v1/certs',
'client_x509_cert_url' => 'https://www.googleapis.com/robot/v1/metadata/x509/test%40test-project.iam.gserviceaccount.com',
'universe_domain' => 'googleapis.com',
];

$valid_source = (object) [
'uuid' => '123e4567-e89b-12d3-a456-426614174000',
'service' => 'google-sheets',
'credentials' => $valid_credentials,
'spreadsheet' => [
'id' => 'spreadsheet_id',
'name' => 'Spreadsheet Name',
],
'sheet' => [
'id' => 0,
'name' => 'Sheet Name',
],
'slug' => 'valid-slug',
];

$result = DatasourceCRUD::validate_google_sheets_source( $valid_source );
$this->assertIsObject( $result );
$this->assertEquals( $valid_source->uuid, $result->uuid );
}

public function test_validate_google_sheets_source_with_invalid_input() {
$invalid_source = (object) [
'uuid' => '123e4567-e89b-12d3-a456-426614174000',
'service' => 'google-sheets',
'credentials' => [],
'slug' => 'valid-slug',
];

$this->assertInstanceOf( WP_Error::class, DatasourceCRUD::validate_google_sheets_source( $invalid_source ) );
}

public function test_validate_source_with_valid_input() {
$valid_source = (object) [
'uuid' => '123e4567-e89b-12d3-a456-426614174000',
'token' => 'valid_token',
'service' => 'airtable',
'base' => [
'id' => 'base_id',
'name' => 'Base Name',
],
'table' => [
'id' => 'table_id',
'name' => 'Table Name',
],
'slug' => 'valid-slug',
];

$result = DatasourceCRUD::validate_source( $valid_source );
$this->assertIsObject( $result );
$this->assertObjectHasProperty( 'uuid', $result );
$this->assertEquals( $valid_source->uuid, $result->uuid );
}

public function test_validate_source_with_invalid_input() {
$invalid_source = (object) [
'uuid' => 'invalid-uuid',
'service' => 'unsupported',
'slug' => 'valid-slug',
];

$result = DatasourceCRUD::validate_source( $invalid_source );
$this->assertInstanceOf( WP_Error::class, $result );
$this->assertEquals( 'invalid_uuid', $result->get_error_code() );
}

public function test_register_new_data_source_with_valid_input() {
$valid_source = [
'token' => 'valid_token',
'service' => 'airtable',
'base' => [
'id' => 'base_id',
'name' => 'Base Name',
],
'table' => [
'id' => 'table_id',
'name' => 'Table Name',
],
'slug' => 'valid-slug',
];

$result = DatasourceCRUD::register_new_data_source( $valid_source );
$this->assertIsObject( $result );
$this->assertTrue( wp_is_uuid( $result->uuid ) );
}

public function test_register_new_data_source_with_invalid_input() {
$invalid_source = [
'service' => 'unsupported',
'slug' => 'valid-slug',
];

$this->assertInstanceOf( WP_Error::class, DatasourceCRUD::register_new_data_source( $invalid_source ) );
}

public function test_get_data_sources() {
$source1 = DatasourceCRUD::register_new_data_source( [
'token' => 'token1',
'service' => 'airtable',
'base' => [
'id' => 'base_id1',
'name' => 'Base Name 1',
],
'table' => [
'id' => 'table_id1',
'name' => 'Table Name 1',
],
'slug' => 'source-1',
] );

$source2 = DatasourceCRUD::register_new_data_source( [
'token' => 'token2',
'service' => 'shopify',
'store' => 'mystore.myshopify.com',
'slug' => 'source-2',
] );

set_mocked_option( DatasourceCRUD::CONFIG_OPTION_NAME, [
$source1,
$source2,
] );

$all_sources = DatasourceCRUD::get_data_sources();
$this->assertCount( 2, $all_sources );

$airtable_sources = DatasourceCRUD::get_data_sources( 'airtable' );
$this->assertCount( 1, $airtable_sources );
$this->assertEquals( 'source-1', $airtable_sources[0]->slug );

$shopify_sources = DatasourceCRUD::get_data_sources( 'shopify' );
$this->assertCount( 1, $shopify_sources );
$this->assertEquals( 'source-2', $shopify_sources[0]->slug );
}

public function test_get_item_by_uuid_with_valid_uuid() {
$source = DatasourceCRUD::register_new_data_source( [
'token' => 'token1',
'service' => 'airtable',
'base' => [
'id' => 'base_id1',
'name' => 'Base Name 1',
],
'table' => [
'id' => 'table_id1',
'name' => 'Table Name 1',
],
'slug' => 'source-1',
] );

$retrieved_source = DatasourceCRUD::get_item_by_uuid( DatasourceCRUD::get_data_sources(), $source->uuid );
$this->assertEquals( $source, $retrieved_source );
}

public function test_get_item_by_uuid_with_invalid_uuid() {
$non_existent = DatasourceCRUD::get_item_by_uuid( DatasourceCRUD::get_data_sources(), 'non-existent-uuid' );
$this->assertFalse( $non_existent );
}

public function test_update_item_by_uuid_with_valid_uuid() {
$source = DatasourceCRUD::register_new_data_source( [
'token' => 'token1',
'service' => 'airtable',
'base' => [
'id' => 'base_id1',
'name' => 'Base Name 1',
],
'table' => [
'id' => 'table_id1',
'name' => 'Table Name 1',
],
'slug' => 'source-1',
] );

$updated_source = DatasourceCRUD::update_item_by_uuid( $source->uuid, [
'token' => 'updated_token',
'slug' => 'updated-slug',
] );

$this->assertIsObject( $updated_source );
$this->assertEquals( 'updated_token', $updated_source->token );
$this->assertEquals( 'updated-slug', $updated_source->slug );
}

public function test_update_item_by_uuid_with_invalid_uuid() {
$non_existent = DatasourceCRUD::update_item_by_uuid( 'non-existent-uuid', [ 'token' => 'new_token' ] );
$this->assertInstanceOf( WP_Error::class, $non_existent );
}

public function test_delete_item_by_uuid() {
$source = DatasourceCRUD::register_new_data_source( [
'token' => 'token1',
'service' => 'airtable',
'base' => [
'id' => 'base_id1',
'name' => 'Base Name 1',
],
'table' => [
'id' => 'table_id1',
'name' => 'Table Name 1',
],
'slug' => 'source-1',
] );

$result = DatasourceCRUD::delete_item_by_uuid( $source->uuid );
$this->assertTrue( $result );

$deleted_source = DatasourceCRUD::get_item_by_uuid( DatasourceCRUD::get_data_sources(), $source->uuid );
$this->assertFalse( $deleted_source );
}
}
Loading

0 comments on commit 8526923

Please sign in to comment.