Skip to content

Commit 6d990af

Browse files
authored
Merge pull request #128 from 5am-code/refactor/record-and-fake-tests
Snapshot and Fake Tests Later
2 parents 0366545 + 7395c7b commit 6d990af

12 files changed

+218
-9
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
vendor
33
.phpunit.result.cache
44
coverage/
5-
.phpunit.cache/
5+
.phpunit.cache/
6+
.env*

src/LaravelNotionApiServiceProvider.php

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace FiveamCode\LaravelNotionApi;
44

5+
use FiveamCode\LaravelNotionApi\Macros\PestHttpRecorder;
56
use Illuminate\Support\ServiceProvider;
67

78
/**
@@ -32,5 +33,9 @@ public function register()
3233
$this->app->singleton(Notion::class, function () {
3334
return new Notion(config('laravel-notion-api.notion-api-token'), config('laravel-notion-api.version'));
3435
});
36+
37+
if ($this->app->runningInConsole()) {
38+
PestHttpRecorder::register();
39+
}
3540
}
3641
}

src/Macros/PestHttpRecorder.php

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
namespace FiveamCode\LaravelNotionApi\Macros;
4+
5+
use GuzzleHttp\Client;
6+
use Illuminate\Http\Client\Request;
7+
use Illuminate\Support\Facades\File;
8+
use Illuminate\Support\Facades\Http;
9+
use Illuminate\Support\Str;
10+
11+
class PestHttpRecorder
12+
{
13+
public static function register()
14+
{
15+
Http::macro('recordAndFakeLater', function (array|string $urls = ['*']) {
16+
if (! is_array($urls)) {
17+
$urls = [$urls];
18+
}
19+
20+
$recorder = new HttpRecorder();
21+
$httpFakeCallbacks = [];
22+
23+
foreach ($urls as $url) {
24+
$httpFakeCallbacks[$url] = fn (Request $request) => $recorder->handle($request);
25+
}
26+
27+
Http::fake($httpFakeCallbacks);
28+
29+
return $recorder;
30+
});
31+
}
32+
}
33+
34+
class HttpRecorder
35+
{
36+
private $snapshotDirectory = 'snapshots';
37+
38+
private $usePrettyJson = true;
39+
40+
public function storeIn($directory)
41+
{
42+
$this->snapshotDirectory = $directory;
43+
44+
return $this;
45+
}
46+
47+
public function minifyJson()
48+
{
49+
$this->usePrettyJson = false;
50+
51+
return $this;
52+
}
53+
54+
public function handle(Request $request)
55+
{
56+
$forceRecording = in_array('--force-recording', $_SERVER['argv']);
57+
58+
$urlInfo = parse_url($request->url());
59+
60+
// create specific filename for storing snapshots
61+
$method = Str::lower($request->method());
62+
$name = Str::slug(Str::replace('/', '-', $urlInfo['path']));
63+
$query = Str::slug(Str::replace('&', '_', Str::replace('=', '-', $urlInfo['query'])));
64+
65+
$fileName = "{$method}_{$name}_{$query}.json";
66+
$directoryPath = "tests/{$this->snapshotDirectory}";
67+
$filePath = "{$directoryPath}/{$fileName}";
68+
69+
if ($forceRecording || ! File::exists($filePath)) {
70+
File::makeDirectory($directoryPath, 0744, true, true);
71+
72+
$client = new Client();
73+
$response = $client->request($request->method(), $request->url(), [
74+
'headers' => $request->headers(),
75+
'body' => $request->body(),
76+
'http_errors' => false,
77+
]);
78+
79+
$recordedResponse = [
80+
'status' => $response->getStatusCode(),
81+
'data' => json_decode($response->getBody()->getContents(), true),
82+
];
83+
84+
file_put_contents(
85+
$filePath,
86+
json_encode($recordedResponse, $this->usePrettyJson ? JSON_PRETTY_PRINT : 0)
87+
);
88+
89+
return Http::response($recordedResponse['data'], $response->getStatusCode());
90+
}
91+
92+
$preRecordedData = json_decode(file_get_contents($filePath), true);
93+
94+
return Http::response($preRecordedData['data'], $preRecordedData['status']);
95+
}
96+
}

tests/EndpointBlocksTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ public function classProvider(): array
314314

315315
/**
316316
* @test
317+
*
317318
* @dataProvider classProvider
318319
*
319320
* @param $entityClass

tests/EndpointCommentsTest.php

-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
});
4343

4444
it('should fetch list of comments with an accurate representation of attributes', function () {
45-
4645
// successfull /v1/comments
4746
Http::fake([
4847
'https://api.notion.com/v1/comments?block_id=abf6b0af-6eaa-45ca-9715-9fa147ef6b17*' => Http::response(
@@ -114,7 +113,6 @@
114113
});
115114

116115
it('successfully creates a comment within a page', function () {
117-
118116
// successfull (post) /v1/comments
119117
Http::fake([
120118
'https://api.notion.com/v1/comments*' => Http::response(

tests/EndpointDatabaseTest.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@
2929
* @see https://developers.notion.com/reference/post-database-query
3030
*/
3131
it('returns a database endpoint instance', function () {
32-
33-
// TODO update for new Filter behaviour
32+
// TODO update for new Filter behaviour
3433
$endpoint = Notion::database('897e5a76ae524b489fdfe71f5945d1af');
3534

3635
$this->assertInstanceOf(Database::class, $endpoint);
@@ -136,7 +135,6 @@
136135
});
137136

