Skip to content

Commit

Permalink
Merge c289167 into 54beb10
Browse files Browse the repository at this point in the history
  • Loading branch information
kelunik committed Jun 10, 2019
2 parents 54beb10 + c289167 commit 85ce7cf
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/Cookie/RequestCookie.php
Expand Up @@ -80,6 +80,18 @@ public function getName(): string
return $this->name;
}

public function withName(string $name): self
{
if (!\preg_match('(^[^()<>@,;:\\\"/[\]?={}\x01-\x20\x7F]++$)', $name)) {
throw new InvalidCookieException("Invalid cookie name: '{$name}'");
}

$clone = clone $this;
$clone->name = $name;

return $clone;
}

/**
* @return string Value of the cookie.
*/
Expand All @@ -88,6 +100,18 @@ public function getValue(): string
return $this->value;
}

public function withValue(string $value): self
{
if (!\preg_match('(^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]*+$)', $value)) {
throw new InvalidCookieException("Invalid cookie value: '{$value}'");
}

$clone = clone $this;
$clone->value = $value;

return $clone;
}

/**
* @return string Representation of the cookie as in a 'cookie' header.
*/
Expand Down
82 changes: 82 additions & 0 deletions src/Cookie/ResponseCookie.php
Expand Up @@ -161,6 +161,18 @@ public function getName(): string
return $this->name;
}

public function withName(string $name): self
{
if (!\preg_match('(^[^()<>@,;:\\\"/[\]?={}\x01-\x20\x7F]++$)', $name)) {
throw new InvalidCookieException("Invalid cookie name: '{$name}'");
}

$clone = clone $this;
$clone->name = $name;

return $clone;
}

/**
* @return string Value of the cookie.
*/
Expand All @@ -169,6 +181,18 @@ public function getValue(): string
return $this->value;
}

public function withValue(string $value): self
{
if (!\preg_match('(^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]*+$)', $value)) {
throw new InvalidCookieException("Invalid cookie value: '{$value}'");
}

$clone = clone $this;
$clone->value = $value;

return $clone;
}

/**
* @return \DateTimeImmutable|null Expiry if set, otherwise `null`.
*
Expand All @@ -179,6 +203,16 @@ public function getExpiry()
return $this->attributes->getExpiry();
}

public function withExpiry(\DateTimeInterface $expiry): self
{
return $this->withAttributes($this->attributes->withExpiry($expiry));
}

public function withoutExpiry(): self
{
return $this->withAttributes($this->attributes->withoutExpiry());
}

/**
* @return int|null Max-Age if set, otherwise `null`.
*
Expand All @@ -189,6 +223,16 @@ public function getMaxAge()
return $this->attributes->getMaxAge();
}

public function withMaxAge(int $maxAge): self
{
return $this->withAttributes($this->attributes->withMaxAge($maxAge));
}

public function withoutMaxAge(): self
{
return $this->withAttributes($this->attributes->withoutMaxAge());
}

/**
* @return string Cookie path.
*
Expand All @@ -199,6 +243,11 @@ public function getPath(): string
return $this->attributes->getPath();
}

public function withPath(string $path): self
{
return $this->withAttributes($this->attributes->withPath($path));
}

/**
* @return string Cookie domain.
*
Expand All @@ -209,6 +258,11 @@ public function getDomain(): string
return $this->attributes->getDomain();
}

public function withDomain(string $domain): self
{
return $this->withAttributes($this->attributes->withDomain($domain));
}

/**
* @return bool Whether the secure flag is enabled or not.
*
Expand All @@ -219,6 +273,16 @@ public function isSecure(): bool
return $this->attributes->isSecure();
}

public function withSecure(): self
{
return $this->withAttributes($this->attributes->withSecure());
}

public function withoutSecure(): self
{
return $this->withAttributes($this->attributes->withoutSecure());
}

/**
* @return bool Whether the httpOnly flag is enabled or not.
*
Expand All @@ -229,6 +293,16 @@ public function isHttpOnly(): bool
return $this->attributes->isHttpOnly();
}

public function withHttpOnly(): self
{
return $this->withAttributes($this->attributes->withHttpOnly());
}

public function withoutHttpOnly(): self
{
return $this->withAttributes($this->attributes->withoutHttpOnly());
}

/**
* @return CookieAttributes All cookie attributes.
*/
Expand All @@ -237,6 +311,14 @@ public function getAttributes(): CookieAttributes
return $this->attributes;
}

public function withAttributes(CookieAttributes $attributes): self
{
$clone = clone $this;
$clone->attributes = $attributes;

return $clone;
}

