diff options
Diffstat (limited to 't')
-rw-r--r-- | t/authenticated-de.t | 112 | ||||
-rw-r--r-- | t/journey-edit.t (renamed from t/12-journey-edit.t) | 92 | ||||
-rw-r--r-- | t/journey-stats.t (renamed from t/11-journey-stats.t) | 87 | ||||
-rw-r--r-- | t/journey-visibility.t (renamed from t/23-journey-visibility.t) | 67 | ||||
-rw-r--r-- | t/past-visibility.t (renamed from t/24-past-visibility.t) | 43 | ||||
-rw-r--r-- | t/r-negative-delay.t | 21 | ||||
-rw-r--r-- | t/registration.t (renamed from t/02-registration.t) | 5 | ||||
-rw-r--r-- | t/relations.t (renamed from t/21-relations.t) | 2 | ||||
-rw-r--r-- | t/static-de.t (renamed from t/01-static.t) | 18 | ||||
-rw-r--r-- | t/static-en.t | 50 | ||||
-rw-r--r-- | t/static-fr.t | 50 | ||||
-rw-r--r-- | t/transit-visibility.t (renamed from t/22-transit-visibility.t) | 147 |
12 files changed, 529 insertions, 165 deletions
diff --git a/t/authenticated-de.t b/t/authenticated-de.t new file mode 100644 index 0000000..f6a9c5c --- /dev/null +++ b/t/authenticated-de.t @@ -0,0 +1,112 @@ +#!/usr/bin/env perl + +# Copyright (C) 2025 Birte Kristina Friesel <derf@finalrewind.org> +# +# SPDX-License-Identifier: MIT + +use Mojo::Base -strict; + +use Test::More; +use Test::Mojo; + +# Include application +use FindBin; +require "$FindBin::Bin/../index.pl"; + +my $t = Test::Mojo->new('Travelynx'); + +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + +if ( not $t->app->config->{db} ) { + plan( skip_all => 'No database configured' ); +} + +# Account boilerplate + +$t->app->pg->db->query('drop schema if exists travelynx_test_auth_de cascade'); +$t->app->pg->db->query('create schema travelynx_test_auth_de'); +$t->app->pg->db->query('set search_path to travelynx_test_auth_de'); +$t->app->pg->on( + connection => sub { + my ( $pg, $dbh ) = @_; + $dbh->do('set search_path to travelynx_test_auth_de'); + } +); + +$t->app->config->{mail}->{disabled} = 1; + +$ENV{__TRAVELYNX_TEST_MINI_IRIS} = 1; +$t->app->start( 'database', 'migrate' ); + +my $csrf_token + = $t->ua->get('/register')->res->dom->at('input[name=csrf_token]') + ->attr('value'); + +# Successful registration +$t->post_ok( + '/register' => form => { + csrf_token => $csrf_token, + dt => 1, + user => 'someone', + email => 'foo@example.org', + password => 'foofoofoo', + password2 => 'foofoofoo', + } +); +$t->status_is(200)->content_like(qr{Verifizierungslink}); + +my $res = $t->app->pg->db->select( 'users', ['id'], { name => 'someone' } ); +my $uid = $res->hash->{id}; +$res = $t->app->pg->db->select( 'pending_registrations', ['token'], + { user_id => $uid } ); +my $token = $res->hash->{token}; + +# Successful verification +$t->get_ok("/reg/${uid}/${token}"); +$t->status_is(200)->content_like(qr{freigeschaltet}); + +# Successful login +$t->post_ok( + '/login' => form => { + csrf_token => $csrf_token, + user => 'someone', + password => 'foofoofoo', + } +); +$t->status_is(302)->header_is( location => '/' ); + +# Actual Test + +$t->get_ok('/account')->status_is(200); +$t->text_like( 'a[href="/p/someone"]' => qr{Öffentliches Profil} ); +$t->text_like( 'a[href="/api"]' => qr{Dokumentation} ); + +for my $subpage (qw(privacy social profile hooks insight language)) { + $t->get_ok("/account/${subpage}")->status_is(200); + $t->text_like( 'button' => qr{Speichern} ); +} + +for my $subpage (qw(password mail name)) { + $t->get_ok("/account/${subpage}")->status_is(200); + $t->text_like( 'button' => qr{Ändern} ); +} + +$t->get_ok('/account/select_backend')->status_is(200); +$t->text_like( 'a[href="#help"]' => qr{Details} ); + +$t->get_ok('/account/traewelling')->status_is(200); +$t->text_like( 'button' => qr{Verknüpfen} ); + +$t->get_ok('/history')->status_is(200); +$t->text_like( 'a[href="/history/map"]' => qr{Fahrtenkarte} ); + +$t->get_ok('/history/map')->status_is(200); +$t->text_like( 'button[type="submit"]' => qr{Anzeigen} ); + +$t->get_ok('/history/commute')->status_is(200); +$t->text_like( 'button[type="submit"]' => qr{Anzeigen} ); + +$t->get_ok('/journey/add')->status_is(200); +$t->text_like( 'button[type="submit"]' => qr{Hinzufügen} ); + +done_testing(); diff --git a/t/12-journey-edit.t b/t/journey-edit.t index 27e309b..f0b2f36 100644 --- a/t/12-journey-edit.t +++ b/t/journey-edit.t @@ -16,9 +16,12 @@ use FindBin; require "$FindBin::Bin/../index.pl"; use DateTime; +use utf8; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } @@ -75,11 +78,12 @@ $t->post_ok( ); $t->status_is(302)->header_is( location => '/' ); -$t->app->journeys->add( +my ( $success, $error ) = $t->app->journeys->add( db => $t->app->pg->db, uid => $uid, - dep_station => 'EMST', - arr_station => 'EG', + backend_id => 1, + dep_station => 'Münster(Westf)Hbf', + arr_station => 'Gelsenkirchen Hbf', sched_departure => DateTime->new( year => 2018, month => 10, @@ -119,12 +123,22 @@ $t->app->journeys->add( comment => 'Huhu' ); -$t->get_ok('/journey/1')->status_is(200)->content_like(qr{M.nster\(Westf\)Hbf}) - ->content_like(qr{Gelsenkirchen Hbf})->content_like(qr{RE 11238}) - ->content_like(qr{Linie 42})->content_like(qr{..:36}) - ->content_like(qr{..:34})->content_like(qr{ca[.] 62 km}) - ->content_like(qr{Luftlinie: 62 km})->content_like(qr{64 km/h}) - ->content_like(qr{Huhu})->content_like(qr{Daten wurden manuell eingetragen}); +ok( $success, "journeys->add" ); +is( $error, undef, "journeys->add" ); + +$t->get_ok('/journey/1') + ->status_is(200) + ->content_like(qr{M.nster\(Westf\)Hbf}) + ->content_like(qr{Gelsenkirchen Hbf}) + ->content_like(qr{RE 11238}) + ->content_like(qr{Linie 42}) + ->content_like(qr{..:36}) + ->content_like(qr{..:34}) + ->content_like(qr{ca[.] 62 km}) + ->content_like(qr{Luftlinie: 62 km}) + ->content_like(qr{64 km/h}) + ->content_like(qr{Huhu}) + ->content_like(qr{Daten wurden manuell eingetragen}); $t->post_ok( '/journey/edit' => form => { @@ -133,10 +147,14 @@ $t->post_ok( } ); -$t->status_is(200)->content_like(qr{M.nster\(Westf\)Hbf}) - ->content_like(qr{Gelsenkirchen Hbf})->content_like(qr{RE 11238}) - ->content_like(qr{Linie 42})->content_like(qr{16.10.2018 ..:36}) - ->content_like(qr{16.10.2018 ..:34})->content_like(qr{Huhu}); +$t->status_is(200) + ->content_like(qr{M.nster\(Westf\)Hbf}) + ->content_like(qr{Gelsenkirchen Hbf}) + ->content_like(qr{RE 11238}) + ->content_like(qr{Linie 42}) + ->content_like(qr{16.10.2018 ..:36}) + ->content_like(qr{16.10.2018 ..:34}) + ->content_like(qr{Huhu}); $csrf_token = $t->tx->res->dom->at('input[name=csrf_token]')->attr('value'); @@ -156,12 +174,19 @@ $t->post_ok( $t->status_is(302)->header_is( location => '/journey/1' ); -$t->get_ok('/journey/1')->status_is(200)->content_like(qr{M.nster\(Westf\)Hbf}) - ->content_like(qr{Gelsenkirchen Hbf})->content_like(qr{RE 11238}) - ->content_like(qr{Linie 42})->content_like(qr{..:36}) - ->content_like(qr{..:34})->content_like(qr{ca[.] 62 km}) - ->content_like(qr{Luftlinie: 62 km})->content_like(qr{64 km/h}) - ->content_like(qr{Huhu})->content_like(qr{Daten wurden manuell eingetragen}); +$t->get_ok('/journey/1') + ->status_is(200) + ->content_like(qr{M.nster\(Westf\)Hbf}) + ->content_like(qr{Gelsenkirchen Hbf}) + ->content_like(qr{RE 11238}) + ->content_like(qr{Linie 42}) + ->content_like(qr{..:36}) + ->content_like(qr{..:34}) + ->content_like(qr{ca[.] 62 km}) + ->content_like(qr{Luftlinie: 62 km}) + ->content_like(qr{64 km/h}) + ->content_like(qr{Huhu}) + ->content_like(qr{Daten wurden manuell eingetragen}); $t->post_ok( '/journey/edit' => form => { @@ -170,10 +195,14 @@ $t->post_ok( } ); -$t->status_is(200)->content_like(qr{M.nster\(Westf\)Hbf}) - ->content_like(qr{Gelsenkirchen Hbf})->content_like(qr{RE 11238}) - ->content_like(qr{Linie 42})->content_like(qr{16.10.2018 ..:36}) - ->content_like(qr{16.10.2018 ..:34})->content_like(qr{Huhu}); +$t->status_is(200) + ->content_like(qr{M.nster\(Westf\)Hbf}) + ->content_like(qr{Gelsenkirchen Hbf}) + ->content_like(qr{RE 11238}) + ->content_like(qr{Linie 42}) + ->content_like(qr{16.10.2018 ..:36}) + ->content_like(qr{16.10.2018 ..:34}) + ->content_like(qr{Huhu}); $csrf_token = $t->tx->res->dom->at('input[name=csrf_token]')->attr('value'); @@ -193,13 +222,18 @@ $t->post_ok( $t->status_is(302)->header_is( location => '/journey/1' ); -$t->get_ok('/journey/1')->status_is(200)->content_like(qr{M.nster\(Westf\)Hbf}) - ->content_like(qr{Gelsenkirchen Hbf})->content_like(qr{RE 11238}) +$t->get_ok('/journey/1') + ->status_is(200) + ->content_like(qr{M.nster\(Westf\)Hbf}) + ->content_like(qr{Gelsenkirchen Hbf}) + ->content_like(qr{RE 11238}) ->content_like(qr{Linie 42}) - ->content_like(qr{..:42\s*\(\+6,\s*Plan: ..:36\)}) - ->content_like(qr{..:33\s*\(-1,\s*Plan: ..:34\)}) - ->content_like(qr{ca[.] 62 km})->content_like(qr{Luftlinie: 62 km}) - ->content_like(qr{73 km/h})->content_like(qr{Huhu}) + ->content_like(qr{..:42 \s*\n*\s* \(\+6, \s*Plan: \s*\n*\s* ..:36\)}mx) + ->content_like(qr{..:33 \s*\n*\s* \( -1, \s*Plan: \s*\n*\s* ..:34\)}mx) + ->content_like(qr{ca[.] 62 km}) + ->content_like(qr{Luftlinie: 62 km}) + ->content_like(qr{73 km/h}) + ->content_like(qr{Huhu}) ->content_like(qr{Daten wurden manuell eingetragen}); $t->app->pg->db->query('drop schema travelynx_test_12 cascade'); diff --git a/t/11-journey-stats.t b/t/journey-stats.t index 9853b85..205bf96 100644 --- a/t/11-journey-stats.t +++ b/t/journey-stats.t @@ -17,6 +17,8 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } @@ -81,36 +83,49 @@ $t->post_ok( csrf_token => $csrf_token, action => 'save', train => 'RE 42 11238', - dep_station => 'EMST', - sched_departure => '16.10.2018 17:36', - rt_departure => '16.10.2018 17:36', + dep_station => 'EMSTP', + sched_departure => '2018-10-16T17:36', + rt_departure => '2018-10-16T17:36', arr_station => 'EG', - sched_arrival => '16.10.2018 18:34', - rt_arrival => '16.10.2018 18:34', + sched_arrival => '2018-10-16T18:34', + rt_arrival => '2018-10-16T18:34', comment => 'Passierschein A38', } ); $t->status_is(302)->header_is( location => '/journey/1' ); -$t->get_ok('/journey/1')->status_is(200)->content_like(qr{M.nster\(Westf\)Hbf}) - ->content_like(qr{Gelsenkirchen Hbf})->content_like(qr{RE 11238}) - ->content_like(qr{Linie 42})->content_like(qr{..:36}) - ->content_like(qr{..:34})->content_like(qr{ca[.] 62 km}) - ->content_like(qr{Luftlinie: 62 km})->content_like(qr{64 km/h}) +$t->get_ok('/journey/1') + ->status_is(200) + ->content_like(qr{M.nster\(Westf\)Hbf}) + ->content_like(qr{Gelsenkirchen Hbf}) + ->content_like(qr{RE 11238}) + ->content_like(qr{Linie 42}) + ->content_like(qr{..:36}) + ->content_like(qr{..:34}) + ->content_like(qr{ca[.] 62 km}) + ->content_like(qr{Luftlinie: 62 km}) + ->content_like(qr{64 km/h}) ->content_like(qr{Passierschein A38}) ->content_like(qr{Daten wurden manuell eingetragen}); -$t->get_ok('/history/2018/10')->status_is(200)->content_like(qr{62 km}) - ->content_like(qr{00:58 Stunden})->content_like(qr{00:00 Stunden}) +$t->get_ok('/history/2018/10') + ->status_is(200) + ->content_like(qr{62 km}) + ->content_like(qr{00:58 Stunden}) + ->content_like(qr{00:00 Stunden}) ->content_like(qr{Bei Abfahrt: 00:00 Stunden}) ->content_like(qr{Bei Ankunft: 00:00 Stunden}); -$t->get_ok('/history/2018')->status_is(200)->content_like(qr{62 km}) - ->content_like(qr{00:58 Stunden})->content_like(qr{00:00 Stunden}) +$t->get_ok('/history/2018') + ->status_is(200) + ->content_like(qr{62 km}) + ->content_like(qr{00:58 Stunden}) + ->content_like(qr{00:00 Stunden}) ->content_like(qr{Bei Abfahrt: 00:00 Stunden}) ->content_like(qr{Bei Ankunft: 00:00 Stunden}); -$t->get_ok('/history/map')->status_is(200) +$t->get_ok('/history/map') + ->status_is(200) ->content_like(qr{\[\[51.956[^,]*,7.635[^]]*\],'M.nster\(Westf\)Hbf'\],}) ->content_like(qr{\[\[51.504[^,]*,7.102[^]]*\],'Gelsenkirchen Hbf'\]}); @@ -122,24 +137,30 @@ $t->post_ok( csrf_token => $csrf_token, action => 'save', train => 'RE 42 11238', - dep_station => 'EMST', - sched_departure => '16.11.2018 17:36', - rt_departure => '16.11.2018 17:45', + dep_station => 'EMSTP', + sched_departure => '2018-11-16T17:36', + rt_departure => '2018-11-16T17:45', arr_station => 'EG', - sched_arrival => '16.11.2018 18:34', - rt_arrival => '16.11.2018 19:00', + sched_arrival => '2018-11-16T18:34', + rt_arrival => '2018-11-16T19:00', } ); $t->status_is(302)->header_is( location => '/journey/2' ); -$t->get_ok('/history/2018/11')->status_is(200)->content_like(qr{62 km}) - ->content_like(qr{01:15 Stunden})->content_like(qr{nach Fahrplan: 00:58}) +$t->get_ok('/history/2018/11') + ->status_is(200) + ->content_like(qr{62 km}) + ->content_like(qr{01:15 Stunden}) + ->content_like(qr{nach Fahrplan: 00:58}) ->content_like(qr{00:00 Stunden}) ->content_like(qr{Bei Abfahrt: 00:09 Stunden}) ->content_like(qr{Bei Ankunft: 00:26 Stunden}); -$t->get_ok('/history/2018')->status_is(200)->content_like(qr{124 km}) - ->content_like(qr{02:13 Stunden})->content_like(qr{nach Fahrplan: 01:56}) +$t->get_ok('/history/2018') + ->status_is(200) + ->content_like(qr{124 km}) + ->content_like(qr{02:13 Stunden}) + ->content_like(qr{nach Fahrplan: 01:56}) ->content_like(qr{00:00 Stunden}) ->content_like(qr{Bei Abfahrt: 00:09 Stunden}) ->content_like(qr{Bei Ankunft: 00:26 Stunden}); @@ -153,23 +174,29 @@ $t->post_ok( action => 'save', train => 'ICE 1', dep_station => 'EE', - sched_departure => '17.11.2018 15:42', + sched_departure => '2018-11-17T15:42', rt_departure => '', arr_station => 'BL', - sched_arrival => '17.11.2018 19:42', + sched_arrival => '2018-11-17T19:42', rt_arrival => '', } ); $t->status_is(302)->header_is( location => '/journey/3' ); -$t->get_ok('/history/2018/11')->status_is(200)->content_like(qr{513 km}) - ->content_like(qr{05:15 Stunden})->content_like(qr{nach Fahrplan: 04:58}) +$t->get_ok('/history/2018/11') + ->status_is(200) + ->content_like(qr{513 km}) + ->content_like(qr{05:15 Stunden}) + ->content_like(qr{nach Fahrplan: 04:58}) ->content_like(qr{00:00 Stunden}) ->content_like(qr{Bei Abfahrt: 00:09 Stunden}) ->content_like(qr{Bei Ankunft: 00:26 Stunden}); -$t->get_ok('/history/2018')->status_is(200)->content_like(qr{576 km}) - ->content_like(qr{06:13 Stunden})->content_like(qr{nach Fahrplan: 05:56}) +$t->get_ok('/history/2018') + ->status_is(200) + ->content_like(qr{576 km}) + ->content_like(qr{06:13 Stunden}) + ->content_like(qr{nach Fahrplan: 05:56}) ->content_like(qr{00:00 Stunden}) ->content_like(qr{Bei Abfahrt: 00:09 Stunden}) ->content_like(qr{Bei Ankunft: 00:26 Stunden}); diff --git a/t/23-journey-visibility.t b/t/journey-visibility.t index 2124940..c2294b3 100644 --- a/t/23-journey-visibility.t +++ b/t/journey-visibility.t @@ -20,6 +20,8 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } @@ -110,20 +112,24 @@ sub test_journey_visibility { $opt{effective_visibility_str}, $desc ); if ( $opt{public} ) { - $t->get_ok("/p/test1/j/$jid")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid")->status_is(404) + $t->get_ok("/p/test1/j/$jid") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } if ( $opt{with_token} ) { - $t->get_ok("/p/test1/j/$jid$token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid$token")->status_is(404) + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } @@ -134,21 +140,25 @@ sub test_journey_visibility { # users can see their own status if visibility is >= followrs if ( $opt{effective_visibility} >= 60 ) { - $t->get_ok("/p/test1/j/$jid")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid")->status_is(404) + $t->get_ok("/p/test1/j/$jid") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } # users can see their own status with token if visibility is >= unlisted if ( $opt{effective_visibility} >= 30 ) { - $t->get_ok("/p/test1/j/$jid$token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid$token")->status_is(404) + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } @@ -160,21 +170,25 @@ sub test_journey_visibility { # uid2 can see uid1 if visibility is >= followers if ( $opt{effective_visibility} >= 60 ) { - $t->get_ok("/p/test1/j/$jid")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid")->status_is(404) + $t->get_ok("/p/test1/j/$jid") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } # uid2 can see uid1 with token if visibility is >= unlisted if ( $opt{effective_visibility} >= 30 ) { - $t->get_ok("/p/test1/j/$jid$token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid$token")->status_is(404) + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } @@ -186,21 +200,25 @@ sub test_journey_visibility { # uid3 can see uid1 if visibility is >= travelynx if ( $opt{effective_visibility} >= 80 ) { - $t->get_ok("/p/test1/j/$jid")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid")->status_is(404) + $t->get_ok("/p/test1/j/$jid") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } # uid3 can see uid1 with token if visibility is >= unlisted if ( $opt{effective_visibility} >= 30 ) { - $t->get_ok("/p/test1/j/$jid$token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/p/test1/j/$jid$token")->status_is(404) + $t->get_ok("/p/test1/j/$jid$token") + ->status_is(404) ->content_like(qr{Fahrt nicht gefunden.}); } @@ -303,6 +321,7 @@ $t->app->in_transit->add( departure_eva => 8000001, train => $train_dep, route => [], + backend_id => $t->app->stations->get_backend_id( iris => 1 ), ); $t->app->in_transit->set_arrival_eva( uid => $uid1, diff --git a/t/24-past-visibility.t b/t/past-visibility.t index 51c8081..5c084b2 100644 --- a/t/24-past-visibility.t +++ b/t/past-visibility.t @@ -20,6 +20,8 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } @@ -115,12 +117,14 @@ sub test_history_visibility { = "history vis=$opt{set_past_visibility} journey=$jid vis=$journey->{effective_visibility_str}"; if ( $opt{public} ) { - $t->get_ok('/p/test1')->status_is(200) - ->content_like( qr{DPN 667}, "public $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_like( qr{DPN\s*667}, "public $desc" ); } else { - $t->get_ok('/p/test1')->status_is(200) - ->content_unlike( qr{DPN 667}, "public $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_unlike( qr{DPN\s*667}, "public $desc" ); } login( @@ -129,12 +133,14 @@ sub test_history_visibility { ); if ( $opt{self} ) { - $t->get_ok('/p/test1')->status_is(200) - ->content_like( qr{DPN 667}, "self $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_like( qr{DPN\s*667}, "self $desc" ); } else { - $t->get_ok('/p/test1')->status_is(200) - ->content_unlike( qr{DPN 667}, "self $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_unlike( qr{DPN\s*667}, "self $desc" ); } logout(); @@ -144,12 +150,14 @@ sub test_history_visibility { ); if ( $opt{followers} ) { - $t->get_ok('/p/test1')->status_is(200) - ->content_like( qr{DPN 667}, "follower $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_like( qr{DPN\s*667}, "follower $desc" ); } else { - $t->get_ok('/p/test1')->status_is(200) - ->content_unlike( qr{DPN 667}, "follower $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_unlike( qr{DPN\s*667}, "follower $desc" ); } logout(); @@ -159,12 +167,14 @@ sub test_history_visibility { ); if ( $opt{travelynx} ) { - $t->get_ok('/p/test1')->status_is(200) - ->content_like( qr{DPN 667}, "travelynx $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_like( qr{DPN\s*667}, "travelynx $desc" ); } else { - $t->get_ok('/p/test1')->status_is(200) - ->content_unlike( qr{DPN 667}, "travelynx $desc" ); + $t->get_ok('/p/test1') + ->status_is(200) + ->content_unlike( qr{DPN\s*667}, "travelynx $desc" ); } logout(); @@ -266,6 +276,7 @@ $t->app->in_transit->add( departure_eva => 8000001, train => $train_dep, route => [], + backend_id => $t->app->stations->get_backend_id( iris => 1 ), ); $t->app->in_transit->set_arrival_eva( uid => $uid1, diff --git a/t/r-negative-delay.t b/t/r-negative-delay.t index 78bd6e0..9f87510 100644 --- a/t/r-negative-delay.t +++ b/t/r-negative-delay.t @@ -17,6 +17,8 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } @@ -82,18 +84,21 @@ $t->post_ok( csrf_token => $csrf_token, action => 'save', train => 'RE 42 11238', - dep_station => 'EMST', - sched_departure => '16.10.2018 17:36', - rt_departure => '16.10.2018 17:35', + dep_station => 'EMSTP', + sched_departure => '2018-10-16T17:36', + rt_departure => '2018-10-16T17:35', arr_station => 'EG', - sched_arrival => '16.10.2018 18:34', - rt_arrival => '16.10.2018 18:32', + sched_arrival => '2018-10-16T18:34', + rt_arrival => '2018-10-16T18:32', } ); -$t->status_is(302)->header_is( location => '/journey/1' ); +$t->status_is(302)->header_is( location => '/journey/1' )->content_is(q{}); -$t->get_ok('/history/2018/10')->status_is(200)->content_like(qr{62 km}) - ->content_like(qr{00:57 Stunden})->content_like(qr{nach Fahrplan: 00:58}) +$t->get_ok('/history/2018/10') + ->status_is(200) + ->content_like(qr{62 km}) + ->content_like(qr{00:57 Stunden}) + ->content_like(qr{nach Fahrplan: 00:58}) ->content_like(qr{Bei Abfahrt: -00:01 Stunden}) ->content_like(qr{Bei Ankunft: -00:02 Stunden}); diff --git a/t/02-registration.t b/t/registration.t index 799022f..ec09eaf 100644 --- a/t/02-registration.t +++ b/t/registration.t @@ -17,6 +17,8 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } @@ -206,7 +208,8 @@ $res = $t->app->pg->db->select( 'pending_passwords', ['token'], { user_id => $uid } ); $token = $res->hash->{token}; -$t->get_ok("/recover/${uid}/${token}")->status_is(200) +$t->get_ok("/recover/${uid}/${token}") + ->status_is(200) ->content_like(qr{Neues Passwort eintragen}); $t->post_ok( diff --git a/t/21-relations.t b/t/relations.t index 857d20d..c5fbe32 100644 --- a/t/21-relations.t +++ b/t/relations.t @@ -17,6 +17,8 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } diff --git a/t/01-static.t b/t/static-de.t index 3727f1e..21d0350 100644 --- a/t/01-static.t +++ b/t/static-de.t @@ -15,20 +15,28 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + $t->get_ok('/')->status_is(200); $t->text_like( 'a[href="/register"]' => qr{Registrieren} ); $t->text_like( 'a[href="/login"]' => qr{Anmelden} ); -$t->get_ok('/register')->status_is(200); -$t->element_exists('input[name="csrf_token"]'); -$t->element_exists('a[href="/impressum"]'); -$t->text_like( 'button' => qr{Registrieren} ); +$t->get_ok('/about')->status_is(200); +$t->get_ok('/api')->status_is(200); +$t->get_ok('/changelog')->status_is(200); +$t->get_ok('/legend')->status_is(200); +$t->get_ok('/offline.html')->status_is(200); $t->get_ok('/login')->status_is(200); $t->element_exists('input[name="csrf_token"]'); $t->text_like( 'button' => qr{Anmelden} ); -$t->get_ok('/about')->status_is(200); +$t->get_ok('/recover')->status_is(200); + +$t->get_ok('/register')->status_is(200); +$t->element_exists('input[name="csrf_token"]'); +$t->element_exists('a[href="/impressum"]'); +$t->text_like( 'button' => qr{Registrieren} ); # Protected sites should redirect to login form diff --git a/t/static-en.t b/t/static-en.t new file mode 100644 index 0000000..26641cb --- /dev/null +++ b/t/static-en.t @@ -0,0 +1,50 @@ +#!/usr/bin/env perl + +# Copyright (C) 2020 Birte Kristina Friesel <derf@finalrewind.org> +# +# SPDX-License-Identifier: MIT + +use Mojo::Base -strict; + +use Test::More; +use Test::Mojo; + +# Include application +use FindBin; +require "$FindBin::Bin/../index.pl"; + +my $t = Test::Mojo->new('Travelynx'); + +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('en-GB') } ); + +$t->get_ok('/')->status_is(200); +$t->text_like( 'a[href="/register"]' => qr{Register} ); +$t->text_like( 'a[href="/login"]' => qr{Login} ); + +$t->get_ok('/about')->status_is(200); +$t->get_ok('/api')->status_is(200); +$t->get_ok('/changelog')->status_is(200); +$t->get_ok('/legend')->status_is(200); +$t->get_ok('/offline.html')->status_is(200); + +$t->get_ok('/login')->status_is(200); +$t->element_exists('input[name="csrf_token"]'); +$t->text_like( 'button' => qr{Login} ); + +$t->get_ok('/recover')->status_is(200); + +$t->get_ok('/register')->status_is(200); +$t->element_exists('input[name="csrf_token"]'); +$t->element_exists('a[href="/impressum"]'); +$t->text_like( 'button' => qr{Register} ); + +# Protected sites should redirect to login form + +for my $protected (qw(/account /account/password /history /s/EE)) { + $t->get_ok($protected)->text_like( 'button' => qr{Login} ); +} + +# Otherwise, we expect a 404 +$t->get_ok('/definitelydoesnotexist')->status_is(404); + +done_testing(); diff --git a/t/static-fr.t b/t/static-fr.t new file mode 100644 index 0000000..dc4c278 --- /dev/null +++ b/t/static-fr.t @@ -0,0 +1,50 @@ +#!/usr/bin/env perl + +# Copyright (C) 2020 Birte Kristina Friesel <derf@finalrewind.org> +# +# SPDX-License-Identifier: MIT + +use Mojo::Base -strict; + +use Test::More; +use Test::Mojo; + +# Include application +use FindBin; +require "$FindBin::Bin/../index.pl"; + +my $t = Test::Mojo->new('Travelynx'); + +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('fr-FR') } ); + +$t->get_ok('/')->status_is(200); +$t->text_like( 'a[href="/register"]' => qr{Inscription} ); +$t->text_like( 'a[href="/login"]' => qr{Connexion} ); + +$t->get_ok('/about')->status_is(200); +$t->get_ok('/api')->status_is(200); +$t->get_ok('/changelog')->status_is(200); +$t->get_ok('/legend')->status_is(200); +$t->get_ok('/offline.html')->status_is(200); + +$t->get_ok('/login')->status_is(200); +$t->element_exists('input[name="csrf_token"]'); +$t->text_like( 'button' => qr{Connexion} ); + +$t->get_ok('/recover')->status_is(200); + +$t->get_ok('/register')->status_is(200); +$t->element_exists('input[name="csrf_token"]'); +$t->element_exists('a[href="/impressum"]'); +$t->text_like( 'button' => qr{Inscription} ); + +# Protected sites should redirect to login form + +for my $protected (qw(/account /account/password /history /s/EE)) { + $t->get_ok($protected)->text_like( 'button' => qr{Connexion} ); +} + +# Otherwise, we expect a 404 +$t->get_ok('/definitelydoesnotexist')->status_is(404); + +done_testing(); diff --git a/t/22-transit-visibility.t b/t/transit-visibility.t index 7e995c5..6aa48ed 100644 --- a/t/22-transit-visibility.t +++ b/t/transit-visibility.t @@ -20,6 +20,8 @@ require "$FindBin::Bin/../index.pl"; my $t = Test::Mojo->new('Travelynx'); +$t->ua->on( start => sub { $_[1]->req->headers->accept_language('de-DE') } ); + if ( not $t->app->config->{db} ) { plan( skip_all => 'No database configured' ); } @@ -108,30 +110,40 @@ sub test_intransit_visibility { $opt{effective_visibility_str}, $desc ); if ( $opt{public} ) { - $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667}); + $t->get_ok('/status/test1') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667}); } else { - $t->get_ok('/status/test1')->status_is(200) + $t->get_ok('/status/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/p/test1')->status_is(200) + $t->get_ok('/p/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } if ( $opt{with_token} ) { - $t->get_ok("/status/test1/$token")->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/status/test1/$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/status/test1/$token")->status_is(200) + $t->get_ok("/status/test1/$token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } @@ -142,31 +154,41 @@ sub test_intransit_visibility { # users can see their own status if visibility is >= followrs if ( $opt{effective_visibility} >= 60 ) { - $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667}); + $t->get_ok('/status/test1') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667}); } else { - $t->get_ok('/status/test1')->status_is(200) + $t->get_ok('/status/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/p/test1')->status_is(200) + $t->get_ok('/p/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } # users can see their own status with token if visibility is >= unlisted if ( $opt{effective_visibility} >= 30 ) { - $t->get_ok("/status/test1/$token")->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/status/test1/$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/status/test1/$token")->status_is(200) + $t->get_ok("/status/test1/$token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } @@ -178,31 +200,41 @@ sub test_intransit_visibility { # uid2 can see uid1 if visibility is >= followers if ( $opt{effective_visibility} >= 60 ) { - $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667}); + $t->get_ok('/status/test1') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667}); } else { - $t->get_ok('/status/test1')->status_is(200) + $t->get_ok('/status/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/p/test1')->status_is(200) + $t->get_ok('/p/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } # uid2 can see uid1 with token if visibility is >= unlisted if ( $opt{effective_visibility} >= 30 ) { - $t->get_ok("/status/test1/$token")->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/status/test1/$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/status/test1/$token")->status_is(200) + $t->get_ok("/status/test1/$token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } @@ -214,31 +246,41 @@ sub test_intransit_visibility { # uid3 can see uid1 if visibility is >= travelynx if ( $opt{effective_visibility} >= 80 ) { - $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667}); + $t->get_ok('/status/test1') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667}); } else { - $t->get_ok('/status/test1')->status_is(200) + $t->get_ok('/status/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/ajax/status/test1.html')->status_is(200) + $t->get_ok('/ajax/status/test1.html') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok('/p/test1')->status_is(200) + $t->get_ok('/p/test1') + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } # uid3 can see uid1 with token if visibility is >= unlisted if ( $opt{effective_visibility} >= 30 ) { - $t->get_ok("/status/test1/$token")->status_is(200) - ->content_like(qr{DPN 667}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) - ->content_like(qr{DPN 667}); + $t->get_ok("/status/test1/$token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) + ->content_like(qr{DPN\s*667}); } else { - $t->get_ok("/status/test1/$token")->status_is(200) + $t->get_ok("/status/test1/$token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); - $t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200) + $t->get_ok("/ajax/status/test1.html?token=$j_token") + ->status_is(200) ->content_like(qr{nicht eingecheckt}); } @@ -341,6 +383,7 @@ $t->app->in_transit->add( departure_eva => 8000001, train => $train_dep, route => [], + backend_id => $t->app->stations->get_backend_id( iris => 1 ), ); $t->app->in_transit->set_arrival_eva( uid => $uid1, |