Merge lp:~charlesk/indicator-datetime/lp-1295799-date-menuitem-should-open-calendar into lp:indicator-datetime/14.04

Proposed by Charles Kerr
Status: Merged
Approved by: Ted Gould
Approved revision: 329
Merged at revision: 332
Proposed branch: lp:~charlesk/indicator-datetime/lp-1295799-date-menuitem-should-open-calendar
Merge into: lp:indicator-datetime/14.04
Diff against target: 1162 lines (+537/-305)
11 files modified
README (+16/-8)
include/datetime/actions-live.h (+11/-8)
include/datetime/actions.h (+13/-7)
src/actions-live.cpp (+38/-25)
src/actions.cpp (+81/-61)
src/menu.cpp (+32/-24)
tests/actions-mock.h (+46/-23)
tests/test-actions.cpp (+192/-104)
tests/test-exporter.cpp (+8/-5)
tests/test-live-actions.cpp (+80/-29)
tests/test-menus.cpp (+20/-11)
To merge this branch: bzr merge lp:~charlesk/indicator-datetime/lp-1295799-date-menuitem-should-open-calendar
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+212277@code.launchpad.net

Commit message

Add support for opening the calendar app on the phone via the date menuitem.

Description of the change

Add support for opening the calendar app on the phone via the date menuitem.

To post a comment you must log in.
Revision history for this message
Charles Kerr (charlesk) wrote :

> * Ensure the project compiles and the test suite executes without error

Done on desktop + nexus phone.

> * Ensure that non-obvious code has comments explaining it

No new non-obvious code. The per-profile actions are actually more readable now.

> * If the change works on specific profiles, please include those in the merge description.

Changes phone behavior s.t. clicking on the date menuitem pops up the calendar app.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ted Gould (ted) wrote :

