Make the image optional for WordPress posts too

Some blog posts just don't have one. WordPressPublisher no longer
rejects publishing a type=blog post without image_url — it uploads
and attaches it as the featured image when present, and simply skips
that step (no featured_media set) otherwise.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
m105
2026-07-21 20:07:47 +03:00
co-authored by Claude Sonnet 5
parent 42abc658f2
commit 4b3af4cc89
5 changed files with 70 additions and 45 deletions
+36 -13
View File
@@ -29,20 +29,9 @@ test('it fails when the post has no title', function () {
->assertExitCode(1);
});
test('it fails when the post has no image', function () {
$site = Site::factory()->wordpress()->create();
$post = Post::factory()->create(['site_id' => $site->id, 'type' => 'blog', 'title' => 'Hi', 'image_url' => null]);
$this->artisan('posts:publish', ['post' => $post->id])
->expectsOutputToContain('no image')
->assertExitCode(1);
expect($post->fresh()->status)->toBe($post->status);
});
test('it fails when the site is not configured as WordPress', function () {
$site = Site::factory()->create(['cms_type' => 'custom']);
$post = Post::factory()->create(['site_id' => $site->id, 'type' => 'blog', 'title' => 'Hi', 'image_url' => 'https://example.com/image.jpg']);
$post = Post::factory()->create(['site_id' => $site->id, 'type' => 'blog', 'title' => 'Hi']);
$this->artisan('posts:publish', ['post' => $post->id])
->expectsOutputToContain('not configured as WordPress')
@@ -51,13 +40,47 @@ test('it fails when the site is not configured as WordPress', function () {
test('it fails when the WordPress site is missing credentials', function () {
$site = Site::factory()->create(['cms_type' => 'wordpress', 'wp_username' => null, 'wp_app_password' => null]);
$post = Post::factory()->create(['site_id' => $site->id, 'type' => 'blog', 'title' => 'Hi', 'image_url' => 'https://example.com/image.jpg']);
$post = Post::factory()->create(['site_id' => $site->id, 'type' => 'blog', 'title' => 'Hi']);
$this->artisan('posts:publish', ['post' => $post->id])
->expectsOutputToContain('missing WordPress credentials')
->assertExitCode(1);
});
test('it publishes successfully without an image', function () {
Http::fake([
'*/wp-json/wp/v2/posts' => Http::response([
'id' => 42,
'link' => 'https://wp.example.com/2026/07/hello-world/',
], 201),
]);
$site = Site::factory()->wordpress()->create(['url' => 'https://wp.example.com']);
$post = Post::factory()->create([
'site_id' => $site->id,
'type' => 'blog',
'title' => 'Hello World',
'body' => 'Post content',
'image_url' => null,
'status' => 'draft',
]);
$this->artisan('posts:publish', ['post' => $post->id])
->expectsOutputToContain('"success":true')
->assertExitCode(0);
expect($post->fresh())
->status->toBe('published')
->published_url->toBe('https://wp.example.com/2026/07/hello-world/');
Http::assertNotSent(fn ($request) => $request->url() === 'https://wp.example.com/wp-json/wp/v2/media');
Http::assertSent(function ($request) {
return $request->url() === 'https://wp.example.com/wp-json/wp/v2/posts'
&& ! array_key_exists('featured_media', $request->data());
});
});
test('it publishes successfully, uploading the image as the featured media', function () {
Http::fake([
'https://images.example.com/*' => Http::response('fake-image-bytes', 200, ['Content-Type' => 'image/jpeg']),