Skip to content

Commit

Permalink
Authored models questionnaires (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
daVitekPL authored Jun 15, 2023
1 parent 16e6146 commit 1312be8
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 2 deletions.
9 changes: 9 additions & 0 deletions database/seeders/QuestionnairePermissionsSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,16 @@ public function run(): void
Permission::findOrCreate($permission, 'api');
}

$tutorPermissions = [
QuestionnairePermissionsEnum::QUESTIONNAIRE_LIST_AUTHORED,
];

foreach ($tutorPermissions as $permission) {
Permission::findOrCreate($permission, 'api');
}

$admin->givePermissionTo($permissions);
$tutor->givePermissionTo($permissions);
$tutor->givePermissionTo($tutorPermissions);
}
}
7 changes: 7 additions & 0 deletions src/Dtos/QuestionAnswerFilterCriteriaDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
use EscolaLms\Core\Dtos\CriteriaDto;
use EscolaLms\Core\Repositories\Criteria\Primitives\EqualCriterion;
use EscolaLms\Core\Repositories\Criteria\Primitives\LikeCriterion;
use EscolaLms\Questionnaire\Enums\QuestionnairePermissionsEnum;
use EscolaLms\Questionnaire\Repository\Criteria\AuthoredModelsQuestionnaireCriterion;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;

class QuestionAnswerFilterCriteriaDto extends CriteriaDto implements InstantiateFromRequest
{
Expand All @@ -23,6 +26,10 @@ public static function instantiateFromRequest(Request $request): self
$criteria->push(new EqualCriterion('questionnaire_model_id', $request->input('questionnaire_model_id')));
}

if (Auth::user() && Auth::user()->can(QuestionnairePermissionsEnum::QUESTIONNAIRE_LIST_AUTHORED)) {
$criteria->push(new AuthoredModelsQuestionnaireCriterion('questionnaireModel'));
}

return new self($criteria);
}
}
7 changes: 7 additions & 0 deletions src/Dtos/QuestionnairesFilterCriteriaDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
use EscolaLms\Core\Dtos\Contracts\InstantiateFromRequest;
use EscolaLms\Core\Dtos\CriteriaDto;
use EscolaLms\Core\Repositories\Criteria\Primitives\LikeCriterion;
use EscolaLms\Questionnaire\Enums\QuestionnairePermissionsEnum;
use EscolaLms\Questionnaire\Repository\Criteria\AuthoredModelsQuestionnaireCriterion;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;

class QuestionnairesFilterCriteriaDto extends CriteriaDto implements InstantiateFromRequest
{
Expand All @@ -18,6 +21,10 @@ public static function instantiateFromRequest(Request $request): self
$criteria->push(new LikeCriterion('title', $request->input('title')));
}

if (Auth::user() && Auth::user()->can(QuestionnairePermissionsEnum::QUESTIONNAIRE_LIST_AUTHORED)) {
$criteria->push(new AuthoredModelsQuestionnaireCriterion());
}

return new self($criteria);
}
}
2 changes: 2 additions & 0 deletions src/Enums/QuestionnairePermissionsEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ class QuestionnairePermissionsEnum extends BasicEnum
const QUESTION_UPDATE = 'question_update';

const QUESTION_ANSWER_VISIBILITY_CHANGE = 'question_answer_visibility_change';

const QUESTIONNAIRE_LIST_AUTHORED = 'questionnaire_list_authored';
}
68 changes: 68 additions & 0 deletions src/Repository/Criteria/AuthoredModelsQuestionnaireCriterion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace EscolaLms\Questionnaire\Repository\Criteria;

use EscolaLms\Consultations\Models\Consultation;
use EscolaLms\Core\Repositories\Criteria\Criterion;
use EscolaLms\Courses\Models\Course;
use EscolaLms\Webinar\Models\Webinar;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Facades\Auth;

class AuthoredModelsQuestionnaireCriterion extends Criterion
{
public function __construct(?string $key = 'questionnaireModels')
{
parent::__construct($key);
}

public function apply(Builder $query): Builder
{
$user = Auth::user();
return $query->where(function (Builder $query) use ($user) {
if (class_exists(Course::class)) {
$query->where(function (Builder $query) use ($user) {
return $query->whereHas($this->key, function (Builder $q) use ($user) {
$q->whereHas('modelableType', fn(Builder $q) => $q
->where('model_class', '=', Course::class))
->join('courses', function (JoinClause $join) {
$join->on('courses.id', '=', 'questionnaire_models.model_id');
})
->join('course_author', function (JoinClause $join) use ($user) {
$join->on('course_author.course_id', '=', 'courses.id')
->where('course_author.author_id', '=', $user->getKey());
});
});
});
}
if (class_exists(Consultation::class)) {
$query->orWhere(function (Builder $query) use ($user) {
return $query->whereHas($this->key, function (Builder $q) use ($user) {
$q->whereHas('modelableType', fn(Builder $q) => $q
->where('model_class', '=', Consultation::class))
->join('consultations', function (JoinClause $join) use ($user) {
$join->on('consultations.id', '=', 'questionnaire_models.model_id')
->where('consultations.author_id', '=', $user->getKey());
});
});
});
}
if (class_exists(Webinar::class)) {
$query->orWhere(function (Builder $query) use ($user) {
return $query->whereHas($this->key, function (Builder $q) use ($user) {
$q->whereHas('modelableType', fn(Builder $q) => $q
->where('model_class', '=', Webinar::class))
->join('webinars', function (JoinClause $join) {
$join->on('webinars.id', '=', 'questionnaire_models.model_id');
})
->join('webinar_trainers', function (JoinClause $join) use ($user) {
$join->on('webinar_trainers.webinar_id', '=', 'webinars.id')
->where('webinar_trainers.trainer_id', '=', $user->getKey());
});
});
});
}
});
}
}
75 changes: 74 additions & 1 deletion tests/Api/QuestionAnswerListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
namespace EscolaLms\Questionnaire\Tests\Api;

