Merge lp:~renatofilho/address-book-app/fix-1268731 into lp:address-book-app

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Bill Filler
Approved revision: 119
Merged at revision: 118
Proposed branch: lp:~renatofilho/address-book-app/fix-1268731
Merge into: lp:address-book-app
Diff against target: 412 lines (+189/-43)
10 files modified
src/imports/Common/ContactDetailGroupBase.qml (+1/-1)
src/imports/Common/ContactDetailGroupWithTypeBase.qml (+3/-8)
src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml (+1/-1)
src/imports/ContactView/ContactDetailGroupWithTypeView.qml (+1/-1)
src/imports/ContactView/ContactDetailPhoneNumbersView.qml (+1/-1)
src/imports/Ubuntu/Contacts/ContactDetailOnlineAccountTypeModel.qml (+3/-0)
src/imports/Ubuntu/Contacts/ContactDetailPhoneNumberTypeModel.qml (+7/-13)
tests/autopilot/address_book_app/tests/__init__.py (+46/-16)
tests/autopilot/address_book_app/tests/test_add_contact.py (+124/-0)
tests/autopilot/address_book_app/tests/test_edit_contact.py (+2/-2)
To merge this branch: bzr merge lp:~renatofilho/address-book-app/fix-1268731
Reviewer Review Type Date Requested Status
Bill Filler (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+201524@code.launchpad.net

Commit message

Fixed phone and email context save.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
118. By Renato Araujo Oliveira Filho

Fixed field label with memory manager.

119. By Renato Araujo Oliveira Filho

Created autopilot test for phone and email field label.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote :

Does not work for me. Here is what I tested

0) first I synced my google contacts
1) Add new contact
2) fill in first name and last name
3) add 3 email addresses (home, work, other)
4) press save

I either get "Failed to load contacts" dialog, or if I try again I just get spinning cursor on the black screen with "Cancel" and "Save" buttons showing on the bottom.

This is in the ~/.cache/upstart/application-legacy-address-book-app-.log:

void QtContacts::QDeclarativeContactModel::onContactsAddedFetchRequestStateChanged(QtContacts::QContactAbstractRequest::State) contact to be added already exists in the model

review: Needs Fixing
Revision history for this message
Bill Filler (bfiller) wrote :

Also with this branch this is broken:

1) create new contact with just first name/last name and nothing else
2) edit the contact and add 3 email addresses
3) save the contact, this is saved correctly
4) try to delete the contact

the contact is not deleted and cannot be deleted from toolbar or swipe to delete

review: Needs Fixing
Revision history for this message
Bill Filler (bfiller) wrote :

the reported problems are not due to this branch, they are reported here:
https://bugs.launchpad.net/ubuntu/+source/address-book-app/+bug/1269561