138137
it('throws a notion exception for a bad request', function () {
139-
140138
// failing /v1/databases
141139
Http::fake([
142140
'https://api.notion.com/v1/databases/8284f3ff77e24d4a939d19459e4d6bdc/query*' => Http::response(

tests/EndpointPagesTest.php

-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ public function it_throws_a_notion_exception_not_found()
107107
/** @test */
108108
public function it_assembles_properties_for_a_new_page()
109109
{
110-
111110
// test values
112111
$pageId = '0349b883a1c64539b435289ea62b6eab';
113112
$pageTitle = 'I was updated from Tinkerwell';

tests/FilterBagTest.php

-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@
128128
});
129129

130130
it('creates a filter bag with with the AND operator and a nested OR condition', function () {
131-
132131
// Filter for all entries that are
133132
// (KnownFor == Univac && (Name == Grace || Name == Jean))
134133

tests/Pest.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
<?php
22

3+
use Dotenv\Dotenv;
34
use FiveamCode\LaravelNotionApi\Tests\NotionApiTest;
5+
use Illuminate\Support\Facades\Config;
46

5-
uses(NotionApiTest::class)->in(__DIR__);
7+
uses(NotionApiTest::class)->beforeEach(function () {
8+
if (file_exists(__DIR__.'/../.env.testing')) {
9+
$dotenv = Dotenv::createImmutable(__DIR__.'/..', '.env.testing');
10+
$dotenv->load();
11+
}
12+
Config::set('laravel-notion-api.notion-api-token', env('NOTION_API_TOKEN', ''));
13+
})->in(__DIR__);
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
use Carbon\Carbon;
4+
use FiveamCode\LaravelNotionApi\Entities\Collections\CommentCollection;
5+
use FiveamCode\LaravelNotionApi\Entities\Comment;
6+
use FiveamCode\LaravelNotionApi\Entities\PropertyItems\RichText;
7+
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
8+
use Illuminate\Support\Facades\Http;
9+
10+
beforeEach(function () {
11+
Http::recordAndFakeLater('https://api.notion.com/v1/comments*')
12+
->storeIn('snapshots/comments');
13+
});
14+
15+
it('should fetch list of comments with an accurate representation of attributes', function () {
16+
$commentCollection = \Notion::comments()->ofBlock('cb588bcbcbdb4f2eac3db05446b8f5d9');
17+
18+
$collection = $commentCollection->asCollection();
19+
$json = $commentCollection->asJson();
20+
21+
expect($commentCollection)->toBeInstanceOf(CommentCollection::class);
22+
expect($collection)->toBeInstanceOf(\Illuminate\Support\Collection::class);
23+
expect($json)->toBeString();
24+
25+
expect($collection->count())->toBe(1);
26+
expect($collection->first())->toBeInstanceOf(Comment::class);
27+
expect($collection->first()->getObjectType())->toBe('comment');
28+
expect($collection->first()->getId())->toBe('99457ae4-8262-413a-b224-0bd82346d885');
29+
expect($collection->first()->getCreatedTime())->toEqual(Carbon::parse('2023-02-18T10:53:00.000000+0000')->toDateTime());
30+
expect($collection->first()->getLastEditedTime())->toEqual(Carbon::parse('2023-02-18T10:53:00.000000+0000')->toDateTime());
31+
expect($collection->first()->getCreatedBy()->getId())->toBe('04536682-603a-4531-a18f-4fa89fdfb4a8');
32+
expect($collection->first()->getLastEditedBy())->toBe(null);
33+
expect($collection->first()->getText())->toBe('This is a Test Comment for Laravel');
34+
expect($collection->first()->getRichText()->getPlainText())->toBe('This is a Test Comment for Laravel');
35+
expect($collection->first()->getRichText())->toBeInstanceOf(RichText::class);
36+
expect($collection->first()->getParentId())->toBe('cb588bcb-cbdb-4f2e-ac3d-b05446b8f5d9');
37+
expect($collection->first()->getParentType())->toBe('page_id');
38+
expect($collection->first()->getDiscussionId())->toBe('f203fa27-fe02-40c9-be9f-fb35e2e956ba');
39+
40+
expect($json)->toBeJson();
41+
});
42+
43+
it('should throw correct exception if block_id has not been found when listing comments', function () {
44+
$this->expectException(NotionException::class);
45+
$this->expectExceptionMessage('Not Found');
46+
$this->expectExceptionCode(404);
47+
48+
\Notion::comments()->ofBlock('cbf6b0af-6eaa-45ca-9715-9fa147ef6b17')->list();
49+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"status": 200,
3+
"data": {
4+
"object": "list",
5+
"results": [
6+
{
7+
"object": "comment",
8+
"id": "99457ae4-8262-413a-b224-0bd82346d885",
9+
"parent": {
10+
"type": "page_id",
11+
"page_id": "cb588bcb-cbdb-4f2e-ac3d-b05446b8f5d9"
12+
},
13+
"discussion_id": "f203fa27-fe02-40c9-be9f-fb35e2e956ba",
14+
"created_time": "2023-02-18T10:53:00.000Z",
15+
"last_edited_time": "2023-02-18T10:53:00.000Z",
16+
"created_by": {
17+
"object": "user",
18+
"id": "04536682-603a-4531-a18f-4fa89fdfb4a8"
19+
},
20+
"rich_text": [
21+
{
22+
"type": "text",
23+
"text": {
24+
"content": "This is a Test Comment for Laravel",
25+
"link": null
26+
},
27+
"annotations": {
28+
"bold": false,
29+
"italic": false,
30+
"strikethrough": false,
31+
"underline": false,
32+
"code": false,
33+
"color": "default"
34+
},
35+
"plain_text": "This is a Test Comment for Laravel",
36+
"href": null
37+
}
38+
]
39+
}
40+
],
41+
"next_cursor": null,
42+
"has_more": false,
43+
"type": "comment",
44+
"comment": []
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"status": 404,
3+
"data": {
4+
"object": "error",
5+
"status": 404,
6+
"code": "object_not_found",
7+
"message": "Could not find block with ID: cbf6b0af-6eaa-45ca-9715-9fa147ef6b17. Make sure the relevant pages and databases are shared with your integration."
8+
}
9+
}

0 commit comments

Comments
 (0)