feat: migrate test suite from PHPUnit to Pest

- Replace phpunit/phpunit with pestphp/pest ^3.0
- Drop scrutinizer/ocular (incompatible with Pest's symfony/console)
- Add tests/Pest.php with MockeryPHPUnitIntegration trait binding
- Extract namespace-level function stubs (config, route, dir) to
  tests/Overrides.php, loaded via autoload-dev files
- Convert all 5 test classes to Pest closure-based syntax:
  setUp() → beforeEach(), assertions → expect(), skip() for skipped tests
- Delete tests/TestCase.php (logic moved to Pest.php)
- Stubs (TokenStub, User) unchanged
This commit is contained in:
Joel Male
2026-02-18 10:38:20 +10:00
parent 8ec2c3cc38
commit 97c04ec693
9 changed files with 426 additions and 830 deletions
+9 -4
View File
@@ -27,9 +27,8 @@
"require-dev": { "require-dev": {
"laravel/pint": "^1.2", "laravel/pint": "^1.2",
"mockery/mockery": "^1.6", "mockery/mockery": "^1.6",
"phpunit/phpunit": "^10.5|^11.0", "pestphp/pest": "^3.0",
"psy/psysh": "^0.12", "psy/psysh": "^0.12"
"scrutinizer/ocular": "^1.9"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@@ -39,7 +38,10 @@
"autoload-dev": { "autoload-dev": {
"psr-4": { "psr-4": {
"Wearepixel\\QuickBooks\\": "tests/" "Wearepixel\\QuickBooks\\": "tests/"
} },
"files": [
"tests/Overrides.php"
]
}, },
"extra": { "extra": {
"laravel": { "laravel": {
@@ -50,6 +52,9 @@
} }
}, },
"config": { "config": {
"allow-plugins": {
"pestphp/pest-plugin": true
},
"sort-packages": true "sort-packages": true
}, },
"prefer-stable": true "prefer-stable": true
+31 -166
View File
@@ -1,35 +1,11 @@
<?php <?php
namespace Wearepixel\QuickBooks;
use Mockery;
use Mockery\Mock;
use PHPUnit\Framework\Attributes\Test;
use QuickBooksOnline\API\DataService\DataService; use QuickBooksOnline\API\DataService\DataService;
use QuickBooksOnline\API\Exception\ServiceException; use QuickBooksOnline\API\Exception\ServiceException;
use Wearepixel\QuickBooks\Client;
use Wearepixel\QuickBooks\Token;
/** beforeEach(function () {
* Class ClientTest
*/
class ClientTest extends TestCase
{
/**
* @var Client
*/
protected $client;
/**
* @var array
*/
protected $configs = [];
/**
* @var Mock
*/
protected $token_mock;
protected function setUp(): void
{
$this->configs = [ $this->configs = [
'data_service' => [ 'data_service' => [
'auth_mode' => 'oauth2', 'auth_mode' => 'oauth2',
@@ -41,28 +17,14 @@ protected function setUp(): void
]; ];
$this->token_mock = Mockery::mock(Token::class); $this->token_mock = Mockery::mock(Token::class);
$this->client = new Client($this->configs, $this->token_mock);
});
$this->client = $this->makeClient(); it('can be constructed', function () {
} expect($this->client)->toBeInstanceOf(Client::class);
});
private function makeClient($configs = null) it('returns a data service configured to request oauth token when token is empty', function () {
{
if (! is_null($configs)) {
return new Client($configs, $this->token_mock);
}
return new Client($this->configs, $this->token_mock);
}
#[Test]
public function it_can_be_constructed()
{
$this->assertInstanceOf(Client::class, $this->client);
}
#[Test]
public function it_returns_a_data_service_configured_to_request_oauth_token_when_token_is_empty()
{
$this->token_mock $this->token_mock
->shouldReceive('getAttribute') ->shouldReceive('getAttribute')
->twice() ->twice()
@@ -75,17 +37,15 @@ public function it_returns_a_data_service_configured_to_request_oauth_token_when
->with('hasValidRefreshToken') ->with('hasValidRefreshToken')
->andReturnFalse(); ->andReturnFalse();
$this->assertFalse( expect(
$this->client $this->client
->getDataService() ->getDataService()
->getServiceContext() ->getServiceContext()
->IppConfiguration->Security->isAccessTokenSet(), ->IppConfiguration->Security->isAccessTokenSet(),
); )->toBeFalse();
} });
#[Test] it('caches the data service once it is made', function () {
public function it_caches_the_data_service_once_it_is_made()
{
$this->token_mock $this->token_mock
->shouldReceive('getAttribute') ->shouldReceive('getAttribute')
->twice() ->twice()
@@ -98,13 +58,10 @@ public function it_caches_the_data_service_once_it_is_made()
->with('hasValidRefreshToken') ->with('hasValidRefreshToken')
->andReturnFalse(); ->andReturnFalse();
// TODO: Find out if this is the actual goal of this test, to make sure a DataService is received expect($this->client->getDataService())->toBeInstanceOf(DataService::class);
$this->assertEquals(DataService::class, get_class($this->client->getDataService())); });
}
#[Test] it('returns a data service with oauth token when valid access token exists', function () {
public function it_returns_a_data_service_with_oauth_token_when_valid_access_token_exist()
{
$this->token_mock $this->token_mock
->shouldReceive('getAttribute') ->shouldReceive('getAttribute')
->twice() ->twice()
@@ -129,19 +86,15 @@ public function it_returns_a_data_service_with_oauth_token_when_valid_access_tok
->with('refresh_token') ->with('refresh_token')
->andReturn('refresh_token'); ->andReturn('refresh_token');
$this->assertTrue( expect(
$this->client $this->client
->getDataService() ->getDataService()
->getServiceContext() ->getServiceContext()
->IppConfiguration->Security->isAccessTokenSet(), ->IppConfiguration->Security->isAccessTokenSet(),
); )->toBeTrue();
} });
#[Test]
public function it_returns_a_data_service_with_refreshed_token_when_access_token_expired_but_refresh_token_valid()
{
$this->expectException(ServiceException::class);
it('returns a data service with refreshed token when access token expired but refresh token valid', function () {
$this->token_mock $this->token_mock
->shouldReceive('getAttribute') ->shouldReceive('getAttribute')
->twice() ->twice()
@@ -171,112 +124,24 @@ public function it_returns_a_data_service_with_refreshed_token_when_access_token
->with('refresh_token') ->with('refresh_token')
->andReturn('refresh_token'); ->andReturn('refresh_token');
// TODO: This really needs to test that things are getting called correctly on the DataService class $this->client->getDataService();
$this->assertFalse( })->throws(ServiceException::class);
$this->client
->getDataService()
->getServiceContext()
->IppConfiguration->Security->isAccessTokenSet(),
);
}
#[Test] it('returns a report service using the data service')
public function it_returns_a_report_service_using_the_data_service() ->skip('Once we figure out how to test around the static DataService::Configure');
{
$this->markTestSkipped(
'Once we figure out how to test around the static DataService::Configure',
);
}
#[Test] it('has logging off by default')
public function it_has_logging_off_by_default() ->skip('Have to figure out how to test this with the new code in 5.x');
{
$this->markTestSkipped('Have to figure out how to test this with the new code in 5.x');
$this->token_mock it('allows logging turned on and pointed to expected file')
->shouldReceive('getAttribute') ->skip('Have to figure out how to test this with the new code in 5.x');
->once()
->with('hasValidAccessToken')
->andReturnFalse();
$this->token_mock it('returns self after deleting token', function () {
->shouldReceive('getAttribute')
->once()
->with('hasValidRefreshToken')
->andReturnFalse();
$this->assertFalse(
filter_var(
$this->client->getDataService()->getServiceContext()->IppConfiguration->Logger
->RequestLog->EnableRequestResponseLogging,
FILTER_VALIDATE_BOOLEAN,
),
);
}
#[Test]
public function it_allows_logging_turned_on_and_pointed_to_expected_file()
{
$this->markTestSkipped('Have to figure out how to test this with the new code in 5.x');
$this->client = $this->makeClient(
array_merge(
[
'logging' => [
'enabled' => true,
'location' => '/some/valid/path',
],
],
$this->configs,
),
);
$this->token_mock
->shouldReceive('getAttribute')
->once()
->with('hasValidAccessToken')
->andReturnFalse();
$this->token_mock
->shouldReceive('getAttribute')
->once()
->with('hasValidRefreshToken')
->andReturnFalse();
$this->assertTrue(
filter_var(
$this->client->getDataService()->getServiceContext()->IppConfiguration->Logger
->RequestLog->EnableRequestResponseLogging,
FILTER_VALIDATE_BOOLEAN,
),
);
$this->assertEquals(
'/some/valid/path',
$this->client->getDataService()->getServiceContext()->IppConfiguration->Logger
->RequestLog->ServiceRequestLoggingLocation,
);
}
#[Test]
public function it_returns_self_after_deleting_token()
{
$this->token_mock $this->token_mock
->shouldReceive('remove') ->shouldReceive('remove')
->once() ->once()
->withNoArgs() ->withNoArgs()
->andReturnSelf(); ->andReturnSelf();
$this->assertInstanceOf(Client::class, $this->client->deleteToken()); expect($this->client->deleteToken())->toBeInstanceOf(Client::class);
} });
}
function dir($path)
{
return $path === '/some/valid/path';
}
function route($name)
{
return $name;
}
+9 -29
View File
@@ -1,36 +1,16 @@
<?php <?php
namespace Wearepixel\QuickBooks;
use PHPUnit\Framework\Attributes\Test;
use Wearepixel\QuickBooks\Stubs\User; use Wearepixel\QuickBooks\Stubs\User;
use Wearepixel\QuickBooks\Token;
/** beforeEach(function () {
* Class HasQuickBooksTokenTest
*/
class HasQuickBooksTokenTest extends TestCase
{
/**
* @var User
*/
protected $user;
protected function setUp(): void
{
parent::setUp();
$this->user = new User; $this->user = new User;
} });
#[Test] it('can be constructed', function () {
public function it_can_be_constructed() expect($this->user)->toBeInstanceOf(User::class);
{ });
$this->assertInstanceOf(User::class, $this->user);
}
#[Test] it('has a hasOne relationship to token', function () {
public function it_has_a_has_one_relationship_to_token() expect($this->user->quickBooksToken()->getModel())->toBeInstanceOf(Token::class);
{ });
$this->assertInstanceOf(Token::class, $this->user->quickBooksToken()->getModel());
}
}
+18 -92
View File
@@ -1,7 +1,5 @@
<?php <?php
namespace Wearepixel\QuickBooks\Http\Controllers;
use Illuminate\Contracts\Routing\UrlGenerator; use Illuminate\Contracts\Routing\UrlGenerator;
use Illuminate\Contracts\View\Factory as ViewFactory; use Illuminate\Contracts\View\Factory as ViewFactory;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
@@ -9,65 +7,11 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Routing\Redirector; use Illuminate\Routing\Redirector;
use Illuminate\Session\Store; use Illuminate\Session\Store;
use Mockery;
use Mockery\Mock;
use PHPUnit\Framework\Attributes\Test;
use QuickBooksOnline\API\DataService\DataService; use QuickBooksOnline\API\DataService\DataService;
use Wearepixel\QuickBooks\Client as QuickBooks; use Wearepixel\QuickBooks\Client as QuickBooks;
use Wearepixel\QuickBooks\TestCase; use Wearepixel\QuickBooks\Http\Controllers\Controller;
/** beforeEach(function () {
* Class ControllerTest
*/
class ControllerTest extends TestCase
{
/**
* @var Controller
*/
protected $controller;
/**
* @var Mock
*/
protected $data_service_mock;
/**
* @var Mock
*/
protected $quickbooks_mock;
/**
* @var Mock
*/
protected $redirector_mock;
/**
* @var Mock
*/
protected $request_mock;
/**
* @var Mock
*/
protected $session_mock;
/**
* @var Mock
*/
protected $url_generator_mock;
/**
* @var Mock
*/
protected $view_factory_mock;
/**
* @var Mock
*/
protected $view_mock;
protected function setUp(): void
{
$this->data_service_mock = Mockery::mock(DataService::class); $this->data_service_mock = Mockery::mock(DataService::class);
$this->quickbooks_mock = Mockery::mock(QuickBooks::class); $this->quickbooks_mock = Mockery::mock(QuickBooks::class);
$this->redirector_mock = Mockery::mock(Redirector::class); $this->redirector_mock = Mockery::mock(Redirector::class);
@@ -78,24 +22,18 @@ protected function setUp(): void
$this->view_mock = Mockery::mock(View::class); $this->view_mock = Mockery::mock(View::class);
$this->controller = new Controller; $this->controller = new Controller;
} });
#[Test] it('can be constructed', function () {
public function it_can_be_constructed() expect($this->controller)->toBeInstanceOf(Controller::class);
{ });
$this->assertInstanceOf(Controller::class, $this->controller);
}
#[Test] it('shows view to disconnect if account linked', function () {
public function it_shows_view_to_connect_if_account_not_linked()
{
$this->data_service_mock $this->data_service_mock
->shouldReceive('getCompanyInfo') ->shouldReceive('getCompanyInfo')
->once() ->once()
->withNoArgs() ->withNoArgs()
->andReturn([ ->andReturn(['name' => 'Company']);
'name' => 'Company',
]);
$this->quickbooks_mock $this->quickbooks_mock
->shouldReceive('hasValidRefreshToken') ->shouldReceive('hasValidRefreshToken')
@@ -118,20 +56,13 @@ public function it_shows_view_to_connect_if_account_not_linked()
$this->view_mock $this->view_mock
->shouldReceive('with') ->shouldReceive('with')
->once() ->once()
->withArgs([ ->withArgs(['company', ['name' => 'Company']])
'company',
[
'name' => 'Company',
],
])
->andReturnSelf(); ->andReturnSelf();
$this->controller->connect($this->quickbooks_mock, $this->view_factory_mock); $this->controller->connect($this->quickbooks_mock, $this->view_factory_mock);
} });
#[Test] it('shows view to connect if account not linked', function () {
public function it_shows_view_to_disconnect_if_account_linked()
{
$this->quickbooks_mock $this->quickbooks_mock
->shouldReceive('hasValidRefreshToken') ->shouldReceive('hasValidRefreshToken')
->once() ->once()
@@ -157,11 +88,9 @@ public function it_shows_view_to_disconnect_if_account_linked()
->andReturnSelf(); ->andReturnSelf();
$this->controller->connect($this->quickbooks_mock, $this->view_factory_mock); $this->controller->connect($this->quickbooks_mock, $this->view_factory_mock);
} });
#[Test] it('disconnects from quickbooks when requested', function () {
public function it_disconnects_from_quickbooks_when_requested()
{
$this->request_mock $this->request_mock
->shouldReceive('session') ->shouldReceive('session')
->once() ->once()
@@ -188,12 +117,10 @@ public function it_disconnects_from_quickbooks_when_requested()
$this->quickbooks_mock, $this->quickbooks_mock,
); );
$this->assertInstanceOf(RedirectResponse::class, $result); expect($result)->toBeInstanceOf(RedirectResponse::class);
} });
#[Test] it('finishes connecting to quickbooks when given a valid token', function () {
public function it_finishes_connecting_to_quickbooks_when_given_a_valid_token_by_quickbooks()
{
$realmId = random_int(1, 9999); $realmId = random_int(1, 9999);
$this->quickbooks_mock $this->quickbooks_mock
@@ -241,6 +168,5 @@ public function it_finishes_connecting_to_quickbooks_when_given_a_valid_token_by
$this->url_generator_mock, $this->url_generator_mock,
); );
$this->assertInstanceOf(RedirectResponse::class, $result); expect($result)->toBeInstanceOf(RedirectResponse::class);
} });
}
+12 -61
View File
@@ -1,54 +1,13 @@
<?php <?php
namespace Wearepixel\QuickBooks\Http\Middleware;
use Illuminate\Contracts\Routing\UrlGenerator; use Illuminate\Contracts\Routing\UrlGenerator;
use Illuminate\Contracts\Session\Session; use Illuminate\Contracts\Session\Session;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Routing\Redirector; use Illuminate\Routing\Redirector;
use Mockery;
use Mockery\Mock;
use PHPUnit\Framework\Attributes\Test;
use Wearepixel\QuickBooks\Client as QuickBooks; use Wearepixel\QuickBooks\Client as QuickBooks;
use Wearepixel\QuickBooks\TestCase; use Wearepixel\QuickBooks\Http\Middleware\Filter;
/** beforeEach(function () {
* Class FilterTest
*/
class FilterTest extends TestCase
{
/**
* @var Filter
*/
protected $filter;
/**
* @var Mock
*/
protected $quickbooks_mock;
/**
* @var Mock
*/
protected $redirector_mock;
/**
* @var Mock
*/
protected $request_mock;
/**
* @var Mock
*/
protected $session_mock;
/**
* @var Mock
*/
protected $url_generator_mock;
protected function setUp(): void
{
$this->quickbooks_mock = Mockery::mock(QuickBooks::class); $this->quickbooks_mock = Mockery::mock(QuickBooks::class);
$this->redirector_mock = Mockery::mock(Redirector::class); $this->redirector_mock = Mockery::mock(Redirector::class);
$this->request_mock = Mockery::mock(Request::class); $this->request_mock = Mockery::mock(Request::class);
@@ -61,19 +20,15 @@ protected function setUp(): void
$this->session_mock, $this->session_mock,
$this->url_generator_mock, $this->url_generator_mock,
); );
} });
#[Test] it('can be constructed', function () {
public function it_can_be_constructed() expect($this->filter)->toBeInstanceOf(Filter::class);
{ });
$this->assertInstanceOf(Filter::class, $this->filter);
}
#[Test] it('passes the request to the next middleware if account linked to quickbooks', function () {
public function it_just_passes_the_request_to_the_next_middleware_if_account_linked_to_quickbooks()
{
$next_middleware = function ($request) { $next_middleware = function ($request) {
$this->assertEquals($this->request_mock, $request); expect($request)->toBe($this->request_mock);
}; };
$this->quickbooks_mock $this->quickbooks_mock
@@ -83,11 +38,9 @@ public function it_just_passes_the_request_to_the_next_middleware_if_account_lin
->andReturnTrue(); ->andReturnTrue();
$this->filter->handle($this->request_mock, $next_middleware); $this->filter->handle($this->request_mock, $next_middleware);
} });
#[Test] it('redirects to quickbooks connect route after setting intended session if account not linked', function () {
public function it_redirects_to_quickbooks_connect_route_after_setting_intended_session_if_account_not_linked()
{
$this->request_mock $this->request_mock
->shouldReceive('path') ->shouldReceive('path')
->once() ->once()
@@ -113,8 +66,7 @@ public function it_redirects_to_quickbooks_connect_route_after_setting_intended_
->andReturnSelf(); ->andReturnSelf();
$next_middleware = function ($request) { $next_middleware = function ($request) {
// If this is called, then fail test throw new RuntimeException('Next middleware should not be called');
$this->assertTrue(false);
}; };
$this->quickbooks_mock $this->quickbooks_mock
@@ -124,5 +76,4 @@ public function it_redirects_to_quickbooks_connect_route_after_setting_intended_
->andReturnFalse(); ->andReturnFalse();
$this->filter->handle($this->request_mock, $next_middleware); $this->filter->handle($this->request_mock, $next_middleware);
} });
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace Wearepixel\QuickBooks;
use Wearepixel\QuickBooks\Stubs\User;
function config(string $key): array
{
return [
'keys' => [
'foreign' => 'user_id',
'owner' => 'id',
],
'model' => User::class,
];
}
function route(string $name): string
{
return $name;
}
function dir(string $path): bool
{
return $path === '/some/valid/path';
}
+5
View File
@@ -0,0 +1,5 @@
<?php
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
pest()->use(MockeryPHPUnitIntegration::class);
-75
View File
@@ -1,75 +0,0 @@
<?php
namespace Wearepixel\QuickBooks;
use ArrayAccess;
use Countable;
use Iterator;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use Mockery\MockInterface;
use PHPUnit\Framework\TestCase as PHPUnitTestCase;
/**
* Class TestCase
*/
abstract class TestCase extends PHPUnitTestCase
{
use MockeryPHPUnitIntegration;
/**
* Helper to allow mocking of iterator classes.
*
* @link https://gist.github.com/VladaHejda/8299871
*
* @return void
*/
protected function mockArrayIterator(MockInterface $mock, array $items)
{
if ($mock instanceof ArrayAccess) {
foreach ($items as $key => $val) {
$mock
->shouldReceive('offsetGet')
->with($key)
->andReturn($val);
$mock
->shouldReceive('offsetExists')
->with($key)
->andReturn(true);
}
$mock->shouldReceive('offsetExists')->andReturn(false);
}
if ($mock instanceof Iterator) {
$counter = 0;
$mock->shouldReceive('rewind')->andReturnUsing(function () use (&$counter) {
$counter = 0;
});
$vals = array_values($items);
$keys = array_values(array_keys($items));
$mock->shouldReceive('valid')->andReturnUsing(function () use (&$counter, $vals) {
return isset($vals[$counter]);
});
$mock->shouldReceive('current')->andReturnUsing(function () use (&$counter, $vals) {
return $vals[$counter];
});
$mock->shouldReceive('key')->andReturnUsing(function () use (&$counter, $keys) {
return $keys[$counter];
});
$mock->shouldReceive('next')->andReturnUsing(function () use (&$counter) {
$counter++;
});
}
if ($mock instanceof Countable) {
$mock->shouldReceive('count')->andReturn(count($items));
}
}
}
+51 -138
View File
@@ -1,163 +1,90 @@
<?php <?php
namespace Wearepixel\QuickBooks;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasOne;
use Mockery;
use PHPUnit\Framework\Attributes\Test;
use QuickBooksOnline\API\Core\OAuth\OAuth2\OAuth2AccessToken;
use Wearepixel\QuickBooks\Stubs\TokenStub; use Wearepixel\QuickBooks\Stubs\TokenStub;
use Wearepixel\QuickBooks\Stubs\User; use Wearepixel\QuickBooks\Stubs\User;
use Wearepixel\QuickBooks\Token;
/** beforeEach(function () {
* Class TokenTest
*/
class TokenTest extends TestCase
{
/**
* @var Token
*/
protected $token;
protected function setUp(): void
{
$this->token = new TokenStub; $this->token = new TokenStub;
} });
#[Test] it('can be constructed', function () {
public function it_can_be_constructed() expect($this->token)->toBeInstanceOf(Token::class);
{ });
$this->assertInstanceOf(Token::class, $this->token);
}
#[Test] it('has accessor for valid access token', function () {
public function it_has_accessor_for_valid_access_token() expect($this->token->getHasValidAccessTokenAttribute())->not->toBeNull();
{ });
$this->assertNotNull($this->token->getHasValidAccessTokenAttribute());
}
#[Test] it('has accessor for valid refresh token', function () {
public function it_has_accessor_for_valid_refresh_token() expect($this->token->getHasValidRefreshTokenAttribute())->not->toBeNull();
{ });
$this->assertNotNull($this->token->getHasValidRefreshTokenAttribute());
}
#[Test] it('knows that the access token expires at has to be valid', function () {
public function it_knows_that_the_access_token_expires_at_has_to_be_valid() expect($this->token->getHasValidAccessTokenAttribute())->toBeFalse();
{ });
$this->assertFalse($this->token->getHasValidAccessTokenAttribute());
}
#[Test] it('knows that the refresh token expires at has to be valid', function () {
public function it_knows_that_the_refresh_token_expires_at_has_to_be_valid() expect($this->token->getHasValidRefreshTokenAttribute())->toBeFalse();
{ });
$this->assertFalse($this->token->getHasValidRefreshTokenAttribute());
}
#[Test] it('knows if access token expires at is less than now it is not expired', function () {
public function it_know_if_access_token_expires_at_is_less_than_now_it_is_not_expired() Carbon::setTestNow(Carbon::now());
{
$now = Carbon::now();
Carbon::setTestNow($now);
$this->token->access_token_expires_at = Carbon::now()->addSecond(); $this->token->access_token_expires_at = Carbon::now()->addSecond();
$this->assertTrue($this->token->getHasValidAccessTokenAttribute()); expect($this->token->getHasValidAccessTokenAttribute())->toBeTrue();
} });
#[Test] it('knows if refresh token expires at is less than now it is not expired', function () {
public function it_know_if_refresh_token_expires_at_is_less_than_now_it_is_not_expired() Carbon::setTestNow(Carbon::now());
{
$now = Carbon::now();
Carbon::setTestNow($now);
$this->token->refresh_token_expires_at = Carbon::now()->addSecond(); $this->token->refresh_token_expires_at = Carbon::now()->addSecond();
$this->assertTrue($this->token->getHasValidRefreshTokenAttribute()); expect($this->token->getHasValidRefreshTokenAttribute())->toBeTrue();
} });
#[Test] it('knows if access token expires at is greater than or equal to now it is expired', function () {
public function it_know_if_access_token_expires_at_is_greater_than_or_equal_to_now_it_is_expired() Carbon::setTestNow(Carbon::now());
{
$now = Carbon::now();
Carbon::setTestNow($now);
$this->token->access_token_expires_at = Carbon::now(); $this->token->access_token_expires_at = Carbon::now();
expect($this->token->getHasValidAccessTokenAttribute())->toBeFalse();
$this->assertFalse($this->token->getHasValidAccessTokenAttribute());
$this->token->access_token_expires_at->subSecond(); $this->token->access_token_expires_at->subSecond();
expect($this->token->getHasValidAccessTokenAttribute())->toBeFalse();
});
$this->assertFalse($this->token->getHasValidAccessTokenAttribute()); it('knows if refresh token expires at is greater than or equal to now it is expired', function () {
} Carbon::setTestNow(Carbon::now());
#[Test]
public function it_know_if_refresh_token_expires_at_is_greater_than_or_equal_to_now_it_is_expired()
{
$now = Carbon::now();
Carbon::setTestNow($now);
$this->token->refresh_token_expires_at = Carbon::now(); $this->token->refresh_token_expires_at = Carbon::now();
expect($this->token->getHasValidRefreshTokenAttribute())->toBeFalse();
$this->assertFalse($this->token->getHasValidRefreshTokenAttribute());
$this->token->refresh_token_expires_at->subSecond(); $this->token->refresh_token_expires_at->subSecond();
expect($this->token->getHasValidRefreshTokenAttribute())->toBeFalse();
});
$this->assertFalse($this->token->getHasValidRefreshTokenAttribute()); it('stores the oauth token parts in expected properties', function () {
} $oauth_token_mock = Mockery::mock(QuickBooksOnline\API\Core\OAuth\OAuth2\OAuth2AccessToken::class);
#[Test] $oauth_token_mock->shouldReceive('getAccessToken')->once()->withNoArgs()->andReturn('access_token');
public function it_stores_the_oauth_token_parts_in_expected_properties() $oauth_token_mock->shouldReceive('getAccessTokenExpiresAt')->once()->withNoArgs()->andReturn('now');
{ $oauth_token_mock->shouldReceive('getRealmID')->once()->withNoArgs()->andReturn('realm_id');
$oauth_token_mock = Mockery::mock(OAuth2AccessToken::class); $oauth_token_mock->shouldReceive('getRefreshToken')->once()->withNoArgs()->andReturn('refresh_token');
$oauth_token_mock->shouldReceive('getRefreshTokenExpiresAt')->once()->withNoArgs()->andReturn('now');
$oauth_token_mock
->shouldReceive('getAccessToken')
->once()
->withNoArgs()
->andReturn('access_token');
$oauth_token_mock
->shouldReceive('getAccessTokenExpiresAt')
->once()
->withNoArgs()
->andReturn('now');
$oauth_token_mock
->shouldReceive('getRealmID')
->once()
->withNoArgs()
->andReturn('realm_id');
$oauth_token_mock
->shouldReceive('getRefreshToken')
->once()
->withNoArgs()
->andReturn('refresh_token');
$oauth_token_mock
->shouldReceive('getRefreshTokenExpiresAt')
->once()
->withNoArgs()
->andReturn('now');
$this->token->parseOauthToken($oauth_token_mock); $this->token->parseOauthToken($oauth_token_mock);
} });
#[Test] it('allows itself to be deleted and returns new token', function () {
public function it_allows_itself_to_be_deleted_and_returns_new_token()
{
$this->token->user = Mockery::mock(User::class); $this->token->user = Mockery::mock(User::class);
$has_one_mock = Mockery::mock(HasOne::class); $has_one_mock = Mockery::mock(HasOne::class);
$token_mock = Mockery::mock(Token::class); $token_mock = Mockery::mock(Token::class);
$has_one_mock $has_one_mock->shouldReceive('make')->once()->withNoArgs()->andReturn($token_mock);
->shouldReceive('make')
->once()
->withNoArgs()
->andReturn($token_mock);
$this->token->user $this->token->user
->shouldReceive('quickBooksToken') ->shouldReceive('quickBooksToken')
@@ -167,23 +94,9 @@ public function it_allows_itself_to_be_deleted_and_returns_new_token()
$this->token->user->id = 1; $this->token->user->id = 1;
$this->assertEquals($token_mock, $this->token->remove()); expect($this->token->remove())->toBe($token_mock);
} });
#[Test] it('gets related user model from configuration', function () {
public function it_get_related_user_model_from_configuration() expect($this->token->user()->getModel())->toBeInstanceOf(User::class);
{ });
$this->assertInstanceOf(User::class, $this->token->user()->getModel());
}
}
function config($key)
{
return [
'keys' => [
'foreign' => 'user_id',
'owner' => 'id',
],
'model' => User::class,
];
}