Commit workspace changes
This commit is contained in:
216
tests/Feature/Studio/StudioNewsPagesTest.php
Normal file
216
tests/Feature/Studio/StudioNewsPagesTest.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Models\User;
|
||||
use Inertia\Testing\AssertableInertia;
|
||||
use Illuminate\Support\Carbon;
|
||||
use cPad\Plugins\News\Models\NewsArticle;
|
||||
use cPad\Plugins\News\Models\NewsCategory;
|
||||
use cPad\Plugins\News\Models\NewsTag;
|
||||
|
||||
function studioNewsCategory(array $attributes = []): NewsCategory
|
||||
{
|
||||
return NewsCategory::query()->create(array_merge([
|
||||
'name' => 'Studio News',
|
||||
'slug' => 'studio-news',
|
||||
'description' => 'Studio News category',
|
||||
'position' => 0,
|
||||
'is_active' => true,
|
||||
], $attributes));
|
||||
}
|
||||
|
||||
function studioNewsTag(array $attributes = []): NewsTag
|
||||
{
|
||||
return NewsTag::query()->create(array_merge([
|
||||
'name' => 'Studio',
|
||||
'slug' => 'studio',
|
||||
], $attributes));
|
||||
}
|
||||
|
||||
it('forbids newsroom studio pages for non moderators', function (): void {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('studio.news.index'))
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
it('renders newsroom studio pages for moderators', function (): void {
|
||||
$moderator = User::factory()->create([
|
||||
'role' => 'moderator',
|
||||
'username' => 'modnews',
|
||||
'name' => 'Moderator News',
|
||||
]);
|
||||
$author = User::factory()->create([
|
||||
'username' => 'writernews',
|
||||
'name' => 'Writer News',
|
||||
]);
|
||||
$category = studioNewsCategory();
|
||||
$tag = studioNewsTag();
|
||||
$article = NewsArticle::query()->create([
|
||||
'title' => 'Moderated newsroom article',
|
||||
'slug' => 'moderated-newsroom-article',
|
||||
'excerpt' => 'Studio-managed newsroom article.',
|
||||
'content' => 'Studio body',
|
||||
'author_id' => $author->id,
|
||||
'category_id' => $category->id,
|
||||
'type' => NewsArticle::TYPE_EDITORIAL,
|
||||
'status' => 'published',
|
||||
'editorial_status' => NewsArticle::EDITORIAL_STATUS_PUBLISHED,
|
||||
'published_at' => Carbon::parse('2026-04-05 09:30:00'),
|
||||
]);
|
||||
$article->tags()->sync([$tag->id]);
|
||||
|
||||
$this->actingAs($moderator)
|
||||
->get(route('studio.news.index'))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Studio/StudioNewsIndex')
|
||||
->where('title', 'Newsroom')
|
||||
->where('listing.items.0.title', 'Moderated newsroom article')
|
||||
->where('createUrl', route('studio.news.create')));
|
||||
|
||||
$this->actingAs($moderator)
|
||||
->get(route('studio.news.create'))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Studio/StudioNewsEditor')
|
||||
->where('title', 'Create article')
|
||||
->has('typeOptions')
|
||||
->has('statusOptions')
|
||||
->has('categoryOptions')
|
||||
->has('tagOptions')
|
||||
->where('defaultAuthor.id', $moderator->id));
|
||||
|
||||
$this->actingAs($moderator)
|
||||
->get(route('studio.news.categories'))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Studio/StudioNewsTaxonomies')
|
||||
->where('activeTab', 'categories')
|
||||
->has('categories.0')
|
||||
->has('tags.0'));
|
||||
|
||||
$this->actingAs($moderator)
|
||||
->get(route('studio.news.preview', ['article' => $article->id]))
|
||||
->assertOk()
|
||||
->assertSee('Preview mode')
|
||||
->assertSee('Moderated newsroom article');
|
||||
});
|
||||
|
||||
it('filters newsroom listing by status type and category', function (): void {
|
||||
$moderator = User::factory()->create([
|
||||
'role' => 'moderator',
|
||||
]);
|
||||
$category = studioNewsCategory([
|
||||
'name' => 'Filtered Category',
|
||||
'slug' => 'filtered-category',
|
||||
]);
|
||||
$otherCategory = studioNewsCategory([
|
||||
'name' => 'Other Category',
|
||||
'slug' => 'other-category',
|
||||
]);
|
||||
$author = User::factory()->create();
|
||||
|
||||
NewsArticle::query()->create([
|
||||
'title' => 'Keep Me',
|
||||
'slug' => 'keep-me',
|
||||
'excerpt' => 'Should survive filtering.',
|
||||
'content' => 'Content',
|
||||
'author_id' => $author->id,
|
||||
'category_id' => $category->id,
|
||||
'type' => NewsArticle::TYPE_ANNOUNCEMENT,
|
||||
'status' => 'draft',
|
||||
'editorial_status' => NewsArticle::EDITORIAL_STATUS_DRAFT,
|
||||
]);
|
||||
|
||||
NewsArticle::query()->create([
|
||||
'title' => 'Drop Me By Type',
|
||||
'slug' => 'drop-me-type',
|
||||
'excerpt' => 'Wrong type.',
|
||||
'content' => 'Content',
|
||||
'author_id' => $author->id,
|
||||
'category_id' => $category->id,
|
||||
'type' => NewsArticle::TYPE_EDITORIAL,
|
||||
'status' => 'draft',
|
||||
'editorial_status' => NewsArticle::EDITORIAL_STATUS_DRAFT,
|
||||
]);
|
||||
|
||||
NewsArticle::query()->create([
|
||||
'title' => 'Drop Me By Category',
|
||||
'slug' => 'drop-me-category',
|
||||
'excerpt' => 'Wrong category.',
|
||||
'content' => 'Content',
|
||||
'author_id' => $author->id,
|
||||
'category_id' => $otherCategory->id,
|
||||
'type' => NewsArticle::TYPE_ANNOUNCEMENT,
|
||||
'status' => 'draft',
|
||||
'editorial_status' => NewsArticle::EDITORIAL_STATUS_DRAFT,
|
||||
]);
|
||||
|
||||
$this->actingAs($moderator)
|
||||
->get(route('studio.news.index', [
|
||||
'status' => NewsArticle::EDITORIAL_STATUS_DRAFT,
|
||||
'type' => NewsArticle::TYPE_ANNOUNCEMENT,
|
||||
'category_id' => $category->id,
|
||||
]))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Studio/StudioNewsIndex')
|
||||
->where('listing.filters.status', NewsArticle::EDITORIAL_STATUS_DRAFT)
|
||||
->where('listing.filters.type', NewsArticle::TYPE_ANNOUNCEMENT)
|
||||
->where('listing.filters.category_id', $category->id)
|
||||
->has('listing.items', 1)
|
||||
->where('listing.items.0.title', 'Keep Me'));
|
||||
});
|
||||
|
||||
it('stores a newsroom draft with taxonomy links', function (): void {
|
||||
$moderator = User::factory()->create([
|
||||
'role' => 'moderator',
|
||||
'username' => 'editornews',
|
||||
'name' => 'Editor News',
|
||||
]);
|
||||
$author = User::factory()->create();
|
||||
$category = studioNewsCategory([
|
||||
'name' => 'Launches',
|
||||
'slug' => 'launches',
|
||||
]);
|
||||
$tag = studioNewsTag([
|
||||
'name' => 'Update',
|
||||
'slug' => 'update',
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($moderator)->post(route('studio.news.store'), [
|
||||
'title' => 'Stored newsroom draft',
|
||||
'slug' => 'stored-newsroom-draft',
|
||||
'excerpt' => 'Stored through the Studio newsroom form.',
|
||||
'content' => 'This article was created through the new Studio News flow.',
|
||||
'type' => NewsArticle::TYPE_ANNOUNCEMENT,
|
||||
'category_id' => $category->id,
|
||||
'author_id' => $author->id,
|
||||
'editorial_status' => NewsArticle::EDITORIAL_STATUS_DRAFT,
|
||||
'published_at' => null,
|
||||
'tag_ids' => [$tag->id],
|
||||
'is_featured' => true,
|
||||
'is_pinned' => false,
|
||||
'meta_title' => 'Stored newsroom draft meta',
|
||||
'meta_description' => 'Stored newsroom draft description',
|
||||
]);
|
||||
|
||||
$article = NewsArticle::query()->where('slug', 'stored-newsroom-draft')->firstOrFail();
|
||||
|
||||
$response->assertRedirect(route('studio.news.edit', ['article' => $article->id]));
|
||||
|
||||
$this->assertDatabaseHas('news_articles', [
|
||||
'id' => $article->id,
|
||||
'title' => 'Stored newsroom draft',
|
||||
'slug' => 'stored-newsroom-draft',
|
||||
'author_id' => $author->id,
|
||||
'category_id' => $category->id,
|
||||
'editorial_status' => NewsArticle::EDITORIAL_STATUS_DRAFT,
|
||||
'status' => 'draft',
|
||||
]);
|
||||
|
||||
expect($article->tags()->pluck('news_tags.id')->all())->toBe([$tag->id]);
|
||||
});
|
||||
Reference in New Issue
Block a user