165 lines
5.4 KiB
PHP
165 lines
5.4 KiB
PHP
<?php
|
|
|
|
use App\Livewire\NewSupportRequest;
|
|
use App\Livewire\Support;
|
|
use App\Models\Customer;
|
|
use App\Models\Instance;
|
|
use App\Models\SupportRequest;
|
|
use App\Models\User;
|
|
use Livewire\Livewire;
|
|
|
|
/**
|
|
* Asking for help, and being able to see that you did.
|
|
*
|
|
* The page used to be a decorated placeholder: a button that raised a toast
|
|
* saying the form was "only hinted at in the prototype", three invented ticket
|
|
* titles sitting in the translation file, and no way to check what had become
|
|
* of anything. It looked thin because nothing on it was real.
|
|
*/
|
|
|
|
function supportCustomer(): array
|
|
{
|
|
$user = User::factory()->create(['name' => 'Dr. S. Berger']);
|
|
$customer = Customer::factory()->create(['user_id' => $user->id, 'email' => $user->email]);
|
|
|
|
return [$user, $customer];
|
|
}
|
|
|
|
it('records a request and shows it back to the customer', function () {
|
|
[$user, $customer] = supportCustomer();
|
|
|
|
Livewire::actingAs($user)
|
|
->test(NewSupportRequest::class)
|
|
->set('category', 'technical')
|
|
->set('subject', 'Kalendersynchronisation mit Outlook')
|
|
->set('body', 'Termine werden bei zwei Mitarbeitern nicht mehr übernommen.')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$request = SupportRequest::query()->where('customer_id', $customer->id)->sole();
|
|
|
|
expect($request->status)->toBe('open')
|
|
// The person, not the account: on a shared login the account name says
|
|
// nothing about who is actually asking.
|
|
->and($request->reported_by)->toBe('Dr. S. Berger');
|
|
|
|
Livewire::actingAs($user)
|
|
->test(Support::class)
|
|
->assertSee('Kalendersynchronisation mit Outlook')
|
|
->assertSee(__('support.status_open'));
|
|
});
|
|
|
|
it('attaches the instance so nobody has to ask which server', function () {
|
|
[$user, $customer] = supportCustomer();
|
|
$instance = Instance::factory()->create(['customer_id' => $customer->id, 'status' => 'active']);
|
|
|
|
Livewire::actingAs($user)
|
|
->test(NewSupportRequest::class)
|
|
->set('subject', 'Ein Betreff')
|
|
->set('body', 'Eine Nachricht, die lang genug ist.')
|
|
->call('save');
|
|
|
|
expect(SupportRequest::query()->sole()->instance_id)->toBe($instance->id);
|
|
});
|
|
|
|
it('still takes a request from somebody whose cloud is not built yet', function () {
|
|
// A question can arrive before provisioning finishes, and that is exactly
|
|
// when somebody is most likely to have one.
|
|
[$user] = supportCustomer();
|
|
|
|
Livewire::actingAs($user)
|
|
->test(NewSupportRequest::class)
|
|
->set('subject', 'Wann geht es los?')
|
|
->set('body', 'Wir haben gestern bestellt und würden gerne planen.')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
expect(SupportRequest::query()->sole()->instance_id)->toBeNull();
|
|
});
|
|
|
|
it('refuses an empty or barely-written request', function () {
|
|
[$user] = supportCustomer();
|
|
|
|
Livewire::actingAs($user)
|
|
->test(NewSupportRequest::class)
|
|
->set('subject', '')
|
|
->set('body', 'kurz')
|
|
->call('save')
|
|
->assertHasErrors(['subject', 'body']);
|
|
|
|
expect(SupportRequest::query()->count())->toBe(0);
|
|
});
|
|
|
|
it('refuses a category that is not on the form', function () {
|
|
[$user] = supportCustomer();
|
|
|
|
Livewire::actingAs($user)
|
|
->test(NewSupportRequest::class)
|
|
->set('category', 'urgent-vip')
|
|
->set('subject', 'Ein Betreff')
|
|
->set('body', 'Eine Nachricht, die lang genug ist.')
|
|
->call('save')
|
|
->assertHasErrors('category');
|
|
});
|
|
|
|
it('shows a customer only their own requests', function () {
|
|
[$user] = supportCustomer();
|
|
[, $other] = supportCustomer();
|
|
|
|
SupportRequest::create([
|
|
'customer_id' => $other->id,
|
|
'subject' => 'Fremde Anfrage',
|
|
'category' => 'billing',
|
|
'body' => 'Gehört jemand anderem.',
|
|
'status' => 'open',
|
|
]);
|
|
|
|
Livewire::actingAs($user)
|
|
->test(Support::class)
|
|
->assertDontSee('Fremde Anfrage')
|
|
->assertSee(__('support.empty_title'));
|
|
});
|
|
|
|
it('counts only what is still open', function () {
|
|
[$user, $customer] = supportCustomer();
|
|
|
|
foreach (['open', 'in_progress', 'answered', 'closed'] as $status) {
|
|
SupportRequest::create([
|
|
'customer_id' => $customer->id,
|
|
'subject' => 'Anfrage '.$status,
|
|
'category' => 'other',
|
|
'body' => 'Eine Nachricht, die lang genug ist.',
|
|
'status' => $status,
|
|
]);
|
|
}
|
|
|
|
Livewire::actingAs($user)
|
|
->test(Support::class)
|
|
// open + in_progress. Answered and closed are done with.
|
|
->assertViewHas('openCount', 2);
|
|
});
|
|
|
|
it('says something useful when there is nothing to show', function () {
|
|
// An empty state that names the next step, rather than "no data".
|
|
[$user] = supportCustomer();
|
|
|
|
Livewire::actingAs($user)
|
|
->test(Support::class)
|
|
->assertSee(__('support.empty_title'))
|
|
->assertSee(__('support.empty_body'))
|
|
->assertSee(__('support.new'));
|
|
});
|
|
|
|
it('carries no invented ticket titles', function () {
|
|
// Three fictional tickets used to live in the translation file and render
|
|
// as though they were the customer's own.
|
|
foreach (['de', 'en'] as $locale) {
|
|
$keys = array_keys(include base_path("lang/{$locale}/support.php"));
|
|
|
|
expect($keys)->not->toContain('ticket_migration')
|
|
->and($keys)->not->toContain('ticket_training')
|
|
->and($keys)->not->toContain('ticket_smtp')
|
|
->and($keys)->not->toContain('new_toast');
|
|
}
|
|
});
|