Skip to content

Commit 9487c09

Browse files
committed
tests: add smoke, ajax profiler subscriber and transcript happy path test
1 parent f6d1e5a commit 9487c09

File tree

8 files changed

+323
-15
lines changed

8 files changed

+323
-15
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ phpstan.neon
2727
###< phpunit/phpunit ###
2828

2929
chromadb
30+
coverage

Diff for: src/ProfilerSubscriber.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44

55
namespace App;
66

7+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
78
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
89
use Symfony\Component\HttpKernel\Event\ResponseEvent;
9-
use Symfony\Component\HttpKernel\KernelInterface;
1010

1111
/**
1212
* Can be deleted with Symfony 7.3, see https://github.com/symfony/symfony/pull/59123.
1313
*/
1414
final class ProfilerSubscriber implements EventSubscriberInterface
1515
{
1616
public function __construct(
17-
private KernelInterface $kernel,
17+
#[Autowire('kernel.debug')]
18+
private readonly bool $debug,
1819
) {
1920
}
2021

@@ -27,7 +28,7 @@ public static function getSubscribedEvents(): array
2728

2829
public function onKernelResponse(ResponseEvent $event): void
2930
{
30-
if (!$this->kernel->isDebug()) {
31+
if (!$this->debug && !$event->isMainRequest()) {
3132
return;
3233
}
3334

Diff for: templates/index.html.twig

+21-12
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@
2323
<p class="card-text">Retrieval Augmented Generation based on Symfony's blog dumped to a vector store.</p>
2424
<a href="{{ path('rag') }}" class="btn btn-outline-dark d-block">Try RAG Chat Bot</a>
2525
</div>
26-
<div class="card-footer">
27-
{{ ux_icon('solar:code-linear', { height: '20px', width: '20px' }) }}
28-
<a href="{{ path('_profiler_open_file', { file: 'src/Chat/Rag.php', line: 14 }) }}">See Implementation</a>
29-
</div>
26+
{# Profiler route only available in dev #}
27+
{% if 'dev' == app.environment %}
28+
<div class="card-footer">
29+
{{ ux_icon('solar:code-linear', { height: '20px', width: '20px' }) }}
30+
<a href="{{ path('_profiler_open_file', { file: 'src/Chat/Rag.php', line: 14 }) }}">See Implementation</a>
31+
</div>
32+
{% endif %}
3033
</div>
3134
</div>
3235
<div class="col-md-4">
@@ -39,10 +42,13 @@
3942
<p class="card-text">Question answering initialized with transcript of YouTube video.</p>
4043
<a href="{{ path('youtube') }}" class="btn btn-outline-dark d-block">Try YouTube Transcript Bot</a>
4144
</div>
42-
<div class="card-footer">
43-
{{ ux_icon('solar:code-linear', { height: '20px', width: '20px' }) }}
44-
<a href="{{ path('_profiler_open_file', { file: 'src/Chat/YouTube.php', line: 15 }) }}">See Implementation</a>
45-
</div>
45+
{# Profiler route only available in dev #}
46+
{% if 'dev' == app.environment %}
47+
<div class="card-footer">
48+
{{ ux_icon('solar:code-linear', { height: '20px', width: '20px' }) }}
49+
<a href="{{ path('_profiler_open_file', { file: 'src/Chat/YouTube.php', line: 15 }) }}">See Implementation</a>
50+
</div>
51+
{% endif %}
4652
</div>
4753
</div>
4854
<div class="col-md-4">
@@ -55,10 +61,13 @@
5561
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
5662
<a href="{{ path('wikipedia') }}" class="btn btn-outline-dark d-block">Try Wikipedia Research Bot</a>
5763
</div>
58-
<div class="card-footer">
59-
{{ ux_icon('solar:code-linear', { height: '20px', width: '20px' }) }}
60-
<a href="{{ path('_profiler_open_file', { file: 'src/Chat/Wikipedia.php', line: 14 }) }}">See Implementation</a>
61-
</div>
64+
{# Profiler route only available in dev #}
65+
{% if 'dev' == app.environment %}
66+
<div class="card-footer">
67+
{{ ux_icon('solar:code-linear', { height: '20px', width: '20px' }) }}
68+
<a href="{{ path('_profiler_open_file', { file: 'src/Chat/Wikipedia.php', line: 14 }) }}">See Implementation</a>
69+
</div>
70+
{% endif %}
6271
</div>
6372
</div>
6473
</div>

Diff for: tests/ProfilerSubscriberTest.php

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Tests;
6+
7+
use App\Kernel;
8+
use App\ProfilerSubscriber;
9+
use PHPUnit\Framework\Attributes\CoversClass;
10+
use PHPUnit\Framework\Attributes\DataProvider;
11+
use PHPUnit\Framework\TestCase;
12+
use Symfony\Component\HttpFoundation\Request;
13+
use Symfony\Component\HttpFoundation\Response;
14+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
15+
use Symfony\Component\HttpKernel\HttpKernelInterface;
16+
17+
#[CoversClass(ProfilerSubscriber::class)]
18+
final class ProfilerSubscriberTest extends TestCase
19+
{
20+
#[DataProvider('provideInvalidRequests')]
21+
public function testAjaxReplaceHeaderNotSet(int $requestType, bool $debug, bool $isXmlHttpRequest): void
22+
{
23+
$request = new Request();
24+
if ($isXmlHttpRequest) {
25+
$request->headers->set('X-Requested-With', 'XMLHttpRequest');
26+
}
27+
28+
$response = new Response();
29+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), $requestType, $response);
30+
31+
$listener = new ProfilerSubscriber($debug);
32+
$listener->onKernelResponse($event);
33+
34+
$this->assertFalse($response->headers->has('Symfony-Debug-Toolbar-Replace'));
35+
}
36+
37+
/**
38+
* @return iterable<array{int, bool, bool}>
39+
*/
40+
public static function provideInvalidRequests(): iterable
41+
{
42+
yield 'sub request, not debug, not XHR' => [HttpKernelInterface::SUB_REQUEST, false, false];
43+
yield 'sub request, not debug, XHR' => [HttpKernelInterface::SUB_REQUEST, false, true];
44+
yield 'sub request, debug, XHR' => [HttpKernelInterface::SUB_REQUEST, true, true];
45+
yield 'main request, not debug, not XHR' => [HttpKernelInterface::MAIN_REQUEST, false, false];
46+
yield 'main request, debug, not XHR' => [HttpKernelInterface::MAIN_REQUEST, true, false];
47+
}
48+
49+
public function testAjaxReplaceHeaderOnEnabledAndXHR(): void
50+
{
51+
$request = new Request();
52+
$request->headers->set('X-Requested-With', 'XMLHttpRequest');
53+
$response = new Response();
54+
$event = new ResponseEvent($this->createMock(Kernel::class), $request, HttpKernelInterface::MAIN_REQUEST, $response);
55+
56+
$listener = new ProfilerSubscriber(true);
57+
$listener->onKernelResponse($event);
58+
59+
$this->assertEquals('1', $response->headers->get('Symfony-Debug-Toolbar-Replace'));
60+
}
61+
}

Diff for: tests/SmokeTest.php

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Tests;
6+
7+
use PHPUnit\Framework\Attributes\CoversNothing;
8+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
9+
use Symfony\UX\LiveComponent\Test\InteractsWithLiveComponents;
10+
11+
#[CoversNothing]
12+
final class SmokeTest extends WebTestCase
13+
{
14+
use InteractsWithLiveComponents;
15+
16+
public function testIndex(): void
17+
{
18+
$client = static::createClient();
19+
$client->request('GET', '/');
20+
21+
self::assertResponseIsSuccessful();
22+
self::assertSelectorTextContains('h1', 'Welcome');
23+
self::assertSelectorCount(3, '.card');
24+
}
25+
26+
public function testRag(): void
27+
{
28+
$client = static::createClient();
29+
$client->request('GET', '/rag');
30+
31+
self::assertResponseIsSuccessful();
32+
self::assertSelectorTextContains('h4', 'Retrieval Augmented Generation with the Symfony blog');
33+
self::assertSelectorCount(1, '#chat-submit');
34+
}
35+
36+
public function testYouTube(): void
37+
{
38+
$client = static::createClient();
39+
$client->request('GET', '/youtube');
40+
41+
self::assertResponseIsSuccessful();
42+
self::assertSelectorTextContains('h4', 'Chat about a YouTube Video');
43+
self::assertSelectorCount(1, '#chat-submit');
44+
}
45+
46+
public function testWikipedia(): void
47+
{
48+
$client = static::createClient();
49+
$client->request('GET', '/wikipedia');
50+
51+
self::assertResponseIsSuccessful();
52+
self::assertSelectorTextContains('h4', 'Wikipedia Research');
53+
self::assertSelectorCount(1, '#chat-submit');
54+
}
55+
}

Diff for: tests/YouTube/TranscriptFetcherTest.php

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Tests\YouTube;
6+
7+
use App\YouTube\TranscriptFetcher;
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\TestCase;
10+
use Symfony\Component\HttpClient\MockHttpClient;
11+
use Symfony\Component\HttpClient\Response\MockResponse;
12+
13+
#[CoversClass(TranscriptFetcher::class), ]
14+
final class TranscriptFetcherTest extends TestCase
15+
{
16+
public function testFetchTranscript(): void
17+
{
18+
$videoResponse = MockResponse::fromFile(__DIR__.'/fixtures/video.html');
19+
$transcriptResponse = MockResponse::fromFile(__DIR__.'/fixtures/transcript.xml');
20+
$mockClient = new MockHttpClient([$videoResponse, $transcriptResponse]);
21+
22+
$fetcher = new TranscriptFetcher($mockClient);
23+
$transcript = $fetcher->fetchTranscript('6uXW-ulpj0s');
24+
25+
self::assertStringContainsString('symphony is a PHP framework', $transcript);
26+
}
27+
}

Diff for: tests/YouTube/fixtures/transcript.xml

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<transcript>
3+
<text start="2.12" dur="5.679">symphony is a PHP framework and this is</text>
4+
<text start="5.22" dur="5.1">an advantage why because almost 80</text>
5+
<text start="7.799" dur="5.88">percent of all websites in the internet</text>
6+
<text start="10.32" dur="5.22">use PHP as a server-side language eighty</text>
7+
<text start="13.679" dur="4.141">percent this does mean that wherever you</text>
8+
<text start="15.54" dur="4.68">are right now there is someone near you</text>
9+
<text start="17.82" dur="4.86">probably searching to hire a PHP</text>
10+
<text start="20.22" dur="4.799">developer Symphony will not only teach</text>
11+
<text start="22.68" dur="4.859">you more PHP but also will teach you</text>
12+
<text start="25.019" dur="4.141">different software architecture patterns</text>
13+
<text start="27.539" dur="4.201">that you can use in different languages</text>
14+
<text start="29.16" dur="4.44">software architecture patterns are so</text>
15+
<text start="31.74" dur="3.12">much important in your skill sets</text>
16+
<text start="33.6" dur="4.02">because they allow you to understand</text>
17+
<text start="34.86" dur="4.92">complex software when you only know the</text>
18+
<text start="37.62" dur="3.72">architecture that was used in that</text>
19+
<text start="39.78" dur="3.959">software please let me tell you a story</text>
20+
<text start="41.34" dur="4.02">that happened to me I had a PHP laravel</text>
21+
<text start="43.739" dur="4.861">interview in a company and the interview</text>
22+
<text start="45.36" dur="5.219">was successful so they invite me for a</text>
23+
<text start="48.6" dur="4.04">test work day and that test work day</text>
24+
<text start="50.579" dur="4.62">they asked me to build an application</text>
25+
<text start="52.64" dur="4.18">using.net and Seashore they told me we</text>
26+
<text start="55.199" dur="3.84">know you didn&amp;#39;t had any previous</text>
27+
<text start="56.82" dur="4.32">experience using C sharp but we want to</text>
28+
<text start="59.039" dur="3.721">see how you can get along with different</text>
29+
<text start="61.14" dur="4.32">programming language I was able to</text>
30+
<text start="62.76" dur="5.46">Google and found out that the dotnet</text>
31+
<text start="65.46" dur="5.04">framework is an MVC architect framework</text>
32+
<text start="68.22" dur="4.32">the same framework is used in Symphony</text>
33+
<text start="70.5" dur="4.32">and Bam I built the application in</text>
34+
<text start="72.54" dur="4.8">c-sharp and I got a wonderful job offer</text>
35+
<text start="74.82" dur="4.979">so yes learning Symphony will teach you</text>
36+
<text start="77.34" dur="5.16">software architecture patterns that are</text>
37+
<text start="79.799" dur="5.281">essential in your skill set symphony is</text>
38+
<text start="82.5" dur="4.979">a full stack framework that mean you can</text>
39+
<text start="85.08" dur="4.5">create deploy ready application you will</text>
40+
<text start="87.479" dur="5.341">be using front-end Technologies like</text>
41+
<text start="89.58" dur="6.24">HTML CSS and JavaScript and back-end or</text>
42+
<text start="92.82" dur="5.52">server Technologies like PHP databases</text>
43+
<text start="95.82" dur="5.1">that will process the user request all</text>
44+
<text start="98.34" dur="5.279">in one place Symphony can integrate</text>
45+
<text start="100.92" dur="5.699">easily with modern JavaScript Frameworks</text>
46+
<text start="103.619" dur="5.761">like vue.js or react.js or even you can</text>
47+
<text start="106.619" dur="5.161">set up different databases like MySQL</text>
48+
<text start="109.38" dur="4.98">postgres or whatever you want Symphony</text>
49+
<text start="111.78" dur="4.799">has a CLI tool that can help build and</text>
50+
<text start="114.36" dur="4.92">speak and debug your application and is</text>
51+
<text start="116.579" dur="5.04">one of the most advanced code generation</text>
52+
<text start="119.28" dur="4.14">tool in the planner is relate in the</text>
53+
<text start="121.619" dur="4.921">comment if you know anything that is</text>
54+
<text start="123.42" dur="5.039">good finally documentation Symphony has</text>
55+
<text start="126.54" dur="4.74">good documentation that will make it</text>
56+
<text start="128.459" dur="5.761">easy for newcomers to learn and have fun</text>
57+
<text start="131.28" dur="4.86">with the technology so that was my 6y2</text>
58+
<text start="134.22" dur="3.54">simple normally I don&amp;#39;t do this but</text>
59+
<text start="136.14" dur="3.179">right now go and check the description</text>
60+
<text start="137.76" dur="3.3">see the comment and write me what you</text>
61+
<text start="139.319" dur="3.301">think like the video and subscribe to my</text>
62+
<text start="141.06" dur="3.06">channel then go to the channel check the</text>
63+
<text start="142.62" dur="2.759">videos and like each one of them and</text>
64+
<text start="144.12" dur="4.759">comment again and come back to this</text>
65+
<text start="145.379" dur="3.5">video and watch it again thank you</text>
66+
</transcript>

0 commit comments

Comments
 (0)