From f106f2455aaa128e1e32f816f70809cd4f4b4730 Mon Sep 17 00:00:00 2001 From: philipp lang Date: Fri, 17 Feb 2023 01:50:44 +0100 Subject: [PATCH] Add Activity Store And Update --- app/Activity/Actions/ActivityUpdateAction.php | 65 +++++++++ routes/web.php | 2 + tests/Feature/Activity/UpdateTest.php | 129 +++++++++++++----- 3 files changed, 163 insertions(+), 33 deletions(-) create mode 100644 app/Activity/Actions/ActivityUpdateAction.php diff --git a/app/Activity/Actions/ActivityUpdateAction.php b/app/Activity/Actions/ActivityUpdateAction.php new file mode 100644 index 00000000..8ae53f60 --- /dev/null +++ b/app/Activity/Actions/ActivityUpdateAction.php @@ -0,0 +1,65 @@ +update($payload); + $activity->subactivities()->sync($payload['subactivities']); + }); + } + + public function rules(): array + { + return [ + 'name' => 'required|max:255', + 'subactivities' => 'present|array' + ]; + } + + public function asController(ActionRequest $request, Activity $activity): RedirectResponse + { + if ($activity->hasNami) { + $this->validateNami($activity, $request->validated()); + } + + $this->handle($activity, $request->validated()); + + return redirect()->route('activity.index'); + } + + /** + * @todo handle this with a model event on the pivot model + */ + private function validateNami(Activity $activity, array $payload): void + { + if ($activity->name !== data_get($payload, 'name', '')) { + throw ValidationException::withMessages(['nami_id' => 'Aktivität ist in NaMi. Update des Namens nicht möglich.']); + } + + $removingSubactivities = $activity->subactivities()->whereNotIn('id', data_get($payload, 'subactivities'))->pluck('id'); + + if ($removingSubactivities->first(fn ($subactivity) => Subactivity::find($subactivity)->hasNami)) { + throw ValidationException::withMessages(['nami_id' => 'Untertätigkeit kann nicht entfernt werden.']); + } + + $addingSubactivities = collect(data_get($payload, 'subactivities'))->filter(fn ($subactivityId) => $activity->subactivities->doesntContain($subactivityId)); + + if ($addingSubactivities->first(fn ($subactivity) => Subactivity::find($subactivity)->hasNami)) { + throw ValidationException::withMessages(['nami_id' => 'Untertätigkeit kann nicht hinzugefügt werden.']); + } + } +} diff --git a/routes/web.php b/routes/web.php index 8156697d..53b10747 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ 'auth:web'], function (): void { Route::get('/contribution/generate', [ContributionController::class, 'generate'])->name('contribution.generate'); Route::get('/activity', ActivityIndexAction::class)->name('activity.index'); Route::post('/activity', ActivityStoreAction::class)->name('activity.store'); + Route::patch('/activity/{activity}', ActivityUpdateAction::class)->name('activity.update'); }); diff --git a/tests/Feature/Activity/UpdateTest.php b/tests/Feature/Activity/UpdateTest.php index 6f164790..68934b18 100644 --- a/tests/Feature/Activity/UpdateTest.php +++ b/tests/Feature/Activity/UpdateTest.php @@ -14,76 +14,139 @@ class UpdateTest extends TestCase public function testItCannotUpdateAnActivityFromNami(): void { $this->login()->loginNami(); - - $activity = Activity::factory()->inNami(67)->create(); + $activity = Activity::factory()->inNami(67)->name('abc')->create(); $response = $this->patch(route('activity.update', ['activity' => $activity]), [ 'name' => 'Lorem', 'subactivities' => [], ]); - $response->assertStatus(403); + $response->assertSessionHasErrors(['nami_id' => 'Aktivität ist in NaMi. Update des Namens nicht möglich.']); } - public function testItUpdatesName(): void + public function testItCanUpdateSubactivitiesOfNamiActivity(): void { - $this->login()->loginNami()->withoutExceptionHandling(); - $activity = Activity::factory()->name('before')->create(); + $this->login()->loginNami(); + $activity = Activity::factory()->inNami(67)->name('abc')->create(); + $subactivity = Subactivity::factory()->create(); - $response = $this->from("/activity/{$activity->id}")->patch(route('activity.update', ['activity' => $activity]), [ - 'name' => 'after', + $this->patch(route('activity.update', ['activity' => $activity]), [ + 'name' => 'abc', + 'subactivities' => [$subactivity->id], + ]); + + $this->assertDatabaseHas('activity_subactivity', ['activity_id' => $activity->id, 'subactivity_id' => $subactivity->id]); + } + + public function testItCannotRemoveANamiSubactivityFromANamiActivity(): void + { + $this->login()->loginNami(); + $activity = Activity::factory()->inNami(67)->name('abc')->has(Subactivity::factory()->inNami(69))->create(); + + $response = $this->patch(route('activity.update', ['activity' => $activity]), [ + 'name' => 'abc', 'subactivities' => [], ]); - $response->assertRedirect('/activity'); - $this->assertDatabaseHas('activities', [ - 'name' => 'Lorem', - 'nami_id' => null, + $response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht entfernt werden.']); + } + + public function testItCannotAddANamiSubactivityToANamiActivity(): void + { + $this->login()->loginNami(); + $activity = Activity::factory()->inNami(67)->name('abc')->create(); + $subactivity = Subactivity::factory()->inNami(60)->create(); + + $response = $this->patch(route('activity.update', ['activity' => $activity]), [ + 'name' => 'abc', + 'subactivities' => [$subactivity->id], ]); - $this->assertDatabaseCount('activity_subactivity', 0); + + $response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht hinzugefügt werden.']); + } + + public function testItCannotRemoveANamiSubactivityFromANamiActivityAndSetAnother(): void + { + $this->login()->loginNami(); + $activity = Activity::factory()->inNami(67)->name('abc')->has(Subactivity::factory()->inNami(69))->create(); + $otherSubactivity = Subactivity::factory()->create(); + + $response = $this->patch(route('activity.update', ['activity' => $activity]), [ + 'name' => 'abc', + 'subactivities' => [$otherSubactivity->id], + ]); + + $response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht entfernt werden.']); } public function testNameIsRequired(): void { $this->login()->loginNami(); - $activity = Activity::factory()->name('before')->create(); - $response = $this->post(route('activity.store'), []); + $activity = Activity::factory()->create(); - $response->assertSessionHasErrors([ - 'name' => 'Name ist erforderlich.', - 'subactivities' => 'Untergliederungen muss vorhanden sein.', + $response = $this->patch(route('activity.update', ['activity' => $activity]), [ + 'name' => '', ]); + + $response->assertSessionHasErrors(['name' => 'Name ist erforderlich.']); + $response->assertSessionHasErrors(['subactivities' => 'Untergliederungen muss vorhanden sein.']); } - public function testNamiIdIsNotSet(): void + public function testItUpdatesName(): void { - $this->login()->loginNami()->withoutExceptionHandling(); + $this->login()->loginNami(); + $activity = Activity::factory()->name('UUU')->create(); - $response = $this->post(route('activity.store'), [ + $response = $this->patch(route('activity.update', ['activity' => $activity]), [ 'name' => 'Lorem', - 'nami_id' => 556, 'subactivities' => [], ]); - $this->assertDatabaseHas('activities', [ - 'nami_id' => null, - ]); + $response->assertRedirect('/activity'); + $this->assertDatabaseHas('activities', ['name' => 'Lorem']); } - public function testItCanStoreASubactivityWithTheActivity(): void + public function testItSetsSubactivities(): void { - $this->login()->loginNami()->withoutExceptionHandling(); + $this->login()->loginNami(); + $activity = Activity::factory()->create(); $subactivity = Subactivity::factory()->create(); - $response = $this->from('/activity')->post(route('activity.store'), [ + $this->patch(route('activity.update', ['activity' => $activity]), [ 'name' => 'Lorem', 'subactivities' => [$subactivity->id], ]); - $this->assertDatabaseCount('activity_subactivity', 1); - $this->assertDatabaseHas('activity_subactivity', [ - 'activity_id' => Activity::firstWhere('name', 'Lorem')->id, - 'subactivity_id' => $subactivity->id, - ]); + $this->assertDatabaseHas('activity_subactivity', ['activity_id' => $activity->id, 'subactivity_id' => $subactivity->id]); } + + public function testItCannotSetNamiId(): void + { + $this->login()->loginNami(); + $activity = Activity::factory()->create(); + + $this->patch(route('activity.update', ['activity' => $activity]), [ + 'name' => 'Lorem', + 'nami_id' => 66, + 'subactivities' => [], + ]); + + $this->assertDatabaseHas('activities', ['nami_id' => null]); + } + + public function testItUnsetsSubactivities(): void + { + $this->login()->loginNami(); + $activity = Activity::factory() + ->hasAttached(Subactivity::factory()) + ->create(); + + $this->patch(route('activity.update', ['activity' => $activity]), [ + 'name' => 'Lorem', + 'subactivities' => [], + ]); + + $this->assertDatabaseEmpty('activity_subactivity'); + } + }