approving this branch

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/imports/Common/ContactDetailGroupBase.qml'
2--- src/imports/Common/ContactDetailGroupBase.qml 2013-11-14 13:25:28 +0000
3+++ src/imports/Common/ContactDetailGroupBase.qml 2014-01-14 20:44:40 +0000
4@@ -112,7 +112,7 @@
5 Binding {
6 target: detailItem.item
7 property: "detail"
8- value: root.details[index]
9+ value: root.contact && root.details ? root.details[index] : null
10 }
11
12 Binding {
13
14=== modified file 'src/imports/Common/ContactDetailGroupWithTypeBase.qml'
15--- src/imports/Common/ContactDetailGroupWithTypeBase.qml 2013-07-15 22:43:13 +0000
16+++ src/imports/Common/ContactDetailGroupWithTypeBase.qml 2014-01-14 20:44:40 +0000
17@@ -40,7 +40,7 @@
18 }
19
20 typeModel: ListModel {
21-
22+ property bool ready: false
23 signal loaded()
24
25 function getTypeIndex(detail) {
26@@ -61,7 +61,7 @@
27 return 0
28 } else if (context === QtContacts.ContactDetail.ContextWork) {
29 return 1
30- } else if (subType === QtContacts.ContactDetail.ContextOther) {
31+ } else if (context === QtContacts.ContactDetail.ContextOther) {
32 return 2
33 } else {
34 return 0 // default value is "Home"
35@@ -103,12 +103,6 @@
36 return false
37 }
38
39- // WORKAROUND: in EDS empty context is equal to QtContacts.ContactDetail.ContextOther
40- // this will avoid call contact update if the context has not changed
41- if ((detail.contexts.length === 0) && (modelData.value === QtContacts.ContactDetail.ContextOther)) {
42- return false
43- }
44-
45 var newContext = detail.contexts.filter(isNotAModelValue)
46 newContext.push(modelData.value)
47 if (!compareList(newContext, detail.contexts)) {
48@@ -122,6 +116,7 @@
49 append({"value": QtContacts.ContactDetail.ContextHome, "label": i18n.tr("Home"), "icon": null})
50 append({"value": QtContacts.ContactDetail.ContextWork, "label": i18n.tr("Work"), "icon": null})
51 append({"value": QtContacts.ContactDetail.ContextOther, "label": i18n.tr("Other"), "icon": null})
52+ ready = true
53 loaded()
54 }
55 }
56
57=== modified file 'src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml'
58--- src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml 2013-11-18 19:17:01 +0000
59+++ src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml 2014-01-14 20:44:40 +0000
60@@ -160,7 +160,7 @@
61 Item {
62 Connections {
63 target: root.typeModel
64- onLoaded: updateCombo(true)
65+ onReadyChanged: updateCombo(true)
66 }
67 }
68 }
69
70=== modified file 'src/imports/ContactView/ContactDetailGroupWithTypeView.qml'
71--- src/imports/ContactView/ContactDetailGroupWithTypeView.qml 2013-10-21 19:42:00 +0000
72+++ src/imports/ContactView/ContactDetailGroupWithTypeView.qml 2014-01-14 20:44:40 +0000
73@@ -51,7 +51,7 @@
74 }
75
76 detailDelegate: ContactDetailWithTypeView {
77- property variant detailType: detail && root.contact && root.typeModel ? root.getType(detail) : null
78+ property variant detailType: detail && root.contact && root.typeModel.ready ? root.getType(detail) : null
79
80 action: root.defaultAction
81 contact: root.contact
82
83=== modified file 'src/imports/ContactView/ContactDetailPhoneNumbersView.qml'
84--- src/imports/ContactView/ContactDetailPhoneNumbersView.qml 2013-11-14 13:25:28 +0000
85+++ src/imports/ContactView/ContactDetailPhoneNumbersView.qml 2014-01-14 20:44:40 +0000
86@@ -35,7 +35,7 @@
87 }
88
89 detailDelegate: ContactDetailPhoneNumberView {
90- property variant detailType: detail && root.contact && root.typeModel ? root.getType(detail) : null
91+ property variant detailType: detail && root.contact && root.typeModel.ready ? root.getType(detail) : null
92 property bool isPreferred: root.contact && root.contact.preferredDetails && detail && root.contact.isPreferredDetail("TEL", detail)
93
94 action: Action {
95
96=== modified file 'src/imports/Ubuntu/Contacts/ContactDetailOnlineAccountTypeModel.qml'
97--- src/imports/Ubuntu/Contacts/ContactDetailOnlineAccountTypeModel.qml 2013-07-31 19:36:55 +0000
98+++ src/imports/Ubuntu/Contacts/ContactDetailOnlineAccountTypeModel.qml 2014-01-14 20:44:40 +0000
99@@ -20,6 +20,8 @@
100 ListModel {
101 id: typeModel
102
103+ property bool ready: false
104+
105 signal loaded()
106
107 function getTypeIndex(detail) {
108@@ -67,5 +69,6 @@
109 /*4*/ append({"value": 7, "label": i18n.tr("Skype"), "icon": "artwork:/protocol-skype.svg"})
110 /*5*/ append({"value": 8, "label": i18n.tr("Yahoo"), "icon": "artwork:/protocol-yahoo.svg"})
111 loaded()
112+ ready = true
113 }
114 }
115
116=== modified file 'src/imports/Ubuntu/Contacts/ContactDetailPhoneNumberTypeModel.qml'
117--- src/imports/Ubuntu/Contacts/ContactDetailPhoneNumberTypeModel.qml 2013-07-31 19:36:55 +0000
118+++ src/imports/Ubuntu/Contacts/ContactDetailPhoneNumberTypeModel.qml 2014-01-14 20:44:40 +0000
119@@ -20,6 +20,7 @@
120 ListModel {
121 id: typeModel
122
123+ property bool ready: false
124 signal loaded()
125
126 function getTypeIndex(detail) {
127@@ -38,7 +39,9 @@
128 } else {
129 return 1
130 }
131- } else{
132+ } else if (contexts.indexOf(QtContacts.ContactDetail.ContextOther) > -1) {
133+ return 4
134+ } else {
135 return 2 // Default value is "Mobile"
136 }
137 }
138@@ -69,21 +72,11 @@
139 return false
140 }
141
142-// // WORKAROUND: in EDS empty context is equal to QtContacts.ContactDetail.ContextOther
143-// // this will avoid call contact update if the context has not changed
144-// if ((detail.contexts.length === 0) && (modelData.value === "Other")) {
145-// return
146-// }
147-
148 var newSubTypes = []
149 var newContext = []
150
151 newContext.push(modelData.context)
152- if (modelData.subType !== -1) {
153- newSubTypes.push(modelData.subType)
154- }
155- // All current labels is voice type
156- newSubTypes.push(QtContacts.PhoneNumber.Voice)
157+ newSubTypes.push(modelData.subType)
158
159 var changed = false
160 if (!compareList(newContext, detail.contexts)) {
161@@ -108,7 +101,8 @@
162 append({"value": "Mobile-Work", "label": i18n.tr("Work Mobile"), "icon": null,
163 "context": QtContacts.ContactDetail.ContextWork, "subType": QtContacts.PhoneNumber.Mobile })
164 append({"value": "Other", "label": i18n.tr("Other"), "icon": null,
165- "context": QtContacts.ContactDetail.ContextOther, "subType": -1 })
166+ "context": QtContacts.ContactDetail.ContextOther, "subType": QtContacts.PhoneNumber.Landline })
167 loaded()
168+ ready = true
169 }
170 }
171
172=== modified file 'tests/autopilot/address_book_app/tests/__init__.py'
173--- tests/autopilot/address_book_app/tests/__init__.py 2014-01-10 15:07:11 +0000
174+++ tests/autopilot/address_book_app/tests/__init__.py 2014-01-14 20:44:40 +0000
175@@ -78,8 +78,6 @@
176 def launch_test_installed(self):
177 df = "/usr/share/applications/address-book-app.desktop"
178 self.ARGS.append("--desktop_file_hint=" + df)
179- print "ARGS:", AddressBookAppTestCase.ARGS
180- print "ENV:", os.environ["ADDRESS_BOOK_TEST_DATA"]
181 self.app = self.launch_test_application(
182 "address-book-app",
183 *AddressBookAppTestCase.ARGS,
184@@ -159,6 +157,50 @@
185
186 return edit_page
187
188+ def set_phone_number(self, idx, phone_number, phone_type=-1):
189+ phoneGroup = self.main_window.select_single(
190+ "ContactDetailGroupWithTypeEditor",
191+ objectName="phones")
192+
193+ if (idx > 0):
194+ self.create_new_detail(phoneGroup)
195+
196+ phone_number_input = self.main_window.select_single(
197+ "TextInputDetail",
198+ objectName="phoneNumber_" + str(idx))
199+ self.type_on_field(phone_number_input, phone_number)
200+
201+ if (phone_type != -1):
202+ phone_value_selector = self.main_window.select_single(
203+ "ValueSelector",
204+ objectName="type_phoneNumber_" + str(idx))
205+ self.pointing_device.click_object(phone_value_selector)
206+ self.select_a_value(phone_number_input,
207+ phone_value_selector,
208+ phone_type)
209+
210+ def set_email_address(self, idx, email_address, email_type=-1):
211+ emailGroup = self.main_window.select_single(
212+ "ContactDetailGroupWithTypeEditor",
213+ objectName="emails")
214+
215+ if (idx > 0):
216+ self.create_new_detail(emailGroup)
217+
218+ email_address_input = self.main_window.select_single(
219+ "TextInputDetail",
220+ objectName="emailAddress_" + str(idx))
221+ self.type_on_field(email_address_input, email_address)
222+
223+ if (email_type != -1):
224+ email_value_selector = self.main_window.select_single(
225+ "ValueSelector",
226+ objectName="type_email_" + str(idx))
227+ self.pointing_device.click_object(email_value_selector)
228+ self.select_a_value(email_address_input,
229+ email_value_selector,
230+ email_type)
231+
232 def add_contact(self,
233 first_name,
234 last_name,
235@@ -187,26 +229,14 @@
236 "ContactDetailGroupWithTypeEditor",
237 objectName="phones")
238 for idx, number in enumerate(phone_numbers):
239- if (idx > 0):
240- self.create_new_detail(phoneGroup)
241-
242- phone_number_input = self.main_window.select_single(
243- "TextInputDetail",
244- objectName="phoneNumber_" + str(idx))
245- self.type_on_field(phone_number_input, number)
246+ self.set_phone_number(idx, number)
247
248 if (email_address):
249 emailGroup = self.main_window.select_single(
250 "ContactDetailGroupWithTypeEditor",
251 objectName="emails")
252 for idx, address in enumerate(email_address):
253- if (idx > 0):
254- self.create_new_detail(emailGroup)
255-
256- email_address_input = self.main_window.select_single(
257- "TextInputDetail",
258- objectName="emailAddress_" + str(idx))
259- self.type_on_field(email_address_input, address)
260+ self.set_email_address(idx, address)
261
262 if (im_address):
263 imGroup = self.main_window.select_single(
264
265=== modified file 'tests/autopilot/address_book_app/tests/test_add_contact.py'
266--- tests/autopilot/address_book_app/tests/test_add_contact.py 2013-11-21 12:14:04 +0000
267+++ tests/autopilot/address_book_app/tests/test_add_contact.py 2014-01-14 20:44:40 +0000
268@@ -279,3 +279,127 @@
269 "ContactListView",
270 objectName="contactListView")
271 self.assertThat(list_view.count, Eventually(Equals(1)))
272+
273+ def test_email_label_save(self):
274+ # execute add new contact
275+ self.main_window.open_toolbar().click_button("Add")
276+
277+ # fill name
278+ firstNameField = self.main_window.wait_select_single(
279+ "TextInputDetail",
280+ objectName="firstName")
281+ lastNameField = self.main_window.wait_select_single(
282+ "TextInputDetail",
283+ objectName="lastName")
284+ self.type_on_field(firstNameField, "Sherlock")
285+ self.type_on_field(lastNameField, "Holmes")
286+
287+ # Home
288+ self.set_email_address(0, "home@email.com", 0)
289+ # Work
290+ self.set_email_address(1, "work@email.com", 1)
291+ # Other
292+ self.set_email_address(2, "other@email.com", 2)
293+
294+ # Save contact
295+ acceptButton = self.main_window.wait_select_single(
296+ "Button",
297+ objectName="accept")
298+ self.pointing_device.click_object(acceptButton)
299+
300+ contacts = self.main_window.select_many("ContactDelegate")
301+ self.pointing_device.click_object(contacts[0])
302+
303+ # check if contacts was saved with the correct labels
304+ view_page = self.main_window.get_contact_view_page()
305+ self.assertThat(view_page.visible, Eventually(Equals(True)))
306+
307+ # check if we have 3 emails"""
308+ email_group = view_page.select_single(
309+ "ContactDetailGroupWithTypeView",
310+ objectName="emails")
311+ self.assertThat(email_group.detailsCount, Eventually(Equals(3)))
312+
313+ emails = {"home@email.com" : "Home",
314+ "work@email.com" : "Work",
315+ "other@email.com" : "Other"}
316+
317+ # Check if they have the correct label
318+ for idx in range(3):
319+ email_type = view_page.select_single(
320+ "Label",
321+ objectName="type_email_" + str(idx))
322+
323+ email_label = view_page.select_single(
324+ "Label",
325+ objectName="label_emailAddress_" + str(idx) + ".0")
326+
327+ self.assertThat(emails[email_label.text], Equals(email_type.text))
328+ del emails[email_label.text]
329+
330+ self.assertThat(len(emails), Equals(0))
331+
332+ def test_phone_label_save(self):
333+ # execute add new contact
334+ self.main_window.open_toolbar().click_button("Add")
335+
336+ # fill name
337+ firstNameField = self.main_window.wait_select_single(
338+ "TextInputDetail",
339+ objectName="firstName")
340+ lastNameField = self.main_window.wait_select_single(
341+ "TextInputDetail",
342+ objectName="lastName")
343+ self.type_on_field(firstNameField, "Sherlock")
344+ self.type_on_field(lastNameField, "Holmes")
345+
346+ # Home
347+ self.set_phone_number(0, "00 0000 0000", 0)
348+ # Work
349+ self.set_phone_number(1, "11 1111 1111", 1)
350+ # Mobile
351+ self.set_phone_number(2, "22 2222 2222", 2)
352+ # Work Mobile
353+ self.set_phone_number(3, "33 3333 3333", 3)
354+ # Other
355+ self.set_phone_number(4, "44 4444 4444", 4)
356+
357+ # Save contact
358+ acceptButton = self.main_window.wait_select_single(
359+ "Button",
360+ objectName="accept")
361+ self.pointing_device.click_object(acceptButton)
362+
363+ contacts = self.main_window.select_many("ContactDelegate")
364+ self.pointing_device.click_object(contacts[0])
365+
366+ # check if contacts was saved with the correct labels
367+ view_page = self.main_window.get_contact_view_page()
368+ self.assertThat(view_page.visible, Eventually(Equals(True)))
369+
370+ # check if we have five phones"""
371+ phone_group = view_page.select_single(
372+ "ContactDetailGroupWithTypeView",
373+ objectName="phones")
374+ self.assertThat(phone_group.detailsCount, Eventually(Equals(5)))
375+
376+ phones = {"00 0000 0000" : "Home",
377+ "11 1111 1111" : "Work",
378+ "22 2222 2222" : "Mobile",
379+ "33 3333 3333" : "Work Mobile",
380+ "44 4444 4444" : "Other"}
381+
382+ # Check if they have the correct label
383+ for idx in range(5):
384+ phone_type = view_page.select_single(
385+ "Label",
386+ objectName="type_phoneNumber_" + str(idx))
387+
388+ phone_label = view_page.select_single(
389+ "Label",
390+ objectName="label_phoneNumber_" + str(idx) + ".0")
391+
392+ self.assertThat(phones[phone_label.text], Equals(phone_type.text))
393+ del phones[phone_label.text]
394+
395+ self.assertThat(len(phones), Equals(0))
396
397=== modified file 'tests/autopilot/address_book_app/tests/test_edit_contact.py'
398--- tests/autopilot/address_book_app/tests/test_edit_contact.py 2013-11-22 01:05:52 +0000
399+++ tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-01-14 20:44:40 +0000
400@@ -109,10 +109,10 @@
401 self.assertThat(email_group.detailsCount, Eventually(Equals(1)))
402
403 # check if the new value is correct
404- phone_label_1 = view_page.select_single(
405+ email_label_1 = view_page.select_single(
406 "Label",
407 objectName="label_emailAddress_0.0")
408- self.assertThat(phone_label_1.text,
409+ self.assertThat(email_label_1.text,
410 Eventually(Equals("fulano@internet.com.br")))
411
412 def test_remove_email(self):

Subscribers

People subscribed via source and target branches