diff options
Diffstat (limited to 't')
-rw-r--r-- | t/app/01app.t | 10 | ||||
-rw-r--r-- | t/app/02pod.t | 10 | ||||
-rw-r--r-- | t/app/03podcoverage.t | 14 | ||||
-rw-r--r-- | t/app/controller/about.t | 26 | ||||
-rw-r--r-- | t/app/controller/auth.t | 217 | ||||
-rw-r--r-- | t/app/controller/my.t | 19 | ||||
-rw-r--r-- | t/app/controller/page_not_found.t | 20 | ||||
-rw-r--r-- | t/app/controller/report_import.t | 158 | ||||
-rw-r--r-- | t/app/controller/report_new.t | 465 | ||||
-rw-r--r-- | t/app/controller/sample.jpg | bin | 0 -> 22588 bytes | |||
-rw-r--r-- | t/app/helpers/send_email.t | 44 | ||||
-rw-r--r-- | t/app/helpers/send_email_sample.txt | 29 | ||||
-rw-r--r-- | t/app/load_general_config.t | 13 | ||||
-rw-r--r-- | t/app/model/db.t | 8 | ||||
-rw-r--r-- | t/app/model/token.t | 96 | ||||
-rw-r--r-- | t/app/view/email.t | 8 | ||||
-rw-r--r-- | t/app/view/web.t | 8 | ||||
-rw-r--r-- | t/cobrand/loading.t | 71 | ||||
-rw-r--r-- | t/fixmystreet.t | 37 | ||||
-rw-r--r-- | t/i18n.t | 39 |
20 files changed, 1292 insertions, 0 deletions
diff --git a/t/app/01app.t b/t/app/01app.t new file mode 100644 index 000000000..02ffcd217 --- /dev/null +++ b/t/app/01app.t @@ -0,0 +1,10 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +use Catalyst::Test 'FixMyStreet::App'; + +ok( request('/')->is_success, 'Request should succeed' ); + +done_testing(); diff --git a/t/app/02pod.t b/t/app/02pod.t new file mode 100644 index 000000000..ababc2eaa --- /dev/null +++ b/t/app/02pod.t @@ -0,0 +1,10 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD}; +eval "use Test::Pod 1.14"; +plan skip_all => 'Test::Pod 1.14 required' if $@; + +all_pod_files_ok(); diff --git a/t/app/03podcoverage.t b/t/app/03podcoverage.t new file mode 100644 index 000000000..6ddc5c6b6 --- /dev/null +++ b/t/app/03podcoverage.t @@ -0,0 +1,14 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD}; + +eval "use Test::Pod::Coverage 1.04"; +plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@; + +eval "use Pod::Coverage 0.20"; +plan skip_all => 'Pod::Coverage 0.20 required' if $@; + +all_pod_coverage_ok(); diff --git a/t/app/controller/about.t b/t/app/controller/about.t new file mode 100644 index 000000000..aeca47d86 --- /dev/null +++ b/t/app/controller/about.t @@ -0,0 +1,26 @@ +use strict; +use warnings; + +use Test::More; +use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App'; + +ok( my $mech = Test::WWW::Mechanize::Catalyst->new, 'Created mech object' ); + +# check that we can get the page +$mech->get_ok('/about'); +$mech->content_contains('About Us :: FixMyStreet.com'); +$mech->content_contains('html lang="en-gb"'); + +# check that geting the page as EHA produces a different page +ok $mech->host("reportemptyhomes.co.uk"), 'change host to reportemptyhomes'; +$mech->get_ok('/about'); +$mech->content_contains('About us :: Report Empty Homes'); +$mech->content_contains('html lang="en-gb"'); + +# check that geting the page as EHA in welsh produces a different page +ok $mech->host("cy.reportemptyhomes.co.uk"), 'host to cy.reportemptyhomes'; +$mech->get_ok('/about'); +$mech->content_contains('Amdanom ni :: Adrodd am Eiddo Gwag'); +$mech->content_contains('html lang="cy"'); + +done_testing(); diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t new file mode 100644 index 000000000..6e1e8d58d --- /dev/null +++ b/t/app/controller/auth.t @@ -0,0 +1,217 @@ +use strict; +use warnings; + +use Test::More tests => 97; + +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; + +my $test_email = 'test@example.com'; +my $test_password = 'foobar'; + +END { + ok( FixMyStreet::App->model('DB::User')->find( { email => $_ } )->delete, + "delete test user '$_'" ) + for ($test_email); +} + +$mech->get_ok('/auth'); + +# check that we can't reach a page that is only available to authenticated users +$mech->not_logged_in_ok; + +# check that submitting form with no / bad email creates an error. +$mech->get_ok('/auth'); + +for my $test ( + [ '' => 'enter an email address' ], + [ 'not an email' => 'check your email address is correct' ], + [ 'bob@foo' => 'check your email address is correct' ], + [ 'bob@foonaoedudnueu.co.uk' => 'check your email address is correct' ], + ) +{ + my ( $email, $error_message ) = @$test; + pass "--- testing bad email '$email' gives error '$error_message'"; + $mech->get_ok('/auth'); + $mech->content_lacks($error_message); + $mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { email => $email, }, + button => 'email_login', + }, + "try to create an account with email '$email'" + ); + is $mech->uri->path, '/auth', "still on auth page"; + $mech->content_contains($error_message); +} + +# create a new account +$mech->clear_emails_ok; +$mech->get_ok('/auth'); +$mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { email => $test_email, }, + button => 'email_login', + }, + "create an account for '$test_email'" +); +is $mech->uri->path, '/auth/token', "redirected to welcome page"; + +# check that we are not logged in yet +$mech->not_logged_in_ok; + +# check that we got one email +{ + $mech->email_count_is(1); + my $email = $mech->get_email; + $mech->clear_emails_ok; + is $email->header('Subject'), "Your FixMyStreet.com account details", + "subject is correct"; + is $email->header('To'), $test_email, "to is correct"; + + # extract the link + my ($link) = $email->body =~ m{(http://\S+)}; + ok $link, "Found a link in email '$link'"; + + # check that the user does not exist + sub get_user { + FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + } + ok !get_user(), "no user exists"; + + # visit the confirm link (with bad token) and check user no confirmed + $mech->get_ok( $link . 'XXX' ); + ok !get_user(), "no user exists"; + $mech->not_logged_in_ok; + + # visit the confirm link and check user is confirmed + $mech->get_ok($link); + ok get_user(), "user created"; + is $mech->uri->path, '/my', "redirected to the 'my' section of site"; + $mech->logged_in_ok; + + # logout and try to use the token again + $mech->log_out_ok; + $mech->get_ok($link); + is $mech->uri, $link, "not logged in"; + $mech->content_contains( 'Link too old or already used', + 'token now invalid' ); + $mech->not_logged_in_ok; +} + +# get a login email and change password +{ + $mech->clear_emails_ok; + $mech->get_ok('/auth'); + $mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { email => "$test_email", }, + button => 'email_login', + }, + "email_login with '$test_email'" + ); + is $mech->uri->path, '/auth/token', "redirected to token page"; + + # rest is as before so no need to test + + # follow link and change password - check not prompted for old password + $mech->not_logged_in_ok; + + $mech->email_count_is(1); + my $email = $mech->get_email; + $mech->clear_emails_ok; + my ($link) = $email->body =~ m{(http://\S+)}; + $mech->get_ok($link); + + $mech->follow_link_ok( { url => '/auth/change_password' } ); + + ok my $form = $mech->form_name('change_password'), + "found change password form"; + is_deeply [ sort grep { $_ } map { $_->name } $form->inputs ], # + [ 'confirm', 'new_password' ], + "check we got expected fields (ie not old_password)"; + + # check the various ways the form can be wrong + for my $test ( + { new => '', conf => '', err => 'enter a password', }, + { new => 'secret', conf => '', err => 'do not match', }, + { new => '', conf => 'secret', err => 'do not match', }, + { new => 'secret', conf => 'not_secret', err => 'do not match', }, + ) + { + $mech->get_ok('/auth/change_password'); + $mech->content_lacks( $test->{err}, "did not find expected error" ); + $mech->submit_form_ok( + { + form_name => 'change_password', + fields => + { new_password => $test->{new}, confirm => $test->{conf}, }, + }, + "change_password with '$test->{new}' and '$test->{conf}'" + ); + $mech->content_contains( $test->{err}, "found expected error" ); + } + + my $user = + FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + ok $user, "got a user"; + ok !$user->password, "user has no password"; + + $mech->get_ok('/auth/change_password'); + $mech->submit_form_ok( + { + form_name => 'change_password', + fields => + { new_password => $test_password, confirm => $test_password, }, + }, + "change_password with '$test_password' and '$test_password'" + ); + is $mech->uri->path, '/auth/change_password', + "still on change password page"; + $mech->content_contains( 'password has been changed', + "found password changed" ); + + $user->discard_changes(); + ok $user->password, "user now has a password"; +} + +# login using valid details +$mech->get_ok('/auth'); +$mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { + email => $test_email, + password => $test_password, + }, + button => 'login', + }, + "login with '$test_email' & '$test_password" +); +is $mech->uri->path, '/my', "redirected to correct page"; + +# logout +$mech->log_out_ok; + +# try to login with bad details +$mech->get_ok('/auth'); +$mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { + email => $test_email, + password => 'not the password', + }, + button => 'login', + }, + "login with '$test_email' & '$test_password" +); +is $mech->uri->path, '/auth', "redirected to correct page"; +$mech->content_contains( 'Email or password wrong', 'found error message' ); + +# more test: +# TODO: test that email are always lowercased + diff --git a/t/app/controller/my.t b/t/app/controller/my.t new file mode 100644 index 000000000..1ed6806a4 --- /dev/null +++ b/t/app/controller/my.t @@ -0,0 +1,19 @@ +use strict; +use warnings; + +use Test::More tests => 11; + +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; + +$mech->get_ok('/my'); +is $mech->uri->path, '/auth', "got sent to the login page"; + +# login +my $user = $mech->log_in_ok( 'test@example.com' ); +$mech->get_ok('/my'); +is $mech->uri->path, '/my', "stayed on '/my/' page"; + +# cleanup +$mech->delete_user( $user ); + diff --git a/t/app/controller/page_not_found.t b/t/app/controller/page_not_found.t new file mode 100644 index 000000000..9c8d7e5a6 --- /dev/null +++ b/t/app/controller/page_not_found.t @@ -0,0 +1,20 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More tests => 4; + +use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App'; + +my $mech = Test::WWW::Mechanize::Catalyst->new; + +# homepage ok +$mech->get_ok('/'); + +# get 404 page +my $path_to_404 = '/bad/path/page_not_found'; +my $res = $mech->get($path_to_404); +ok !$res->is_success(), "want a bad response"; +is $res->code, 404, "got 404"; +$mech->content_contains($path_to_404); diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t new file mode 100644 index 000000000..5c16324d3 --- /dev/null +++ b/t/app/controller/report_import.t @@ -0,0 +1,158 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +use Web::Scraper; +use Path::Class; + +my $mech = FixMyStreet::TestMech->new; +$mech->get_ok('/import'); + +my $sample_file = file(__FILE__)->parent->file("sample.jpg")->stringify; +ok -e $sample_file, "sample file $sample_file exists"; + +# submit an empty report to import - check we get all errors +subtest "Test creating bad partial entries" => sub { + + foreach my $test ( + { + fields => { email => 'bob', }, + errors => [ + 'You must supply a service', + 'Please enter a subject', + 'Please enter your name', + 'Please enter a valid email', + 'Either a location or a photo must be provided.', + ], + }, + { + fields => { email => 'bob@example.com' }, + errors => [ + 'You must supply a service', + 'Please enter a subject', + 'Please enter your name', + 'Either a location or a photo must be provided.', + ], + }, + { + fields => { lat => 1, lon => 1, }, + errors => [ + 'You must supply a service', + 'Please enter a subject', + 'Please enter your name', + 'Please enter your email', +'We had a problem with the supplied co-ordinates - outside the UK?', + ], + }, + { + fields => { photo => $sample_file, }, + errors => [ + 'You must supply a service', + 'Please enter a subject', + 'Please enter your name', + 'Please enter your email', + ], + }, + ) + { + $mech->get_ok('/import'); + + $mech->submit_form_ok( # + { with_fields => $test->{fields} }, + "fill in form" + ); + + is_deeply( $mech->import_errors, $test->{errors}, "expected errors" ); + } + +}; + +# submit an empty report to import - check we get all errors +subtest "Submit a correct entry" => sub { + + $mech->get_ok('/import'); + + $mech->submit_form_ok( # + { + with_fields => { + service => 'test-script', + name => 'Test User', + email => 'test@example.com', + subject => 'Test report', + detail => 'This is a test report', + photo => $sample_file, + } + }, + "fill in form" + ); + + is_deeply( $mech->import_errors, [], "got no errors" ); + is $mech->content, 'SUCCESS', "Got success response"; + + # check that we have received the email + $mech->email_count_is(1); + my $email = $mech->get_email; + $mech->clear_emails_ok; + + my ($token_url) = $email->body =~ m{(http://\S+)}; + ok $token_url, "Found a token url $token_url"; + + # go to the token url + $mech->get_ok($token_url); + + # check that we are not shown anything as we don't have a location yet + is_deeply $mech->visible_form_values, { pc => '' }, + "check only pc field is shown"; + + $mech->submit_form_ok( # + { with_fields => { pc => 'SW1A 1AA' } }, + "fill in postcode" + ); + + # check that we are not shown anything as we don't have a location yet + is_deeply $mech->visible_form_values, + { + name => 'Test User', + email => 'test@example.com', + title => 'Test report', + detail => 'This is a test report', + photo => '', + phone => '', + may_show_name => '1', + }, + "check imported fields are shown"; + + TODO: { + local $TODO = "'/report/123' urls not srved by catalyst yet"; + + # change the details + $mech->submit_form_ok( # + { + with_fields => { + name => 'New Test User', + email => 'test@example.com', + title => 'New Test report', + detail => 'This is a test report', + phone => '01234 567 890', + may_show_name => '1', + } + }, + "Update details and save" + ); + } + + # check that report has been created + my $user = + FixMyStreet::App->model('DB::User') + ->find( { email => 'test@example.com' } ); + ok $user, "Found a user"; + + my $report = $user->problems->first; + is $report->state, 'confirmed', 'is confirmed'; + is $report->title, 'New Test report', 'title is correct'; + + $mech->delete_user($user); +}; + +done_testing(); diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t new file mode 100644 index 000000000..dca86db77 --- /dev/null +++ b/t/app/controller/report_new.t @@ -0,0 +1,465 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +use Web::Scraper; + +my $mech = FixMyStreet::TestMech->new; +$mech->get_ok('/report/new'); + +# test various locations on inital search box +foreach my $test ( + { + pc => '', # + errors => [], + pc_alternatives => [], + }, + { + pc => 'xxxxxxxxxxxxxxxxxxxxxxxxxxx', + errors => ['Sorry, we could not find that location.'], + pc_alternatives => [], + }, + { + pc => 'glenthorpe', + errors => [], + pc_alternatives => [ # TODO - should filter out these non-UK addresses + 'Glenthorpe Crescent, Leeds LS9 7, UK', + 'Glenthorpe Rd, Merton, Greater London SM4 4, UK', + 'Glenthorpe Ln, Katy, TX 77494, USA', + 'Glenthorpe Dr, Walnut, CA 91789, USA', + 'Glenthorpe Ave, Leeds LS9 7, UK', + 'Glenthorpe Ct, Katy, TX 77494, USA', + ], + }, + { + pc => 'Glenthorpe Ct, Katy, TX 77494, USA', + errors => + ['We had a problem with the supplied co-ordinates - outside the UK?'], + pc_alternatives => [], + }, + ) +{ + subtest "test bad pc value '$test->{pc}'" => sub { + $mech->get_ok('/report/new'); + $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } }, + "bad location" ); + is_deeply $mech->form_errors, $test->{errors}, + "expected errors for pc '$test->{pc}'"; + is_deeply $mech->pc_alternatives, $test->{pc_alternatives}, + "expected alternatives for pc '$test->{pc}'"; + }; +} + +# check that exact queries result in the correct lat,lng +foreach my $test ( + { + pc => 'SW1A 1AA', + latitude => '51.5010096115539', + longitude => '-0.141587067110009', + }, + { + pc => 'Manchester', + latitude => '53.4807125', + longitude => '-2.2343765', + }, + { + pc => 'Glenthorpe Rd, Merton, Greater London SM4 4, UK', + latitude => '51.3937997', + longitude => '-0.2209596', + }, + ) +{ + subtest "check lat/lng for '$test->{pc}'" => sub { + $mech->get_ok('/report/new'); + $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } }, + "good location" ); + is_deeply $mech->form_errors, [], "no errors for pc '$test->{pc}'"; + is_deeply $mech->extract_location, $test, + "got expected location for pc '$test->{pc}'"; + }; +} + +# test that the various bit of form get filled in and errors correctly +# generated. +foreach my $test ( + { + msg => 'all fields empty', + pc => 'SW1A 1AA', + fields => { + title => '', + detail => '', + photo => '', + name => '', + may_show_name => '1', + email => '', + phone => '', + }, + changes => {}, + errors => [ + 'Please enter a subject', + 'Please enter some details', + 'Please enter your name', + 'Please enter your email', + ], + }, + { + msg => 'may_show_name defaults to true', + pc => 'SW1A 1AA', + fields => { + title => '', + detail => '', + photo => '', + name => '', + may_show_name => undef, + email => '', + phone => '', + }, + changes => { may_show_name => '1' }, + errors => [ + 'Please enter a subject', + 'Please enter some details', + 'Please enter your name', + 'Please enter your email', + ], + }, + { + msg => 'may_show_name unchanged if name is present (stays false)', + pc => 'SW1A 1AA', + fields => { + title => '', + detail => '', + photo => '', + name => 'Bob Jones', + may_show_name => undef, + email => '', + phone => '', + }, + changes => {}, + errors => [ + 'Please enter a subject', + 'Please enter some details', + 'Please enter your email', + ], + }, + { + msg => 'may_show_name unchanged if name is present (stays true)', + pc => 'SW1A 1AA', + fields => { + title => '', + detail => '', + photo => '', + name => 'Bob Jones', + may_show_name => '1', + email => '', + phone => '', + }, + changes => {}, + errors => [ + 'Please enter a subject', + 'Please enter some details', + 'Please enter your email', + ], + }, + { + msg => 'title and details tidied up', + pc => 'SW1A 1AA', + fields => { + title => 'DOG SHIT ON WALLS', + detail => 'on this portakabin - more of a portaloo HEH!!', + photo => '', + name => 'Bob Jones', + may_show_name => '1', + email => '', + phone => '', + }, + changes => { + title => 'Dog poo on walls', + detail => + 'On this [portable cabin] - more of a [portable loo] HEH!!', + }, + errors => [ 'Please enter your email', ], + }, + { + msg => 'name too short', + pc => 'SW1A 1AA', + fields => { + title => 'Test title', + detail => 'Test detail', + photo => '', + name => 'DUDE', + may_show_name => '1', + email => '', + phone => '', + }, + changes => {}, + errors => [ +'Please enter your full name, councils need this information - if you do not wish your name to be shown on the site, untick the box', + 'Please enter your email', + ], + }, + { + msg => 'name is anonymous', + pc => 'SW1A 1AA', + fields => { + title => 'Test title', + detail => 'Test detail', + photo => '', + name => 'anonymous', + may_show_name => '1', + email => '', + phone => '', + }, + changes => {}, + errors => [ +'Please enter your full name, councils need this information - if you do not wish your name to be shown on the site, untick the box', + 'Please enter your email', + ], + }, + { + msg => 'email invalid', + pc => 'SW1A 1AA', + fields => { + title => 'Test title', + detail => 'Test detail', + photo => '', + name => 'Joe Smith', + may_show_name => '1', + email => 'not an email', + phone => '', + }, + changes => { email => 'notanemail', }, + errors => [ 'Please enter a valid email', ], + }, + { + msg => 'cleanup title and detail', + pc => 'SW1A 1AA', + fields => { + title => " Test title ", + detail => " first line \n\n second\nline\n\n ", + photo => '', + name => '', + may_show_name => '1', + email => '', + phone => '', + }, + changes => { + title => 'Test title', + detail => "First line\n\nSecond line", + }, + errors => [ 'Please enter your name', 'Please enter your email', ], + }, + { + msg => 'clean up name and email', + pc => 'SW1A 1AA', + fields => { + title => '', + detail => '', + photo => '', + name => ' Bob Jones ', + may_show_name => '1', + email => ' BOB @ExAmplE.COM ', + phone => '', + }, + changes => { + name => 'Bob Jones', + email => 'bob@example.com', + }, + errors => [ 'Please enter a subject', 'Please enter some details', ], + }, + ) +{ + subtest "check form errors where $test->{msg}" => sub { + $mech->get_ok('/report/new'); + + # submit initial pc form + $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } }, + "submit location" ); + is_deeply $mech->form_errors, [], "no errors for pc '$test->{pc}'"; + + # submit the main form + $mech->submit_form_ok( { with_fields => $test->{fields} }, + "submit form" ); + + # check that we got the errors expected + is_deeply $mech->form_errors, $test->{errors}, "check errors"; + + # check that fields have changed as expected + my $new_values = { + %{ $test->{fields} }, # values added to form + %{ $test->{changes} }, # changes we expect + }; + is_deeply $mech->visible_form_values, $new_values, + "values correctly changed"; + }; +} + +subtest "test report creation for a user who does not have an account" => sub { + $mech->log_out_ok; + $mech->clear_emails_ok; + + # check that the user does not exist + my $test_email = 'test-1@example.com'; + ok !FixMyStreet::App->model('DB::User')->find( { email => $test_email } ), + "test user does not exist"; + + # submit initial pc form + $mech->get_ok('/report/new'); + $mech->submit_form_ok( { with_fields => { pc => 'SW1A 1AA', } }, + "submit location" ); + $mech->submit_form_ok( + { + with_fields => { + title => 'Test Report', + detail => 'Test report details.', + photo => '', + name => 'Joe Bloggs', + may_show_name => '1', + email => 'test-1@example.com', + phone => '07903 123 456', + } + }, + "submit good details" + ); + + # check that we got the errors expected + is_deeply $mech->form_errors, [], "check there were no errors"; + + # check that the user has been created + my $user = + FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + ok $user, "created new user"; + + # find the report + my $report = $user->problems->first; + ok $report, "Found the report"; + + # check that the report is not available yet. + is $report->state, 'unconfirmed', "report not confirmed"; + is $mech->get( '/report/' . $report->id )->code, 404, "report not found"; + + # receive token + my $email = $mech->get_email; + ok $email, "got an email"; + like $email->body, qr/confirm the problem/i, "confirm the problem"; + + my ($url) = $email->body =~ m{(http://\S+)}; + ok $url, "extracted confirm url '$url'"; + + # confirm token + $mech->get_ok($url); + $report->discard_changes; + is $report->state, 'confirmed', "Report is now confirmed"; + is $report->state, 'confirmed', "report is now confirmed"; + + TODO: { + local $TODO = "'/report/<<id>>' not handled by catalyst yet"; + $mech->get_ok( '/report/' . $report->id ); + } + + # user is created and logged in + $mech->logged_in_ok; + + # cleanup + $mech->delete_user($user); +}; + +#### test report creation for a user who has account but is not logged in +# come to site +# fill in report +# receive token +# confirm token +# report is confirmed + +#### test report creation for user with account and logged in +subtest "test report creation for a user who is logged in" => sub { + + # check that the user does not exist + my $test_email = 'test-2@example.com'; + + $mech->clear_emails_ok; + my $user = $mech->log_in_ok($test_email); + + # setup the user. + ok $user->update( + { + name => 'Test User', + phone => '01234 567 890', + } + ), + "set users details"; + + # submit initial pc form + $mech->get_ok('/report/new'); + $mech->submit_form_ok( { with_fields => { pc => 'SW1A 1AA', } }, + "submit location" ); + + # check that the fields are correctly prefilled + is_deeply( + $mech->visible_form_values, + { + title => '', + detail => '', + may_show_name => '1', + email => $test_email, + name => 'Test User', + phone => '01234 567 890', + photo => '', + }, + "user's details prefilled" + ); + + TODO: { + local $TODO = +"'/report/<<id>>' not handled by catalyst yet - form creation redirects to there on success if logged in"; + eval { + $mech->submit_form_ok( + { + with_fields => { + title => 'Test Report', + detail => 'Test report details.', + photo => '', + name => 'Joe Bloggs', + may_show_name => '1', + phone => '07903 123 456', + } + }, + "submit good details" + ); + }; + } + + # find the report + my $report = $user->problems->first; + ok $report, "Found the report"; + + # check that we got redirected to /report/ + is $mech->uri->path, "/report/" . $report->id, "redirected to report page"; + + # check that no emails have been sent + $mech->email_count_is(0); + + # check report is confirmed and available + is $report->state, 'confirmed', "report is now confirmed"; + TODO: { + local $TODO = "'/report/<<id>>' not handled by catalyst yet"; + $mech->get_ok( '/report/' . $report->id ); + } + + # user is still logged in + $mech->logged_in_ok; + + # cleanup + $mech->delete_user($user); +}; + +#### test uploading an image + +#### test completing a partial report (eq flickr upload) + +#### possibly manual testing +# create report without using map +# create report by clicking on may with javascript off +# create report with images off + +done_testing(); diff --git a/t/app/controller/sample.jpg b/t/app/controller/sample.jpg Binary files differnew file mode 100644 index 000000000..23198cb83 --- /dev/null +++ b/t/app/controller/sample.jpg diff --git a/t/app/helpers/send_email.t b/t/app/helpers/send_email.t new file mode 100644 index 000000000..adf2c56c1 --- /dev/null +++ b/t/app/helpers/send_email.t @@ -0,0 +1,44 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use utf8; + +BEGIN { + use FixMyStreet; + FixMyStreet->test_mode(1); +} + +use Test::More tests => 5; + +use Email::Send::Test; +use Path::Class; + +use_ok 'FixMyStreet::App'; +my $c = FixMyStreet::App->new; + +# fake up the request a little +$c->req->uri( URI->new('http://localhost/') ); +$c->req->base( $c->req->uri ); + +# set some values in the stash +$c->stash->{foo} = 'bar'; + +# clear the email queue +Email::Send::Test->clear; + +# send the test email +ok $c->send_email( 'test.txt', { to => 'test@recipient.com' } ), + "sent an email"; + +# check it got templated and sent correctly +my @emails = Email::Send::Test->emails; +is scalar(@emails), 1, "caught one email"; + +# Get the email, check it has a date and then strip it out +my $email_as_string = $emails[0]->as_string; +ok $email_as_string =~ s{\s+Date:\s+\S.*?$}{}xms, "Found and stripped out date"; + +is $email_as_string, + file(__FILE__)->dir->file('send_email_sample.txt')->slurp, + "email is as expected"; diff --git a/t/app/helpers/send_email_sample.txt b/t/app/helpers/send_email_sample.txt new file mode 100644 index 000000000..c6bdac74f --- /dev/null +++ b/t/app/helpers/send_email_sample.txt @@ -0,0 +1,29 @@ +MIME-Version: 1.0 +Subject: test email =?utf-8?Q?=E2=98=BA?= +Content-Type: text/plain; charset="utf-8" +To: test@recipient.com +Content-Transfer-Encoding: quoted-printable +From: evdb@ecclestoad.co.uk + + Hello, + + This is a test email where foo: bar. + + utf8: =E6=88=91=E4=BB=AC=E5=BA=94=E8=AF=A5=E8=83=BD=E5=A4=9F=E6=97=A0= +=E7=BC=9D=E5=A4=84=E7=90=86UTF8=E7=BC=96=E7=A0=81 + + indented_text + + long line: Lorem ipsum dolor sit amet, consectetur adipisicing + elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud + exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate + velit esse cillum dolore eu fugiat nulla pariatur. Excepteur + sint occaecat cupidatat non proident, sunt in culpa qui officia + deserunt mollit anim id est laborum. + + Yours, + FixMyStreet. + + diff --git a/t/app/load_general_config.t b/t/app/load_general_config.t new file mode 100644 index 000000000..3855c2565 --- /dev/null +++ b/t/app/load_general_config.t @@ -0,0 +1,13 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; + +use Test::More tests => 2; + +use_ok 'FixMyStreet::App'; + +# GAZE_URL chosen as it is unlikely to change +is FixMyStreet::App->config->{GAZE_URL}, # + 'http://gaze.mysociety.org/gaze', # + "check that known config param is loaded"; diff --git a/t/app/model/db.t b/t/app/model/db.t new file mode 100644 index 000000000..bebd68f0b --- /dev/null +++ b/t/app/model/db.t @@ -0,0 +1,8 @@ +use strict; +use warnings; + +use Test::More; + +use_ok 'FixMyStreet::App::Model::DB'; + +done_testing(); diff --git a/t/app/model/token.t b/t/app/model/token.t new file mode 100644 index 000000000..12945975e --- /dev/null +++ b/t/app/model/token.t @@ -0,0 +1,96 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More tests => 45; + +use FixMyStreet; +use FixMyStreet::App; +use mySociety::AuthToken; +use mySociety::DBHandle 'dbh'; + +# set things up so that code using mySociety::DBHandle is happy +FixMyStreet->configure_mysociety_dbhandle(); + +# NOTE - remember that you need to explicitly dbh()->commit after making +# database changes with the mySociety::* modules. + +# create a token using DBIC and check we can read it using AuthToken, and vice +# versa + +my %tests = ( + nested_hash => { foo => 'bar', and => [ 'baz', 'bundy' ] }, + array => [ 'foo', 'bar' ], + scalar => 123, +); + +my $token_rs = FixMyStreet::App->model('DB::Token'); + +# create using DBIC +foreach my $test_data_name ( sort keys %tests ) { + my $test_data = $tests{$test_data_name}; + + pass "--- testing DBIC create using '$test_data_name'"; + + my $dbic_token = + $token_rs->create( { scope => 'testing', data => $test_data } ); + my $token = $dbic_token->token; + ok $token, "stored token '$token'"; + + is_deeply $dbic_token->data, $test_data, "data stored correctly using DBIC"; + + # read back using DBIC + is_deeply $token_rs->find( { token => $token, scope => 'testing' } )->data, + $test_data, + "data read back correctly with DBIC"; + + # read back using mySociety::AuthToken + is_deeply mySociety::AuthToken::retrieve( 'testing', $token ), + $test_data, "data read back correctly with m::AT"; + + # delete token + ok $dbic_token->delete, "delete token"; + + is $token_rs->find( { token => $token, scope => 'testing' } ), + undef, + "token gone for DBIC"; + + # read back using mySociety::AuthToken + is mySociety::AuthToken::retrieve( 'testing', $token ), + undef, "token gone with m::AT"; + +} + +# create using m::AT +foreach my $test_data_name ( sort keys %tests ) { + my $test_data = $tests{$test_data_name}; + + pass "--- testing m::AT create using '$test_data_name'"; + + my $token = mySociety::AuthToken::store( 'testing', $test_data ); + dbh->commit(); + ok $token, "stored token '$token'"; + + # read back using DBIC + is_deeply $token_rs->find( { token => $token, scope => 'testing' } )->data, + $test_data, + "data read back correctly with DBIC"; + + # read back using mySociety::AuthToken + is_deeply mySociety::AuthToken::retrieve( 'testing', $token ), + $test_data, "data read back correctly with m::AT"; + + # delete token + ok mySociety::AuthToken::destroy( 'testing', $token ), "destroy token"; + dbh->commit(); + + is $token_rs->find( { token => $token, scope => 'testing' } ), + undef, + "token gone for DBIC"; + + # read back using mySociety::AuthToken + is mySociety::AuthToken::retrieve( 'testing', $token ), + undef, "token gone with m::AT"; + +} diff --git a/t/app/view/email.t b/t/app/view/email.t new file mode 100644 index 000000000..4d7bbe8ff --- /dev/null +++ b/t/app/view/email.t @@ -0,0 +1,8 @@ +use strict; +use warnings; + +use Test::More; + +BEGIN { use_ok 'FixMyStreet::App::View::Email' } + +done_testing(); diff --git a/t/app/view/web.t b/t/app/view/web.t new file mode 100644 index 000000000..0f49b986b --- /dev/null +++ b/t/app/view/web.t @@ -0,0 +1,8 @@ +use strict; +use warnings; +use Test::More; +use Test::More; + +BEGIN { use_ok 'FixMyStreet::App::View::Web' } + +done_testing(); diff --git a/t/cobrand/loading.t b/t/cobrand/loading.t new file mode 100644 index 000000000..405ef4761 --- /dev/null +++ b/t/cobrand/loading.t @@ -0,0 +1,71 @@ +use strict; +use warnings; + +use Test::More; +use Sub::Override; + +use FixMyStreet; + +use_ok 'FixMyStreet::Cobrand'; + +# check that the allowed cobrands is correctly loaded from config +{ + my $allowed = FixMyStreet::Cobrand->get_allowed_cobrands; + ok $allowed, "got the allowed_cobrands"; + isa_ok $allowed, "ARRAY"; + cmp_ok scalar @$allowed, '>', 1, "got more than one"; + is join( '|', @$allowed ), FixMyStreet->config('ALLOWED_COBRANDS'), + "matches config value"; +} + +# fake the allowed cobrands for testing +my $override = Sub::Override->new( # + 'FixMyStreet::Cobrand::get_allowed_cobrands' => + sub { return ['emptyhomes'] } +); +is_deeply FixMyStreet::Cobrand->get_allowed_cobrands, ['emptyhomes'], + 'overidden get_allowed_cobrands'; + +sub run_host_tests { + my %host_tests = @_; + for my $host ( sort keys %host_tests ) { + is FixMyStreet::Cobrand->get_class_for_host($host), + "FixMyStreet::Cobrand::$host_tests{$host}", + "does $host -> F::C::$host_tests{$host}"; + } +} + +# get the cobrand class by host +run_host_tests( + 'www.fixmystreet.com' => 'Default', + 'reportemptyhomes.com' => 'EmptyHomes', + 'barnet.fixmystreet.com' => 'Default', # not in the allowed_cobrands list + 'some.odd.site.com' => 'Default', +); + +# now enable barnet too and check that it works +$override->replace( # + 'FixMyStreet::Cobrand::get_allowed_cobrands' => + sub { return [ 'emptyhomes', 'barnet' ] } +); + +# get the cobrand class by host +run_host_tests( + 'www.fixmystreet.com' => 'Default', + 'reportemptyhomes.com' => 'EmptyHomes', + 'barnet.fixmystreet.com' => 'Barnet', # found now it is in allowed_cobrands + 'some.odd.site.com' => 'Default', +); + +# check that the moniker works as expected both on class and object. +is FixMyStreet::Cobrand::EmptyHomes->moniker, 'emptyhomes', + 'class->moniker works'; +is FixMyStreet::Cobrand::EmptyHomes->new->moniker, 'emptyhomes', + 'object->moniker works'; + +# check is_default works +ok FixMyStreet::Cobrand::Default->is_default, '::Default is default'; +ok !FixMyStreet::Cobrand::EmptyHomes->is_default, '::Emptyhomes is not default'; + +# all done +done_testing(); diff --git a/t/fixmystreet.t b/t/fixmystreet.t new file mode 100644 index 000000000..d7f00b047 --- /dev/null +++ b/t/fixmystreet.t @@ -0,0 +1,37 @@ +use strict; +use warnings; +use Path::Class; + +use Test::More; +use Test::Exception; + +use_ok 'FixMyStreet'; + +# check that the path_to works +my $file_path = file(__FILE__)->absolute->stringify; +my $path_to_path = FixMyStreet->path_to('t/fixmystreet.t'); + +isa_ok $path_to_path, 'Path::Class::File'; +ok $path_to_path->is_absolute, "path is absolute"; +is "$path_to_path", $file_path, "got $file_path"; + +# check that the config gets loaded and is immutable +my $config = FixMyStreet->config; +isa_ok $config, 'HASH'; +is $config->{GAZE_URL}, 'http://gaze.mysociety.org/gaze', + "got GAZE_URL correctly"; +throws_ok( + sub { $config->{GAZE_URL} = 'some other value'; }, + qr/Modification of a read-only value attempted/, + 'attempt to change config caught' +); +is $config->{GAZE_URL}, 'http://gaze.mysociety.org/gaze', "GAZE_URL unchanged"; + +# check that we can get the value by key as well +is FixMyStreet->config('GAZE_URL'), 'http://gaze.mysociety.org/gaze', + "GAZE_URL correct when got by key"; +is FixMyStreet->config('BAD_KEY_DOES_NOT_EXIST'), undef, "config miss is undef"; + +# all done +done_testing(); + diff --git a/t/i18n.t b/t/i18n.t new file mode 100644 index 000000000..6a5d94fa2 --- /dev/null +++ b/t/i18n.t @@ -0,0 +1,39 @@ +use strict; +use warnings; + +use Test::More; + +use FixMyStreet; +use mySociety::Locale; + +# check that the mo files have been generated +die "You need to run 'commonlib/bin/gettext-makemo --quiet FixMyStreet' " + . "to generate the *.mo files needed." + unless -e FixMyStreet->path_to( + 'locale/cy_GB.UTF-8/LC_MESSAGES/FixMyStreet-EmptyHomes.mo'); + +# Example strings +my $english = "Sorry! Something's gone wrong."; +my $welsh = "Ymddiheuriadau! Mae rhywbeth wedi mynd o'i le."; + +# set english as the language +mySociety::Locale::negotiate_language( # + 'en-gb,English,en_GB|cy,Cymraeg,cy_GB', 'en_GB' +); + +mySociety::Locale::gettext_domain( 'FixMyStreet-EmptyHomes', 1 ); +mySociety::Locale::change(); +is _($english), $english, "english to english"; + +# set to welsh and check for translation +mySociety::Locale::change('cy'); +is _($english), $welsh, "english to welsh"; + +# check that being in a deep directory does not confuse the code +chdir FixMyStreet->path_to('t/app/controller') . ''; +mySociety::Locale::gettext_domain( 'FixMyStreet-EmptyHomes', 1, + FixMyStreet->path_to('locale')->stringify ); +mySociety::Locale::change('cy'); +is _($english), $welsh, "english to welsh (deep directory)"; + +done_testing(); |