/* * Copyright 2014-2016 Canonical Ltd. * * 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 . * * Authors: * Charles Kerr */ #include #include #include #include "notification-fixture.h" /*** **** ***/ using namespace ayatana::indicator::datetime; namespace { static constexpr char const * APP_NAME {"indicator-datetime-service"}; gboolean quit_idle (gpointer gloop) { g_main_loop_quit(static_cast(gloop)); return G_SOURCE_REMOVE; } } /*** **** ***/ TEST_F(NotificationFixture,Response) { // create the world mock_capabilities(); auto ne = std::make_shared(APP_NAME); auto sb = std::make_shared(); auto settings = std::make_shared(); int next_notification_id {FIRST_NOTIFY_ID}; // set a response callback that remembers what response we got bool on_response_called {}; Snap::Response response {}; auto on_response = [this, &on_response_called, &response] (const Appointment&, const Alarm&, const Snap::Response& r){ on_response_called = true; response = r; g_idle_add(quit_idle, loop); }; // our tests! const struct { Appointment appt; std::vector expected_actions; std::string action; Snap::Response expected_response; } tests[] = { { appt, {"show-app"}, "show-app", Snap::Response::ShowApp }, { ualarm, {"none", "snooze"}, "snooze", Snap::Response::Snooze }, { ualarm, {"none", "snooze"}, "none", Snap::Response::None } }; settings->cal_notification_enabled.set(true); settings->cal_notification_sounds.set(true); settings->cal_notification_vibrations.set(true); settings->cal_notification_bubbles.set(true); settings->cal_notification_list.set(true); // walk through the tests for (const auto& test : tests) { // wait for previous iterations' bus noise to finish and reset the counters GError* error {}; wait_msec(500); dbus_test_dbus_mock_object_clear_method_calls(notify_mock, notify_obj, &error); g_assert_no_error(error); on_response_called = false; // create a snap decision auto snap = create_snap(ne, sb, settings); (*snap)(test.appt, test.appt.alarms.front(), on_response); // wait for the notification to show up EXPECT_METHOD_CALLED_EVENTUALLY(notify_mock, notify_obj, METHOD_NOTIFY); // test that Notify was called the right number of times static constexpr int expected_num_notify_calls {1}; guint num_notify_calls {}; const auto notify_calls = dbus_test_dbus_mock_object_get_method_calls( notify_mock, notify_obj, METHOD_NOTIFY, &num_notify_calls, &error); g_assert_no_error(error); EXPECT_EQ(expected_num_notify_calls, num_notify_calls); // test that Notify was called with the correct list of actions if (num_notify_calls > 0) { std::vector actions; const gchar** as {nullptr}; g_variant_get_child(notify_calls[0].params, 5, "^a&s", &as); for (int i=0; as && as[i]; i+=2) // actions are in pairs of (name, i18n), skip the i18n actions.push_back(as[i]); EXPECT_EQ(test.expected_actions, actions); } // make the notification mock tell the world that the user invoked an action const auto notification_id = next_notification_id++; idle_add([this, notification_id, test](){ GError* err {}; dbus_test_dbus_mock_object_emit_signal(notify_mock, notify_obj, "ActionInvoked", G_VARIANT_TYPE("(us)"), g_variant_new("(us)", guint(notification_id), test.action.c_str()), &err); dbus_test_dbus_mock_object_emit_signal(notify_mock, notify_obj, "NotificationClosed", G_VARIANT_TYPE("(uu)"), g_variant_new("(uu)", guint(notification_id), guint(NOTIFICATION_CLOSED_DISMISSED)), &err); g_assert_no_error(err); return G_SOURCE_REMOVE; }); // confirm that the response callback got the right response EXPECT_TRUE(wait_for([&on_response_called](){return on_response_called;})); EXPECT_EQ(int(test.expected_response), int(response)) << "notification_id " << notification_id; } }