forceFill(array_merge([ 'lan_id' => 1, 'name' => 'Erik Olsson', 'guardian_name' => 'Karin Olsson', 'deposit' => 0, 'amount_left' => 0, 'give_leftover' => 0, 'is_in_group' => 0, ], $attributes))->save(); return $customer; } /** The group endpoints sit behind auth:sanctum */ private function asUser(): self { $this->actingAs(User::factory()->create(), 'sanctum'); return $this; } public function test_it_creates_a_group_with_a_customer_row_of_its_own(): void { $erik = $this->customer(['lan_id' => 1, 'name' => 'Erik', 'guardian_name' => 'Karin']); $anna = $this->customer(['lan_id' => 2, 'name' => 'Anna']); $this->asUser()->postJson('/api/customer-group', [ 'group_name' => 'Klanen', 'customers' => [$erik->id, $anna->id], ])->assertRedirect('customer-groups/'); $group = CustomerGroup::firstWhere('name', 'Klanen'); $this->assertNotNull($group); // The group gets its own customer row, which is where the balance lives $groupCustomer = Customer::where('customer_group_id', $group->id) ->where('is_in_group', 0) ->first(); $this->assertSame('Klanen', $groupCustomer->name); // The guardian is taken from the first member in the list $this->assertSame('Karin', $groupCustomer->guardian_name); } public function test_the_members_are_marked_as_belonging_to_the_group(): void { $erik = $this->customer(['lan_id' => 1, 'name' => 'Erik']); $anna = $this->customer(['lan_id' => 2, 'name' => 'Anna']); $this->asUser()->postJson('/api/customer-group', [ 'group_name' => 'Klanen', 'customers' => [$erik->id, $anna->id], ]); $group = CustomerGroup::firstWhere('name', 'Klanen'); foreach ([$erik, $anna] as $member) { $member->refresh(); $this->assertSame(1, (int) $member->is_in_group); $this->assertSame($group->id, $member->customer_group_id); } } public function test_the_members_balances_are_moved_to_the_group(): void { $erik = $this->customer(['lan_id' => 1, 'deposit' => 500, 'amount_left' => 500]); $anna = $this->customer(['lan_id' => 2, 'deposit' => 300, 'amount_left' => 300]); $this->asUser()->postJson('/api/customer-group', [ 'group_name' => 'Klanen', 'customers' => [$erik->id, $anna->id], ]); $group = CustomerGroup::firstWhere('name', 'Klanen'); $groupCustomer = Customer::where('customer_group_id', $group->id)->where('is_in_group', 0)->first(); $this->assertSame(800, $groupCustomer->amount_left); $this->assertSame(800, $groupCustomer->deposit); // Nothing is left behind on the members $this->assertSame(0, $erik->refresh()->amount_left); $this->assertSame(0, $erik->deposit); $this->assertSame(0, $anna->refresh()->amount_left); $this->assertSame(0, $anna->deposit); } public function test_the_moved_balance_is_recorded_as_a_deposit_on_the_group(): void { $erik = $this->customer(['lan_id' => 1, 'deposit' => 500, 'amount_left' => 500]); $this->asUser()->postJson('/api/customer-group', [ 'group_name' => 'Klanen', 'customers' => [$erik->id], ]); $group = CustomerGroup::firstWhere('name', 'Klanen'); $groupCustomer = Customer::where('customer_group_id', $group->id)->where('is_in_group', 0)->first(); $this->assertSame(1, Deposit::where('customer_id', $groupCustomer->id)->count()); $this->assertSame(500, Deposit::where('customer_id', $groupCustomer->id)->first()->amount); } public function test_what_a_member_has_already_spent_does_not_follow_along(): void { // Erik put in 500 and has spent 200, so 300 is what he can still use $erik = $this->customer(['lan_id' => 1, 'deposit' => 500, 'amount_left' => 300]); $this->asUser()->postJson('/api/customer-group', [ 'group_name' => 'Klanen', 'customers' => [$erik->id], ]); $group = CustomerGroup::firstWhere('name', 'Klanen'); $groupCustomer = Customer::where('customer_group_id', $group->id)->where('is_in_group', 0)->first(); // The group takes over what is left, and its deposit is set to the same // number — the 200 already spent is not carried over as history $this->assertSame(300, $groupCustomer->amount_left); $this->assertSame(300, $groupCustomer->deposit); } public function test_it_requires_a_name_and_at_least_one_customer(): void { $this->asUser()->postJson('/api/customer-group', ['group_name' => 'Klanen']) ->assertStatus(422); $this->asUser()->postJson('/api/customer-group', ['customers' => [1]]) ->assertStatus(422); $this->assertSame(0, CustomerGroup::count()); } public function test_the_endpoint_is_closed_to_anyone_not_logged_in(): void { $erik = $this->customer(); $this->postJson('/api/customer-group', [ 'group_name' => 'Klanen', 'customers' => [$erik->id], ])->assertStatus(401); $this->assertSame(0, CustomerGroup::count()); } }