diff --git a/system/Test/TestResponse.php b/system/Test/TestResponse.php index e2c6e4781048..4c7a655457c8 100644 --- a/system/Test/TestResponse.php +++ b/system/Test/TestResponse.php @@ -406,7 +406,8 @@ public function getJSON() */ public function assertJSONFragment(array $fragment, bool $strict = false) { - $json = json_decode($this->getJSON(), true); + $json = json_decode($this->getJSON(), true); + $this->assertIsArray($json, 'Response does not have valid json'); $patched = array_replace_recursive($json, $fragment); if ($strict) diff --git a/tests/system/Test/FeatureResponseTest.php b/tests/system/Test/FeatureResponseTest.php deleted file mode 100644 index 824eee79d763..000000000000 --- a/tests/system/Test/FeatureResponseTest.php +++ /dev/null @@ -1,400 +0,0 @@ -getFeatureResponse('Hello World'); - $this->response->setStatusCode($code); - - $this->assertEquals($isOk, $this->feature->isOK()); - } - - /** - * Provides status codes and their expected "OK" - */ - public function statusCodeProvider(): array - { - return [ - [100, false], - [200, true], - [201, true], - [300, true], // Redirects are acceptable if the body is empty - [301, true], - [400, false], - [401, false], - [599, false], - ]; - } - - public function testIsOKEmpty() - { - $this->getFeatureResponse('Hi there'); - $this->response->setStatusCode(200); - $this->response->setBody(''); - - $this->assertFalse($this->feature->isOK()); - } - - public function testAssertSee() - { - $this->getFeatureResponse('

Hello World

'); - - $this->feature->assertSee('Hello'); - $this->feature->assertSee('World', 'h1'); - } - - public function testAssertDontSee() - { - $this->getFeatureResponse('

Hello World

'); - - $this->feature->assertDontSee('Worlds'); - $this->feature->assertDontSee('World', 'h2'); - } - - public function testAssertSeeElement() - { - $this->getFeatureResponse('

Hello World

'); - - $this->feature->assertSeeElement('h1'); - $this->feature->assertSeeElement('span'); - $this->feature->assertSeeElement('h1.header'); - } - - public function testAssertDontSeeElement() - { - $this->getFeatureResponse('

Hello World

'); - - $this->feature->assertDontSeeElement('h2'); - $this->feature->assertDontSeeElement('.span'); - $this->feature->assertDontSeeElement('h1.para'); - } - - public function testAssertSeeLink() - { - $this->getFeatureResponse('

Hello World

'); - - $this->feature->assertSeeElement('h1'); - $this->feature->assertSeeLink('Hello'); - } - - public function testAssertSeeInField() - { - $this->getFeatureResponse(''); - - $this->feature->assertSeeInField('user[name]', 'Foobar'); - } - - public function testAssertRedirectFail() - { - $this->getFeatureResponse('

Hello World

'); - - $this->assertFalse($this->feature->response instanceof RedirectResponse); - $this->assertFalse($this->feature->isRedirect()); - $this->feature->assertNotRedirect(); - } - - public function testAssertRedirectSuccess() - { - $this->getFeatureResponse('

Hello World

'); - $this->feature->response = new RedirectResponse(new App()); - - $this->assertTrue($this->feature->response instanceof RedirectResponse); - $this->assertTrue($this->feature->isRedirect()); - $this->feature->assertRedirect(); - } - - public function testAssertRedirectSuccessWithoutRedirectResponse() - { - $this->getFeatureResponse('

Hello World

'); - $this->response->redirect('foo/bar'); - - $this->assertFalse($this->feature->response instanceof RedirectResponse); - $this->assertTrue($this->feature->isRedirect()); - $this->feature->assertRedirect(); - $this->assertEquals('foo/bar', $this->feature->getRedirectUrl()); - } - - public function testGetRedirectUrlReturnsUrl() - { - $this->getFeatureResponse('

Hello World

'); - $this->feature->response = new RedirectResponse(new App()); - $this->feature->response->redirect('foo/bar'); - - $this->assertEquals('foo/bar', $this->feature->getRedirectUrl()); - } - - public function testGetRedirectUrlReturnsNull() - { - $this->getFeatureResponse('

Hello World

'); - - $this->assertNull($this->feature->getRedirectUrl()); - } - - public function testRedirectToSuccess() - { - $this->getFeatureResponse('

Hello World

'); - $this->feature->response = new RedirectResponse(new App()); - $this->feature->response->redirect('foo/bar'); - - $this->feature->assertRedirectTo('foo/bar'); - } - - public function testRedirectToSuccessFullURL() - { - $this->getFeatureResponse('

Hello World

'); - $this->feature->response = new RedirectResponse(new App()); - $this->feature->response->redirect('http://foo.com/bar'); - - $this->feature->assertRedirectTo('http://foo.com/bar'); - } - - public function testRedirectToSuccessMixedURL() - { - $this->getFeatureResponse('

Hello World

'); - $this->feature->response = new RedirectResponse(new App()); - $this->feature->response->redirect('bar'); - - $this->feature->assertRedirectTo('http://example.com/index.php/bar'); - } - - public function testAssertStatus() - { - $this->getFeatureResponse('

Hello World

', ['statusCode' => 201]); - - $this->feature->assertStatus(201); - } - - /** - * @dataProvider statusCodeProvider - */ - public function testAssertIsOK(int $code, bool $isOk) - { - $this->getFeatureResponse('

Hello World

', ['statusCode' => $code]); - - if ($isOk) - { - $this->feature->assertOK(); - } - else - { - $this->feature->assertNotOK(); - } - } - - public function testAssertSessionHas() - { - $_SESSION['foo'] = 'bar'; - $this->getFeatureResponse('

Hello World

'); - - $this->feature->assertSessionHas('foo'); - $this->feature->assertSessionHas('foo', 'bar'); - } - - public function testAssertSessionMissing() - { - $_SESSION = []; - $this->getFeatureResponse('

Hello World

'); - - $this->feature->assertSessionMissing('foo'); - } - - public function testAssertHeader() - { - $this->getFeatureResponse('

Hello World

', [], ['foo' => 'bar']); - - $this->feature->assertHeader('foo'); - $this->feature->assertHeader('foo', 'bar'); - } - - public function testAssertHeaderMissing() - { - $this->getFeatureResponse('

Hello World

', [], ['foo' => 'bar']); - - $this->feature->assertHeader('foo'); - $this->feature->assertHeaderMissing('banana'); - } - - public function testAssertCookie() - { - $this->getFeatureResponse('

Hello World

'); - - $this->response = $this->response->setCookie('foo', 'bar'); - - $this->feature->assertCookie('foo'); - $this->feature->assertCookie('foo', 'bar'); - } - - public function testAssertCookieMissing() - { - $this->getFeatureResponse('

Hello World

'); - - $this->response = $this->response->setCookie('foo', 'bar'); - - $this->feature->assertCookieMissing('bar'); - } - - public function testAssertCookieExpired() - { - $this->getFeatureResponse('

Hello World

'); - - $this->response = $this->response->setCookie('foo', 'bar', strtotime('-1 day')); - - $this->feature->assertCookieExpired('foo'); - } - - public function testGetJSON() - { - $this->getFeatureResponse(['foo' => 'bar']); - $formatter = Services::format()->getFormatter('application/json'); - - $this->assertEquals($formatter->format(['foo' => 'bar']), $this->feature->getJSON()); - } - - public function testEmptyJSON() - { - $this->getFeatureResponse('

Hello World

'); - $this->response->setJSON('', true); - - // this should be "" - json_encode(''); - $this->assertEquals('""', $this->feature->getJSON()); - } - - public function testFalseJSON() - { - $this->getFeatureResponse('

Hello World

'); - $this->response->setJSON(false, true); - - // this should be FALSE - json_encode(false) - $this->assertEquals('false', $this->feature->getJSON()); - } - - public function testTrueJSON() - { - $this->getFeatureResponse('

Hello World

'); - $this->response->setJSON(true, true); - - // this should be TRUE - json_encode(true) - $this->assertEquals('true', $this->feature->getJSON()); - } - - public function testInvalidJSON() - { - $tmp = ' test " case '; - $this->getFeatureResponse('

Hello World

'); - $this->response->setBody($tmp); - - // this should be FALSE - invalid JSON - will see if this is working that way ;-) - $this->assertFalse($this->response->getBody() === $this->feature->getJSON()); - } - - public function testGetXML() - { - $this->getFeatureResponse(['foo' => 'bar']); - $formatter = Services::format()->getFormatter('application/xml'); - - $this->assertEquals($formatter->format(['foo' => 'bar']), $this->feature->getXML()); - } - - public function testJsonFragment() - { - $this->getFeatureResponse([ - 'config' => [ - 'key-a', - 'key-b', - ], - ]); - - $this->feature->assertJSONFragment(['config' => ['key-a']]); - $this->feature->assertJSONFragment(['config' => ['key-a']], true); - } - - public function testAssertJSONFragmentFollowingAssertArraySubset() - { - $this->getFeatureResponse([ - 'config' => '124', - ]); - - $this->feature->assertJSONFragment(['config' => 124]); // must fail on strict - $this->feature->assertJSONFragment(['config' => '124'], true); - } - - public function testJsonExact() - { - $data = [ - 'config' => [ - 'key-a', - 'key-b', - ], - ]; - - $this->getFeatureResponse($data); - - $this->feature->assertJSONExact($data); - } - - public function testJsonExactString() - { - $data = [ - 'config' => [ - 'key-a', - 'key-b', - ], - ]; - - $this->getFeatureResponse($data); - $formatter = Services::format()->getFormatter('application/json'); - - $this->feature->assertJSONExact($formatter->format($data)); - } - - protected function getFeatureResponse($body = null, array $responseOptions = [], array $headers = []) - { - $this->response = new Response(new App()); - $this->response->setBody($body); - - foreach ($responseOptions as $key => $value) - { - $method = 'set' . ucfirst($key); - - if (method_exists($this->response, $method)) - { - $this->response = $this->response->$method($value); - } - } - - foreach ($headers as $key => $value) - { - $this->response = $this->response->setHeader($key, $value); - } - - $this->feature = new FeatureResponse($this->response); - } -} diff --git a/tests/system/Test/TestResponseTest.php b/tests/system/Test/TestResponseTest.php new file mode 100644 index 000000000000..24ef181ebd80 --- /dev/null +++ b/tests/system/Test/TestResponseTest.php @@ -0,0 +1,435 @@ +getTestResponse('Hello World'); + $this->response->setStatusCode($code); + + $this->assertEquals($isOk, $this->testResponse->isOK()); + } + + /** + * Provides status codes and their expected "OK" + */ + public function statusCodeProvider(): array + { + return [ + [ + 100, + false, + ], + [ + 200, + true, + ], + [ + 201, + true, + ], + [ + 300, + true, + ], // Redirects are acceptable if the body is empty + [ + 301, + true, + ], + [ + 400, + false, + ], + [ + 401, + false, + ], + [ + 599, + false, + ], + ]; + } + + public function testIsOKEmpty() + { + $this->getTestResponse('Hi there'); + $this->response->setStatusCode(200); + $this->response->setBody(''); + + $this->assertFalse($this->testResponse->isOK()); + } + + public function testAssertSee() + { + $this->getTestResponse('

Hello World

'); + + $this->testResponse->assertSee('Hello'); + $this->testResponse->assertSee('World', 'h1'); + } + + public function testAssertDontSee() + { + $this->getTestResponse('

Hello World

'); + + $this->testResponse->assertDontSee('Worlds'); + $this->testResponse->assertDontSee('World', 'h2'); + } + + public function testAssertSeeElement() + { + $this->getTestResponse('

Hello World

'); + + $this->testResponse->assertSeeElement('h1'); + $this->testResponse->assertSeeElement('span'); + $this->testResponse->assertSeeElement('h1.header'); + } + + public function testAssertDontSeeElement() + { + $this->getTestResponse('

Hello World

'); + + $this->testResponse->assertDontSeeElement('h2'); + $this->testResponse->assertDontSeeElement('.span'); + $this->testResponse->assertDontSeeElement('h1.para'); + } + + public function testAssertSeeLink() + { + $this->getTestResponse('

Hello World

'); + + $this->testResponse->assertSeeElement('h1'); + $this->testResponse->assertSeeLink('Hello'); + } + + public function testAssertSeeInField() + { + $this->getTestResponse(''); + + $this->testResponse->assertSeeInField('user[name]', 'Foobar'); + } + + public function testAssertRedirectFail() + { + $this->getTestResponse('

Hello World

'); + + $this->assertFalse($this->testResponse->response() instanceof RedirectResponse); + $this->assertFalse($this->testResponse->isRedirect()); + $this->testResponse->assertNotRedirect(); + } + + public function testAssertRedirectSuccess() + { + $this->getTestResponse('

Hello World

'); + $this->testResponse->setResponse(new RedirectResponse(new App())); + + $this->assertTrue($this->testResponse->response() instanceof RedirectResponse); + $this->assertTrue($this->testResponse->isRedirect()); + $this->testResponse->assertRedirect(); + } + + public function testAssertRedirectSuccessWithoutRedirectResponse() + { + $this->getTestResponse('

Hello World

'); + $this->response->redirect('foo/bar'); + + $this->assertFalse($this->testResponse->response() instanceof RedirectResponse); + $this->assertTrue($this->testResponse->isRedirect()); + $this->testResponse->assertRedirect(); + $this->assertEquals('foo/bar', $this->testResponse->getRedirectUrl()); + } + + public function testGetRedirectUrlReturnsUrl() + { + $this->getTestResponse('

Hello World

'); + $this->testResponse->setResponse(new RedirectResponse(new App())); + $this->testResponse->response()->redirect('foo/bar'); + + $this->assertEquals('foo/bar', $this->testResponse->getRedirectUrl()); + } + + public function testGetRedirectUrlReturnsNull() + { + $this->getTestResponse('

Hello World

'); + + $this->assertNull($this->testResponse->getRedirectUrl()); + } + + public function testRedirectToSuccess() + { + $this->getTestResponse('

Hello World

'); + $this->testResponse->setResponse(new RedirectResponse(new App())); + $this->testResponse->response()->redirect('foo/bar'); + + $this->testResponse->assertRedirectTo('foo/bar'); + } + + public function testRedirectToSuccessFullURL() + { + $this->getTestResponse('

Hello World

'); + $this->testResponse->setResponse(new RedirectResponse(new App())); + $this->testResponse->response()->redirect('http://foo.com/bar'); + + $this->testResponse->assertRedirectTo('http://foo.com/bar'); + } + + public function testRedirectToSuccessMixedURL() + { + $this->getTestResponse('

Hello World

'); + $this->testResponse->setResponse(new RedirectResponse(new App())); + $this->testResponse->response()->redirect('bar'); + + $this->testResponse->assertRedirectTo('http://example.com/index.php/bar'); + } + + public function testAssertStatus() + { + $this->getTestResponse('

Hello World

', ['statusCode' => 201]); + + $this->testResponse->assertStatus(201); + } + + /** + * @dataProvider statusCodeProvider + */ + public function testAssertIsOK(int $code, bool $isOk) + { + $this->getTestResponse('

Hello World

', ['statusCode' => $code]); + + if ($isOk) + { + $this->testResponse->assertOK(); + } + else + { + $this->testResponse->assertNotOK(); + } + } + + public function testAssertSessionHas() + { + $_SESSION['foo'] = 'bar'; + $this->getTestResponse('

Hello World

'); + + $this->testResponse->assertSessionHas('foo'); + $this->testResponse->assertSessionHas('foo', 'bar'); + } + + public function testAssertSessionMissing() + { + $_SESSION = []; + $this->getTestResponse('

Hello World

'); + + $this->testResponse->assertSessionMissing('foo'); + } + + public function testAssertHeader() + { + $this->getTestResponse('

Hello World

', [], ['foo' => 'bar']); + + $this->testResponse->assertHeader('foo'); + $this->testResponse->assertHeader('foo', 'bar'); + } + + public function testAssertHeaderMissing() + { + $this->getTestResponse('

Hello World

', [], ['foo' => 'bar']); + + $this->testResponse->assertHeader('foo'); + $this->testResponse->assertHeaderMissing('banana'); + } + + public function testAssertCookie() + { + $this->getTestResponse('

Hello World

'); + + $this->response = $this->response->setCookie('foo', 'bar'); + + $this->testResponse->assertCookie('foo'); + $this->testResponse->assertCookie('foo', 'bar'); + } + + public function testAssertCookieMissing() + { + $this->getTestResponse('

Hello World

'); + + $this->response = $this->response->setCookie('foo', 'bar'); + + $this->testResponse->assertCookieMissing('bar'); + } + + public function testAssertCookieExpired() + { + $this->getTestResponse('

Hello World

'); + + $this->response = $this->response->setCookie('foo', 'bar', strtotime('-1 day')); + + $this->testResponse->assertCookieExpired('foo'); + } + + public function testGetJSON() + { + $this->getTestResponse(['foo' => 'bar']); + $formatter = Services::format()->getFormatter('application/json'); + + $this->assertEquals($formatter->format(['foo' => 'bar']), $this->testResponse->getJSON()); + } + + public function testEmptyJSON() + { + $this->getTestResponse('

Hello World

'); + $this->response->setJSON('', true); + + // this should be "" - json_encode(''); + $this->assertEquals('""', $this->testResponse->getJSON()); + } + + public function testFalseJSON() + { + $this->getTestResponse('

Hello World

'); + $this->response->setJSON(false, true); + + // this should be FALSE - json_encode(false) + $this->assertEquals('false', $this->testResponse->getJSON()); + } + + public function testTrueJSON() + { + $this->getTestResponse('

Hello World

'); + $this->response->setJSON(true, true); + + // this should be TRUE - json_encode(true) + $this->assertEquals('true', $this->testResponse->getJSON()); + } + + public function testInvalidJSON() + { + $tmp = ' test " case '; + $this->getTestResponse('

Hello World

'); + $this->response->setBody($tmp); + + // this should be FALSE - invalid JSON - will see if this is working that way ;-) + $this->assertFalse($this->response->getBody() === $this->testResponse->getJSON()); + } + + public function testGetXML() + { + $this->getTestResponse(['foo' => 'bar']); + $formatter = Services::format()->getFormatter('application/xml'); + + $this->assertEquals($formatter->format(['foo' => 'bar']), $this->testResponse->getXML()); + } + + public function testJsonFragment() + { + $this->getTestResponse([ + 'config' => [ + 'key-a', + 'key-b', + ], + ]); + + $this->testResponse->assertJSONFragment(['config' => ['key-a']]); + $this->testResponse->assertJSONFragment(['config' => ['key-a']], true); + } + + public function testAssertJSONFragmentFollowingAssertArraySubset() + { + $this->getTestResponse([ + 'config' => '124', + ]); + + $this->testResponse->assertJSONFragment(['config' => 124]); // must fail on strict + $this->testResponse->assertJSONFragment(['config' => '124'], true); + } + + public function testAssertJSONFragmentFailsGracefullyWhenNotGivenJson() + { + $this->getTestResponse('

Hello World!

'); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Response does not have valid json'); + + $this->testResponse->assertJSONFragment(['foo' => 'bar']); + } + + public function testJsonExact() + { + $data = [ + 'config' => [ + 'key-a', + 'key-b', + ], + ]; + + $this->getTestResponse($data); + + $this->testResponse->assertJSONExact($data); + } + + public function testJsonExactString() + { + $data = [ + 'config' => [ + 'key-a', + 'key-b', + ], + ]; + + $this->getTestResponse($data); + $formatter = Services::format()->getFormatter('application/json'); + + $this->testResponse->assertJSONExact($formatter->format($data)); + } + + protected function getTestResponse($body = null, array $responseOptions = [], array $headers = []) + { + $this->response = new Response(new App()); + $this->response->setBody($body); + + foreach ($responseOptions as $key => $value) + { + $method = 'set' . ucfirst($key); + + if (method_exists($this->response, $method)) + { + $this->response = $this->response->$method($value); + } + } + + foreach ($headers as $key => $value) + { + $this->response = $this->response->setHeader($key, $value); + } + + $this->testResponse = new TestResponse($this->response); + } +}