File manager - Edit - /var/www/html/portal/tests/Feature/CronogramasTest.php
Back
<?php namespace Tests\Feature; use App\Enums\Accounts\Cronogramas\CronogramaActivityStatus; use App\Enums\Accounts\Cronogramas\CronogramaResponsibleType; use App\Models\Accounts\Cronogramas\Activity; use App\Models\Accounts\Cronogramas\ActivityResponsible; use App\Models\Accounts\Cronogramas\Project; use App\Models\Permissao; use App\Models\User; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Tests\TestCase; class CronogramasTest extends TestCase { use DatabaseTransactions; private function seedUserWithCronogramasPermissao(): ?User { $structureId = \DB::table('structures')->value('id'); if (! $structureId) { return null; } $suffix = Str::lower(Str::random(8)); $user = User::query()->create([ 'structure_id' => $structureId, 'firstName' => 'Teste', 'lastName' => 'Cronogramas', 'cpf' => str_pad((string) random_int(10000000000, 99999999999), 11, '0', STR_PAD_LEFT), 'matriculation' => 'CR-' . $suffix, 'phoneNumber' => '21999999999', 'email' => 'cr_' . $suffix . '@example.com', 'password' => Hash::make('password'), 'status' => 'ATIVADO', 'isPasswordDefault' => 0, ]); Permissao::query()->create([ 'user_id' => $user->id, 'permissao' => 'GERENCIADOR_DE_CRONOGRAMAS', 'visualizar' => 1, 'adicionar' => 1, 'editar' => 1, 'excluir' => 1, 'status' => 'ATIVADO', ]); return $user->fresh(); } public function test_visitante_e_redirecionado_ao_login(): void { $response = $this->get(route('admin.cronogramas.dashboard')); $response->assertRedirect(route('admin.login')); } public function test_usuario_com_permissao_acessa_dashboard(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $response = $this->actingAs($user)->get(route('admin.cronogramas.dashboard')); $response->assertOk(); $response->assertSeeText(__('Cronogramas'), false); } public function test_criar_projeto_exige_escopo_organizacional(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $response = $this->actingAs($user)->post(route('admin.cronogramas.projetos.store'), [ 'name' => 'Projeto sem escopo', 'description' => 'Teste', ]); $response->assertSessionHasErrors('scope_structures'); } public function test_criar_projeto_com_escopo_e_atividade(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $this->actingAs($user); $response = $this->post(route('admin.cronogramas.projetos.store'), [ 'name' => 'Projeto teste CR', 'description' => '<script>alert(1)</script>Descrição', 'scope_structures' => [$user->structure_id], ]); $response->assertRedirect(); $project = Project::query()->where('user_id', $user->id)->orderByDesc('created_at')->first(); $this->assertNotNull($project); $this->assertStringNotContainsString('<script>', (string) $project->description); $activityResponse = $this->postJson(route('admin.cronogramas.atividades.store', $project), [ 'title' => 'Atividade inicial', 'status' => 'not_started', ]); $activityResponse->assertOk(); $this->assertDatabaseHas('cr_activities', [ 'project_id' => $project->id, 'title' => 'Atividade inicial', ]); } public function test_anexo_perigoso_e_rejeitado(): void { Storage::fake('public'); $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto anexo', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $activity = Activity::query()->create([ 'project_id' => $project->id, 'title' => 'Atividade anexo', 'status' => 'not_started', 'completion_percent' => 0, 'sort_order' => 1, ]); $file = UploadedFile::fake()->createWithContent('malicioso.txt', '<?php echo "x"; ?>'); $response = $this->actingAs($user)->postJson( route('admin.cronogramas.atividades.attachments', ['project' => $project->id, 'activity' => $activity->id]), ['attachments' => [$file]], ); $response->assertStatus(422); Storage::disk('public')->assertMissing('cronogramas/' . $file->hashName()); } public function test_criar_atividade_aplica_percentual_padrao_do_status(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto percentual status', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $response = $this->actingAs($user)->postJson(route('admin.cronogramas.atividades.store', $project), [ 'title' => 'Atividade em andamento', 'status' => CronogramaActivityStatus::InProgress->value, ]); $response->assertOk(); $this->assertDatabaseHas('cr_activities', [ 'project_id' => $project->id, 'title' => 'Atividade em andamento', 'status' => CronogramaActivityStatus::InProgress->value, 'completion_percent' => 50, ]); } public function test_mudanca_de_status_inline_atualiza_percentual(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto inline status', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $activity = Activity::query()->create([ 'project_id' => $project->id, 'title' => 'Atividade inline', 'status' => CronogramaActivityStatus::NotStarted->value, 'completion_percent' => 0, 'sort_order' => 1, ]); $response = $this->actingAs($user)->patchJson( route('admin.cronogramas.atividades.inline', ['project' => $project->id, 'activity' => $activity->id]), ['status' => CronogramaActivityStatus::Validation->value], ); $response->assertOk(); $this->assertDatabaseHas('cr_activities', [ 'id' => $activity->id, 'status' => CronogramaActivityStatus::Validation->value, 'completion_percent' => 75, ]); } public function test_percentual_explicito_nao_e_sobrescrito_ao_mudar_status(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto percentual explicito', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $activity = Activity::query()->create([ 'project_id' => $project->id, 'title' => 'Atividade custom', 'status' => CronogramaActivityStatus::NotStarted->value, 'completion_percent' => 0, 'sort_order' => 1, ]); $response = $this->actingAs($user)->putJson( route('admin.cronogramas.atividades.update', ['project' => $project->id, 'activity' => $activity->id]), [ 'status' => CronogramaActivityStatus::InProgress->value, 'completion_percent' => 33, ], ); $response->assertOk(); $this->assertDatabaseHas('cr_activities', [ 'id' => $activity->id, 'status' => CronogramaActivityStatus::InProgress->value, 'completion_percent' => 33, ]); } public function test_status_suspenso_preserva_percentual_atual(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto suspenso', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $activity = Activity::query()->create([ 'project_id' => $project->id, 'title' => 'Atividade suspensa', 'status' => CronogramaActivityStatus::InProgress->value, 'completion_percent' => 42, 'sort_order' => 1, ]); $response = $this->actingAs($user)->patchJson( route('admin.cronogramas.atividades.inline', ['project' => $project->id, 'activity' => $activity->id]), ['status' => CronogramaActivityStatus::Suspended->value], ); $response->assertOk(); $this->assertDatabaseHas('cr_activities', [ 'id' => $activity->id, 'status' => CronogramaActivityStatus::Suspended->value, 'completion_percent' => 42, ]); } public function test_atrasado_nao_e_status_selecionavel(): void { $selectable = CronogramaActivityStatus::selectableCases(); $this->assertNotContains(CronogramaActivityStatus::Overdue, $selectable); $this->assertCount(7, $selectable); } public function test_atividade_vencida_aceita_status_de_trabalho_no_inline(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto vencido', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $activity = Activity::query()->create([ 'project_id' => $project->id, 'title' => 'Atividade vencida', 'status' => CronogramaActivityStatus::NotStarted->value, 'completion_percent' => 0, 'planned_end_date' => now()->subDays(5)->toDateString(), 'sort_order' => 1, ]); $response = $this->actingAs($user)->patchJson( route('admin.cronogramas.atividades.inline', ['project' => $project->id, 'activity' => $activity->id]), ['status' => CronogramaActivityStatus::InProgress->value], ); $response->assertOk(); $response->assertJsonPath('activity.status', CronogramaActivityStatus::InProgress->value); $response->assertJsonPath('activity.is_overdue', true); $this->assertDatabaseHas('cr_activities', [ 'id' => $activity->id, 'status' => CronogramaActivityStatus::InProgress->value, 'completion_percent' => 50, ]); } public function test_homologacao_e_o_rotulo_do_status_validation(): void { $this->assertSame(__('Homologação'), CronogramaActivityStatus::Validation->label()); } public function test_enum_responsavel_inclui_unidade_organizacional(): void { $this->assertContains('unidade', CronogramaResponsibleType::values()); $this->assertSame(__('Unidade Organizacional'), CronogramaResponsibleType::Unidade->label()); } public function test_criar_atividade_com_multiplos_responsaveis(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto multi responsavel', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $response = $this->actingAs($user)->postJson(route('admin.cronogramas.atividades.store', $project), [ 'title' => 'Atividade com responsáveis', 'status' => 'not_started', 'responsibles' => [ ['type' => 'user', 'id' => $user->id], ['type' => 'structure', 'id' => $user->structure_id], ], ]); $response->assertOk(); $activity = Activity::query() ->where('project_id', $project->id) ->where('title', 'Atividade com responsáveis') ->firstOrFail(); $this->assertDatabaseHas('cr_activity_responsibles', [ 'activity_id' => $activity->id, 'responsible_type' => 'user', 'responsible_id' => $user->id, ]); $this->assertDatabaseHas('cr_activity_responsibles', [ 'activity_id' => $activity->id, 'responsible_type' => 'structure', 'responsible_id' => $user->structure_id, ]); $this->assertSame(2, ActivityResponsible::where('activity_id', $activity->id)->count()); } public function test_responsavel_inexistente_e_rejeitado(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto responsavel invalido', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $response = $this->actingAs($user)->postJson(route('admin.cronogramas.atividades.store', $project), [ 'title' => 'Atividade responsável inválido', 'status' => 'not_started', 'responsibles' => [ ['type' => 'user', 'id' => (string) Str::uuid()], ], ]); $response->assertStatus(422); } public function test_atualizar_substitui_responsaveis(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto troca responsavel', 'status' => 'active', 'completion_percent' => 0, ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $activity = Activity::query()->create([ 'project_id' => $project->id, 'title' => 'Atividade troca', 'status' => 'not_started', 'completion_percent' => 0, 'sort_order' => 1, ]); ActivityResponsible::create([ 'activity_id' => $activity->id, 'responsible_type' => 'user', 'responsible_id' => $user->id, ]); $response = $this->actingAs($user)->putJson( route('admin.cronogramas.atividades.update', ['project' => $project->id, 'activity' => $activity->id]), [ 'title' => 'Atividade troca', 'responsibles' => [ ['type' => 'structure', 'id' => $user->structure_id], ], ], ); $response->assertOk(); $this->assertDatabaseMissing('cr_activity_responsibles', [ 'activity_id' => $activity->id, 'responsible_type' => 'user', 'responsible_id' => $user->id, ]); $this->assertDatabaseHas('cr_activity_responsibles', [ 'activity_id' => $activity->id, 'responsible_type' => 'structure', 'responsible_id' => $user->structure_id, ]); } public function test_visualizacao_publica_retorna_404_quando_inativa(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto privado', 'status' => 'active', 'completion_percent' => 0, 'public_share_enabled' => false, 'public_share_token' => Str::random(64), ]); $this->get(route('cronogramas.public.show', ['token' => $project->public_share_token])) ->assertNotFound(); } public function test_visualizacao_publica_exibe_projeto_ativo(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $token = Str::random(64); $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto executivo público', 'description' => 'Resumo institucional', 'status' => 'active', 'completion_percent' => 25, 'public_share_enabled' => true, 'public_share_token' => $token, 'public_share_enabled_at' => now(), ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); Activity::query()->create([ 'project_id' => $project->id, 'code' => '1.1', 'title' => 'Marco inicial', 'status' => 'in_progress', 'completion_percent' => 50, 'sort_order' => 1, ]); $response = $this->get(route('cronogramas.public.show', ['token' => $token])); $response->assertOk(); $response->assertSeeText('Projeto executivo público', false); $response->assertSeeText('Marco inicial', false); $response->assertSeeText(__('Visualização executiva'), false); } public function test_botao_visualizacao_publica_ativa_link_e_redireciona(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto link público', 'status' => 'active', 'completion_percent' => 0, 'public_share_enabled' => false, 'public_share_token' => Str::random(64), ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $response = $this->actingAs($user)->get(route('admin.cronogramas.projetos.public.open', $project)); $response->assertRedirect(); $project->refresh(); $this->assertTrue($project->public_share_enabled); $this->assertNotEmpty($project->public_share_token); } public function test_dashboard_exibe_botao_visualizacao_publica(): void { $user = $this->seedUserWithCronogramasPermissao(); if ($user === null) { $this->markTestSkipped('Sem estrutura no banco de testes.'); } $project = Project::query()->create([ 'user_id' => $user->id, 'name' => 'Projeto com botão público', 'status' => 'active', 'completion_percent' => 0, 'public_share_token' => Str::random(64), ]); $project->scopes()->create([ 'scope_type' => 'structure', 'scope_id' => $user->structure_id, ]); $response = $this->actingAs($user)->get(route('admin.cronogramas.dashboard')); $response->assertOk(); $response->assertSeeText(__('Visualização Pública'), false); $response->assertSee(route('admin.cronogramas.projetos.public.open', $project), false); } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.28 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings