Skip to content

Commit 5297923

Browse files
committed
Improve the URL Field and add tests
1 parent 590c9bc commit 5297923

File tree

4 files changed

+95
-5
lines changed

4 files changed

+95
-5
lines changed

src/Field/Configurator/UrlConfigurator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public function supports(FieldDto $field, EntityDto $entityDto): bool
2323
public function configure(FieldDto $field, EntityDto $entityDto, AdminContext $context): void
2424
{
2525
$field->setFormTypeOptionIfNotSet('attr.inputmode', 'url');
26+
$field->setFormTypeOptionIfNotSet('default_protocol', $field->getCustomOption(UrlField::OPTION_DEFAULT_PROTOCOL));
2627

2728
$prettyUrl = str_replace(['http://www.', 'https://www.', 'http://', 'https://'], '', (string) $field->getValue());
2829
$prettyUrl = rtrim($prettyUrl, '/');

src/Field/UrlField.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ final class UrlField implements FieldInterface
1313
{
1414
use FieldTrait;
1515

16+
public const OPTION_DEFAULT_PROTOCOL = 'defaultProtocol';
17+
1618
/**
1719
* @param TranslatableInterface|string|false|null $label
1820
*/
@@ -24,6 +26,20 @@ public static function new(string $propertyName, $label = null): self
2426
->setTemplateName('crud/field/url')
2527
->setFormType(UrlType::class)
2628
->addCssClass('field-url')
27-
->setDefaultColumns('col-md-10 col-xxl-8');
29+
->setDefaultColumns('col-md-10 col-xxl-8')
30+
->setCustomOption(self::OPTION_DEFAULT_PROTOCOL, null);
31+
}
32+
33+
/**
34+
* Defines the protocol prepended to the URL if it doesn't include it.
35+
* If not set, no protocol is prepended to the URL and the field is rendered
36+
* using an <input type="url"> HTML element to enable local browser validation.
37+
* See https://symfony.com/doc/current/reference/forms/types/url.html#default-protocol
38+
*/
39+
public function setDefaultProtocol(string $protocol): self
40+
{
41+
$this->setCustomOption(self::OPTION_DEFAULT_PROTOCOL, $protocol);
42+
43+
return $this;
2844
}
2945
}

tests/Field/AbstractFieldTest.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace EasyCorp\Bundle\EasyAdminBundle\Tests\Field;
44

5+
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
56
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
67
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
78
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
@@ -30,15 +31,16 @@ private function getEntityDto(): EntityDto
3031
return $this->entityDto = $entityDtoMock;
3132
}
3233

33-
private function getAdminContext(string $pageName, string $requestLocale): AdminContext
34+
private function getAdminContext(string $pageName, string $requestLocale, string $actionName): AdminContext
3435
{
3536
self::bootKernel();
3637

3738
$crudMock = $this->getMockBuilder(CrudDto::class)
3839
->disableOriginalConstructor()
39-
->onlyMethods(['getCurrentPage', 'getDatePattern', 'getDateTimePattern', 'getTimePattern'])
40+
->onlyMethods(['getCurrentPage', 'getCurrentAction', 'getDatePattern', 'getDateTimePattern', 'getTimePattern'])
4041
->getMock();
4142
$crudMock->method('getCurrentPage')->willReturn($pageName);
43+
$crudMock->method('getCurrentAction')->willReturn($actionName);
4244
$crudMock->method('getDatePattern')->willReturn(DateTimeField::FORMAT_MEDIUM);
4345
$crudMock->method('getTimePattern')->willReturn(DateTimeField::FORMAT_MEDIUM);
4446
$crudMock->method('getDateTimePattern')->willReturn([DateTimeField::FORMAT_MEDIUM, DateTimeField::FORMAT_MEDIUM]);
@@ -80,10 +82,10 @@ private function getAdminContext(string $pageName, string $requestLocale): Admin
8082
return $this->adminContext = $adminContextMock;
8183
}
8284

83-
protected function configure(FieldInterface $field, string $pageName = Crud::PAGE_INDEX, string $requestLocale = 'en'): FieldDto
85+
protected function configure(FieldInterface $field, string $pageName = Crud::PAGE_INDEX, string $requestLocale = 'en', string $actionName = Action::INDEX): FieldDto
8486
{
8587
$fieldDto = $field->getAsDto();
86-
$this->configurator->configure($fieldDto, $this->getEntityDto(), $this->getAdminContext($pageName, $requestLocale));
88+
$this->configurator->configure($fieldDto, $this->getEntityDto(), $this->getAdminContext($pageName, $requestLocale, $actionName));
8789

8890
return $fieldDto;
8991
}

tests/Field/UrlFieldTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace EasyCorp\Bundle\EasyAdminBundle\Tests\Field;
4+
5+
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
6+
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
7+
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
8+
use EasyCorp\Bundle\EasyAdminBundle\Field\Configurator\CountryConfigurator;
9+
use EasyCorp\Bundle\EasyAdminBundle\Field\Configurator\UrlConfigurator;
10+
use EasyCorp\Bundle\EasyAdminBundle\Field\CountryField;
11+
use EasyCorp\Bundle\EasyAdminBundle\Field\UrlField;
12+
13+
class UrlFieldTest extends AbstractFieldTest
14+
{
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
18+
}
19+
20+
public function testDefaultFieldOptions()
21+
{
22+
$this->initializeConfigurator();
23+
24+
$field = UrlField::new('foo');
25+
$fieldDto = $this->configure($field, actionName: Action::EDIT);
26+
27+
self::assertSame('url', $fieldDto->getFormTypeOption('attr.inputmode'));
28+
self::assertNull($fieldDto->getCustomOption(UrlField::OPTION_DEFAULT_PROTOCOL));
29+
}
30+
31+
/**
32+
* @testWith [""]
33+
* ["http"]
34+
* ["https"]
35+
* ["ftp"]
36+
*/
37+
public function testDefaultProtocolOption(string $defaultProtocol)
38+
{
39+
$this->initializeConfigurator();
40+
41+
$field = UrlField::new('foo');
42+
$field->setDefaultProtocol($defaultProtocol);
43+
$fieldDto = $this->configure($field, actionName: Action::EDIT);
44+
45+
self::assertSame($defaultProtocol, $fieldDto->getCustomOption(UrlField::OPTION_DEFAULT_PROTOCOL));
46+
self::assertSame($defaultProtocol, $fieldDto->getFormTypeOption('default_protocol'));
47+
}
48+
49+
/**
50+
* @testWith ["http://example.com", "example.com"]
51+
* ["https://example.com", "example.com"]
52+
* ["http://www.example.com", "example.com"]
53+
* ["https://www.example.com", "example.com"]
54+
* ["https://01234567890123456789012345678901234567890123456789.com", "0123456789012345678901234567890…"]
55+
*/
56+
public function testFormattedValuesOnIndexAction(string $url, string $expectedRenderedUrl)
57+
{
58+
$this->initializeConfigurator();
59+
60+
$field = UrlField::new('foo')->setValue($url);
61+
$fieldDto = $this->configure($field);
62+
63+
self::assertSame($expectedRenderedUrl, $fieldDto->getFormattedValue());
64+
}
65+
66+
private function initializeConfigurator(): void
67+
{
68+
self::bootKernel();
69+
$this->configurator = new UrlConfigurator();
70+
}
71+
}

0 commit comments

Comments
 (0)