1use strict;
2use warnings;
3
4use DBICx::TestDatabase;
5use Test::More;
6
7use lib 't/lib';
8
9my $schema = DBICx::TestDatabase->new('AuditTest::Schema');
10
11$schema->audit_log_schema->deploy;
12
13my $al_schema = $schema->audit_log_schema;
14
15my $test_user;
16
17# CREATE
18$schema->txn_do(
19    sub {
20        $test_user = $schema->resultset('User')->create(
21            {   name  => "JohnSample",
22                email => 'jsample@sample.com',
23                phone => '999-888-7777',
24            }
25        );
26    },
27    {   description => "adding new user: JohnSample",
28        user_id     => "TestAdminUser01",
29    },
30);
31
32my $al_user = $al_schema->resultset('AuditLogUser')
33    ->search( { name => 'TestAdminUser01' } )->first;
34
35isa_ok(
36    $al_user->Changeset->first,
37    "DBIx::Class::Schema::AuditLog::Structure::Changeset",
38    "Changeset found after CREATE"
39);
40subtest 'CREATE Tests' => sub {
41    ok( $al_user->Changeset->first->description eq
42            "adding new user: JohnSample",
43        "AuditLogChangeset has correct description"
44    );
45    ok( $al_user->Changeset->first->Action->first->action_type eq "insert",
46        "AuditLogAction has correct type" );
47    ok( $al_user->Changeset->first->Action->first->Change,
48        "AuditLogChange(s) found for CREATE" );
49    ok( !$al_schema->resultset('AuditLogField')->search( { name => "email" } )
50            ->count,
51        "Field 'email' correctly ignored as per schema option"
52    );
53    done_testing();
54};
55
56# UPDATE
57$schema->txn_do(
58    sub {
59        $test_user
60            = $schema->resultset('User')->find( { name => "JohnSample" } )
61            ->update( { name => 'JaneSample', } );
62    },
63    {   description => "updating user: JohnSample",
64        user_id     => "TestAdminUser02",
65    },
66);
67
68$al_user = $al_schema->resultset('AuditLogUser')
69    ->search( { name => 'TestAdminUser02' } )->first;
70
71isa_ok(
72    $al_user->Changeset->first,
73    "DBIx::Class::Schema::AuditLog::Structure::Changeset",
74    "Changeset found after UPDATE"
75);
76subtest 'UPDATE Tests' => sub {
77    ok( $al_user->Changeset->first->description eq
78            "updating user: JohnSample",
79        "AuditLogChangeset has correct description"
80    );
81    ok( $al_user->Changeset->first->Action->first->action_type eq "update",
82        "AuditLogAction has correct type" );
83    ok( $al_user->Changeset->first->Action->first->Change->first->old_value eq
84            'JohnSample',
85        "AuditLogChange OLD value correct"
86    );
87    ok( $al_user->Changeset->first->Action->first->Change->first->new_value eq
88            'JaneSample',
89        "AuditLogChange NEW value correct"
90    );
91    done_testing();
92};
93
94# DELETE
95$schema->txn_do(
96    sub {
97        $test_user
98            = $schema->resultset('User')->find( { name => "JaneSample" } )
99            ->delete;
100    },
101    {   description => "deleting user: JaneSample",
102        user_id     => "TestAdminUser03",
103    },
104);
105
106$al_user = $al_schema->resultset('AuditLogUser')
107    ->search( { name => 'TestAdminUser03' } )->first;
108
109isa_ok(
110    $al_user->Changeset->first,
111    "DBIx::Class::Schema::AuditLog::Structure::Changeset",
112    "Changeset found after DELETE"
113);
114subtest 'DELETE Tests' => sub {
115    ok( $al_user->Changeset->first->description eq
116            "deleting user: JaneSample",
117        "AuditLogChangeset has correct description"
118    );
119    ok( $al_user->Changeset->first->Action->first->action_type eq "delete",
120        "AuditLogAction has correct type" );
121    my $field = $al_schema->resultset('AuditLogField')
122        ->search( { name => 'name' } )->first;
123    ok( $al_user->Changeset->first->Action->first->Change->search(
124            { field_id => $field->id }
125            )->first->old_value eq 'JaneSample',
126        "AuditLogChange OLD value correct"
127    );
128    ok( !defined $al_user->Changeset->first->Action->first->Change->first
129            ->new_value,
130        "AuditLogChange NEW value correctly set to null"
131    );
132    done_testing();
133};
134
135# Disable audit logging when local variable set
136{
137    no warnings 'once';
138    local $DBIx::Class::AuditLog::enabled = 0;
139
140    $schema->txn_do(
141        sub {
142            $test_user = $schema->resultset('User')->create(
143                {   name  => "Larry Wall",
144                    email => 'lwall@perl.org',
145                    phone => '123-457-7890',
146                }
147            );
148        },
149        {   description => "adding new user: Lary Wall",
150            user_id     => "TestAdminUser04",
151        },
152    );
153
154    $al_user = $al_schema->resultset('AuditLogUser')
155        ->search( { name => 'TestAdminUser04' } )->first;
156
157    ok(!$al_user, 'No audit log created when $DBIx::Class::AuditLog::enabled = 0');
158}
159
160# Audit logging again enabled outside of scope
161$schema->txn_do(
162    sub {
163        $test_user->name('Damian Conway');
164        $test_user->update;
165        {
166            no warnings 'once';
167            local $DBIx::Class::AuditLog::enabled = 0;
168
169            $test_user->email('dconway@perl.org');
170            $test_user->update;
171        }
172    },
173    {   description => "updating user: Lary Wall -> name = Damian Conway",
174        user_id     => "TestAdminUser05",
175    },
176);
177
178$al_user = $al_schema->resultset('AuditLogUser')
179    ->search( { name => 'TestAdminUser05' } )->first;
180
181ok( $al_user->Changeset->first->Action->first->Change->first->new_value eq
182        'Damian Conway',
183    "Audit Logging again enabled outside of scoped local enabled = 0"
184);
185
186ok( $al_user->Changeset->first->Action->count == 1,
187    'Locally scoped enabled = 0 inside transaction is not logged' );
188
189
190done_testing();
191