From c63c494456566d34013d9c97993ffcb9dcbd771d Mon Sep 17 00:00:00 2001 From: Michael Andreen Date: Mon, 23 Jun 2008 19:23:09 +0200 Subject: [PATCH] Converted the graphs --- NDWeb/Graph.pm | 69 ----------- NDWeb/Image.pm | 50 -------- NDWeb/Pages/Graph.pm | 164 ------------------------- database/group_roles.sql | 3 + lib/NDWeb.pm | 22 +++- lib/NDWeb/Controller/Graphs.pm | 213 +++++++++++++++++++++++++++++++++ root/lib/site/wrapper.tt2 | 15 ++- root/src/graphs/index.tt2 | 8 ++ t/controller_Graphs.t | 10 ++ 9 files changed, 264 insertions(+), 290 deletions(-) delete mode 100644 NDWeb/Graph.pm delete mode 100644 NDWeb/Image.pm delete mode 100644 NDWeb/Pages/Graph.pm create mode 100644 lib/NDWeb/Controller/Graphs.pm create mode 100644 root/src/graphs/index.tt2 create mode 100644 t/controller_Graphs.t diff --git a/NDWeb/Graph.pm b/NDWeb/Graph.pm deleted file mode 100644 index b564fc9..0000000 --- a/NDWeb/Graph.pm +++ /dev/null @@ -1,69 +0,0 @@ -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ - -package NDWeb::Graph; -use strict; -use warnings; -use ND::Include; -use GD::Graph::lines; -require Exporter; - -our @ISA = qw/Exporter/; - -our @EXPORT = qw/graphFromQuery/; - -sub graphFromQuery { - my ($x,$y,$settings,$query,) = @_; - - my %graph_settings = ( - line_width => 1, - y_number_format => sub { prettyValue abs $_[0]}, - legend_placement => 'BL', - #zero_axis => 1, - box_axis => 0, - boxclr => 'black', - axislabelclr => 'black', - ); - - my $fields = $query->{NUM_OF_FIELDS}; - my @fields; - for (my $i = 0; $i < $fields; $i++){ - push @fields,[]; - } - while (my @result = $query->fetchrow){ - for (my $i = 0; $i < $fields; $i++){ - push @{$fields[$i]},$result[$i]; - } - - } - $graph_settings{x_label_skip} = int(1+(scalar @{$fields[0]}) / 6); - - my $graph = GD::Graph::lines->new($x,$y); - $graph->set_legend(@{$query->{NAME}}[1..$fields]) or die $graph->error; - - for my $key (keys %{$settings}){ - $graph_settings{$key} = $settings->{$key}; - } - - $graph->set(%graph_settings); - my $gd = $graph->plot(\@fields) or die $graph->error; - return $gd->png; -} - -1; diff --git a/NDWeb/Image.pm b/NDWeb/Image.pm deleted file mode 100644 index eab37df..0000000 --- a/NDWeb/Image.pm +++ /dev/null @@ -1,50 +0,0 @@ -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ - -package NDWeb::Image; -use strict; -use warnings; - -use base qw/NDWeb::Page/; - - -sub render { - my $self = shift; - - my $img; - eval { - $img = $self->render_body; - }; - if (defined $img){ - if ((my $rc = $self->{R}->meets_conditions) != Apache2::Const::OK){ - $self->{R}->status($rc); - }else{ - $self->{R}->headers_out->set(Content_Length => length $img); - $self->{R}->content_type('image/png'); - $self->{R}->rflush; - binmode STDOUT; - print $img; - } - }elsif(defined $@){ - $self->{R}->content_type('text/plain'); - print $@; - } -}; - -1; diff --git a/NDWeb/Pages/Graph.pm b/NDWeb/Pages/Graph.pm deleted file mode 100644 index a8530e0..0000000 --- a/NDWeb/Pages/Graph.pm +++ /dev/null @@ -1,164 +0,0 @@ -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ - -package NDWeb::Pages::Graph; -use strict; -use warnings FATAL => 'all'; -use ND::Include; -use NDWeb::Graph; -use DBI qw(:sql_types); -use DBD::Pg qw(:pg_types); - - -use base qw/NDWeb::Image/; - -$NDWeb::Page::PAGES{graph} = 'NDWeb::Pages::Graph'; - -sub render_body { - my $self = shift; - my $DBH = $self->{DBH}; - - my %graph_settings = ( - y_number_format => sub { prettyValue abs $_[0]}, - y1_label => 'size', - y2_label => 'rest', - ); - - my ($tick) = $DBH->selectrow_array(q{SELECT max(tick) from planet_stats}); - my %req; - my $type; - if ($self->{URI} =~ m{^/\w+/(stats|ranks)/(.*)}){ - $type = $1; - if ($2 =~ m{(\d+)(?: |:)(\d+)(?:(?: |:)(\d+))?$}){ - $req{x} = $1; - $req{y} = $2; - $req{z} = $3; - if (defined $3){ - ($req{id}) = $DBH->selectrow_array(q{SELECT planetid($1,$2,$3,$4)},undef,$1,$2,$3,$tick); - }else{ - $type = "gal$type"; - $req{id} = 100*$1+$2; - } - } - }elsif($self->{URI} =~ m{^/\w+/(alliance(?:avg)?)/(\d+)}){ - $type = $1; - $req{id} = $2; - }elsif($self->{URI} =~ m{^/\w+/planetvsnd/(\d+)}){ - $type = 'planetvsnd'; - $req{id} = $1; - } - - die 'no real type' unless $type; - - my $findGraph = $DBH->prepare(q{SELECT EXTRACT(EPOCH FROM last_modified) AS last_modified FROM graphs WHERE id = $1 AND tick = $2 AND type = $3}); - $findGraph->execute($req{id},$tick,$type) or die $DBH->errstr; - if (my $graph = $findGraph->fetchrow_hashref){ - $self->{R}->set_last_modified($graph->{last_modified}); - if ((my $rc = $self->{R}->meets_conditions) != Apache2::Const::OK){ - $self->{R}->status($rc); - return; - } - my $findGraph = $DBH->prepare(q{SELECT img FROM graphs WHERE id = $1 AND tick = $2 AND type = $3}); - $findGraph->execute($req{id},$tick,$type) or die $DBH->errstr; - $graph = $findGraph->fetchrow_hashref; - return $graph->{img} - } - - my $img; - my $delGraph = $DBH->prepare(q{DELETE FROM graphs WHERE id = $1 AND type = $2}); - my $addGraph = $DBH->prepare(q{INSERT INTO graphs (type,id,tick,img) VALUES($1,$2,$3,$4)}); - if ($type eq 'stats' || $type eq 'ranks'){ - my $type = $1; - my $findGraph; - my ($x,$y,$z) = ($req{x},$req{y},$req{z}); - my $query; - if ($type eq 'stats'){ - $query = $DBH->prepare(q{SELECT tick,score,size,value,xp*60 AS "xp*60" FROM planets natural join planet_stats WHERE id = planetid($1,$2,$3,$4) ORDER BY tick ASC}); - $graph_settings{y_min_value} = 0; - }elsif($type eq 'ranks'){ - $query = $DBH->prepare(q{SELECT tick,-scorerank AS score,-sizerank AS size,-valuerank AS value,-xprank AS xp FROM planets natural join planet_stats WHERE id = planetid($1,$2,$3,$4) ORDER BY tick ASC}); - $graph_settings{y_max_value} = 0; - } - $query->execute($x,$y,$z,$tick) or die $DBH->errstr; - $graph_settings{title} = "$type: $x:$y:$z"; - $graph_settings{two_axes} = 1; - $graph_settings{use_axis} = [2,1,2,2]; - $img = graphFromQuery 500,300,\%graph_settings,$query; - }elsif ($type eq 'galstats' || $type eq 'galranks'){ - my $query; - my ($x,$y) = ($req{x},$req{y}); - if ($type eq 'galstats'){ - $query = $DBH->prepare(q{SELECT tick,score,size,value,xp*60 AS "xp*60" FROM galaxies WHERE x = $1 AND y = $2 ORDER BY tick ASC}); - $graph_settings{y_min_value} = 0; - }elsif($type eq 'galranks'){ - $query = $DBH->prepare(q{SELECT tick,-scorerank AS score,-sizerank AS size,-valuerank AS value,-xprank AS xp FROM galaxies WHERE x = $1 AND y = $2 ORDER BY tick ASC}); - $graph_settings{y_max_value} = 0; - } - $query->execute($x,$y) or die $DBH->errstr; - $graph_settings{title} = "$type: $x:$y"; - $graph_settings{two_axes} = 1; - $graph_settings{use_axis} = [2,1,2,2]; - $img = graphFromQuery 500,300,\%graph_settings,$query; - }elsif ($type eq 'alliance' || $type eq 'allianceavg'){ - - - $graph_settings{title} = 'Alliance vs known members'; - $graph_settings{two_axes} = 1; - $graph_settings{use_axis} = [2,1,1,2]; - $graph_settings{y2_label} = 'score'; - - my $query; - if ($type eq 'alliance'){ - $query = $DBH->prepare(q{SELECT a.tick,a.score,a.size,memsize, memscore FROM (SELECT tick,SUM(size) AS memsize,SUM(score) AS memscore FROM planets p JOIN planet_stats ps USING (id) WHERE p.alliance_id = $1 GROUP BY tick) p JOIN alliance_stats a ON a.tick = p.tick -WHERE a.id = $1 AND a.tick > (SELECT max(tick) - 50 FROM alliance_stats) ORDER BY tick}); - }else{ - $graph_settings{title} = 'Average alliance vs known members'; - $query = $DBH->prepare(q{SELECT a.tick,a.score/members AS score,a.size/members AS size,memsize, memscore FROM (SELECT tick,AVG(size) AS memsize,AVG(score) AS memscore FROM planets p JOIN planet_stats ps USING (id) WHERE p.alliance_id = $1 GROUP BY tick) p JOIN alliance_stats a ON a.tick = p.tick -WHERE a.id = $1 AND a.tick > (SELECT max(tick) - 50 FROM alliance_stats)ORDER BY tick}); - } - $query->execute($2) or die $DBH->errstr; - - $img = graphFromQuery 500,300,\%graph_settings,$query; - }elsif ($type eq 'planetvsnd'){ - $graph_settings{title} = 'You vs ND AVG'; - $graph_settings{two_axes} = 1; - $graph_settings{use_axis} = [2,1,1,2]; - $graph_settings{y2_label} = 'score'; - - my $query = $DBH->prepare(q{SELECT a.tick,a.score/members AS NDscore,a.size/members as NDsize,memsize, memscore FROM (SELECT tick,size AS memsize,score AS memscore FROM planets p JOIN planet_stats ps USING (id) WHERE p.id = $1) p JOIN alliance_stats a ON a.tick = p.tick - WHERE a.id = 1 ORDER BY tick}); - $query->execute($req{id}) or die $DBH->errstr; - - $img = graphFromQuery 500,300,\%graph_settings,$query; - } - - die 'no image' unless defined $img; - - $delGraph->execute($req{id},$type) or die $DBH->errstr; - $addGraph->bind_param('$1',$type,{TYPE => DBI::SQL_VARCHAR }) or die $DBH->errstr; - $addGraph->bind_param('$2',$req{id},{TYPE => DBI::SQL_INTEGER }) or die $DBH->errstr; - $addGraph->bind_param('$3',$tick,{TYPE => DBI::SQL_INTEGER }) or die $DBH->errstr; - $addGraph->bind_param('$4',$img,{TYPE => DBI::SQL_VARBINARY }) or die $DBH->errstr; - $addGraph->execute or die $DBH->errstr; - $self->{R}->set_last_modified(time); - - return $img; -}; - -1; diff --git a/database/group_roles.sql b/database/group_roles.sql index fc50bef..d6b9628 100644 --- a/database/group_roles.sql +++ b/database/group_roles.sql @@ -18,6 +18,7 @@ INSERT INTO roles VALUES('no_fleet_update'); INSERT INTO roles VALUES('admin_users'); INSERT INTO roles VALUES('rankings_planet_intel'); INSERT INTO roles VALUES('alliances_resources'); +INSERT INTO roles VALUES('graphs_intel'); INSERT INTO group_roles (gid,role) VALUES(2,'member_menu'); INSERT INTO group_roles (gid,role) VALUES(2,'attack_menu'); @@ -33,6 +34,7 @@ INSERT INTO group_roles (gid,role) VALUES(1,'intel_menu'); INSERT INTO group_roles (gid,role) VALUES(1,'admin_users'); INSERT INTO group_roles (gid,role) VALUES(1,'rankings_planet_intel'); INSERT INTO group_roles (gid,role) VALUES(1,'alliances_resources'); +INSERT INTO group_roles (gid,role) VALUES(1,'graphs_intel'); INSERT INTO group_roles (gid,role) VALUES(3,'dc_menu'); INSERT INTO group_roles (gid,role) VALUES(3,'bc_menu'); @@ -41,3 +43,4 @@ INSERT INTO group_roles (gid,role) VALUES(3,'intel_menu'); INSERT INTO group_roles (gid,role) VALUES(3,'admin_users'); INSERT INTO group_roles (gid,role) VALUES(3,'rankings_planet_intel'); INSERT INTO group_roles (gid,role) VALUES(3,'alliances_resources'); +INSERT INTO group_roles (gid,role) VALUES(3,'graphs_intel'); diff --git a/lib/NDWeb.pm b/lib/NDWeb.pm index 85cbae1..7507a2f 100644 --- a/lib/NDWeb.pm +++ b/lib/NDWeb.pm @@ -32,7 +32,21 @@ our $VERSION = '0.01'; __PACKAGE__->config( name => 'NDWeb' ); __PACKAGE__->config->{'Plugin::Authentication'}{'use_session'} = 1; - +__PACKAGE__->config(session => { + storage => "/tmp/ndweb-$>/sesession", + directory_umask => 077, +}); +__PACKAGE__->config( cache => { + backend => { + class => "Cache::FileCache", + cache_root => "/tmp/ndweb-$>", + directory_umask => 077, + }, +}); + +__PACKAGE__->config( page_cache => { + set_http_headers => 1, +}); # Start the application @@ -51,10 +65,16 @@ __PACKAGE__->setup(qw/ Session Session::Store::File Session::State::Cookie + + Cache + PageCache /); + __PACKAGE__->deny_access_unless('/users',[qw/admin_users/]); __PACKAGE__->deny_access_unless('/alliances/resources',[qw/alliances_resources/]); +__PACKAGE__->deny_access_unless('/graphs/alliancevsintel',[qw/graphs_intel/]); +__PACKAGE__->deny_access_unless('/graphs/avgalliancevsintel',[qw/graphs_intel/]); =head1 NAME diff --git a/lib/NDWeb/Controller/Graphs.pm b/lib/NDWeb/Controller/Graphs.pm new file mode 100644 index 0000000..d2ea8df --- /dev/null +++ b/lib/NDWeb/Controller/Graphs.pm @@ -0,0 +1,213 @@ +package NDWeb::Controller::Graphs; + +use strict; +use warnings; +use parent 'Catalyst::Controller'; + +use ND::Include; + +=head1 NAME + +NDWeb::Controller::Graphs - Catalyst Controller + +=head1 DESCRIPTION + +Catalyst Controller. + +=head1 METHODS + +=cut + + +=head2 index + +=cut + +sub begin : Private { + my ( $self, $c ) = @_; + + $c->stash(width => 500); + $c->stash(height => 300); + $c->stash(settings => { + line_width => 1, + y_number_format => sub { prettyValue abs $_[0]}, + legend_placement => 'BL', + #zero_axis => 1, + box_axis => 0, + boxclr => 'black', + axislabelclr => 'black', + use_axis => [2,1,2,2], + y1_label => 'size', + two_axes => 1, + y2_label => 'rest', + }); + $c->stash(defaultgraph => 1); +} + +sub planetranks : Local { + my ( $self, $c, $planet ) = @_; + my $dbh = $c->model; + + $c->cache_page(3600); + + $c->stash->{settings}->{y_max_value} = '0'; + my $query = $dbh->prepare(q{SELECT tick,-scorerank AS score,-sizerank AS size + ,-valuerank AS value,-xprank AS xp + FROM planets NATUral JOIN planet_stats + WHERE id = $1 ORDER BY tick ASC + }); + $query->execute($planet); + $c->stash(query => $query); +} + +sub planetstats : Local { + my ( $self, $c, $planet ) = @_; + my $dbh = $c->model; + + $c->cache_page(3600); + + $c->stash->{settings}->{y_min_value} = '0'; + my $query = $dbh->prepare(q{SELECT tick,score,size,value,xp*60 AS "xp*60" + FROM planets NATURAL JOIN planet_stats + WHERE id = $1 ORDER BY tick ASC + }); + $query->execute($planet); + $c->stash(query => $query); +} + + +sub galaxyranks : Local { + my ( $self, $c, $x,$y ) = @_; + my $dbh = $c->model; + + $c->cache_page(3600); + + $c->stash->{settings}->{title} = "Ranks : $x:$y"; + $c->stash->{settings}->{y_max_value} = '0'; + my $query = $dbh->prepare(q{SELECT tick,-scorerank AS score,-sizerank AS size + ,-valuerank AS value,-xprank AS xp + FROM galaxies WHERE x = $1 AND y = $2 + ORDER BY tick ASC + }); + $query->execute($x,$y); + $c->stash(query => $query); +} + +sub galaxystats : Local { + my ( $self, $c, $x,$y ) = @_; + my $dbh = $c->model; + + $c->cache_page(3600); + + $c->stash->{settings}->{title} = "Stats : $x:$y"; + $c->stash->{settings}->{y_min_value} = '0'; + my $query = $dbh->prepare(q{SELECT tick,score,size,value,xp*60 AS "xp*60" + FROM galaxies WHERE x = $1 AND y = $2 + ORDER BY tick ASC + }); + $query->execute($x,$y); + $c->stash(query => $query); +} + +sub planetvsnd : Local { + my ( $self, $c, $planet ) = @_; + my $dbh = $c->model; + + $c->cache_page(3600); + + $c->stash->{settings}->{title} = 'You vs ND AVG'; + $c->stash->{settings}->{use_axis} = [2,1,1,2]; + $c->stash->{settings}->{y2_label} = 'score'; + + my $query = $dbh->prepare(q{SELECT a.tick,a.score/LEAST(members,60) AS NDscore + ,a.size/members as NDsize,memsize, memscore + FROM (SELECT tick,size AS memsize,score AS memscore + FROM planets p JOIN planet_stats ps USING (id) WHERE p.id = $1) p + JOIN alliance_stats a ON a.tick = p.tick + WHERE a.id = 1 ORDER BY tick + }); + $query->execute($planet); + $c->stash(query => $query); +} + + +sub alliancevsintel : Local { + my ( $self, $c, $alliance ) = @_; + my $dbh = $c->model; + + $c->stash->{settings}->{title} = 'Alliance vs known members'; + $c->stash->{settings}->{use_axis} = [2,1,1,2]; + $c->stash->{settings}->{y2_label} = 'score'; + + my $query = $dbh->prepare(q{SELECT a.tick,a.score,a.size,memsize, memscore + FROM (SELECT tick,SUM(size) AS memsize,SUM(score) AS memscore + FROM planets p JOIN planet_stats ps USING (id) + WHERE p.alliance_id = $1 GROUP BY tick) p + JOIN alliance_stats a ON a.tick = p.tick + WHERE a.id = $1 + AND a.tick > (SELECT max(tick) - 50 FROM alliance_stats) + ORDER BY tick + }); + $query->execute($alliance); + $c->stash(query => $query); +} + +sub avgalliancevsintel : Local { + my ( $self, $c, $alliance ) = @_; + my $dbh = $c->model; + + $c->stash->{settings}->{title} = 'Average alliance vs known members'; + $c->stash->{settings}->{use_axis} = [2,1,1,2]; + $c->stash->{settings}->{y2_label} = 'score'; + + my $query = $dbh->prepare(q{SELECT a.tick,a.score/LEAST(members,60) AS score + ,a.size/members AS size,memsize, memscore + FROM (SELECT tick,AVG(size) AS memsize,AVG(score) AS memscore + FROM planets p JOIN planet_stats ps USING (id) WHERE p.alliance_id = $1 + GROUP BY tick) p + JOIN alliance_stats a ON a.tick = p.tick + WHERE a.id = $1 + AND a.tick > (SELECT max(tick) - 50 FROM alliance_stats) + ORDER BY tick + }); + $query->execute($alliance); + $c->stash(query => $query); +} + + +sub end : ActionClass('RenderView') { + my ( $self, $c ) = @_; + $c->res->headers->content_type('image/png'); + if ($c->stash->{defaultgraph}){ + $c->stash(template => 'graphs/index.tt2'); + + my $query = $c->stash->{query}; + my $fields = $query->{NUM_OF_FIELDS}; + my @fields; + for (my $i = 0; $i < $fields; $i++){ + push @fields,[]; + } + while (my @result = $query->fetchrow){ + for (my $i = 0; $i < $fields; $i++){ + push @{$fields[$i]},$result[$i]; + } + } + $c->stash->{settings}->{x_label_skip} = int(1+(scalar @{$fields[0]}) / 6); + my @legend = @{$query->{NAME}}[1..$fields]; + $c->stash(legend => \@legend); + $c->stash(data => \@fields); + } + +} + +=head1 AUTHOR + +Michael Andreen (harv@ruin.nu) + +=head1 LICENSE + +GPL 2.0, or later. + +=cut + +1; diff --git a/root/lib/site/wrapper.tt2 b/root/lib/site/wrapper.tt2 index 37674ca..3a7af07 100644 --- a/root/lib/site/wrapper.tt2 +++ b/root/lib/site/wrapper.tt2 @@ -1,8 +1,11 @@ [% IF template.name.match('\.(css|js|txt)'); - debug("Passing page through as text: $template.name"); - content; - ELSE; - debug("Applying HTML page layout wrappers to $template.name\n"); - content WRAPPER site/html.tt2 + site/layout.tt2; - END; + debug("Passing page through as text: $template.name"); + content; +ELSIF template.name.match('graphs/'); + debug("Passing page through graph: $template.name"); + content; +ELSE; + debug("Applying HTML page layout wrappers to $template.name\n"); + content WRAPPER site/html.tt2 + site/layout.tt2; +END; -%] diff --git a/root/src/graphs/index.tt2 b/root/src/graphs/index.tt2 new file mode 100644 index 0000000..4e3fe02 --- /dev/null +++ b/root/src/graphs/index.tt2 @@ -0,0 +1,8 @@ +[% FILTER null; + USE g = GD.Graph.lines(width,height); + + g.set(settings); + g.set_legend(legend); +END; + g.plot(data).png; +-%] diff --git a/t/controller_Graphs.t b/t/controller_Graphs.t new file mode 100644 index 0000000..122a9cf --- /dev/null +++ b/t/controller_Graphs.t @@ -0,0 +1,10 @@ +use strict; +use warnings; +use Test::More tests => 3; + +BEGIN { use_ok 'Catalyst::Test', 'NDWeb' } +BEGIN { use_ok 'NDWeb::Controller::Graphs' } + +ok( request('/graphs')->is_success, 'Request should succeed' ); + + -- 2.39.2