Skip to content

Commit

Permalink
Merge pull request #78 from scify/project_lp_cta
Browse files Browse the repository at this point in the history
Refactored projects that are shown in the home page
  • Loading branch information
PavlosIsaris authored Oct 4, 2024
2 parents 691f90d + b221acf commit f8a84a8
Show file tree
Hide file tree
Showing 12 changed files with 314 additions and 312 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions app/Http/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
16 changes: 9 additions & 7 deletions app/Http/Controllers/Questionnaire/QuestionnaireController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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',
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -23,26 +22,19 @@ 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', ])
->where(['status_id' => $questionnaireStatusId])
->withCount('responses')
->orderBy('prerequisite_order')
->orderBy('questionnaire_created', 'desc');
});
})->with('problems');

if (count($additionalRelationships)) {
$builder = $builder->with($additionalRelationships);
}

return $builder->get();
}

public function getPastProjects(): Collection {
return CrowdSourcingProject::where(['status_id' => CrowdSourcingProjectStatusLkp::FINALIZED])->get();
}
}
2 changes: 1 addition & 1 deletion resources/views/home/partials/projects-list-home.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{!! $project->currentTranslation->motto_title !!}
</div>
<div class="project-visit-btn">
@if($project->latestQuestionnaire && $project->latestQuestionnaire->status_id == \App\BusinessLogicLayer\lkp\QuestionnaireStatusLkp::PUBLISHED)
@if(($project->latestQuestionnaire && $project->latestQuestionnaire->status_id == \App\BusinessLogicLayer\lkp\QuestionnaireStatusLkp::PUBLISHED) || $project->problems)
<a href="/{{app()->getLocale() .'/'.$project->slug}}"
class="btn btn-block btn-primary call-to-action action-dark">
{{ isset($projectBtnText) ? $projectBtnText : 'Contribute' }}
Expand Down
15 changes: 1 addition & 14 deletions resources/views/home/partials/together/projects.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,9 @@
<p>The <b><i>"Together"</i></b> crowdsourcing platform hosts various projects. Please check below those
that are the currently active and waiting for your contribution.
Please visit a project's page and make an impact by answering just a couple of questions!</p>

@include('home.partials.projects-list-home')
</div>
</div>
</div>
</div>
@if(isset($pastProjects))
<section id="past-projects">
<div class="container py-5">
<div class="row">
<div class="col-md-6 col-xs-12 mx-auto text-center">
<h2>Check out our past projects:</h2>
</div>
</div>
<div class="row">
@include('home.partials.projects-list-home', ['projects' => $pastProjects, 'projectBtnText' => 'See more'])
</div>
</div>
</section>
@endif
72 changes: 38 additions & 34 deletions tests/Feature/Controllers/CrowdSourcingProjectControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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']));
Expand All @@ -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);
}
Expand All @@ -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');
Expand All @@ -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,
Expand All @@ -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',
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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',
Expand Down
52 changes: 29 additions & 23 deletions tests/Feature/Controllers/FileControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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']);
Expand All @@ -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']);
Expand All @@ -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']);
Expand All @@ -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']);
Expand Down
Loading

0 comments on commit f8a84a8

Please sign in to comment.