Skip to content
Merged
Show file tree
Hide file tree
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
7 changes: 5 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
name: Tests

on: [push, pull_request]
on:
- push
- pull_request

jobs:
test:
runs-on: ubuntu-latest

strategy:
fail-fast: true
matrix:
php: [8.2, 8.1]
php: ['8.3', '8.4', '8.5']
stability: [lowest, highest]

name: PHP ${{ matrix.php }} - ${{ matrix.stability }} deps
Expand Down
10 changes: 6 additions & 4 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
name: Static Analysis

on: [push, pull_request]
on:
- push
- pull_request

jobs:
phpstan:
name: PHPStan (PHP ${{ matrix.php-version }})

runs-on: ubuntu-latest

strategy:
matrix:
php-version:
- '8.2'
php-version: ['8.3', '8.4', '8.5']

steps:
- name: Checkout code
Expand All @@ -27,4 +29,4 @@ jobs:
uses: ramsey/composer-install@v3

- name: Run PHPStan
run: 'vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr'
run: vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"require-dev": {
"laravel/pint": "^1.10.1",
"pestphp/pest": "^2.6.3",
"pestphp/pest": "^4.0",
"phpstan/phpstan": "^1.10.16"
},
"autoload": {
Expand Down
6 changes: 0 additions & 6 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
parameters:
paths:
- src
- tests
level: 6
ignoreErrors:
-
message: "#^Call to protected method createConfiguredMock\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#"
count: 6
path: tests/ClientTest.php
16 changes: 0 additions & 16 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,32 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="vendor/autoload.php"
backupGlobals="false"
colors="true"
processIsolation="false"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false"
>
<coverage>
<report>
<clover outputFile="build/logs/clover.xml"/>
<html outputDirectory="build/coverage"/>
<text outputFile="build/coverage.txt"/>
</report>
</coverage>

<testsuites>
<testsuite name="Spatie Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>

<logging>
<junit outputFile="build/report.junit.xml"/>
</logging>

<source>
<include>
<directory suffix=".php">src/</directory>
Expand Down
114 changes: 33 additions & 81 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@
});

it('can download a file', function () {
$expectedResponse = $this->getMockBuilder(StreamInterface::class)
->getMock();
$expectedResponse = $this->createMock(StreamInterface::class);
$expectedResponse->expects($this->once())
->method('isReadable')
->willReturn(true);
Expand All @@ -165,8 +164,7 @@
});

it('can download a folder as zip', function () {
$expectedResponse = $this->getMockBuilder(StreamInterface::class)
->getMock();
$expectedResponse = $this->createMock(StreamInterface::class);
$expectedResponse->expects($this->once())
->method('isReadable')
->willReturn(true);
Expand Down Expand Up @@ -231,8 +229,7 @@
});

