xref: /dokuwiki/_test/tests/ChangeLog/PageChangeLogTest.php (revision 2bde879a12352d26be5e3f11e86855f463734d2d)
1<?php
2
3namespace dokuwiki\test\ChangeLog;
4
5use dokuwiki\ChangeLog\PageChangeLog;
6
7/**
8 * Tests for dokuwiki\ChangeLog\PageChangeLog.
9 */
10class PageChangeLogTest extends \DokuWikiTest
11{
12    /**
13     * A page deleted through DokuWiki is recorded as its own revision, newer than the
14     * last revision that still had content. getRelativeRevision() must walk back from
15     * that deletion entry to the last content revision (issue #4635).
16     */
17    public function testRevisionBeforeNormalDeletion()
18    {
19        $page = 'changelog_deleted';
20        saveWikiText($page, 'first content', 'create', false);
21        $this->waitForTick(true);
22        saveWikiText($page, 'second content longer', 'edit', false);
23        $this->waitForTick(true);
24
25        $editRev = (new PageChangeLog($page))->currentRevision();
26
27        saveWikiText($page, '', 'delete', false);
28        clearstatcache();
29
30        $changelog = new PageChangeLog($page);
31        $delRev = $changelog->currentRevision();
32
33        $this->assertNotEquals($editRev, $delRev, 'deletion should get its own revision');
34        $this->assertEquals(
35            DOKU_CHANGE_TYPE_DELETE,
36            $changelog->getRevisionInfo($delRev)['type'],
37            'current revision should be the deletion'
38        );
39        $this->assertEquals(
40            $editRev,
41            $changelog->getRelativeRevision($delRev, -1),
42            'the revision before the deletion should be the last edit'
43        );
44    }
45
46    /**
47     * An external deletion is detected and persisted on first read as its own revision
48     * with an unknown exact date, newer than the last content revision.
49     * getRelativeRevision() must walk back from it to that last content revision
50     * (issue #4635).
51     */
52    public function testRevisionBeforeExternalDeletion()
53    {
54        $page = 'changelog_extdeleted';
55        saveWikiText($page, 'first content', 'create', false);
56        $this->waitForTick(true);
57        saveWikiText($page, 'second content longer', 'edit', false);
58        $this->waitForTick(true);
59
60        $editRev = (new PageChangeLog($page))->currentRevision();
61
62        // delete the page file externally, bypassing DokuWiki
63        unlink(wikiFN($page));
64        clearstatcache();
65
66        // first read detects and persists the external deletion
67        $changelog = new PageChangeLog($page);
68        $delRev = $changelog->currentRevision();
69        $delInfo = $changelog->getRevisionInfo($delRev);
70
71        $this->assertNotEquals($editRev, $delRev, 'external deletion should get its own revision');
72        $this->assertEquals(DOKU_CHANGE_TYPE_DELETE, $delInfo['type'], 'current revision should be the deletion');
73        $this->assertFalse($delInfo['timestamp'], 'external deletion has an unknown exact date');
74        $this->assertEquals(
75            $editRev,
76            $changelog->getRelativeRevision($delRev, -1),
77            'the revision before the external deletion should be the last edit'
78        );
79    }
80}
81