From ab1198f4da4aaab5afed543beaed6128341353e4 Mon Sep 17 00:00:00 2001 From: Geoffrey Brier Date: Fri, 2 May 2014 17:23:01 +0200 Subject: [PATCH 1/6] [DomCrawler] Fixed image input case sensitive --- src/Symfony/Component/DomCrawler/Crawler.php | 5 +++-- .../Component/DomCrawler/Field/ChoiceFormField.php | 4 ++-- .../Component/DomCrawler/Field/FileFormField.php | 2 +- .../Component/DomCrawler/Field/InputFormField.php | 4 ++-- src/Symfony/Component/DomCrawler/Form.php | 12 ++++++------ src/Symfony/Component/DomCrawler/Tests/FormTest.php | 7 +++++++ 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index a96d1db89a..770e4026b8 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -651,8 +651,9 @@ class Crawler extends \SplObjectStorage */ public function selectButton($value) { - $xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')). - sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value). + $translate = 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")'; + $xpath = sprintf('//input[((contains(%s, "submit") or contains(%s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', $translate, $translate, static::xpathLiteral(' '.$value.' ')). + sprintf('or (contains(%s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', $translate, static::xpathLiteral(' '.$value.' '), $value, $value). sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value); return $this->filterXPath($xpath); diff --git a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php index 58a6bf0bed..efdcf5b922 100644 --- a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php @@ -206,7 +206,7 @@ class ChoiceFormField extends FormField throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); } - if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) { + if ('input' == $this->node->nodeName && 'checkbox' != strtolower($this->node->getAttribute('type')) && 'radio' != strtolower($this->node->getAttribute('type'))) { throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type'))); } @@ -215,7 +215,7 @@ class ChoiceFormField extends FormField $this->multiple = false; if ('input' == $this->node->nodeName) { - $this->type = $this->node->getAttribute('type'); + $this->type = strtolower($this->node->getAttribute('type')); $optionValue = $this->buildOptionValue($this->node); $this->options[] = $optionValue; diff --git a/src/Symfony/Component/DomCrawler/Field/FileFormField.php b/src/Symfony/Component/DomCrawler/Field/FileFormField.php index c65b5c9c4f..160ddc6e0d 100644 --- a/src/Symfony/Component/DomCrawler/Field/FileFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/FileFormField.php @@ -103,7 +103,7 @@ class FileFormField extends FormField throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName)); } - if ('file' != $this->node->getAttribute('type')) { + if ('file' != strtolower($this->node->getAttribute('type'))) { throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $this->node->getAttribute('type'))); } diff --git a/src/Symfony/Component/DomCrawler/Field/InputFormField.php b/src/Symfony/Component/DomCrawler/Field/InputFormField.php index d3d3957934..00141d84c6 100644 --- a/src/Symfony/Component/DomCrawler/Field/InputFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/InputFormField.php @@ -34,11 +34,11 @@ class InputFormField extends FormField throw new \LogicException(sprintf('An InputFormField can only be created from an input or button tag (%s given).', $this->node->nodeName)); } - if ('checkbox' == $this->node->getAttribute('type')) { + if ('checkbox' == strtolower($this->node->getAttribute('type'))) { throw new \LogicException('Checkboxes should be instances of ChoiceFormField.'); } - if ('file' == $this->node->getAttribute('type')) { + if ('file' == strtolower($this->node->getAttribute('type'))) { throw new \LogicException('File inputs should be instances of FileFormField.'); } diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index 2b9e43c701..a19cc79da7 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -352,7 +352,7 @@ class Form extends Link implements \ArrayAccess protected function setNode(\DOMNode $node) { $this->button = $node; - if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) { + if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image')))) { if ($node->hasAttribute('form')) { // if the node has the HTML5-compliant 'form' attribute, use it $formId = $node->getAttribute('form'); @@ -394,7 +394,7 @@ class Form extends Link implements \ArrayAccess // add submitted button if it has a valid name if ('form' !== $this->button->nodeName && $this->button->hasAttribute('name') && $this->button->getAttribute('name')) { - if ('input' == $this->button->nodeName && 'image' == $this->button->getAttribute('type')) { + if ('input' == $this->button->nodeName && 'image' == strtolower($this->button->getAttribute('type'))) { $name = $this->button->getAttribute('name'); $this->button->setAttribute('value', '0'); @@ -445,17 +445,17 @@ class Form extends Link implements \ArrayAccess } $nodeName = $node->nodeName; - if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) { + if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == strtolower($node->getAttribute('type'))) { $this->set(new Field\ChoiceFormField($node)); - } elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) { + } elseif ('input' == $nodeName && 'radio' == strtolower($node->getAttribute('type'))) { if ($this->has($node->getAttribute('name'))) { $this->get($node->getAttribute('name'))->addChoice($node); } else { $this->set(new Field\ChoiceFormField($node)); } - } elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) { + } elseif ('input' == $nodeName && 'file' == strtolower($node->getAttribute('type'))) { $this->set(new Field\FileFormField($node)); - } elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) { + } elseif ('input' == $nodeName && !in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image'))) { $this->set(new Field\InputFormField($node)); } elseif ('textarea' == $nodeName) { $this->set(new Field\TextareaFormField($node)); diff --git a/src/Symfony/Component/DomCrawler/Tests/FormTest.php b/src/Symfony/Component/DomCrawler/Tests/FormTest.php index ecb7207c2e..1fbfbb983d 100644 --- a/src/Symfony/Component/DomCrawler/Tests/FormTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/FormTest.php @@ -631,6 +631,13 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertSame($nodes->item(0), $form->getFormNode(), '->getFormNode() returns the form node associated with this form'); } + public function testTypeAttributeIsCaseInsensitive() + { + $form = $this->createForm('
'); + $this->assertTrue($form->has('example.x'), '->has() returns true if the image input was correctly turned into an x and a y fields'); + $this->assertTrue($form->has('example.y'), '->has() returns true if the image input was correctly turned into an x and a y fields'); + } + /** * @expectedException \InvalidArgumentException */ From bc42dae162bcab809cfd817363c21a3159470d37 Mon Sep 17 00:00:00 2001 From: alquerci Date: Tue, 31 Dec 2013 17:23:37 +0100 Subject: [PATCH 2/6] Added test when TTL has expired --- .../Tests/HttpCache/HttpCacheTest.php | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index 50a1de907d..c54caf832e 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -595,6 +595,89 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('Hello World', $this->response->getContent()); } + public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpired() + { + $this->setNextResponse(); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertTraceContains('miss'); + $this->assertTraceContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + + sleep(4); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('stale'); + $this->assertTraceContains('invalid'); + $this->assertTraceContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + } + + public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpiredWithStatus304() + { + $this->setNextResponse(); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertTraceContains('miss'); + $this->assertTraceContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + + sleep(4); + + $this->setNextResponse(304); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('stale'); + $this->assertTraceContains('valid'); + $this->assertTraceContains('store'); + $this->assertTraceNotContains('miss'); + $this->assertEquals('Hello World', $this->response->getContent()); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + } + public function testDoesNotAssignDefaultTtlWhenResponseHasMustRevalidateDirective() { $this->setNextResponse(200, array('Cache-Control' => 'must-revalidate')); From e3983e8ec584311d6eced6a8547eae5a6113e8df Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 12 May 2014 17:25:47 +0200 Subject: [PATCH 3/6] [HttpKernel] fixed default TTL not applied under certain conditions --- .../HttpKernel/HttpCache/HttpCache.php | 12 +++--- .../Tests/HttpCache/HttpCacheTest.php | 38 ++++++++++++++----- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 2bea9f58ba..871b3a87fc 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -428,12 +428,6 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $response = $this->forward($subRequest, $catch); - if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { - $response->setPrivate(true); - } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) { - $response->setTtl($this->options['default_ttl']); - } - if ($response->isCacheable()) { $this->store($request, $response); } @@ -487,6 +481,12 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $this->processResponseBody($request, $response); + if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { + $response->setPrivate(true); + } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) { + $response->setTtl($this->options['default_ttl']); + } + return $response; } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index c54caf832e..e08f198281 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -593,6 +593,7 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=10/', $this->response->headers->get('Cache-Control')); } public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpired() @@ -607,17 +608,25 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('Hello World', $this->response->getContent()); $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - sleep(4); + // expires the cache + $values = $this->getMetaStorageValues(); + $this->assertCount(1, $values); + $tmp = unserialize($values[0]); + $time = \DateTime::createFromFormat('U', time()); + $tmp[0][1]['date'] = \DateTime::createFromFormat('U', time() - 5)->format(DATE_RFC2822); + $r = new \ReflectionObject($this->store); + $m = $r->getMethod('save'); + $m->setAccessible(true); + $m->invoke($this->store, 'md'.sha1('http://localhost/'), serialize($tmp)); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsCalled(); $this->assertEquals(200, $this->response->getStatusCode()); @@ -625,14 +634,17 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceContains('invalid'); $this->assertTraceContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); + + $this->setNextResponse(); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); } public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpiredWithStatus304() @@ -647,7 +659,6 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('Hello World', $this->response->getContent()); $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); @@ -655,11 +666,17 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); - sleep(4); + // expires the cache + $values = $this->getMetaStorageValues(); + $this->assertCount(1, $values); + $tmp = unserialize($values[0]); + $time = \DateTime::createFromFormat('U', time()); + $tmp[0][1]['date'] = \DateTime::createFromFormat('U', time() - 5)->format(DATE_RFC2822); + $r = new \ReflectionObject($this->store); + $m = $r->getMethod('save'); + $m->setAccessible(true); + $m->invoke($this->store, 'md'.sha1('http://localhost/'), serialize($tmp)); - $this->setNextResponse(304); - - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsCalled(); $this->assertEquals(200, $this->response->getStatusCode()); @@ -668,14 +685,15 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceContains('store'); $this->assertTraceNotContains('miss'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); } public function testDoesNotAssignDefaultTtlWhenResponseHasMustRevalidateDirective() From 46725c9cc8b6e81e29a743417e297839776b475d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 13 May 2014 10:47:23 +0200 Subject: [PATCH 4/6] fixed CS --- src/Symfony/Component/Console/Tests/ApplicationTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 0965d24ad5..2c27339a6e 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -476,7 +476,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $application->expects($this->any()) ->method('getTerminalWidth') ->will($this->returnValue(120)); - $application->register('foo')->setCode(function () {throw new \Exception('エラーメッセージ');}); + $application->register('foo')->setCode(function () { + throw new \Exception('エラーメッセージ'); + }); $tester = new ApplicationTester($application); $tester->run(array('command' => 'foo'), array('decorated' => false)); @@ -490,7 +492,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $application->expects($this->any()) ->method('getTerminalWidth') ->will($this->returnValue(32)); - $application->register('foo')->setCode(function () {throw new \Exception('コマンドの実行中にエラーが発生しました。');}); + $application->register('foo')->setCode(function () { + throw new \Exception('コマンドの実行中にエラーが発生しました。'); + }); $tester = new ApplicationTester($application); $tester->run(array('command' => 'foo'), array('decorated' => false)); $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal'); From 8cadb49613054722efc607daa6d95dd36d02203b Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Tue, 13 May 2014 14:44:05 +0100 Subject: [PATCH 5/6] Update the fixtures. --- .../application_renderexception_doublewidth2.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt index 545cd7b0b4..5605f10697 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt @@ -1,10 +1,11 @@ - - [Exception] - コマンドの実行中にエラーが - 発生しました。 - + + [Exception] + コマンドの実行中に + エラーが発生しまし + た。 + foo From 61108b91856234af98057727c5ca2e511ca24679 Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Tue, 13 May 2014 22:34:13 +0100 Subject: [PATCH 6/6] Disable 5.6 until it is stable again. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index ca4c19d381..6e4c449744 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ php: matrix: allow_failures: + - php: 5.6 - php: hhvm-nightly services: mongodb