GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

testIsPublishScheduled()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 17

Duplication

Lines 17
Ratio 100 %

Importance

Changes 0
Metric Value
dl 17
loc 17
rs 9.7
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Symbiote\AdvancedWorkflow\Tests;
4
5
use SilverStripe\CMS\Model\SiteTree;
6
use SilverStripe\Core\Config\Config;
7
use SilverStripe\Dev\SapphireTest;
8
use SilverStripe\ORM\DataObject;
9
use SilverStripe\ORM\FieldType\DBDatetime;
10
use SilverStripe\Translatable\Model\Translatable;
11
use SilverStripe\Security\Member;
12
use SilverStripe\Subsites\Extensions\SiteTreeSubsites;
13
use SilverStripe\Versioned\Versioned;
14
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction;
15
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition;
16
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition;
17
use Symbiote\AdvancedWorkflow\Extensions\WorkflowEmbargoExpiryExtension;
18
use Symbiote\AdvancedWorkflow\Services\WorkflowService;
19
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
20
use Symbiote\QueuedJobs\Services\QueuedJobService;
21
22
/**
23
 * @author [email protected]
24
 * @license BSD License http://silverstripe.org/bsd-license/
25
 */
26
class WorkflowEmbargoExpiryTest extends SapphireTest
27
{
28
    protected static $fixture_file = 'WorkflowEmbargoExpiry.yml';
29
30
    protected function setUp()
31
    {
32
        // Prevent failure if queuedjobs module isn't installed.
33
        if (!class_exists(AbstractQueuedJob::class)) {
34
            static::$fixture_file = '';
35
            parent::setUp();
36
            $this->markTestSkipped("This test requires queuedjobs");
37
        }
38
        parent::setUp();
39
40
        DBDatetime::set_mock_now('2014-01-05 12:00:00');
41
42
        // This doesn't play nicely with PHPUnit
43
        Config::modify()->set(QueuedJobService::class, 'use_shutdown_function', false);
44
    }
45
46
    protected function tearDown()
47
    {
48
        DBDatetime::clear_mock_now();
49
        parent::tearDown();
50
    }
51
52
    /**
53
     * @var array
54
     */
55
    protected static $required_extensions = array(
56
        SiteTree::class => array(
57
            WorkflowEmbargoExpiryExtension::class,
58
            Versioned::class,
59
        ),
60
    );
61
62
    /**
63
     * @var array
64
     */
65
    protected static $illegal_extensions = array(
66
        SiteTree::class => array(
67
            Translatable::class,
68
            SiteTreeSubsites::class,
69
        ),
70
    );
71
72
    /**
73
     * Start a workflow for a page,
74
     * this will set it into a state where a workflow is currently being processes
75
     *
76
     * @param DataObject $obj
77
     * @return DataObject
78
     */
79
    private function startWorkflow($obj)
80
    {
81
        $workflow = $this->objFromFixture(WorkflowDefinition::class, 'requestPublication');
82
        $obj->WorkflowDefinitionID = $workflow->ID;
83
        $obj->write();
84
85
        $svc = singleton(WorkflowService::class);
86
        $svc->startWorkflow($obj, $obj->WorkflowDefinitionID);
87
        return $obj;
88
    }
89
90
    /**
91
     * Start and finish a workflow which will publish the page immediately basically.
92
     *
93
     * @param DataObject $obj
94
     * @return DataObject
95
     */
96
    private function finishWorkflow($obj)
97
    {
98
        $workflow = $this->objFromFixture(WorkflowDefinition::class, 'approvePublication');
99
        $obj->WorkflowDefinitionID = $workflow->ID;
100
        $obj->write();
101
102
        $svc = singleton(WorkflowService::class);
103
        $svc->startWorkflow($obj, $obj->WorkflowDefinitionID);
104
105
        $obj = DataObject::get($obj->ClassName)->byID($obj->ID);
106
        return $obj;
107
    }
108
109
    /**
110
     * Retrieves the live version for an object
111
     *
112
     * @param DataObject $obj
113
     * @return DataObject
114
     */
115
    private function getLive($obj)
116
    {
117
        $oldMode = Versioned::get_reading_mode();
118
        Versioned::set_reading_mode(Versioned::LIVE);
119
        $live = DataObject::get($obj->ClassName)->byID($obj->ID);
120
        Versioned::set_reading_mode($oldMode);
121
122
        return $live;
123
    }
124
125
    /**
126
     * Test when embargo and expiry are both empty.
127
     *
128
     * No jobs should be created, but page is published by the workflow action.
129
     */
130
    public function testEmptyEmbargoExpiry()
131
    {
132
        $page = $this->objFromFixture(SiteTree::class, 'emptyEmbargoExpiry');
133
        $page->Content = 'Content to go live';
134
135
        $live = $this->getLive($page);
136
137
        $this->assertEmpty($live->Content);
138
        $this->assertEquals(0, $page->PublishJobID);
139
        $this->assertEquals(0, $page->UnPublishJobID);
140
141
        $page = $this->finishWorkflow($page);
142
143
        $live = $this->getLive($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 141 can be null; however, Symbiote\AdvancedWorkflo...goExpiryTest::getLive() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
144
145
        $this->assertNotEmpty($live->Content);
146
        $this->assertEquals(0, $page->PublishJobID);
147
        $this->assertEquals(0, $page->UnPublishJobID);
148
    }
149
150
    /**
151
     * Test for embargo in the past
152
     *
153
     * Creates a publish job which is queued for immediately
154
     */
155 View Code Duplication
    public function testPastEmbargo()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
    {
157
        $page = $this->objFromFixture(SiteTree::class, 'pastEmbargo');
158
159
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 159 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
160
161
        $this->assertNotEquals(0, $page->PublishJobID);
162
        $this->assertEquals(0, $page->UnPublishJobID);
163
164
        $publish = strtotime($page->PublishJob()->StartAfter);
165
        $this->assertFalse($publish);
166
    }
167
168
    /**
169
     * Test for expiry in the past
170
     *
171
     * Creates an unpublish job which is queued for immediately
172
     */
173 View Code Duplication
    public function testPastExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
174
    {
175
        $page = $this->objFromFixture(SiteTree::class, 'pastExpiry');
176
177
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 177 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
178
179
        $this->assertEquals(0, $page->PublishJobID);
180
        $this->assertNotEquals(0, $page->UnPublishJobID);
181
182
        $unpublish = strtotime($page->UnPublishJob()->StartAfter);
183
184
        $this->assertFalse($unpublish);
185
    }
186
187
    /**
188
     * Test for embargo and expiry in the past
189
     *
190
     * Creates an unpublish job which is queued for immediately
191
     */
192 View Code Duplication
    public function testPastEmbargoExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
    {
194
        $page = $this->objFromFixture(SiteTree::class, 'pastEmbargoExpiry');
195
196
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 196 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
197
198
        $this->assertEquals(0, $page->PublishJobID);
199
        $this->assertNotEquals(0, $page->UnPublishJobID);
200
201
        $unpublish = strtotime($page->UnPublishJob()->StartAfter);
202
203
        $this->assertFalse($unpublish);
204
    }
205
206
    /**
207
     * Test for embargo in the past and expiry in the future
208
     *
209
     * Creates a publish job which is queued for immediately and an unpublish job which is queued for later
210
     */
211 View Code Duplication
    public function testPastEmbargoFutureExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
212
    {
213
        $page = $this->objFromFixture(SiteTree::class, 'pastEmbargoFutureExpiry');
214
215
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 215 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
216
217
        $this->assertNotEquals(0, $page->PublishJobID);
218
        $this->assertNotEquals(0, $page->UnPublishJobID);
219
220
        $publish = strtotime($page->PublishJob()->StartAfter);
221
        $unpublish = strtotime($page->UnPublishJob()->StartAfter);
222
223
        $this->assertFalse($publish);
224
        $this->assertNotFalse($unpublish);
225
    }
226
227
    /**
228
     * Test for embargo and expiry in the future
229
     *
230
     * Creates a publish and unpublish job which are queued for immediately
231
     */
232 View Code Duplication
    public function testFutureEmbargoExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
233
    {
234
        $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoExpiry');
235
236
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 236 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
237
238
        $this->assertNotEquals(0, $page->PublishJobID);
239
        $this->assertNotEquals(0, $page->UnPublishJobID);
240
241
        $publish = strtotime($page->PublishJob()->StartAfter);
242
        $unpublish = strtotime($page->UnPublishJob()->StartAfter);
243
244
        $this->assertNotFalse($publish);
245
        $this->assertNotFalse($unpublish);
246
    }
247
248
    /**
249
     * Test for embargo after expiry in the past
250
     *
251
     * No jobs should be created, invalid option
252
     */
253 View Code Duplication
    public function testPastEmbargoAfterExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
254
    {
255
        $page = $this->objFromFixture(SiteTree::class, 'pastEmbargoAfterExpiry');
256
257
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 257 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
258
259
        $this->assertEquals(0, $page->PublishJobID);
260
        $this->assertEquals(0, $page->UnPublishJobID);
261
    }
262
263
    /**
264
     * Test for embargo after expiry in the future
265
     *
266
     * No jobs should be created, invalid option
267
     */
268 View Code Duplication
    public function testFutureEmbargoAfterExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
269
    {
270
        $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoAfterExpiry');
271
272
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 272 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
273
274
        $this->assertEquals(0, $page->PublishJobID);
275
        $this->assertEquals(0, $page->UnPublishJobID);
276
    }
277
278
    /**
279
     * Test for embargo and expiry in the past, both have the same value
280
     *
281
     * No jobs should be created, invalid option
282
     */
283 View Code Duplication
    public function testPastSameEmbargoExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
284
    {
285
        $page = $this->objFromFixture(SiteTree::class, 'pastSameEmbargoExpiry');
286
287
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 287 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
288
289
        $this->assertEquals(0, $page->PublishJobID);
290
        $this->assertEquals(0, $page->UnPublishJobID);
291
    }
292
293
    /**
294
     * Test for embargo and expiry in the future, both have the same value
295
     *
296
     * No jobs should be created, invalid option
297
     */
298 View Code Duplication
    public function testFutureSameEmbargoExpiry()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
299
    {
300
        $page = $this->objFromFixture(SiteTree::class, 'futureSameEmbargoExpiry');
301
302
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 302 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
303
304
        $this->assertEquals(0, $page->PublishJobID);
305
        $this->assertEquals(0, $page->UnPublishJobID);
306
    }
307
308
    /**
309
     * When an item is queued for publishing or unpublishing and new dates are entered
310
     *
311
     * The existing queued jobs should be cleared
312
     */
313
    public function testDesiredRemovesJobs()
314
    {
315
        $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoExpiry');
316
317
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 317 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
318
319
        $this->assertNotEquals(0, $page->PublishJobID);
320
        $this->assertNotEquals(0, $page->UnPublishJobID);
321
322
        $page->DesiredPublishDate = '2020-02-01 00:00:00';
323
        $page->DesiredUnPublishDate = '2020-02-01 02:00:00';
324
325
        $page->write();
326
327
        $this->assertEquals(0, $page->PublishJobID);
328
        $this->assertEquals(0, $page->UnPublishJobID);
329
    }
330
331
    /**
332
     * Tests that checking for publishing scheduled state is working
333
     */
334 View Code Duplication
    public function testIsPublishScheduled()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
335
    {
336
        $page = SiteTree::create();
337
        $page->Title = 'My page';
338
        $page->PublishOnDate = '2010-01-01 00:00:00';
339
        $page->AllowEmbargoedEditing = false;
340
        $page->write();
341
342
        $this->assertFalse($page->getIsPublishScheduled());
343
344
        $page->PublishOnDate = '2016-02-01 00:00:00';
345
        DBDatetime::set_mock_now('2016-01-16 00:00:00');
346
        $this->assertTrue($page->getIsPublishScheduled());
347
348
        DBDatetime::set_mock_now('2016-02-16 00:00:00');
349
        $this->assertFalse($page->getIsPublishScheduled());
350
    }
351
352
    /**
353
     * Tests that checking for un-publishing scheduled state is working
354
     */
355 View Code Duplication
    public function testIsUnPublishScheduled()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
356
    {
357
        $page = SiteTree::create();
358
        $page->Title = 'My page';
359
        $page->PublishOnDate = '2010-01-01 00:00:00';
360
        $page->AllowEmbargoedEditing = false;
361
        $page->write();
362
363
        $this->assertFalse($page->getIsUnPublishScheduled());
364
365
        $page->UnPublishOnDate = '2016-02-01 00:00:00';
366
        DBDatetime::set_mock_now('2016-01-16 00:00:00');
367
        $this->assertTrue($page->getIsUnPublishScheduled());
368
369
        DBDatetime::set_mock_now('2016-02-16 00:00:00');
370
        $this->assertFalse($page->getIsUnPublishScheduled());
371
    }
372
373
    /**
374
     * Tests that status flags (badges) are added properly for a page
375
     */
376
    public function testStatusFlags()
377
    {
378
        $page = SiteTree::create();
379
        $page->Title = 'stuff';
380
        DBDatetime::set_mock_now('2016-01-16 00:00:00');
381
382
        $flags = $page->getStatusFlags(false);
383
        $this->assertNotContains('embargo_expiry', array_keys($flags));
384
        $this->assertNotContains('embargo', array_keys($flags));
385
        $this->assertNotContains('expiry', array_keys($flags));
386
387
        $page->PublishOnDate = '2016-02-01 00:00:00';
388
        $page->UnPublishOnDate = null;
389
        $flags = $page->getStatusFlags(false);
390
        $this->assertNotContains('embargo_expiry', array_keys($flags));
391
        $this->assertContains('embargo', array_keys($flags));
392
        $this->assertNotContains('expiry', array_keys($flags));
393
394
        $page->PublishOnDate = null;
395
        $page->UnPublishOnDate = '2016-02-01 00:00:00';
396
        $flags = $page->getStatusFlags(false);
397
        $this->assertNotContains('embargo_expiry', array_keys($flags));
398
        $this->assertNotContains('embargo', array_keys($flags));
399
        $this->assertContains('expiry', array_keys($flags));
400
401
        $page->PublishOnDate = '2016-02-01 00:00:00';
402
        $page->UnPublishOnDate = '2016-02-08 00:00:00';
403
        $flags = $page->getStatusFlags(false);
404
        $this->assertContains('embargo_expiry', array_keys($flags));
405
        $this->assertNotContains('embargo', array_keys($flags));
406
        $this->assertNotContains('expiry', array_keys($flags));
407
    }
408
409
    /**
410
     * Test workflow definition "Can disable edits during embargo"
411
     * Make sure page cannot be edited when an embargo is in place
412
     */
413
    public function testCanEditConfig()
414
    {
415
        $this->logOut();
416
417
        $page = SiteTree::create();
418
        $page->Title = 'My page';
419
        $page->PublishOnDate = '2010-01-01 00:00:00';
420
        $page->write();
421
422
        $memberID = $this->logInWithPermission('SITETREE_EDIT_ALL');
0 ignored issues
show
Unused Code introduced by
$memberID is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
423
        $this->assertTrue($page->canEdit(), 'Can edit page without embargo and no permission');
424
425
        $page->PublishOnDate = '2020-01-01 00:00:00';
426
        $page->AllowEmbargoedEditing = false;
427
        $page->write();
428
        $this->assertFalse($page->canEdit(), 'Cannot edit page with embargo and no permission');
429
430
        $this->logOut();
431
        $memberID = $this->logInWithPermission('ADMIN');
0 ignored issues
show
Unused Code introduced by
$memberID is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
432
        $this->assertTrue($page->canEdit(), 'Can edit page with embargo as Admin');
433
434
        $this->logOut();
435
        $memberID = $this->logInWithPermission(array('SITETREE_EDIT_ALL', 'EDIT_EMBARGOED_WORKFLOW'));
0 ignored issues
show
Unused Code introduced by
$memberID is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
436
        $this->assertTrue($page->canEdit(), 'Can edit page with embargo and permission');
437
438
        $page->PublishOnDate = '2010-01-01 00:00:00';
439
        $page->write();
440
        $this->assertTrue($page->canEdit(), 'Can edit page without embargo and permission');
441
    }
442
443 View Code Duplication
    protected function createDefinition()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
444
    {
445
        $definition = new WorkflowDefinition();
446
        $definition->Title = 'Dummy Workflow Definition';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
447
        $definition->write();
448
449
        $stepOne = new WorkflowAction();
450
        $stepOne->Title = 'Step One';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<Symbiote\Advanced...Objects\WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
451
        $stepOne->WorkflowDefID = $definition->ID;
0 ignored issues
show
Documentation introduced by
The property WorkflowDefID does not exist on object<Symbiote\Advanced...Objects\WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
452
        $stepOne->write();
453
454
        $stepTwo = new WorkflowAction();
455
        $stepTwo->Title = 'Step Two';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<Symbiote\Advanced...Objects\WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
456
        $stepTwo->WorkflowDefID = $definition->ID;
0 ignored issues
show
Documentation introduced by
The property WorkflowDefID does not exist on object<Symbiote\Advanced...Objects\WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
457
        $stepTwo->write();
458
459
        $transitionOne = new WorkflowTransition();
460
        $transitionOne->Title = 'Step One T1';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<Symbiote\Advanced...cts\WorkflowTransition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
461
        $transitionOne->ActionID = $stepOne->ID;
0 ignored issues
show
Documentation introduced by
The property ActionID does not exist on object<Symbiote\Advanced...cts\WorkflowTransition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
462
        $transitionOne->NextActionID = $stepTwo->ID;
0 ignored issues
show
Documentation introduced by
The property NextActionID does not exist on object<Symbiote\Advanced...cts\WorkflowTransition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
463
        $transitionOne->write();
464
465
        return $definition;
466
    }
467
468
    /**
469
     * Make sure that publish and unpublish dates are not carried over to the duplicates.
470
     */
471
    public function testDuplicateRemoveEmbargoExpiry()
472
    {
473
        $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoExpiry');
474
475
        // fake publish jobs
476
        $page = $this->finishWorkflow($page);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $this->finishWorkflow($page) on line 476 can be null; however, Symbiote\AdvancedWorkflo...yTest::finishWorkflow() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
477
478
        $dupe = $page->duplicate();
479
        $this->assertNotNull($page->PublishOnDate, 'Not blank publish on date');
480
        $this->assertNotNull($page->UnPublishOnDate, 'Not blank unpublish on date');
481
        $this->assertNotEquals($page->PublishJobID, 0, 'Publish job ID still set');
482
        $this->assertNotEquals($page->UnPublishJobID, 0, 'Unpublish job ID still set');
483
        $this->assertNull($dupe->PublishOnDate, 'Blank publish on date');
484
        $this->assertNull($dupe->UnPublishOnDate, 'Blank unpublish on date');
485
        $this->assertEquals($dupe->PublishJobID, 0, 'Publish job ID unset');
486
        $this->assertEquals($dupe->UnPublishJobID, 0, 'Unpublish job ID unset');
487
    }
488
}
489