Files
einundzwanzig-app/tests/Feature/Api/MeetupWriteApiTest.php
T
HolgerHatGarKeineNode f5cf85b438 Add restore_point functionality to Meetups
- 💾 Introduced `restore_point` JSON column in `meetups` table for saving and restoring master data.
- 🛠️ Added methods `captureRestorePoint` and `restoreFromRestorePoint` to `Meetup` model for managing restore points.
- 🔒 Implemented authorization for updating meetups via `updateViaPortal` policy to include pivot members.
- 🔗 Created Artisan commands `meetups:snapshot` and `meetups:restore` for managing restore points from CLI.
- 🚦 Added rate limiter to restrict excessive update attempts in Livewire meetup editing.
-  Developed exhaustive feature tests for snapshot and restore actions, portal editing rules, and rate limiting.
2026-06-10 10:56:38 +02:00

97 lines
2.9 KiB
PHP

<?php
use App\Models\City;
use App\Models\Meetup;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
it('rejects a guest', function () {
$this->postJson('/api/meetup', [
'name' => 'Einundzwanzig Ansbach',
'city_id' => City::factory()->create()->id,
])->assertUnauthorized();
});
it('lets an authenticated user create', function () {
Sanctum::actingAs($user = User::factory()->create());
$this->postJson('/api/meetup', [
'name' => 'Einundzwanzig Ansbach',
'city_id' => City::factory()->create()->id,
])
->assertCreated()
->assertJsonPath('data.name', 'Einundzwanzig Ansbach');
$this->assertDatabaseHas('meetups', [
'name' => 'Einundzwanzig Ansbach',
'created_by' => $user->id,
]);
});
it('fails validation', function () {
Sanctum::actingAs(User::factory()->create());
$this->postJson('/api/meetup', [])
->assertUnprocessable()
->assertJsonValidationErrors(['name', 'city_id']);
});
it('lets the owner update', function () {
Sanctum::actingAs($user = User::factory()->create());
$meetup = Meetup::factory()->create(['created_by' => $user->id]);
$this->patchJson('/api/meetup/'.$meetup->id, [
'name' => 'Plan B Lugano',
])
->assertSuccessful()
->assertJsonPath('data.name', 'Plan B Lugano');
});
it('forbids updating someone elses', function () {
$owner = User::factory()->create();
$meetup = Meetup::factory()->create(['created_by' => $owner->id]);
Sanctum::actingAs(User::factory()->create());
$this->patchJson('/api/meetup/'.$meetup->id, [
'name' => 'Plan B Lugano',
])->assertForbidden();
});
it('forbids updating as a pivot member who is not the creator', function () {
$owner = User::factory()->create();
$meetup = Meetup::factory()->create(['created_by' => $owner->id]);
Sanctum::actingAs($member = User::factory()->create());
$meetup->users()->attach($member);
$this->patchJson('/api/meetup/'.$meetup->id, [
'name' => 'Plan B Lugano',
])->assertForbidden();
});
it('returns only own in mine index', function () {
Sanctum::actingAs($user = User::factory()->create());
$other = User::factory()->create();
Meetup::factory()->count(2)->create(['created_by' => $user->id]);
Meetup::factory()->create(['created_by' => $other->id]);
$response = $this->getJson('/api/my-meetups');
$response->assertSuccessful();
expect($response->json('data'))->toHaveCount(2);
collect($response->json('data'))->each(
fn ($meetup) => expect($meetup['created_by'])->toBe($user->id)
);
});
it('forbids viewing someone elses in mine show', function () {
$owner = User::factory()->create();
$meetup = Meetup::factory()->create(['created_by' => $owner->id]);
Sanctum::actingAs(User::factory()->create());
$this->getJson('/api/my-meetups/'.$meetup->id)->assertForbidden();
});