diff --git a/t/app.t b/t/app.t
index 3a4f1b293f8e9e68d339ece5242252f02e491beb..37096ea3fad6007727b4621beef706b6eaea976b 100755
--- a/t/app.t
+++ b/t/app.t
@@ -12,6 +12,9 @@ use Test::HTML::Tidy5 qw();
 use Test::More;
 use Test::Mojo::WithRoles 'SubmitForm';
 
+use AccountManager::Data::DB;
+use AccountManager::Data::Entity;
+
 plan(skip_all => 'live database required') unless
     $ENV{TEST_DB_HOST} &&
     $ENV{TEST_DB_NAME} &&
@@ -19,7 +22,7 @@ plan(skip_all => 'live database required') unless
     $ENV{TEST_DB_USERNAME} &&
     $ENV{TEST_DB_PASSWORD};
 
-plan tests => 4;
+plan tests => 9;
 
 sub named_subtest {
     my ($name, $code, @args) = @_;
@@ -43,6 +46,27 @@ sub setup {
     system("mysql --host=$host --user=$username --password=$password $name < conf/manager.sql") == 0
         or die "can't run mysql: $CHILD_ERROR\n";
 
+    AccountManager::Data::DB->register_db(
+        driver   => $args{type},
+        host     => $host,
+        database => $name,
+        password => $password,
+        username => $username,
+    );
+    my $db = AccountManager::Data::DB->new();
+
+    my $entity = AccountManager::Data::Entity->new(
+        db               => $db,
+        type             => 'sp',
+        entityid         => 'https://sp.renater.fr/',
+        display_name     => 'https://sp.renater.fr/ (Test SP)',
+        information_url  => 'https://sp.renater.fr',
+        organization_url => 'http://www.renater.fr ',
+        contacts         => ['contact1@renater.fr', 'contact2@renater.fr'],
+        federations      => ['edugain'],
+    );
+    $entity->save();
+
     my $temp_dir = File::Temp->newdir(CLEANUP => $ENV{TEST_DEBUG} ? 0 : 1);
     diag("temp dir: $temp_dir") if $ENV{TEST_DEBUG};
 
@@ -160,13 +184,13 @@ named_subtest "SP selection page" => sub {
     $t->get_ok('/step1')
       ->status_is(200)
       ->text_is('html head title' => 'eduGAIN Access Check', 'expected title')
-      ->element_exists('select[id=all][name=all]', 'SP list');
+      ->element_exists('select[id=all][name=all]', 'SP selection widget');
 
     my $res = $t->tx()->res();
     html_ok($res) or diag_file($res, $test_dir);
 };
 
-named_subtest "email selection page, missing entityid parameter" => sub {
+named_subtest "email selection page, missing entityid" => sub {
     my $t = get_test_object(test => $_[0]);
 
     $t->get_ok('/step2' => form => {federation => 'edugain'})
@@ -178,7 +202,7 @@ named_subtest "email selection page, missing entityid parameter" => sub {
     html_ok($res) or diag_file($res, $test_dir);
 };
 
-named_subtest "email selection page, invalid entityid parameter" => sub {
+named_subtest "email selection page, invalid entityid" => sub {
     my $t = get_test_object(test => $_[0]);
 
     $t->get_ok('/step2' => form => {federation => 'edugain', entityid => 'foo'})
@@ -189,3 +213,63 @@ named_subtest "email selection page, invalid entityid parameter" => sub {
     my $res = $t->tx()->res();
     html_ok($res) or diag_file($res, $test_dir);
 };
+
+named_subtest "email selection page, valid entityid" => sub {
+    my $t = get_test_object(test => $_[0]);
+
+    $t->get_ok('/step2' => form => {federation => 'edugain', entityid => 'https://sp.renater.fr/'})
+      ->status_is(200)
+      ->text_is('html head title' => 'eduGAIN Access Check', 'expected title')
+      ->element_exists('input[name=email][value=contact1@renater.fr]', 'email selection widget');
+
+    my $res = $t->tx()->res();
+    html_ok($res) or diag_file($res, $test_dir);
+};
+
+named_subtest "challenge page, missing entityid" => sub {
+    my $t = get_test_object(test => $_[0]);
+
+    $t->get_ok('/step3' => form => {federation => 'edugain'})
+      ->status_is(200)
+      ->text_is('html head title' => 'eduGAIN Access Check', 'expected title')
+      ->content_like(qr/Error:[\n\s]+missing parameter 'entityid'/, 'expected error message');
+
+    my $res = $t->tx()->res();
+    html_ok($res) or diag_file($res, $test_dir);
+};
+
+named_subtest "challenge page, invalid entityid" => sub {
+    my $t = get_test_object(test => $_[0]);
+
+    $t->get_ok('/step3' => form => {federation => 'edugain', entityid => 'foo'})
+      ->status_is(200)
+      ->text_is('html head title' => 'eduGAIN Access Check', 'expected title')
+      ->content_like(qr/Error:[\n\s]+invalid parameter 'entityid'/, 'expected error message');
+
+    my $res = $t->tx()->res();
+    html_ok($res) or diag_file($res, $test_dir);
+};
+
+named_subtest "challenge page, valid entityid, missing email" => sub {
+    my $t = get_test_object(test => $_[0]);
+
+    $t->get_ok('/step3' => form => {federation => 'edugain', entityid => 'https://sp.renater.fr/'})
+      ->status_is(200)
+      ->text_is('html head title' => 'eduGAIN Access Check', 'expected title')
+      ->content_like(qr/Error:[\n\s]+missing parameter 'email'/, 'expected error message');
+
+    my $res = $t->tx()->res();
+    html_ok($res) or diag_file($res, $test_dir);
+};
+
+named_subtest "challenge page, valid entityid, invalid email" => sub {
+    my $t = get_test_object(test => $_[0]);
+
+    $t->get_ok('/step3' => form => {federation => 'edugain', entityid => 'https://sp.renater.fr/', email => 'foo'})
+      ->status_is(200)
+      ->text_is('html head title' => 'eduGAIN Access Check', 'expected title')
+      ->content_like(qr/Error:[\n\s]+invalid parameter 'email'/, 'expected error message');
+
+    my $res = $t->tx()->res();
+    html_ok($res) or diag_file($res, $test_dir);
+};