diff --git a/src/Dto/WebinarUserDto.php b/src/Dto/WebinarUserDto.php new file mode 100644 index 0000000..f6234c8 --- /dev/null +++ b/src/Dto/WebinarUserDto.php @@ -0,0 +1,27 @@ +push(new WebinarUserCriterion($array['webinar_id'])); + } + + if (key_exists('search', $array) && !is_null($array['search'])) { + $criteria->push(new UserSearchCriterion($array['search'])); + } + + return new self($criteria); + } +} diff --git a/src/Http/Controllers/Swagger/WebinarSwagger.php b/src/Http/Controllers/Swagger/WebinarSwagger.php index 83a1ee5..b042b11 100644 --- a/src/Http/Controllers/Swagger/WebinarSwagger.php +++ b/src/Http/Controllers/Swagger/WebinarSwagger.php @@ -7,6 +7,7 @@ use EscolaLms\Webinar\Http\Requests\UpdateWebinarRequest; use EscolaLms\Webinar\Http\Requests\ListWebinarsRequest; use EscolaLms\Webinar\Http\Requests\WebinarAssignableUserListRequest; +use EscolaLms\Webinar\Http\Requests\WebinarUserRequest; use Illuminate\Http\JsonResponse; interface WebinarSwagger @@ -313,4 +314,47 @@ public function destroy(int $id, DeleteWebinarRequest $request): JsonResponse; * ) */ public function assignableUsers(WebinarAssignableUserListRequest $request): JsonResponse; + + /** + * @OA\Get( + * tags={"Admin Webinars"}, + * path="/api/admin/webinars/{id}/users", + * description="Get webinars users", + * security={ + * {"passport": {}}, + * }, + * @OA\Parameter( + * name="id", + * description="id of Webinar", + * @OA\Schema( + * type="integer", + * ), + * required=true, + * in="path" + * ), + * @OA\Parameter( + * name="search", + * required=false, + * in="query", + * @OA\Schema( + * type="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="successful operation", + * @OA\MediaType( + * mediaType="application/json", + * ), + * ), + * @OA\Response( + * response=422, + * description="Bad request", + * @OA\MediaType( + * mediaType="application/json" + * ) + * ) + * ) + */ + public function webinarUsers(int $id, WebinarUserRequest $request): JsonResponse; } diff --git a/src/Http/Controllers/WebinarController.php b/src/Http/Controllers/WebinarController.php index e6b2462..f530176 100644 --- a/src/Http/Controllers/WebinarController.php +++ b/src/Http/Controllers/WebinarController.php @@ -5,6 +5,7 @@ use EscolaLms\Auth\Dtos\Admin\UserAssignableDto; use EscolaLms\Auth\Http\Resources\UserFullResource; use EscolaLms\Auth\Services\Contracts\UserServiceContract; +use EscolaLms\Webinar\Dto\WebinarUserDto; use EscolaLms\Webinar\Http\Requests\DeleteWebinarRequest; use EscolaLms\Webinar\Http\Requests\ShowWebinarRequest; use EscolaLms\Core\Dtos\OrderDto; @@ -17,6 +18,7 @@ use EscolaLms\Core\Http\Controllers\EscolaLmsBaseController; use EscolaLms\Webinar\Http\Requests\ListWebinarsRequest; use EscolaLms\Webinar\Http\Requests\WebinarAssignableUserListRequest; +use EscolaLms\Webinar\Http\Requests\WebinarUserRequest; use EscolaLms\Webinar\Http\Resources\WebinarSimpleResource; use EscolaLms\Webinar\Services\Contracts\WebinarServiceContract; use Illuminate\Http\JsonResponse; @@ -93,4 +95,12 @@ public function assignableUsers(WebinarAssignableUserListRequest $request): Json ->assignableUsersWithCriteria($dto, $request->get('per_page'), $request->get('page')); return $this->sendResponseForResource(UserFullResource::collection($result), __('Users assignable to courses')); } + + public function webinarUsers(int $id, WebinarUserRequest $request): JsonResponse + { + $dto = WebinarUserDto::instantiateFromArray(array_merge($request->validated(), ['webinar_id' => $id])); + $result = $this->userService + ->assignableUsersWithCriteria($dto, $request->get('per_page'), $request->get('page')); + return $this->sendResponseForResource(UserFullResource::collection($result), __('Webinar Users retrieved successfully')); + } } diff --git a/src/Http/Requests/WebinarUserRequest.php b/src/Http/Requests/WebinarUserRequest.php new file mode 100644 index 0000000..07e11f8 --- /dev/null +++ b/src/Http/Requests/WebinarUserRequest.php @@ -0,0 +1,23 @@ + ['string'], + ]; + } +} diff --git a/src/Repositories/Criteria/WebinarUserCriterion.php b/src/Repositories/Criteria/WebinarUserCriterion.php new file mode 100644 index 0000000..49db3bc --- /dev/null +++ b/src/Repositories/Criteria/WebinarUserCriterion.php @@ -0,0 +1,27 @@ +getModel()->getTable(); + + return $query->whereExists(function ($subQuery) use ($userTable) { + $subQuery->select(DB::raw(1)) + ->from('webinar_user') + ->whereRaw("webinar_user.user_id = {$userTable}.id") + ->where('webinar_user.webinar_id', $this->value); + }); + } +} diff --git a/src/routes.php b/src/routes.php index 996dcf1..ca62fb4 100644 --- a/src/routes.php +++ b/src/routes.php @@ -7,6 +7,7 @@ // admin endpoints Route::group(['middleware' => ['auth:api'], 'prefix' => 'api/admin'], function () { Route::post('webinars/{id}', [WebinarController::class, 'update']); + Route::get('webinars/{id}/users', [WebinarController::class, 'webinarUsers']); Route::resource('webinars', WebinarController::class); Route::get('webinars/users/assignable', [WebinarController::class, 'assignableUsers']); }); diff --git a/tests/APIs/WebinarApiTest.php b/tests/APIs/WebinarApiTest.php index 76d3a56..4bb26d1 100644 --- a/tests/APIs/WebinarApiTest.php +++ b/tests/APIs/WebinarApiTest.php @@ -8,6 +8,7 @@ use EscolaLms\Core\Tests\CreatesUsers; use EscolaLms\Tags\Models\Tag; use EscolaLms\Webinar\Database\Seeders\WebinarsPermissionSeeder; +use EscolaLms\Webinar\Dto\WebinarUserDto; use EscolaLms\Webinar\Enum\WebinarPermissionsEnum; use EscolaLms\Webinar\Enum\WebinarStatusEnum; use EscolaLms\Webinar\Models\Webinar; @@ -451,4 +452,43 @@ public function testGenerateSignedUrlsNotSupported(): void ]) ->assertStatus(400); } + + public function testWebinarUsersUnauthorized(): void + { + $this->response = $this + ->json('GET', "/api/admin/webinars/{$this->webinar->getKey()}/users") + ->assertUnauthorized(); + } + + public function testWebinarUsers(): void + { + $admin = $this->makeAdmin(); + $student = config('auth.providers.users.model')::factory()->create(); + $student->guard_name = 'api'; + $student->assignRole('student'); + + $this->webinar->users()->sync($student); + + $dto = WebinarUserDto::instantiateFromArray(['webinar_id' => $this->webinar->getKey()]); + $users = app(UserServiceContract::class)->assignableUsersWithCriteria($dto); + assert($users instanceof LengthAwarePaginator); + + $this->response = $this + ->actingAs($this->user, 'api') + ->json('GET', "/api/admin/webinars/{$this->webinar->getKey()}/users") + ->assertOk() + ->assertJsonCount(min($users->total(), $users->perPage()), 'data') + ->assertJsonFragment([ + 'id' => $student->getKey(), + 'email' => $student->email, + ]) + ->assertJsonMissing([ + 'id' => $admin->getKey(), + 'email' => $admin->email, + ]) + ->assertJsonMissing([ + 'id' => $this->user->getKey(), + 'email' => $this->user->email, + ]); + } }