test add insights page and correlation API tests

Cover /insights page rendering (canvases, nav, breadcrumbs, graph controls, default timeframe) and /api/correlation endpoint (valid pair, no overlap, invalid probe, missing params). Update homepage test to verify Insights nav and quick link.

Commit
6500c7a70ed7720382e4c29a73f3f10f8633957e
Author
GPT-5 medium <codex@openai.com>
Author date
Committer
GPT-5 medium <codex@openai.com>
Committer date
Changed files
roles/dashboard/t/00-homepage.t
index 54005048..1255934e 100644..100644
@@ -14,6 +14,7 @@
14 14 ->element_exists('body nav.navbar + main')
15 15 ->text_is( 'a.navbar-brand[href="/"]', 'FAPG' )
16 16 ->text_is( '.navbar-nav a.nav-link[href="/probes"]', 'Probes' )
17 Added: ->text_is( '.navbar-nav a.nav-link[href="/insights"]', 'Insights' )
17 18 ->text_is( '.navbar-nav a.nav-link[href="/downloads"]', 'Downloads' )
18 19 ->element_exists_not('.navbar-nav a.nav-link.active')
19 20 ->element_exists(
@@ -21,6 +22,7 @@
21 22 ->element_exists_not('nav[aria-label="Breadcrumb"]')
22 23 ->element_exists('h1.display-5')
23 24 ->element_exists('nav[aria-label="Quick links"] a[href="/probes"]')
25 Added: ->element_exists('nav[aria-label="Quick links"] a[href="/insights"]')
24 26 ->element_exists('nav[aria-label="Quick links"] a[href="/status"]')
25 27 ->element_exists('nav[aria-label="Quick links"] a[href="/downloads"]')
26 28 ->element_exists(
roles/dashboard/t/08-insights.t
index 00000000..83546f88 000000..100644
@@ -0,0 +1,65 @@
1 Added: use Mojo::Base -strict;
2 Added:
3 Added: use Test2::V0;
4 Added:
5 Added: use FindBin;
6 Added: use lib "${FindBin::Bin}/../lib/";
7 Added: use lib "${FindBin::Bin}/lib/";
8 Added: use Dashboard::Test qw(test_app test_empty_app);
9 Added:
10 Added: my $t = test_app();
11 Added:
12 Added: subtest 'insights page renders' => sub {
13 Added: $t->get_ok('/insights')
14 Added: ->status_is(200)
15 Added: ->text_is('title', 'FAPG DAQ Insights')
16 Added: ->element_exists('nav[aria-label="Breadcrumb"]')
17 Added: ->text_like('.breadcrumb-item.active span', qr/Insights/)
18 Added: ->element_exists('.navbar-nav a.nav-link.active[href="/insights"]')
19 Added: ->element_exists('canvas#chart-overlay-do-orp')
20 Added: ->element_exists('canvas#chart-overlay-all')
21 Added: ->element_exists('[data-default-timeframe="month"]');
22 Added: };
23 Added:
24 Added: subtest 'insights page has graph controls' => sub {
25 Added: $t->get_ok('/insights')
26 Added: ->status_is(200)
27 Added: ->element_exists('.graph-control-scroll')
28 Added: ->element_exists('button[data-timeframe="hour"]')
29 Added: ->element_exists('button[data-timeframe="month"]');
30 Added: };
31 Added:
32 Added: subtest 'correlation API returns points' => sub {
33 Added: $t->get_ok('/api/correlation/ph/do?timeframe=year&range=1')
34 Added: ->status_is(200)
35 Added: ->json_has('/points')
36 Added: ->json_is('/points/0/x' => '7.12')
37 Added: ->json_is('/points/0/y' => '8.34');
38 Added: };
39 Added:
40 Added: subtest 'correlation API with no overlapping data' => sub {
41 Added: $t->get_ok('/api/correlation/ph/ec?timeframe=year&range=1')
42 Added: ->status_is(200)
43 Added: ->json_has('/points')
44 Added: ->json_is('/points' => []);
45 Added: };
46 Added:
47 Added: subtest 'correlation API with invalid probe' => sub {
48 Added: $t->get_ok('/api/correlation/nope/do?timeframe=day&range=1')
49 Added: ->status_is(404);
50 Added: };
51 Added:
52 Added: subtest 'correlation API requires timeframe' => sub {
53 Added: $t->get_ok('/api/correlation/ph/do')
54 Added: ->status_is(200)
55 Added: ->json_has('/points');
56 Added: };
57 Added:
58 Added: subtest 'empty database insights page' => sub {
59 Added: my $empty = test_empty_app();
60 Added: $empty->get_ok('/insights')
61 Added: ->status_is(200)
62 Added: ->element_exists('canvas#chart-overlay-do-orp');
63 Added: };
64 Added:
65 Added: done_testing;