diff --git a/Web/lib/MJB/Web.pm b/Web/lib/MJB/Web.pm index 0128afb..dec0a3c 100644 --- a/Web/lib/MJB/Web.pm +++ b/Web/lib/MJB/Web.pm @@ -47,6 +47,8 @@ sub startup ($self) { }); $self->helper( sync_blog => sub ( $c, $blog ) { + return if $c->is_testmode; # Do not run jobs in test mode. + my $build_job_id = $c->minion->enqueue( 'sync_blog', [ $blog->id ], { notes => { '_bid_' . $blog->id => 1 }, priority => $blog->build_priority, @@ -55,6 +57,8 @@ sub startup ($self) { }); $self->helper( sync_blog_media => sub ( $c, $blog ) { + return if $c->is_testmode; # Do not run jobs in test mode. + my $build_job_id = $c->minion->enqueue( 'sync_blog_media', [ $blog->id ], { notes => { '_bid_' . $blog->id => 1 }, priority => $blog->build_priority, diff --git a/Web/lib/MJB/Web/Controller/Blog.pm b/Web/lib/MJB/Web/Controller/Blog.pm index 88178f0..aa81f9d 100644 --- a/Web/lib/MJB/Web/Controller/Blog.pm +++ b/Web/lib/MJB/Web/Controller/Blog.pm @@ -184,7 +184,19 @@ sub do_domain ( $c ) { # This page gives the user the chance to set the title, description, email, etc. #== sub settings ( $c ) { + my $blog = $c->stash->{blog} = $c->db->blog( $c->param('id') ); + + # Make sure that a blog can be loaded. + if ( ! $blog ) { + $c->redirect_to( $c->url_for( 'show_dashboard' ) ); + return undef; + } + # Make sure the current user owns the blog that has been loaded. + if ( $blog->person->id ne $c->stash->{person}->id ) { + $c->redirect_to( $c->url_for( 'show_dashboard' ) ); + return undef; + } } #== @@ -199,13 +211,16 @@ sub settings ( $c ) { sub do_settings ( $c ) { my $blog = $c->stash->{blog} = $c->db->blog( $c->param('id') ); + # Make sure that a blog can be loaded. + if ( ! $blog ) { + $c->redirect_to( $c->url_for( 'show_dashboard' ) ); + return undef; + } + + # Make sure the current user owns the blog that has been loaded. if ( $blog->person->id ne $c->stash->{person}->id ) { - $c->render( - text => "Error: This blog isn't owned by you.", - status => 404, - format => 'txt', - ); - return; + $c->redirect_to( $c->url_for( 'show_dashboard' ) ); + return undef; } my $jekyll = $c->jekyll($blog->domain->name); diff --git a/Web/t/01_endpoints/03_blog/05_settings.t b/Web/t/01_endpoints/03_blog/05_settings.t new file mode 100644 index 0000000..b29cc49 --- /dev/null +++ b/Web/t/01_endpoints/03_blog/05_settings.t @@ -0,0 +1,69 @@ +#!/usr/bin/env perl +use MJB::Web::Test; + +#== +# This test ensures that the settings setup page exists after a blog +# is created and can be accessed. +# +# It also ensures that a user cannot access a settings page that doesn't +# belong to them. +# +# A user account will be registered, and the user will create a blog on +# blog.example.com, and then it will be confirmed that a blog exists. +# +# With this blog existing, the settings page should give a 200. Before existing, +# it should redirect to the dashboard. If a user accesses a blog that they did +# not create, it should also redirect to the dashboard. +# +# Note: During testing ->jekyll uses an alternative root path to store repos at. +# When using ->jekyll in tests, you MUST call $t->clear_tempdir when you are +# done testing to remove the altrernative jekyll root. +#== + +my $t = Test::Mojo::MJB->new('MJB::Web'); + +$t->get_ok( '/blog/1/settings' ) + ->status_is( 302 ) + ->header_is( location => '/login', "Cannot access settings without account."); + +# Make sure that open registration method is enabled and create a user account. +$t->app->config->{register}{enable_open} = 1; +$t->post_ok( '/register/open', form => { + name => 'fred', + email => 'fred@blog.com', + password => 'SuperSecure', + password_confirm => 'SuperSecure', + }) + ->status_is( 302 ); + +$t->get_ok( '/blog/1/settings' ) + ->status_is( 302 ) + ->header_is( location => '/dashboard', "Cannot access settings before blog exists."); + +# Create a blog.... +$t->post_ok( '/blog/domain', form => { + domain => 'blog.example.com', + calling_route => 'show_blog_domain_owned', + }); + +$t->get_ok( '/blog/1/settings' ) + ->status_is( 200 ); + +# Logout. +$t->reset_session; + +$t->post_ok( '/register/open', form => { + name => 'Ms Hax', + email => 'hacker@blog.com', + password => 'SuperSecure', + password_confirm => 'SuperSecure', + }) + ->status_is( 302 ) + ->get_ok( '/blog/1/settings' ) + ->status_is( 302 ) + ->header_is( location => '/dashboard', 'Cannot access settings for blog that isn\'t yours.' ); + +# Remove the alternative path. +$t->clear_tempdir; + +done_testing; diff --git a/Web/t/01_endpoints/03_blog/06_do_settings.t b/Web/t/01_endpoints/03_blog/06_do_settings.t new file mode 100644 index 0000000..c9c2116 --- /dev/null +++ b/Web/t/01_endpoints/03_blog/06_do_settings.t @@ -0,0 +1,63 @@ +#!/usr/bin/env perl +use MJB::Web::Test; +use Mojo::File; +use YAML::XS qw( Load ); + +#== +# This test ensures that the settings for a blog will take effect as part +# of the blog setup. +# +# It will create a blog, then submit the settings page. Once it has, it will +# load the config file that was created and confirm the updates. +# +# Note: During testing ->jekyll uses an alternative root path to store repos at. +# When using ->jekyll in tests, you MUST call $t->clear_tempdir when you are +# done testing to remove the altrernative jekyll root. +#== + +my $t = Test::Mojo::MJB->new('MJB::Web'); + +$t->get_ok( '/blog/1/settings' ) + ->status_is( 302 ) + ->header_is( location => '/login', "Cannot access settings without account."); + +# Make sure that open registration method is enabled and create a user account. +$t->app->config->{register}{enable_open} = 1; +$t->post_ok( '/register/open', form => { + name => 'fred', + email => 'fred@blog.com', + password => 'SuperSecure', + password_confirm => 'SuperSecure', + }) + ->status_is( 302 ); + +$t->get_ok( '/blog/1/settings' ) + ->status_is( 302 ) + ->header_is( location => '/dashboard', "Cannot access settings before blog exists."); + +# Create a blog.... +$t->post_ok( '/blog/domain', form => { + domain => 'blog.example.com', + calling_route => 'show_blog_domain_owned', + }); + +# Make the settings for the blog... +$t->post_ok( '/blog/1/settings', form => { + configTitle => 'Installed By Bot', + configDesc => 'A blog about robot dogs.' + }) + ->status_is( 302 ); + +# Confirm the settings were written to disk.... +ok my $config = Load( + Mojo::File->new( $t->app->jekyll( 'blog.example.com' )->root . '/blog.example.com/_config.yml' )->slurp +), 'Load blog config file from disk.'; + +# Confirm the changes were written. +is $config->{title}, 'Installed By Bot', "Confirm config title was updated."; +is $config->{description}, 'A blog about robot dogs.', "Confirm config description was updated."; + +# Remove the alternative path. +$t->clear_tempdir; + +done_testing;