Wow, simple changes cause a lot of ripple. We should probably long term think about a way to get the action names into consts so that we're not duplicating them all over the codebase. Then we could "C++ namespace" as well as "GAction namespace" them. Not for this MR though.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README'
2--- README 2014-01-22 15:04:30 +0000
3+++ README 2014-03-22 07:33:30 +0000
4@@ -1,18 +1,26 @@
5 ACTIONS
6 =======
7
8- * "activate-settings"
9- Description: opens a page for changing indicator-datetime's settings
10- State: None
11- Parameter: None
12-
13- * "activate-planner"
14- Description: opens an appointment editor.
15+ * "desktop.open-settings-app"
16+ * "phone.open-settings-app"
17+ Description: open the settings application.
18+ State: None
19+ Parameter: None
20+
21+ * "desktop.open-alarm-app"
22+ * "phone.open-alarm-app"
23+ Description: open the application for creating new alarms.
24+ State: None
25+ Parameter: None
26+
27+ * "desktop.open-calendar-app"
28+ * "phone.open-calendar-app"
29 State: None
30 Parameter: int64, a time_t hinting which day/time to show in the planner,
31 or 0 for the current day
32
33- * "activate-appointment"
34+ * "desktop.open-appointment"
35+ * "phone.open-appointment"
36 Description: opens an appointment editor to the specified appointment.
37 State: None
38 Parameter: string, an opaque uid to specify which appointment to use.
39
40=== modified file 'include/datetime/actions-live.h'
41--- include/datetime/actions-live.h 2014-03-06 23:54:57 +0000
42+++ include/datetime/actions-live.h 2014-03-22 07:33:30 +0000
43@@ -39,15 +39,18 @@
44 LiveActions(const std::shared_ptr<State>& state_in);
45 ~LiveActions() =default;
46
47- void open_desktop_settings();
48- void open_phone_settings();
49- void open_phone_clock_app();
50- bool can_open_planner() const;
51- void open_planner();
52- void open_planner_at(const DateTime&);
53- void open_appointment(const std::string& uid);
54+ bool desktop_has_calendar_app() const;
55+ void desktop_open_alarm_app();
56+ void desktop_open_appointment(const Appointment&);
57+ void desktop_open_calendar_app(const DateTime&);
58+ void desktop_open_settings_app();
59+
60+ void phone_open_alarm_app();
61+ void phone_open_appointment(const Appointment&);
62+ void phone_open_calendar_app(const DateTime&);
63+ void phone_open_settings_app();
64+
65 void set_location(const std::string& zone, const std::string& name);
66- void set_calendar_date(const DateTime&);
67
68 protected:
69 virtual void execute_command(const std::string& command);
70
71=== modified file 'include/datetime/actions.h'
72--- include/datetime/actions.h 2014-03-06 23:54:57 +0000
73+++ include/datetime/actions.h 2014-03-22 07:33:30 +0000
74@@ -42,14 +42,20 @@
75 class Actions
76 {
77 public:
78- virtual void open_desktop_settings() =0;
79- virtual void open_phone_settings() =0;
80- virtual void open_phone_clock_app() =0;
81- virtual bool can_open_planner() const = 0;
82- virtual void open_planner() =0;
83- virtual void open_planner_at(const DateTime&) =0;
84- virtual void open_appointment(const std::string& uid) =0;
85+
86+ virtual bool desktop_has_calendar_app() const =0;
87+ virtual void desktop_open_alarm_app() =0;
88+ virtual void desktop_open_appointment(const Appointment&) =0;
89+ virtual void desktop_open_calendar_app(const DateTime&) =0;
90+ virtual void desktop_open_settings_app() =0;
91+
92+ virtual void phone_open_alarm_app() =0;
93+ virtual void phone_open_appointment(const Appointment&) =0;
94+ virtual void phone_open_calendar_app(const DateTime&) =0;
95+ virtual void phone_open_settings_app() =0;
96+
97 virtual void set_location(const std::string& zone, const std::string& name)=0;
98+
99 void set_calendar_date(const DateTime&);
100 GActionGroup* action_group();
101 const std::shared_ptr<State> state() const;
102
103=== modified file 'src/actions-live.cpp'
104--- src/actions-live.cpp 2014-03-14 17:37:21 +0000
105+++ src/actions-live.cpp 2014-03-22 07:33:30 +0000
106@@ -51,6 +51,7 @@
107
108 void LiveActions::dispatch_url(const std::string& url)
109 {
110+ g_debug("Dispatching url '%s'", url.c_str());
111 url_dispatch_send(url.c_str(), nullptr, nullptr);
112 }
113
114@@ -58,7 +59,7 @@
115 ****
116 ***/
117
118-void LiveActions::open_desktop_settings()
119+void LiveActions::desktop_open_settings_app()
120 {
121 auto path = g_find_program_in_path("unity-control-center");
122
123@@ -74,7 +75,7 @@
124 g_free (path);
125 }
126
127-bool LiveActions::can_open_planner() const
128+bool LiveActions::desktop_has_calendar_app() const
129 {
130 static bool inited = false;
131 static bool have_calendar = false;
132@@ -98,22 +99,17 @@
133 return have_calendar;
134 }
135
136-void LiveActions::open_planner()
137+void LiveActions::desktop_open_alarm_app()
138 {
139 execute_command("evolution -c calendar");
140 }
141
142-void LiveActions::open_phone_settings()
143-{
144- dispatch_url("settings:///system/time-date");
145-}
146-
147-void LiveActions::open_phone_clock_app()
148-{
149- dispatch_url("appid://com.ubuntu.clock/clock/current-user-version");
150-}
151-
152-void LiveActions::open_planner_at(const DateTime& dt)
153+void LiveActions::desktop_open_appointment(const Appointment& appt)
154+{
155+ desktop_open_calendar_app(appt.begin);
156+}
157+
158+void LiveActions::desktop_open_calendar_app(const DateTime& dt)
159 {
160 const auto day_begins = dt.add_full(0, 0, 0, -dt.hour(), -dt.minute(), -dt.seconds());
161 const auto gmt = day_begins.to_timezone("UTC");
162@@ -121,17 +117,34 @@
163 execute_command(cmd.c_str());
164 }
165
166-void LiveActions::open_appointment(const std::string& uid)
167-{
168- for(const auto& appt : state()->calendar_upcoming->appointments().get())
169- {
170- if(appt.uid != uid)
171- continue;
172-
173- if (!appt.url.empty())
174- dispatch_url(appt.url);
175- break;
176- }
177+/***
178+****
179+***/
180+
181+void LiveActions::phone_open_alarm_app()
182+{
183+ dispatch_url("appid://com.ubuntu.clock/clock/current-user-version");
184+}
185+
186+void LiveActions::phone_open_appointment(const Appointment& appt)
187+{
188+ if (!appt.url.empty())
189+ dispatch_url(appt.url);
190+ else if (appt.has_alarms)
191+ phone_open_alarm_app();
192+ else
193+ phone_open_calendar_app(DateTime::NowLocal());
194+}
195+
196+void LiveActions::phone_open_calendar_app(const DateTime&)
197+{
198+ // does calendar app have a mechanism for specifying dates?
199+ dispatch_url("appid://com.ubuntu.calendar/calendar/current-user-version");
200+}
201+
202+void LiveActions::phone_open_settings_app()
203+{
204+ dispatch_url("settings:///system/time-date");
205 }
206
207 /***
208
209=== modified file 'src/actions.cpp'
210--- src/actions.cpp 2014-03-10 02:08:47 +0000
211+++ src/actions.cpp 2014-03-22 07:33:30 +0000
212@@ -34,67 +34,81 @@
213 namespace
214 {
215
216-void on_desktop_settings_activated(GSimpleAction * /*action*/,
217- GVariant * /*param*/,
218- gpointer gself)
219-{
220- static_cast<Actions*>(gself)->open_desktop_settings();
221-}
222-
223-void on_phone_settings_activated(GSimpleAction * /*action*/,
224- GVariant * /*param*/,
225- gpointer gself)
226-{
227- static_cast<Actions*>(gself)->open_phone_settings();
228-}
229-
230-void on_phone_clock_activated(GSimpleAction * /*action*/,
231- GVariant * /*param*/,
232- gpointer gself)
233-{
234- static_cast<Actions*>(gself)->open_phone_clock_app();
235-}
236-
237-void on_activate_appointment(GSimpleAction * /*action*/,
238- GVariant * param,
239- gpointer gself)
240-{
241- const auto uid = g_variant_get_string(param, nullptr);
242- auto self = static_cast<Actions*>(gself);
243-
244- g_return_if_fail(uid && *uid);
245-
246- // find url of the upcoming appointment with this uid
247- for (const auto& appt : self->state()->calendar_upcoming->appointments().get())
248+DateTime datetime_from_timet_variant(GVariant* v)
249+{
250+ int64_t t = 0;
251+
252+ if (v != nullptr)
253+ if (g_variant_type_equal(G_VARIANT_TYPE_INT64,g_variant_get_type(v)))
254+ t = g_variant_get_int64(v);
255+
256+ if (t != 0)
257+ return DateTime(t);
258+ else
259+ return DateTime::NowLocal();
260+}
261+
262+bool lookup_appointment_by_uid_variant(const std::shared_ptr<State>& state, GVariant* vuid, Appointment& setme)
263+{
264+ g_return_val_if_fail(vuid != nullptr, false);
265+ g_return_val_if_fail(g_variant_type_equal(G_VARIANT_TYPE_STRING,g_variant_get_type(vuid)), false);
266+ const auto uid = g_variant_get_string(vuid, nullptr);
267+ g_return_val_if_fail(uid && *uid, false);
268+
269+ for(const auto& appt : state->calendar_upcoming->appointments().get())
270 {
271 if (appt.uid == uid)
272 {
273- const auto url = appt.url;
274- g_debug("%s: uid[%s] -> url[%s]", G_STRFUNC, uid, url.c_str());
275- self->open_appointment(url);
276- break;
277+ setme = appt;
278+ return true;
279 }
280 }
281-}
282-
283-void on_activate_planner(GSimpleAction * /*action*/,
284- GVariant * param,
285- gpointer gself)
286-{
287- const auto at = g_variant_get_int64(param);
288- auto self = static_cast<Actions*>(gself);
289-
290- if (at)
291- {
292- auto gdt = g_date_time_new_from_unix_local(at);
293- self->open_planner_at(DateTime(gdt));
294- g_date_time_unref(gdt);
295- }
296- else // no time specified...
297- {
298- self->open_planner();
299- }
300-}
301+
302+ return false;
303+}
304+
305+void on_desktop_appointment_activated (GSimpleAction*, GVariant *vuid, gpointer gself)
306+{
307+ auto self = static_cast<Actions*>(gself);
308+ Appointment appt;
309+ if (lookup_appointment_by_uid_variant(self->state(), vuid, appt))
310+ self->desktop_open_appointment(appt);
311+}
312+void on_desktop_alarm_activated (GSimpleAction*, GVariant*, gpointer gself)
313+{
314+ static_cast<Actions*>(gself)->desktop_open_alarm_app();
315+}
316+void on_desktop_calendar_activated (GSimpleAction*, GVariant* vt, gpointer gself)
317+{
318+ const auto dt = datetime_from_timet_variant(vt);
319+ static_cast<Actions*>(gself)->desktop_open_calendar_app(dt);
320+}
321+void on_desktop_settings_activated (GSimpleAction*, GVariant*, gpointer gself)
322+{
323+ static_cast<Actions*>(gself)->desktop_open_settings_app();
324+}
325+
326+void on_phone_appointment_activated (GSimpleAction*, GVariant *vuid, gpointer gself)
327+{
328+ auto self = static_cast<Actions*>(gself);
329+ Appointment appt;
330+ if (lookup_appointment_by_uid_variant(self->state(), vuid, appt))
331+ self->phone_open_appointment(appt);
332+}
333+void on_phone_alarm_activated (GSimpleAction*, GVariant*, gpointer gself)
334+{
335+ static_cast<Actions*>(gself)->phone_open_alarm_app();
336+}
337+void on_phone_calendar_activated (GSimpleAction*, GVariant* vt, gpointer gself)
338+{
339+ const auto dt = datetime_from_timet_variant(vt);
340+ static_cast<Actions*>(gself)->phone_open_calendar_app(dt);
341+}
342+void on_phone_settings_activated (GSimpleAction*, GVariant*, gpointer gself)
343+{
344+ static_cast<Actions*>(gself)->phone_open_settings_app();
345+}
346+
347
348 void on_set_location(GSimpleAction * /*action*/,
349 GVariant * param,
350@@ -183,11 +197,17 @@
351 m_actions(g_simple_action_group_new())
352 {
353 GActionEntry entries[] = {
354- { "activate-desktop-settings", on_desktop_settings_activated },
355- { "activate-phone-settings", on_phone_settings_activated },
356- { "activate-phone-clock-app", on_phone_clock_activated },
357- { "activate-appointment", on_activate_appointment, "s", nullptr },
358- { "activate-planner", on_activate_planner, "x", nullptr },
359+
360+ { "desktop.open-appointment", on_desktop_appointment_activated, "s", nullptr },
361+ { "desktop.open-alarm-app", on_desktop_alarm_activated },
362+ { "desktop.open-calendar-app", on_desktop_calendar_activated, "x", nullptr },
363+ { "desktop.open-settings-app", on_desktop_settings_activated },
364+
365+ { "phone.open-appointment", on_phone_appointment_activated, "s", nullptr },
366+ { "phone.open-alarm-app", on_phone_alarm_activated },
367+ { "phone.open-calendar-app", on_phone_calendar_activated, "x", nullptr },
368+ { "phone.open-settings-app", on_phone_settings_activated },
369+
370 { "calendar-active", nullptr, nullptr, "false", on_calendar_active_changed },
371 { "set-location", on_set_location, "s" }
372 };
373
374=== modified file 'src/menu.cpp'
375--- src/menu.cpp 2014-03-10 03:32:19 +0000
376+++ src/menu.cpp 2014-03-22 07:33:30 +0000
377@@ -225,22 +225,28 @@
378
379 GMenuModel* create_calendar_section(Profile profile)
380 {
381- const bool allow_activation = (profile == Desktop)
382- || (profile == Phone);
383 const bool show_calendar = m_state->settings->show_calendar.get() &&
384 ((profile == Desktop) || (profile == DesktopGreeter));
385 auto menu = g_menu_new();
386
387+ const char * action_name;
388+
389+ if (profile == Phone)
390+ action_name = "indicator.phone.open-calendar-app";
391+ else if (profile == Desktop)
392+ action_name = "indicator.desktop.open-calendar-app";
393+ else
394+ action_name = nullptr;
395+
396 // add a menuitem that shows the current date
397 auto label = m_state->clock->localtime().format(_("%A, %e %B %Y"));
398 auto item = g_menu_item_new (label.c_str(), nullptr);
399 auto v = get_serialized_calendar_icon();
400 g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, v);
401- if (allow_activation)
402+ if (action_name != nullptr)
403 {
404 v = g_variant_new_int64(0);
405- const char* action = "indicator.activate-planner";
406- g_menu_item_set_action_and_target_value (item, action, v);
407+ g_menu_item_set_action_and_target_value (item, action_name, v);
408 }
409 g_menu_append_item(menu, item);
410 g_object_unref(item);
411@@ -253,11 +259,8 @@
412 g_menu_item_set_action_and_target_value (item, "indicator.calendar", v);
413 g_menu_item_set_attribute (item, "x-canonical-type",
414 "s", "com.canonical.indicator.calendar");
415- if (allow_activation)
416- {
417- g_menu_item_set_attribute (item, "activation-action",
418- "s", "indicator.activate-planner");
419- }
420+ if (action_name != nullptr)
421+ g_menu_item_set_attribute (item, "activation-action", "s", action_name);
422 g_menu_append_item (menu, item);
423 g_object_unref (item);
424 }
425@@ -270,6 +273,15 @@
426 const int MAX_APPTS = 5;
427 std::set<std::string> added;
428
429+ const char * action_name;
430+
431+ if (profile == Phone)
432+ action_name = "indicator.phone.open-appointment";
433+ else if ((profile == Desktop) && m_actions->desktop_has_calendar_app())
434+ action_name = "indicator.desktop.open-appointment";
435+ else
436+ action_name = nullptr;
437+
438 for (const auto& appt : m_upcoming)
439 {
440 // don't show duplicates
441@@ -303,15 +315,11 @@
442
443 if (!appt.color.empty())
444 g_menu_item_set_attribute (menu_item, "x-canonical-color", "s", appt.color.c_str());
445-
446- if (profile == Phone)
447- g_menu_item_set_action_and_target_value (menu_item,
448- "indicator.activate-appointment",
449- g_variant_new_string (appt.uid.c_str()));
450- else if (m_actions->can_open_planner())
451- g_menu_item_set_action_and_target_value (menu_item,
452- "indicator.activate-planner",
453- g_variant_new_int64 (unix_time));
454+
455+ if (action_name != nullptr)
456+ g_menu_item_set_action_and_target_value (menu_item, action_name,
457+ g_variant_new_string (appt.uid.c_str()));
458+
459 g_menu_append_item (menu, menu_item);
460 g_object_unref (menu_item);
461 }
462@@ -325,11 +333,11 @@
463 {
464 add_appointments (menu, profile);
465
466- if (m_actions->can_open_planner())
467+ if (m_actions->desktop_has_calendar_app())
468 {
469 // add the 'Add Event…' menuitem
470 auto menu_item = g_menu_item_new(_("Add Event…"), nullptr);
471- const gchar* action_name = "indicator.activate-planner";
472+ const gchar* action_name = "indicator.desktop.open-calendar-app";
473 auto v = g_variant_new_int64(0);
474 g_menu_item_set_action_and_target_value(menu_item, action_name, v);
475 g_menu_append_item(menu, menu_item);
476@@ -338,7 +346,7 @@
477 }
478 else if (profile==Phone)
479 {
480- auto menu_item = g_menu_item_new (_("Clock"), "indicator.activate-phone-clock-app");
481+ auto menu_item = g_menu_item_new (_("Clock"), "indicator.phone.open-alarm-app");
482 g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ICON, get_serialized_alarm_icon());
483 g_menu_append_item (menu, menu_item);
484 g_object_unref (menu_item);
485@@ -383,11 +391,11 @@
486
487 if (profile == Desktop)
488 {
489- g_menu_append (menu, _("Date & Time Settings…"), "indicator.activate-desktop-settings");
490+ g_menu_append (menu, _("Date & Time Settings…"), "indicator.desktop.open-settings-app");
491 }
492 else if (profile == Phone)
493 {
494- g_menu_append (menu, _("Time & Date settings…"), "indicator.activate-phone-settings");
495+ g_menu_append (menu, _("Time & Date settings…"), "indicator.phone.open-settings-app");
496 }
497
498 return G_MENU_MODEL (menu);
499
500=== modified file 'tests/actions-mock.h'
501--- tests/actions-mock.h 2014-03-06 23:54:57 +0000
502+++ tests/actions-mock.h 2014-03-22 07:33:30 +0000
503@@ -34,28 +34,54 @@
504 MockActions(std::shared_ptr<State>& state_in): Actions(state_in) {}
505 ~MockActions() =default;
506
507- enum Action { OpenDesktopSettings, OpenPhoneSettings, OpenPhoneClockApp,
508- OpenPlanner, OpenPlannerAt, OpenAppointment, SetLocation };
509+ enum Action { DesktopOpenAlarmApp,
510+ DesktopOpenAppt,
511+ DesktopOpenCalendarApp,
512+ DesktopOpenSettingsApp,
513+ PhoneOpenAlarmApp,
514+ PhoneOpenAppt,
515+ PhoneOpenCalendarApp,
516+ PhoneOpenSettingsApp,
517+ SetLocation };
518+
519 const std::vector<Action>& history() const { return m_history; }
520 const DateTime& date_time() const { return m_date_time; }
521 const std::string& zone() const { return m_zone; }
522 const std::string& name() const { return m_name; }
523- const std::string& url() const { return m_url; }
524+ const Appointment& appointment() const { return m_appt; }
525 void clear() { m_history.clear(); m_zone.clear(); m_name.clear(); }
526
527- void open_desktop_settings() { m_history.push_back(OpenDesktopSettings); }
528-
529- void open_phone_settings() { m_history.push_back(OpenPhoneSettings); }
530-
531- void open_phone_clock_app() { m_history.push_back(OpenPhoneClockApp); }
532-
533- bool can_open_planner() const { return m_can_open_planner; }
534-
535- void open_planner() { m_history.push_back(OpenPlanner); }
536-
537- void open_planner_at(const DateTime& date_time_) {
538- m_history.push_back(OpenPlannerAt);
539- m_date_time = date_time_;
540+ bool desktop_has_calendar_app() const {
541+ return m_desktop_has_calendar_app;
542+ }
543+ void desktop_open_alarm_app() {
544+ m_history.push_back(DesktopOpenAlarmApp);
545+ }
546+ void desktop_open_appointment(const Appointment& appt) {
547+ m_appt = appt;
548+ m_history.push_back(DesktopOpenAppt);
549+ }
550+ void desktop_open_calendar_app(const DateTime& dt) {
551+ m_date_time = dt;
552+ m_history.push_back(DesktopOpenCalendarApp);
553+ }
554+ void desktop_open_settings_app() {
555+ m_history.push_back(DesktopOpenSettingsApp);
556+ }
557+
558+ void phone_open_alarm_app() {
559+ m_history.push_back(PhoneOpenAlarmApp);
560+ }
561+ void phone_open_appointment(const Appointment& appt) {
562+ m_appt = appt;
563+ m_history.push_back(PhoneOpenAppt);
564+ }
565+ void phone_open_calendar_app(const DateTime& dt) {
566+ m_date_time = dt;
567+ m_history.push_back(PhoneOpenCalendarApp);
568+ }
569+ void phone_open_settings_app() {
570+ m_history.push_back(PhoneOpenSettingsApp);
571 }
572
573 void set_location(const std::string& zone_, const std::string& name_) {
574@@ -64,16 +90,13 @@
575 m_name = name_;
576 }
577
578- void open_appointment(const std::string& url_) {
579- m_history.push_back(OpenAppointment);
580- m_url = url_;
581+ void set_desktop_has_calendar_app(bool b) {
582+ m_desktop_has_calendar_app = b;
583 }
584
585- void set_can_open_planner(bool b) { m_can_open_planner = b; }
586-
587 private:
588- bool m_can_open_planner = true;
589- std::string m_url;
590+ bool m_desktop_has_calendar_app = true;
591+ Appointment m_appt;
592 std::string m_zone;
593 std::string m_name;
594 DateTime m_date_time;
595
596=== modified file 'tests/test-actions.cpp'
597--- tests/test-actions.cpp 2014-03-10 02:08:47 +0000
598+++ tests/test-actions.cpp 2014-03-22 07:33:30 +0000
599@@ -23,7 +23,130 @@
600
601 using namespace unity::indicator::datetime;
602
603-typedef StateFixture ActionsFixture;
604+class ActionsFixture: public StateFixture
605+{
606+ typedef StateFixture super;
607+
608+ std::vector<Appointment> build_some_appointments()
609+ {
610+ const auto now = m_state->clock->localtime();
611+ auto gdt_tomorrow = g_date_time_add_days(now.get(), 1);
612+ const auto tomorrow = DateTime(gdt_tomorrow);
613+ g_date_time_unref(gdt_tomorrow);
614+
615+ Appointment a1; // an alarm clock appointment
616+ a1.color = "red";
617+ a1.summary = "Alarm";
618+ a1.summary = "http://www.example.com/";
619+ a1.uid = "example";
620+ a1.has_alarms = true;
621+ a1.begin = a1.end = tomorrow;
622+
623+ Appointment a2; // a non-alarm appointment
624+ a2.color = "green";
625+ a2.summary = "Other Text";
626+ a2.summary = "http://www.monkey.com/";
627+ a2.uid = "monkey";
628+ a2.has_alarms = false;
629+ a2.begin = a2.end = tomorrow;
630+
631+ return std::vector<Appointment>({a1, a2});
632+ }
633+
634+protected:
635+
636+ virtual void SetUp()
637+ {
638+ super::SetUp();
639+ }
640+
641+ virtual void TearDown()
642+ {
643+ super::TearDown();
644+ }
645+
646+ void test_action_with_no_args(const char * action_name,
647+ MockActions::Action expected_action)
648+ {
649+ // preconditions
650+ EXPECT_TRUE(m_mock_actions->history().empty());
651+ auto action_group = m_actions->action_group();
652+ EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
653+
654+ // run the test
655+ g_action_group_activate_action(action_group, action_name, nullptr);
656+
657+ // test the results
658+ EXPECT_EQ(std::vector<MockActions::Action>({expected_action}),
659+ m_mock_actions->history());
660+ }
661+
662+ void test_action_with_time_arg(const char * action_name,
663+ MockActions::Action expected_action)
664+ {
665+ // preconditions
666+ EXPECT_TRUE(m_mock_actions->history().empty());
667+ auto action_group = m_actions->action_group();
668+ EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
669+
670+ // activate the action
671+ const auto now = DateTime::NowLocal();
672+ auto v = g_variant_new_int64(now.to_unix());
673+ g_action_group_activate_action(action_group, action_name, v);
674+
675+ // test the results
676+ EXPECT_EQ(std::vector<MockActions::Action>({expected_action}),
677+ m_mock_actions->history());
678+ EXPECT_EQ(now.format("%F %T"),
679+ m_mock_actions->date_time().format("%F %T"));
680+ }
681+
682+ void test_action_with_appt_arg(const char * action_name,
683+ MockActions::Action expected_action)
684+ {
685+ ///
686+ /// Test 1: activate an appointment that we know about
687+ ///
688+
689+ // preconditions
690+ EXPECT_TRUE(m_mock_actions->history().empty());
691+ auto action_group = m_actions->action_group();
692+ EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
693+
694+ // init some appointments to the state
695+ const auto appointments = build_some_appointments();
696+ m_mock_state->mock_range_planner->appointments().set(appointments);
697+
698+ // activate the action
699+ auto v = g_variant_new_string(appointments[0].uid.c_str());
700+ g_action_group_activate_action(action_group, action_name, v);
701+
702+ // test the results
703+ EXPECT_EQ(std::vector<MockActions::Action>({expected_action}),
704+ m_mock_actions->history());
705+ EXPECT_EQ(appointments[0],
706+ m_mock_actions->appointment());
707+
708+ ///
709+ /// Test 2: activate an appointment we *don't* know about
710+ ///
711+
712+ // setup
713+ m_mock_actions->clear();
714+ EXPECT_TRUE(m_mock_actions->history().empty());
715+
716+ // activate the action
717+ v = g_variant_new_string("this-uid-is-not-one-that-we-have");
718+ g_action_group_activate_action(action_group, action_name, v);
719+
720+ // test the results
721+ EXPECT_TRUE(m_mock_actions->history().empty());
722+ }
723+};
724+
725+/***
726+****
727+***/
728
729 TEST_F(ActionsFixture, ActionsExist)
730 {
731@@ -32,92 +155,80 @@
732 const char* names[] = { "desktop-header",
733 "calendar",
734 "set-location",
735- "activate-planner",
736- "activate-appointment",
737- "activate-phone-settings",
738- "activate-phone-clock-app",
739- "activate-desktop-settings" };
740+ "desktop.open-appointment",
741+ "desktop.open-alarm-app",
742+ "desktop.open-calendar-app",
743+ "desktop.open-settings-app",
744+ "phone.open-appointment",
745+ "phone.open-alarm-app",
746+ "phone.open-calendar-app",
747+ "phone.open-settings-app" };
748+
749 for(const auto& name: names)
750 {
751 EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), name));
752 }
753 }
754
755-TEST_F(ActionsFixture, ActivateDesktopSettings)
756-{
757- const auto action_name = "activate-desktop-settings";
758- const auto expected_action = MockActions::OpenDesktopSettings;
759-
760- auto action_group = m_actions->action_group();
761- auto history = m_mock_actions->history();
762- EXPECT_EQ(0, history.size());
763- EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
764-
765- g_action_group_activate_action(action_group, action_name, nullptr);
766- history = m_mock_actions->history();
767- EXPECT_EQ(1, history.size());
768- EXPECT_EQ(expected_action, history[0]);
769-}
770-
771-TEST_F(ActionsFixture, ActivatePhoneSettings)
772-{
773- const auto action_name = "activate-phone-settings";
774- const auto expected_action = MockActions::OpenPhoneSettings;
775-
776- auto action_group = m_actions->action_group();
777- EXPECT_TRUE(m_mock_actions->history().empty());
778- EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
779-
780- g_action_group_activate_action(action_group, action_name, nullptr);
781- auto history = m_mock_actions->history();
782- EXPECT_EQ(1, history.size());
783- EXPECT_EQ(expected_action, history[0]);
784-}
785-
786-TEST_F(ActionsFixture, ActivatePhoneClockApp)
787-{
788- const auto action_name = "activate-phone-clock-app";
789- const auto expected_action = MockActions::OpenPhoneClockApp;
790-
791- auto action_group = m_actions->action_group();
792- EXPECT_TRUE(m_mock_actions->history().empty());
793- EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
794-
795- g_action_group_activate_action(action_group, action_name, nullptr);
796- auto history = m_mock_actions->history();
797- EXPECT_EQ(1, history.size());
798- EXPECT_EQ(expected_action, history[0]);
799-}
800-
801-TEST_F(ActionsFixture, ActivatePlanner)
802-{
803- const auto action_name = "activate-planner";
804- auto action_group = m_actions->action_group();
805- EXPECT_TRUE(m_mock_actions->history().empty());
806- EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
807-
808- const auto expected_action = MockActions::OpenPlanner;
809- auto v = g_variant_new_int64(0);
810- g_action_group_activate_action(action_group, action_name, v);
811- auto history = m_mock_actions->history();
812- EXPECT_EQ(1, history.size());
813- EXPECT_EQ(expected_action, history[0]);
814-}
815-
816-TEST_F(ActionsFixture, ActivatePlannerAt)
817-{
818- const auto action_name = "activate-planner";
819- auto action_group = m_actions->action_group();
820- EXPECT_TRUE(m_mock_actions->history().empty());
821- EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
822-
823- const auto now = DateTime::NowLocal();
824- auto v = g_variant_new_int64(now.to_unix());
825- g_action_group_activate_action(action_group, action_name, v);
826- const auto a = MockActions::OpenPlannerAt;
827- EXPECT_EQ(std::vector<MockActions::Action>({a}), m_mock_actions->history());
828- EXPECT_EQ(now.to_unix(), m_mock_actions->date_time().to_unix());
829-}
830+/***
831+****
832+***/
833+
834+TEST_F(ActionsFixture, DesktopOpenAlarmApp)
835+{
836+ test_action_with_no_args("desktop.open-alarm-app",
837+ MockActions::DesktopOpenAlarmApp);
838+}
839+
840+TEST_F(ActionsFixture, DesktopOpenAppointment)
841+{
842+ test_action_with_appt_arg("desktop.open-appointment",
843+ MockActions::DesktopOpenAppt);
844+}
845+
846+TEST_F(ActionsFixture, DesktopOpenCalendarApp)
847+{
848+ test_action_with_time_arg("desktop.open-calendar-app",
849+ MockActions::DesktopOpenCalendarApp);
850+}
851+
852+TEST_F(ActionsFixture, DesktopOpenSettingsApp)
853+{
854+ test_action_with_no_args("desktop.open-settings-app",
855+ MockActions::DesktopOpenSettingsApp);
856+}
857+
858+/***
859+****
860+***/
861+
862+TEST_F(ActionsFixture, PhoneOpenAlarmApp)
863+{
864+ test_action_with_no_args("phone.open-alarm-app",
865+ MockActions::PhoneOpenAlarmApp);
866+}
867+
868+TEST_F(ActionsFixture, PhoneOpenAppointment)
869+{
870+ test_action_with_appt_arg("phone.open-appointment",
871+ MockActions::PhoneOpenAppt);
872+}
873+
874+TEST_F(ActionsFixture, PhoneOpenCalendarApp)
875+{
876+ test_action_with_time_arg("phone.open-calendar-app",
877+ MockActions::PhoneOpenCalendarApp);
878+}
879+
880+TEST_F(ActionsFixture, PhoneOpenSettingsApp)
881+{
882+ test_action_with_no_args("phone.open-settings-app",
883+ MockActions::PhoneOpenSettingsApp);
884+}
885+
886+/***
887+****
888+***/
889
890 TEST_F(ActionsFixture, SetLocation)
891 {
892@@ -209,26 +320,3 @@
893 g_clear_pointer(&calendar_state, g_variant_unref);
894
895 }
896-
897-
898-TEST_F(ActionsFixture, OpenAppointment)
899-{
900- Appointment appt;
901- appt.uid = "some arbitrary uid";
902- appt.url = "http://www.canonical.com/";
903- appt.begin = m_state->clock->localtime();
904- m_state->calendar_upcoming->appointments().set(std::vector<Appointment>({appt}));
905-
906- const auto action_name = "activate-appointment";
907- auto action_group = m_actions->action_group();
908- EXPECT_TRUE(m_mock_actions->history().empty());
909- EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
910-
911- auto v = g_variant_new_string(appt.uid.c_str());
912- g_action_group_activate_action(action_group, action_name, v);
913- const auto a = MockActions::OpenAppointment;
914- ASSERT_EQ(1, m_mock_actions->history().size());
915- ASSERT_EQ(a, m_mock_actions->history()[0]);
916- EXPECT_EQ(appt.url, m_mock_actions->url());
917-}
918-
919
920=== modified file 'tests/test-exporter.cpp'
921--- tests/test-exporter.cpp 2014-01-27 07:26:52 +0000
922+++ tests/test-exporter.cpp 2014-03-22 07:33:30 +0000
923@@ -104,11 +104,14 @@
924 names.insert(names_strv[i]);
925
926 // confirm the actions that we expect
927- EXPECT_EQ(1, names.count("activate-appointment"));
928- EXPECT_EQ(1, names.count("activate-desktop-settings"));
929- EXPECT_EQ(1, names.count("activate-phone-clock-app"));
930- EXPECT_EQ(1, names.count("activate-phone-settings"));
931- EXPECT_EQ(1, names.count("activate-planner"));
932+ EXPECT_EQ(1, names.count("desktop.open-alarm-app"));
933+ EXPECT_EQ(1, names.count("desktop.open-appointment"));
934+ EXPECT_EQ(1, names.count("desktop.open-calendar-app"));
935+ EXPECT_EQ(1, names.count("desktop.open-settings-app"));
936+ EXPECT_EQ(1, names.count("phone.open-alarm-app"));
937+ EXPECT_EQ(1, names.count("phone.open-appointment"));
938+ EXPECT_EQ(1, names.count("phone.open-calendar-app"));
939+ EXPECT_EQ(1, names.count("phone.open-settings-app"));
940 EXPECT_EQ(1, names.count("calendar"));
941 EXPECT_EQ(1, names.count("desktop_greeter-header"));
942 EXPECT_EQ(1, names.count("desktop-header"));
943
944=== modified file 'tests/test-live-actions.cpp'
945--- tests/test-live-actions.cpp 2014-03-13 14:22:16 +0000
946+++ tests/test-live-actions.cpp 2014-03-22 07:33:30 +0000
947@@ -252,43 +252,94 @@
948 EXPECT_EQ(expected, m_state->settings->timezone_name.get());
949 }
950
951-TEST_F(LiveActionsFixture, OpenDesktopSettings)
952-{
953- m_actions->open_desktop_settings();
954+/***
955+****
956+***/
957+
958+TEST_F(LiveActionsFixture, DesktopOpenAlarmApp)
959+{
960+ m_actions->desktop_open_alarm_app();
961+ const std::string expected = "evolution -c calendar";
962+ EXPECT_EQ(expected, m_live_actions->last_cmd);
963+}
964+
965+TEST_F(LiveActionsFixture, DesktopOpenAppointment)
966+{
967+ Appointment a;
968+ a.uid = "some-uid";
969+ a.begin = DateTime::NowLocal();
970+ m_actions->desktop_open_appointment(a);
971+ const std::string expected_substr = "evolution \"calendar:///?startdate=";
972+ EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos);
973+}
974+
975+TEST_F(LiveActionsFixture, DesktopOpenCalendarApp)
976+{
977+ m_actions->desktop_open_calendar_app(DateTime::NowLocal());
978+ const std::string expected_substr = "evolution \"calendar:///?startdate=";
979+ EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos);
980+}
981+
982+TEST_F(LiveActionsFixture, DesktopOpenSettingsApp)
983+{
984+ m_actions->desktop_open_settings_app();
985 const std::string expected_substr = "control-center";
986 EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos);
987 }
988
989-TEST_F(LiveActionsFixture, OpenPlanner)
990-{
991- m_actions->open_planner();
992- const std::string expected = "evolution -c calendar";
993- EXPECT_EQ(expected, m_live_actions->last_cmd);
994-}
995-
996-TEST_F(LiveActionsFixture, OpenPhoneSettings)
997-{
998- m_actions->open_phone_settings();
999+/***
1000+****
1001+***/
1002+
1003+namespace
1004+{
1005+ const std::string clock_app_url = "appid://com.ubuntu.clock/clock/current-user-version";
1006+
1007+ const std::string calendar_app_url = "appid://com.ubuntu.calendar/calendar/current-user-version";
1008+}
1009+
1010+TEST_F(LiveActionsFixture, PhoneOpenAlarmApp)
1011+{
1012+ m_actions->phone_open_alarm_app();
1013+ EXPECT_EQ(clock_app_url, m_live_actions->last_url);
1014+}
1015+
1016+TEST_F(LiveActionsFixture, PhoneOpenAppointment)
1017+{
1018+ Appointment a;
1019+
1020+ a.uid = "some-uid";
1021+ a.begin = DateTime::NowLocal();
1022+ a.has_alarms = false;
1023+ m_actions->phone_open_appointment(a);
1024+ EXPECT_EQ(calendar_app_url, m_live_actions->last_url);
1025+
1026+ a.has_alarms = true;
1027+ m_actions->phone_open_appointment(a);
1028+ EXPECT_EQ(clock_app_url, m_live_actions->last_url);
1029+
1030+ a.url = "appid://blah";
1031+ m_actions->phone_open_appointment(a);
1032+ EXPECT_EQ(a.url, m_live_actions->last_url);
1033+}
1034+
1035+TEST_F(LiveActionsFixture, PhoneOpenCalendarApp)
1036+{
1037+ m_actions->phone_open_calendar_app(DateTime::NowLocal());
1038+ const std::string expected = "appid://com.ubuntu.calendar/calendar/current-user-version";
1039+ EXPECT_EQ(expected, m_live_actions->last_url);
1040+}
1041+
1042+TEST_F(LiveActionsFixture, PhoneOpenSettingsApp)
1043+{
1044+ m_actions->phone_open_settings_app();
1045 const std::string expected = "settings:///system/time-date";
1046 EXPECT_EQ(expected, m_live_actions->last_url);
1047 }
1048
1049-TEST_F(LiveActionsFixture, OpenPhoneClockApp)
1050-{
1051- m_actions->open_phone_clock_app();
1052- const std::string expected = "appid://com.ubuntu.clock/clock/current-user-version";
1053- EXPECT_EQ(expected, m_live_actions->last_url);
1054-}
1055-
1056-TEST_F(LiveActionsFixture, OpenPlannerAt)
1057-{
1058- const auto now = DateTime::NowLocal();
1059- m_actions->open_planner_at(now);
1060- const auto today_begins = now.add_full(0, 0, 0, -now.hour(), -now.minute(), -now.seconds());
1061- const auto gmt = today_begins.to_timezone("UTC");
1062- const auto expected = gmt.format("evolution \"calendar:///?startdate=%Y%m%dT%H%M%SZ\"");
1063- EXPECT_EQ(expected, m_live_actions->last_cmd);
1064-}
1065+/***
1066+****
1067+***/
1068
1069 TEST_F(LiveActionsFixture, CalendarState)
1070 {
1071
1072=== modified file 'tests/test-menus.cpp'
1073--- tests/test-menus.cpp 2014-03-10 03:32:19 +0000
1074+++ tests/test-menus.cpp 2014-03-22 07:33:30 +0000
1075@@ -92,7 +92,16 @@
1076 void InspectCalendar(GMenuModel* menu_model, Menu::Profile profile)
1077 {
1078 gchar* str = nullptr;
1079- const auto actions_expected = (profile == Menu::Desktop) || (profile == Menu::Phone);
1080+
1081+ const char * expected_action;
1082+
1083+ if (profile == Menu::Desktop)
1084+ expected_action = "indicator.desktop.open-calendar-app";
1085+ else if (profile == Menu::Phone)
1086+ expected_action = "indicator.phone.open-calendar-app";
1087+ else
1088+ expected_action = nullptr;
1089+
1090 const auto calendar_expected = ((profile == Menu::Desktop) || (profile == Menu::DesktopGreeter))
1091 && (m_state->settings->show_calendar.get());
1092
1093@@ -113,8 +122,8 @@
1094 g_clear_pointer(&str, g_free);
1095
1096 g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str);
1097- if (actions_expected)
1098- EXPECT_STREQ("indicator.activate-planner", str);
1099+ if (expected_action != nullptr)
1100+ EXPECT_STREQ(expected_action, str);
1101 else
1102 EXPECT_TRUE(str == nullptr);
1103 g_clear_pointer(&str, g_free);
1104@@ -131,8 +140,8 @@
1105 g_clear_pointer(&str, g_free);
1106
1107 g_menu_model_get_item_attribute(section, 1, "activation-action", "s", &str);
1108- if (actions_expected)
1109- EXPECT_STREQ("indicator.activate-planner", str);
1110+ if (expected_action != nullptr)
1111+ EXPECT_STREQ(expected_action, str);
1112 else
1113 EXPECT_TRUE(str == nullptr);
1114 g_clear_pointer(&str, g_free);
1115@@ -297,7 +306,7 @@
1116 // there should be an "add event" button even if there aren't any appointments
1117 gchar* action = nullptr;
1118 EXPECT_TRUE(g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &action));
1119- const char* expected_action = "activate-planner";
1120+ const char* expected_action = "desktop.open-calendar-app";
1121 EXPECT_EQ(std::string("indicator.")+expected_action, action);
1122 EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), expected_action));
1123 g_free(action);
1124@@ -328,7 +337,7 @@
1125
1126 // check that there's a "clock app" menuitem even when there are no appointments
1127 auto section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION);
1128- const char* expected_action = "activate-phone-clock-app";
1129+ const char* expected_action = "phone.open-alarm-app";
1130 EXPECT_EQ(1, g_menu_model_get_n_items(section));
1131 gchar* action = nullptr;
1132 EXPECT_TRUE(g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &action));
1133@@ -354,7 +363,7 @@
1134
1135 void InspectAppointments(GMenuModel* menu_model, Menu::Profile profile)
1136 {
1137- const auto can_open_planner = m_actions->can_open_planner();
1138+ const auto can_open_planner = m_actions->desktop_has_calendar_app();
1139
1140 switch (profile)
1141 {
1142@@ -443,9 +452,9 @@
1143 std::string expected_action;
1144
1145 if (profile == Menu::Desktop)
1146- expected_action = "indicator.activate-desktop-settings";
1147+ expected_action = "indicator.desktop.open-settings-app";
1148 else if (profile == Menu::Phone)
1149- expected_action = "indicator.activate-phone-settings";
1150+ expected_action = "indicator.phone.open-settings-app";
1151
1152 // get the Settings section
1153 auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU);
1154@@ -520,7 +529,7 @@
1155 // toggle can_open_planner() and test the desktop again
1156 // to confirm that the "Add Event…" menuitem appears iff
1157 // there's a calendar available user-agent
1158- m_mock_actions->set_can_open_planner (!m_actions->can_open_planner());
1159+ m_mock_actions->set_desktop_has_calendar_app (!m_actions->desktop_has_calendar_app());
1160 std::shared_ptr<Menu> menu = m_menu_factory->buildMenu(Menu::Desktop);
1161 InspectAppointments(menu->menu_model(), menu->profile());
1162 }

Subscribers

People subscribed via source and target branches