
public class Test
{
    private static MainWindow setup ()
    {
        GLib.Test.log_set_fatal_handler (ignore_warnings);

        TestMainWindow main_window = new TestMainWindow ();
        var list = new TestList (main_window.get_background (), main_window.menubar);
        main_window.push_list (list);
        main_window.show_all();
        // Make sure we are really shown
        process_events ();

        return main_window;
    }

    private static bool ignore_warnings (string? log_domain,
                                         GLib.LogLevelFlags log_level,
                                         string message)
    {
        return ((log_level & (GLib.LogLevelFlags.LEVEL_CRITICAL |
                              GLib.LogLevelFlags.LEVEL_ERROR)) != 0);
    }

    private static void process_events ()
    {
        while (Gtk.events_pending ())
            Gtk.main_iteration ();
    }

    private static void wait_for_scrolling_end (TestList list)
    {
        while (list.is_scrolling ())
        {
            process_events ();
            Posix.usleep (10000);
        }
    }

    // BEGIN This group of functions asume email/password for remote directory servers
    private static DashEntry remote_directory_entry_email_field (TestList list)
    {
        var fixed = list.selected_entry.get_child() as Gtk.Fixed;
        var grid = fixed.get_children().nth_data(1) as Gtk.Grid;
        return grid.get_child_at(1, 1) as DashEntry;
    }

    private static DashEntry remote_directory_entry_password_field (TestList list)
    {
        var fixed = list.selected_entry.get_child() as Gtk.Fixed;
        var grid = fixed.get_children().nth_data(1) as Gtk.Grid;
        return grid.get_child_at(1, 2) as DashEntry;
    }
    // END This group of functions asume email/password for remote directory servers

    // BEGIN This group of functions asume domain/username/password for remote login servers
    private static DashEntry remote_login_entry_domain_field (TestList list)
    {
        var fixed = list.selected_entry.get_child() as Gtk.Fixed;
        var grid = fixed.get_children().nth_data(1) as Gtk.Grid;
        return grid.get_child_at(1, 1) as DashEntry;
    }

    private static DashEntry remote_login_entry_username_field (TestList list)
    {
        var fixed = list.selected_entry.get_child() as Gtk.Fixed;
        var grid = fixed.get_children().nth_data(1) as Gtk.Grid;
        return grid.get_child_at(1, 2) as DashEntry;
    }

    private static DashEntry remote_login_entry_password_field (TestList list)
    {
        var fixed = list.selected_entry.get_child() as Gtk.Fixed;
        var grid = fixed.get_children().nth_data(1) as Gtk.Grid;
        return grid.get_child_at(1, 3) as DashEntry;
    }
    // BEGIN This group of functions asume domain/username/password for remote login servers

    private static void do_scroll (TestList list, GreeterList.ScrollTarget direction)
    {
        process_events ();
        switch (direction)
        {
            case GreeterList.ScrollTarget.START:
                inject_key (list, Gdk.Key.Page_Up);
            break;
            case GreeterList.ScrollTarget.END:
                inject_key (list, Gdk.Key.Page_Down);
            break;
            case GreeterList.ScrollTarget.UP:
                inject_key (list, Gdk.Key.Up);
            break;
            case GreeterList.ScrollTarget.DOWN:
                inject_key (list, Gdk.Key.Down);
            break;
        }
        wait_for_scrolling_end (list);
    }

    private static void scroll_to_remote_login (TestList list)
    {
        do_scroll (list, GreeterList.ScrollTarget.END);
        while (list.selected_entry.id == "*guest")
        {
            do_scroll (list, GreeterList.ScrollTarget.END);
            process_events ();
            Posix.usleep (10000);
        }
    }

    private static void inject_key (Gtk.Widget w, int keyval)
    {
        // Make sure everything is flushed
        process_events ();

        Gdk.KeymapKey[] keys;

        bool success = Gdk.Keymap.get_default ().get_entries_for_keyval (keyval, out keys);
        GLib.assert (success);
        Gdk.Event event = new Gdk.Event(Gdk.EventType.KEY_PRESS);
        event.key.window = w.get_parent_window ();
        event.key.hardware_keycode = (int16)keys[0].keycode;
        event.key.keyval = keyval;
        event.set_device(Gdk.Display.get_default ().get_device_manager ().get_client_pointer ());
        event.key.time = Gdk.CURRENT_TIME;

        Gtk.main_do_event (event);
    }

    private static void wait_for_focus (Gtk.Widget w)
    {
        while (!w.has_focus)
        {
            process_events ();
            Posix.usleep (10000);
        }
    }

