Files
WMS/Modules/Helpdesk/Tests/Feature/SettingsCrudTest.php
T

303 lines
15 KiB
PHP

<?php
declare(strict_types=1);
namespace Modules\Helpdesk\Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Modules\Helpdesk\Livewire\SettingsManager;
use Modules\Helpdesk\Models\Category;
use Modules\Helpdesk\Models\GitRepository;
use Modules\Helpdesk\Models\AutomationRule;
use Modules\Helpdesk\Models\CannedResponse;
use Modules\Helpdesk\Models\ChecklistTemplate;
use Modules\Helpdesk\Models\KanbanBoard;
use Modules\Helpdesk\Models\Product;
use Modules\Helpdesk\Models\SlaPolicy;
use Modules\Helpdesk\Models\Tag;
use Modules\Helpdesk\Models\Priority;
use Modules\Helpdesk\Models\Project;
use Modules\Helpdesk\Models\Status;
use Modules\Helpdesk\Models\Team;
use Modules\Helpdesk\Models\WorkflowTemplate;
use Modules\Helpdesk\Tests\Concerns\BuildsHelpdeskFixtures;
use Tests\TestCase;
final class SettingsCrudTest extends TestCase
{
use BuildsHelpdeskFixtures;
use RefreshDatabase;
public function test_settings_manager_creates_updates_and_deletes_statuses(): void
{
$admin = $this->admin();
$component = Livewire::actingAs($admin)
->test(SettingsManager::class)
->set('statusForm.name', 'Awaiting Customer')
->set('statusForm.color', 'amber')
->set('statusForm.sort_order', 20)
->set('statusForm.is_closed', false)
->call('saveStatus')
->assertHasNoErrors();
$status = Status::query()->where('slug', 'awaiting-customer')->firstOrFail();
$component->call('editStatus', $status->id)
->set('statusForm.name', 'Waiting Customer')
->call('saveStatus')
->assertHasNoErrors();
$this->assertDatabaseHas('helpdesk_statuses', ['id' => $status->id, 'name' => 'Waiting Customer']);
$component->call('deleteStatus', $status->id);
$this->assertDatabaseMissing('helpdesk_statuses', ['id' => $status->id]);
}
public function test_settings_manager_creates_lookup_project_team_repository_and_workflow_records(): void
{
$admin = $this->admin();
Livewire::actingAs($admin)
->test(SettingsManager::class)
->set('priorityForm.name', 'Critical')
->set('priorityForm.color', 'red')
->set('priorityForm.sort_order', 1)
->call('savePriority')
->set('categoryForm.name', 'Bug Fix')
->set('categoryForm.color', 'rose')
->set('categoryForm.description', 'Production defects')
->call('saveCategory')
->set('teamForm.name', 'Platform Support')
->set('teamForm.color', 'indigo')
->set('teamForm.description', 'Platform team')
->call('saveTeam')
->set('projectForm.title', 'Core WMS')
->set('projectForm.team_id', Team::query()->where('slug', 'platform-support')->firstOrFail()->id)
->set('projectForm.color', 'blue')
->set('projectForm.description', 'Core platform')
->call('saveProject')
->set('repositoryForm.name', 'WMS Core')
->set('repositoryForm.project_id', Project::query()->where('slug', 'core-wms')->firstOrFail()->id)
->set('repositoryForm.provider', 'github')
->set('repositoryForm.remote_url', 'git@github.com:mpba/wms-core.git')
->set('repositoryForm.default_branch', 'develop')
->set('repositoryForm.webhook_secret', 'secret')
->call('saveRepository')
->set('workflowForm.name', 'Ticket Raised')
->set('workflowForm.event', 'ticket.created')
->set('workflowForm.subject', 'Ticket {{ ticket.reference }} created')
->set('workflowForm.html_body', '<p>Hello {{ requester.name }}</p>')
->set('workflowForm.text_body', 'Hello {{ requester.name }}')
->set('workflowForm.to_role', 'requester')
->call('saveWorkflowTemplate')
->assertHasNoErrors();
$this->assertDatabaseHas('helpdesk_priorities', ['slug' => 'critical']);
$this->assertDatabaseHas('helpdesk_categories', ['slug' => 'bug-fix']);
$this->assertDatabaseHas('helpdesk_teams', ['slug' => 'platform-support']);
$this->assertDatabaseHas('helpdesk_projects', ['slug' => 'core-wms']);
$this->assertDatabaseHas('helpdesk_git_repositories', ['name' => 'WMS Core', 'provider' => 'github']);
$this->assertDatabaseHas('helpdesk_workflow_templates', ['name' => 'Ticket Raised', 'event' => 'ticket.created']);
}
public function test_settings_manager_creates_every_settings_record_with_browser_empty_select_values(): void
{
$admin = $this->admin();
$status = $this->ticketStatus(['name' => 'Triage', 'slug' => 'triage']);
$priority = $this->priority(['name' => 'Standard', 'slug' => 'standard']);
$category = $this->category(['name' => 'General', 'slug' => 'general']);
$team = $this->team(['name' => 'Support Desk', 'slug' => 'support-desk']);
$project = $this->project(['title' => 'Support Portal', 'slug' => 'support-portal']);
Livewire::actingAs($admin)
->test(SettingsManager::class)
->set('categoryForm.company_id', '')
->set('categoryForm.name', 'Accounts')
->set('categoryForm.color', 'blue')
->call('saveCategory')
->assertHasNoErrors()
->set('teamForm.company_id', '')
->set('teamForm.name', 'Accounts Team')
->set('teamForm.color', 'indigo')
->call('saveTeam')
->assertHasNoErrors()
->set('projectForm.company_id', '')
->set('projectForm.team_id', '')
->set('projectForm.title', 'Accounts Portal')
->set('projectForm.color', 'blue')
->call('saveProject')
->assertHasNoErrors()
->set('boardForm.name', 'Support Board')
->set('boardForm.owner_id', '')
->set('boardForm.status_ids', [$status->id])
->call('saveBoard')
->assertHasNoErrors()
->set('repositoryForm.company_id', '')
->set('repositoryForm.project_id', '')
->set('repositoryForm.name', 'Support Repo')
->set('repositoryForm.provider', 'github')
->set('repositoryForm.remote_url', 'git@example.com:support/repo.git')
->set('repositoryForm.default_branch', 'main')
->set('repositoryForm.webhook_secret', '')
->call('saveRepository')
->assertHasNoErrors()
->set('workflowForm.name', 'Updated')
->set('workflowForm.event', 'ticket.updated')
->set('workflowForm.subject', 'Updated {{ ticket.reference }}')
->set('workflowForm.html_body', '<p>Updated</p>')
->set('workflowForm.text_body', '')
->set('workflowForm.cc', '')
->set('workflowForm.bcc', '')
->set('workflowForm.to_role', 'requester')
->call('saveWorkflowTemplate')
->assertHasNoErrors()
->set('cannedForm.company_id', '')
->set('cannedForm.category_id', '')
->set('cannedForm.team_id', '')
->set('cannedForm.name', 'Greeting')
->set('cannedForm.visibility', 'agents')
->set('cannedForm.subject', '')
->set('cannedForm.body', 'Hello {{ requester.name }}')
->call('saveCannedResponse')
->assertHasNoErrors()
->set('slaForm.company_id', '')
->set('slaForm.priority_id', '')
->set('slaForm.category_id', '')
->set('slaForm.name', 'Standard SLA')
->set('slaForm.first_response_minutes', 120)
->set('slaForm.resolution_minutes', 1440)
->call('saveSlaPolicy')
->assertHasNoErrors()
->set('automationForm.company_id', '')
->set('automationForm.name', 'Route Accounts')
->set('automationForm.match_sender', '')
->set('automationForm.match_subject', '')
->set('automationForm.match_mailbox', '')
->set('automationForm.match_category_id', '')
->set('automationForm.set_priority_id', $priority->id)
->set('automationForm.set_category_id', $category->id)
->set('automationForm.set_team_id', $team->id)
->set('automationForm.set_project_id', $project->id)
->set('automationForm.set_status_id', $status->id)
->set('automationForm.set_agent_id', '')
->call('saveAutomationRule')
->assertHasNoErrors()
->set('checklistTemplateForm.company_id', '')
->set('checklistTemplateForm.category_id', '')
->set('checklistTemplateForm.project_id', '')
->set('checklistTemplateForm.name', 'Closure Checks')
->set('checklistTemplateForm.items_text', "Confirm requester\nClose ticket")
->call('saveChecklistTemplate')
->assertHasNoErrors()
->set('tagForm.company_id', '')
->set('tagForm.name', 'Escalated')
->set('tagForm.color', 'red')
->call('saveTag')
->assertHasNoErrors()
->set('productForm.company_id', '')
->set('productForm.name', 'WMS Support')
->set('productForm.type', 'service')
->set('productForm.version', '')
->set('productForm.release_channel', '')
->set('productForm.description', '')
->call('saveProduct')
->assertHasNoErrors();
$this->assertDatabaseHas('helpdesk_categories', ['slug' => 'accounts', 'company_id' => null]);
$this->assertDatabaseHas('helpdesk_teams', ['slug' => 'accounts-team', 'company_id' => null]);
$this->assertDatabaseHas('helpdesk_projects', ['slug' => 'accounts-portal', 'company_id' => null, 'team_id' => null]);
$this->assertDatabaseHas('helpdesk_kanban_boards', ['slug' => 'support-board', 'owner_id' => null]);
$this->assertDatabaseHas('helpdesk_git_repositories', ['name' => 'Support Repo', 'project_id' => null, 'webhook_secret' => null]);
$this->assertDatabaseHas('helpdesk_workflow_templates', ['name' => 'Updated', 'text_body' => null, 'cc' => null, 'bcc' => null]);
$this->assertDatabaseHas('helpdesk_canned_responses', ['slug' => 'greeting', 'category_id' => null, 'team_id' => null]);
$this->assertDatabaseHas('helpdesk_sla_policies', ['slug' => 'standard-sla', 'priority_id' => null, 'category_id' => null]);
$this->assertDatabaseHas('helpdesk_automation_rules', ['slug' => 'route-accounts', 'set_agent_id' => null]);
$this->assertDatabaseHas('helpdesk_checklist_templates', ['slug' => 'closure-checks', 'category_id' => null, 'project_id' => null]);
$this->assertDatabaseHas('helpdesk_tags', ['slug' => 'escalated', 'company_id' => null]);
$this->assertDatabaseHas('helpdesk_products', ['slug' => 'wms-support', 'company_id' => null]);
self::assertTrue(KanbanBoard::query()->where('slug', 'support-board')->firstOrFail()->statuses()->whereKey($status->id)->exists());
self::assertNotNull(CannedResponse::query()->where('slug', 'greeting')->first());
self::assertNotNull(SlaPolicy::query()->where('slug', 'standard-sla')->first());
self::assertNotNull(AutomationRule::query()->where('slug', 'route-accounts')->first());
self::assertNotNull(ChecklistTemplate::query()->where('slug', 'closure-checks')->first());
self::assertNotNull(Tag::query()->where('slug', 'escalated')->first());
self::assertNotNull(Product::query()->where('slug', 'wms-support')->first());
}
public function test_settings_manager_can_edit_and_delete_all_new_setup_records(): void
{
$admin = $this->admin();
$priority = $this->priority(['name' => 'Low', 'slug' => 'low']);
$category = $this->category(['name' => 'Support', 'slug' => 'support']);
$team = $this->team(['name' => 'First Line', 'slug' => 'first-line']);
$project = $this->project(['title' => 'Portal', 'slug' => 'portal', 'team_id' => $team->id]);
$repository = $this->repository(['project_id' => $project->id, 'name' => 'Portal Repo']);
$template = WorkflowTemplate::query()->create([
'name' => 'Closed Message',
'event' => 'ticket.closed',
'subject' => 'Closed {{ ticket.reference }}',
'html_body' => '<p>Closed</p>',
'text_body' => 'Closed',
'to_role' => 'requester',
'is_active' => true,
]);
$component = Livewire::actingAs($admin)->test(SettingsManager::class);
$component->call('editPriority', $priority->id)->set('priorityForm.name', 'Low Priority')->call('savePriority');
$component->call('editCategory', $category->id)->set('categoryForm.name', 'Customer Support')->call('saveCategory');
$component->call('editTeam', $team->id)->set('teamForm.name', 'First Line Support')->call('saveTeam');
$component->call('editProject', $project->id)->set('projectForm.title', 'Customer Portal')->call('saveProject');
$component->call('editRepository', $repository->id)->set('repositoryForm.name', 'Customer Portal Repo')->call('saveRepository');
$component->call('editWorkflowTemplate', $template->id)->set('workflowForm.name', 'Ticket Closed Message')->call('saveWorkflowTemplate');
$this->assertDatabaseHas('helpdesk_priorities', ['id' => $priority->id, 'name' => 'Low Priority']);
$this->assertDatabaseHas('helpdesk_categories', ['id' => $category->id, 'name' => 'Customer Support']);
$this->assertDatabaseHas('helpdesk_teams', ['id' => $team->id, 'name' => 'First Line Support']);
$this->assertDatabaseHas('helpdesk_projects', ['id' => $project->id, 'title' => 'Customer Portal']);
$this->assertDatabaseHas('helpdesk_git_repositories', ['id' => $repository->id, 'name' => 'Customer Portal Repo']);
$this->assertDatabaseHas('helpdesk_workflow_templates', ['id' => $template->id, 'name' => 'Ticket Closed Message']);
$component->call('deletePriority', $priority->id)
->call('deleteCategory', $category->id)
->call('deleteRepository', $repository->id)
->call('deleteWorkflowTemplate', $template->id);
self::assertNull(Priority::query()->find($priority->id));
self::assertNull(Category::query()->find($category->id));
self::assertNull(GitRepository::query()->find($repository->id));
self::assertNull(WorkflowTemplate::query()->find($template->id));
}
public function test_settings_manager_keeps_each_section_open_after_crud_actions(): void
{
$admin = $this->admin();
Livewire::actingAs($admin)
->test(SettingsManager::class)
->call('showSection', 'priorities')
->assertSet('section', 'priorities')
->set('priorityForm.name', 'Browser Critical')
->set('priorityForm.color', 'red')
->set('priorityForm.sort_order', 5)
->call('savePriority')
->assertHasNoErrors()
->assertSet('section', 'priorities');
$priority = Priority::query()->where('slug', 'browser-critical')->firstOrFail();
Livewire::actingAs($admin)
->test(SettingsManager::class)
->call('deletePriority', $priority->id)
->assertSet('section', 'priorities')
->assertHasNoErrors();
$this->assertDatabaseMissing('helpdesk_priorities', ['id' => $priority->id]);
}
}