Passed
Push — int-types ( c34c73...b1a342 )
by Sam
10:49 queued 05:06
created

TransactionTest::testReadOnlyTransaction()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 20
nc 5
nop 0
dl 0
loc 34
rs 9.6
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\ORM\Tests;
4
5
use SilverStripe\ORM\DB;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\Dev\SapphireTest;
8
use SilverStripe\ORM\Tests\TransactionTest\TestObject;
9
10
class TransactionTest extends SapphireTest
11
{
12
    protected $usesDatabase = true;
13
14
    protected $usesTransactions = false;
15
16
    protected static $extra_dataobjects = [
17
        TransactionTest\TestObject::class,
18
    ];
19
20
    public static function setUpBeforeClass()
21
    {
22
        parent::setUpBeforeClass();
23
        if (!DB::get_conn()->supportsTransactions()) {
24
            static::markTestSkipped('Current database does not support transactions');
25
        }
26
    }
27
28
    public function testNestedTransaction()
29
    {
30
        $this->assertCount(0, TestObject::get());
31
        try {
32
            DB::get_conn()->withTransaction(function () {
33
                $obj = TransactionTest\TestObject::create();
34
                $obj->Title = 'Test';
35
                $obj->write();
36
37
                $this->assertCount(1, TestObject::get());
38
39
                DB::get_conn()->withTransaction(function () {
40
                    $obj = TransactionTest\TestObject::create();
41
                    $obj->Title = 'Test2';
42
                    $obj->write();
43
                    $this->assertCount(2, TestObject::get());
44
                });
45
46
                throw new \Exception('roll back transaction');
47
            });
48
        } catch (\Exception $e) {
49
            $this->assertEquals('roll back transaction', $e->getMessage());
50
        }
51
        $this->assertCount(0, TestObject::get());
52
    }
53
54
    public function testCreateWithTransaction()
55
    {
56
        // First/Second in a successful transaction
57
        DB::get_conn()->transactionStart();
58
        $obj = new TransactionTest\TestObject();
59
        $obj->Title = 'First page';
60
        $obj->write();
61
62
        $obj = new TransactionTest\TestObject();
63
        $obj->Title = 'Second page';
64
        $obj->write();
65
        DB::get_conn()->transactionEnd();
66
67
        // Third/Fourth in a rolled back transaction
68
        DB::get_conn()->transactionStart();
69
        $obj = new TransactionTest\TestObject();
70
        $obj->Title = 'Third page';
71
        $obj->write();
72
73
        $obj = new TransactionTest\TestObject();
74
        $obj->Title = 'Fourth page';
75
        $obj->write();
76
        DB::get_conn()->transactionRollback();
77
78
79
        $first = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='First page'");
80
        $second = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Second page'");
81
        $third = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Third page'");
82
        $fourth = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Fourth page'");
83
84
        //These pages should be in the system
85
        $this->assertTrue(is_object($first) && $first->exists());
86
        $this->assertTrue(is_object($second) && $second->exists());
87
88
        //These pages should NOT exist, we rolled back
89
        $this->assertFalse(is_object($third) && $third->exists());
90
        $this->assertFalse(is_object($fourth) && $fourth->exists());
91
    }
92
93
    public function testReadOnlyTransaction()
94
    {
95
        if (DB::get_conn()->supportsTransactions() == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
96
            $page = new MyObject();
0 ignored issues
show
Bug introduced by
The type SilverStripe\ORM\Tests\MyObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
97
            $page->MyField = 'Read only success';
98
            $page->write();
99
100
            DB::get_conn()->transactionStart('READ ONLY');
101
102
            try {
103
                $page = new MyObject();
104
                $page->MyField = 'Read only page failed';
105
                $page->write();
106
                DB::get_conn()->transactionEnd();
107
108
            } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The type SilverStripe\ORM\Tests\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
109
                //could not write this record
110
                //We need to do a rollback or a commit otherwise we'll get error messages
111
                DB::get_conn()->transactionRollback();
112
            }
113
114
            DataObject::flush_and_destroy_cache();
115
116
            $success = DataObject::get(MyObject::class, "\"MyField\"='Read only success'");
117
            $fail = DataObject::get(MyObject::class, "\"MyField\"='Read only page failed'");
118
119
            //This page should be in the system
120
            $this->assertTrue(is_object($success) && $success->exists());
121
122
            //This page should NOT exist, we had 'read only' permissions
123
            $this->assertNotInternalType('object', $fail);
124
            $this->assertFalse($fail->exists());
125
        } else {
126
            $this->markTestSkipped('Current database is doesn\'t support transactions');
127
        }
128
    }
129
}
130