use EscolaLms\Core\Models\User;
use EscolaLms\Core\Tests\CreatesUsers;
use EscolaLms\Courses\Models\Course;
use EscolaLms\Questionnaire\Database\Seeders\QuestionnairePermissionsSeeder;
use EscolaLms\Questionnaire\Models\Question;
use EscolaLms\Questionnaire\Models\QuestionAnswer;
use EscolaLms\Questionnaire\Models\Questionnaire;
use EscolaLms\Questionnaire\Models\QuestionnaireModel;
use EscolaLms\Questionnaire\Models\QuestionnaireModelType;
use EscolaLms\Questionnaire\Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class QuestionAnswerListTest extends TestCase
{
use DatabaseTransactions;
use DatabaseTransactions, CreatesUsers;

public Questionnaire $questionnaire;
public QuestionnaireModel $questionnaireModel;
Expand Down Expand Up @@ -220,4 +223,74 @@ public function testAnswersListWithFiltersAndSorts(): void
$response->assertJsonCount(1, 'data');
$this->assertTrue($response->json('data.0.id') === $questionAnswer1->getKey());
}

public function testListAnswersOnlyAuthoredModels(): void
{
$tutor = $this->makeInstructor();
$tutor2 = $this->makeInstructor();

$questionnaire = Questionnaire::factory([
'title' => 'Only authored',
])->create();

$course1 = Course::factory()->create();
$course1->authors()->sync($tutor);

$course2 = Course::factory()->create();
$course2->authors()->sync($tutor2);

$questionnaireModelType = QuestionnaireModelType::query()->where('model_class', '=', Course::class)->first();
if (empty($questionnaireModelType)) {
$questionnaireModelType = QuestionnaireModelType::factory()->createOne();
}

$questionnaireModel1 = $questionnaire->questionnaireModels()->save(QuestionnaireModel::factory()->make([
'model_id' => $course1->getKey(),
'model_type_id' => $questionnaireModelType->getKey(),
]));

$questionnaireModel2 = $questionnaire->questionnaireModels()->save(QuestionnaireModel::factory()->make([
'model_id' => $course2->getKey(),
'model_type_id' => $questionnaireModelType->getKey(),
]));

$question = Question::factory()->create([
'questionnaire_id' => $questionnaire->getKey(),
'title' => 'Question',
]);

$student = $this->makeStudent();

$questionAnswer1 = QuestionAnswer::factory()->create([
'rate' => 1,
'question_id' => $question->getKey(),
'questionnaire_model_id' => $questionnaireModel1->getKey(),
'note' => 'aaaa',
'user_id' => $student->getKey(),
]);

$questionAnswer2 = QuestionAnswer::factory()->create([
'rate' => 2,
'question_id' => $question->getKey(),
'questionnaire_model_id' => $questionnaireModel2->getKey(),
'note' => 'bbbb',
'user_id' => $student->getKey(),
]);

$this
->actingAs($tutor, 'api')
->json('GET', '/api/admin/question-answers/' . $questionnaire->getKey())
->assertOk()
->assertJsonCount(1, 'data')
->assertJsonFragment([
'id' => $questionAnswer1->getKey(),
'rate' => 1,
'note' => 'aaaa',
])
->assertJsonMissing([
'id' => $questionAnswer2->getKey(),
'rate' => 2,
'note' => 'bbbb',
]);
}
}
42 changes: 41 additions & 1 deletion tests/Api/QuestionnaireListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

namespace EscolaLms\Questionnaire\Tests\Api;

use EscolaLms\Core\Tests\CreatesUsers;
use EscolaLms\Courses\Models\Course;
use EscolaLms\Questionnaire\Database\Seeders\QuestionnairePermissionsSeeder;
use EscolaLms\Questionnaire\Enums\QuestionTypeEnum;
use EscolaLms\Questionnaire\Models\Question;
use EscolaLms\Questionnaire\Models\Questionnaire;
use EscolaLms\Questionnaire\Models\QuestionnaireModel;
use EscolaLms\Questionnaire\Models\QuestionnaireModelType;
use EscolaLms\Questionnaire\Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class QuestionnaireListTest extends TestCase
{
use DatabaseTransactions;
use DatabaseTransactions, CreatesUsers;

protected function setUp(): void
{
Expand Down Expand Up @@ -477,4 +480,41 @@ public function testListQuestionsType(): void
'title' => $textQuestion->title,
]);
}

public function testListOnlyAuthoredModels(): void
{
$tutor = $this->makeInstructor();

$questionnaire = Questionnaire::factory([
'title' => 'Only authored',
])->create();

$this
->actingAs($tutor, 'api')
->json('GET', '/api/admin/questionnaire')
->assertOk()
->assertJsonCount(0, 'data');

$course = Course::factory()->create();
$course->authors()->sync($tutor);

$questionnaireModelType = QuestionnaireModelType::query()->where('model_class', '=', Course::class)->first();
if (empty($questionnaireModelType)) {
$questionnaireModelType = QuestionnaireModelType::factory()->createOne();
}

$questionnaire->questionnaireModels()->save(QuestionnaireModel::factory()->make([
'model_id' => $course->getKey(),
'model_type_id' => $questionnaireModelType->getKey(),
]));

$this
->actingAs($tutor, 'api')
->json('GET', '/api/admin/questionnaire')
->assertOk()
->assertJsonCount(1, 'data')
->assertJsonFragment([
'title' => 'Only authored',
]);
}
}

0 comments on commit 1312be8

Please sign in to comment.