145 lines
4.9 KiB
PHP
145 lines
4.9 KiB
PHP
<?php
|
|
|
|
use App\Enums\FollowStatus;
|
|
use App\Models\MealPosts;
|
|
use App\Models\PostReviews;
|
|
use App\Models\User;
|
|
use App\Models\UserBlock;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Laravel\Sanctum\Sanctum;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
it('blocks a user idempotently, removes follows, lists the block, and unblocks', function () {
|
|
$blocker = User::factory()->create();
|
|
$blocked = User::factory()->create();
|
|
|
|
$blocker->following()->attach($blocked, ['status' => FollowStatus::Accepted]);
|
|
$blocked->following()->attach($blocker, ['status' => FollowStatus::Accepted]);
|
|
|
|
Sanctum::actingAs($blocker);
|
|
|
|
$this->postJson("/api/users/{$blocked->id}/block")
|
|
->assertOk()
|
|
->assertJsonPath('code', 'USER_BLOCKED');
|
|
|
|
$this->postJson("/api/users/{$blocked->id}/block")->assertOk();
|
|
|
|
expect(UserBlock::query()->count())->toBe(1)
|
|
->and($blocker->following()->count())->toBe(0)
|
|
->and($blocker->followers()->count())->toBe(0);
|
|
|
|
$this->getJson('/api/me/blocked-users')
|
|
->assertOk()
|
|
->assertJsonCount(1, 'data')
|
|
->assertJsonPath('data.0.id', $blocked->id);
|
|
|
|
$this->deleteJson("/api/users/{$blocked->id}/block")->assertNoContent();
|
|
|
|
expect(UserBlock::query()->count())->toBe(0);
|
|
});
|
|
|
|
it('does not allow a user to block themselves', function () {
|
|
$user = User::factory()->create();
|
|
|
|
Sanctum::actingAs($user);
|
|
|
|
$this->postJson("/api/users/{$user->id}/block")
|
|
->assertUnprocessable()
|
|
->assertJsonPath('code', 'CANNOT_BLOCK_SELF');
|
|
});
|
|
|
|
it('requires authentication to manage blocks', function () {
|
|
$user = User::factory()->create();
|
|
|
|
$this->getJson('/api/me/blocked-users')->assertUnauthorized();
|
|
$this->postJson("/api/users/{$user->id}/block")->assertUnauthorized();
|
|
$this->deleteJson("/api/users/{$user->id}/block")->assertUnauthorized();
|
|
});
|
|
|
|
it('hides blocked users and prevents reciprocal content interactions', function () {
|
|
$viewer = User::factory()->create();
|
|
$blocked = User::factory()->create();
|
|
$neutral = User::factory()->create();
|
|
$blockedMeal = MealPosts::factory()->for($blocked, 'user')->create();
|
|
$neutralMeal = MealPosts::factory()->for($neutral, 'user')->create();
|
|
$blockedReview = PostReviews::query()->create([
|
|
'meal_post_id' => $neutralMeal->id,
|
|
'user_id' => $blocked->id,
|
|
'rating' => 4,
|
|
'comment' => 'Avis masqué.',
|
|
]);
|
|
|
|
UserBlock::factory()->create([
|
|
'blocker_id' => $viewer->id,
|
|
'blocked_id' => $blocked->id,
|
|
]);
|
|
|
|
Sanctum::actingAs($viewer);
|
|
|
|
$this->getJson('/api/meal-posts')
|
|
->assertOk()
|
|
->assertJsonFragment(['id' => $neutralMeal->id])
|
|
->assertJsonMissing(['id' => $blockedMeal->id]);
|
|
|
|
$this->getJson("/api/users/{$blocked->id}")->assertNotFound();
|
|
$this->getJson("/api/meal-posts/{$blockedMeal->id}")->assertNotFound();
|
|
$this->postJson("/api/users/{$blocked->id}/follow")->assertNotFound();
|
|
$this->postJson("/api/meal-posts/{$blockedMeal->id}/like")->assertNotFound();
|
|
$this->postJson("/api/meal-posts/{$blockedMeal->id}/reviews", [
|
|
'rating' => 5,
|
|
'comment' => 'Interaction interdite.',
|
|
])->assertNotFound();
|
|
|
|
$this->getJson("/api/meal-posts/{$neutralMeal->id}/reviews")
|
|
->assertOk()
|
|
->assertJsonMissing(['id' => $blockedReview->id]);
|
|
});
|
|
|
|
it('applies reciprocal exclusion when the other user initiated the block', function () {
|
|
$viewer = User::factory()->create();
|
|
$blocker = User::factory()->create();
|
|
$meal = MealPosts::factory()->for($blocker, 'user')->create();
|
|
|
|
UserBlock::factory()->create([
|
|
'blocker_id' => $blocker->id,
|
|
'blocked_id' => $viewer->id,
|
|
]);
|
|
|
|
Sanctum::actingAs($viewer);
|
|
|
|
$this->getJson('/api/meal-posts')
|
|
->assertOk()
|
|
->assertJsonMissing(['id' => $meal->id]);
|
|
$this->getJson("/api/users/{$blocker->id}")->assertNotFound();
|
|
$this->getJson("/api/meal-posts/{$meal->id}")->assertNotFound();
|
|
$this->postJson("/api/users/{$blocker->id}/follow")->assertNotFound();
|
|
});
|
|
|
|
it('keeps content hidden until both directional blocks are removed', function () {
|
|
$firstUser = User::factory()->create();
|
|
$secondUser = User::factory()->create();
|
|
$meal = MealPosts::factory()->for($secondUser, 'user')->create();
|
|
|
|
UserBlock::factory()->create([
|
|
'blocker_id' => $firstUser->id,
|
|
'blocked_id' => $secondUser->id,
|
|
]);
|
|
UserBlock::factory()->create([
|
|
'blocker_id' => $secondUser->id,
|
|
'blocked_id' => $firstUser->id,
|
|
]);
|
|
|
|
Sanctum::actingAs($firstUser);
|
|
|
|
$this->deleteJson("/api/users/{$secondUser->id}/block")->assertNoContent();
|
|
$this->getJson("/api/meal-posts/{$meal->id}")->assertNotFound();
|
|
|
|
UserBlock::query()
|
|
->where('blocker_id', $secondUser->id)
|
|
->where('blocked_id', $firstUser->id)
|
|
->delete();
|
|
|
|
$this->getJson("/api/meal-posts/{$meal->id}")->assertOk();
|
|
});
|