Completed
Push — master ( d001a9...e5c7d1 )
by Robbie
27s queued 18s
created

tests/DMSDocumentTest.php (13 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
class DMSDocumentTest extends SapphireTest
3
{
4
    protected static $fixture_file = 'dmstest.yml';
5
6
    public function testDefaultDownloadBehabiourCMSFields()
7
    {
8
        $document = singleton('DMSDocument');
9
        Config::inst()->update('DMSDocument', 'default_download_behaviour', 'open');
10
        $cmsFields = $document->getCMSFields();
11
        $this->assertEquals('open', $cmsFields->dataFieldByName('DownloadBehavior')->Value());
12
13
14
        Config::inst()->update('DMSDocument', 'default_download_behaviour', 'download');
15
        $cmsFields = $document->getCMSFields();
16
        $this->assertEquals('download', $cmsFields->dataFieldByName('DownloadBehavior')->Value());
17
    }
18
19
    /**
20
     * Ensure that related documents can be retrieved for a given DMS document
21
     */
22
    public function testRelatedDocuments()
23
    {
24
        $document = $this->objFromFixture('DMSDocument', 'document_with_relations');
25
        $this->assertGreaterThan(0, $document->RelatedDocuments()->count());
26
        $this->assertEquals(
27
            array('test-file-file-doesnt-exist-1', 'test-file-file-doesnt-exist-2'),
28
            $document->getRelatedDocuments()->column('Filename')
29
        );
30
    }
31
32
    /**
33
     * Test the extensibility of getRelatedDocuments
34
     */
35 View Code Duplication
    public function testGetRelatedDocumentsIsExtensible()
36
    {
37
        DMSDocument::add_extension('StubRelatedDocumentExtension');
38
39
        $emptyDocument = new DMSDocument;
40
        $relatedDocuments = $emptyDocument->getRelatedDocuments();
41
42
        $this->assertCount(1, $relatedDocuments);
43
        $this->assertSame('Extended', $relatedDocuments->first()->Filename);
44
    }
45
46
    /**
47
     * Ensure that the DMS Document CMS actions contains a grid field for managing related documents
48
     */
49
    public function testDocumentHasCmsFieldForManagingRelatedDocuments()
50
    {
51
        $document = $this->objFromFixture('DMSDocument', 'document_with_relations');
52
        $gridField = $this->getRelatedDocumentsGridField($document);
0 ignored issues
show
$document is of type object<DataObject>|null, but the function expects a object<DMSDocument>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
53
        $this->assertInstanceOf('GridField', $gridField);
0 ignored issues
show
The method assertInstanceOf() does not seem to exist on object<DMSDocumentTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
54
55
        $gridFieldConfig = $gridField->getConfig();
56
57
        $this->assertNotNull(
58
            'GridFieldAddExistingAutocompleter',
59
            $addExisting = $gridFieldConfig->getComponentByType('GridFieldAddExistingAutocompleter'),
60
            'Related documents GridField has an "add existing" autocompleter'
61
        );
62
63
        $this->assertNull(
64
            $gridFieldConfig->getComponentByType('GridFieldAddNewButton'),
65
            'Related documents GridField does not have an "add new" button'
66
        );
67
    }
68
69
    /**
70
     * Ensures that the DMS Document CMS Related and Versions fields are removed if user can't edit
71
     */
72
    public function testDocumentHasNoCMSFieldsForManagingRelatedDocumentsIfCantEdit()
73
    {
74
        $this->logInWithPermission('another-user');
75
        $document = $this->objFromFixture('DMSDocument', 'doc-only-these-users');
76
        $gridField = $this->getRelatedDocumentsGridField($document);
0 ignored issues
show
$document is of type object<DataObject>|null, but the function expects a object<DMSDocument>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
77
        $this->assertNull($gridField);
0 ignored issues
show
The method assertNull() does not seem to exist on object<DMSDocumentTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
78
    }
79
80
    /**
81
     * Ensure that the related documents list does not include the current document itself
82
     */
83
    public function testGetRelatedDocumentsForAutocompleter()
84
    {
85
        $document = $this->objFromFixture('DMSDocument', 'd1');
86
        $gridField = $this->getRelatedDocumentsGridField($document);
0 ignored issues
show
$document is of type object<DataObject>|null, but the function expects a object<DMSDocument>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
87
        $this->assertInstanceOf('GridField', $gridField);
88
89
        $config = $gridField->getConfig();
90
91
        $autocompleter = $config->getComponentByType('GridFieldAddExistingAutocompleter');
92
        $autocompleter->setResultsFormat('$Filename');
93
94
        $jsonResult = $autocompleter->doSearch(
95
            $gridField,
96
            new SS_HTTPRequest('GET', '/', array('gridfield_relationsearch' => 'test'))
97
        );
98
99
        $this->assertNotContains('test-file-file-doesnt-exist-1', $jsonResult);
100
        $this->assertContains('test-file-file-doesnt-exist-2', $jsonResult);
101
        $this->assertEquals(array('Title:PartialMatch', 'Filename:PartialMatch'), $autocompleter->getSearchFields());
102
    }
103
104
    /**
105
     * @return GridField
106
     */
107
    protected function getRelatedDocumentsGridField(DMSDocument $document)
108
    {
109
        $documentFields = $document->getCMSFields();
110
        /** @var FieldGroup $actions */
111
        $actions = $documentFields->fieldByName('ActionsPanel');
112
113
        $gridField = null;
114
        foreach ($actions->getChildren() as $child) {
115
            /** @var FieldGroup $child */
116
            if ($gridField = $child->fieldByName('RelatedDocuments')) {
117
                break;
118
            }
119
        }
120
        return $gridField;
121
    }
122
123
    /**
124
     * Ensure that HTML is returned containing list items with action panel steps
125
     */
126
    public function testGetActionTaskHtml()
127
    {
128
        $document = $this->objFromFixture('DMSDocument', 'd1');
129
        $document->addActionPanelTask('example', 'Example');
130
131
        $result = $document->getActionTaskHtml();
132
133
        $this->assertContains('<label class="left">Actions</label>', $result);
134
        $this->assertContains('<li class="ss-ui-button dmsdocument-action" data-panel="', $result);
135
        $this->assertContains('permission', $result);
136
        $this->assertContains('Example', $result);
137
138
        $actions = array('example', 'embargo','find-usage');
139
        foreach ($actions as $action) {
140
            // Test remove with string
141
            $document->removeActionPanelTask($action);
142
        }
143
        $result = $document->getActionTaskHtml();
144
145
        $this->assertNotContains('Example', $result);
146
        $this->assertNotContains('embargo', $result);
147
        $this->assertNotContains('find-usage', $result);
148
        // Positive test to see some action still remains
149
        $this->assertContains('find-references', $result);
150
    }
151
152
    /*
153
     * Tests whether the permissions fields are added
154
     */
155
    public function testGetPermissionsActionPanel()
156
    {
157
        $result = $this->objFromFixture('DMSDocument', 'd1')->getPermissionsActionPanel();
158
159
        $this->assertInstanceOf('CompositeField', $result);
160
        $this->assertNotNull($result->getChildren()->fieldByName('CanViewType'));
161
        $this->assertNotNull($result->getChildren()->fieldByName('ViewerGroups'));
162
    }
163
164
    /**
165
     * Test view permissions
166
     */
167
    public function testCanView()
168
    {
169
        /** @var DMSDocument $document */
170
        $document = $this->objFromFixture('DMSDocument', 'doc-logged-in-users');
171
        $this->logoutMember();
172
        // Logged out user test
173
        $this->assertFalse($document->canView());
174
175
        // Logged in user test
176
        $adminID = $this->logInWithPermission();
177
        $admin = Member::get()->byID($adminID);
178
        $this->assertTrue($document->canView($admin));
179
        /** @var Member $member */
180
        $admin->logout();
181
182
        // Check anyone
183
        $document = $this->objFromFixture('DMSDocument', 'doc-anyone');
184
        $this->assertTrue($document->canView());
185
186
        // Check OnlyTheseUsers
187
        $document = $this->objFromFixture('DMSDocument', 'doc-only-these-users');
188
        $reportAdminID = $this->logInWithPermission('cable-guy');
189
        /** @var Member $reportAdmin */
190
        $reportAdmin = Member::get()->byID($reportAdminID);
191
        $this->assertFalse($document->canView($reportAdmin));
192
        // Add reportAdmin to group
193
        $reportAdmin->addToGroupByCode('content-author');
194
        $this->assertTrue($document->canView($reportAdmin));
195
        $reportAdmin->logout();
196
    }
197
198
    /**
199
     * Tests edit permissions
200
     */
201
    public function testCanEdit()
202
    {
203
        $this->logoutMember();
204
205
        /** @var DMSDocument $document1 */
206
        $document1 = $this->objFromFixture('DMSDocument', 'doc-logged-in-users');
207
208
        // Logged out user test
209
        $this->assertFalse($document1->canEdit());
210
211
        //Logged in user test
212
        $contentAuthor = $this->objFromFixture('Member', 'editor');
213
        $this->assertTrue($document1->canEdit($contentAuthor));
214
215
        // Check OnlyTheseUsers
216
        /** @var DMSDocument $document2 */
217
        $document2 = $this->objFromFixture('DMSDocument', 'doc-only-these-users');
218
        /** @var Member $cableGuy */
219
        $cableGuy = $this->objFromFixture('Member', 'non-editor');
220
        $this->assertFalse($document2->canEdit($cableGuy));
221
222
        $cableGuy->addToGroupByCode('content-author');
223
        $this->assertTrue($document2->canEdit($cableGuy));
224
    }
225
226
    /**
227
     * Tests delete permissions
228
     */
229 View Code Duplication
    public function testCanDelete()
0 ignored issues
show
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...
230
    {
231
        $this->logoutMember();
232
        $document1 = $this->objFromFixture('DMSDocument', 'doc-logged-in-users');
233
234
        // Logged out user test
235
        $this->assertFalse($document1->canDelete());
0 ignored issues
show
The method assertFalse() does not seem to exist on object<DMSDocumentTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
236
237
        // Test editors can delete
238
        $contentAuthor = $this->objFromFixture('Member', 'editor');
239
        $this->assertTrue($document1->canDelete($contentAuthor));
0 ignored issues
show
It seems like $contentAuthor defined by $this->objFromFixture('Member', 'editor') on line 238 can also be of type object<DataObject>; however, DataObject::canDelete() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
The method assertTrue() does not seem to exist on object<DMSDocumentTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
240
    }
241
242
    /**
243
     * Tests create permission
244
     */
245 View Code Duplication
    public function testCanCreate()
0 ignored issues
show
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...
246
    {
247
        $this->logoutMember();
248
        $document1 = $this->objFromFixture('DMSDocument', 'doc-logged-in-users');
249
        $this->logInWithPermission('CMS_ACCESS_DMSDocumentAdmin');
250
        // Test CMS access can create
251
        $this->assertTrue($document1->canCreate());
0 ignored issues
show
The method assertTrue() does not seem to exist on object<DMSDocumentTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
252
253
        $this->logoutMember();
254
255
        // Test editors can create
256
        $contentAuthor = $this->objFromFixture('Member', 'editor');
257
        $this->assertTrue($document1->canCreate($contentAuthor));
0 ignored issues
show
It seems like $contentAuthor defined by $this->objFromFixture('Member', 'editor') on line 256 can also be of type object<DataObject>; however, DataObject::canCreate() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
The method assertTrue() does not seem to exist on object<DMSDocumentTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
258
    }
259
260
    /**
261
     * Logs out any active member
262
     */
263
    protected function logoutMember()
264
    {
265
        if ($member = Member::currentUser()) {
266
            $member->logOut();
267
        }
268
    }
269
270
    /**
271
     * Test permission denied reasons for documents
272
     */
273
    public function testGetPermissionDeniedReason()
274
    {
275
        /** @var DMSDocument $document1 */
276
        $doc1 = $this->objFromFixture('DMSDocument', 'doc-logged-in-users');
277
        $this->assertContains('Please log in to view this document', $doc1->getPermissionDeniedReason());
278
279
        /** @var DMSDocument $doc2 */
280
        $doc2 = $this->objFromFixture('DMSDocument', 'doc-only-these-users');
281
        $this->assertContains('You are not authorised to view this document', $doc2->getPermissionDeniedReason());
282
283
        /** @var DMSDocument $doc3 */
284
        $doc3 = $this->objFromFixture('DMSDocument', 'doc-anyone');
285
        $this->assertEquals('', $doc3->getPermissionDeniedReason());
286
    }
287
288
    /**
289
     * Ensure that all pages that a document belongs to (via many document sets) can be retrieved in one list
290
     */
291
    public function testGetRelatedPages()
292
    {
293
        $document = $this->objFromFixture('DMSDocument', 'd1');
294
        $result = $document->getRelatedPages();
295
        $this->assertCount(3, $result, 'Document 1 is related to 3 Pages');
296
        $this->assertSame(array('s1', 's2', 's3'), $result->column('URLSegment'));
297
    }
298
299
    /**
300
     * Test that the title is returned if it is set, otherwise the filename without ID
301
     */
302
    public function testGetTitleOrFilenameWithoutId()
303
    {
304
        $d1 = $this->objFromFixture('DMSDocument', 'd1');
305
        $this->assertSame('test-file-file-doesnt-exist-1', $d1->getTitle());
306
307
        $d2 = $this->objFromFixture('DMSDocument', 'd2');
308
        $this->assertSame('File That Doesn\'t Exist (Title)', $d2->getTitle());
309
    }
310
311
    /**
312
     * Ensure that the folder a document's file is stored in can be retrieved, and that delete() will also delete
313
     * the file and the record
314
     */
315
    public function testGetStorageFolderThenDelete()
316
    {
317
        Config::inst()->update('DMS', 'folder_name', 'assets/_unit-tests');
318
319
        $document = DMS::inst()->storeDocument('dms/tests/DMS-test-lorum-file.pdf');
320
        $filename = $document->getStorageFolder() . '/' . $document->getFilename();
321
322
        $this->assertTrue(file_exists($filename));
323
        $document->delete();
324
        $this->assertFalse($document->exists());
325
        $this->assertFalse(file_exists($filename));
326
327
        DMSFilesystemTestHelper::delete('assets/_unit-tests');
328
    }
329
330
    /**
331
     * Test that the link contains an ID and URL slug
332
     */
333
    public function testGetLink()
334
    {
335
        Config::inst()->update('DMS', 'folder_name', 'assets/_unit-tests');
336
337
        $document = DMS::inst()->storeDocument('dms/tests/DMS-test-lorum-file.pdf');
338
339
        $expected = '/dmsdocument/' . $document->ID . '-dms-test-lorum-file-pdf';
340
        $this->assertSame($expected, $document->Link());
341
        $this->assertSame($expected, $document->getLink());
342
    }
343
344
    /**
345
     * Ensure that the description can be returned in HTML format
346
     */
347
    public function testGetDescriptionWithLineBreak()
348
    {
349
        $document = DMSDocument::create();
350
        $document->Description = "Line 1\nLine 2\nLine 3";
351
        $document->write();
352
353
        $this->assertSame("Line 1<br />\nLine 2<br />\nLine 3", $document->getDescriptionWithLineBreak());
354
    }
355
}
356