Upgrade to Laravel 13

This commit is contained in:
Jonny Barnes 2026-04-07 09:01:19 +01:00
commit 9f012b01e4
Signed by: jonny
SSH key fingerprint: SHA256:CTuSlns5U7qlD9jqHvtnVmfYV3Zwl2Z7WnJ4/dqOaL8
117 changed files with 1878 additions and 2215 deletions

View file

@ -26,7 +26,7 @@ abstract class DuskTestCase extends BaseTestCase
/**
* Create the RemoteWebDriver instance.
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
* @return RemoteWebDriver
*/
protected function driver()
{

View file

@ -55,11 +55,11 @@ class ArticlesTest extends TestCase
$user = User::factory()->make();
$faker = Factory::create();
$text = $faker->text;
if ($fh = fopen(sys_get_temp_dir() . '/article.md', 'w')) {
if ($fh = fopen(sys_get_temp_dir().'/article.md', 'w')) {
fwrite($fh, $text);
fclose($fh);
}
$path = sys_get_temp_dir() . '/article.md';
$path = sys_get_temp_dir().'/article.md';
$file = new UploadedFile($path, 'article.md', 'text/plain', null, true);
$this->actingAs($user)
@ -83,7 +83,7 @@ class ArticlesTest extends TestCase
]);
$response = $this->actingAs($user)
->get('/admin/blog/' . $article->id . '/edit');
->get('/admin/blog/'.$article->id.'/edit');
$response->assertSeeText('This is *my* new blog. It uses `Markdown`.');
}
@ -94,7 +94,7 @@ class ArticlesTest extends TestCase
$article = Article::factory()->create();
$this->actingAs($user)
->post('/admin/blog/' . $article->id, [
->post('/admin/blog/'.$article->id, [
'_method' => 'PUT',
'title' => 'My New Blog',
'main' => 'This article has been edited',
@ -112,7 +112,7 @@ class ArticlesTest extends TestCase
$article = Article::factory()->create();
$this->actingAs($user)
->post('/admin/blog/' . $article->id, [
->post('/admin/blog/'.$article->id, [
'_method' => 'DELETE',
]);
$this->assertSoftDeleted('articles', [

View file

@ -59,7 +59,7 @@ class ClientsTest extends TestCase
]);
$response = $this->actingAs($user)
->get('/admin/clients/' . $client->id . '/edit');
->get('/admin/clients/'.$client->id.'/edit');
$response->assertSee('https://jbl5.dev/notes/new');
}
@ -70,7 +70,7 @@ class ClientsTest extends TestCase
$client = MicropubClient::factory()->create();
$this->actingAs($user)
->post('/admin/clients/' . $client->id, [
->post('/admin/clients/'.$client->id, [
'_method' => 'PUT',
'client_url' => 'https://jbl5.dev/notes/new',
'client_name' => 'JBL5dev',
@ -90,7 +90,7 @@ class ClientsTest extends TestCase
]);
$this->actingAs($user)
->post('/admin/clients/' . $client->id, [
->post('/admin/clients/'.$client->id, [
'_method' => 'DELETE',
]);
$this->assertDatabaseMissing('clients', [

View file

@ -21,9 +21,9 @@ class ContactsTest extends TestCase
protected function tearDown(): void
{
if (file_exists(public_path() . '/assets/profile-images/tantek.com/image')) {
unlink(public_path() . '/assets/profile-images/tantek.com/image');
rmdir(public_path() . '/assets/profile-images/tantek.com');
if (file_exists(public_path().'/assets/profile-images/tantek.com/image')) {
unlink(public_path().'/assets/profile-images/tantek.com/image');
rmdir(public_path().'/assets/profile-images/tantek.com');
}
parent::tearDown();
}
@ -69,7 +69,7 @@ class ContactsTest extends TestCase
$user = User::factory()->make();
$contact = Contact::factory()->create();
$response = $this->actingAs($user)->get('/admin/contacts/' . $contact->id . '/edit');
$response = $this->actingAs($user)->get('/admin/contacts/'.$contact->id.'/edit');
$response->assertViewIs('admin.contacts.edit');
}
@ -79,7 +79,7 @@ class ContactsTest extends TestCase
$user = User::factory()->make();
$contact = Contact::factory()->create();
$this->actingAs($user)->post('/admin/contacts/' . $contact->id, [
$this->actingAs($user)->post('/admin/contacts/'.$contact->id, [
'_method' => 'PUT',
'name' => 'Tantek Celik',
'nick' => 'tantek',
@ -95,13 +95,13 @@ class ContactsTest extends TestCase
#[Test]
public function admin_can_edit_contact_and_upload_avatar(): void
{
copy(__DIR__ . '/../../aaron.png', sys_get_temp_dir() . '/tantek.png');
$path = sys_get_temp_dir() . '/tantek.png';
copy(__DIR__.'/../../aaron.png', sys_get_temp_dir().'/tantek.png');
$path = sys_get_temp_dir().'/tantek.png';
$file = new UploadedFile($path, 'tantek.png', 'image/png', null, true);
$user = User::factory()->make();
$contact = Contact::factory()->create();
$this->actingAs($user)->post('/admin/contacts/' . $contact->id, [
$this->actingAs($user)->post('/admin/contacts/'.$contact->id, [
'_method' => 'PUT',
'name' => 'Tantek Celik',
'nick' => 'tantek',
@ -110,8 +110,8 @@ class ContactsTest extends TestCase
'avatar' => $file,
]);
$this->assertFileEquals(
__DIR__ . '/../../aaron.png',
public_path() . '/assets/profile-images/tantek.com/image'
__DIR__.'/../../aaron.png',
public_path().'/assets/profile-images/tantek.com/image'
);
}
@ -125,7 +125,7 @@ class ContactsTest extends TestCase
'nick' => 'tantek',
]);
$this->actingAs($user)->post('/admin/contacts/' . $contact->id, [
$this->actingAs($user)->post('/admin/contacts/'.$contact->id, [
'_method' => 'DELETE',
]);
$this->assertDatabaseMissing('contacts', [
@ -141,7 +141,7 @@ class ContactsTest extends TestCase
<img class="u-photo" alt="" src="http://tantek.com/tantek.png">
</div>
HTML;
$file = fopen(__DIR__ . '/../../aaron.png', 'rb');
$file = fopen(__DIR__.'/../../aaron.png', 'rb');
$mock = new MockHandler([
new Response(200, ['Content-Type' => 'text/html'], $html),
new Response(200, ['Content-Type' => 'image/png'], $file),
@ -154,11 +154,11 @@ class ContactsTest extends TestCase
'homepage' => 'https://tantek.com',
]);
$this->actingAs($user)->get('/admin/contacts/' . $contact->id . '/getavatar');
$this->actingAs($user)->get('/admin/contacts/'.$contact->id.'/getavatar');
$this->assertFileEquals(
__DIR__ . '/../../aaron.png',
public_path() . '/assets/profile-images/tantek.com/image'
__DIR__.'/../../aaron.png',
public_path().'/assets/profile-images/tantek.com/image'
);
}
@ -174,9 +174,9 @@ class ContactsTest extends TestCase
$user = User::factory()->make();
$contact = Contact::factory()->create();
$response = $this->actingAs($user)->get('/admin/contacts/' . $contact->id . '/getavatar');
$response = $this->actingAs($user)->get('/admin/contacts/'.$contact->id.'/getavatar');
$response->assertRedirect('/admin/contacts/' . $contact->id . '/edit');
$response->assertRedirect('/admin/contacts/'.$contact->id.'/edit');
}
#[Test]
@ -197,9 +197,9 @@ class ContactsTest extends TestCase
$user = User::factory()->make();
$contact = Contact::factory()->create();
$response = $this->actingAs($user)->get('/admin/contacts/' . $contact->id . '/getavatar');
$response = $this->actingAs($user)->get('/admin/contacts/'.$contact->id.'/getavatar');
$response->assertRedirect('/admin/contacts/' . $contact->id . '/edit');
$response->assertRedirect('/admin/contacts/'.$contact->id.'/edit');
}
#[Test]
@ -211,8 +211,8 @@ class ContactsTest extends TestCase
]);
$user = User::factory()->make();
$response = $this->actingAs($user)->get('/admin/contacts/' . $contact->id . '/getavatar');
$response = $this->actingAs($user)->get('/admin/contacts/'.$contact->id.'/getavatar');
$response->assertRedirect('/admin/contacts/' . $contact->id . '/edit');
$response->assertRedirect('/admin/contacts/'.$contact->id.'/edit');
}
}

View file

@ -59,7 +59,7 @@ class LikesTest extends TestCase
$like = Like::factory()->create();
$response = $this->actingAs($user)
->get('/admin/likes/' . $like->id . '/edit');
->get('/admin/likes/'.$like->id.'/edit');
$response->assertSee('Edit Like');
}
@ -71,7 +71,7 @@ class LikesTest extends TestCase
$like = Like::factory()->create();
$this->actingAs($user)
->post('/admin/likes/' . $like->id, [
->post('/admin/likes/'.$like->id, [
'_method' => 'PUT',
'like_url' => 'https://example.com',
]);
@ -89,7 +89,7 @@ class LikesTest extends TestCase
$user = User::factory()->make();
$this->actingAs($user)
->post('/admin/likes/' . $like->id, [
->post('/admin/likes/'.$like->id, [
'_method' => 'DELETE',
]);
$this->assertDatabaseMissing('likes', [

View file

@ -54,7 +54,7 @@ class NotesTest extends TestCase
$user = User::factory()->make();
$note = Note::factory()->create();
$response = $this->actingAs($user)->get('/admin/notes/' . $note->id . '/edit');
$response = $this->actingAs($user)->get('/admin/notes/'.$note->id.'/edit');
$response->assertViewIs('admin.notes.edit');
}
@ -65,7 +65,7 @@ class NotesTest extends TestCase
$user = User::factory()->make();
$note = Note::factory()->create();
$this->actingAs($user)->post('/admin/notes/' . $note->id, [
$this->actingAs($user)->post('/admin/notes/'.$note->id, [
'_method' => 'PUT',
'content' => 'An edited note',
'webmentions' => true,
@ -83,7 +83,7 @@ class NotesTest extends TestCase
$user = User::factory()->make();
$note = Note::factory()->create();
$this->actingAs($user)->post('/admin/notes/' . $note->id, [
$this->actingAs($user)->post('/admin/notes/'.$note->id, [
'_method' => 'DELETE',
]);
$this->assertSoftDeleted('notes', [

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Tests\Feature\Admin;
use App\Models\Note;
use App\Models\Place;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
@ -55,7 +56,7 @@ class PlacesTest extends TestCase
$user = User::factory()->make();
$place = Place::factory()->create();
$response = $this->actingAs($user)->get('/admin/places/' . $place->id . '/edit');
$response = $this->actingAs($user)->get('/admin/places/'.$place->id.'/edit');
$response->assertViewIs('admin.places.edit');
}
@ -67,7 +68,7 @@ class PlacesTest extends TestCase
'name' => 'The Bridgewater Pub',
]);
$this->actingAs($user)->post('/admin/places/' . $place->id, [
$this->actingAs($user)->post('/admin/places/'.$place->id, [
'_method' => 'PUT',
'name' => 'The Bridgewater',
'description' => 'Who uses “Pub” anyway',
@ -78,4 +79,62 @@ class PlacesTest extends TestCase
'name' => 'The Bridgewater',
]);
}
#[Test]
public function merge_index_page_loads(): void
{
$user = User::factory()->make();
// Use specific coordinates to avoid haversine acos overflow with extreme faker values
$place = Place::factory()->create(['latitude' => 53.48, 'longitude' => -2.24]);
$response = $this->actingAs($user)->get('/admin/places/'.$place->id.'/merge');
$response->assertViewIs('admin.places.merge.index');
}
#[Test]
public function merge_edit_page_loads(): void
{
$user = User::factory()->make();
$place1 = Place::factory()->create();
$place2 = Place::factory()->create();
$response = $this->actingAs($user)->get('/admin/places/'.$place1->id.'/merge/'.$place2->id);
$response->assertViewIs('admin.places.merge.edit');
}
#[Test]
public function merge_store_with_delete_one_moves_notes_and_deletes_place1(): void
{
$user = User::factory()->make();
$place1 = Place::factory()->create();
$place2 = Place::factory()->create();
$note = Note::factory()->create(['place_id' => $place1->id]);
$this->actingAs($user)->post('/admin/places/merge', [
'place1' => $place1->id,
'place2' => $place2->id,
'delete' => '1',
]);
$this->assertDatabaseMissing('places', ['id' => $place1->id]);
$this->assertDatabaseHas('notes', ['id' => $note->id, 'place_id' => $place2->id]);
}
#[Test]
public function merge_store_with_delete_two_moves_notes_and_deletes_place2(): void
{
$user = User::factory()->make();
$place1 = Place::factory()->create();
$place2 = Place::factory()->create();
$note = Note::factory()->create(['place_id' => $place2->id]);
$this->actingAs($user)->post('/admin/places/merge', [
'place1' => $place1->id,
'place2' => $place2->id,
'delete' => '2',
]);
$this->assertDatabaseMissing('places', ['id' => $place2->id]);
$this->assertDatabaseHas('notes', ['id' => $note->id, 'place_id' => $place1->id]);
}
}

View file

@ -0,0 +1,136 @@
<?php
declare(strict_types=1);
namespace Tests\Feature\Admin;
use App\Models\SyndicationTarget;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class SyndicationTargetsTest extends TestCase
{
use RefreshDatabase;
#[Test]
public function index_requires_authentication(): void
{
$response = $this->get('/admin/syndication');
$response->assertRedirect();
}
#[Test]
public function index_lists_syndication_targets(): void
{
$user = User::factory()->make();
$target = SyndicationTarget::factory()->create();
$response = $this->actingAs($user)->get('/admin/syndication');
$response->assertOk();
$response->assertSeeText($target->uid);
}
#[Test]
public function create_page_loads(): void
{
$user = User::factory()->make();
$response = $this->actingAs($user)->get('/admin/syndication/create');
$response->assertOk();
}
#[Test]
public function store_creates_a_new_syndication_target(): void
{
$user = User::factory()->make();
$this->actingAs($user)->post('/admin/syndication', [
'uid' => 'https://mastodon.social/users/me',
'name' => 'Mastodon',
]);
$this->assertDatabaseHas('syndication_targets', [
'uid' => 'https://mastodon.social/users/me',
'name' => 'Mastodon',
]);
}
#[Test]
public function store_redirects_to_index_after_creation(): void
{
$user = User::factory()->make();
$response = $this->actingAs($user)->post('/admin/syndication', [
'uid' => 'https://mastodon.social/users/me',
'name' => 'Mastodon',
]);
$response->assertRedirect('/admin/syndication');
}
#[Test]
public function edit_page_loads_with_target_data(): void
{
$user = User::factory()->make();
$target = SyndicationTarget::factory()->create(['name' => 'My Mastodon']);
$response = $this->actingAs($user)->get("/admin/syndication/{$target->id}/edit");
$response->assertOk();
$response->assertSee('value="My Mastodon"', false);
}
#[Test]
public function update_modifies_syndication_target(): void
{
$user = User::factory()->make();
$target = SyndicationTarget::factory()->create(['name' => 'Old Name']);
$this->actingAs($user)->put("/admin/syndication/{$target->id}", [
'uid' => $target->uid,
'name' => 'New Name',
]);
$this->assertDatabaseHas('syndication_targets', [
'id' => $target->id,
'name' => 'New Name',
]);
}
#[Test]
public function update_redirects_to_index(): void
{
$user = User::factory()->make();
$target = SyndicationTarget::factory()->create();
$response = $this->actingAs($user)->put("/admin/syndication/{$target->id}", [
'uid' => $target->uid,
'name' => 'Updated Name',
]);
$response->assertRedirect('/admin/syndication');
}
#[Test]
public function destroy_deletes_syndication_target(): void
{
$user = User::factory()->make();
$target = SyndicationTarget::factory()->create();
$this->actingAs($user)->delete("/admin/syndication/{$target->id}");
$this->assertDatabaseMissing('syndication_targets', ['id' => $target->id]);
}
#[Test]
public function destroy_redirects_to_index(): void
{
$user = User::factory()->make();
$target = SyndicationTarget::factory()->create();
$response = $this->actingAs($user)->delete("/admin/syndication/{$target->id}");
$response->assertRedirect('/admin/syndication');
}
}

View file

@ -33,8 +33,8 @@ class ArticlesTest extends TestCase
public function wrong_date_in_url_redirects_to_correct_date()
{
$article = Article::factory()->create();
$response = $this->get('/blog/1900/01/' . $article->titleurl);
$response->assertRedirect('/blog/' . date('Y') . '/' . date('m') . '/' . $article->titleurl);
$response = $this->get('/blog/1900/01/'.$article->titleurl);
$response->assertRedirect('/blog/'.date('Y').'/'.date('m').'/'.$article->titleurl);
}
#[Test]
@ -42,14 +42,14 @@ class ArticlesTest extends TestCase
{
$article = Article::factory()->create();
$num60Id = resolve(Numbers::class)->numto60($article->id);
$response = $this->get('/blog/s/' . $num60Id);
$response = $this->get('/blog/s/'.$num60Id);
$response->assertRedirect($article->link);
}
#[Test]
public function unknown_slug_gets_not_found_response()
{
$response = $this->get('/blog/' . date('Y') . '/' . date('m') . '/unknown-slug');
$response = $this->get('/blog/'.date('Y').'/'.date('m').'/unknown-slug');
$response->assertNotFound();
}

View file

@ -6,6 +6,7 @@ namespace Tests\Feature;
use App\Jobs\ProcessBookmark;
use App\Models\Bookmark;
use App\Models\Tag;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use PHPUnit\Framework\Attributes\Test;
@ -27,7 +28,7 @@ class BookmarksTest extends TestCase
public function single_bookmark_page_loads_without_error(): void
{
$bookmark = Bookmark::factory()->create();
$response = $this->get('/bookmarks/' . $bookmark->id);
$response = $this->get('/bookmarks/'.$bookmark->id);
$response->assertViewIs('bookmarks.show');
}
@ -37,7 +38,7 @@ class BookmarksTest extends TestCase
Queue::fake();
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->getToken(),
'Authorization' => 'Bearer '.$this->getToken(),
])->post('/api/post', [
'h' => 'entry',
'bookmark-of' => 'https://example.org/blog-post',
@ -55,7 +56,7 @@ class BookmarksTest extends TestCase
Queue::fake();
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->getToken(),
'Authorization' => 'Bearer '.$this->getToken(),
])->json('POST', '/api/post', [
'type' => ['h-entry'],
'properties' => [
@ -69,13 +70,34 @@ class BookmarksTest extends TestCase
$this->assertDatabaseHas('bookmarks', ['url' => 'https://example.org/blog-post']);
}
#[Test]
public function tagged_bookmarks_page_only_shows_bookmarks_with_that_tag(): void
{
$tag = Tag::factory()->create(['tag' => 'php']);
$tagged = Bookmark::factory()->create();
$tagged->tags()->attach($tag);
$untagged = Bookmark::factory()->create();
$response = $this->get('/bookmarks/tagged/php');
$response->assertViewIs('bookmarks.tagged');
$response->assertSee($tagged->url);
$response->assertDontSee($untagged->url);
}
#[Test]
public function bookmark_local_uri_attribute_returns_correct_url(): void
{
$bookmark = Bookmark::factory()->create();
$this->assertEquals(config('app.url').'/bookmarks/'.$bookmark->id, $bookmark->local_uri);
}
#[Test]
public function when_the_bookmark_is_created_check_necessary_tags_are_also_created(): void
{
Queue::fake();
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->getToken(),
'Authorization' => 'Bearer '.$this->getToken(),
])->json('POST', '/api/post', [
'type' => ['h-entry'],
'properties' => [

View file

@ -21,7 +21,7 @@ class CorsHeadersTest extends TestCase
[],
[],
[],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertHeader('Access-Control-Allow-Origin', '*');
}

View file

@ -59,7 +59,7 @@ class FeedsTest extends TestCase
$response->assertHeader('Content-Type', 'application/jf2feed+json');
$response->assertJson([
'type' => 'feed',
'name' => 'Blog feed for ' . config('app.name'),
'name' => 'Blog feed for '.config('app.name'),
'url' => url('/blog'),
'author' => [
'type' => 'card',
@ -117,7 +117,7 @@ class FeedsTest extends TestCase
$response->assertHeader('Content-Type', 'application/jf2feed+json');
$response->assertJson([
'type' => 'feed',
'name' => 'Notes feed for ' . config('app.name'),
'name' => 'Notes feed for '.config('app.name'),
'url' => url('/notes'),
'author' => [
'type' => 'card',

View file

@ -16,10 +16,10 @@ class HeaderLinkTest extends TestCase
$linkHeaders = $response->headers->allPreserveCaseWithoutCookies()['Link'];
$this->assertSame('<' . config('app.url') . '/.well-known/indieauth-server>; rel="indieauth-metadata"', $linkHeaders[0]);
$this->assertSame('<' . config('app.url') . '/auth>; rel="authorization_endpoint"', $linkHeaders[1]);
$this->assertSame('<' . config('app.url') . '/token>; rel="token_endpoint"', $linkHeaders[2]);
$this->assertSame('<' . config('app.url') . '/api/post>; rel="micropub"', $linkHeaders[3]);
$this->assertSame('<' . config('app.url') . '/webmention>; rel="webmention"', $linkHeaders[4]);
$this->assertSame('<'.config('app.url').'/.well-known/indieauth-server>; rel="indieauth-metadata"', $linkHeaders[0]);
$this->assertSame('<'.config('app.url').'/auth>; rel="authorization_endpoint"', $linkHeaders[1]);
$this->assertSame('<'.config('app.url').'/token>; rel="token_endpoint"', $linkHeaders[2]);
$this->assertSame('<'.config('app.url').'/api/post>; rel="micropub"', $linkHeaders[3]);
$this->assertSame('<'.config('app.url').'/webmention>; rel="webmention"', $linkHeaders[4]);
}
}

View file

@ -369,7 +369,7 @@ class IndieAuthTest extends TestCase
$this->assertCount(3, $parts);
$this->assertStringContainsString('code=', $parts[0]);
$this->assertSame('state=123456', $parts[1]);
$this->assertSame('iss=' . config('app.url'), $parts[2]);
$this->assertSame('iss='.config('app.url'), $parts[2]);
}
#[Test]

View file

@ -6,7 +6,6 @@ namespace Tests\Feature;
use App\Jobs\ProcessLike;
use App\Models\Like;
use Codebird\Codebird;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
@ -34,7 +33,7 @@ class LikesTest extends TestCase
public function single_like_page_has_correct_view(): void
{
$like = Like::factory()->create();
$response = $this->get('/likes/' . $like->id);
$response = $this->get('/likes/'.$like->id);
$response->assertViewIs('likes.show');
}
@ -44,7 +43,7 @@ class LikesTest extends TestCase
Queue::fake();
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->getToken(),
'Authorization' => 'Bearer '.$this->getToken(),
])->json('POST', '/api/post', [
'type' => ['h-entry'],
'properties' => [
@ -64,7 +63,7 @@ class LikesTest extends TestCase
Queue::fake();
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->getToken(),
'Authorization' => 'Bearer '.$this->getToken(),
])->post('/api/post', [
'h' => 'entry',
'like-of' => 'https://example.org/blog-post',
@ -194,82 +193,6 @@ class LikesTest extends TestCase
$this->assertNull(Like::find($id)->author_name);
}
#[Test]
public function like_that_is_a_tweet(): void
{
$like = new Like;
$like->url = 'https://twitter.com/jonnybarnes/status/1050823255123251200';
$like->save();
$id = $like->id;
$job = new ProcessLike($like);
$mock = new MockHandler([
new Response(201, [], json_encode([
'url' => 'https://twitter.com/likes/id',
])),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$this->app->bind(Client::class, function () use ($client) {
return $client;
});
$info = (object) [
'author_name' => 'Jonny Barnes',
'author_url' => 'https://twitter.com/jonnybarnes',
'html' => '<div>HTML of the tweet embed</div>',
];
$codebirdMock = $this->createPartialMock(Codebird::class, ['__call']);
$codebirdMock->method('__call')
->with('statuses_oembed', $this->anything())
->willReturn($info);
$this->app->instance(Codebird::class, $codebirdMock);
$authorship = new Authorship;
$job->handle($client, $authorship);
$this->assertEquals('Jonny Barnes', Like::find($id)->author_name);
}
#[Test]
public function no_error_for_failure_to_posse_with_bridgy(): void
{
$like = new Like;
$like->url = 'https://twitter.com/jonnybarnes/status/1050823255123251200';
$like->save();
$id = $like->id;
$job = new ProcessLike($like);
$mock = new MockHandler([
new Response(404, [], 'Not found'),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$this->app->bind(Client::class, function () use ($client) {
return $client;
});
$info = (object) [
'author_name' => 'Jonny Barnes',
'author_url' => 'https://twitter.com/jonnybarnes',
'html' => '<div>HTML of the tweet embed</div>',
];
$codebirdMock = $this->createPartialMock(Codebird::class, ['__call']);
$codebirdMock->method('__call')
->with('statuses_oembed', $this->anything())
->willReturn($info);
$this->app->instance(Codebird::class, $codebirdMock);
$authorship = new Authorship;
$job->handle($client, $authorship);
$this->assertEquals('Jonny Barnes', Like::find($id)->author_name);
}
#[Test]
public function unknown_like_gives_not_found_response(): void
{

View file

@ -47,7 +47,7 @@ class MicropubControllerTest extends TestCase
#[Test]
public function micropub_get_request_with_valid_token_returns_ok_response(): void
{
$response = $this->get('/api/post', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
$response = $this->get('/api/post', ['HTTP_Authorization' => 'Bearer '.$this->getToken()]);
$response->assertStatus(200);
$response->assertJsonFragment(['response' => 'token']);
}
@ -55,7 +55,7 @@ class MicropubControllerTest extends TestCase
#[Test]
public function micropub_clients_can_request_syndication_targets_can_be_empty(): void
{
$response = $this->get('/api/post?q=syndicate-to', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
$response = $this->get('/api/post?q=syndicate-to', ['HTTP_Authorization' => 'Bearer '.$this->getToken()]);
$response->assertJsonFragment(['syndicate-to' => []]);
}
@ -63,7 +63,7 @@ class MicropubControllerTest extends TestCase
public function micropub_clients_can_request_syndication_targets_populates_from_model(): void
{
$syndicationTarget = SyndicationTarget::factory()->create();
$response = $this->get('/api/post?q=syndicate-to', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
$response = $this->get('/api/post?q=syndicate-to', ['HTTP_Authorization' => 'Bearer '.$this->getToken()]);
$response->assertJsonFragment(['uid' => $syndicationTarget->uid]);
}
@ -75,7 +75,7 @@ class MicropubControllerTest extends TestCase
'latitude' => '53.5',
'longitude' => '-2.38',
]);
$response = $this->get('/api/post?q=geo:53.5,-2.38', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
$response = $this->get('/api/post?q=geo:53.5,-2.38', ['HTTP_Authorization' => 'Bearer '.$this->getToken()]);
$response->assertJson(['places' => [['slug' => 'the-bridgewater-pub']]]);
}
@ -90,14 +90,14 @@ class MicropubControllerTest extends TestCase
#[Test]
public function return_empty_result_when_micropub_client_requests_known_nearby_places(): void
{
$response = $this->get('/api/post?q=geo:1.23,4.56', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
$response = $this->get('/api/post?q=geo:1.23,4.56', ['HTTP_Authorization' => 'Bearer '.$this->getToken()]);
$response->assertJson(['places' => []]);
}
#[Test]
public function micropub_client_can_request_endpoint_config(): void
{
$response = $this->get('/api/post?q=config', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
$response = $this->get('/api/post?q=config', ['HTTP_Authorization' => 'Bearer '.$this->getToken()]);
$response->assertJsonFragment(['media-endpoint' => route('media-endpoint')]);
}
@ -113,7 +113,7 @@ class MicropubControllerTest extends TestCase
'h' => 'entry',
'content' => $note,
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertJson(['response' => 'created']);
@ -146,7 +146,7 @@ class MicropubControllerTest extends TestCase
'https://bsky.app/profile/jonnybarnes.uk',
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertJson(['response' => 'created']);
$this->assertDatabaseHas('notes', ['note' => $note]);
@ -164,7 +164,7 @@ class MicropubControllerTest extends TestCase
'name' => 'The Barton Arms',
'geo' => 'geo:53.4974,-2.3768',
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertJson(['response' => 'created']);
$this->assertDatabaseHas('places', ['slug' => 'the-barton-arms']);
@ -181,7 +181,7 @@ class MicropubControllerTest extends TestCase
'latitude' => '53.4974',
'longitude' => '-2.3768',
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertJson(['response' => 'created']);
$this->assertDatabaseHas('places', ['slug' => 'the-barton-arms']);
@ -196,7 +196,7 @@ class MicropubControllerTest extends TestCase
'h' => 'entry',
'content' => 'A random note',
],
['HTTP_Authorization' => 'Bearer ' . $this->getInvalidToken()]
['HTTP_Authorization' => 'Bearer '.$this->getInvalidToken()]
);
$response->assertStatus(400);
$response->assertJson(['error' => 'invalid_token']);
@ -211,7 +211,7 @@ class MicropubControllerTest extends TestCase
'h' => 'entry',
'content' => 'A random note',
],
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithNoScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithNoScope()]
);
$response->assertStatus(400);
$response->assertJson(['error_description' => 'The provided token has no scopes']);
@ -226,7 +226,7 @@ class MicropubControllerTest extends TestCase
'h' => 'entry',
'content' => 'A random note',
],
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithIncorrectScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithIncorrectScope()]
);
$response->assertStatus(401);
$response->assertJson(['error' => 'insufficient_scope']);
@ -265,10 +265,10 @@ class MicropubControllerTest extends TestCase
'https://mastodon.social/@jonnybarnes',
'https://bsky.app/profile/jonnybarnes.uk',
],
'photo' => [config('filesystems.disks.public.url') . '/media/test-photo.jpg'],
'photo' => [config('filesystems.disks.public.url').'/media/test-photo.jpg'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -292,7 +292,7 @@ class MicropubControllerTest extends TestCase
'location' => ['geo:1.23,4.56'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -326,7 +326,7 @@ class MicropubControllerTest extends TestCase
'location' => [$place->uri],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -358,7 +358,7 @@ class MicropubControllerTest extends TestCase
],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -391,7 +391,7 @@ class MicropubControllerTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -444,7 +444,7 @@ class MicropubControllerTest extends TestCase
'content' => [$note],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithIncorrectScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithIncorrectScope()]
);
$response
->assertJson([
@ -465,7 +465,7 @@ class MicropubControllerTest extends TestCase
'content' => ['Some content'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson([
@ -485,10 +485,10 @@ class MicropubControllerTest extends TestCase
'type' => ['h-card'],
'properties' => [
'name' => [$faker->name],
'geo' => ['geo:' . $faker->latitude . ',' . $faker->longitude],
'geo' => ['geo:'.$faker->latitude.','.$faker->longitude],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'created'])
@ -505,10 +505,10 @@ class MicropubControllerTest extends TestCase
'type' => ['h-card'],
'properties' => [
'name' => [$faker->name],
'geo' => ['geo:' . $faker->latitude . ',' . $faker->longitude . ';u=35'],
'geo' => ['geo:'.$faker->latitude.','.$faker->longitude.';u=35'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'created'])
@ -528,7 +528,7 @@ class MicropubControllerTest extends TestCase
'content' => ['replaced content'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -551,7 +551,7 @@ class MicropubControllerTest extends TestCase
'content' => [['value' => 'plain text', 'html' => 'html version']],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -577,7 +577,7 @@ class MicropubControllerTest extends TestCase
],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -602,7 +602,7 @@ class MicropubControllerTest extends TestCase
'photo' => ['https://example.org/photo.jpg'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -619,12 +619,12 @@ class MicropubControllerTest extends TestCase
'/api/post',
[
'action' => 'update',
'url' => config('app.url') . '/blog/A',
'url' => config('app.url').'/blog/A',
'add' => [
'syndication' => ['https://www.swarmapp.com/checkin/123'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['error' => 'invalid'])
@ -638,12 +638,12 @@ class MicropubControllerTest extends TestCase
'/api/post',
[
'action' => 'update',
'url' => config('app.url') . '/notes/ZZZZ',
'url' => config('app.url').'/notes/ZZZZ',
'add' => [
'syndication' => ['https://www.swarmapp.com/checkin/123'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['error' => 'invalid_request'])
@ -663,7 +663,7 @@ class MicropubControllerTest extends TestCase
'syndication' => ['https://www.swarmapp.com/checkin/123'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['error' => 'unsupported_operation'])
@ -677,12 +677,12 @@ class MicropubControllerTest extends TestCase
'/api/post',
[
'action' => 'update',
'url' => config('app.url') . '/notes/B',
'url' => config('app.url').'/notes/B',
'add' => [
'syndication' => ['https://www.swarmapp.com/checkin/123'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithIncorrectScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithIncorrectScope()]
);
$response
->assertStatus(401)
@ -705,7 +705,7 @@ class MicropubControllerTest extends TestCase
],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -750,7 +750,7 @@ class MicropubControllerTest extends TestCase
'syndication' => ['https://www.swarmapp.com/checkin/123'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -777,7 +777,7 @@ class MicropubControllerTest extends TestCase
'url' => $note->uri,
'delete' => ['syndication'],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -805,7 +805,7 @@ class MicropubControllerTest extends TestCase
'syndication' => ['https://www.swarmapp.com/checkin/123'],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -820,7 +820,7 @@ class MicropubControllerTest extends TestCase
public function micropub_client_api_request_can_delete_photo(): void
{
$note = Note::factory()->create();
$media = new \App\Models\Media;
$media = new Media;
$media->path = 'https://example.org/photo.jpg';
$media->type = 'image';
$media->save();
@ -833,7 +833,7 @@ class MicropubControllerTest extends TestCase
'url' => $note->uri,
'delete' => ['photo'],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertJson(['response' => 'updated'])
@ -860,7 +860,7 @@ class MicropubControllerTest extends TestCase
'content' => [$content],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response

View file

@ -28,7 +28,7 @@ class MicropubMediaTest extends TestCase
$response = $this->get(
'/api/media?q=last',
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertStatus(200);
$response->assertJson(['url' => null]);
@ -50,7 +50,7 @@ class MicropubMediaTest extends TestCase
{
$response = $this->get(
'/api/media?q=last',
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithNoScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithNoScope()]
);
$response->assertStatus(400);
$response->assertJsonFragment(['error_description' => 'The provided token has no scopes']);
@ -61,7 +61,7 @@ class MicropubMediaTest extends TestCase
{
$response = $this->get(
'/api/media?q=last',
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithIncorrectScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithIncorrectScope()]
);
$response->assertStatus(401);
$response->assertJsonFragment(['error_description' => 'The tokens scope does not have the necessary requirements.']);
@ -72,7 +72,7 @@ class MicropubMediaTest extends TestCase
{
$response = $this->get(
'/api/media',
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertStatus(200);
$response->assertJson(['status' => 'OK']);
@ -82,7 +82,7 @@ class MicropubMediaTest extends TestCase
public function client_can_list_last_upload(): void
{
Queue::fake();
$file = __DIR__ . '/../aaron.png';
$file = __DIR__.'/../aaron.png';
$token = $this->getToken();
$response = $this->post(
@ -90,7 +90,7 @@ class MicropubMediaTest extends TestCase
[
'file' => new UploadedFile($file, 'aaron.png', 'image/png', null, true),
],
['HTTP_Authorization' => 'Bearer ' . $token]
['HTTP_Authorization' => 'Bearer '.$token]
);
$path = parse_url($response->headers->get('Location'), PHP_URL_PATH);
@ -98,12 +98,12 @@ class MicropubMediaTest extends TestCase
$lastUploadResponse = $this->get(
'/api/media?q=last',
['HTTP_Authorization' => 'Bearer ' . $token]
['HTTP_Authorization' => 'Bearer '.$token]
);
$lastUploadResponse->assertJson(['url' => $response->headers->get('Location')]);
// now remove file
unlink(storage_path('app/private/media/') . $filename);
unlink(storage_path('app/private/media/').$filename);
$this->removeDirIfEmpty(storage_path('app/private/media'));
}
@ -111,7 +111,7 @@ class MicropubMediaTest extends TestCase
public function client_can_source_uploads(): void
{
Queue::fake();
$file = __DIR__ . '/../aaron.png';
$file = __DIR__.'/../aaron.png';
$token = $this->getToken();
$response = $this->post(
@ -119,7 +119,7 @@ class MicropubMediaTest extends TestCase
[
'file' => new UploadedFile($file, 'aaron.png', 'image/png', null, true),
],
['HTTP_Authorization' => 'Bearer ' . $token]
['HTTP_Authorization' => 'Bearer '.$token]
);
$path = parse_url($response->headers->get('Location'), PHP_URL_PATH);
@ -127,7 +127,7 @@ class MicropubMediaTest extends TestCase
$sourceUploadResponse = $this->get(
'/api/media?q=source',
['HTTP_Authorization' => 'Bearer ' . $token]
['HTTP_Authorization' => 'Bearer '.$token]
);
$sourceUploadResponse->assertJson(['items' => [[
'url' => $response->headers->get('Location'),
@ -135,7 +135,7 @@ class MicropubMediaTest extends TestCase
]]]);
// now remove file
unlink(storage_path('app/private/media/') . $filename);
unlink(storage_path('app/private/media/').$filename);
$this->removeDirIfEmpty(storage_path('app/private/media'));
}
@ -143,7 +143,7 @@ class MicropubMediaTest extends TestCase
public function client_can_source_uploads_with_limit(): void
{
Queue::fake();
$file = __DIR__ . '/../aaron.png';
$file = __DIR__.'/../aaron.png';
$token = $this->getToken();
$response = $this->post(
@ -151,7 +151,7 @@ class MicropubMediaTest extends TestCase
[
'file' => new UploadedFile($file, 'aaron.png', 'image/png', null, true),
],
['HTTP_Authorization' => 'Bearer ' . $token]
['HTTP_Authorization' => 'Bearer '.$token]
);
$path = parse_url($response->headers->get('Location'), PHP_URL_PATH);
@ -159,7 +159,7 @@ class MicropubMediaTest extends TestCase
$sourceUploadResponse = $this->get(
'/api/media?q=source&limit=1',
['HTTP_Authorization' => 'Bearer ' . $token]
['HTTP_Authorization' => 'Bearer '.$token]
);
$sourceUploadResponse->assertJson(['items' => [[
'url' => $response->headers->get('Location'),
@ -169,7 +169,7 @@ class MicropubMediaTest extends TestCase
$this->assertCount(1, json_decode($sourceUploadResponse->getContent(), true)['items']);
// now remove file
unlink(storage_path('app/private/media/') . $filename);
unlink(storage_path('app/private/media/').$filename);
$this->removeDirIfEmpty(storage_path('app/private/media'));
}
@ -179,7 +179,7 @@ class MicropubMediaTest extends TestCase
$response = $this->post(
'/api/media',
[],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertStatus(400);
$response->assertJson([
@ -194,7 +194,7 @@ class MicropubMediaTest extends TestCase
{
$response = $this->get(
'/api/media?q=unknown',
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertStatus(400);
$response->assertJson(['error' => 'invalid_request']);
@ -227,7 +227,7 @@ class MicropubMediaTest extends TestCase
$response = $this->post(
'/api/media',
[],
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithNoScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithNoScope()]
);
$response->assertStatus(400);
$response->assertJsonFragment(['error_description' => 'The provided token has no scopes']);
@ -239,7 +239,7 @@ class MicropubMediaTest extends TestCase
$response = $this->post(
'/api/media',
[],
['HTTP_Authorization' => 'Bearer ' . $this->getTokenWithIncorrectScope()]
['HTTP_Authorization' => 'Bearer '.$this->getTokenWithIncorrectScope()]
);
$response->assertStatus(401);
$response->assertJsonFragment([
@ -251,14 +251,14 @@ class MicropubMediaTest extends TestCase
public function media_endpoint_upload_file(): void
{
Queue::fake();
$file = __DIR__ . '/../aaron.png';
$file = __DIR__.'/../aaron.png';
$response = $this->post(
'/api/media',
[
'file' => new UploadedFile($file, 'aaron.png', 'image/png', null, true),
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$path = parse_url($response->headers->get('Location'), PHP_URL_PATH);
@ -266,7 +266,7 @@ class MicropubMediaTest extends TestCase
Queue::assertPushed(ProcessMedia::class);
Storage::disk('local')->assertExists($filename);
// now remove file
unlink(storage_path('app/private/') . $filename);
unlink(storage_path('app/private/').$filename);
$this->removeDirIfEmpty(storage_path('app/private/media'));
}
@ -274,14 +274,14 @@ class MicropubMediaTest extends TestCase
public function media_endpoint_upload_audio_file(): void
{
Queue::fake();
$file = __DIR__ . '/../audio.mp3';
$file = __DIR__.'/../audio.mp3';
$response = $this->post(
'/api/media',
[
'file' => new UploadedFile($file, 'audio.mp3', 'audio/mpeg', null, true),
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$path = parse_url($response->headers->get('Location'), PHP_URL_PATH);
@ -289,7 +289,7 @@ class MicropubMediaTest extends TestCase
Queue::assertPushed(ProcessMedia::class);
Storage::disk('local')->assertExists($filename);
// now remove file
unlink(storage_path('app/private/') . $filename);
unlink(storage_path('app/private/').$filename);
$this->removeDirIfEmpty(storage_path('app/private/media'));
}
@ -297,14 +297,14 @@ class MicropubMediaTest extends TestCase
public function media_endpoint_upload_video_file(): void
{
Queue::fake();
$file = __DIR__ . '/../video.ogv';
$file = __DIR__.'/../video.ogv';
$response = $this->post(
'/api/media',
[
'file' => new UploadedFile($file, 'video.ogv', 'video/ogg', null, true),
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$path = parse_url($response->headers->get('Location'), PHP_URL_PATH);
@ -312,7 +312,7 @@ class MicropubMediaTest extends TestCase
Queue::assertPushed(ProcessMedia::class);
Storage::disk('local')->assertExists($filename);
// now remove file
unlink(storage_path('app/private/') . $filename);
unlink(storage_path('app/private/').$filename);
$this->removeDirIfEmpty(storage_path('app/private/media'));
}
@ -326,7 +326,7 @@ class MicropubMediaTest extends TestCase
[
'file' => UploadedFile::fake()->create('document.pdf', 100),
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$path = parse_url($response->headers->get('Location'), PHP_URL_PATH);
@ -334,7 +334,7 @@ class MicropubMediaTest extends TestCase
Queue::assertPushed(ProcessMedia::class);
Storage::disk('local')->assertExists($filename);
// now remove file
unlink(storage_path('app/private/') . $filename);
unlink(storage_path('app/private/').$filename);
$this->removeDirIfEmpty(storage_path('app/private/media'));
}
@ -348,14 +348,14 @@ class MicropubMediaTest extends TestCase
'/api/media',
[
'file' => new UploadedFile(
__DIR__ . '/../aaron.png',
__DIR__.'/../aaron.png',
'aaron.png',
'image/png',
UPLOAD_ERR_INI_SIZE,
true
),
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response->assertStatus(400);
$response->assertJson(['error_description' => 'The uploaded file failed validation']);

View file

@ -50,7 +50,7 @@ class NotesControllerTest extends TestCase
public function old_note_urls_redirect(): void
{
$note = Note::factory()->create();
$response = $this->get('/note/' . $note->id);
$response = $this->get('/note/'.$note->id);
$response->assertRedirect($note->uri);
}

View file

@ -20,10 +20,10 @@ class ParseCachedWebMentionsTest extends TestCase
{
parent::setUp();
mkdir(storage_path('HTML') . '/https/aaronpk.localhost/reply', 0777, true);
mkdir(storage_path('HTML') . '/http/tantek.com', 0777, true);
copy(__DIR__ . '/../aaron.html', storage_path('HTML') . '/https/aaronpk.localhost/reply/1');
copy(__DIR__ . '/../tantek.html', storage_path('HTML') . '/http/tantek.com/index.html');
mkdir(storage_path('HTML').'/https/aaronpk.localhost/reply', 0777, true);
mkdir(storage_path('HTML').'/http/tantek.com', 0777, true);
copy(__DIR__.'/../aaron.html', storage_path('HTML').'/https/aaronpk.localhost/reply/1');
copy(__DIR__.'/../tantek.html', storage_path('HTML').'/http/tantek.com/index.html');
}
#[Test]
@ -39,16 +39,16 @@ class ParseCachedWebMentionsTest extends TestCase
'created_at' => Carbon::now()->subDays(5),
'updated_at' => Carbon::now()->subDays(5),
]);
$this->assertFileExists(storage_path('HTML') . '/https/aaronpk.localhost/reply/1');
$this->assertFileExists(storage_path('HTML') . '/http/tantek.com/index.html');
$htmlAaron = file_get_contents(storage_path('HTML') . '/https/aaronpk.localhost/reply/1');
$htmlAaron = str_replace('href="/notes', 'href="' . config('app.url') . '/notes', $htmlAaron);
$htmlAaron = str_replace('datetime=""', 'dateime="' . carbon()->now()->toIso8601String() . '"', $htmlAaron);
file_put_contents(storage_path('HTML') . '/https/aaronpk.localhost/reply/1', $htmlAaron);
$htmlTantek = file_get_contents(storage_path('HTML') . '/http/tantek.com/index.html');
$htmlTantek = str_replace('href="/notes', 'href="' . config('app.url') . '/notes', $htmlTantek);
$htmlTantek = str_replace('datetime=""', 'dateime="' . carbon()->now()->toIso8601String() . '"', $htmlTantek);
file_put_contents(storage_path('HTML') . '/http/tantek.com/index.html', $htmlTantek);
$this->assertFileExists(storage_path('HTML').'/https/aaronpk.localhost/reply/1');
$this->assertFileExists(storage_path('HTML').'/http/tantek.com/index.html');
$htmlAaron = file_get_contents(storage_path('HTML').'/https/aaronpk.localhost/reply/1');
$htmlAaron = str_replace('href="/notes', 'href="'.config('app.url').'/notes', $htmlAaron);
$htmlAaron = str_replace('datetime=""', 'dateime="'.carbon()->now()->toIso8601String().'"', $htmlAaron);
file_put_contents(storage_path('HTML').'/https/aaronpk.localhost/reply/1', $htmlAaron);
$htmlTantek = file_get_contents(storage_path('HTML').'/http/tantek.com/index.html');
$htmlTantek = str_replace('href="/notes', 'href="'.config('app.url').'/notes', $htmlTantek);
$htmlTantek = str_replace('datetime=""', 'dateime="'.carbon()->now()->toIso8601String().'"', $htmlTantek);
file_put_contents(storage_path('HTML').'/http/tantek.com/index.html', $htmlTantek);
Artisan::call('webmentions:parsecached');
@ -62,11 +62,11 @@ class ParseCachedWebMentionsTest extends TestCase
protected function tearDown(): void
{
$fs = new FileSystem;
if ($fs->exists(storage_path() . '/HTML/https')) {
$fs->deleteDirectory(storage_path() . '/HTML/https');
if ($fs->exists(storage_path().'/HTML/https')) {
$fs->deleteDirectory(storage_path().'/HTML/https');
}
if ($fs->exists(storage_path() . '/HTML/http')) {
$fs->deleteDirectory(storage_path() . '/HTML/http');
if ($fs->exists(storage_path().'/HTML/http')) {
$fs->deleteDirectory(storage_path().'/HTML/http');
}
parent::tearDown();

View file

@ -48,7 +48,7 @@ class SwarmTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -94,7 +94,7 @@ class SwarmTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -136,7 +136,7 @@ class SwarmTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -170,7 +170,7 @@ class SwarmTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -211,7 +211,7 @@ class SwarmTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -257,7 +257,7 @@ class SwarmTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$response
->assertStatus(201)
@ -309,7 +309,7 @@ class SwarmTest extends TestCase
]],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
['HTTP_Authorization' => 'Bearer '.$this->getToken()]
);
$this->assertDatabaseHas('places', [
'name' => 'Forbidden Planet',

View file

@ -28,7 +28,7 @@ class TokenServiceTest extends TestCase
];
$token = $tokenService->getNewToken($data);
$response = $this->get('/api/post', ['HTTP_Authorization' => 'Bearer ' . $token]);
$response = $this->get('/api/post', ['HTTP_Authorization' => 'Bearer '.$token]);
$response->assertJson([
'response' => 'token',
@ -60,7 +60,7 @@ class TokenServiceTest extends TestCase
->getToken($config->signer(), InMemory::plainText(random_bytes(32)))
->toString();
$response = $this->get('/api/post', ['HTTP_Authorization' => 'Bearer ' . $token]);
$response = $this->get('/api/post', ['HTTP_Authorization' => 'Bearer '.$token]);
$response->assertJson([
'response' => 'error',

View file

@ -42,7 +42,7 @@ class WebMentionsControllerTest extends TestCase
{
$response = $this->call('POST', '/webmention', [
'source' => 'https://example.org/post/123',
'target' => config('app.url') . '/invalid/target',
'target' => config('app.url').'/invalid/target',
]);
$response->assertStatus(400);
}
@ -55,7 +55,7 @@ class WebMentionsControllerTest extends TestCase
{
$response = $this->call('POST', '/webmention', [
'source' => 'https://example.org/post/123',
'target' => config('app.url') . '/blog/target',
'target' => config('app.url').'/blog/target',
]);
$response->assertStatus(501);
}
@ -68,7 +68,7 @@ class WebMentionsControllerTest extends TestCase
{
$response = $this->call('POST', '/webmention', [
'source' => 'https://example.org/post/123',
'target' => config('app.url') . '/notes/ZZZZZ',
'target' => config('app.url').'/notes/ZZZZZ',
]);
$response->assertStatus(400);
}

View file

@ -31,7 +31,7 @@ class ArticlesTest extends TestCase
$article = new Article;
$article->main = 'Some *markdown*';
$this->assertEquals('<p>Some <em>markdown</em></p>' . PHP_EOL, $article->html);
$this->assertEquals('<p>Some <em>markdown</em></p>'.PHP_EOL, $article->html);
}
#[Test]
@ -58,7 +58,7 @@ class ArticlesTest extends TestCase
$article->title = 'Test Title';
$this->assertEquals(
'/blog/' . date('Y') . '/' . date('m') . '/test',
'/blog/'.date('Y').'/'.date('m').'/test',
$article->link
);
}

View file

@ -18,8 +18,8 @@ class DownloadWebMentionJobTest extends TestCase
protected function tearDown(): void
{
$fs = new FileSystem;
if ($fs->exists(storage_path() . '/HTML/https')) {
$fs->deleteDirectory(storage_path() . '/HTML/https');
if ($fs->exists(storage_path().'/HTML/https')) {
$fs->deleteDirectory(storage_path().'/HTML/https');
}
parent::tearDown();
}
@ -34,7 +34,7 @@ class DownloadWebMentionJobTest extends TestCase
<a class="u-like-of" href=""></a>
</div>
HTML;
$html = str_replace('href=""', 'href="' . config('app.url') . '/notes/A"', $html);
$html = str_replace('href=""', 'href="'.config('app.url').'/notes/A"', $html);
$mock = new MockHandler([
new Response(200, ['X-Foo' => 'Bar'], $html),
new Response(200, ['X-Foo' => 'Bar'], $html),
@ -49,7 +49,7 @@ class DownloadWebMentionJobTest extends TestCase
$job->handle($client);
$this->assertFileDoesNotExist(storage_path('HTML/https/example.org/reply') . '/1.' . date('Y-m-d') . '.backup');
$this->assertFileDoesNotExist(storage_path('HTML/https/example.org/reply').'/1.'.date('Y-m-d').'.backup');
}
#[Test]
@ -68,8 +68,8 @@ class DownloadWebMentionJobTest extends TestCase
<a class="u-repost-of" href=""></a>
</div>
HTML;
$html = str_replace('href=""', 'href="' . config('app.url') . '/notes/A"', $html);
$html2 = str_replace('href=""', 'href="' . config('app.url') . '/notes/A"', $html2);
$html = str_replace('href=""', 'href="'.config('app.url').'/notes/A"', $html);
$html2 = str_replace('href=""', 'href="'.config('app.url').'/notes/A"', $html2);
$mock = new MockHandler([
new Response(200, ['X-Foo' => 'Bar'], $html),
new Response(200, ['X-Foo' => 'Bar'], $html2),
@ -84,7 +84,7 @@ class DownloadWebMentionJobTest extends TestCase
$job->handle($client);
$this->assertFileExists(storage_path('HTML/https/example.org/reply') . '/1.' . date('Y-m-d') . '.backup');
$this->assertFileExists(storage_path('HTML/https/example.org/reply').'/1.'.date('Y-m-d').'.backup');
}
#[Test]
@ -97,7 +97,7 @@ class DownloadWebMentionJobTest extends TestCase
<a class="u-like-of" href=""></a>
</div>
HTML;
$html = str_replace('href=""', 'href="' . config('app.url') . '/notes/A"', $html);
$html = str_replace('href=""', 'href="'.config('app.url').'/notes/A"', $html);
$mock = new MockHandler([
new Response(200, ['X-Foo' => 'Bar'], $html),
]);

View file

@ -20,18 +20,18 @@ class ProcessMediaJobTest extends TestCase
$job = new ProcessMedia('file.txt');
$job->handle($manager);
$this->assertFileDoesNotExist(storage_path('app/media/') . 'file.txt');
$this->assertFileDoesNotExist(storage_path('app/media/').'file.txt');
}
#[Test]
public function small_images_are_not_resized(): void
{
$manager = app()->make(ImageManager::class);
Storage::disk('local')->put('media/aaron.png', file_get_contents(__DIR__ . '/../../aaron.png'));
Storage::disk('local')->put('media/aaron.png', file_get_contents(__DIR__.'/../../aaron.png'));
$job = new ProcessMedia('aaron.png');
$job->handle($manager);
$this->assertFileDoesNotExist(storage_path('app/media/') . 'aaron.png');
$this->assertFileDoesNotExist(storage_path('app/media/').'aaron.png');
// Tidy up files created by the job
Storage::disk('local')->delete('public/media/aaron.png');
@ -51,7 +51,7 @@ class ProcessMediaJobTest extends TestCase
Storage::disk('public')->assertExists('media/test-image-small.jpg');
Storage::disk('public')->assertExists('media/test-image-medium.jpg');
$this->assertFileDoesNotExist(storage_path('app/media/') . 'test-image.jpg');
$this->assertFileDoesNotExist(storage_path('app/media/').'test-image.jpg');
// Tidy up files created by the job
Storage::disk('public')->delete('media/test-image.jpg');

View file

@ -27,8 +27,8 @@ class ProcessWebMentionJobTest extends TestCase
protected function tearDown(): void
{
$fs = new FileSystem;
if ($fs->exists(storage_path() . '/HTML/https')) {
$fs->deleteDirectory(storage_path() . '/HTML/https');
if ($fs->exists(storage_path().'/HTML/https')) {
$fs->deleteDirectory(storage_path().'/HTML/https');
}
parent::tearDown();
}
@ -64,7 +64,7 @@ class ProcessWebMentionJobTest extends TestCase
I liked <a class="u-like-of" href="/notes/1">a note</a>.
</div>
HTML;
$html = str_replace('href="', 'href="' . config('app.url'), $html);
$html = str_replace('href="', 'href="'.config('app.url'), $html);
$mock = new MockHandler([
new Response(200, [], $html),
]);
@ -117,7 +117,7 @@ class ProcessWebMentionJobTest extends TestCase
'source' => $source,
'type' => 'in-reply-to',
// phpcs:ignore Generic.Files.LineLength.TooLong
'mf2' => '{"rels": [], "items": [{"type": ["h-entry"], "properties": {"content": [{"html": "Updated reply", "value": "Updated reply"}], "in-reply-to": ["' . $note->uri . '"]}}], "rel-urls": []}',
'mf2' => '{"rels": [], "items": [{"type": ["h-entry"], "properties": {"content": [{"html": "Updated reply", "value": "Updated reply"}], "in-reply-to": ["'.$note->uri.'"]}}], "rel-urls": []}',
]);
}
@ -142,7 +142,7 @@ class ProcessWebMentionJobTest extends TestCase
$source = 'https://example.org/reply/1';
$webmention = new WebMention;
$webmention->source = $source;
$webmention->target = config('app.url') . '/notes/E';
$webmention->target = config('app.url').'/notes/E';
$webmention->type = 'in-reply-to';
$webmention->save();
@ -179,7 +179,7 @@ class ProcessWebMentionJobTest extends TestCase
$source = 'https://example.org/reply/1';
$webmention = new WebMention;
$webmention->source = $source;
$webmention->target = config('app.url') . '/notes/E';
$webmention->target = config('app.url').'/notes/E';
$webmention->type = 'like-of';
$webmention->save();
@ -207,7 +207,7 @@ class ProcessWebMentionJobTest extends TestCase
I liked <a class="u-like-of" href="/notes/1">a note</a>.
</div>
HTML;
$html = str_replace('href="', 'href="' . config('app.url'), $html);
$html = str_replace('href="', 'href="'.config('app.url'), $html);
$mock = new MockHandler([
new Response(200, [], $html),
]);
@ -248,7 +248,7 @@ class ProcessWebMentionJobTest extends TestCase
$source = 'https://example.org/reply/1';
$webmention = new WebMention;
$webmention->source = $source;
$webmention->target = config('app.url') . '/notes/E';
$webmention->target = config('app.url').'/notes/E';
$webmention->type = 'repost-of';
$webmention->save();

View file

@ -18,9 +18,9 @@ class SaveProfileImageJobTest extends TestCase
{
protected function tearDown(): void
{
if (file_exists(public_path() . '/assets/profile-images/example.org/image')) {
unlink(public_path() . '/assets/profile-images/example.org/image');
rmdir(public_path() . '/assets/profile-images/example.org');
if (file_exists(public_path().'/assets/profile-images/example.org/image')) {
unlink(public_path().'/assets/profile-images/example.org/image');
rmdir(public_path().'/assets/profile-images/example.org');
}
parent::tearDown();
}
@ -77,7 +77,7 @@ class SaveProfileImageJobTest extends TestCase
$job = new SaveProfileImage($mf);
$job->handle($authorship);
$this->assertFileExists(public_path() . '/assets/profile-images/example.org/image');
$this->assertFileExists(public_path().'/assets/profile-images/example.org/image');
}
#[Test]
@ -103,8 +103,8 @@ class SaveProfileImageJobTest extends TestCase
$job = new SaveProfileImage($mf);
$job->handle($authorship);
$this->assertFileEquals(
public_path() . '/assets/profile-images/default-image',
public_path() . '/assets/profile-images/example.org/image'
public_path().'/assets/profile-images/default-image',
public_path().'/assets/profile-images/example.org/image'
);
}
@ -133,7 +133,7 @@ class SaveProfileImageJobTest extends TestCase
$job = new SaveProfileImage($mf);
$job->handle($authorship);
$this->assertFileExists(public_path() . '/assets/profile-images/example.org/image');
$this->assertFileExists(public_path().'/assets/profile-images/example.org/image');
}
#[Test]
@ -164,6 +164,6 @@ class SaveProfileImageJobTest extends TestCase
$job = new SaveProfileImage($mf);
$job->handle($authorship);
$this->assertFileExists(public_path() . '/assets/profile-images/example.org/image');
$this->assertFileExists(public_path().'/assets/profile-images/example.org/image');
}
}

View file

@ -7,6 +7,7 @@ namespace Tests\Unit\Jobs;
use App\Jobs\SaveScreenshot;
use App\Models\Bookmark;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
@ -27,7 +28,7 @@ class SaveScreenshotJobTest extends TestCase
$guzzleMock = new MockHandler([
new Response(201, ['Content-Type' => 'application/json'], '{"data":{"id":"68d52633-e170-465e-b13e-746c97d01ffb","job_id":null,"status":"finished","credits":null,"code":null,"message":null,"percent":100,"operation":"capture-website","engine":"chrome","engine_version":"107","result":null,"created_at":"2023-01-07T21:05:48+00:00","started_at":null,"ended_at":null,"retry_of_task_id":null,"copy_of_task_id":null,"user_id":61485254,"priority":-10,"host_name":null,"storage":"ceph-fra","depends_on_task_ids":[],"links":{"self":"https:\/\/api.cloudconvert.com\/v2\/tasks\/68d52633-e170-465e-b13e-746c97d01ffb"}}}'),
new Response(201, ['Content-Type' => 'application/json'], '{"data":{"id":"27f33137-cc03-4468-aba4-1e1aa8c096fb","job_id":null,"status":"finished","credits":null,"code":null,"message":null,"percent":100,"operation":"export\/url","result":null,"created_at":"2023-01-07T21:10:02+00:00","started_at":null,"ended_at":null,"retry_of_task_id":null,"copy_of_task_id":null,"user_id":61485254,"priority":-10,"host_name":null,"storage":"ceph-fra","depends_on_task_ids":["68d52633-e170-465e-b13e-746c97d01ffb"],"links":{"self":"https:\/\/api.cloudconvert.com\/v2\/tasks\/27f33137-cc03-4468-aba4-1e1aa8c096fb"}}}'),
new Response(200, ['Content-Type' => 'image/png'], fopen(__DIR__ . '/../../theverge.com.png', 'rb')),
new Response(200, ['Content-Type' => 'image/png'], fopen(__DIR__.'/../../theverge.com.png', 'rb')),
]);
$guzzleHandler = HandlerStack::create($guzzleMock);
$guzzleClient = new Client(['handler' => $guzzleHandler]);
@ -45,7 +46,7 @@ class SaveScreenshotJobTest extends TestCase
}
// Retry connection exceptions
if ($exception instanceof \GuzzleHttp\Exception\ConnectException) {
if ($exception instanceof ConnectException) {
return true;
}
@ -82,7 +83,7 @@ class SaveScreenshotJobTest extends TestCase
$bookmark->refresh();
$this->assertEquals('68d52633-e170-465e-b13e-746c97d01ffb', $bookmark->screenshot);
Storage::disk('public')->assertExists('/assets/img/bookmarks/' . $bookmark->screenshot . '.png');
Storage::disk('public')->assertExists('/assets/img/bookmarks/'.$bookmark->screenshot.'.png');
}
#[Test]
@ -92,7 +93,7 @@ class SaveScreenshotJobTest extends TestCase
$guzzleMock = new MockHandler([
new Response(201, ['Content-Type' => 'application/json'], '{"id":1,"data":{"id":"68d52633-e170-465e-b13e-746c97d01ffb","job_id":null,"status":"waiting","credits":null,"code":null,"message":null,"percent":100,"operation":"capture-website","engine":"chrome","engine_version":"107","result":null,"created_at":"2023-01-07T21:05:48+00:00","started_at":null,"ended_at":null,"retry_of_task_id":null,"copy_of_task_id":null,"user_id":61485254,"priority":-10,"host_name":null,"storage":"ceph-fra","depends_on_task_ids":[],"links":{"self":"https:\/\/api.cloudconvert.com\/v2\/tasks\/68d52633-e170-465e-b13e-746c97d01ffb"}}}'),
new Response(201, ['Content-Type' => 'application/json'], '{"id":2,"data":{"id":"27f33137-cc03-4468-aba4-1e1aa8c096fb","job_id":null,"status":"waiting","credits":null,"code":null,"message":null,"percent":100,"operation":"export\/url","result":null,"created_at":"2023-01-07T21:10:02+00:00","started_at":null,"ended_at":null,"retry_of_task_id":null,"copy_of_task_id":null,"user_id":61485254,"priority":-10,"host_name":null,"storage":"ceph-fra","depends_on_task_ids":["68d52633-e170-465e-b13e-746c97d01ffb"],"links":{"self":"https:\/\/api.cloudconvert.com\/v2\/tasks\/27f33137-cc03-4468-aba4-1e1aa8c096fb"}}}'),
new Response(200, ['Content-Type' => 'image/png'], fopen(__DIR__ . '/../../theverge.com.png', 'rb')),
new Response(200, ['Content-Type' => 'image/png'], fopen(__DIR__.'/../../theverge.com.png', 'rb')),
]);
$guzzleHandler = HandlerStack::create($guzzleMock);
$guzzleClient = new Client(['handler' => $guzzleHandler]);
@ -115,7 +116,7 @@ class SaveScreenshotJobTest extends TestCase
}
// Retry connection exceptions
if ($exception instanceof \GuzzleHttp\Exception\ConnectException) {
if ($exception instanceof ConnectException) {
return true;
}
@ -152,7 +153,7 @@ class SaveScreenshotJobTest extends TestCase
$bookmark->refresh();
$this->assertEquals('68d52633-e170-465e-b13e-746c97d01ffb', $bookmark->screenshot);
Storage::disk('public')->assertExists('/assets/img/bookmarks/' . $bookmark->screenshot . '.png');
Storage::disk('public')->assertExists('/assets/img/bookmarks/'.$bookmark->screenshot.'.png');
// Also assert we made the correct number of requests
$this->assertCount(2, $container);
// However with retries there should be more than 4 responses for the 2 requests

View file

@ -29,7 +29,7 @@ class SendWebMentionJobTest extends TestCase
{
$url = 'https://example.org/webmention';
$mock = new MockHandler([
new Response(200, ['Link' => '<' . $url . '>; rel="webmention"']),
new Response(200, ['Link' => '<'.$url.'>; rel="webmention"']),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);

View file

@ -25,7 +25,7 @@ class SyndicateNoteToBlueskyJobTest extends TestCase
$faker = Factory::create();
$randomNumber = $faker->randomNumber();
$mock = new MockHandler([
new Response(201, ['Location' => 'https://bsky.app/profile/jonnybarnes.uk/' . $randomNumber]),
new Response(201, ['Location' => 'https://bsky.app/profile/jonnybarnes.uk/'.$randomNumber]),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
@ -35,7 +35,7 @@ class SyndicateNoteToBlueskyJobTest extends TestCase
$job->handle($client);
$this->assertDatabaseHas('notes', [
'bluesky_url' => 'https://bsky.app/profile/jonnybarnes.uk/' . $randomNumber,
'bluesky_url' => 'https://bsky.app/profile/jonnybarnes.uk/'.$randomNumber,
]);
}
@ -49,7 +49,7 @@ class SyndicateNoteToBlueskyJobTest extends TestCase
$container = [];
$history = Middleware::history($container);
$mock = new MockHandler([
new Response(201, ['Location' => 'https://bsky.app/profile/jonnybarnes.uk/' . $randomNumber]),
new Response(201, ['Location' => 'https://bsky.app/profile/jonnybarnes.uk/'.$randomNumber]),
]);
$handler = HandlerStack::create($mock);
$handler->push($history);
@ -60,7 +60,7 @@ class SyndicateNoteToBlueskyJobTest extends TestCase
$job->handle($client);
$this->assertDatabaseHas('notes', [
'bluesky_url' => 'https://bsky.app/profile/jonnybarnes.uk/' . $randomNumber,
'bluesky_url' => 'https://bsky.app/profile/jonnybarnes.uk/'.$randomNumber,
]);
$expectedRequestContent = '{"type":["h-entry"],"properties":{"content":["This is a **test**"]}}';

View file

@ -25,7 +25,7 @@ class SyndicateNoteToMastodonJobTest extends TestCase
$faker = Factory::create();
$randomNumber = $faker->randomNumber();
$mock = new MockHandler([
new Response(201, ['Location' => 'https://mastodon.example/@jonny/' . $randomNumber]),
new Response(201, ['Location' => 'https://mastodon.example/@jonny/'.$randomNumber]),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
@ -35,7 +35,7 @@ class SyndicateNoteToMastodonJobTest extends TestCase
$job->handle($client);
$this->assertDatabaseHas('notes', [
'mastodon_url' => 'https://mastodon.example/@jonny/' . $randomNumber,
'mastodon_url' => 'https://mastodon.example/@jonny/'.$randomNumber,
]);
}
@ -49,7 +49,7 @@ class SyndicateNoteToMastodonJobTest extends TestCase
$container = [];
$history = Middleware::history($container);
$mock = new MockHandler([
new Response(201, ['Location' => 'https://mastodon.example/@jonny/' . $randomNumber]),
new Response(201, ['Location' => 'https://mastodon.example/@jonny/'.$randomNumber]),
]);
$handler = HandlerStack::create($mock);
$handler->push($history);
@ -60,7 +60,7 @@ class SyndicateNoteToMastodonJobTest extends TestCase
$job->handle($client);
$this->assertDatabaseHas('notes', [
'mastodon_url' => 'https://mastodon.example/@jonny/' . $randomNumber,
'mastodon_url' => 'https://mastodon.example/@jonny/'.$randomNumber,
]);
$expectedRequestContent = '{"type":["h-entry"],"properties":{"content":["This is a **test**"]}}';

View file

@ -7,6 +7,7 @@ namespace Tests\Unit;
use App\Models\Media;
use App\Models\Note;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
@ -38,4 +39,68 @@ class MediaTest extends TestCase
$this->assertEquals($absoluteUrl, $media->url);
}
#[Test]
public function local_paths_get_storage_url_prepended(): void
{
$media = new Media;
$media->path = 'photo.jpg';
$this->assertEquals(config('app.url').'/storage/photo.jpg', $media->url);
}
#[Test]
public function medium_url_returns_resized_path(): void
{
$media = new Media;
$media->path = 'photo.jpg';
$this->assertEquals(config('app.url').'/storage/photo-medium.jpg', $media->mediumurl);
}
#[Test]
public function small_url_returns_resized_path(): void
{
$media = new Media;
$media->path = 'photo.jpg';
$this->assertEquals(config('app.url').'/storage/photo-small.jpg', $media->smallurl);
}
#[Test]
public function size_url_handles_dotted_basename(): void
{
$media = new Media;
$media->path = 'file.name.png';
$this->assertEquals(config('app.url').'/storage/file.name-medium.png', $media->mediumurl);
}
/**
* @dataProvider mimeTypeProvider
*/
#[DataProvider('mimeTypeProvider')]
public function mimetype_returns_correct_mime_for_extension(string $path, string $expected): void
{
$media = new Media;
$media->path = $path;
$this->assertEquals($expected, $media->mimetype);
}
public static function mimeTypeProvider(): array
{
return [
['photo.gif', 'image/gif'],
['photo.jpeg', 'image/jpeg'],
['photo.jpg', 'image/jpeg'],
['photo.png', 'image/png'],
['photo.svg', 'image/svg+xml'],
['photo.tiff', 'image/tiff'],
['photo.webp', 'image/webp'],
['video.mp4', 'video/mp4'],
['video.mkv', 'video/mkv'],
['file.bin', 'application/octet-stream'],
];
}
}

View file

@ -0,0 +1,110 @@
<?php
declare(strict_types=1);
namespace Tests\Unit;
use App\Services\Micropub\Data\UpdateData;
use Illuminate\Http\Request;
use JsonException;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class MicropubUpdateDataTest extends TestCase
{
/**
* @throws JsonException
*/
#[Test]
public function from_request_parses_json_body(): void
{
$request = Request::create('/micropub', 'POST', [], [], [], [
'CONTENT_TYPE' => 'application/json',
], json_encode([
'token_data' => ['me' => 'https://example.com'],
'url' => 'https://example.com/notes/1',
'replace' => ['content' => ['new content']],
'add' => ['syndication' => ['https://twitter.com']],
'delete' => ['category' => ['old-tag']],
], JSON_THROW_ON_ERROR));
$dto = UpdateData::fromRequest($request);
$this->assertEquals(['me' => 'https://example.com'], $dto->tokenData);
$this->assertEquals('https://example.com/notes/1', $dto->updateUrl);
$this->assertEquals(['content' => ['new content']], $dto->updateReplace);
$this->assertEquals(['syndication' => ['https://twitter.com']], $dto->updateAdd);
$this->assertEquals(['category' => ['old-tag']], $dto->updateDelete);
}
#[Test]
public function from_request_parses_form_encoded_body(): void
{
$request = Request::create('/micropub', 'POST', [
'token_data' => ['me' => 'https://example.com'],
'url' => 'https://example.com/notes/1',
'replace' => ['content' => ['new content']],
'add' => ['syndication' => ['https://twitter.com']],
'delete' => ['category' => ['old-tag']],
]);
$dto = UpdateData::fromRequest($request);
$this->assertEquals(['me' => 'https://example.com'], $dto->tokenData);
$this->assertEquals('https://example.com/notes/1', $dto->updateUrl);
$this->assertEquals(['content' => ['new content']], $dto->updateReplace);
$this->assertEquals(['syndication' => ['https://twitter.com']], $dto->updateAdd);
$this->assertEquals(['category' => ['old-tag']], $dto->updateDelete);
}
/**
* @throws JsonException
*/
#[Test]
public function from_request_nullable_fields_default_to_null(): void
{
$request = Request::create('/micropub', 'POST', [], [], [], [
'CONTENT_TYPE' => 'application/json',
], json_encode([
'token_data' => ['me' => 'https://example.com'],
'url' => 'https://example.com/notes/1',
], JSON_THROW_ON_ERROR));
$dto = UpdateData::fromRequest($request);
$this->assertNull($dto->updateReplace);
$this->assertNull($dto->updateAdd);
$this->assertNull($dto->updateDelete);
}
#[Test]
public function from_array_maps_all_fields(): void
{
$dto = UpdateData::fromArray([
'token_data' => ['me' => 'https://example.com'],
'update_url' => 'https://example.com/notes/1',
'update_replace' => ['content' => ['updated']],
'update_add' => ['category' => ['new-tag']],
'update_delete' => ['syndication' => ['https://old.example.com']],
]);
$this->assertEquals(['me' => 'https://example.com'], $dto->tokenData);
$this->assertEquals('https://example.com/notes/1', $dto->updateUrl);
$this->assertEquals(['content' => ['updated']], $dto->updateReplace);
$this->assertEquals(['category' => ['new-tag']], $dto->updateAdd);
$this->assertEquals(['syndication' => ['https://old.example.com']], $dto->updateDelete);
}
#[Test]
public function from_array_nullable_fields_default_to_null(): void
{
$dto = UpdateData::fromArray([
'token_data' => ['me' => 'https://example.com'],
]);
$this->assertNull($dto->updateUrl);
$this->assertNull($dto->updateReplace);
$this->assertNull($dto->updateAdd);
$this->assertNull($dto->updateDelete);
}
}

View file

@ -31,7 +31,7 @@ class NotesTest extends TestCase
public function get_note_attribute_method_calls_sub_methods(): void
{
// phpcs:ignore
$expected = '<p>Having a <a rel="tag" class="p-category" href="/notes/tagged/beer">#beer</a> at the local. 🍺</p>' . PHP_EOL;
$expected = '<p>Having a <a rel="tag" class="p-category" href="/notes/tagged/beer">#beer</a> at the local. 🍺</p>'.PHP_EOL;
$note = Note::factory([
'note' => 'Having a #beer at the local. 🍺',
])->create();
@ -53,7 +53,7 @@ class NotesTest extends TestCase
<img class="social-icon" src="/assets/img/social-icons/twitter.svg" alt=""> t
</a>
</span>
</span></p>' . PHP_EOL;
</span></p>'.PHP_EOL;
Contact::factory()->create([
'nick' => 'tantek',
'name' => 'Tantek Çelik',
@ -98,7 +98,7 @@ class NotesTest extends TestCase
<img class="social-icon" src="/assets/img/social-icons/facebook.svg" alt=""> Facebook
</a>
</span>
</span></p>' . PHP_EOL;
</span></p>'.PHP_EOL;
$this->assertEquals($expected, $note->note);
}
@ -108,7 +108,7 @@ class NotesTest extends TestCase
#[Test]
public function twitter_link_is_created_when_no_contact_found(): void
{
$expected = '<p>Hi <a href="https://twitter.com/bob">@bob</a></p>' . PHP_EOL;
$expected = '<p>Hi <a href="https://twitter.com/bob">@bob</a></p>'.PHP_EOL;
$note = Note::factory()->create([
'note' => 'Hi @bob',
]);
@ -312,7 +312,7 @@ class NotesTest extends TestCase
$note->media()->save($media);
$expected = 'A nice image
<img src="' . config('app.url') . '/storage/test.png" alt="">';
<img src="'.config('app.url').'/storage/test.png" alt="">';
$this->assertEquals($expected, $note->content);
}
@ -329,7 +329,7 @@ class NotesTest extends TestCase
$note->media()->save($media);
$expected = 'A nice video
<video src="' . config('app.url') . '/storage/test.mkv">';
<video src="'.config('app.url').'/storage/test.mkv">';
$this->assertEquals($expected, $note->content);
}
@ -346,7 +346,7 @@ class NotesTest extends TestCase
$note->media()->save($media);
$expected = 'Some nice audio
<audio src="' . config('app.url') . '/storage/test.flac">';
<audio src="'.config('app.url').'/storage/test.flac">';
$this->assertEquals($expected, $note->content);
}
@ -378,29 +378,11 @@ class NotesTest extends TestCase
]);
$this->assertSame(
'<p>The best search engine? <a href="https://kagi.com">https://kagi.com</a></p>' . PHP_EOL,
'<p>The best search engine? <a href="https://kagi.com">https://kagi.com</a></p>'.PHP_EOL,
$note->note
);
}
/**
* For now, just reply on a cached object instead of actually querying Twitter.
*/
#[Test]
public function check_in_reply_to_is_twitter_link(): void
{
$tempContent = (object) [
'html' => 'something random',
];
Cache::put('933662564587855877', $tempContent);
$note = Note::factory()->create([
'in_reply_to' => 'https://twitter.com/someRando/status/933662564587855877',
]);
$this->assertEquals($tempContent, $note->twitter);
}
#[Test]
public function latitude_and_longitude_can_be_parsed_from_plain_location(): void
{
@ -427,7 +409,7 @@ class NotesTest extends TestCase
#[Test]
public function mastodon_usernames_are_parsed_correctly(): void
{
$expected = '<p>Hi <a href="https://phpc.social/@freekmurze">@freekmurze@phpc.social</a> how are you?</p>' . PHP_EOL;
$expected = '<p>Hi <a href="https://phpc.social/@freekmurze">@freekmurze@phpc.social</a> how are you?</p>'.PHP_EOL;
$note = Note::factory()->create([
'note' => 'Hi @freekmurze@phpc.social how are you?',
]);

View file

@ -46,7 +46,7 @@ class PlacesTest extends TestCase
$place = Place::factory()->create([
'name' => 'The Bridgewater Pub',
]);
$this->assertEquals(config('app.url') . '/places/the-bridgewater-pub', $place->uri);
$this->assertEquals(config('app.url').'/places/the-bridgewater-pub', $place->uri);
}
#[Test]

View file

@ -6,10 +6,8 @@ namespace Tests\Unit;
use App\Models\Note;
use App\Models\WebMention;
use Codebird\Codebird;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
@ -82,41 +80,6 @@ class WebMentionTest extends TestCase
$this->assertEquals($expected, $webmention->createPhotoLink($twitterProfileImage));
}
#[Test]
public function create_photo_link_returns_cached_twitter_photo_links(): void
{
$webmention = new WebMention;
$twitterURL = 'https://twitter.com/example';
$expected = 'https://pbs.twimg.com/static_profile_link.jpg';
Cache::put($twitterURL, $expected, 1);
$this->assertEquals($expected, $webmention->createPhotoLink($twitterURL));
}
#[Test]
public function create_photo_link_resolves_twitter_photo_links(): void
{
$info = (object) [
'profile_image_url_https' => 'https://pbs.twimg.com/static_profile_link.jpg',
];
$codebirdMock = $this->createPartialMock(Codebird::class, ['__call']);
$codebirdMock->method('__call')
->with('users_show', $this->anything())
->willReturn($info);
$this->app->instance(Codebird::class, $codebirdMock);
Cache::shouldReceive('has')
->once()
->andReturn(false);
Cache::shouldReceive('put')
->once()
->andReturn(true);
$webmention = new WebMention;
$twitterURL = 'https://twitter.com/example';
$expected = 'https://pbs.twimg.com/static_profile_link.jpg';
$this->assertEquals($expected, $webmention->createPhotoLink($twitterURL));
}
#[Test]
public function get_reply_attribute_defaults_to_null(): void
{
@ -131,4 +94,37 @@ class WebMentionTest extends TestCase
$webmention->mf2 = json_encode(['no_html' => 'found_here']);
$this->assertNull($webmention->reply);
}
#[Test]
public function author_attribute_returns_null_when_mf2_is_null(): void
{
$webmention = new WebMention;
$webmention->mf2 = null;
$this->assertNull($webmention->author);
}
#[Test]
public function author_attribute_returns_hcard_without_photo_key_when_no_photo_present(): void
{
$webmention = new WebMention;
$webmention->mf2 = json_encode([
'items' => [[
'type' => ['h-entry'],
'properties' => [
'author' => [[
'type' => ['h-card'],
'properties' => [
'name' => ['Test Person'],
'url' => ['https://example.com'],
],
]],
'content' => ['hello'],
],
]],
]);
$hCard = $webmention->author;
$this->assertNotNull($hCard);
$this->assertArrayNotHasKey('photo', $hCard['properties'] ?? []);
}
}