From 62f4861b11ba7e3c58c75cf574cc999e623b4247 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Feb 2016 14:49:01 -0600 Subject: update notification tests to wait for the needed bus events instead of waiting for arbitrary time intervals --- tests/test-snap.cpp | 396 ---------------------------------------------------- 1 file changed, 396 deletions(-) delete mode 100644 tests/test-snap.cpp (limited to 'tests/test-snap.cpp') diff --git a/tests/test-snap.cpp b/tests/test-snap.cpp deleted file mode 100644 index 2c53900..0000000 --- a/tests/test-snap.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright 2014 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3, as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include -#include -#include -#include - -#include -#include - -#include "notification-fixture.h" - -using namespace ayatana::indicator::datetime; - -namespace uin = ayatana::indicator::notifications; - -/*** -**** -***/ - -namespace -{ - static constexpr char const * APP_NAME {"ayatana-indicator-datetime-service"}; -} - -using namespace ayatana::indicator::datetime; - -/*** -**** -***/ - -namespace -{ - gboolean quit_idle (gpointer gloop) - { - g_main_loop_quit(static_cast(gloop)); - return G_SOURCE_REMOVE; - }; -} - -TEST_F(NotificationFixture, InteractiveDuration) -{ - static constexpr int duration_minutes = 120; - auto settings = std::make_shared(); - settings->alarm_duration.set(duration_minutes); - auto ne = std::make_shared(APP_NAME); - auto sb = std::make_shared(); - auto snap = create_snap(ne, sb, settings); - - make_interactive(); - - // call the Snap Decision - auto func = [this](const Appointment&, const Alarm&){g_idle_add(quit_idle, loop);}; - (*snap)(appt, appt.alarms.front(), func, func); - - // confirm that Notify got called once - guint len = 0; - GError * error = nullptr; - const auto calls = dbus_test_dbus_mock_object_get_method_calls (notify_mock, - notify_obj, - METHOD_NOTIFY, - &len, - &error); - g_assert_no_error(error); - ASSERT_EQ(1, len); - - // confirm that the app_name passed to Notify was APP_NAME - const auto& params = calls[0].params; - ASSERT_EQ(8, g_variant_n_children(params)); - const char * str = nullptr; - g_variant_get_child (params, 0, "&s", &str); - ASSERT_STREQ(APP_NAME, str); - - // confirm that the icon passed to Notify was "alarm-clock" - g_variant_get_child (params, 2, "&s", &str); - ASSERT_STREQ("alarm-clock", str); - - // confirm that the hints passed to Notify included a timeout matching duration_minutes - int32_t i32; - bool b; - auto hints = g_variant_get_child_value (params, 6); - b = g_variant_lookup (hints, HINT_TIMEOUT, "i", &i32); - EXPECT_TRUE(b); - const auto duration = std::chrono::minutes(duration_minutes); - EXPECT_EQ(std::chrono::duration_cast(duration).count(), i32); - g_variant_unref(hints); - ne.reset(); -} - -/*** -**** -***/ - -TEST_F(NotificationFixture, InhibitSleep) -{ - auto settings = std::make_shared(); - auto ne = std::make_shared(APP_NAME); - auto sb = std::make_shared(); - auto snap = create_snap(ne, sb, settings); - - make_interactive(); - - // invoke the notification - auto func = [this](const Appointment&, const Alarm&){g_idle_add(quit_idle, loop);}; - (*snap)(appt, appt.alarms.front(), func, func); - - wait_msec(1000); - - // confirm that sleep got inhibited - GError * error = nullptr; - EXPECT_TRUE (dbus_test_dbus_mock_object_check_method_call (powerd_mock, - powerd_obj, - POWERD_METHOD_REQUEST_SYS_STATE, - g_variant_new("(si)", APP_NAME, POWERD_SYS_STATE_ACTIVE), - &error)); - - // confirm that the screen got forced on - EXPECT_TRUE (dbus_test_dbus_mock_object_check_method_call (screen_mock, - screen_obj, - SCREEN_METHOD_KEEP_DISPLAY_ON, - nullptr, - &error)); - - // force-close the snap - wait_msec(100); - snap.reset(); - wait_msec(100); - - // confirm that sleep got uninhibted - EXPECT_TRUE (dbus_test_dbus_mock_object_check_method_call (powerd_mock, - powerd_obj, - POWERD_METHOD_CLEAR_SYS_STATE, - g_variant_new("(s)", POWERD_COOKIE), - &error)); - - // confirm that the screen's no longer forced on - EXPECT_TRUE (dbus_test_dbus_mock_object_check_method_call (screen_mock, - screen_obj, - SCREEN_METHOD_REMOVE_DISPLAY_ON_REQUEST, - g_variant_new("(i)", SCREEN_COOKIE), - &error)); - - g_assert_no_error (error); -} - -/*** -**** -***/ - -TEST_F(NotificationFixture, ForceScreen) -{ - auto settings = std::make_shared(); - auto ne = std::make_shared(APP_NAME); - auto sb = std::make_shared(); - auto snap = create_snap(ne, sb, settings); - - make_interactive(); - - // invoke the notification - auto func = [this](const Appointment&, const Alarm&){g_idle_add(quit_idle, loop);}; - (*snap)(appt, appt.alarms.front(), func, func); - - wait_msec(1000); - - // confirm that sleep got inhibited - GError * error = nullptr; - EXPECT_TRUE (dbus_test_dbus_mock_object_check_method_call (powerd_mock, - powerd_obj, - POWERD_METHOD_REQUEST_SYS_STATE, - g_variant_new("(si)", APP_NAME, POWERD_SYS_STATE_ACTIVE), - &error)); - g_assert_no_error(error); - - // force-close the snap - wait_msec(100); - snap.reset(); - wait_msec(100); - - // confirm that sleep got uninhibted - EXPECT_TRUE (dbus_test_dbus_mock_object_check_method_call (powerd_mock, - powerd_obj, - POWERD_METHOD_CLEAR_SYS_STATE, - g_variant_new("(s)", POWERD_COOKIE), - &error)); - g_assert_no_error(error); -} - -/*** -**** -***/ - -/** - * A DefaultSoundBuilder wrapper which remembers the parameters of the last sound created. - */ -class TestSoundBuilder: public uin::SoundBuilder -{ -public: - TestSoundBuilder() =default; - ~TestSoundBuilder() =default; - - virtual std::shared_ptr create(const std::string& role, const std::string& uri, unsigned int volume, bool loop) override { - m_role = role; - m_uri = uri; - m_volume = volume; - m_loop = loop; - return m_impl.create(role, uri, volume, loop); - } - - const std::string& role() { return m_role; } - const std::string& uri() { return m_uri; } - unsigned int volume() { return m_volume; } - bool loop() { return m_loop; } - -private: - std::string m_role; - std::string m_uri; - unsigned int m_volume; - bool m_loop; - uin::DefaultSoundBuilder m_impl; -}; - -std::string path_to_uri(const std::string& path) -{ - auto file = g_file_new_for_path(path.c_str()); - auto uri_cstr = g_file_get_uri(file); - std::string uri = uri_cstr; - g_free(uri_cstr); - g_clear_pointer(&file, g_object_unref); - return uri; -} - -TEST_F(NotificationFixture,DefaultSounds) -{ - auto settings = std::make_shared(); - auto ne = std::make_shared(APP_NAME); - auto sb = std::make_shared(); - auto func = [this](const Appointment&, const Alarm&){g_idle_add(quit_idle, loop);}; - - const struct { - Appointment appointment; - std::string expected_role; - std::string expected_uri; - } test_cases[] = { - { ualarm, "alarm", path_to_uri(ALARM_DEFAULT_SOUND) }, - { appt, "alert", path_to_uri(CALENDAR_DEFAULT_SOUND) } - }; - - auto snap = create_snap(ne, sb, settings); - - for(const auto& test_case : test_cases) - { - (*snap)(test_case.appointment, test_case.appointment.alarms.front(), func, func); - wait_msec(100); - EXPECT_EQ(test_case.expected_uri, sb->uri()); - EXPECT_EQ(test_case.expected_role, sb->role()); - } -} - -/*** -**** -***/ - -TEST_F(NotificationFixture,Notification) -{ - // Feed different combinations of system settings, - // indicator-datetime settings, and event types, - // then see if notifications and haptic feedback behave as expected. - - auto settings = std::make_shared(); - auto ne = std::make_shared(APP_NAME); - auto sb = std::make_shared(); - auto func = [this](const Appointment&, const Alarm&){g_idle_add(quit_idle, loop);}; - - // combinatorial factor #1: event type - struct { - Appointment appt; - bool expected_notify_called; - bool expected_vibrate_called; - } test_appts[] = { - { appt, true, true }, - { ualarm, true, true } - }; - - // combinatorial factor #2: indicator-datetime's haptic mode - struct { - const char* haptic_mode; - bool expected_notify_called; - bool expected_vibrate_called; - } test_haptics[] = { - { "none", true, false }, - { "pulse", true, true } - }; - - // combinatorial factor #3: system settings' "other vibrations" enabled - struct { - bool other_vibrations; - bool expected_notify_called; - bool expected_vibrate_called; - } test_other_vibrations[] = { - { true, true, true }, - { false, true, false } - }; - - // combinatorial factor #4: system settings' notifications app blacklist - const std::set> blacklist_calendar { std::make_pair(std::string{"com.lomiri.calendar"}, std::string{"calendar-app"}) }; - const std::set> blacklist_empty; - struct { - std::set> muted_apps; // apps that should not trigger notifications - bool expected_notify_called; // do we expect the notification tho show? - bool expected_vibrate_called; // do we expect the phone to vibrate? - } test_muted_apps[] = { - { blacklist_calendar, false, false }, - { blacklist_empty, true, true } - }; - - for (const auto& test_appt : test_appts) - { - for (const auto& test_haptic : test_haptics) - { - for (const auto& test_vibes : test_other_vibrations) - { - for (const auto& test_muted : test_muted_apps) - { - auto snap = create_snap(ne, sb, settings); - - const bool expected_notify_called = test_appt.expected_notify_called - && test_vibes.expected_notify_called - && test_muted.expected_notify_called - && test_haptic.expected_notify_called; - - const bool expected_vibrate_called = test_appt.expected_vibrate_called - && test_vibes.expected_vibrate_called - && test_muted.expected_vibrate_called - && test_haptic.expected_vibrate_called; - - // clear out any previous iterations' noise - GError * error = nullptr; - dbus_test_dbus_mock_object_clear_method_calls(haptic_mock, haptic_obj, &error); - g_assert_no_error(error); - dbus_test_dbus_mock_object_clear_method_calls(notify_mock, notify_obj, &error); - g_assert_no_error(error); - - // set the properties to match the test case - settings->muted_apps.set(test_muted.muted_apps); - settings->alarm_haptic.set(test_haptic.haptic_mode); - dbus_test_dbus_mock_object_update_property(as_mock, - as_obj, - PROP_OTHER_VIBRATIONS, - g_variant_new_boolean(test_vibes.other_vibrations), - &error); - g_assert_no_error(error); - wait_msec(100); - - // run the test - (*snap)(appt, appt.alarms.front(), func, func); - wait_msec(100); - - // test that the notification was as expected - const bool notify_called = dbus_test_dbus_mock_object_check_method_call(notify_mock, - notify_obj, - METHOD_NOTIFY, - nullptr, - &error); - g_assert_no_error(error); - EXPECT_EQ(expected_notify_called, notify_called); - - // test that the vibration was as expected - const bool vibrate_called = dbus_test_dbus_mock_object_check_method_call(haptic_mock, - haptic_obj, - HAPTIC_METHOD_VIBRATE_PATTERN, - nullptr, - &error); - g_assert_no_error(error); - EXPECT_EQ(expected_vibrate_called, vibrate_called); - } - } - } - } -} -- cgit v1.2.3