Acme-CPANModulesBundle-Import-PerlDancerAdvent-2018

 view release on metacpan or  search on metacpan

devdata/http_advent.perldancer.org_2018_20  view on Meta::CPAN

use feature ':5.10';</pre>

<p>but saves a lot of typing.
Next we load the necessary testing libraries.
Then make an instance of <code>Test::Mojo</code> composed with the <code>PSGI</code> role and make a new instance that points to the app we want to test.</p>
<pre class="prettyprint">use Test::More;
use Test::Mojo;
my $t = Test::Mojo-&gt;with_roles('+PSGI')-&gt;new('app.psgi');</pre>

<p>With that out of the way, on to the tests!
In our first tests we'll focus on the plain text endpoint <code>/text</code>.</p>
<pre class="prettyprint">$t-&gt;get_ok('/text')
  -&gt;status_is(200)
  -&gt;content_type_like(qr[text/plain])
  -&gt;content_is('hello world');</pre>

<p>Each of the above method calls is a test.
The first, <code>get_ok</code>, builds a transaction and requests the resource.
Since the url is relative, it is handled by the app (if we wanted we could request and web resource too using a fully qualified url).
The transaction is stored in the tester object (<code>$t</code>) and all following tests will check it until it is replaced by the next request.</p>
<p>The remaining tests are reasonably self-explanatory, we check that the response status was 200, that we got a content type header that we expected and that its content is as we expect.
The content has already been utf-8 decoded, and the script has implicitly <code>use utf8</code>, so if you expected unicode, you can compare them easily.
The tests return the tester object so chaining is possible, making for visually clean sets of tests.</p>
<p>The next test is similar but this one uses the standard <a href="https://mojolicious.org/perldoc/Mojo/UserAgent">Mojo::UserAgent</a> style request generation to build a query string naming Santa for our greeting.
The tests are all the same except of course that it checks that the content greets Santa.</p>
<pre class="prettyprint">$t-&gt;get_ok('/text', form =&gt; { name =&gt; 'santa' })
  -&gt;status_is(200)
  -&gt;content_type_like(qr[text/plain])
  -&gt;content_is('hello santa');</pre>

<p>Moving on we request the data endpoint, both without and with a query, then similarly test the responses.</p>
<pre class="prettyprint">$t-&gt;get_ok('/data')
  -&gt;status_is(200)
  -&gt;content_type_like(qr[application/json])
  -&gt;json_is('/hello' =&gt; 'world');

$t-&gt;post_ok('/data' =&gt; form =&gt; { name =&gt; 'rudolph' })
  -&gt;status_is(200)
  -&gt;content_type_like(qr[application/json])
  -&gt;json_is('/hello' =&gt; 'rudolph');</pre>

<p>You can see we use the <code>json_is</code> method to test the responses.
Now, the test could have been <code>-&gt;json_is({hello =&gt; 'rudolph'})</code> if had wanted to test the entire document.
By passing a <a href="https://mojolicious.org/perldoc/Mojo/JSON/Pointer">JSON Pointer</a> I can inspect only the portions I'm interested in.</p>
<p>Finally I'm going to test the HTML endpoint.
As I said above, the result resists easy parsing.
We want to test the <code>dd</code> tag contents that follows a <code>dt</code> tag with the id <code>hello</code>, all inside a <code>dl</code> tag with the id <code>data</code>.
That would be a monstrous regexp (hehe).
However it is a piece of cake using <a href="https://mojolicious.org/perldoc/Mojo/DOM/CSS">CSS Selectors</a>.</p>
<pre class="prettyprint">$t-&gt;get_ok('/html')
  -&gt;status_is(200)
  -&gt;content_type_like(qr[text/html])
  -&gt;text_is('dl#data dt#hello + dd', 'world');

$t-&gt;post_ok('/html' =&gt; form =&gt; { name =&gt; 'grinch' })



( run in 0.341 second using v1.01-cache-2.11-cpan-27979f6cc8f )