it('can get a thumbnail', function () {
$expectedResponse = $this->getMockBuilder(StreamInterface::class)
->getMock();
$expectedResponse = $this->createMock(StreamInterface::class);

$mockGuzzle = $this->mockGuzzleRequest(
$expectedResponse,
Expand Down Expand Up @@ -404,38 +401,6 @@
->and($uploadSessionCursor->offset)->toBe(32);
});

it('can upload a file string chunked', function () {
$content = 'chunk0chunk1chunk2rest';
$mockClient = $this->mockChunkedUploadClient($content, 6);

expect($mockClient->uploadChunked('Homework/math/answers.txt', $content, 'add', 6))
->toBe(['name' => 'answers.txt']);
})->skip('Must fix method "mockChunkedUploadClient".');

it('can upload a file resource chunked', function () {
$content = 'chunk0chunk1chunk2rest';
$resource = fopen('php://memory', 'r+');
fwrite($resource, $content);
rewind($resource);

$mockClient = $this->mockChunkedUploadClient($content, 6);

expect($mockClient->uploadChunked('Homework/math/answers.txt', $resource, 'add', 6))
->toBe(['name' => 'answers.txt']);
})->skip('Must fix method "mockChunkedUploadClient".');

it('can upload a tiny file chunked', function () {
$content = 'smallerThenChunkSize';
$resource = fopen('php://memory', 'r+');
fwrite($resource, $content);
rewind($resource);

$mockClient = $this->mockChunkedUploadClient($content, 21);

expect($mockClient->uploadChunked('Homework/math/answers.txt', $resource, 'add', 21))
->toBe(['name' => 'answers.txt']);
})->skip('Must fix method "mockChunkedUploadClient".');

it('can finish an upload session', function () {
$mockGuzzle = $this->mockGuzzleRequest(
json_encode([
Expand Down Expand Up @@ -531,15 +496,13 @@
});

test('content endpoint request can throw exception', function () {
$mockGuzzle = $this->getMockBuilder(GuzzleClient::class)
->onlyMethods(['request'])
->getMock();
$mockGuzzle = $this->createMock(GuzzleClient::class);
$mockGuzzle->expects($this->once())
->method('request')
->willThrowException(new ClientException(
'there was an error',
$this->getMockBuilder(RequestInterface::class)->getMock(),
$this->getMockBuilder(ResponseInterface::class)->getMock(),
$this->createMock(RequestInterface::class),
$this->createMock(ResponseInterface::class),
));

$client = new Client('test_token', $mockGuzzle);
Expand All @@ -552,16 +515,14 @@
'getToken' => 'test_token',
]);

$mockGuzzle = $this->getMockBuilder(GuzzleClient::class)
->onlyMethods(['request'])
->getMock();
$mockGuzzle = $this->createMock(GuzzleClient::class);

$mockGuzzle->expects($this->exactly(2))
->method('request')
->willThrowException($e = new ClientException(
'there was an error',
$this->getMockBuilder(RequestInterface::class)->getMock(),
$this->getMockBuilder(ResponseInterface::class)->getMock(),
$this->createMock(RequestInterface::class),
$this->createMock(ResponseInterface::class),
));

$tokenProvider->expects($this->once())
Expand All @@ -575,21 +536,17 @@
})->throws(ClientException::class);

test('rpc endpoint request can throw exception with 400 status code', function () {
$mockResponse = $this->getMockBuilder(ResponseInterface::class)
->getMock();
$mockResponse->expects($this->any())
->method('getStatusCode')
->willReturn(400);
$mockResponse = $this->createConfiguredMock(ResponseInterface::class, [
'getStatusCode' => 400,
]);

$mockGuzzle = $this->getMockBuilder(GuzzleClient::class)
->onlyMethods(['request'])
->getMock();
$mockGuzzle = $this->createMock(GuzzleClient::class);

$mockGuzzle->expects($this->once())
->method('request')
->willThrowException(new ClientException(
'there was an error',
$this->getMockBuilder(RequestInterface::class)->getMock(),
$this->createMock(RequestInterface::class),
$mockResponse,
));

Expand All @@ -606,24 +563,18 @@
'error_summary' => 'Human readable error code',
];

$mockResponse = $this->getMockBuilder(ResponseInterface::class)
->getMock();
$mockResponse->expects($this->any())
->method('getStatusCode')
->willReturn(409);
$mockResponse->expects($this->any())
->method('getBody')
->willReturn($this->createStreamFromString(json_encode($body)));
$mockResponse = $this->createConfiguredMock(ResponseInterface::class, [
'getStatusCode' => 409,
'getBody' => $this->createStreamFromString(json_encode($body)),
]);

$mockGuzzle = $this->getMockBuilder(GuzzleClient::class)
->onlyMethods(['request'])
->getMock();
$mockGuzzle = $this->createMock(GuzzleClient::class);

$mockGuzzle->expects($this->once())
->method('request')
->willThrowException(new ClientException(
'there was an error',
$this->getMockBuilder(RequestInterface::class)->getMock(),
$this->createMock(RequestInterface::class),
$mockResponse,
));

Expand All @@ -649,15 +600,13 @@
'getBody' => $this->createStreamFromString(json_encode($body)),
]);

$mockGuzzle = $this->getMockBuilder(GuzzleClient::class)
->onlyMethods(['request'])
->getMock();
$mockGuzzle = $this->createMock(GuzzleClient::class);

$mockGuzzle->expects($this->exactly(2))
->method('request')
->willThrowException($e = new ClientException(
'there was an error',
$this->getMockBuilder(RequestInterface::class)->getMock(),
$this->createMock(RequestInterface::class),
$mockResponse,
));

Expand Down Expand Up @@ -697,22 +646,25 @@
'getBody' => $this->createStreamFromString(json_encode($successBody)),
]);

