2026-10-17 15:56:58 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
use App\Models\Product;
|
|
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
|
|
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
|
|
|
|
|
|
function badgePayload(array $overrides = []): array
|
|
|
|
|
{
|
|
|
|
|
return array_merge([
|
|
|
|
|
'title' => 'Badge Product',
|
|
|
|
|
'description' => 'A product description',
|
|
|
|
|
'website_url' => 'https://example.com',
|
|
|
|
|
'category_id' => makeCategory()->id,
|
|
|
|
|
], $overrides);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
test('submitter ticks badges on create', function () {
|
|
|
|
|
$user = userWithRole('user');
|
|
|
|
|
|
|
|
|
|
$this->actingAs($user)->post(route('products.store'), badgePayload([
|
|
|
|
|
'eu_hosted' => 1,
|
|
|
|
|
'open_source' => 1,
|
|
|
|
|
]))->assertRedirect();
|
|
|
|
|
|
|
|
|
|
$product = Product::firstOrFail();
|
|
|
|
|
expect($product->eu_hosted)->toBeTrue()
|
|
|
|
|
->and($product->open_source)->toBeTrue()
|
|
|
|
|
->and($product->free_tier)->toBeFalse()
|
|
|
|
|
->and($product->eu_made)->toBeFalse();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('submitter can change badges while pending', function () {
|
|
|
|
|
$user = userWithRole('user');
|
|
|
|
|
$product = Product::factory()->pending()->create(['user_id' => $user->id]);
|
|
|
|
|
|
|
|
|
|
$this->actingAs($user)->put(route('products.update', $product), badgePayload([
|
|
|
|
|
'category_id' => $product->category_id,
|
|
|
|
|
'eu_made' => 1,
|
|
|
|
|
]))->assertRedirect();
|
|
|
|
|
|
|
|
|
|
expect($product->fresh()->eu_made)->toBeTrue();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('submitter cannot change badges after approval', function () {
|
|
|
|
|
$user = userWithRole('user');
|
|
|
|
|
$product = Product::factory()->approved()->create([
|
|
|
|
|
'user_id' => $user->id,
|
|
|
|
|
'eu_hosted' => false,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->actingAs($user)->put(route('products.update', $product), badgePayload([
|
|
|
|
|
'category_id' => $product->category_id,
|
|
|
|
|
'eu_hosted' => 1,
|
|
|
|
|
]))->assertRedirect();
|
|
|
|
|
|
|
|
|
|
expect($product->fresh()->eu_hosted)->toBeFalse();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('moderator can untick a badge on an approved product', function () {
|
|
|
|
|
$moderator = userWithRole('moderator');
|
|
|
|
|
$product = Product::factory()->approved()->create(['eu_hosted' => true]);
|
|
|
|
|
|
|
|
|
|
$this->actingAs($moderator)->put(route('products.update', $product), badgePayload([
|
|
|
|
|
'category_id' => $product->category_id,
|
|
|
|
|
]))->assertRedirect();
|
|
|
|
|
|
|
|
|
|
expect($product->fresh()->eu_hosted)->toBeFalse();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('edit form shows badges read-only to owner of approved product', function () {
|
|
|
|
|
$user = userWithRole('user');
|
|
|
|
|
$approved = Product::factory()->approved()->create(['user_id' => $user->id]);
|
|
|
|
|
$pending = Product::factory()->pending()->create(['user_id' => $user->id]);
|
|
|
|
|
|
|
|
|
|
$this->actingAs($user)->get(route('products.edit', $approved))
|
|
|
|
|
->assertOk()
|
|
|
|
|
->assertSee('EU hosted')
|
|
|
|
|
->assertSee('disabled')
|
|
|
|
|
->assertSee('Locked after approval');
|
|
|
|
|
|
|
|
|
|
$this->actingAs($user)->get(route('products.edit', $pending))
|
|
|
|
|
->assertOk()
|
|
|
|
|
->assertSee('EU hosted')
|
|
|
|
|
->assertDontSee('disabled')
|
|
|
|
|
->assertDontSee('Locked after approval');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('show page lists ticked badges only', function () {
|
|
|
|
|
$product = Product::factory()->approved()->create(['eu_hosted' => true]);
|
|
|
|
|
|
|
|
|
|
$this->get(route('products.show', $product))
|
|
|
|
|
->assertOk()
|
|
|
|
|
->assertSee('EU hosted')
|
|
|
|
|
->assertDontSee('EU made');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('existing product without new data still renders', function () {
|
|
|
|
|
$product = Product::factory()->approved()->create();
|
|
|
|
|
|
|
|
|
|
$this->get(route('products.show', $product))->assertOk();
|
|
|
|
|
});
|
2026-10-17 15:58:47 +03:00
|
|
|
|
|
|
|
|
test('badge-less product emits no badge markup on card or show page', function () {
|
|
|
|
|
$product = Product::factory()->approved()->create();
|
|
|
|
|
|
|
|
|
|
$this->get(route('products.show', $product))->assertOk()->assertDontSee('rounded-full text-xs font-medium', false);
|
|
|
|
|
|
|
|
|
|
$html = view('components.product.card', ['product' => $product->load(['user', 'category'])])->render();
|
|
|
|
|
expect($html)->not->toContain('mb-3 flex')
|
|
|
|
|
->and($html)->not->toContain('gap-1.5');
|
|
|
|
|
|
|
|
|
|
$badged = Product::factory()->approved()->create(['eu_made' => true])->load(['user', 'category']);
|
|
|
|
|
expect(view('components.product.card', ['product' => $badged])->render())->toContain('gap-1.5')->toContain('EU made');
|
|
|
|
|
});
|