diff --git a/app/BusinessLogicLayer/CrowdSourcingProject/CrowdSourcingProjectManager.php b/app/BusinessLogicLayer/CrowdSourcingProject/CrowdSourcingProjectManager.php
index a172eb46..eeaee7ed 100644
--- a/app/BusinessLogicLayer/CrowdSourcingProject/CrowdSourcingProjectManager.php
+++ b/app/BusinessLogicLayer/CrowdSourcingProject/CrowdSourcingProjectManager.php
@@ -4,7 +4,6 @@
use App\BusinessLogicLayer\gamification\ContributorBadge;
use App\BusinessLogicLayer\lkp\CrowdSourcingProjectStatusLkp;
-use App\BusinessLogicLayer\lkp\QuestionnaireStatusLkp;
use App\BusinessLogicLayer\questionnaire\QuestionnaireGoalManager;
use App\BusinessLogicLayer\UserManager;
use App\Models\CrowdSourcingProject\CrowdSourcingProject;
@@ -67,28 +66,12 @@ public function __construct(CrowdSourcingProjectRepository $crowdSourcingProject
public function getCrowdSourcingProjectsForHomePage(): Collection {
$projects = $this->crowdSourcingProjectRepository->getActiveProjectsWithAtLeastOneQuestionnaireWithStatus();
- $projectsWithFinalizedQuestionnaires = $this->crowdSourcingProjectRepository->getActiveProjectsWithAtLeastOneQuestionnaireWithStatus([], QuestionnaireStatusLkp::FINALIZED);
- // for each project in the finalized ones,
- // if it does not exist in the collection of the projects with active questionnaires,
- // add it there.
- foreach ($projectsWithFinalizedQuestionnaires as $project) {
- if (!$projects->contains('id', $project->id)) {
- $projects->push($project);
- }
- }
-
- foreach ($projects as $project) {
- $project->currentTranslation = $this->crowdSourcingProjectTranslationManager->getFieldsTranslationForProject($project);
- $project->latestQuestionnaire = $project->questionnaires->last();
- }
- return $projects;
- }
-
- public function getPastCrowdSourcingProjectsForHomePage(): Collection {
- $projects = $this->crowdSourcingProjectRepository->getPastProjects();
foreach ($projects as $project) {
$project->currentTranslation = $this->crowdSourcingProjectTranslationManager->getFieldsTranslationForProject($project);
+ if ($project->questionnaires->count() > 0) {
+ $project->latestQuestionnaire = $project->questionnaires->last();
+ }
}
return $projects;
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index d84d0c62..844c87f7 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -15,9 +15,8 @@ public function __construct(CrowdSourcingProjectManager $crowdSourcingProjectMan
public function showHomePage() {
$projects = $this->crowdSourcingProjectManager->getCrowdSourcingProjectsForHomePage();
- $pastProjects = $this->crowdSourcingProjectManager->getPastCrowdSourcingProjectsForHomePage();
- return view('home.home')->with(['projects' => $projects, 'pastProjects' => $pastProjects]);
+ return view('home.home')->with(['projects' => $projects]);
}
public function showTermsAndPrivacyPage() {
diff --git a/app/Http/Controllers/Questionnaire/QuestionnaireController.php b/app/Http/Controllers/Questionnaire/QuestionnaireController.php
index a0a6fbc6..4f47c665 100644
--- a/app/Http/Controllers/Questionnaire/QuestionnaireController.php
+++ b/app/Http/Controllers/Questionnaire/QuestionnaireController.php
@@ -25,11 +25,11 @@ class QuestionnaireController extends Controller {
protected QuestionnaireTranslator $questionnaireTranslator;
protected QuestionnaireLanguageManager $questionnaireLanguageManager;
- public function __construct(QuestionnaireManager $questionnaireManager,
- UserQuestionnaireShareManager $questionnaireShareManager,
- QuestionnaireVMProvider $questionnaireVMProvider,
- QuestionnaireTranslator $questionnaireTranslator,
- QuestionnaireLanguageManager $questionnaireLanguageManager) {
+ public function __construct(QuestionnaireManager $questionnaireManager,
+ UserQuestionnaireShareManager $questionnaireShareManager,
+ QuestionnaireVMProvider $questionnaireVMProvider,
+ QuestionnaireTranslator $questionnaireTranslator,
+ QuestionnaireLanguageManager $questionnaireLanguageManager) {
$this->questionnaireManager = $questionnaireManager;
$this->questionnaireShareManager = $questionnaireShareManager;
$this->questionnaireVMProvider = $questionnaireVMProvider;
@@ -60,8 +60,9 @@ public function createQuestionnaire() {
public function store(Request $request) {
$data = $request->all();
- if (!isset($data['status_id']))
+ if (!isset($data['status_id'])) {
$data['status_id'] = QuestionnaireStatusLkp::DRAFT;
+ }
$this->validate($request, [
'type_id' => 'required|integer',
@@ -74,8 +75,9 @@ public function store(Request $request) {
'project_ids' => 'required|array',
]);
$questionnaire = $this->questionnaireManager->storeOrUpdateQuestionnaire($data);
- if (isset($data['lang_codes']) && count($data['lang_codes']) > 0)
+ if (isset($data['lang_codes']) && count($data['lang_codes']) > 0) {
$this->questionnaireLanguageManager->saveLanguagesForQuestionnaire($data['lang_codes'], $questionnaire->id);
+ }
return $questionnaire;
}
diff --git a/app/Repository/CrowdSourcingProject/CrowdSourcingProjectRepository.php b/app/Repository/CrowdSourcingProject/CrowdSourcingProjectRepository.php
index a06775da..7980bc69 100644
--- a/app/Repository/CrowdSourcingProject/CrowdSourcingProjectRepository.php
+++ b/app/Repository/CrowdSourcingProject/CrowdSourcingProjectRepository.php
@@ -6,7 +6,6 @@
use App\BusinessLogicLayer\lkp\QuestionnaireStatusLkp;
use App\Models\CrowdSourcingProject\CrowdSourcingProject;
use App\Repository\Repository;
-use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
class CrowdSourcingProjectRepository extends Repository {
@@ -23,9 +22,6 @@ public function getActiveProjectsWithAtLeastOneQuestionnaireWithStatus(
$additionalRelationships = [], $questionnaireStatusId = QuestionnaireStatusLkp::PUBLISHED
): Collection {
$builder = CrowdSourcingProject::where(['status_id' => CrowdSourcingProjectStatusLkp::PUBLISHED])
- ->whereHas('questionnaires', function (Builder $query) use ($questionnaireStatusId) {
- $query->where(['status_id' => $questionnaireStatusId]);
- })
->with('questionnaires', function ($query) use ($questionnaireStatusId) {
$query->select(['id', 'prerequisite_order', 'status_id', 'default_language_id',
'goal', 'statistics_page_visibility_lkp_id', 'questionnaires.created_at as questionnaire_created', ])
@@ -33,7 +29,7 @@ public function getActiveProjectsWithAtLeastOneQuestionnaireWithStatus(
->withCount('responses')
->orderBy('prerequisite_order')
->orderBy('questionnaire_created', 'desc');
- });
+ })->with('problems');
if (count($additionalRelationships)) {
$builder = $builder->with($additionalRelationships);
@@ -41,8 +37,4 @@ public function getActiveProjectsWithAtLeastOneQuestionnaireWithStatus(
return $builder->get();
}
-
- public function getPastProjects(): Collection {
- return CrowdSourcingProject::where(['status_id' => CrowdSourcingProjectStatusLkp::FINALIZED])->get();
- }
}
diff --git a/resources/views/home/partials/projects-list-home.blade.php b/resources/views/home/partials/projects-list-home.blade.php
index dc08e516..80f8eadb 100644
--- a/resources/views/home/partials/projects-list-home.blade.php
+++ b/resources/views/home/partials/projects-list-home.blade.php
@@ -11,7 +11,7 @@
{!! $project->currentTranslation->motto_title !!}
-@if(isset($pastProjects))
-
-
-
-
-
Check out our past projects:
-
-
-
- @include('home.partials.projects-list-home', ['projects' => $pastProjects, 'projectBtnText' => 'See more'])
-
-
-
-@endif
diff --git a/tests/Feature/Controllers/CrowdSourcingProjectControllerTest.php b/tests/Feature/Controllers/CrowdSourcingProjectControllerTest.php
index e466a4b0..bdfc1a02 100644
--- a/tests/Feature/Controllers/CrowdSourcingProjectControllerTest.php
+++ b/tests/Feature/Controllers/CrowdSourcingProjectControllerTest.php
@@ -5,6 +5,7 @@
use App\BusinessLogicLayer\CrowdSourcingProject\CrowdSourcingProjectManager;
use App\BusinessLogicLayer\lkp\CrowdSourcingProjectStatusLkp;
use App\BusinessLogicLayer\lkp\UserRolesLkp;
+use App\Http\Middleware\VerifyCsrfToken;
use App\Models\CrowdSourcingProject\CrowdSourcingProject;
use App\Models\User;
use App\Models\UserRole;
@@ -282,13 +283,14 @@ public function adminCanAccessEditPage() {
* @test
*/
public function guestCannotStoreProject() {
- $response = $this->post(route('projects.store'), [
- 'name' => 'Test Project',
- 'description' => 'Test Description',
- 'status_id' => 1,
- 'slug' => 'test-project',
- 'language_id' => 1,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('projects.store'), [
+ 'name' => 'Test Project',
+ 'description' => 'Test Description',
+ 'status_id' => 1,
+ 'slug' => 'test-project',
+ 'language_id' => 1,
+ ]);
$response->assertStatus(302);
$response->assertRedirect(route('login', ['locale' => 'en']));
@@ -298,16 +300,17 @@ public function guestCannotStoreProject() {
* @test
*/
public function authenticatedUserCannotStoreProject() {
- $user = User::factory()->make();
- $this->be($user);
-
- $response = $this->post(route('projects.store'), [
- 'name' => 'Test Project',
- 'description' => 'Test Description',
- 'status_id' => 1,
- 'slug' => 'test-project',
- 'language_id' => 1,
- ]);
+ $user = User::factory()->create();
+ $this->actingAs($user);
+
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class) // Disable CSRF only
+ ->post(route('projects.store'), [
+ 'name' => 'Test Project',
+ 'description' => 'Test Description',
+ 'status_id' => 1,
+ 'slug' => 'test-project',
+ 'language_id' => 1,
+ ]);
$response->assertStatus(403);
}
@@ -323,17 +326,18 @@ public function adminCanStoreProjectWithValidData() {
$faker = Faker::create();
- $response = $this->post(route('projects.store'), [
- 'name' => 'Valid Project',
- 'description' => 'Valid Description',
- 'status_id' => 1,
- 'slug' => 'valid-project',
- 'language_id' => 1,
- 'color_ids' => [1],
- 'color_names' => [$faker->name],
- 'color_codes' => [$faker->hexColor],
- 'motto_subtitle' => $faker->text,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('projects.store'), [
+ 'name' => 'Valid Project',
+ 'description' => 'Valid Description',
+ 'status_id' => 1,
+ 'slug' => 'valid-project',
+ 'language_id' => 1,
+ 'color_ids' => [1],
+ 'color_names' => [$faker->name],
+ 'color_codes' => [$faker->hexColor],
+ 'motto_subtitle' => $faker->text,
+ ]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_success', 'The project has been successfully created');
@@ -357,7 +361,7 @@ public function adminCannotStoreProjectWithExistingData() {
$project = CrowdSourcingProject::factory()->create();
- $response = $this->post(route('projects.store'), [
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)->post(route('projects.store'), [
'name' => $project->defaultTranslation->name,
'description' => $project->defaultTranslation->description,
'status_id' => $project->status_id,
@@ -378,7 +382,7 @@ public function storeProjectWithInvalidData() {
->create();
$this->be($user);
- $response = $this->post(route('projects.store'), [
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)->post(route('projects.store'), [
'name' => '',
'description' => '',
'status_id' => 'invalid',
@@ -396,7 +400,7 @@ public function storeProjectWithInvalidData() {
public function guestCannotUpdateProject() {
$project = CrowdSourcingProject::factory()->create();
- $response = $this->put(route('projects.update', ['project' => $project->id]), [
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)->put(route('projects.update', ['project' => $project->id]), [
'name' => 'Updated Project',
'description' => 'Updated Description',
'status_id' => 1,
@@ -417,7 +421,7 @@ public function authenticatedUserCannotUpdateProject() {
$project = CrowdSourcingProject::factory()->create();
- $response = $this->put(route('projects.update', ['project' => $project->id]), [
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)->put(route('projects.update', ['project' => $project->id]), [
'name' => 'Updated Project',
'description' => 'Updated Description',
'status_id' => 1,
@@ -439,7 +443,7 @@ public function adminCanUpdateProjectWithValidData() {
$project = CrowdSourcingProject::factory()->create();
$faker = Faker::create();
- $response = $this->put(route('projects.update', ['project' => $project->id]), [
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)->put(route('projects.update', ['project' => $project->id]), [
'name' => 'Updated Project',
'description' => 'Updated Description',
'status_id' => 1,
@@ -475,7 +479,7 @@ public function adminCannotUpdateProjectWithInvalidData() {
$project = CrowdSourcingProject::factory()->create();
- $response = $this->put(route('projects.update', ['project' => $project->id]), [
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)->put(route('projects.update', ['project' => $project->id]), [
'name' => '',
'description' => '',
'status_id' => 'invalid',
diff --git a/tests/Feature/Controllers/FileControllerTest.php b/tests/Feature/Controllers/FileControllerTest.php
index b70f5edf..a01d8b86 100644
--- a/tests/Feature/Controllers/FileControllerTest.php
+++ b/tests/Feature/Controllers/FileControllerTest.php
@@ -2,6 +2,7 @@
namespace Tests\Feature\Controllers;
+use App\Http\Middleware\VerifyCsrfToken;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
@@ -20,11 +21,12 @@ public function uploadFilesSuccessfullyUploadsFiles() {
UploadedFile::fake()->image('photo2.jpg'),
];
- $response = $this->postJson('/files/upload', [
- 'files' => $files,
- 'project_id' => 1,
- 'questionnaire_id' => 1,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->postJson('/files/upload', [
+ 'files' => $files,
+ 'project_id' => 1,
+ 'questionnaire_id' => 1,
+ ]);
$response->assertStatus(200);
$response->assertJsonCount(2);
@@ -42,11 +44,12 @@ public function uploadFilesFailsWithInvalidFileType() {
UploadedFile::fake()->create('document.txt', 100),
];
- $response = $this->postJson('/files/upload', [
- 'files' => $files,
- 'project_id' => 1,
- 'questionnaire_id' => 1,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->postJson('/files/upload', [
+ 'files' => $files,
+ 'project_id' => 1,
+ 'questionnaire_id' => 1,
+ ]);
$response->assertStatus(422);
$response->assertJsonValidationErrors(['files.0']);
@@ -57,11 +60,12 @@ public function uploadFilesFailsWithTooManyFiles() {
Storage::fake('s3');
$files = array_fill(0, 9, UploadedFile::fake()->image('photo.jpg'));
- $response = $this->postJson('/files/upload', [
- 'files' => $files,
- 'project_id' => 1,
- 'questionnaire_id' => 1,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->postJson('/files/upload', [
+ 'files' => $files,
+ 'project_id' => 1,
+ 'questionnaire_id' => 1,
+ ]);
$response->assertStatus(422);
$response->assertJsonValidationErrors(['files']);
@@ -74,10 +78,11 @@ public function uploadFilesFailsWithoutProjectId() {
UploadedFile::fake()->image('photo.jpg'),
];
- $response = $this->postJson('/files/upload', [
- 'files' => $files,
- 'questionnaire_id' => 1,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->postJson('/files/upload', [
+ 'files' => $files,
+ 'questionnaire_id' => 1,
+ ]);
$response->assertStatus(422);
$response->assertJsonValidationErrors(['project_id']);
@@ -90,10 +95,11 @@ public function uploadFilesFailsWithoutQuestionnaireId() {
UploadedFile::fake()->image('photo.jpg'),
];
- $response = $this->postJson('/files/upload', [
- 'files' => $files,
- 'project_id' => 1,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->postJson('/files/upload', [
+ 'files' => $files,
+ 'project_id' => 1,
+ ]);
$response->assertStatus(422);
$response->assertJsonValidationErrors(['questionnaire_id']);
diff --git a/tests/Feature/Controllers/Questionnaire/QuestionnaireControllerTest.php b/tests/Feature/Controllers/Questionnaire/QuestionnaireControllerTest.php
index 1da12dc0..bfac7df0 100644
--- a/tests/Feature/Controllers/Questionnaire/QuestionnaireControllerTest.php
+++ b/tests/Feature/Controllers/Questionnaire/QuestionnaireControllerTest.php
@@ -5,30 +5,27 @@
use App\BusinessLogicLayer\lkp\CrowdSourcingProjectStatusLkp;
use App\BusinessLogicLayer\lkp\QuestionnaireStatusLkp;
use App\BusinessLogicLayer\lkp\UserRolesLkp;
+use App\Http\Middleware\VerifyCsrfToken;
use App\Models\CrowdSourcingProject\CrowdSourcingProject;
use App\Models\Questionnaire\Questionnaire;
use App\Models\Questionnaire\QuestionnaireLanguage;
use App\Models\User;
use App\Models\UserRole;
use App\Utils\Translator;
-use Illuminate\Foundation\Testing\RefreshDatabase;
use Mockery;
use Tests\TestCase;
class QuestionnaireControllerTest extends TestCase {
- use RefreshDatabase;
-
- protected $seed = true;
-
/**
* @test
*/
public function guestCannotSaveQuestionnaireStatus() {
- $response = $this->post(route('update-questionnaire-status'), [
- 'questionnaire_id' => 1,
- 'status_id' => 1,
- 'comments' => 'Test comment',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('update-questionnaire-status'), [
+ 'questionnaire_id' => 1,
+ 'status_id' => 1,
+ 'comments' => 'Test comment',
+ ]);
$response->assertStatus(302);
$response->assertRedirect(route('login', ['locale' => 'en']));
@@ -45,11 +42,12 @@ public function adminCanSaveQuestionnaireStatus() {
$questionnaire = Questionnaire::factory()->create();
- $response = $this->post(route('update-questionnaire-status'), [
- 'questionnaire_id' => $questionnaire->id,
- 'status_id' => QuestionnaireStatusLkp::PUBLISHED,
- 'comments' => 'Test comment',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('update-questionnaire-status'), [
+ 'questionnaire_id' => $questionnaire->id,
+ 'status_id' => QuestionnaireStatusLkp::PUBLISHED,
+ 'comments' => 'Test comment',
+ ]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_success', 'The questionnaire status has been updated.');
@@ -68,11 +66,12 @@ public function adminCannotSaveQuestionnaireStatusWithInvalidQuestionnaireId() {
->create();
$this->be($user);
- $response = $this->post(route('update-questionnaire-status'), [
- 'questionnaire_id' => 'invalid',
- 'status_id' => 'invalid',
- 'comments' => '',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('update-questionnaire-status'), [
+ 'questionnaire_id' => 'invalid',
+ 'status_id' => 'invalid',
+ 'comments' => '',
+ ]);
$response->assertStatus(302);
$response->assertSessionHasErrors(['status_id']);
@@ -87,11 +86,12 @@ public function adminCannotSaveQuestionnaireStatusWithInvalidData() {
->create();
$this->be($user);
- $response = $this->post(route('update-questionnaire-status'), [
- 'questionnaire_id' => 1,
- 'status_id' => 'invalid',
- 'comments' => '',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('update-questionnaire-status'), [
+ 'questionnaire_id' => 1,
+ 'status_id' => 'invalid',
+ 'comments' => '',
+ ]);
$response->assertStatus(302);
$response->assertSessionHasErrors(['status_id']);
@@ -130,28 +130,29 @@ public function adminCanStoreQuestionnaireWithValidData() {
->has(UserRole::factory()->state(['role_id' => UserRolesLkp::ADMIN]))
->create();
$this->be($user);
- $response = $this->post(route('store-questionnaire'), [
- 'title' => 'Test Questionnaire',
- 'description' => 'Test Description',
- 'project_id' => 1,
- 'prerequisite_order' => 1,
- 'status_id' => 1,
- 'type_id' => 1,
- 'language' => 1,
- 'goal' => 123,
- 'questionnaire_json' => json_encode([
- 'question1' => 'What is your name?',
- 'question2' => 'What is your age?',
- 'question3' => 'What?']),
- 'statistics_page_visibility_lkp_id' => 1,
- 'max_votes_num' => 5,
- 'show_general_statistics' => true,
- 'respondent_auth_required' => false,
- 'show_file_type_questions_to_statistics_page_audience' => false,
- 'lang_codes' => ['en', 'fr'],
- 'content' => 'Test content',
- 'project_ids' => [1],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('store-questionnaire'), [
+ 'title' => 'Test Questionnaire',
+ 'description' => 'Test Description',
+ 'project_id' => 1,
+ 'prerequisite_order' => 1,
+ 'status_id' => 1,
+ 'type_id' => 1,
+ 'language' => 1,
+ 'goal' => 123,
+ 'questionnaire_json' => json_encode([
+ 'question1' => 'What is your name?',
+ 'question2' => 'What is your age?',
+ 'question3' => 'What?']),
+ 'statistics_page_visibility_lkp_id' => 1,
+ 'max_votes_num' => 5,
+ 'show_general_statistics' => true,
+ 'respondent_auth_required' => false,
+ 'show_file_type_questions_to_statistics_page_audience' => false,
+ 'lang_codes' => ['en', 'fr'],
+ 'content' => 'Test content',
+ 'project_ids' => [1],
+ ]);
$response->assertStatus(201);
$questionnaire = Questionnaire::latest()->first();
@@ -172,19 +173,20 @@ public function adminCannotStoreQuestionnaireWithInvalidData() {
->create();
$this->be($user);
- $response = $this->post(route('store-questionnaire'), [
- 'title' => 'Test Questionnaire',
- 'description' => 'Test Description',
- 'project_id' => 'invalid',
- 'prerequisite_order' => 1,
- 'status_id' => 1,
- 'type_id' => 1,
- 'language' => 1,
- 'goal' => 123,
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('store-questionnaire'), [
+ 'title' => 'Test Questionnaire',
+ 'description' => 'Test Description',
+ 'project_id' => 'invalid',
+ 'prerequisite_order' => 1,
+ 'status_id' => 1,
+ 'type_id' => 1,
+ 'language' => 1,
+ 'goal' => 123,
+ ]);
$response->assertStatus(302);
- $response->assertSessionHasErrors(['statistics_page_visibility_lkp_id', 'lang_codes', 'content', 'project_ids']);
+ $response->assertSessionHasErrors(['statistics_page_visibility_lkp_id', 'content', 'project_ids']);
}
/**
@@ -196,28 +198,29 @@ public function adminCannotStoreQuestionnaireWithInvalidData() {
public function guestCannotUpdateQuestionnaire() {
$questionnaire = Questionnaire::factory()->create();
- $response = $this->post(route('update-questionnaire', ['id' => $questionnaire->id]), [
- 'title' => 'Test Questionnaire',
- 'description' => 'Test Description',
- 'project_id' => 1,
- 'prerequisite_order' => 1,
- 'status_id' => 1,
- 'type_id' => 1,
- 'language' => 1,
- 'goal' => 123,
- 'questionnaire_json' => json_encode([
- 'question1' => 'What is your name?',
- 'question2' => 'What is your age?',
- 'question3' => 'What?']),
- 'statistics_page_visibility_lkp_id' => 1,
- 'max_votes_num' => 5,
- 'show_general_statistics' => true,
- 'respondent_auth_required' => false,
- 'show_file_type_questions_to_statistics_page_audience' => false,
- 'lang_codes' => ['en', 'fr'],
- 'content' => 'Test content',
- 'project_ids' => [1],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('update-questionnaire', ['id' => $questionnaire->id]), [
+ 'title' => 'Test Questionnaire',
+ 'description' => 'Test Description',
+ 'project_id' => 1,
+ 'prerequisite_order' => 1,
+ 'status_id' => 1,
+ 'type_id' => 1,
+ 'language' => 1,
+ 'goal' => 123,
+ 'questionnaire_json' => json_encode([
+ 'question1' => 'What is your name?',
+ 'question2' => 'What is your age?',
+ 'question3' => 'What?']),
+ 'statistics_page_visibility_lkp_id' => 1,
+ 'max_votes_num' => 5,
+ 'show_general_statistics' => true,
+ 'respondent_auth_required' => false,
+ 'show_file_type_questions_to_statistics_page_audience' => false,
+ 'lang_codes' => ['en', 'fr'],
+ 'content' => 'Test content',
+ 'project_ids' => [1],
+ ]);
$response->assertStatus(302);
$response->assertRedirect(route('login', ['locale' => 'en']));
@@ -235,28 +238,29 @@ public function adminCanUpdateQuestionnaireWithValidData() {
->has(UserRole::factory()->state(['role_id' => UserRolesLkp::ADMIN]))
->create();
$this->be($user);
- $response = $this->post(route('update-questionnaire', ['id' => $questionnaire->id]), [
- 'title' => 'Test Questionnaire new',
- 'description' => 'Test Description new',
- 'project_id' => 1,
- 'prerequisite_order' => 1,
- 'status_id' => 1,
- 'type_id' => 1,
- 'language' => 1,
- 'goal' => 10,
- 'questionnaire_json' => json_encode([
- 'question1' => 'What is your name?',
- 'question2' => 'What is your age?',
- 'question3' => 'What?']),
- 'statistics_page_visibility_lkp_id' => 1,
- 'max_votes_num' => 5,
- 'show_general_statistics' => 1,
- 'respondent_auth_required' => false,
- 'show_file_type_questions_to_statistics_page_audience' => false,
- 'lang_codes' => ['en', 'fr'],
- 'content' => 'Test content',
- 'project_ids' => [1],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('update-questionnaire', ['id' => $questionnaire->id]), [
+ 'title' => 'Test Questionnaire new',
+ 'description' => 'Test Description new',
+ 'project_id' => 1,
+ 'prerequisite_order' => 1,
+ 'status_id' => 1,
+ 'type_id' => 1,
+ 'language' => 1,
+ 'goal' => 10,
+ 'questionnaire_json' => json_encode([
+ 'question1' => 'What is your name?',
+ 'question2' => 'What is your age?',
+ 'question3' => 'What?']),
+ 'statistics_page_visibility_lkp_id' => 1,
+ 'max_votes_num' => 5,
+ 'show_general_statistics' => 1,
+ 'respondent_auth_required' => false,
+ 'show_file_type_questions_to_statistics_page_audience' => false,
+ 'lang_codes' => ['en', 'fr'],
+ 'content' => 'Test content',
+ 'project_ids' => [1],
+ ]);
$response->assertStatus(200);
$this->assertDatabaseHas('questionnaires', [
@@ -284,31 +288,33 @@ public function adminCannotUpdateQuestionnaireWithInvalidData() {
$questionnaire = Questionnaire::factory()->create();
- $response = $this->post(route('update-questionnaire', ['id' => $questionnaire->id]), [
- 'title' => 'Test Questionnaire',
- 'description' => 'Test Description',
- 'project_id' => 'invalid',
- 'prerequisite_order' => 1,
- 'status_id' => 1,
- 'type_id' => 1,
- 'language' => 1,
- 'goal' => 123,
- 'content' => 'Test content',
- 'project_ids' => [1],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('update-questionnaire', ['id' => $questionnaire->id]), [
+ 'title' => 'Test Questionnaire',
+ 'description' => 'Test Description',
+ 'project_id' => 'invalid',
+ 'prerequisite_order' => 1,
+ 'status_id' => 1,
+ 'type_id' => 1,
+ 'language' => 1,
+ 'goal' => 123,
+ 'content' => 'Test content',
+ 'project_ids' => [1],
+ ]);
$response->assertStatus(302);
- $response->assertSessionHasErrors(['statistics_page_visibility_lkp_id', 'lang_codes']);
+ $response->assertSessionHasErrors(['statistics_page_visibility_lkp_id']);
}
/**
* @test
*/
public function guestCannotTranslateQuestionnaire() {
- $response = $this->post(route('questionnaire.translate'), [
- 'questionnaire_json' => '{}',
- 'locales' => ['en', 'fr'],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.translate'), [
+ 'questionnaire_json' => '{}',
+ 'locales' => ['en', 'fr'],
+ ]);
$response->assertStatus(302);
$response->assertRedirect(route('login', ['locale' => 'en']));
@@ -339,10 +345,11 @@ public function adminCanTranslateQuestionnaireWithValidData() {
// Inject the mock into the service container
$this->app->instance(Translator::class, $translatorMock);
- $response = $this->post(route('questionnaire.translate'), [
- 'questionnaire_json' => '{ "title": { "default": "What is your opinion on Democracy in EU?", "gr": "Ποιά είναι η άποψή σας για τις Εκλογές στην ΕΕ;" }, "description": { "default": "Please share your opinion with us!", "gr": "Μοιραστείτε μαζί μας τη γνώμη σας!" }, "logoPosition": "right", "pages": [ { "name": "page1", "elements": [ { "type": "radiogroup", "name": "question2", "title": { "default": "Have you ever participated in Democratic processes about the EU?", "gr": "Έχετε συμμετάσχει ποτέ σε δημοκρατικές διαδικασίες που αφορούν την ΕΕ;" }, "choices": [ { "value": "item1", "text": { "default": "Yes, more than once", "gr": "Ναι, περισσότερες από μια φορές" } }, { "value": "item2", "text": { "default": "I am not sure", "gr": "Δεν είμαι σίγουρος/η" } }, { "value": "item3", "text": { "default": "Never", "gr": "Ποτέ" } } ] }, { "type": "comment", "name": "question3", "title": { "default": "How could Democracy in EU improve?", "gr": "Πώς θα μπορούσε να βελτιωθεί η Δημοκρατία στην ΕΕ;" } } ] } ] }',
- 'locales' => ['en', 'fr'],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.translate'), [
+ 'questionnaire_json' => '{ "title": { "default": "What is your opinion on Democracy in EU?", "gr": "Ποιά είναι η άποψή σας για τις Εκλογές στην ΕΕ;" }, "description": { "default": "Please share your opinion with us!", "gr": "Μοιραστείτε μαζί μας τη γνώμη σας!" }, "logoPosition": "right", "pages": [ { "name": "page1", "elements": [ { "type": "radiogroup", "name": "question2", "title": { "default": "Have you ever participated in Democratic processes about the EU?", "gr": "Έχετε συμμετάσχει ποτέ σε δημοκρατικές διαδικασίες που αφορούν την ΕΕ;" }, "choices": [ { "value": "item1", "text": { "default": "Yes, more than once", "gr": "Ναι, περισσότερες από μια φορές" } }, { "value": "item2", "text": { "default": "I am not sure", "gr": "Δεν είμαι σίγουρος/η" } }, { "value": "item3", "text": { "default": "Never", "gr": "Ποτέ" } } ] }, { "type": "comment", "name": "question3", "title": { "default": "How could Democracy in EU improve?", "gr": "Πώς θα μπορούσε να βελτιωθεί η Δημοκρατία στην ΕΕ;" } } ] } ] }',
+ 'locales' => ['en', 'fr'],
+ ]);
$response->assertStatus(200);
$response->assertJsonStructure(['translation']);
@@ -357,10 +364,11 @@ public function adminCannotTranslateQuestionnaireWithInvalidData() {
->create();
$this->be($user);
- $response = $this->post(route('questionnaire.translate'), [
- 'questionnaire_json' => '',
- 'locales' => 'invalid',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.translate'), [
+ 'questionnaire_json' => '',
+ 'locales' => 'invalid',
+ ]);
$response->assertStatus(302);
$response->assertSessionHasErrors(['questionnaire_json', 'locales']);
@@ -401,12 +409,13 @@ public function adminCanMarkQuestionnaireTranslations() {
]);
- $response = $this->post(route('questionnaire.mark-translations'), [
- 'questionnaire_id' => $questionnaire->id,
- 'lang_ids_to_status' => [
- ['id' => 1, 'status' => true],
- ],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.mark-translations'), [
+ 'questionnaire_id' => $questionnaire->id,
+ 'lang_ids_to_status' => [
+ ['id' => 1, 'status' => true],
+ ],
+ ]);
$response->assertStatus(200);
$response->assertJson(['success' => true]);
diff --git a/tests/Feature/Controllers/Questionnaire/QuestionnaireResponseControllerTest.php b/tests/Feature/Controllers/Questionnaire/QuestionnaireResponseControllerTest.php
index d0723174..1a4e270a 100644
--- a/tests/Feature/Controllers/Questionnaire/QuestionnaireResponseControllerTest.php
+++ b/tests/Feature/Controllers/Questionnaire/QuestionnaireResponseControllerTest.php
@@ -3,6 +3,7 @@
namespace Tests\Feature\Controllers\Questionnaire;
use App\BusinessLogicLayer\UserManager;
+use App\Http\Middleware\VerifyCsrfToken;
use App\Models\CrowdSourcingProject\CrowdSourcingProject;
use App\Models\Questionnaire\Questionnaire;
use App\Models\Questionnaire\QuestionnaireResponse;
@@ -20,11 +21,12 @@ public function testStoreInvalidData() {
$user = User::factory()->create();
$this->be($user);
- $response = $this->postJson(route('questionnaire-responses.store'), [
- 'browser_fingerprint_id' => '',
- 'questionnaire_id' => 'invalid',
- 'project_id' => 'invalid',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->postJson(route('questionnaire-responses.store'), [
+ 'browser_fingerprint_id' => '',
+ 'questionnaire_id' => 'invalid',
+ 'project_id' => 'invalid',
+ ]);
$response->assertStatus(422);
$response->assertJsonValidationErrors(['browser_fingerprint_id', 'questionnaire_id', 'project_id']);
@@ -34,21 +36,22 @@ public function testStoreInvalidData() {
public function testStoreWithoutAuthenticationForNonModerator() {
$questionnaire = Questionnaire::factory()->create();
- $response = $this->postJson(route('questionnaire-responses.store'), [
- 'browser_fingerprint_id' => 'test_fingerprint',
- 'questionnaire_id' => $questionnaire->id,
- 'project_id' => 1,
- 'lang' => 'en',
- 'moderator' => false,
- 'response' => json_encode([
- 'question1' => 5,
- 'question5' => 'item1',
- 'question4' => [
- 'item1' => 'answer1',
- 'item2' => 'answer2',
- ],
- ]),
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->postJson(route('questionnaire-responses.store'), [
+ 'browser_fingerprint_id' => 'test_fingerprint',
+ 'questionnaire_id' => $questionnaire->id,
+ 'project_id' => 1,
+ 'lang' => 'en',
+ 'moderator' => false,
+ 'response' => json_encode([
+ 'question1' => 5,
+ 'question5' => 'item1',
+ 'question4' => [
+ 'item1' => 'answer1',
+ 'item2' => 'answer2',
+ ],
+ ]),
+ ]);
// since in case of non-logged in user we create an anonymous user, the user that responded is the
// latest user inserted in the Database.
@@ -90,7 +93,8 @@ public function testStoreOfModerator() {
];
// Send POST request to store endpoint
- $response = $this->post(route('questionnaire-responses.store'), $requestData);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire-responses.store'), $requestData);
// Assert response status
$response->assertStatus(200);
@@ -130,7 +134,8 @@ public function testStoreWithoutAuthenticationForNonModeratorWithStoredCookie()
];
// Send POST request to store endpoint
- $response = $this->post(route('questionnaire-responses.store'), $requestData);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire-responses.store'), $requestData);
// Assert response status
$response->assertStatus(200);
@@ -193,7 +198,8 @@ public function testVoteAnswerUpvote() {
];
// Send POST request to voteAnswer endpoint
- $response = $this->post(route('questionnaire.answer-votes.store'), $requestData);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.answer-votes.store'), $requestData);
// Assert response status
$response->assertStatus(200);
@@ -227,7 +233,8 @@ public function testVoteAnswerDownvote() {
];
// Send POST request to voteAnswer endpoint
- $response = $this->post(route('questionnaire.answer-votes.store'), $requestData);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.answer-votes.store'), $requestData);
// Assert response status
$response->assertStatus(200);
diff --git a/tests/Feature/Controllers/Questionnaire/QuestionnaireStatisticsControllerTest.php b/tests/Feature/Controllers/Questionnaire/QuestionnaireStatisticsControllerTest.php
index 23949ae3..d27252f4 100644
--- a/tests/Feature/Controllers/Questionnaire/QuestionnaireStatisticsControllerTest.php
+++ b/tests/Feature/Controllers/Questionnaire/QuestionnaireStatisticsControllerTest.php
@@ -6,6 +6,7 @@
use App\BusinessLogicLayer\lkp\QuestionnaireStatusLkp;
use App\BusinessLogicLayer\lkp\UserRolesLkp;
use App\BusinessLogicLayer\questionnaire\QuestionnaireStatisticsManager;
+use App\Http\Middleware\VerifyCsrfToken;
use App\Models\CrowdSourcingProject\CrowdSourcingProject;
use App\Models\Questionnaire\Questionnaire;
use App\Models\User;
@@ -63,11 +64,12 @@ public function saveStatisticsColorsSavesColorsAndRedirectsBackWithSuccessMessag
$this->be($user);
$questionnaire = Questionnaire::factory()->create();
- $response = $this->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
- 'goal_responses_color' => '#FFFFFF',
- 'actual_responses_color' => '#000000',
- 'total_responses_color' => '#111111',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
+ 'goal_responses_color' => '#FFFFFF',
+ 'actual_responses_color' => '#000000',
+ 'total_responses_color' => '#111111',
+ ]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_success', 'Colors saved!');
@@ -81,15 +83,16 @@ public function saveAllStatisticsColorsSavesColorsAndRedirectsBackWithSuccessMes
$this->be($user);
$questionnaire = Questionnaire::factory()->create();
- $response = $this->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
- 'goal_responses_color' => '#FFFFFF',
- 'actual_responses_color' => '#000000',
- 'total_responses_color' => '#111111',
- 'lang_colors' => [
- '1' => '#000000',
- '2' => '#111111',
- ],
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
+ 'goal_responses_color' => '#FFFFFF',
+ 'actual_responses_color' => '#000000',
+ 'total_responses_color' => '#111111',
+ 'lang_colors' => [
+ '1' => '#000000',
+ '2' => '#111111',
+ ],
+ ]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_success', 'Colors saved!');
@@ -103,10 +106,11 @@ public function saveStatisticsColorsSavesColorsWithWrongInputAndRedirectsBackWit
$this->be($user);
$questionnaire = Questionnaire::factory()->create();
- $response = $this->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
- 'color1' => '#FFFFFF',
- 'color2' => '#000000',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
+ 'color1' => '#FFFFFF',
+ 'color2' => '#000000',
+ ]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_failure', 'Error: 0 Undefined array key "goal_responses_color"');
@@ -124,10 +128,11 @@ public function saveStatisticsColorsHandlesExceptionAndRedirectsBackWithFailureM
$mock->shouldReceive('saveStatisticsColors')->andThrow(new \Exception('Test Exception', 123));
});
- $response = $this->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
- 'color1' => '#FFFFFF',
- 'color2' => '#000000',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('questionnaire.statistics-colors.store', ['questionnaire' => $questionnaire->id]), [
+ 'color1' => '#FFFFFF',
+ 'color2' => '#000000',
+ ]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_failure', 'Error: 123 Test Exception');
diff --git a/tests/Feature/Controllers/UserControllerTest.php b/tests/Feature/Controllers/UserControllerTest.php
index 1c466c21..580d0f95 100644
--- a/tests/Feature/Controllers/UserControllerTest.php
+++ b/tests/Feature/Controllers/UserControllerTest.php
@@ -3,6 +3,7 @@
namespace Tests\Feature\Controllers;
use App\BusinessLogicLayer\lkp\UserRolesLkp;
+use App\Http\Middleware\VerifyCsrfToken;
use App\Models\User;
use App\Models\UserRole;
use Tests\TestCase;
@@ -51,12 +52,13 @@ public function patchUpdatesUserProfileWithValidData() {
$user = User::factory()->create();
$this->be($user);
- $response = $this->post(route('updateUser'), [
- 'nickname' => 'updated-nickname',
- 'password' => '12345678',
- 'password_confirmation' => '12345678',
- 'current_password' => 'password',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('updateUser'), [
+ 'nickname' => 'updated-nickname',
+ 'password' => '12345678',
+ 'password_confirmation' => '12345678',
+ 'current_password' => 'password',
+ ]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_success', 'Profile updated.');
@@ -68,12 +70,13 @@ public function patchUpdatesUserProfileWithValidData() {
/** @test */
public function patchRedirectsToLoginForUnauthenticatedUser() {
- $response = $this->post(route('updateUser'), [
- 'nickname' => 'updated-nickname',
- 'password' => '12345678',
- 'password_confirmation' => '12345678',
- 'current_password' => 'password',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('updateUser'), [
+ 'nickname' => 'updated-nickname',
+ 'password' => '12345678',
+ 'password_confirmation' => '12345678',
+ 'current_password' => 'password',
+ ]);
$response->assertStatus(302);
$response->assertRedirect(route('login', ['locale' => 'en']));
@@ -84,10 +87,11 @@ public function patchHandlesInvalidDataCorrectly() {
$user = User::factory()->create();
$this->be($user);
- $response = $this->post(route('updateUser'), [
- 'nickname' => 'updated-nickname',
- 'password' => '1234',
- ]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('updateUser'), [
+ 'nickname' => 'updated-nickname',
+ 'password' => '1234',
+ ]);
$response->assertStatus(302);
$response->assertSessionHasErrors(['password']);
@@ -98,7 +102,8 @@ public function cannotDeleteDeactivatesUserForNonAdminUser() {
$user = User::factory()->create();
$this->be($user);
- $response = $this->post(route('deleteUser'), ['id' => $user->id]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('deleteUser'), ['id' => $user->id]);
$response->assertStatus(403);
$this->assertDatabaseHas('users', [
@@ -113,14 +118,14 @@ public function deleteDeactivatesUserForAdminUser() {
->has(UserRole::factory()->state(['role_id' => UserRolesLkp::ADMIN]))
->create();
$this->be($user);
- $now = now()->toDateTimeString();
- $response = $this->post(route('deleteUser'), ['id' => $user->id]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('deleteUser'), ['id' => $user->id]);
$response->assertStatus(302);
$response->assertSessionHas('flash_message_success', 'User deleted.');
$this->assertDatabaseHas('users', [
'id' => $user->id,
- 'deleted_at' => $now,
+ 'deleted_at' => \DB::raw('deleted_at IS NOT NULL'),
]);
}
@@ -128,7 +133,8 @@ public function deleteDeactivatesUserForAdminUser() {
public function deleteRedirectsToLoginForUnauthenticatedUser() {
$user = User::factory()->create();
- $response = $this->post(route('deleteUser'), ['id' => $user->id]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('deleteUser'), ['id' => $user->id]);
$response->assertStatus(302);
$response->assertRedirect(route('login', ['locale' => 'en']));
@@ -141,7 +147,8 @@ public function deleteHandlesInvalidUserIdCorrectly() {
->create();
$this->be($user);
- $response = $this->post(route('deleteUser'), ['id' => 999]);
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->post(route('deleteUser'), ['id' => 999]);
$response->assertStatus(404);
}
@@ -173,7 +180,8 @@ public function nonAdminUserCannotGetUsersByCriteria() {
$user = User::factory()->create();
$this->be($user);
- $response = $this->get(route('filterUsers'));
+ $response = $this->withoutMiddleware(VerifyCsrfToken::class)
+ ->get(route('filterUsers'));
$response->assertStatus(403);
}