feat: ship creator journey v2 and profile updates
This commit is contained in:
126
tests/Feature/ContentTypeDynamicRoutingTest.php
Normal file
126
tests/Feature/ContentTypeDynamicRoutingTest.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
use App\Services\ArtworkService;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
function dynamicRoutingEmptyPaginator(string $path = '/'): LengthAwarePaginator
|
||||
{
|
||||
return (new LengthAwarePaginator(collect(), 0, 20, 1))->setPath($path);
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
$artworksMock = \Mockery::mock(ArtworkService::class);
|
||||
$artworksMock->shouldReceive('getFeaturedArtworks')->andReturn(dynamicRoutingEmptyPaginator('/'))->byDefault();
|
||||
$artworksMock->shouldReceive('getLatestArtworks')->andReturn(collect())->byDefault();
|
||||
$this->app->instance(ArtworkService::class, $artworksMock);
|
||||
|
||||
$this->contentTypeId = DB::table('content_types')->insertGetId([
|
||||
'name' => 'Digital Art',
|
||||
'slug' => 'digital-art',
|
||||
'description' => 'Digital art uploads',
|
||||
'order' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
DB::table('content_type_slug_histories')->insert([
|
||||
'content_type_id' => $this->contentTypeId,
|
||||
'old_slug' => 'concept-art',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
});
|
||||
|
||||
it('redirects old explore content type slugs to the current canonical slug', function () {
|
||||
$this->get('/explore/concept-art?sort=latest')
|
||||
->assertRedirect('/digital-art?sort=latest');
|
||||
});
|
||||
|
||||
it('redirects old rss explore slugs while preserving mode and query string', function () {
|
||||
$this->get('/rss/explore/concept-art/trending?limit=10')
|
||||
->assertRedirect('/rss/explore/digital-art/trending?limit=10');
|
||||
});
|
||||
|
||||
it('redirects old artwork paths to the current canonical content type slug', function () {
|
||||
$this->get('/concept-art/fantasy/castle-sunrise')
|
||||
->assertRedirect('/digital-art/fantasy/castle-sunrise');
|
||||
});
|
||||
|
||||
it('returns 404 for unknown dynamic content type slugs', function () {
|
||||
$this->get('/made-up-content-type')
|
||||
->assertNotFound();
|
||||
});
|
||||
|
||||
it('lists resolver-backed content types on the rss feeds page', function () {
|
||||
$this->get('/rss-feeds')
|
||||
->assertOk()
|
||||
->assertSee('/rss/explore/digital-art', false)
|
||||
->assertSee('Digital Art');
|
||||
});
|
||||
|
||||
it('keeps static routes ahead of dynamic content type routes even with bad data', function () {
|
||||
DB::table('content_types')->insert([
|
||||
'name' => 'RSS Collision',
|
||||
'slug' => 'rss',
|
||||
'description' => 'Invalid but useful for route-order regression coverage',
|
||||
'order' => 99,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$this->get('/rss')
|
||||
->assertOk()
|
||||
->assertHeader('Content-Type', 'application/rss+xml; charset=utf-8');
|
||||
});
|
||||
|
||||
it('blocks reserved content type slugs in the admin save flow', function () {
|
||||
$admin = User::factory()->create(['role' => 'admin']);
|
||||
|
||||
$this->withoutMiddleware();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->post(route('admin.cp.artworks.content-types.store'), [
|
||||
'name' => 'Reserved Help',
|
||||
'slug' => 'help',
|
||||
'description' => 'Should be rejected',
|
||||
'order' => 1,
|
||||
])
|
||||
->assertStatus(422)
|
||||
->assertSeeText('This content type slug is reserved by the public routing layer.');
|
||||
});
|
||||
|
||||
it('allows updating an existing content type that already uses the same reserved slug', function () {
|
||||
$admin = User::factory()->create(['role' => 'admin']);
|
||||
|
||||
$contentTypeId = DB::table('content_types')->insertGetId([
|
||||
'name' => 'Members',
|
||||
'slug' => 'members',
|
||||
'description' => 'Legacy reserved slug still in use',
|
||||
'order' => 5,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$this->withoutMiddleware();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->post(route('admin.cp.artworks.content-types.update', ['id' => $contentTypeId]), [
|
||||
'name' => 'Members Updated',
|
||||
'slug' => 'members',
|
||||
'description' => 'Updated without renaming slug',
|
||||
'order' => 5,
|
||||
])
|
||||
->assertRedirect(route('admin.cp.artworks.content-types.main'));
|
||||
|
||||
$this->assertDatabaseHas('content_types', [
|
||||
'id' => $contentTypeId,
|
||||
'slug' => 'members',
|
||||
'name' => 'Members Updated',
|
||||
'description' => 'Updated without renaming slug',
|
||||
]);
|
||||
});
|
||||
Reference in New Issue
Block a user