    public static void simple_navigation ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        GLib.assert (list.num_entries() > 0);

        // Make sure we are at the beginning of the list
        do_scroll (list, GreeterList.ScrollTarget.START);
        GLib.assert (list.selected_entry.id == "active");

        // Scrolling up does nothing
        do_scroll (list, GreeterList.ScrollTarget.UP);
        GLib.assert (list.selected_entry.id == "active");

        // Scrolling down works
        do_scroll (list, GreeterList.ScrollTarget.DOWN);
        GLib.assert (list.selected_entry.id == "auth-error");

        // Remote Login is at the end;
        do_scroll (list, GreeterList.ScrollTarget.END);
        GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");

        mw.hide ();
    }

    public static void remote_login ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);
        GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");
        GLib.assert (!list.selected_entry.has_errors);

        // If we answer without filling in any field -> error
        list.selected_entry.respond ({});
        GLib.assert (list.selected_entry.has_errors);

        // Go to first and back to last to clear the error
        do_scroll (list, GreeterList.ScrollTarget.START);
        do_scroll (list, GreeterList.ScrollTarget.END);
        GLib.assert (!list.selected_entry.has_errors);

        // Fill in a valid email and password
        // Check there is no error and we moved to the last logged in server
        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "password";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");
        wait_for_scrolling_end (list);

        // Go back to the remote_directory entry and write the same password but an invalid email
        // Check there is error and we did not move anywhere
        while (!list.selected_entry.id.has_prefix("*remote_directory*http://crazyurl.com"))
            do_scroll (list, GreeterList.ScrollTarget.UP);
        email = remote_directory_entry_email_field (list);
        pwd = remote_directory_entry_password_field (list);
        email.text = "a @ foobar";
        pwd.text = "password";
        list.selected_entry.respond ({});
        GLib.assert (list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");

        mw.hide ();
    }

    public static void remote_login_servers_updated_signal ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "delay1";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");

        bool done = false;
        // The delay1 code triggers at 5 seconds
        Timeout.add (5250, () =>
            {
                // If the directory server where were browsing disappears the login servers are removed too
                // and we get moved to the new directory server
                wait_for_scrolling_end (list);
                GLib.assert (list.selected_entry.id == "*remote_directory*http://internalcompayserver.com");
                done = true;
                return false;
            }
        );

        while (!done)
        {
            process_events ();
            Posix.usleep (10000);
        }

        mw.hide ();
    }

    public static void remote_login_servers_updated_signal_focus_not_in_remote_server ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "delay1";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");
        wait_for_scrolling_end (list);

        while (list.selected_entry.id.has_prefix("*remote_"))
        {
            do_scroll (list, GreeterList.ScrollTarget.UP);
        }
        string nonRemoteEntry = list.selected_entry.id;

        bool done = false;
        // The delay1 code triggers at 5 seconds
        Timeout.add (5250, () =>
            {
                // If we were not in a remote entry we are not moved even if the directory servers change
                // Moving down we find the new directory server
                GLib.assert (list.selected_entry.id == nonRemoteEntry);
                do_scroll (list, GreeterList.ScrollTarget.DOWN);
                GLib.assert (list.selected_entry.id == "*remote_directory*http://internalcompayserver.com");
                done = true;
                return false;
            }
        );

        while (!done)
        {
            process_events ();
            Posix.usleep (10000);
        }

        mw.hide ();
    }

    public static void remote_login_login_servers_updated_signal ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "delay2";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");

        bool done = false;
        // The delay2 code triggers at 5 seconds
        Timeout.add (5250, () =>
            {
                // If the login server we were disappears we get moved to a different one
                wait_for_scrolling_end (list);
                GLib.assert (list.selected_entry.id == "*remote_login*http://megacoolrdpserver.com*");
                done = true;
                return false;
            }
        );

        while (!done)
        {
            process_events ();
            Posix.usleep (10000);
        }

        mw.hide ();
    }

    public static void remote_login_login_servers_updated_signal_focus_not_in_removed_server ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "delay2";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");

        // Move to a server that won't be removed
        while (list.selected_entry.id != "*remote_login*http://coolrdpserver.com*")
            do_scroll (list, GreeterList.ScrollTarget.UP);

        bool done = false;
        // The delay2 code triggers at 5 seconds
        Timeout.add (5250, () =>
            {
                // If the login server we were did not disappear we are still in the same one
                wait_for_scrolling_end (list);
                GLib.assert (list.selected_entry.id == "*remote_login*http://coolrdpserver.com*");
                done = true;
                return false;
            }
        );

        while (!done)
        {
            process_events ();
            Posix.usleep (10000);
        }

        mw.hide ();
    }

    public static void remote_login_remote_login_changed_signal ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "delay3";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");

        bool done = false;
        // The delay3 code triggers at 5 seconds
        Timeout.add (5250, () =>
            {
                // If the remote login details change while on one of its servers the login servers are removed
                // and we get moved to the directory server
                wait_for_scrolling_end (list);
                GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");

                do_scroll (list, GreeterList.ScrollTarget.DOWN); // There are no server to log in
                GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");

                done = true;
                return false;
            }
        );

        while (!done)
        {
            process_events ();
            Posix.usleep (10000);
        }

        mw.hide ();
    }

    public static void remote_login_remote_login_changed_signalfocus_not_in_changed_server ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "delay3";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");
        wait_for_scrolling_end (list);

        while (list.selected_entry.id.has_prefix("*remote_"))
        {
            do_scroll (list, GreeterList.ScrollTarget.UP);
        }
        string nonRemoteEntry = list.selected_entry.id;

        bool done = false;
        // The delay3 code triggers at 5 seconds
        Timeout.add (5250, () =>
            {
                // If we were not in a remote entry we are not moved when we are asked to reauthenticate
                // What happens is that the login servers of that directory server get removed
                // Moving down we find the new directory server
                GLib.assert (list.selected_entry.id == nonRemoteEntry);
                do_scroll (list, GreeterList.ScrollTarget.DOWN);
                GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");

                do_scroll (list, GreeterList.ScrollTarget.DOWN); // There are no server to log in
                GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");
                done = true;
                return false;
            }
        );

        while (!done)
        {
            process_events ();
            Posix.usleep (10000);
        }

        mw.hide ();
    }

    public static void remote_login_authentication ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);
        GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");
        GLib.assert (!list.selected_entry.has_errors);

        // Fill in a valid email and password
        // Check there is no error and we moved to the last logged in server
        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "password";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");
        wait_for_scrolling_end (list);

        ArcticaGreeter.singleton.session_started = false;
        pwd = remote_login_entry_password_field (list);
        pwd.text = "password";
        list.selected_entry.respond ({});
        GLib.assert (ArcticaGreeter.singleton.session_started);

        mw.hide ();
    }

    public static void remote_login_cancel_authentication ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);
        GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");
        GLib.assert (!list.selected_entry.has_errors);

        // Fill in a valid email and password
        // Check there is no error and we moved to the last logged in server
        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "password";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername2.com*lwola");
        wait_for_scrolling_end (list);

        ArcticaGreeter.singleton.session_started = false;
        pwd = remote_login_entry_password_field (list);
        pwd.text = "delay";
        pwd.activate ();
        GLib.assert (!list.sensitive); // We are not sensitive because we are waiting for servers answer
        GLib.assert (pwd.did_respond); // We are showing the spinner
        list.cancel_authentication ();
        pwd = remote_login_entry_password_field (list);
        GLib.assert (list.sensitive); // We are sensitive again because we cancelled the login
        GLib.assert (!pwd.did_respond); // We are not showing the spinner anymore

        mw.hide ();
    }

    public static void remote_login_duplicate_entries()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        scroll_to_remote_login (list); //Wait until remote login appears.
        GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");
        GLib.assert (!list.selected_entry.has_errors);

        // If we answer without filling in any field -> error
        list.selected_entry.respond ({});
        GLib.assert (list.selected_entry.has_errors);

        // Go to first and back to last to clear the error
        do_scroll (list, GreeterList.ScrollTarget.START);
        do_scroll (list, GreeterList.ScrollTarget.END);
        GLib.assert (!list.selected_entry.has_errors);

        // Fill in a valid email and password
        // Check there is no error and we moved to the last logged in server
        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "duplicate";
        list.selected_entry.respond ({});
        GLib.assert (!list.selected_entry.has_errors);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername.com*alowl2");

        var username = remote_login_entry_username_field(list);
        var domain = remote_login_entry_domain_field(list);
        var password = remote_login_entry_password_field(list);
        GLib.assert (username.text == "alowl2" && domain.text == "PRINTERS" && password.text == "duplicate2");

        do_scroll (list, GreeterList.ScrollTarget.DOWN);
        GLib.assert (list.selected_entry.id == "*remote_login*http://rdpdefaultusername.com*alowl1");
        username = remote_login_entry_username_field(list);
        domain = remote_login_entry_domain_field(list);
        password = remote_login_entry_password_field(list);
        GLib.assert (username.text == "alowl1" && domain.text == "SCANNERS" && password.text == "duplicate1");
        wait_for_scrolling_end (list);
        mw.hide ();
    }

    public static void email_autocomplete ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        var email = remote_directory_entry_email_field (list);

        wait_for_focus (email);

        GLib.assert (email.text.length == 0);

        inject_key(email, Gdk.Key.a);
        GLib.assert (email.text == "a");

        inject_key(email, Gdk.Key.at);
        GLib.assert (email.text == "a@canonical.com");

        inject_key(email, Gdk.Key.u);
        GLib.assert (email.text == "a@ubuntu.org");

        inject_key(email, Gdk.Key.r);
        GLib.assert (email.text == "a@urban.net");

        inject_key(email, Gdk.Key.BackSpace);
        GLib.assert (email.text == "a@ur");

        inject_key(email, Gdk.Key.BackSpace);
        GLib.assert (email.text == "a@u");

        inject_key(email, Gdk.Key.BackSpace);
        GLib.assert (email.text == "a@");

        inject_key(email, Gdk.Key.c);
        GLib.assert (email.text == "a@canonical.com");

        inject_key(email, Gdk.Key.a);
        GLib.assert (email.text == "a@canonical.com");

        inject_key(email, Gdk.Key.n);
        GLib.assert (email.text == "a@canonical.com");

        inject_key(email, Gdk.Key.d);
        GLib.assert (email.text == "a@candy.com");

        mw.hide ();
    }

    public static void greeter_communcation ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        // Fill in a valid email and password
        // Check there is no error and we moved to the last logged in server
        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "password";
        list.selected_entry.respond ({});
        wait_for_scrolling_end (list);

        while (list.selected_entry.id != "*remote_login*http://coolrdpserver.com*")
            do_scroll (list, GreeterList.ScrollTarget.UP);

        var domain = remote_login_entry_domain_field (list);
        var username = remote_login_entry_username_field (list);
        pwd = remote_login_entry_password_field (list);
        domain.text = "foo";
        username.text = "bar";
        pwd.text = "foobar";

        ArcticaGreeter.singleton.show_prompt("remote login:", LightDM.PromptType.QUESTION);
        GLib.assert (ArcticaGreeter.singleton.last_respond_response == username.text);
        ArcticaGreeter.singleton.show_prompt("remote host:", LightDM.PromptType.QUESTION);
        GLib.assert (ArcticaGreeter.singleton.last_respond_response == "http://coolrdpserver.com");
        ArcticaGreeter.singleton.show_prompt("domain:", LightDM.PromptType.QUESTION);
        GLib.assert (ArcticaGreeter.singleton.last_respond_response == domain.text);
        ArcticaGreeter.singleton.show_prompt("password:", LightDM.PromptType.SECRET);
        GLib.assert (ArcticaGreeter.singleton.last_respond_response == pwd.text);

        mw.hide ();
    }

    public static void unsupported_server_type ()
    {
        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

        // Wait until remote login appears
        scroll_to_remote_login (list);

        // Fill in a valid email and password
        // Check there is no error and we moved to the last logged in server
        var email = remote_directory_entry_email_field (list);
        var pwd = remote_directory_entry_password_field (list);
        email.text = "a@canonical.com";
        pwd.text = "password";
        list.selected_entry.respond ({});
        wait_for_scrolling_end (list);

        while (list.selected_entry.id != "*remote_login*http://notsupportedserver.com*")
            do_scroll (list, GreeterList.ScrollTarget.UP);

        GLib.assert (list.selected_entry.has_errors);
        GLib.assert (!list.selected_entry.sensitive);

        mw.hide ();
    }

    public static void remote_login_only ()
    {
        ArcticaGreeter.singleton.test_mode = true;
        ArcticaGreeter.singleton.session_started = false;

	/* this configuration should result in the list containing only the remote login entry,
	   without any fallback manual entry */
        ArcticaGreeter.singleton._hide_users_hint = true;
        ArcticaGreeter.singleton._show_remote_login_hint = true;
        ArcticaGreeter.singleton._has_guest_account_hint = false;
        ArcticaGreeter.singleton._show_manual_login_hint = false;

        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

	/* don't go too fast, otherwise the lastest gdk3 will lose control... */
	Posix.sleep(1);

	/* Wait for Remote Login to appear */
	bool rl_appeared = false;
	for (int i=0; i<100 && !rl_appeared; i++)
	{
            do_scroll (list, GreeterList.ScrollTarget.END);
            process_events ();
            if (list.selected_entry.id == "*remote_directory*http://crazyurl.com")
		rl_appeared = true;
	}

	GLib.assert (rl_appeared);
        GLib.assert (list.num_entries() == 1);
        GLib.assert (list.selected_entry.id == "*remote_directory*http://crazyurl.com");

	mw.hide ();
   }

   public static void manual_login_fallback ()
   {
        ArcticaGreeter.singleton.test_mode = true;
        ArcticaGreeter.singleton.session_started = false;

	/* this configuration should result in the list containing at least a manual entry */
        ArcticaGreeter.singleton._hide_users_hint = true;
        ArcticaGreeter.singleton._show_remote_login_hint = false;
        ArcticaGreeter.singleton._has_guest_account_hint = false;
        ArcticaGreeter.singleton._show_manual_login_hint = true;

        MainWindow mw = setup ();
        TestList list = mw.stack.top () as TestList;

	/* verify if the manual entry has been added as a fallback mechanism */
        GLib.assert (list.num_entries() == 1);
        GLib.assert (list.selected_entry.id == "*other");

	mw.hide ();
   }


    static void setup_gsettings()
    {
        try
        {
            var dir = GLib.DirUtils.make_tmp ("arctica-greeter-test-XXXXXX");

            var schema_dir = Path.build_filename(dir, "share", "glib-2.0", "schemas");
            DirUtils.create_with_parents(schema_dir, 0700);

            var data_dirs = Environment.get_variable("XDG_DATA_DIRS");
            if (data_dirs == null)
                data_dirs = "/usr/share";
            Environment.set_variable("XDG_DATA_DIRS", "%s:%s".printf(Path.build_filename(dir, "share"), data_dirs), true);

            var top_srcdir = Environment.get_variable("top_srcdir");
            if (top_srcdir == null || top_srcdir == "")
                top_srcdir = "..";
            if (Posix.system("cp %s/data/org.ArcticaProject.arctica-greeter.gschema.xml %s".printf(top_srcdir, schema_dir)) != 0)
                error("Could not copy schema to %s", schema_dir);

            if (Posix.system("glib-compile-schemas %s".printf(schema_dir)) != 0)
                error("Could not compile schemas in %s", schema_dir);

            Environment.set_variable("GSETTINGS_BACKEND", "memory", true);
        }
        catch (Error e)
        {
            error("Error setting up gsettings: %s", e.message);
        }
    }

    public static int main (string[] args)
    {
        Gtk.test_init(ref args);

        setup_gsettings ();

        ArcticaGreeter.singleton = new ArcticaGreeter();
        ArcticaGreeter.singleton.test_mode = true;

        GLib.Test.add_func ("/Simple Navigation", simple_navigation);
        GLib.Test.add_func ("/Remote Login", remote_login);
        GLib.Test.add_func ("/Remote Login duplicate entries", remote_login_duplicate_entries);
        GLib.Test.add_func ("/Remote Login with Servers Updated signal", remote_login_servers_updated_signal);
        GLib.Test.add_func ("/Remote Login with Servers Updated signal and not in remote server", remote_login_servers_updated_signal_focus_not_in_remote_server);
        GLib.Test.add_func ("/Remote Login with Login Servers Updated signal", remote_login_login_servers_updated_signal);
        GLib.Test.add_func ("/Remote Login with Login Servers Updated signal and not in removed server", remote_login_login_servers_updated_signal_focus_not_in_removed_server);
        GLib.Test.add_func ("/Remote Login with Remote Login Changed signal", remote_login_remote_login_changed_signal);
        GLib.Test.add_func ("/Remote Login with Remote Login Changed signal and not in changed server", remote_login_remote_login_changed_signalfocus_not_in_changed_server);
        GLib.Test.add_func ("/Remote Login authentication", remote_login_authentication);
        GLib.Test.add_func ("/Remote Login cancel authentication", remote_login_cancel_authentication);
        GLib.Test.add_func ("/Email Autocomplete", email_autocomplete);
        GLib.Test.add_func ("/Greeter Communication", greeter_communcation);
        GLib.Test.add_func ("/Unsupported server type", unsupported_server_type);
        GLib.Test.add_func ("/Remote Login Only", remote_login_only);
        GLib.Test.add_func ("/Manual Login Fallback", manual_login_fallback);

        return GLib.Test.run();
    }

}
