'', 'nestingLabel' => '{{input}}{{text}}', 'radioWrapper' => '{{label}}', 'selectedClass' => 'selected', ]; $this->templates = new StringTemplate($templates); $this->context = $this->getMockBuilder('Cake\View\Form\ContextInterface')->getMock(); } /** * Test rendering basic radio buttons without nested inputs * * @return void */ public function testRenderSimpleNotNested() { $this->templates->add([ 'nestingLabel' => '{{text}}', 'radioWrapper' => '{{input}}{{label}}', ]); $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Crayons[color]', 'label' => null, 'options' => ['r' => 'Red', 'b' => 'Black'], ]; $result = $radio->render($data, $this->context); $expected = [ ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', ]], ['label' => ['for' => 'crayons-color-r']], 'Red', '/label', ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'b', 'id' => 'crayons-color-b', ]], ['label' => ['for' => 'crayons-color-b']], 'Black', '/label', ]; $this->assertHtml($expected, $result); $data = [ 'name' => 'Crayons[color]', 'label' => false, 'options' => ['r' => 'Red', 'b' => 'Black'], ]; $result = $radio->render($data, $this->context); $expected = [ ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', ]], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'b', 'id' => 'crayons-color-b', ]], ]; $this->assertHtml($expected, $result); } /** * Test rendering basic radio buttons. * * @return void */ public function testRenderSimple() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Crayons[color]', 'label' => null, 'options' => ['r' => 'Red', 'b' => 'Black'], ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'crayons-color-r']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', ]], 'Red', '/label', ['label' => ['for' => 'crayons-color-b']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'b', 'id' => 'crayons-color-b', ]], 'Black', '/label', ]; $this->assertHtml($expected, $result); $data = [ 'name' => 'Crayons[color]', 'options' => new Collection(['r' => 'Red', 'b' => 'Black']), ]; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); } /** * Test rendering the activeClass template var * * @return void */ public function testRenderSimpleActiveTemplateVar() { $this->templates->add([ 'nestingLabel' => '', 'radioWrapper' => '{{input}}{{label}}', ]); $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Crayons[color]', 'val' => 'r', 'options' => ['r' => 'Red', 'b' => 'Black'], ]; $result = $radio->render($data, $this->context); $expected = [ ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', 'checked' => 'checked', ]], ['label' => ['class' => 'active', 'for' => 'crayons-color-r']], 'Red', '/label', ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'b', 'id' => 'crayons-color-b', ]], ['label' => ['class' => '', 'for' => 'crayons-color-b']], 'Black', '/label', ]; $this->assertHtml($expected, $result); } /** * Test rendering inputs with the complex option form. * * @return void */ public function testRenderComplex() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Crayons[color]', 'options' => [ ['value' => 'r', 'text' => 'Red', 'id' => 'my_id'], ['value' => 'b', 'text' => 'Black', 'id' => 'my_id_2', 'data-test' => 'test'], ], ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'my_id']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'my_id', ]], 'Red', '/label', ['label' => ['for' => 'my_id_2']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'b', 'id' => 'my_id_2', 'data-test' => 'test', ]], 'Black', '/label', ]; $this->assertHtml($expected, $result); } /** * Test rendering inputs with label options * * @return void */ public function testRenderComplexLabelAttributes() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Crayons[color]', 'options' => [ ['value' => 'r', 'text' => 'Red', 'label' => ['style' => 'color:red']], ['value' => 'b', 'text' => 'Black', 'label' => ['data-test' => 'yes']], ], ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'crayons-color-r', 'style' => 'color:red']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', ]], 'Red', '/label', ['label' => ['for' => 'crayons-color-b', 'data-test' => 'yes']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'b', 'id' => 'crayons-color-b', ]], 'Black', '/label', ]; $this->assertHtml($expected, $result); } /** * Test that id suffixes are generated to not collide * * @return void */ public function testRenderIdSuffixGeneration() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Thing[value]', 'options' => ['a>b' => 'First', 'a 'Second'], ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'thing-value-a-b']], ['input' => [ 'type' => 'radio', 'name' => 'Thing[value]', 'value' => 'a>b', 'id' => 'thing-value-a-b', ]], 'First', '/label', ['label' => ['for' => 'thing-value-a-b1']], ['input' => [ 'type' => 'radio', 'name' => 'Thing[value]', 'value' => 'a<b', 'id' => 'thing-value-a-b1', ]], 'Second', '/label', ]; $this->assertHtml($expected, $result); } /** * Test rendering checks the right option with booleanish values. * * @return void */ public function testRenderBooleanishValues() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Model[field]', 'options' => ['1' => 'Yes', '0' => 'No'], 'val' => '0', ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'model-field-1']], ['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1']], 'Yes', '/label', ['label' => ['for' => 'model-field-0']], ['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0', 'checked' => 'checked']], 'No', '/label', ]; $this->assertHtml($expected, $result); $data['val'] = 0; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); $data['val'] = false; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); $expected = [ ['label' => ['for' => 'model-field-1']], ['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1']], 'Yes', '/label', ['label' => ['for' => 'model-field-0']], ['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0']], 'No', '/label', ]; $data['val'] = null; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); $data['val'] = ''; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); $expected = [ ['label' => ['for' => 'model-field-1']], ['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1', 'checked' => 'checked']], 'Yes', '/label', ['label' => ['for' => 'model-field-0']], ['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0']], 'No', '/label', ]; $data['val'] = '1'; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); $data['val'] = 1; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); $data['val'] = true; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); } /** * Test that render() works with the required attribute. * * @return void */ public function testRenderRequiredAndFormAttribute() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'published', 'options' => ['option A', 'option B'], 'required' => true, 'form' => 'my-form', ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'published-0']], ['input' => ['type' => 'radio', 'name' => 'published', 'value' => '0', 'id' => 'published-0', 'required' => 'required', 'form' => 'my-form']], 'option A', '/label', ['label' => ['for' => 'published-1']], ['input' => ['type' => 'radio', 'name' => 'published', 'value' => '1', 'id' => 'published-1', 'required' => 'required', 'form' => 'my-form']], 'option B', '/label', ]; $this->assertHtml($expected, $result); } /** * Test rendering the empty option. * * @return void */ public function testRenderEmptyOption() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Crayons[color]', 'options' => ['r' => 'Red'], 'empty' => true, ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'crayons-color']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => '', 'id' => 'crayons-color', ]], 'empty', '/label', ['label' => ['for' => 'crayons-color-r']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', ]], 'Red', '/label', ]; $this->assertHtml($expected, $result); $data['empty'] = 'Choose one'; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'crayons-color']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => '', 'id' => 'crayons-color', ]], 'Choose one', '/label', ['label' => ['for' => 'crayons-color-r']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', ]], 'Red', '/label', ]; $this->assertHtml($expected, $result); } /** * Test rendering the input inside the label. * * @return void */ public function testRenderInputInsideLabel() { $this->templates->add([ 'label' => '{{input}}{{text}}', 'radioWrapper' => '{{label}}', ]); $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Crayons[color]', 'options' => ['r' => 'Red'], ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'crayons-color-r']], ['input' => [ 'type' => 'radio', 'name' => 'Crayons[color]', 'value' => 'r', 'id' => 'crayons-color-r', ]], 'Red', '/label', ]; $this->assertHtml($expected, $result); } /** * test render() and selected inputs. * * @return void */ public function testRenderSelected() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Versions[ver]', 'val' => '1', 'options' => [ 1 => 'one', '1x' => 'one x', '2' => 'two', ], ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'versions-ver-1']], ['input' => [ 'id' => 'versions-ver-1', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1', 'checked' => 'checked', ]], 'one', '/label', ['label' => ['for' => 'versions-ver-1x']], ['input' => [ 'id' => 'versions-ver-1x', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1x', ]], 'one x', '/label', ['label' => ['for' => 'versions-ver-2']], ['input' => [ 'id' => 'versions-ver-2', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '2', ]], 'two', '/label', ]; $this->assertHtml($expected, $result); } /** * Test rendering with disable inputs * * @return void */ public function testRenderDisabled() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Versions[ver]', 'options' => [ 1 => 'one', '1x' => 'one x', '2' => 'two', ], 'disabled' => true, ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'versions-ver-1']], ['input' => [ 'id' => 'versions-ver-1', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1', 'disabled' => 'disabled', ]], 'one', '/label', ['label' => ['for' => 'versions-ver-1x']], ['input' => [ 'id' => 'versions-ver-1x', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1x', 'disabled' => 'disabled', ]], 'one x', '/label', ]; $this->assertHtml($expected, $result); $data['disabled'] = 'a string'; $result = $radio->render($data, $this->context); $this->assertHtml($expected, $result); $data['disabled'] = ['1']; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['for' => 'versions-ver-1']], ['input' => [ 'id' => 'versions-ver-1', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1', 'disabled' => 'disabled', ]], 'one', '/label', ['label' => ['for' => 'versions-ver-1x']], ['input' => [ 'id' => 'versions-ver-1x', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1x', ]], 'one x', '/label', ]; $this->assertHtml($expected, $result); } /** * Test rendering with label options. * * @return void */ public function testRenderLabelOptions() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Versions[ver]', 'options' => [ 1 => 'one', '1x' => 'one x', '2' => 'two', ], 'label' => false, ]; $result = $radio->render($data, $this->context); $expected = [ ['input' => [ 'id' => 'versions-ver-1', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1', ]], ['input' => [ 'id' => 'versions-ver-1x', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1x', ]], ]; $this->assertHtml($expected, $result); $data = [ 'name' => 'Versions[ver]', 'options' => [ 1 => 'one', '1x' => 'one x', '2' => 'two', ], 'label' => [ 'class' => 'my-class', ], ]; $result = $radio->render($data, $this->context); $expected = [ ['label' => ['class' => 'my-class', 'for' => 'versions-ver-1']], ['input' => [ 'id' => 'versions-ver-1', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1', ]], 'one', '/label', ['label' => ['class' => 'my-class', 'for' => 'versions-ver-1x']], ['input' => [ 'id' => 'versions-ver-1x', 'name' => 'Versions[ver]', 'type' => 'radio', 'value' => '1x', ]], 'one x', '/label', ]; $this->assertHtml($expected, $result); } /** * Ensure that the input + label are composed with * a template. * * @return void */ public function testRenderContainerTemplate() { $this->templates->add([ 'radioWrapper' => '
{{input}}{{label}}
', ]); $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Versions[ver]', 'options' => [ 1 => 'one', '1x' => 'one x', '2' => 'two', ], ]; $result = $radio->render($data, $this->context); $this->assertContains( '
assertContains( '
', $result ); } /** * Ensure that template vars work. * * @return void */ public function testRenderTemplateVars() { $this->templates->add([ 'radioWrapper' => '
{{label}}
', 'radio' => '', 'nestingLabel' => '{{input}}{{text}} {{labelVar}} {{wrapperVar}}', ]); $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $data = [ 'name' => 'Versions[ver]', 'options' => [ ['value' => '1x', 'text' => 'one x', 'templateVars' => ['labelVar' => 'l-var', 'inputVar' => 'i-var']], '2' => 'two', ], 'templateVars' => [ 'wrapperVar' => 'wrap-var', ], ]; $result = $radio->render($data, $this->context); $this->assertContains('data-var="wrap-var">assertContains('type="radio" data-i="i-var"', $result); $this->assertContains('one x l-var wrap-var', $result); $this->assertContains('two wrap-var', $result); } /** * testRenderCustomAttributes method * * Test render with custom attributes. * * @return void */ public function testRenderCustomAttributes() { $label = new NestingLabelWidget($this->templates); $radio = new RadioWidget($this->templates, $label); $result = $radio->render([ 'name' => 'Model[field]', 'label' => null, 'options' => ['option A', 'option B'], 'class' => 'my-class', 'data-ref' => 'custom-attr', ], $this->context); $expected = [ ['label' => ['for' => 'model-field-0']], [ 'input' => [ 'type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0', 'class' => 'my-class', 'data-ref' => 'custom-attr', ], ], 'option A', '/label', ['label' => ['for' => 'model-field-1']], [ 'input' => [ 'type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1', 'class' => 'my-class', 'data-ref' => 'custom-attr', ], ], 'option B', '/label', ]; $this->assertHtml($expected, $result); } /** * testRenderExplicitId method * * Test that the id passed is actually used * Issue: https://github.com/cakephp/cakephp/issues/13342 * * @return void */ public function testRenderExplicitId() { $label = new NestingLabelWidget($this->templates); $input = new RadioWidget($this->templates, $label); $data = [ 'name' => 'field', 'options' => ['value1', 'value2', -1 => 'negative'], 'id' => 'alternative-id', 'idPrefix' => 'willBeIgnored', ]; $result = $input->render($data, $this->context); $expected = [ [ 'label' => ['for' => 'alternative-id-0'], 'input' => ['type' => 'radio', 'name' => 'field', 'value' => '0', 'id' => 'alternative-id-0'], ], 'value1', '/label', [ 'label' => ['for' => 'alternative-id-1'], 'input' => ['type' => 'radio', 'name' => 'field', 'value' => '1', 'id' => 'alternative-id-1'], ], 'value2', '/label', [ 'label' => ['for' => 'alternative-id--1'], 'input' => ['type' => 'radio', 'name' => 'field', 'value' => '-1', 'id' => 'alternative-id--1'], ], 'negative', '/label', ]; $this->assertHtml($expected, $result); $data = [ 'name' => 'field', 'options' => ['value1', 'value2'], 'idPrefix' => 'formprefix', ]; $result = $input->render($data, $this->context); $expected = [ [ 'label' => ['for' => 'formprefix-field-0'], 'input' => ['type' => 'radio', 'name' => 'field', 'value' => '0', 'id' => 'formprefix-field-0'], ], 'value1', '/label', [ 'label' => ['for' => 'formprefix-field-1'], 'input' => ['type' => 'radio', 'name' => 'field', 'value' => '1', 'id' => 'formprefix-field-1'], ], 'value2', '/label', ]; $this->assertHtml($expected, $result); } /** * testRenderSelectedClass method * * Test that the custom selected class is passed to label * Issue: https://github.com/cakephp/cakephp/issues/11249 * * @return void */ public function testRenderSelectedClass() { $this->templates->add(['selectedClass' => 'active']); $label = new NestingLabelWidget($this->templates); $input = new RadioWidget($this->templates, $label); $data = [ 'name' => 'field', 'options' => ['value1' => 'title1'], 'val' => 'value1', 'label' => ['title' => 'my label'], ]; $result = $input->render($data, $this->context); $expected = [ ['label' => [ 'title' => 'my label', 'class' => 'active', 'for' => 'field-value1', ]], ]; $this->assertHtml($expected, $result); } }