Skip to content

Commit 73e9cf6

Browse files
author
farhadzand
committed
add ferature tests
1 parent a07525b commit 73e9cf6

File tree

7 files changed

+659
-26
lines changed

7 files changed

+659
-26
lines changed

phpunit.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@
2424
<directory suffix=".php">src</directory>
2525
</include>
2626
</source>
27+
<php>
28+
<env name="DB_CONNECTION" value="sqlite"/>
29+
<env name="DB_DATABASE" value=":memory:"/>
30+
</php>
2731
</phpunit>

src/Drivers/MySQLDriver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private function getTableName(string $entityType): string
174174
// Handle pluralization
175175
$tableName = Str::plural($className);
176176

177-
return $this->tablePrefix.$tableName.$this->tableSuffix;
177+
return $this->tablePrefix . $tableName . $this->tableSuffix;
178178
}
179179

180180
private function applyFilters(Builder $query, array $options): void
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace iamfarhad\LaravelAuditLog\Tests\Feature;
6+
7+
use Illuminate\Support\Facades\Config;
8+
use Illuminate\Support\Facades\DB;
9+
use Illuminate\Support\Facades\Schema;
10+
use Illuminate\Support\Str;
11+
use iamfarhad\LaravelAuditLog\Tests\Mocks\Post;
12+
use iamfarhad\LaravelAuditLog\Tests\Mocks\User;
13+
use iamfarhad\LaravelAuditLog\Tests\TestCase;
14+
15+
final class AuditLogAdvancedTest extends TestCase
16+
{
17+
/**
18+
* Get the latest audit log for the given model
19+
*
20+
* @param string $modelClass Class name of the model
21+
* @return object|null The audit log record
22+
*/
23+
protected function getLatestAuditLog(string $modelClass): ?object
24+
{
25+
// Convert class name to table name (e.g., User -> audit_users_logs)
26+
$className = class_basename($modelClass);
27+
$tableName = 'audit_' . Str::snake(Str::plural($className)) . '_logs';
28+
29+
return DB::table($tableName)
30+
->latest('id')
31+
->first();
32+
}
33+
34+
/**
35+
* Clear all audit logs for testing
36+
*/
37+
protected function clearAuditLogs(): void
38+
{
39+
DB::table('audit_users_logs')->delete();
40+
DB::table('audit_posts_logs')->delete();
41+
}
42+
43+
public function test_batch_auditing_when_enabled(): void
44+
{
45+
// Enable batch auditing
46+
Config::set('audit-logger.batch.enabled', true);
47+
48+
// Create a user
49+
$user = User::create([
50+
'name' => 'Batch User',
51+
'email' => '[email protected]',
52+
'password' => bcrypt('password'),
53+
'is_active' => true,
54+
]);
55+
56+
// Clear audit logs to start with a clean slate
57+
$this->clearAuditLogs();
58+
59+
// Create multiple posts in a batch
60+
$post1 = Post::create([
61+
'user_id' => $user->id,
62+
'title' => 'Batch Post 1',
63+
'content' => 'Content 1',
64+
'status' => 'draft',
65+
]);
66+
67+
$post2 = Post::create([
68+
'user_id' => $user->id,
69+
'title' => 'Batch Post 2',
70+
'content' => 'Content 2',
71+
'status' => 'draft',
72+
]);
73+
74+
// Audit logs might already be stored depending on implementation
75+
// Let's count logs before termination
76+
$initialCount = DB::table('audit_posts_logs')->count();
77+
78+
// Terminate the application which triggers storing the batched audit logs
79+
// In a real app, this happens when the request ends
80+
$this->app->terminate();
81+
82+
// Now check that audit logs were created
83+
$finalCount = DB::table('audit_posts_logs')->count();
84+
$this->assertGreaterThanOrEqual($initialCount, $finalCount, 'Audit logs count should increase after termination');
85+
86+
// Reset batch auditing to default
87+
Config::set('audit-logger.batch.enabled', false);
88+
}
89+
90+
public function test_conditional_auditing_based_on_field_changes(): void
91+
{
92+
// Create a user
93+
$user = User::create([
94+
'name' => 'Conditional User',
95+
'email' => '[email protected]',
96+
'password' => bcrypt('password'),
97+
'is_active' => true,
98+
]);
99+
100+
// Clear audit logs to start with a clean slate
101+
$this->clearAuditLogs();
102+
103+
// Update a non-important field (assuming updated_at won't trigger audit due to global exclude)
104+
$user->touch();
105+
106+
// No audit log should be created since only updated_at changed
107+
$auditLogCount = DB::table('audit_users_logs')->count();
108+
$this->assertEquals(0, $auditLogCount, 'Audit log should not be created for excluded fields');
109+
110+
// Update an important field
111+
$user->is_active = false;
112+
$user->save();
113+
114+
// Audit log should be created for important field change
115+
$auditLog = $this->getLatestAuditLog(User::class);
116+
$this->assertNotNull($auditLog, 'No audit log found for important field change');
117+
118+
// Only the changed field should be in the audit
119+
$newValues = json_decode($auditLog->new_values, true);
120+
$this->assertArrayHasKey('is_active', $newValues);
121+
$this->assertFalse($newValues['is_active']);
122+
}
123+
124+
public function test_excluded_fields_from_different_sources(): void
125+
{
126+
// Set global excluded fields via config
127+
Config::set('audit-logger.fields.exclude', ['password', 'remember_token', 'updated_at', 'test_field']);
128+
129+
// Create a user with all fields including test_field
130+
Schema::table('users', function ($table) {
131+
// Only add the column if it doesn't already exist
132+
if (!Schema::hasColumn('users', 'test_field')) {
133+
$table->string('test_field')->nullable();
134+
}
135+
});
136+
137+
// Clear audit logs
138+
$this->clearAuditLogs();
139+
140+
// Create the user
141+
$user = User::create([
142+
'name' => 'Exclude Test',
143+
'email' => '[email protected]',
144+
'password' => bcrypt('password'),
145+
'is_active' => true,
146+
'test_field' => 'Should be excluded',
147+
]);
148+
149+
// Get the latest audit log
150+
$auditLog = $this->getLatestAuditLog(User::class);
151+
$this->assertNotNull($auditLog, 'No audit log found for user with excluded fields');
152+
153+
$newValues = json_decode($auditLog->new_values, true);
154+
155+
// Check that fields from both sources are excluded
156+
$this->assertArrayNotHasKey('password', $newValues, 'Password should be excluded');
157+
$this->assertArrayNotHasKey('remember_token', $newValues, 'Remember token should be excluded');
158+
159+
// Only check for updated_at if it's in the array at all (it might be completely filtered)
160+
if (array_key_exists('updated_at', $newValues)) {
161+
$this->fail('updated_at should be excluded from audit log');
162+
}
163+
164+
$this->assertArrayNotHasKey('test_field', $newValues, 'Test field should be excluded');
165+
166+
// Should still have the important fields
167+
$this->assertArrayHasKey('name', $newValues);
168+
$this->assertArrayHasKey('email', $newValues);
169+
$this->assertArrayHasKey('is_active', $newValues);
170+
}
171+
}

0 commit comments

Comments
 (0)