/**
* @return string Representation of the cookie as in a 'set-cookie' header.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Status.php
Expand Up @@ -72,10 +72,12 @@ final class Status
const NOT_EXTENDED = 510;
const NETWORK_AUTHENTICATION_REQUIRED = 511;

// @codeCoverageIgnoreStart
private function __construct()
{
// forbid instances
}
// @codeCoverageIgnoreEnd

public static function getReason(int $code): string
{
Expand Down
36 changes: 36 additions & 0 deletions test/Cookie/RequestCookieTest.php
Expand Up @@ -27,13 +27,31 @@ public function testInvalidCookieName()
new RequestCookie("foo bar");
}

public function testInvalidCookieNameModify()
{
$cookie = new RequestCookie("foobar");

$this->expectException(InvalidCookieException::class);

$cookie->withName('foo bar');
}

public function testInvalidCookieValue()
{
$this->expectException(InvalidCookieException::class);

new RequestCookie("foobar", "what is this");
}

public function testInvalidCookieValueModify()
{
$cookie = new RequestCookie("foobar", "what-is-this");

$this->expectException(InvalidCookieException::class);

$cookie->withValue('what is this');
}

public function testGetters()
{
$cookie = new RequestCookie("foobar", "baz");
Expand All @@ -42,4 +60,22 @@ public function testGetters()
$this->assertSame("baz", $cookie->getValue());
$this->assertSame("foobar=baz", (string) $cookie);
}

public function testModifyName()
{
$cookie = new RequestCookie("foobar", "what-is-this");
$newCookie = $cookie->withName('bar');

$this->assertSame('foobar', $cookie->getName());
$this->assertSame('bar', $newCookie->getName());
}

public function testModifyValue()
{
$cookie = new RequestCookie("foobar", "what-is-this");
$newCookie = $cookie->withValue('what-is-that');

$this->assertSame('what-is-this', $cookie->getValue());
$this->assertSame('what-is-that', $newCookie->getValue());
}
}
122 changes: 122 additions & 0 deletions test/Cookie/ResponseCookieTest.php
Expand Up @@ -126,4 +126,126 @@ public function testToString()

$this->assertSame("foobar=xxx; HttpOnly", (string) $cookie);
}

public function testModifyName()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withName('bar');

$this->assertSame('foobar', $cookie->getName());
$this->assertSame('bar', $newCookie->getName());
}

public function testModifyValue()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withValue('what-is-that');

$this->assertSame('what-is-this', $cookie->getValue());
$this->assertSame('what-is-that', $newCookie->getValue());
}

public function testModifyHttpOnly()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withoutHttpOnly();

$this->assertTrue($cookie->isHttpOnly());
$this->assertTrue($newCookie->withHttpOnly()->isHttpOnly());
$this->assertFalse($newCookie->isHttpOnly());
}

public function testModifySecure()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withSecure();

$this->assertFalse($cookie->isSecure());
$this->assertFalse($newCookie->withoutSecure()->isSecure());
$this->assertTrue($newCookie->isSecure());
}

public function testModifyDomain()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withDomain('example.com');

$this->assertSame('', $cookie->getDomain());
$this->assertSame('example.com', $newCookie->getDomain());
}

public function testModifyPath()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withPath('/example');

$this->assertSame('', $cookie->getPath());
$this->assertSame('/example', $newCookie->getPath());
}

public function testModifyExpiry()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withExpiry(\DateTimeImmutable::createFromFormat('Y-m-d', '2019-06-10'));

$this->assertNull($cookie->getExpiry());
$this->assertNull($newCookie->withoutExpiry()->getExpiry());
$this->assertSame('2019-06-10', $newCookie->getExpiry()->format('Y-m-d'));
}

public function testModifyExpiryMutable()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$expiry = \DateTime::createFromFormat('Y-m-d', '2019-06-10');
$newCookie = $cookie->withExpiry($expiry);

$this->assertNull($cookie->getExpiry());
$this->assertNull($newCookie->withoutExpiry()->getExpiry());
$this->assertSame('2019-06-10', $newCookie->getExpiry()->format('Y-m-d'));

$expiry->add(new \DateInterval('P2D'));
$this->assertSame('2019-06-10', $newCookie->getExpiry()->format('Y-m-d'));
}

public function testModifyMaxAge()
{
$cookie = new ResponseCookie("foobar", "what-is-this");
$newCookie = $cookie->withMaxAge(12);

$this->assertNull($cookie->getMaxAge());
$this->assertNull($newCookie->withoutMaxAge()->getMaxAge());
$this->assertSame(12, $newCookie->getMaxAge());
}

public function testInvalidCookieName()
{
$this->expectException(InvalidCookieException::class);

new ResponseCookie("foo bar");
}

public function testInvalidCookieNameModify()
{
$cookie = new ResponseCookie("foobar");

$this->expectException(InvalidCookieException::class);

$cookie->withName('foo bar');
}

public function testInvalidCookieValue()
{
$this->expectException(InvalidCookieException::class);

new ResponseCookie("foobar", "what is this");
}

public function testInvalidCookieValueModify()
{
$cookie = new ResponseCookie("foobar", "what-is-this");

$this->expectException(InvalidCookieException::class);

$cookie->withValue('what is this');
}
}

0 comments on commit 85ce7cf

Please sign in to comment.