1<?php
2
3if (!defined('DOKU_INC')) die();
4
5/**
6 * Tests the tagRefine function of the tag plugin
7 */
8class plugin_tag_topic_and_tagrefine_test extends DokuWikiTest {
9    private $all_pages = [
10        'tagged_page' => ['id' => 'tagged_page'],
11        'negative_page' => ['id' => 'negative_page'],
12        'third_page' => ['id' => 'third_page']
13    ];
14    public function setUp() : void {
15        $this->pluginsEnabled[] = 'tag';
16        parent::setUp();
17
18        saveWikiText(
19            'tagged_page',
20            '{{tag>mytag test2tag}}', 'Test'
21        );
22        saveWikiText(
23            'negative_page',
24            '{{tag>negative_tag mytag}}',
25            'Test setup'
26        );
27        saveWikiText(
28            'third_page',
29            '{{tag>third_tag}}',
30            'Test setup'
31        );
32        idx_addPage('tagged_page');
33        idx_addPage('negative_page');
34        idx_addPage('third_page');
35    }
36
37    public function testEmptyTag() {
38        $this->assertTopicRefine(['tagged_page', 'negative_page', 'third_page'], '');
39    }
40
41    public function testOnlyNegative() {
42        $this->assertTopicRefine(['tagged_page', 'third_page'], '-negative_tag');
43    }
44
45    public function testMixed() {
46        $this->assertTopicRefine(['tagged_page'], 'mytag -negative_tag');
47
48    }
49
50    public function testAnd() {
51        $this->assertTopicRefine(['tagged_page'], '+mytag +test2tag');
52    }
53
54    public function testAndOr() {
55        $this->assertTopicRefine(['tagged_page',  'third_page'], '+test2tag third_tag');
56    }
57
58    public function testOrAnd() {
59        $this->assertTopicRefine(['tagged_page'], 'mytag +test2tag');
60    }
61
62    public function testRefineDoesntAdd() {
63        /** @var helper_plugin_tag $helper */
64        $helper = plugin_load('helper', 'tag');
65        $pages = $helper->tagRefine([], 'mytag');
66        $this->hasPages([], $pages, 'Refine with empty input array and "mytag" query: ');
67    }
68
69    /**
70     * Test if the getTopic and the tagRefine function with all pages as input both return the expected pages
71     *
72     * @param array  $expected expected page ids
73     * @param string $query    the query for the tagRefine/getTopic-functions
74     */
75    private function assertTopicRefine($expected, $query) {
76        /** @var helper_plugin_tag $helper */
77        $helper = plugin_load('helper', 'tag');
78        $pages = $helper->tagRefine($this->all_pages, $query);
79        $this->hasPages($expected, $pages, 'Refine: '.$query.': ');
80        $pages = $helper->getTopic('', '', $query);
81        $this->hasPages($expected, $pages, 'Topic: '.$query.': ');
82    }
83
84    /**
85     * Makes sure that all pages were found and not more
86     *
87     * @param array $expected List of page ids
88     * @param array $actual   Result list from getTopic/tagRefine
89     * @param string $msg_prefix A prefix that is prepended to all messages
90     */
91    private function hasPages($expected, $actual, $msg_prefix = '') {
92        foreach ($expected as $id) {
93            $found = false;
94            foreach ($actual as $page) {
95                if ($page['id'] === $id) {
96                    $found = true;
97                    break;
98                }
99            }
100            $this->assertTrue($found, $msg_prefix.'Page '.$id.' expected but not found in the result');
101        }
102
103        foreach ($actual as $page) {
104            $this->assertTrue(in_array($page['id'], $expected), $msg_prefix.'Page '.$page['id'].' is in the result but wasn\'t expected');
105        }
106    }
107}
108