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

Add/tests for Data and Verify #81

Merged
merged 17 commits into from
Jun 19, 2024
Merged
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
3 changes: 2 additions & 1 deletion includes/API/Events.php
Original file line number Diff line number Diff line change
@@ -43,7 +43,8 @@ public function __construct( HiiveConnection $hiive, EventManager $event_manager
/**
* Registers the routes for the objects of the controller.
*
* @see register_rest_route()
* @see register_rest_route()
* @see EventManager::rest_api_init()
*/
public function register_routes() {

22 changes: 6 additions & 16 deletions includes/API/Verify.php
Original file line number Diff line number Diff line change
@@ -3,7 +3,9 @@
namespace NewfoldLabs\WP\Module\Data\API;

use NewfoldLabs\WP\Module\Data\HiiveConnection;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Request;
use WP_REST_Server;
use WP_REST_Response;

@@ -37,6 +39,7 @@ public function __construct( HiiveConnection $hiive ) {
* @since 4.7.0
*
* @see register_rest_route()
* @see HiiveConnection::rest_api_init()
*/
public function register_routes() {

@@ -53,20 +56,19 @@ public function register_routes() {
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'permission_callback' => '__return_true',
),
)
);

}

/**
* Returns a verification of the supplied connection token
*
* @since 1.0
*
* @param \WP_REST_Request $request Full details about the request.
* @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
* @param WP_REST_Request $request Full details about the request.
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_items( $request ) {
$valid = $this->hiive->verify_token( $request['token'] );
@@ -82,16 +84,4 @@ public function get_items( $request ) {

return $response;
}

/**
* No authentication required for this endpoint
*
* @since 1.0
*
* @param WP_REST_Request $request Full details about the request.
* @return true|WP_Error
*/
public function get_items_permissions_check( $request ) {
return true;
}
}
21 changes: 12 additions & 9 deletions includes/Data.php
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ public function start(): void {

// Delays our primary module setup until init
add_action( 'init', array( $this, 'init' ) );
add_action( 'rest_authentication_errors', array( $this, 'authenticate' ) );
add_filter( 'rest_authentication_errors', array( $this, 'authenticate' ) );

// If we ever get a 401 response from the Hiive API, delete the token.
add_filter(
@@ -102,22 +102,25 @@ public function init(): void {
* Authenticate incoming REST API requests.
*
* @hooked rest_authentication_errors
* @see WP_REST_Server::check_authentication()
*
* @param bool|null|\WP_Error $status
* @param bool|null|\WP_Error $errors
*
* @return bool|null|\WP_Error
* @see WP_REST_Server::check_authentication()
*
* @used-by ConnectSite::verifyToken() in Hiive.
*
*/
public function authenticate( $status ) {
public function authenticate( $errors ) {

// Make sure there wasn't a different authentication method used before this
if ( ! is_null( $status ) ) {
return $status;
if ( ! is_null( $errors ) ) {
return $errors;
}

// Make sure this is a REST API request
if ( ! defined( 'REST_REQUEST' ) || ! constant( 'REST_REQUEST' ) ) {
return $status;
return $errors;
}

// If no auth header included, bail to allow a different auth method
@@ -156,13 +159,13 @@ public function authenticate( $status ) {
}

if ( ! empty( $user ) && is_a( $user, \WP_User::class ) ) {
wp_set_current_user( $user->id );
wp_set_current_user( $user->ID );

return true;
}
}

// Don't return false, since we could be interfering with a basic auth implementation.
return null;
return $errors;
}
}
189 changes: 189 additions & 0 deletions tests/phpunit/includes/DataTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php

namespace NewfoldLabs\WP\Module\Data;

use Mockery;
use NewfoldLabs\WP\Module\Data\Listeners\Plugin;
use WP_Mock;
use WP_Mock\Tools\TestCase;
use function NewfoldLabs\WP\ModuleLoader\container;

/**
* @coversDefaultClass \NewfoldLabs\WP\Module\Data\Data
*/
class DataTest extends TestCase {

public function setUp(): void
{
parent::setUp();

WP_Mock::userFunction('wp_json_encode')
->andReturnUsing(function($input) {
return json_encode($input);
});
}

public function tearDown(): void {
parent::tearDown();

\Patchwork\restoreAll();

unset($_SERVER['HTTP_AUTHORIZATION']);
}

/**
* @covers ::authenticate
*/
public function test_authenticate()
{
$sut = new Data();

\Patchwork\redefine(
'defined',
function ( string $constant_name ) {
switch ($constant_name) {
case 'REST_REQUEST':
return true;
default:
return \Patchwork\relay(func_get_args());
}
}
);

\Patchwork\redefine(
'constant',
function ( string $constant_name ) {
switch ($constant_name) {
case 'REST_REQUEST':
return true;
default:
return \Patchwork\relay(func_get_args());
}
}
);

$_SERVER['REQUEST_METHOD'] = 'GET';

\Patchwork\redefine(
'file_get_contents',
function ( string $filename ) {
switch ($filename) {
case 'php://input':
return '';
default:
return \Patchwork\relay(func_get_args());
}
}
);

$_SERVER['HTTP_X-Timestamp'] = time();

$hiive_site_auth_token = 'abc123';

$hash = hash( 'sha256', json_encode(array(
'method' => 'GET',
'url' => 'http://', /** @see Url::getCurrentUrl() */
'body' => '',
'timestamp' => null,
// 'timestamp' => $_SERVER['HTTP_X-Timestamp'],
)));
$salt = hash( 'sha256', strrev( $hiive_site_auth_token ) );
$token = hash( 'sha256', $hash . $salt );

$_SERVER['HTTP_AUTHORIZATION'] = "Bearer $token";

WP_Mock::userFunction('get_option')
->with('nfd_data_token')
->andReturn($hiive_site_auth_token);

$user = Mockery::mock(\WP_User::class);
$user->ID = 123;

WP_Mock::userFunction('get_users')
->with(\WP_Mock\Functions::type('array'))
->andReturn(array($user));

WP_Mock::userFunction('wp_set_current_user')
->once()
->with(123);

$result = $sut->authenticate(null);

self::assertTrue($result);
}

/**
* @covers ::authenticate
*/
public function test_authenticate_returns_early_when_no_auth_header()
{

$sut = new Data();

\Patchwork\redefine(
'defined',
function ( string $constant_name ) {
switch ($constant_name) {
case 'REST_REQUEST':
return true;
default:
return \Patchwork\relay(func_get_args());
}
}
);

\Patchwork\redefine(
'constant',
function ( string $constant_name ) {
switch ($constant_name) {
case 'REST_REQUEST':
return true;
default:
return \Patchwork\relay(func_get_args());
}
}
);


$result = $sut->authenticate(null);

self::assertNull($result);

}

/**
* @covers ::authenticate
*/
public function test_authenticate_returns_early_when_not_a_rest_request()
{
$sut = new Data();

\Patchwork\redefine(
'defined',
function ( string $constant_name ) {
switch ($constant_name) {
case 'REST_REQUEST':
return false;
default:
return \Patchwork\relay(func_get_args());
}
}
);

$result = $sut->authenticate(null);

self::assertNull($result);
}

/**
* @covers ::authenticate
*/
public function test_authenticate_returns_early_when_already_authenticated()
{
$sut = new Data();

$result = $sut->authenticate(true);

self::assertTrue($result);
}
}
2 changes: 1 addition & 1 deletion tests/phpunit/includes/HiiveConnectionTest.php
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ public function setUp(): void

WP_Mock::passthruFunction('__');

WP_Mock::userFunction('wp_json_encode')->andReturn(function($input) {
WP_Mock::userFunction('wp_json_encode')->andReturnUsing(function($input) {
return json_encode($input);
});
}
Loading