2023-11-02 17:10:50 -07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Tests\Unit;
|
|
|
|
|
2023-12-21 17:02:44 -08:00
|
|
|
use App\Models\Department;
|
2023-12-21 12:02:48 -08:00
|
|
|
use App\Models\Location;
|
2023-12-18 12:55:48 -08:00
|
|
|
use App\Models\ReportTemplate;
|
2024-01-17 13:19:54 -08:00
|
|
|
use App\Models\User;
|
|
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
|
|
use Tests\Support\InteractsWithSettings;
|
2023-11-02 17:10:50 -07:00
|
|
|
use Tests\TestCase;
|
|
|
|
|
2023-12-18 12:55:48 -08:00
|
|
|
class ReportTemplateTest extends TestCase
|
2023-11-02 17:10:50 -07:00
|
|
|
{
|
2024-01-17 13:19:54 -08:00
|
|
|
use InteractsWithSettings;
|
|
|
|
|
|
|
|
public function testSavedTemplatesAreScopedToTheUser()
|
|
|
|
{
|
|
|
|
// Given there is a saved template for one user
|
|
|
|
ReportTemplate::factory()->create(['name' => 'Report A']);
|
|
|
|
|
|
|
|
// When loading reports/custom while acting as another user that also has a saved template
|
|
|
|
$user = User::factory()->canViewReports()
|
|
|
|
->has(ReportTemplate::factory(['name' => 'Report B']))
|
|
|
|
->create();
|
|
|
|
|
|
|
|
// The user should not see the other user's template (in view as 'report_templates')
|
|
|
|
$this->actingAs($user)
|
|
|
|
->get(route('reports/custom'))
|
|
|
|
->assertViewHas(['report_templates' => function (Collection $reports) {
|
|
|
|
return $reports->pluck('name')->doesntContain('Report A');
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
2023-12-21 13:43:44 -08:00
|
|
|
public function testParsingValuesOnNonExistentReportTemplate()
|
|
|
|
{
|
|
|
|
$unsavedTemplate = new ReportTemplate;
|
|
|
|
|
|
|
|
// checkmarkValue()
|
2023-12-21 17:15:36 -08:00
|
|
|
$this->assertEquals('1', $unsavedTemplate->checkmarkValue('is_a_checkbox_field'));
|
|
|
|
|
2023-12-21 13:43:44 -08:00
|
|
|
// radioValue()
|
2023-12-21 18:07:46 -08:00
|
|
|
$this->assertFalse($unsavedTemplate->radioValue('value_on_unsaved_template', 'can_be_anything'));
|
|
|
|
$this->assertTrue($unsavedTemplate->radioValue('value_on_unsaved_template', 'can_be_anything', true));
|
2023-12-21 17:15:36 -08:00
|
|
|
|
|
|
|
// selectValue()
|
2023-12-21 13:43:44 -08:00
|
|
|
$this->assertNull($unsavedTemplate->selectValue('value_on_unsaved_template'));
|
2023-12-21 17:15:36 -08:00
|
|
|
$this->assertNull($unsavedTemplate->selectValue('value_on_unsaved_template'), Location::class);
|
|
|
|
|
2023-12-21 13:43:44 -08:00
|
|
|
// selectValues()
|
2023-12-21 17:15:36 -08:00
|
|
|
$this->assertEmpty($unsavedTemplate->selectValues('value_on_unsaved_template'));
|
|
|
|
$this->assertEmpty($unsavedTemplate->selectValues('value_on_unsaved_template'), Location::class);
|
|
|
|
|
2023-12-21 13:43:44 -08:00
|
|
|
// textValue()
|
2023-12-21 17:15:36 -08:00
|
|
|
$this->assertEquals('', $unsavedTemplate->selectValue('value_on_unsaved_template'));
|
2023-12-21 13:43:44 -08:00
|
|
|
}
|
|
|
|
|
2023-11-30 16:57:21 -08:00
|
|
|
public function testParsingCheckmarkValue()
|
2023-11-02 17:10:50 -07:00
|
|
|
{
|
2023-12-21 13:46:27 -08:00
|
|
|
$template = ReportTemplate::factory()->create([
|
2023-11-02 17:10:50 -07:00
|
|
|
'options' => [
|
2023-11-30 18:15:04 -08:00
|
|
|
'is_a_checkbox_field' => '1',
|
2024-01-17 17:32:35 -08:00
|
|
|
// This shouldn't happen since unchecked inputs are
|
|
|
|
// not submitted, but we should handle it anyway
|
|
|
|
'is_checkbox_field_with_zero' => '0',
|
2023-11-02 17:10:50 -07:00
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
2023-12-21 13:46:27 -08:00
|
|
|
$this->assertEquals('1', $template->checkmarkValue('is_a_checkbox_field'));
|
|
|
|
$this->assertEquals('0', $template->checkmarkValue('non_existent_key'));
|
2024-01-17 17:32:35 -08:00
|
|
|
$this->assertEquals('0', $template->checkmarkValue('is_checkbox_field_with_zero'));
|
2024-01-18 13:30:51 -08:00
|
|
|
$this->assertEquals('0', (new ReportTemplate)->checkmarkValue('non_existent_key', '0'));
|
2023-11-02 17:10:50 -07:00
|
|
|
}
|
|
|
|
|
2023-11-30 16:57:21 -08:00
|
|
|
public function testParsingTextValue()
|
2023-11-02 17:10:50 -07:00
|
|
|
{
|
2023-12-21 13:46:27 -08:00
|
|
|
$template = ReportTemplate::factory()->create([
|
2023-11-02 17:10:50 -07:00
|
|
|
'options' => [
|
2023-11-30 18:15:04 -08:00
|
|
|
'is_a_text_field' => 'some text',
|
2023-11-02 17:10:50 -07:00
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
2023-12-21 13:46:27 -08:00
|
|
|
$this->assertEquals('some text', $template->textValue('is_a_text_field'));
|
|
|
|
$this->assertEquals('', $template->textValue('non_existent_key'));
|
2023-11-02 17:10:50 -07:00
|
|
|
|
2023-12-18 12:55:48 -08:00
|
|
|
$this->assertEquals('', (new ReportTemplate)->textValue('is_a_text_field'));
|
2023-11-30 18:15:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testParsingRadioValue()
|
|
|
|
{
|
2023-12-21 13:46:27 -08:00
|
|
|
$template = ReportTemplate::factory()->create([
|
2023-12-21 18:07:46 -08:00
|
|
|
'options' => ['property_that_exists' => '1'],
|
2023-11-30 18:15:04 -08:00
|
|
|
]);
|
|
|
|
|
2023-12-21 18:07:46 -08:00
|
|
|
$this->assertTrue($template->radioValue('property_that_exists', '1'));
|
|
|
|
|
|
|
|
// check non-existent key returns false
|
|
|
|
$this->assertFalse($template->radioValue('non_existent_property', 'doesnt_matter'));
|
|
|
|
|
|
|
|
// check default returns true
|
|
|
|
$this->assertTrue($template->radioValue('non_existent_property', 'doesnt_matter', true));
|
2023-11-02 17:10:50 -07:00
|
|
|
}
|
2023-11-30 12:12:57 -08:00
|
|
|
|
2023-11-30 16:57:21 -08:00
|
|
|
public function testParsingSelectValue()
|
|
|
|
{
|
2023-12-21 13:46:27 -08:00
|
|
|
$template = ReportTemplate::factory()->create([
|
2023-11-30 16:57:21 -08:00
|
|
|
'options' => [
|
2023-11-30 18:15:04 -08:00
|
|
|
'is_a_text_field_as_well' => '4',
|
2023-11-30 16:57:21 -08:00
|
|
|
'contains_a_null_value' => null,
|
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
2023-12-21 13:46:27 -08:00
|
|
|
$this->assertEquals('4', $template->selectValue('is_a_text_field_as_well'));
|
|
|
|
$this->assertEquals('', $template->selectValue('non_existent_key'));
|
|
|
|
$this->assertNull($template->selectValue('contains_a_null_value'));
|
2023-11-30 16:57:21 -08:00
|
|
|
}
|
|
|
|
|
2023-11-30 12:12:57 -08:00
|
|
|
public function testParsingSelectValues()
|
2023-11-30 16:57:21 -08:00
|
|
|
{
|
2023-12-21 13:46:27 -08:00
|
|
|
$template = ReportTemplate::factory()->create([
|
2023-11-30 16:57:21 -08:00
|
|
|
'options' => [
|
2023-12-21 16:38:51 -08:00
|
|
|
'an_array' => ['2', '3', '4'],
|
2023-12-21 17:02:44 -08:00
|
|
|
'an_empty_array' => [],
|
2023-12-21 16:38:51 -08:00
|
|
|
'an_array_containing_null' => [null],
|
2023-11-30 16:57:21 -08:00
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
2023-12-21 16:38:51 -08:00
|
|
|
$this->assertEquals(['2', '3', '4'], $template->selectValues('an_array'));
|
|
|
|
$this->assertEquals([], $template->selectValues('an_empty_array'));
|
|
|
|
$this->assertEquals([null], $template->selectValues('an_array_containing_null'));
|
|
|
|
$this->assertEquals([], $template->selectValues('non_existent_key'));
|
2023-11-30 16:57:21 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSelectValueDoesNotIncludeDeletedOrNonExistentModels()
|
2023-11-30 12:12:57 -08:00
|
|
|
{
|
2023-12-21 13:03:43 -08:00
|
|
|
[$locationA, $locationB] = Location::factory()->count(2)->create();
|
|
|
|
$invalidId = 10000;
|
|
|
|
|
|
|
|
$templateWithValidId = ReportTemplate::factory()->create([
|
|
|
|
'options' => ['single_value' => $locationA->id],
|
|
|
|
]);
|
|
|
|
|
|
|
|
$templateWithDeletedId = ReportTemplate::factory()->create([
|
|
|
|
'options' => ['single_value' => $locationB->id],
|
|
|
|
]);
|
|
|
|
$locationB->delete();
|
|
|
|
|
|
|
|
$templateWithInvalidId = ReportTemplate::factory()->create([
|
|
|
|
'options' => ['single_value' => $invalidId],
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
$locationA->id,
|
|
|
|
$templateWithValidId->selectValue('single_value', Location::class)
|
|
|
|
);
|
2023-11-30 16:57:21 -08:00
|
|
|
|
2023-12-21 13:03:43 -08:00
|
|
|
$this->assertNull($templateWithDeletedId->selectValue('single_value', Location::class));
|
|
|
|
$this->assertNull($templateWithInvalidId->selectValue('single_value', Location::class));
|
2023-12-21 13:11:44 -08:00
|
|
|
$this->assertNull((new ReportTemplate)->selectValue('value_on_unsaved_template', Location::class));
|
2023-11-30 12:12:57 -08:00
|
|
|
}
|
|
|
|
|
2023-11-30 16:57:21 -08:00
|
|
|
public function testSelectValuesDoNotIncludeDeletedOrNonExistentModels()
|
2023-11-30 12:12:57 -08:00
|
|
|
{
|
2023-12-21 12:02:48 -08:00
|
|
|
[$locationA, $locationB] = Location::factory()->count(2)->create();
|
2023-12-21 12:15:00 -08:00
|
|
|
$invalidId = 10000;
|
2023-12-21 12:02:48 -08:00
|
|
|
|
2023-12-21 13:46:27 -08:00
|
|
|
$template = ReportTemplate::factory()->create([
|
2023-12-21 12:02:48 -08:00
|
|
|
'options' => [
|
2023-12-21 12:50:21 -08:00
|
|
|
'array_of_ids' => [
|
2023-12-21 12:02:48 -08:00
|
|
|
$locationA->id,
|
|
|
|
$locationB->id,
|
2023-12-21 12:15:00 -08:00
|
|
|
$invalidId,
|
2023-12-21 12:02:48 -08:00
|
|
|
],
|
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
|
|
|
$locationB->delete();
|
|
|
|
|
2023-12-21 13:46:27 -08:00
|
|
|
$parsedValues = $template->selectValues('array_of_ids', Location::class);
|
2023-12-21 12:02:48 -08:00
|
|
|
|
2023-12-21 12:15:00 -08:00
|
|
|
$this->assertContains($locationA->id, $parsedValues);
|
|
|
|
$this->assertNotContains($locationB->id, $parsedValues);
|
|
|
|
$this->assertNotContains($invalidId, $parsedValues);
|
2023-11-30 12:12:57 -08:00
|
|
|
}
|
2023-11-30 16:57:21 -08:00
|
|
|
|
2023-12-07 11:00:26 -08:00
|
|
|
public function testGracefullyHandlesSingleSelectBecomingMultiSelect()
|
|
|
|
{
|
2023-12-21 17:02:44 -08:00
|
|
|
$department = Department::factory()->create();
|
|
|
|
|
|
|
|
$templateWithValue = ReportTemplate::factory()->create([
|
|
|
|
'options' => ['single_value' => 'a string'],
|
|
|
|
]);
|
|
|
|
|
|
|
|
$templateWithModelId = ReportTemplate::factory()->create([
|
|
|
|
'options' => ['by_dept_id' => $department->id],
|
|
|
|
]);
|
|
|
|
|
2024-01-17 11:24:50 -08:00
|
|
|
// If nothing is selected for a single select then it is stored
|
|
|
|
// as null and should be returned as an empty array.
|
|
|
|
$templateWithNull = ReportTemplate::factory()->create([
|
|
|
|
'options' => ['by_dept_id' => null],
|
|
|
|
]);
|
|
|
|
|
2023-12-21 17:02:44 -08:00
|
|
|
$this->assertEquals(['a string'], $templateWithValue->selectValues('single_value'));
|
|
|
|
$this->assertContains($department->id, $templateWithModelId->selectValues('by_dept_id', Department::class));
|
2024-01-17 11:24:50 -08:00
|
|
|
$this->assertEquals([], $templateWithNull->selectValues('by_dept_id'));
|
2023-12-07 11:00:26 -08:00
|
|
|
}
|
|
|
|
|
2024-01-11 13:34:20 -08:00
|
|
|
public function testGracefullyHandlesMultiSelectBecomingSingleSelectBySelectingTheFirstValue()
|
2023-12-07 11:00:26 -08:00
|
|
|
{
|
2023-12-21 17:02:44 -08:00
|
|
|
[$departmentA, $departmentB] = Department::factory()->count(2)->create();
|
|
|
|
|
2024-01-11 13:34:20 -08:00
|
|
|
// Given report templates saved with a property that is an array of values
|
2023-12-21 17:02:44 -08:00
|
|
|
$templateWithValuesInArray = ReportTemplate::factory()->create([
|
2024-01-11 13:34:20 -08:00
|
|
|
'options' => ['array_of_values' => [3, 'a string']],
|
2023-12-21 17:02:44 -08:00
|
|
|
]);
|
|
|
|
|
|
|
|
$templateWithModelIdsInArray = ReportTemplate::factory()->create([
|
2024-01-11 13:34:20 -08:00
|
|
|
'options' => ['array_of_model_ids' => [$departmentA->id, $departmentB->id]],
|
2023-12-21 17:02:44 -08:00
|
|
|
]);
|
|
|
|
|
2024-01-11 13:34:20 -08:00
|
|
|
$this->assertEquals(3, $templateWithValuesInArray->selectValue('array_of_values'));
|
|
|
|
$this->assertEquals(
|
|
|
|
$departmentA->id,
|
|
|
|
$templateWithModelIdsInArray->selectValue('array_of_model_ids', Department::class)
|
|
|
|
);
|
2023-12-07 11:00:26 -08:00
|
|
|
}
|
|
|
|
|
2023-11-30 18:15:04 -08:00
|
|
|
public function testOldValuesStillWorkAfterTheseChanges()
|
|
|
|
{
|
|
|
|
$this->markTestIncomplete();
|
|
|
|
|
|
|
|
// Another marker that won't actually be a test case:
|
|
|
|
// We need to make sure that any behavior involving using "old" input.
|
|
|
|
// I explicitly removed the old()s from the "deleted_assets" radio buttons.
|
|
|
|
// The "x-selects" partials still include them, but I haven't tested them yet.
|
|
|
|
}
|
2023-11-02 17:10:50 -07:00
|
|
|
}
|