3
0
mirror of https://github.com/snipe/snipe-it.git synced 2026-06-01 20:55:23 +00:00
Files
snipe-it/tests/Feature/Users/UserCompanyLoggingTest.php
2026-05-19 13:04:16 +01:00

152 lines
5.4 KiB
PHP

<?php
namespace Tests\Feature\Users;
use App\Models\Actionlog;
use App\Models\Company;
use App\Models\User;
use Tests\TestCase;
class UserCompanyLoggingTest extends TestCase
{
public function test_field_and_company_changes_produce_single_log_entry()
{
[$companyA, $companyB] = Company::factory()->count(2)->create();
$user = User::factory()->create(['company_id' => $companyA->id, 'jobtitle' => 'Engineer']);
$user->companies()->sync([$companyA->id]);
$actor = User::factory()->superuser()->create();
$existingLogIds = Actionlog::where('item_type', User::class)
->where('item_id', $user->id)
->pluck('id');
$this->actingAsForApi($actor)
->patchJson(route('api.users.update', $user), [
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'username' => $user->username,
'jobtitle' => 'Senior Engineer',
'company_ids' => [$companyB->id],
])
->assertOk();
$newLogs = Actionlog::where('item_type', User::class)
->where('item_id', $user->id)
->where('action_type', 'update')
->whereNotIn('id', $existingLogIds)
->get();
$this->assertCount(1, $newLogs, 'Field and company changes should produce exactly one log entry');
$meta = json_decode($newLogs->first()->log_meta, true);
$this->assertArrayHasKey('jobtitle', $meta, 'Log should include field change');
$this->assertArrayHasKey('companies', $meta, 'Log should include company change in same entry');
}
public function test_company_only_change_produces_standalone_log_entry()
{
[$companyA, $companyB] = Company::factory()->count(2)->create();
$user = User::factory()->create(['company_id' => $companyA->id]);
$user->companies()->sync([$companyA->id]);
$actor = User::factory()->superuser()->create();
$existingLogIds = Actionlog::where('item_type', User::class)
->where('item_id', $user->id)
->pluck('id');
// Patch with no field changes — only company_ids differs.
$this->actingAsForApi($actor)
->patchJson(route('api.users.update', $user), [
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'username' => $user->username,
'company_ids' => [$companyB->id],
])
->assertOk();
$newLogs = Actionlog::where('item_type', User::class)
->where('item_id', $user->id)
->where('action_type', 'update')
->whereNotIn('id', $existingLogIds)
->get();
$this->assertCount(1, $newLogs, 'Company-only change should produce one log entry');
$meta = json_decode($newLogs->first()->log_meta, true);
$this->assertArrayHasKey('companies', $meta, 'Log should record company change');
}
public function test_log_entry_records_old_and_new_company_ids()
{
[$companyA, $companyB, $companyC] = Company::factory()->count(3)->create();
$user = User::factory()->create(['company_id' => $companyA->id]);
$user->companies()->sync([$companyA->id, $companyB->id]);
$actor = User::factory()->superuser()->create();
$this->actingAsForApi($actor)
->patchJson(route('api.users.update', $user), [
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'username' => $user->username,
'company_ids' => [$companyC->id],
])
->assertOk();
$log = Actionlog::where('item_type', User::class)
->where('item_id', $user->id)
->where('action_type', 'update')
->latest('id')
->first();
$meta = json_decode($log->log_meta, true);
$this->assertEqualsCanonicalizing(
[$companyA->id, $companyB->id],
$meta['companies']['old'],
'Log old company IDs should match previous pivot'
);
$this->assertEqualsCanonicalizing(
[$companyC->id],
$meta['companies']['new'],
'Log new company IDs should match updated pivot'
);
}
public function test_no_change_to_companies_does_not_create_extra_log_entry()
{
$company = Company::factory()->create();
$user = User::factory()->create(['company_id' => $company->id]);
$user->companies()->sync([$company->id]);
$actor = User::factory()->superuser()->create();
$existingLogIds = Actionlog::where('item_type', User::class)
->where('item_id', $user->id)
->pluck('id');
// Send the same company_ids — no field changes either.
$this->actingAsForApi($actor)
->patchJson(route('api.users.update', $user), [
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'username' => $user->username,
'company_ids' => [$company->id],
])
->assertOk();
$newLogs = Actionlog::where('item_type', User::class)
->where('item_id', $user->id)
->whereNotIn('id', $existingLogIds)
->count();
$this->assertEquals(0, $newLogs, 'No changes should produce no new log entries');
}
}