159 lines
6.1 KiB
PHP
159 lines
6.1 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
use App\Models\User;
|
||
|
|
use App\Modules\Client\Models\Client;
|
||
|
|
use App\Modules\CustomField\Models\CustomFieldDefinition;
|
||
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
|
|
|
||
|
|
uses(RefreshDatabase::class);
|
||
|
|
|
||
|
|
it('lets any authenticated user list field definitions', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
CustomFieldDefinition::factory(2)->create();
|
||
|
|
|
||
|
|
$this->actingAs($user)->getJson('/api/custom-fields')
|
||
|
|
->assertStatus(200)
|
||
|
|
->assertJsonCount(2, 'data');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('lets an admin create a field definition and derives a unique key', function () {
|
||
|
|
$admin = User::factory()->create(['role' => 'admin']);
|
||
|
|
|
||
|
|
$this->actingAs($admin)->postJson('/api/custom-fields', [
|
||
|
|
'label' => 'Beratungsschwerpunkt',
|
||
|
|
'type' => 'select',
|
||
|
|
'options' => ['Steuerrecht', 'Erbrecht'],
|
||
|
|
])->assertStatus(201)->assertJsonPath('data.key', 'beratungsschwerpunkt');
|
||
|
|
|
||
|
|
$this->assertDatabaseHas('custom_field_definitions', ['label' => 'Beratungsschwerpunkt']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('appends new field definitions to the end of the list', function () {
|
||
|
|
$admin = User::factory()->create(['role' => 'admin']);
|
||
|
|
CustomFieldDefinition::factory()->create(['sort_order' => 2]);
|
||
|
|
|
||
|
|
$this->actingAs($admin)->postJson('/api/custom-fields', [
|
||
|
|
'label' => 'Zuletzt',
|
||
|
|
'type' => 'text',
|
||
|
|
])->assertStatus(201)->assertJsonPath('data.sort_order', 3);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('lets an admin reorder field definitions', function () {
|
||
|
|
$admin = User::factory()->create(['role' => 'admin']);
|
||
|
|
$a = CustomFieldDefinition::factory()->create(['sort_order' => 0]);
|
||
|
|
$b = CustomFieldDefinition::factory()->create(['sort_order' => 1]);
|
||
|
|
$c = CustomFieldDefinition::factory()->create(['sort_order' => 2]);
|
||
|
|
|
||
|
|
$this->actingAs($admin)->postJson('/api/custom-fields/reorder', [
|
||
|
|
'ids' => [$c->id, $a->id, $b->id],
|
||
|
|
])->assertStatus(200)
|
||
|
|
->assertJsonPath('data.0.id', $c->id)
|
||
|
|
->assertJsonPath('data.1.id', $a->id)
|
||
|
|
->assertJsonPath('data.2.id', $b->id);
|
||
|
|
|
||
|
|
$this->assertDatabaseHas('custom_field_definitions', ['id' => $c->id, 'sort_order' => 0]);
|
||
|
|
$this->assertDatabaseHas('custom_field_definitions', ['id' => $a->id, 'sort_order' => 1]);
|
||
|
|
$this->assertDatabaseHas('custom_field_definitions', ['id' => $b->id, 'sort_order' => 2]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('forbids staff from reordering field definitions', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
$definition = CustomFieldDefinition::factory()->create();
|
||
|
|
|
||
|
|
$this->actingAs($user)->postJson('/api/custom-fields/reorder', [
|
||
|
|
'ids' => [$definition->id],
|
||
|
|
])->assertStatus(403);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('forbids staff from creating field definitions', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
|
||
|
|
$this->actingAs($user)->postJson('/api/custom-fields', [
|
||
|
|
'label' => 'Heimlich',
|
||
|
|
'type' => 'text',
|
||
|
|
])->assertStatus(403);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('forbids staff from deleting field definitions', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
$definition = CustomFieldDefinition::factory()->create();
|
||
|
|
|
||
|
|
$this->actingAs($user)->deleteJson("/api/custom-fields/{$definition->id}")->assertStatus(403);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('requires options when the type is select', function () {
|
||
|
|
$admin = User::factory()->create(['role' => 'admin']);
|
||
|
|
|
||
|
|
$this->actingAs($admin)->postJson('/api/custom-fields', [
|
||
|
|
'label' => 'Ohne Optionen',
|
||
|
|
'type' => 'select',
|
||
|
|
])->assertStatus(422);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('records a Verlauf entry when a field value changes', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
$client = Client::factory()->create();
|
||
|
|
$definition = CustomFieldDefinition::factory()->create(['label' => 'Beratungsschwerpunkt']);
|
||
|
|
|
||
|
|
$this->actingAs($user)->putJson("/api/clients/{$client->id}/custom-fields/{$definition->id}", [
|
||
|
|
'value' => 'Steuerrecht',
|
||
|
|
])->assertStatus(200);
|
||
|
|
|
||
|
|
$this->assertDatabaseHas('custom_field_values', [
|
||
|
|
'client_id' => $client->id,
|
||
|
|
'custom_field_definition_id' => $definition->id,
|
||
|
|
'value' => 'Steuerrecht',
|
||
|
|
'author_id' => $user->id,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertDatabaseHas('history_entries', [
|
||
|
|
'client_id' => $client->id,
|
||
|
|
'type' => 'field_change',
|
||
|
|
'custom_field_definition_id' => $definition->id,
|
||
|
|
'author_id' => $user->id,
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('does not record a Verlauf entry when the value is unchanged', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
$client = Client::factory()->create();
|
||
|
|
$definition = CustomFieldDefinition::factory()->create();
|
||
|
|
|
||
|
|
$url = "/api/clients/{$client->id}/custom-fields/{$definition->id}";
|
||
|
|
$this->actingAs($user)->putJson($url, ['value' => 'Hallo'])->assertStatus(200);
|
||
|
|
$this->actingAs($user)->putJson($url, ['value' => 'Hallo'])->assertStatus(200);
|
||
|
|
|
||
|
|
expect(\App\Modules\History\Models\HistoryEntry::where('client_id', $client->id)->count())->toBe(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('validates select values against the defined options', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
$client = Client::factory()->create();
|
||
|
|
$definition = CustomFieldDefinition::factory()->select(['Steuerrecht', 'Erbrecht'])->create();
|
||
|
|
|
||
|
|
$this->actingAs($user)->putJson("/api/clients/{$client->id}/custom-fields/{$definition->id}", [
|
||
|
|
'value' => 'Strafrecht',
|
||
|
|
])->assertStatus(422);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('validates number values', function () {
|
||
|
|
$admin = User::factory()->create(['role' => 'admin']);
|
||
|
|
$client = Client::factory()->create();
|
||
|
|
$definition = CustomFieldDefinition::factory()->create(['type' => 'number']);
|
||
|
|
|
||
|
|
$this->actingAs($admin)->putJson("/api/clients/{$client->id}/custom-fields/{$definition->id}", [
|
||
|
|
'value' => 'not-a-number',
|
||
|
|
])->assertStatus(422);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('embeds custom fields on the client detail response', function () {
|
||
|
|
$user = User::factory()->create(['role' => 'staff']);
|
||
|
|
$client = Client::factory()->create();
|
||
|
|
CustomFieldDefinition::factory()->create(['label' => 'Mandant seit', 'sort_order' => 1]);
|
||
|
|
|
||
|
|
$this->actingAs($user)->getJson("/api/clients/{$client->id}")
|
||
|
|
->assertStatus(200)
|
||
|
|
->assertJsonPath('data.custom_fields.0.label', 'Mandant seit')
|
||
|
|
->assertJsonPath('data.custom_fields.0.value', null);
|
||
|
|
});
|