diff --git a/code/app/Circle.php b/code/app/Circle.php new file mode 100644 index 00000000..a5886cf0 --- /dev/null +++ b/code/app/Circle.php @@ -0,0 +1,33 @@ + SluggableCreating::class + ]; + + protected static function boot() + { + parent::boot(); + static::initTrackingEvents(); + } + + public function group(): BelongsTo + { + return $this->belongsTo(Group::class); + } +} diff --git a/code/app/Observers/UserObserver.php b/code/app/Observers/UserObserver.php index e23e55c0..1215eb71 100644 --- a/code/app/Observers/UserObserver.php +++ b/code/app/Observers/UserObserver.php @@ -68,7 +68,7 @@ private function createdNormal($user) foreach($groups as $group) { $circle = $group->circles()->where('is_default', true)->first(); if ($circle) { - $circles[] = $circle; + $circles[] = $circle->id; } } diff --git a/code/app/Providers/ServicesProvider.php b/code/app/Providers/ServicesProvider.php index 96c91307..bc2f29db 100644 --- a/code/app/Providers/ServicesProvider.php +++ b/code/app/Providers/ServicesProvider.php @@ -20,9 +20,11 @@ private function services(): array */ return [ \App\Services\BookingsService::class, + \App\Services\CirclesService::class, \App\Services\DatesService::class, \App\Services\DynamicBookingsService::class, \App\Services\FastBookingsService::class, + \App\Services\GroupsService::class, \App\Services\InvoicesService::class, \App\Services\ModifiersService::class, \App\Services\ModifierTypesService::class, diff --git a/code/app/Services/BookingsService.php b/code/app/Services/BookingsService.php index f1b164a7..add571b7 100644 --- a/code/app/Services/BookingsService.php +++ b/code/app/Services/BookingsService.php @@ -396,7 +396,7 @@ public function handleBookingUpdate($request, $user, $order, $target_user, $deli $booking = $this->readBooking($request, $order, $booking, $delivering); if ($booking) { - $booking->circles()->sync($request['circles']); + $booking->circles()->sync($request['circles'] ?? []); if ($delivering) { BookingDelivered::dispatch($booking, $request['action'], $user); diff --git a/code/app/Services/CirclesService.php b/code/app/Services/CirclesService.php index ae645879..4c1de380 100644 --- a/code/app/Services/CirclesService.php +++ b/code/app/Services/CirclesService.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\DB; +use App\User; use App\Circle; use App\Group; @@ -29,10 +30,22 @@ public function store(array $request) if ($group->circles()->count() == 0) { $c->is_default = true; + $was_first = true; + } + else { + $was_first = false; } $c->save(); + if ($was_first) { + if ($group->context == 'user') { + foreach(User::all() as $user) { + $user->circles()->attach($c->id); + } + } + } + return $c; } @@ -67,6 +80,14 @@ public function destroy($id) $new_default = $other->first(); $new_default->is_default = true; $new_default->save(); + + $users = User::whereHas('circles', function($query) use ($c) { + $query->where('circles.id', $c->id); + })->get(); + + foreach($users as $user) { + $user->circles()->attach($new_default->id); + } } } diff --git a/code/app/Services/GroupsService.php b/code/app/Services/GroupsService.php index 27ce4d6d..705cff60 100644 --- a/code/app/Services/GroupsService.php +++ b/code/app/Services/GroupsService.php @@ -31,10 +31,9 @@ public function update($id, array $request) $g = Group::findOrFail($id); $this->setIfSet($g, $request, 'name'); - $this->setIfSet($g, $request, 'context'); + $this->setIfSet($g, $request, 'context', 'user'); - $context = $request['context'] ?? 'user'; - switch($context) { + switch($g->context) { case 'user': $this->setIfSet($g, $request, 'cardinality'); $this->boolIfSet($g, $request, 'filters_orders'); diff --git a/code/tests/Features/AggregationsTest.php b/code/tests/Features/AggregationsTest.php new file mode 100644 index 00000000..f0033949 --- /dev/null +++ b/code/tests/Features/AggregationsTest.php @@ -0,0 +1,244 @@ +actingAs($this->userAdmin); + + $groups_service = app()->make('GroupsService'); + $circles_service = app()->make('CirclesService'); + + $group = $groups_service->store(['name' => 'Gruppo Test']); + $groups_service->update($group->id, array_merge(['name' => 'Gruppo Test'], $params)); + + $this->nextRound(); + + $circles_service->store([ + 'name' => 'Cerchio Test 1', + 'group_id' => $group->id, + ]); + + $this->nextRound(); + + $circles_service->store([ + 'name' => 'Cerchio Test 2', + 'group_id' => $group->id, + ]); + + $this->nextRound(); + + return $group; + } + + public function testCreate() + { + $group = $this->createBasicGroup([ + 'context' => 'user', + 'cardinality' => 'single', + 'filters_orders' => true, + ]); + + $this->assertFalse(is_null($group)); + $this->assertEquals('Gruppo Test', $group->name); + $this->assertEquals(2, $group->circles()->count()); + $this->assertEquals(1, $this->userAdmin->circles()->count()); + } + + private function attachModifier($circle, $amount) + { + $this->actingAs($this->userAdmin); + + app()->make('ModifierTypesService')->update('spese-trasporto', [ + 'classes' => ['App\Booking', 'App\Product', 'App\Circle'], + ]); + + $this->nextRound(); + + $test_shipping_value = 10; + $modifiers = $circle->applicableModificationTypes(); + $modifier = null; + + foreach ($modifiers as $mod) { + if ($mod->id == 'spese-trasporto') { + $mod = $circle->modifiers()->where('modifier_type_id', $mod->id)->first(); + app()->make('ModifiersService')->update($mod->id, [ + 'value' => 'absolute', + 'arithmetic' => 'sum', + 'scale' => 'minor', + 'applies_type' => 'none', + 'applies_target' => 'booking', + 'distribution_type' => 'none', + 'simplified_amount' => $test_shipping_value, + ]); + + $modifier = $mod; + break; + } + } + + $this->assertNotNull($modifier); + + $this->nextRound(); + return $modifier; + } + + public function testUserModifiers() + { + $group = $this->createBasicGroup([ + 'context' => 'user', + 'cardinality' => 'single', + 'filters_orders' => false, + ]); + + $right_circle = $group->circles()->where('is_default', false)->first(); + $wrong_circle = $group->circles()->where('circles.id', '!=', $right_circle->id)->first(); + + $order = $this->initOrder(null); + $this->populateOrder($order); + + $this->nextRound(); + + $target_user = $this->users->first(); + $target_user->circles()->sync([$right_circle->id]); + + $test_shipping_value = 10; + $mod = $this->attachModifier($right_circle, $test_shipping_value); + + $order = app()->make('OrdersService')->show($order->id); + $redux = $order->aggregate->reduxData(); + $this->assertNotEquals($redux->price, 0.0); + $checked = false; + + foreach($order->bookings as $booking) { + $mods = $booking->applyModifiers($redux, true); + + if ($booking->user->id != $target_user->id) { + $this->assertEquals($mods->count(), 0); + } + else { + $this->assertEquals($mods->count(), 1); + + foreach($mods as $m) { + $this->assertEquals($m->effective_amount, $test_shipping_value); + $this->assertEquals($m->modifier_id, $mod->id); + } + + $checked = true; + } + } + + $this->assertTrue($checked); + } + + public function testBookingModifiers() + { + $group = $this->createBasicGroup([ + 'context' => 'booking', + ]); + + $right_circle = $group->circles()->where('is_default', false)->first(); + $wrong_circle = $group->circles()->where('circles.id', '!=', $right_circle->id)->first(); + + $order = $this->initOrder(null); + $this->populateOrder($order); + + $this->nextRound(); + + $order = app()->make('OrdersService')->show($order->id); + + do { + $target_bookings = []; + + foreach($order->bookings as $booking) { + if (rand() % 2 == 0) { + $booking->circles()->sync([$right_circle->id]); + $target_bookings[] = $booking->id; + } + else { + $booking->circles()->sync([$wrong_circle->id]); + } + } + } while(empty($target_bookings) && count($target_bookings) != $order->bookings->count()); + + $test_shipping_value = 10; + $mod = $this->attachModifier($right_circle, $test_shipping_value); + + $order = app()->make('OrdersService')->show($order->id); + $redux = $order->aggregate->reduxData(); + $this->assertNotEquals($redux->price, 0.0); + $checked = false; + + foreach($order->bookings as $booking) { + $mods = $booking->applyModifiers($redux, true); + + if (in_array($booking->id, $target_bookings) == false) { + $this->assertEquals($mods->count(), 0); + } + else { + $this->assertEquals($mods->count(), 1); + + foreach($mods as $m) { + $this->assertEquals($m->effective_amount, $test_shipping_value); + $this->assertEquals($m->modifier_id, $mod->id); + } + + $checked = true; + } + } + + $this->assertTrue($checked); + } + + public function testAssociateOrder() + { + $group = $this->createBasicGroup([ + 'context' => 'user', + 'cardinality' => 'single', + 'filters_orders' => true, + ]); + + $right_circle = $group->circles()->first(); + $wrong_circle = $group->circles()->where('circles.id', '!=', $right_circle->id)->first(); + + $order = $this->initOrder(null); + + $this->actingAs($this->userReferrer); + app()->make('OrdersService')->update($order->id, [ + 'circles' => [$right_circle->id], + ]); + + $this->nextRound(); + + $order = app()->make('OrdersService')->show($order->id); + $this->assertEquals(1, $order->circles()->count()); + $this->assertEquals($right_circle->id, $order->circles()->first()->id); + + $this->nextRound(); + + $user_yes = $this->createRoleAndUser($this->gas, 'supplier.book'); + $user_yes->circles()->sync([$right_circle->id]); + + $user_no = $this->createRoleAndUser($this->gas, 'supplier.book'); + $user_no->circles()->sync([$wrong_circle->id]); + + $this->nextRound(); + + $this->actingAs($user_yes); + $orders = getOrdersByStatus($user_yes, 'open'); + $this->assertEquals(1, $orders->count()); + + $this->nextRound(); + + $this->actingAs($user_no); + $orders = getOrdersByStatus($user_no, 'open'); + $this->assertEquals(0, $orders->count()); + } +} diff --git a/code/tests/Services/ModifierTypesServiceTest.php b/code/tests/Services/ModifierTypesServiceTest.php index d19fc7be..9184aa27 100644 --- a/code/tests/Services/ModifierTypesServiceTest.php +++ b/code/tests/Services/ModifierTypesServiceTest.php @@ -33,10 +33,10 @@ public function testStore() { $this->actingAs($this->userWithAdminPerm); - $type = app()->make('ModifierTypesService')->store(array( + $type = app()->make('ModifierTypesService')->store([ 'name' => 'Donazione', 'classes' => ['App\Booking'], - )); + ]); $this->assertTrue($type->exists); diff --git a/code/tests/Services/ModifiersServiceTest.php b/code/tests/Services/ModifiersServiceTest.php index 4c3a3594..9c39dd6c 100644 --- a/code/tests/Services/ModifiersServiceTest.php +++ b/code/tests/Services/ModifiersServiceTest.php @@ -13,11 +13,6 @@ class ModifiersServiceTest extends TestCase { use DatabaseTransactions; - public function setUp(): void - { - parent::setUp(); - } - private function localInitOrder() { $this->order = $this->initOrder(null); @@ -678,56 +673,6 @@ public function testOnBooking() } } - /* - Modificatore applicato su Luogo di Consegna - */ - public function testOnShippingPlace() - { - $this->localInitOrder(); - $this->actingAs($this->userAdmin); - - $delivery_1 = \App\Delivery::factory()->create([ - 'default' => true, - ]); - - $delivery_2 = \App\Delivery::factory()->create([ - 'default' => false, - ]); - - $delivery = [$delivery_1, $delivery_2]; - - foreach($this->users as $user) { - $user->preferred_delivery_id = $delivery[rand(0, 1)]->id; - $user->save(); - } - - $test_shipping_value = 10; - $mod = $this->simpleMod($delivery_2, 'booking', 'none', $test_shipping_value); - $this->assertNotNull($mod); - - $this->nextRound(); - - $order = app()->make('OrdersService')->show($this->order->id); - $redux = $order->aggregate->reduxData(); - $this->assertNotEquals($redux->price, 0.0); - - foreach($order->bookings as $booking) { - $mods = $booking->applyModifiers($redux, true); - - if ($booking->user->preferred_delivery_id == $delivery_1->id) { - $this->assertEquals($mods->count(), 0); - } - else { - $this->assertEquals($mods->count(), 1); - - foreach($mods as $m) { - $this->assertEquals($m->effective_amount, $test_shipping_value); - $this->assertEquals($m->modifier_id, $mod->id); - } - } - } - } - private function pushFriend($master) { $friends_role = \App\Role::factory()->create(['actions' => 'users.subusers']); @@ -851,7 +796,7 @@ public function testWithFriend() $shipping_cost_found = false; $printer = new OrderPrinter(); - $formatted = $printer->formatShipping($order, splitFields(['lastname', 'firstname', 'name', 'quantity', 'price']), 'booked', 'all_by_name', 1); + $formatted = $printer->formatShipping($order, splitFields(['lastname', 'firstname', 'name', 'quantity', 'price']), 'booked', ['all_by_name'], 1); foreach($formatted->contents as $d) { if ($d->user_id == $booking->user_id) { @@ -911,7 +856,7 @@ public function testWithOnlyFriend() $shipping_cost_found = false; $printer = new OrderPrinter(); - $formatted = $printer->formatShipping($order, splitFields(['lastname', 'firstname', 'name', 'quantity', 'price']), 'booked', 'all_by_name', 1); + $formatted = $printer->formatShipping($order, splitFields(['lastname', 'firstname', 'name', 'quantity', 'price']), 'booked', ['all_by_name'], 1); foreach($formatted->contents as $d) { if ($d->user_id == $newUser->id) { diff --git a/code/tests/Services/OrdersServiceTest.php b/code/tests/Services/OrdersServiceTest.php index 4a80ddb7..baa06ac5 100644 --- a/code/tests/Services/OrdersServiceTest.php +++ b/code/tests/Services/OrdersServiceTest.php @@ -12,7 +12,6 @@ use App\Exceptions\AuthException; use App\User; -use App\Delivery; use App\Booking; use App\VariantCombo; @@ -178,33 +177,6 @@ public function testChangeState() $this->assertFalse($order->isRunning()); } - /* - Assegnazione Luoghi di Consegna - */ - public function testOnShippingPlace() - { - $this->actingAs($this->userAdmin); - $delivery = Delivery::factory()->create([ - 'default' => true, - ]); - - $this->actingAs($this->userReferrer); - app()->make('OrdersService')->update($this->order->id, array( - 'deliveries' => [$delivery->id], - )); - - $order = app()->make('OrdersService')->show($this->order->id); - $this->assertEquals(1, $order->deliveries()->count()); - - /* - TODO: spostare funzione list() in OrdersService e testare che - userWithNoPerms non veda l'ordine appena modificato - - $this->userWithNoPerms->preferred_delivery_id = $delivery->id; - $this->actingAs($this->userWithNoPerms); - */ - } - /* Accesso Ordine con ID non esistente */ diff --git a/code/tests/Services/UsersServiceTest.php b/code/tests/Services/UsersServiceTest.php index 67b280b8..656db4ad 100644 --- a/code/tests/Services/UsersServiceTest.php +++ b/code/tests/Services/UsersServiceTest.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Str; use Tests\TestCase; use App\Exceptions\IllegalArgumentException; @@ -359,6 +360,24 @@ public function testInvalidCardNumber() ]); } + /* + Modifica Utente con parametri errati + */ + public function testInvalidName() + { + $this->expectException(IllegalArgumentException::class); + + $this->actingAs($this->userWithAdminPerm); + $sample = User::where('gas_id', $this->gas->id)->inRandomOrder()->first(); + + app()->make('UsersService')->store([ + 'username' => Str::random(10), + 'firstname' => $sample->firstname, + 'lastname' => $sample->lastname, + 'password' => Str::random(10), + ]); + } + /* Modifica del proprio Utente con permessi sbagliati */ diff --git a/code/tests/TestCase.php b/code/tests/TestCase.php index 88743c85..6a7640cf 100644 --- a/code/tests/TestCase.php +++ b/code/tests/TestCase.php @@ -13,7 +13,6 @@ abstract class TestCase extends BaseTestCase use CreatesApplication; protected $baseUrl = 'http://localhost'; - protected $services = null; public function setUp(): void { @@ -66,9 +65,12 @@ public function tearDown(): void */ protected function createRoleAndUser($gas, $permissions, $target = null) { - $role = \App\Role::factory()->create([ - 'actions' => $permissions - ]); + $role = \App\Role::where('actions', $permissions)->first(); + if (is_null($role)) { + $role = \App\Role::factory()->create([ + 'actions' => $permissions + ]); + } $user = \App\User::factory()->create(['gas_id' => $gas->id]); $user->addRole($role->id, $target ?: $gas);