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; } /** A group and its own customer row, the way store() leaves them */ private function group(int $balance = 0): array { $group = CustomerGroup::create(['name' => 'Klanen']); $groupCustomer = $this->customer([ 'lan_id' => 10, 'name' => 'Klanen', 'deposit' => $balance, 'amount_left' => $balance, 'is_in_group' => 0, 'customer_group_id' => $group->id, ]); return [$group, $groupCustomer]; } private function asUser(): self { $this->actingAs(User::factory()->create(), 'sanctum'); return $this; } public function test_adding_a_member_moves_their_balance_to_the_group(): void { [$group, $groupCustomer] = $this->group(800); $anna = $this->customer(['lan_id' => 11, 'name' => 'Anna', 'deposit' => 300, 'amount_left' => 300]); $this->asUser()->postJson('/api/add-to-customer-group/' . $group->id, [ 'customers' => [$anna->id], ])->assertOk(); $this->assertSame(1100, $groupCustomer->refresh()->amount_left); $this->assertSame(1100, $groupCustomer->deposit); $anna->refresh(); $this->assertSame(1, (int) $anna->is_in_group); $this->assertSame($group->id, $anna->customer_group_id); } public function test_a_member_who_has_spent_money_only_brings_what_is_left(): void { // Anna put in 300 and has spent 200, so 100 is hers to bring [$group, $groupCustomer] = $this->group(800); $anna = $this->customer(['lan_id' => 11, 'deposit' => 300, 'amount_left' => 100]); $this->asUser()->postJson('/api/add-to-customer-group/' . $group->id, [ 'customers' => [$anna->id], ])->assertOk(); $this->assertSame(900, $groupCustomer->refresh()->amount_left); $this->assertSame(900, $groupCustomer->deposit); } public function test_the_balance_is_cleared_on_the_member_so_it_is_not_counted_twice(): void { [$group] = $this->group(800); $anna = $this->customer(['lan_id' => 11, 'deposit' => 300, 'amount_left' => 300]); $this->asUser()->postJson('/api/add-to-customer-group/' . $group->id, [ 'customers' => [$anna->id], ]); $anna->refresh(); $this->assertSame(0, $anna->deposit); $this->assertSame(0, $anna->amount_left); } public function test_the_moved_balance_is_recorded_as_a_deposit(): void { [$group, $groupCustomer] = $this->group(800); $anna = $this->customer(['lan_id' => 11, 'deposit' => 300, 'amount_left' => 300]); $this->asUser()->postJson('/api/add-to-customer-group/' . $group->id, [ 'customers' => [$anna->id], ]); $this->assertSame(300, Deposit::where('customer_id', $groupCustomer->id)->sum('amount')); } public function test_adding_several_members_at_once_adds_up(): void { [$group, $groupCustomer] = $this->group(0); $anna = $this->customer(['lan_id' => 11, 'deposit' => 300, 'amount_left' => 300]); $bo = $this->customer(['lan_id' => 12, 'deposit' => 200, 'amount_left' => 150]); $this->asUser()->postJson('/api/add-to-customer-group/' . $group->id, [ 'customers' => [$anna->id, $bo->id], ]); $this->assertSame(450, $groupCustomer->refresh()->amount_left); } public function test_adding_to_a_group_without_an_account_row_gives_404(): void { $group = CustomerGroup::create(['name' => 'Tom grupp']); $anna = $this->customer(['lan_id' => 11]); $this->asUser()->postJson('/api/add-to-customer-group/' . $group->id, [ 'customers' => [$anna->id], ])->assertStatus(404); } public function test_deleting_a_group_keeps_the_participants(): void { [$group, $groupCustomer] = $this->group(0); $anna = $this->customer([ 'lan_id' => 11, 'name' => 'Anna', 'is_in_group' => 1, 'customer_group_id' => $group->id, ]); $this->asUser()->deleteJson('/api/customer-group/' . $group->id)->assertOk(); // Anna is a real participant and has to survive the group being dissolved $anna->refresh(); $this->assertNotNull($anna); $this->assertSame(0, (int) $anna->is_in_group); $this->assertNull($anna->customer_group_id); // The group and the row that only existed to hold its balance are gone $this->assertNull(Customer::find($groupCustomer->id)); $this->assertNull(CustomerGroup::find($group->id)); } public function test_a_group_with_money_left_is_not_deleted(): void { [$group, $groupCustomer] = $this->group(450); $anna = $this->customer([ 'lan_id' => 11, 'is_in_group' => 1, 'customer_group_id' => $group->id, ]); $this->asUser()->deleteJson('/api/customer-group/' . $group->id) ->assertStatus(422); $this->assertNotNull(CustomerGroup::find($group->id)); $this->assertNotNull(Customer::find($groupCustomer->id)); $this->assertSame(1, (int) $anna->refresh()->is_in_group); } public function test_the_endpoints_are_closed_to_anyone_not_logged_in(): void { [$group] = $this->group(0); $anna = $this->customer(['lan_id' => 11]); $this->postJson('/api/add-to-customer-group/' . $group->id, ['customers' => [$anna->id]]) ->assertStatus(401); $this->deleteJson('/api/customer-group/' . $group->id)->assertStatus(401); $this->assertNotNull(CustomerGroup::find($group->id)); } }