aboutsummaryrefslogtreecommitdiff
path: root/tests/test-notify.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-notify.cc')
-rw-r--r--tests/test-notify.cc208
1 files changed, 131 insertions, 77 deletions
diff --git a/tests/test-notify.cc b/tests/test-notify.cc
index 6ac3d82..cf1f9d3 100644
--- a/tests/test-notify.cc
+++ b/tests/test-notify.cc
@@ -20,6 +20,7 @@
#include "glib-fixture.h"
+#include "dbus-shared.h"
#include "device.h"
#include "notifier.h"
@@ -49,10 +50,11 @@ private:
DbusTestService * service = nullptr;
DbusTestDbusMock * mock = nullptr;
DbusTestDbusMockObject * obj = nullptr;
- GDBusConnection * bus = nullptr;
protected:
+ GDBusConnection * bus = nullptr;
+
static constexpr int NOTIFY_ID {1234};
static constexpr int NOTIFICATION_CLOSED_EXPIRED {1};
@@ -76,15 +78,15 @@ protected:
// init DBusMock / dbus-test-runner
- service = dbus_test_service_new(NULL);
+ service = dbus_test_service_new(nullptr);
- GError * error = NULL;
+ GError * error = nullptr;
mock = dbus_test_dbus_mock_new(NOTIFY_BUSNAME);
obj = dbus_test_dbus_mock_get_object(mock, NOTIFY_PATH, NOTIFY_INTERFACE, &error);
g_assert_no_error (error);
dbus_test_dbus_mock_object_add_method(mock, obj, METHOD_GET_INFO,
- NULL,
+ nullptr,
G_VARIANT_TYPE("(ssss)"),
"ret = ('mock-notify', 'test vendor', '1.0', '1.1')", // python
&error);
@@ -102,7 +104,7 @@ protected:
dbus_test_service_add_task(service, DBUS_TEST_TASK(mock));
dbus_test_service_start_tasks(service);
- bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
+ bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
g_dbus_connection_set_exit_on_close(bus, FALSE);
g_object_add_weak_pointer(G_OBJECT(bus), (gpointer *)&bus);
@@ -120,7 +122,7 @@ protected:
// wait a little while for the scaffolding to shut down,
// but don't block on it forever...
unsigned int cleartry = 0;
- while ((bus != NULL) && (cleartry < 50))
+ while ((bus != nullptr) && (cleartry < 50))
{
g_usleep(100000);
while (g_main_pending())
@@ -136,88 +138,140 @@ protected:
****
***/
-// mock device provider
-
-// send notifications of a device going down from 50% to 3% by 1% increments
-
-// popup should appear exactly twice: once at 10%, once at 5%
-
+// simple test to confirm the NotifyFixture plumbing all works
TEST_F(NotifyFixture, HelloWorld)
{
}
-#if 0
-using namespace unity::indicator::datetime;
-
-/***
-****
-***/
-
-using namespace unity::indicator::datetime;
-
-class SnapFixture: public GlibFixture
-{
-
-/***
-****
-***/
+// scaffolding to listen for PropertyChanged signals and remember them
namespace
{
- gboolean quit_idle (gpointer gloop)
+ enum
{
- g_main_loop_quit(static_cast<GMainLoop*>(gloop));
- return G_SOURCE_REMOVE;
+ FIELD_POWER_LEVEL = (1<<0),
+ FIELD_IS_WARNING = (1<<1)
};
+
+ struct ChangedParams
+ {
+ int32_t power_level = POWER_LEVEL_OK;
+ bool is_warning = false;
+ uint32_t fields = 0;
+ };
+
+ void on_battery_property_changed (GDBusConnection *connection G_GNUC_UNUSED,
+ const gchar *sender_name G_GNUC_UNUSED,
+ const gchar *object_path G_GNUC_UNUSED,
+ const gchar *interface_name G_GNUC_UNUSED,
+ const gchar *signal_name G_GNUC_UNUSED,
+ GVariant *parameters,
+ gpointer gchanged_params)
+ {
+ g_return_if_fail (g_variant_n_children (parameters) == 3);
+ auto changed_properties = g_variant_get_child_value (parameters, 1);
+ g_return_if_fail (g_variant_is_of_type (changed_properties, G_VARIANT_TYPE_DICTIONARY));
+ auto changed_params = static_cast<ChangedParams*>(gchanged_params);
+
+ gint32 power_level;
+ if (g_variant_lookup (changed_properties, "PowerLevel", "i", &power_level, nullptr))
+ {
+ changed_params->power_level = power_level;
+ changed_params->fields |= FIELD_POWER_LEVEL;
+ }
+
+ gboolean is_warning;
+ if (g_variant_lookup (changed_properties, "IsWarning", "b", &is_warning, nullptr))
+ {
+ changed_params->is_warning = is_warning;
+ changed_params->fields |= FIELD_IS_WARNING;
+ }
+
+ g_variant_unref (changed_properties);
+ }
+}
+
+TEST_F(NotifyFixture, PercentageToLevel)
+{
+ auto battery = indicator_power_device_new ("/object/path",
+ UP_DEVICE_KIND_BATTERY,
+ 50.0,
+ UP_DEVICE_STATE_DISCHARGING,
+ 30);
+
+ // confirm that the power levels trigger at the right percentages
+ for (int i=100; i>=0; --i)
+ {
+ g_object_set (battery, INDICATOR_POWER_DEVICE_PERCENTAGE, (gdouble)i, nullptr);
+ const auto level = indicator_power_notifier_get_power_level(battery);
+
+ if (i <= 2)
+ EXPECT_EQ (POWER_LEVEL_CRITICAL, level);
+ else if (i <= 5)
+ EXPECT_EQ (POWER_LEVEL_VERY_LOW, level);
+ else if (i <= 10)
+ EXPECT_EQ (POWER_LEVEL_LOW, level);
+ else
+ EXPECT_EQ (POWER_LEVEL_OK, level);
+ }
+
+ g_object_unref (battery);
}
-TEST_F(SnapFixture, InteractiveDuration)
+
+TEST_F(NotifyFixture, LevelsDuringBatteryDrain)
{
- static constexpr int duration_minutes = 120;
- auto settings = std::make_shared<Settings>();
- settings->alarm_duration.set(duration_minutes);
- auto timezones = std::make_shared<Timezones>();
- auto clock = std::make_shared<LiveClock>(timezones);
- Snap snap (clock, settings);
-
- // GetCapabilities returns an array containing 'actions',
- // so our snap decision will be interactive.
- // For this test, it means we should get a timeout Notify Hint
- // that matches duration_minutes
- GError * error = nullptr;
- dbus_test_dbus_mock_object_add_method(mock, obj, METHOD_GET_CAPS, nullptr, G_VARIANT_TYPE_STRING_ARRAY, "ret = ['actions', 'body']", &error);
- g_assert_no_error (error);
-
- // call the Snap Decision
- auto func = [this](const Appointment&){g_idle_add(quit_idle, loop);};
- snap(appt, func, func);
-
- // confirm that Notify got called once
- guint len = 0;
- auto calls = dbus_test_dbus_mock_object_get_method_calls (mock, 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<std::chrono::milliseconds>(duration).count(), i32);
- g_variant_unref(hints);
+ auto battery = indicator_power_device_new ("/object/path",
+ UP_DEVICE_KIND_BATTERY,
+ 50.0,
+ UP_DEVICE_STATE_DISCHARGING,
+ 30);
+
+ // set up a notifier and give it the battery so changing the battery's
+ // charge should show up on the bus.
+ auto notifier = indicator_power_notifier_new ();
+ indicator_power_notifier_set_battery (notifier, battery);
+ indicator_power_notifier_set_bus (notifier, bus);
+ wait_msec();
+
+ ChangedParams changed_params;
+ auto subscription_tag = g_dbus_connection_signal_subscribe (bus,
+ nullptr,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ BUS_PATH"/Battery",
+ nullptr,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_battery_property_changed,
+ &changed_params,
+ nullptr);
+
+ // confirm that draining the battery puts
+ // the power_level change through its paces
+ for (int i=100; i>=0; --i)
+ {
+ changed_params = ChangedParams();
+ EXPECT_TRUE (changed_params.fields == 0);
+
+ const auto old_level = indicator_power_notifier_get_power_level(battery);
+ g_object_set (battery, INDICATOR_POWER_DEVICE_PERCENTAGE, (gdouble)i, nullptr);
+ const auto new_level = indicator_power_notifier_get_power_level(battery);
+ wait_msec();
+
+ if (old_level == new_level)
+ {
+ EXPECT_EQ (0, changed_params.fields);
+ }
+ else
+ {
+ EXPECT_EQ (FIELD_POWER_LEVEL, changed_params.fields);
+ EXPECT_EQ (new_level, changed_params.power_level);
+ }
+ }
+
+ // cleanup
+ g_dbus_connection_signal_unsubscribe (bus, subscription_tag);
+ g_object_unref (notifier);
+ g_object_unref (battery);
}
-#endif