$mockGuzzle = $this->getMockBuilder(GuzzleClient::class)
->onlyMethods(['request'])
->getMock();
$mockGuzzle = $this->createMock(GuzzleClient::class);

$e = new ClientException(
'there was an error',
$this->getMockBuilder(RequestInterface::class)->getMock(),
$this->createMock(RequestInterface::class),
$errorResponse,
);

$callCount = 0;
$mockGuzzle->expects($this->exactly(2))
->method('request')
->willReturnOnConsecutiveCalls(
$this->throwException($e),
$successResponse,
);
->willReturnCallback(function () use (&$callCount, $e, $successResponse) {
$callCount++;
if ($callCount === 1) {
throw $e;
}

return $successResponse;
});

$tokenProvider->expects($this->once())
->method('refresh')
Expand Down
51 changes: 2 additions & 49 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
use Spatie\Dropbox\Client;
use Spatie\Dropbox\UploadSessionCursor;

abstract class TestCase extends BaseTestCase
{
Expand All @@ -18,8 +17,7 @@ abstract class TestCase extends BaseTestCase
*/
public function mockGuzzleRequest(string|StreamInterface|null $expectedResponse, string $expectedEndpoint, array $expectedParams): MockObject&GuzzleClient
{
$mockResponse = $this->getMockBuilder(ResponseInterface::class)
->getMock();
$mockResponse = $this->createMock(ResponseInterface::class);

if ($expectedResponse) {
if (is_string($expectedResponse)) {
Expand All @@ -33,9 +31,7 @@ public function mockGuzzleRequest(string|StreamInterface|null $expectedResponse,
}
}

$mockGuzzle = $this->getMockBuilder(GuzzleClient::class)
->onlyMethods(['request'])
->getMock();
$mockGuzzle = $this->createMock(GuzzleClient::class);
$mockGuzzle->expects($this->once())
->method('request')
->with('POST', $expectedEndpoint, $expectedParams)
Expand All @@ -44,49 +40,6 @@ public function mockGuzzleRequest(string|StreamInterface|null $expectedResponse,
return $mockGuzzle;
}

public function mockChunkedUploadClient(string $content, int $chunkSize): MockObject&Client
{
$chunks = str_split($content, $chunkSize);

$mockClient = $this->getMockBuilder(Client::class)
->setConstructorArgs(['test_token'])
->setMethodsExcept(['uploadChunked', 'upload'])
->getMock();

$mockClient->expects($this->once())
->method('uploadSessionStart')
->with(array_shift($chunks))
->willReturn(new UploadSessionCursor('mockedSessionId', $chunkSize));

$mockClient->expects($this->once())
->method('uploadSessionFinish')
->with('', $this->anything(), 'Homework/math/answers.txt', 'add')
->willReturn(['name' => 'answers.txt']);

$remainingChunks = count($chunks);
$offset = $chunkSize;

if ($remainingChunks) {
$withs = [];
$returns = [];

foreach ($chunks as $chunk) {
$offset += $chunkSize;
$withs[] = [$chunk, $this->anything()];
$returns[] = new UploadSessionCursor('mockedSessionId', $offset);
}

$mockClient->expects($this->exactly($remainingChunks))
->method('uploadSessionAppend')
->withConsecutive(...$withs)
->willReturn(...$returns);
}

\assert($mockClient instanceof Client);

return $mockClient;
}

public function createStreamFromString(string $content): Stream
{
$resource = fopen('php://memory', 'r+');
Expand Down