1<?php
2/**
3 * Unit tests for HTML_QuickForm2 package
4 *
5 * PHP version 5
6 *
7 * LICENSE
8 *
9 * This source file is subject to BSD 3-Clause License that is bundled
10 * with this package in the file LICENSE and available at the URL
11 * https://raw.githubusercontent.com/pear/HTML_QuickForm2/trunk/docs/LICENSE
12 *
13 * @category  HTML
14 * @package   HTML_QuickForm2
15 * @author    Alexey Borzov <avb@php.net>
16 * @author    Bertrand Mansion <golgote@mamasam.com>
17 * @copyright 2006-2021 Alexey Borzov <avb@php.net>, Bertrand Mansion <golgote@mamasam.com>
18 * @license   https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
19 * @link      https://pear.php.net/package/HTML_QuickForm2
20 */
21
22/** Sets up includes */
23require_once dirname(__DIR__) . '/TestHelper.php';
24
25class HTML_QuickForm2_ContainerFilterImpl extends HTML_QuickForm2_Container
26{
27    public function getType() { return 'concrete'; }
28    public function setValue($value) { return ''; }
29    public function __toString() { return ''; }
30    public function validate() { return parent::validate(); }
31}
32
33/**
34 * A filter that modifies the value on every iteration
35 * To make sure it is not called more times than it should.
36 */
37function repeatFilter($value)
38{
39    return substr($value, 0, 1).$value;
40}
41
42/**
43 * Unit test for HTML_QuickForm2_Rule class
44 */
45class HTML_QuickForm2_FilterTest extends PHPUnit_Framework_TestCase
46{
47    public function setUp()
48    {
49        $_REQUEST['_qf__filters'] = '';
50        $_POST = [
51            'foo' => '  ',
52            'bar' => 'VALUE',
53            'baz' => ['VALUE1', 'VALUE2'],
54            'sel' => 'VALUE2'
55        ];
56    }
57
58    public function testFiltersShouldPreserveNulls()
59    {
60        $mockElement = $this->getMockBuilder('HTML_QuickForm2_Element')
61            ->setMethods(['getType',
62                                      'getRawValue', 'setValue', '__toString'])
63            ->getMock();
64        $mockElement->expects($this->atLeastOnce())
65                    ->method('getRawValue')->will($this->returnValue(null));
66        $mockElement->addFilter('trim');
67        $this->assertNull($mockElement->getValue());
68
69        $mockContainer = $this->getMockBuilder('HTML_QuickForm2_Container')
70            ->setMethods(['getType', 'setValue', '__toString'])
71            ->getMock();
72        $mockContainer->appendChild($mockElement);
73        $mockContainer->addRecursiveFilter('intval');
74        $mockContainer->addFilter('count');
75
76        $this->assertNull($mockContainer->getValue());
77    }
78
79    public function testContainerValidation()
80    {
81        $form = new HTML_QuickForm2('filters', 'post', null, false);
82        $username = $form->addElement('text', 'foo');
83        $username->addRule('required', 'Username is required');
84        $form->addRecursiveFilter('trim');
85        $this->assertFalse($form->validate());
86        $this->assertSame('', $username->getValue());
87    }
88
89    public function testSelect()
90    {
91        $form = new HTML_QuickForm2('filters', 'post', null, false);
92        $select = $form->addSelect('sel')->loadOptions(
93            ['VALUE1' => 'VALUE1', 'VALUE2' => 'VALUE2', 'VALUE3' => 'VALUE3']);
94        $select->addFilter('strtolower');
95        $this->assertEquals('value2', $select->getValue());
96    }
97
98    public function testSelectMultipleRecursive()
99    {
100        $form = new HTML_QuickForm2('filters', 'post', null, false);
101        $select = $form->addSelect('baz', ['multiple' => 'multiple'])->loadOptions(
102            ['VALUE1' => 'VALUE1', 'VALUE2' => 'VALUE2', 'VALUE3' => 'VALUE3']);
103        $select->addRecursiveFilter('strtolower');
104        $this->assertEquals(['value1', 'value2'], $select->getValue());
105    }
106
107    public function testSelectMultipleNonRecursive()
108    {
109        $s = new HTML_QuickForm2_Element_Select('foo', ['multiple' => 'multiple'],
110                                                ['intrinsic_validation' => false]);
111        $s->setValue(['foo', 'bar']);
112        $s->addFilter('count');
113
114        $this->assertEquals(2, $s->getValue());
115    }
116
117    public function testInputCheckable()
118    {
119        $form = new HTML_QuickForm2('filters', 'post', null, false);
120        $check = $form->appendChild(
121            new HTML_QuickForm2_Element_InputCheckable('bar'));
122        $check->setAttribute('value', 'VALUE');
123        $check->addFilter('strtolower');
124        $this->assertEquals('value', $check->getValue());
125        // in order to be set, the value must be equal to the one in
126        // the value attribute
127        $check->setValue('value');
128        $this->assertNull($check->getValue());
129        $check->setValue('VALUE');
130        $this->assertEquals('value', $check->getValue());
131    }
132
133    public function testButton()
134    {
135        $form = new HTML_QuickForm2('filters', 'post', null, false);
136        $form->addDataSource(new HTML_QuickForm2_DataSource_Array([
137            'bar' => 'VALUE'
138        ]));
139        $button = $form->addButton('bar', ['type' => 'submit']);
140        $button->addFilter('strtolower');
141        $this->assertEquals('value', $button->getValue());
142    }
143
144    public function testInput()
145    {
146        $form = new HTML_QuickForm2('filters', 'post', null, false);
147        $foo = $form->addText('foo');
148        $this->assertEquals($_POST['foo'], $foo->getValue());
149        $foo->addFilter('trim');
150        $this->assertEquals(trim($_POST['foo']), $foo->getValue());
151    }
152
153    public function testTextarea()
154    {
155        $form = new HTML_QuickForm2('filters', 'post', null, false);
156        $area = $form->addTextarea('bar');
157        $area->addFilter('strtolower');
158        $this->assertEquals('value', $area->getValue());
159    }
160
161    public function testContainer()
162    {
163        $c1 = new HTML_QuickForm2_ContainerFilterImpl('filter');
164        $this->assertNull($c1->getValue());
165
166        $el1 = $c1->addText('foo');
167        $el2 = $c1->addText('bar');
168        $el3 = $c1->addText('baz');
169        $this->assertNull($c1->getValue());
170
171        $el1->setValue('A');
172        $el1->addFilter('repeatFilter');
173
174        $el2->setValue('B');
175        $el3->setValue('C');
176
177        $this->assertEquals([
178            'foo' => 'AA',
179            'bar' => 'B',
180            'baz' => 'C'
181        ], $c1->getValue());
182
183        $c1->addRecursiveFilter('strtolower');
184
185        $this->assertEquals('aa', $el1->getValue());
186        $this->assertEquals('b',  $el2->getValue());
187        $this->assertEquals('c',  $el3->getValue());
188
189        $c1->addRecursiveFilter('trim');
190        $c1->addRecursiveFilter('repeatFilter');
191
192        $this->assertEquals('aaa', $el1->getValue());
193        $this->assertEquals('bb',  $el2->getValue());
194        $this->assertEquals('cc',  $el3->getValue());
195        // Second run, just to make sure...
196        $this->assertEquals('aaa', $el1->getValue());
197        $this->assertEquals('bb',  $el2->getValue());
198        $this->assertEquals('cc',  $el3->getValue());
199    }
200
201    public function testGroup()
202    {
203        $value1     = ['foo' => 'foo'];
204        $value1F    = ['foo' => 'F'];
205        $value2     = ['bar' => 'bar', 'baz' => ['quux' => 'baz']];
206        $value2F    = ['bar' => 'Bar', 'baz' => ['quux' => 'Baz']];
207        $valueAnon  = ['e1' => 'e1'];
208        $valueAnonF = ['e1' => '1'];
209        $formValue  = ['g1' => $value1, 'g2' => ['i2' => $value2]] + $valueAnon;
210        $formValueF = ['g1' => $value1F, 'g2' => ['i2' => $value2F]] + $valueAnonF;
211
212        $form = new HTML_QuickForm2('testGroupGetValue');
213        $form->addDataSource(new HTML_QuickForm2_DataSource_Array($formValue));
214
215        $g1 = $form->addGroup('g1');
216        $g1->addRecursiveFilter('strtoupper');
217
218        $el1 = $g1->addText('foo');
219        // Trim O *after* strtoupper
220        $el1->addFilter('trim', ['O']);
221
222        $g2 = $form->addGroup('g2[i2]');
223        $g2->addRecursiveFilter('ucfirst');
224        $g2->addText('bar');
225        $g2->addText('baz[quux]');
226
227        $anon = $form->addGroup();
228        $anon->addText('e1');
229        $anon->addRecursiveFilter('substr', [1, 1]);
230
231        $this->assertEquals($formValueF, $form->getValue());
232    }
233
234    public function testContainerNonRecursive()
235    {
236        $c = new HTML_QuickForm2_ContainerFilterImpl('nonrecursive');
237        $el1 = $c->addElement('text', 'el1')->setValue(' foo');
238        $el2 = $c->addElement('text', 'el2')->setValue('bar ');
239
240        $c->addRecursiveFilter('trim');
241        $c->addFilter('count');
242
243        $this->assertEquals(2, $c->getValue());
244        $this->assertEquals('foo', $el1->getValue());
245    }
246}
247?>
248