[evolution-data-server] I#142 - EContact: Define defaults for attributes without TYPE
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#142 - EContact: Define defaults for attributes without TYPE
- Date: Fri, 16 Aug 2019 10:39:35 +0000 (UTC)
commit 799475ef8751e83f5b62eba1c5e83506a55789e6
Author: Milan Crha <mcrha redhat com>
Date: Fri Aug 16 12:14:43 2019 +0200
I#142 - EContact: Define defaults for attributes without TYPE
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/142
src/addressbook/libebook-contacts/e-contact.c | 327 +++++++++++--
tests/libebook-contacts/CMakeLists.txt | 1 +
tests/libebook-contacts/test-type-param.c | 655 ++++++++++++++++++++++++++
3 files changed, 948 insertions(+), 35 deletions(-)
---
diff --git a/src/addressbook/libebook-contacts/e-contact.c b/src/addressbook/libebook-contacts/e-contact.c
index fa898ecff..334882e6e 100644
--- a/src/addressbook/libebook-contacts/e-contact.c
+++ b/src/addressbook/libebook-contacts/e-contact.c
@@ -58,6 +58,27 @@ struct _EContactPrivate {
gchar *cached_strings[E_CONTACT_FIELD_LAST];
};
+typedef struct _AttrTypeValue {
+ const gchar *attr_name;
+ const gchar *type_values; /* semicolon-delimited upper-case list of used TYPE values */
+} AttrTypeValue;
+
+static AttrTypeValue glob_attr_type_values[] = {
+ { EVC_ADR, "WORK;HOME;OTHER" },
+ { EVC_KEY, "PGP;X509" },
+ { EVC_LABEL, "WORK;HOME;OTHER" },
+ { EVC_TEL, "WORK;HOME;CAR;CELL;FAX;ISDN;PAGER;PREF;VOICE;" EVC_X_ASSISTANT ";" EVC_X_CALLBACK ";"
EVC_X_COMPANY ";" EVC_X_RADIO ";" EVC_X_TELEX ";" EVC_X_TTYTDD },
+ { EVC_X_AIM, "WORK;HOME" },
+ { EVC_X_GADUGADU, "WORK;HOME" },
+ { EVC_X_GOOGLE_TALK, "WORK;HOME" },
+ { EVC_X_GROUPWISE, "WORK;HOME" },
+ { EVC_X_ICQ, "WORK;HOME" },
+ { EVC_X_JABBER, "WORK;HOME" },
+ { EVC_X_MSN, "WORK;HOME" },
+ { EVC_X_SKYPE, "WORK;HOME" },
+ { EVC_X_YAHOO, "WORK;HOME" }
+};
+
#define E_CONTACT_FIELD_TYPE_STRING 0x00000001 /* used for simple single valued attributes */
/*E_CONTACT_FIELD_TYPE_FLOAT*/
#define E_CONTACT_FIELD_TYPE_LIST 0x00000002 /* used for multivalued single attributes - the
elements are of type gchar * */
@@ -153,7 +174,7 @@ static const EContactFieldInfo field_info[] = {
/* Address Labels */
ATTR_TYPE_STR_FIELD (E_CONTACT_ADDRESS_LABEL_HOME, EVC_LABEL, "address_label_home", N_("Home
Address Label"), FALSE, "HOME", 0),
- ATTR_TYPE_STR_FIELD (E_CONTACT_ADDRESS_LABEL_WORK, EVC_LABEL, "address_label_work", N_("Work
Address Label"), FALSE, "WORK", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_ADDRESS_LABEL_WORK, EVC_LABEL, "address_label_work", N_("Work
Address Label"), FALSE, "*WORK", 0),
ATTR_TYPE_STR_FIELD (E_CONTACT_ADDRESS_LABEL_OTHER, EVC_LABEL, "address_label_other", N_("Other
Address Label"), FALSE, "OTHER", 0),
/* Phone fields */
@@ -169,7 +190,7 @@ static const EContactFieldInfo field_info[] = {
ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_HOME_FAX, EVC_TEL, "home_fax", N_("Home Fax"),
FALSE, "HOME", "FAX", 0),
ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_ISDN, EVC_TEL, "isdn_phone", N_("ISDN"),
FALSE, "ISDN", 0),
ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_MOBILE, EVC_TEL, "mobile_phone", N_("Mobile Phone"),
FALSE, "CELL", 0),
- ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_OTHER, EVC_TEL, "other_phone", N_("Other Phone"),
FALSE, "VOICE", "", 0),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_OTHER, EVC_TEL, "other_phone", N_("Other Phone"),
FALSE, "*VOICE", "", 0),
ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_OTHER_FAX, EVC_TEL, "other_fax", N_("Other Fax"),
FALSE, "FAX", "", 0),
ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_PAGER, EVC_TEL, "pager", N_("Pager"),
FALSE, "PAGER", 0),
ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_PRIMARY, EVC_TEL, "primary_phone", N_("Primary
Phone"), FALSE, "PREF", 0),
@@ -252,7 +273,7 @@ static const EContactFieldInfo field_info[] = {
/* Address fields */
MULTI_LIST_FIELD (E_CONTACT_ADDRESS, EVC_ADR, "address", N_("Address List"),
FALSE),
ATTR_TYPE_STRUCT_FIELD (E_CONTACT_ADDRESS_HOME, EVC_ADR, "address_home", N_("Home Address"),
FALSE, "HOME", adr_getter, adr_setter, e_contact_address_get_type),
- ATTR_TYPE_STRUCT_FIELD (E_CONTACT_ADDRESS_WORK, EVC_ADR, "address_work", N_("Work Address"),
FALSE, "WORK", adr_getter, adr_setter, e_contact_address_get_type),
+ ATTR_TYPE_STRUCT_FIELD (E_CONTACT_ADDRESS_WORK, EVC_ADR, "address_work", N_("Work Address"),
FALSE, "*WORK", adr_getter, adr_setter, e_contact_address_get_type),
ATTR_TYPE_STRUCT_FIELD (E_CONTACT_ADDRESS_OTHER, EVC_ADR, "address_other", N_("Other Address"),
FALSE, "OTHER", adr_getter, adr_setter, e_contact_address_get_type),
/* Contact categories */
@@ -334,6 +355,135 @@ static const EContactFieldInfo field_info[] = {
#undef LIST_FIELD
#undef GETSET_FIELD
+static const AttrTypeValue *
+e_contact_find_attr_type_values (const gchar *attr_name)
+{
+ gint ii;
+
+ g_return_val_if_fail (attr_name != NULL, NULL);
+
+ for (ii = 0; ii < G_N_ELEMENTS (glob_attr_type_values); ii++) {
+ if (g_ascii_strcasecmp (glob_attr_type_values[ii].attr_name, attr_name) == 0) {
+ return &(glob_attr_type_values[ii]);
+ }
+ }
+
+ g_warn_if_reached ();
+
+ return NULL;
+}
+
+static gboolean
+e_contact_check_attr_type_value_used (const AttrTypeValue *attr_type_values,
+ const gchar *type_value)
+{
+ gint ii, pos;
+
+ if (!attr_type_values)
+ return TRUE;
+
+ if (!type_value || !*type_value)
+ return FALSE;
+
+ pos = 0;
+
+ for (ii = 0; attr_type_values->type_values[ii]; ii++) {
+ gboolean skip = FALSE;
+
+ if (attr_type_values->type_values[ii] == g_ascii_toupper (type_value[pos])) {
+ pos++;
+
+ if (!type_value[pos]) {
+ if (attr_type_values->type_values[ii + 1] == 0 ||
attr_type_values->type_values[ii + 1] == ';')
+ return TRUE;
+
+ skip = TRUE;
+ }
+ } else {
+ skip = TRUE;
+ }
+
+ if (skip) {
+ pos = 0;
+
+ while (attr_type_values->type_values[ii] && attr_type_values->type_values[ii] != ';')
+ ii++;
+ }
+ }
+
+ return FALSE;
+}
+
+#ifdef ENABLE_MAINTAINER_MODE
+
+static void
+e_contact_maybe_insert_attr_type (GHashTable *used_attr_types,
+ const gchar *vcard_field_name,
+ const gchar *type_value)
+{
+ g_return_if_fail (used_attr_types != NULL);
+ g_return_if_fail (vcard_field_name != NULL);
+
+ /* Skip leading '*', it denotes default value */
+ if (type_value && *type_value == '*')
+ type_value++;
+
+ if (type_value && *type_value) {
+ GHashTable *types_hash;
+
+ types_hash = g_hash_table_lookup (used_attr_types, vcard_field_name);
+
+ if (!types_hash) {
+ types_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ g_hash_table_insert (used_attr_types, (gpointer) vcard_field_name, types_hash);
+ }
+
+ g_hash_table_insert (types_hash, (gpointer) type_value, NULL);
+ }
+}
+
+static gint
+e_contact_cmp_type_values (gconstpointer v1,
+ gconstpointer v2)
+{
+ const gchar *type1 = v1, *type2 = v2;
+ gint who1, who2;
+
+ /* Work/Home/Other has precedence over others, in this order */
+ if (g_str_equal (type1, "WORK"))
+ who1 = 3;
+ else if (g_str_equal (type1, "HOME"))
+ who1 = 2;
+ else if (g_str_equal (type1, "OTHER"))
+ who1 = 1;
+ else
+ who1 = -1;
+
+ if (g_str_equal (type2, "WORK"))
+ who2 = 3;
+ else if (g_str_equal (type2, "HOME"))
+ who2 = 2;
+ else if (g_str_equal (type2, "OTHER"))
+ who2 = 1;
+ else
+ who2 = -1;
+
+ if (who1 == -1) {
+ if (who2 == -1)
+ return g_strcmp0 (type1, type2);
+
+ return 1;
+ }
+
+ if (who2 == -1)
+ return -1;
+
+ return who2 - who1;
+}
+
+#endif /* ENABLE_MAINTAINER_MODE */
+
static void e_contact_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void e_contact_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
@@ -356,6 +506,11 @@ static void
e_contact_class_init (EContactClass *class)
{
GObjectClass *object_class;
+ #ifdef ENABLE_MAINTAINER_MODE
+ GHashTable *used_attr_types; /* gchar *attr_name ~> GHashTable { gchar *type_value ~> NULL } */
+ GHashTableIter iter;
+ gpointer key, value;
+ #endif
gint ii;
g_type_class_add_private (class, sizeof (EContactPrivate));
@@ -365,6 +520,10 @@ e_contact_class_init (EContactClass *class)
object_class->get_property = e_contact_get_property;
object_class->finalize = e_contact_finalize;
+ #ifdef ENABLE_MAINTAINER_MODE
+ used_attr_types = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)
g_hash_table_destroy);
+ #endif
+
for (ii = E_CONTACT_FIELD_FIRST; ii < E_CONTACT_FIELD_LAST; ii++) {
GParamSpec *pspec = NULL;
GParamFlags flags;
@@ -416,7 +575,63 @@ e_contact_class_init (EContactClass *class)
g_object_class_install_property (
object_class, field_info[ii].field_id, pspec);
+
+ #ifdef ENABLE_MAINTAINER_MODE
+ if (field_info[ii].t & E_CONTACT_FIELD_TYPE_ATTR_TYPE) {
+ e_contact_maybe_insert_attr_type (used_attr_types, field_info[ii].vcard_field_name,
field_info[ii].attr_type1);
+ e_contact_maybe_insert_attr_type (used_attr_types, field_info[ii].vcard_field_name,
field_info[ii].attr_type2);
+ }
+ #endif
+ }
+
+ /* To verify whether the static glob_attr_type_values array is filled properly */
+ #ifdef ENABLE_MAINTAINER_MODE
+
+ g_assert_cmpint (g_hash_table_size (used_attr_types), ==, G_N_ELEMENTS (glob_attr_type_values));
+
+ g_hash_table_iter_init (&iter, used_attr_types);
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GHashTableIter iter2;
+ gpointer key2;
+ GSList *values = NULL, *link;
+ GString *expected;
+ const AttrTypeValue *attr_data;
+
+ g_hash_table_iter_init (&iter2, value);
+ while (g_hash_table_iter_next (&iter2, &key2, NULL)) {
+ const gchar *type_value = key2;
+
+ for (ii = 0; type_value && type_value[ii]; ii++) {
+ /* Verify strings are in upper-case */
+ g_assert_cmpint (g_ascii_toupper (type_value[ii]), ==, type_value[ii]);
+ }
+
+ values = g_slist_prepend (values, (gpointer) type_value);
+ }
+
+ values = g_slist_sort (values, e_contact_cmp_type_values);
+
+ expected = g_string_new ("");
+
+ for (link = values; link; link = g_slist_next (link)) {
+ g_string_append (expected, link->data);
+
+ if (link->next)
+ g_string_append_c (expected, ';');
+ }
+
+ attr_data = e_contact_find_attr_type_values (key);
+ g_assert_nonnull (attr_data);
+ g_assert_cmpstr (attr_data->type_values, ==, expected->str);
+
+ g_slist_free (values);
+ g_string_free (expected, TRUE);
}
+
+ g_hash_table_destroy (used_attr_types);
+
+ #endif /* ENABLE_MAINTAINER_MODE */
}
static void
@@ -859,12 +1074,28 @@ e_contact_find_attribute_with_types (EContact *contact,
gint nth)
{
GList *l, *attrs;
+ const AttrTypeValue *attr_type_values;
gboolean found_needed1, found_needed2;
gboolean can_empty_needed2;
+ gboolean use_for_no_type;
can_empty_needed2 = g_ascii_strcasecmp (attr_name, "TEL") == 0 && type_needed2 &&
g_ascii_strcasecmp (type_needed2, "VOICE") == 0;
+ attr_type_values = e_contact_find_attr_type_values (attr_name);
+
+ /* The first type can start with a '*', which means that the found attribute
+ can be also the one with no type specified. It's used for default types
+ per RFC2426.*/
+ use_for_no_type = type_needed1 && (*type_needed1) == '*';
+
+ if (use_for_no_type) {
+ type_needed1++;
+
+ if (!*type_needed1)
+ type_needed1 = NULL;
+ }
+
attrs = e_vcard_get_attributes (E_VCARD (contact));
for (l = attrs; l; l = l->next) {
@@ -877,56 +1108,82 @@ e_contact_find_attribute_with_types (EContact *contact,
name = e_vcard_attribute_get_name (attr);
if (!g_ascii_strcasecmp (name, attr_name)) {
+ GSList *found_types = NULL;
GList *params;
+ guint n_types = 0, n_found_types = 0;
for (params = e_vcard_attribute_get_params (attr); params; params = params->next) {
EVCardAttributeParam *param = params->data;
const gchar *param_name = e_vcard_attribute_param_get_name (param);
- gint n_types = 0;
if (!g_ascii_strcasecmp (param_name, EVC_TYPE)) {
- gboolean matches = FALSE;
- GList *values = e_vcard_attribute_param_get_values (param);
+ GList *value;
- /* empty string on type_needed2 is to get only those attributes,
- * which has exactly one TYPE, to not rewrite those with multiple */
- if (type_needed2 && !*type_needed2)
- found_needed2 = values && !values->next;
+ for (value = e_vcard_attribute_param_get_values (param);
+ value;
+ value = g_list_next (value)) {
+ const gchar *type_value = value->data;
- while (values && values->data) {
n_types++;
- if (!found_needed1 && !g_ascii_strcasecmp ((gchar *)
values->data, type_needed1)) {
- found_needed1 = TRUE;
- matches = TRUE;
- } else if (!found_needed2 && !g_ascii_strcasecmp ((gchar *)
values->data, type_needed2)) {
- found_needed2 = TRUE;
- matches = TRUE;
- } else if (found_needed1) {
- if (!matches || !found_needed2)
- matches = FALSE;
- break;
+ /* Skip any type values which are not used, thus they do not
confuse the search */
+ if (type_value && *type_value &&
+ e_contact_check_attr_type_value_used (attr_type_values,
type_value)) {
+ found_types = g_slist_prepend (found_types,
(gpointer) type_value);
+ n_found_types++;
}
- values = values->next;
}
+ }
+ }
- if (!matches && (!can_empty_needed2 || n_types != 1)) {
- /* this is to enforce that we find an attribute
- * with *only* the TYPE='s we need. This may seem like
- * an odd restriction but it's the only way at present to
- * implement the Other Fax and Other Phone attributes. */
- found_needed1 = FALSE;
+ if (!n_types) {
+ if (use_for_no_type && (nth-- == 0))
+ return attr;
+ } else {
+ GSList *link;
+ gboolean matches = FALSE;
+
+ /* empty string on type_needed2 is to get only those attributes,
+ * which has exactly one TYPE, to not rewrite those with multiple */
+ if (type_needed2 && !*type_needed2)
+ found_needed2 = n_found_types == 1;
+
+ for (link = found_types; link; link = g_slist_next (link)) {
+ const gchar *type_value = link->data;
+
+ if (!type_value)
+ continue;
+
+ if (!found_needed1 && !g_ascii_strcasecmp (type_value, type_needed1))
{
+ found_needed1 = TRUE;
+ matches = TRUE;
+ } else if (!found_needed2 && !g_ascii_strcasecmp (type_value,
type_needed2)) {
+ found_needed2 = TRUE;
+ matches = TRUE;
+ } else if (found_needed1) {
+ if (!found_needed2)
+ matches = FALSE;
break;
}
}
- if (found_needed1 && (found_needed2 || (n_types == 1 && can_empty_needed2))) {
- if (nth-- == 0)
+ if (!matches && (!can_empty_needed2 || n_found_types != 1)) {
+ /* this is to enforce that we find an attribute
+ * with *only* the TYPE='s we need. This may seem like
+ * an odd restriction but it's the only way at present to
+ * implement the Other Fax and Other Phone attributes. */
+ found_needed1 = FALSE;
+ }
+
+ if (found_needed1 && (found_needed2 || (n_found_types == 1 &&
can_empty_needed2))) {
+ if (nth-- == 0) {
+ g_slist_free (found_types);
return attr;
- else
- break;
+ }
}
}
+
+ g_slist_free (found_types);
}
}
@@ -1004,7 +1261,7 @@ e_contact_set_property (GObject *object,
/* we didn't find it - add a new attribute */
attr = e_vcard_attribute_new (NULL, info->vcard_field_name);
if (!g_ascii_strcasecmp (info->vcard_field_name, "EMAIL") &&
- !info->attr_type1 &&
+ (!info->attr_type1 || (info->attr_type1[0] == '*' &&
!info->attr_type1[1])) &&
(!info->attr_type2 || !*info->attr_type2)) {
/* Add default type */
e_vcard_attribute_add_param_with_value (
@@ -1039,10 +1296,10 @@ e_contact_set_property (GObject *object,
/* we didn't find it - add a new attribute */
attr = e_vcard_attribute_new (NULL, info->vcard_field_name);
e_vcard_append_attribute (E_VCARD (contact), attr);
- if (info->attr_type1)
+ if (info->attr_type1 && (info->attr_type1[0] != '*' || info->attr_type1[1]))
e_vcard_attribute_add_param_with_value (
attr, e_vcard_attribute_param_new (EVC_TYPE),
- info->attr_type1);
+ info->attr_type1[0] == '*' ? info->attr_type1 + 1 :
info->attr_type1);
if (info->attr_type2 && *info->attr_type2)
e_vcard_attribute_add_param_with_value (
attr, e_vcard_attribute_param_new (EVC_TYPE),
diff --git a/tests/libebook-contacts/CMakeLists.txt b/tests/libebook-contacts/CMakeLists.txt
index bd68cdacb..7649a3892 100644
--- a/tests/libebook-contacts/CMakeLists.txt
+++ b/tests/libebook-contacts/CMakeLists.txt
@@ -21,6 +21,7 @@ set(TESTS
test-contact-types
test-vcard-parsing
test-untyped-phones
+ test-type-param
test-query
test-phone-number
)
diff --git a/tests/libebook-contacts/test-type-param.c b/tests/libebook-contacts/test-type-param.c
new file mode 100644
index 000000000..3e654a5d3
--- /dev/null
+++ b/tests/libebook-contacts/test-type-param.c
@@ -0,0 +1,655 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License 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 warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <libebook-contacts/libebook-contacts.h>
+
+typedef struct _TestData {
+ const gchar *vcard_str;
+ EContactField field_id;
+ const gchar *expected;
+} TestData;
+
+static void
+test_type_param (const TestData datas[],
+ guint n_datas,
+ void (* check_value_func) (gconstpointer value,
+ const gchar *expected),
+ GDestroyNotify free_value_func)
+{
+ const gchar *vcard_str = NULL;
+ guint ii;
+
+ for (ii = 0; ii < n_datas; ii++) {
+ EContact *contact;
+ gpointer value;
+
+ /* Items can inherit the vCard definition */
+ if (datas[ii].vcard_str)
+ vcard_str = datas[ii].vcard_str;
+
+ g_assert_nonnull (vcard_str);
+
+ contact = e_contact_new_from_vcard (vcard_str);
+ g_assert_nonnull (contact);
+
+ value = e_contact_get (contact, datas[ii].field_id);
+
+ if (datas[ii].expected) {
+ g_assert_nonnull (value);
+
+ if (check_value_func)
+ check_value_func (value, datas[ii].expected);
+ else
+ g_assert_cmpstr (value, ==, datas[ii].expected);
+ } else {
+ g_assert_null (value);
+ }
+
+ if (free_value_func)
+ free_value_func (value);
+ else
+ g_free (value);
+
+ g_object_unref (contact);
+ }
+}
+
+static void
+test_type_param_email (void)
+{
+ TestData datas[] = {
+ { "BEGIN:VCARD\r\n"
+ "EMAIL;TYPE=home:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_EMAIL_1, "V1" },
+ { NULL, E_CONTACT_EMAIL_2, NULL },
+ { NULL, E_CONTACT_EMAIL_3, NULL },
+ { NULL, E_CONTACT_EMAIL_4, NULL },
+ { "BEGIN:VCARD\r\n"
+ "EMAIL;TYPE=home:V1\r\n"
+ "EMAIL;TYPE=home:V2\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_EMAIL_1, "V1" },
+ { NULL, E_CONTACT_EMAIL_2, "V2" },
+ { NULL, E_CONTACT_EMAIL_3, NULL },
+ { NULL, E_CONTACT_EMAIL_4, NULL },
+ { "BEGIN:VCARD\r\n"
+ "EMAIL;TYPE=home:V1\r\n"
+ "EMAIL;TYPE=home:V2\r\n"
+ "EMAIL;TYPE=home:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_EMAIL_1, "V1" },
+ { NULL, E_CONTACT_EMAIL_2, "V2" },
+ { NULL, E_CONTACT_EMAIL_3, "V3" },
+ { NULL, E_CONTACT_EMAIL_4, NULL },
+ { "BEGIN:VCARD\r\n"
+ "EMAIL;TYPE=home:V1\r\n"
+ "EMAIL;TYPE=home:V2\r\n"
+ "EMAIL;TYPE=home:V3\r\n"
+ "EMAIL;TYPE=home:V4\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_EMAIL_1, "V1" },
+ { NULL, E_CONTACT_EMAIL_2, "V2" },
+ { NULL, E_CONTACT_EMAIL_3, "V3" },
+ { NULL, E_CONTACT_EMAIL_4, "V4" },
+ { "BEGIN:VCARD\r\n"
+ "EMAIL;TYPE=home:V1\r\n"
+ "EMAIL;TYPE=home:V2\r\n"
+ "EMAIL;TYPE=home:V3\r\n"
+ "EMAIL;TYPE=home:V4\r\n"
+ "EMAIL;TYPE=home:V5\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_EMAIL_1, "V1" },
+ { NULL, E_CONTACT_EMAIL_2, "V2" },
+ { NULL, E_CONTACT_EMAIL_3, "V3" },
+ { NULL, E_CONTACT_EMAIL_4, "V4" }
+ };
+
+ test_type_param (datas, G_N_ELEMENTS (datas), NULL, NULL);
+}
+
+static void
+check_value_adr (gconstpointer value,
+ const gchar *expected)
+{
+ const EContactAddress *addr = value;
+
+ g_assert_nonnull (addr);
+ g_assert_nonnull (expected);
+
+ g_assert_cmpstr (addr->street, ==, expected);
+}
+
+static void
+test_type_param_adr (void)
+{
+ TestData datas[] = {
+ { "BEGIN:VCARD\r\n"
+ "ADR;TYPE=home:;;V1;;;;\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_HOME, "V1" },
+ { NULL, E_CONTACT_ADDRESS_WORK, NULL },
+ { NULL, E_CONTACT_ADDRESS_OTHER, NULL },
+ { "BEGIN:VCARD\r\n"
+ "ADR:;;V1;;;;\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_WORK, "V1" },
+ { NULL, E_CONTACT_ADDRESS_OTHER, NULL },
+ { "BEGIN:VCARD\r\n"
+ "ADR;TYPE=work:;;V1;;;;\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_WORK, "V1" },
+ { NULL, E_CONTACT_ADDRESS_OTHER, NULL },
+ { "BEGIN:VCARD\r\n"
+ "ADR;TYPE=other:;;V1;;;;\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_WORK, NULL },
+ { NULL, E_CONTACT_ADDRESS_OTHER, "V1" },
+ { "BEGIN:VCARD\r\n"
+ "ADR;TYPE=dom;TYPE=home:;;V1;;;;\r\n"
+ "ADR;TYPE=postal,work:;;V2;;;;\r\n"
+ "ADR;TYPE=postal,intl;TYPE=parcel,other:;;V3;;;;\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_HOME, "V1" },
+ { NULL, E_CONTACT_ADDRESS_WORK, "V2" },
+ { NULL, E_CONTACT_ADDRESS_OTHER, "V3" },
+ { "BEGIN:VCARD\r\n"
+ "ADR:;;V1;;;;\r\n"
+ "ADR;TYPE=dom;TYPE=home:;;V2;;;;\r\n"
+ "ADR;TYPE=postal,intl;TYPE=parcel,other:;;V3;;;;\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_HOME, "V2" },
+ { NULL, E_CONTACT_ADDRESS_WORK, "V1" },
+ { NULL, E_CONTACT_ADDRESS_OTHER, "V3" },
+ { "BEGIN:VCARD\r\n"
+ "ADR;TYPE=dom:;;V1;;;;\r\n"
+ "ADR:;;V2;;;;\r\n"
+ "ADR;TYPE=postal,intl;TYPE=parcel,other:;;V3;;;;\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_WORK, "V2" },
+ { NULL, E_CONTACT_ADDRESS_OTHER, "V3" }
+ };
+
+ test_type_param (datas, G_N_ELEMENTS (datas), check_value_adr, (GDestroyNotify)
e_contact_address_free);
+}
+
+static void
+test_type_param_label (void)
+{
+ TestData datas[] = {
+ { "BEGIN:VCARD\r\n"
+ "LABEL;TYPE=home:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_LABEL_HOME, "V1" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_WORK, NULL },
+ { NULL, E_CONTACT_ADDRESS_LABEL_OTHER, NULL },
+ { "BEGIN:VCARD\r\n"
+ "LABEL:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_LABEL_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_LABEL_WORK, "V1" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_OTHER, NULL },
+ { "BEGIN:VCARD\r\n"
+ "LABEL;TYPE=work:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_LABEL_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_LABEL_WORK, "V1" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_OTHER, NULL },
+ { "BEGIN:VCARD\r\n"
+ "LABEL;TYPE=other:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_LABEL_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_LABEL_WORK, NULL },
+ { NULL, E_CONTACT_ADDRESS_LABEL_OTHER, "V1" },
+ { "BEGIN:VCARD\r\n"
+ "LABEL;TYPE=dom;TYPE=home:V1\r\n"
+ "LABEL;TYPE=postal,work:V2\r\n"
+ "LABEL;TYPE=postal,intl;TYPE=parcel,other:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_LABEL_HOME, "V1" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_WORK, "V2" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_OTHER, "V3" },
+ { "BEGIN:VCARD\r\n"
+ "LABEL:V1\r\n"
+ "LABEL;TYPE=dom;TYPE=home:V2\r\n"
+ "LABEL;TYPE=postal,intl;TYPE=parcel,other:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_LABEL_HOME, "V2" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_WORK, "V1" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_OTHER, "V3" },
+ { "BEGIN:VCARD\r\n"
+ "LABEL;TYPE=dom:V1\r\n"
+ "LABEL:V2\r\n"
+ "LABEL;TYPE=postal,intl;TYPE=parcel,other:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_ADDRESS_LABEL_HOME, NULL },
+ { NULL, E_CONTACT_ADDRESS_LABEL_WORK, "V2" },
+ { NULL, E_CONTACT_ADDRESS_LABEL_OTHER, "V3" }
+ };
+
+ test_type_param (datas, G_N_ELEMENTS (datas), NULL, NULL);
+}
+
+static void
+check_value_key (gconstpointer value,
+ const gchar *expected)
+{
+ const EContactCert *cert = value;
+ gchar *str_cert;
+
+ g_assert_nonnull (cert);
+ g_assert_nonnull (expected);
+
+ str_cert = g_strndup (cert->data, cert->length);
+
+ g_assert_cmpstr (str_cert, ==, expected);
+
+ g_free (str_cert);
+}
+
+static void
+test_type_param_key (void)
+{
+ TestData datas[] = {
+ { "BEGIN:VCARD\r\n"
+ "KEY;TYPE=x509:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_X509_CERT, "V1" },
+ { NULL, E_CONTACT_PGP_CERT, NULL },
+ { "BEGIN:VCARD\r\n"
+ "KEY;TYPE=pgp:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_X509_CERT, NULL },
+ { NULL, E_CONTACT_PGP_CERT, "V1" },
+ { "BEGIN:VCARD\r\n"
+ "KEY;TYPE=X509;TYPE=x-test:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_X509_CERT, "V1" },
+ { NULL, E_CONTACT_PGP_CERT, NULL },
+ { "BEGIN:VCARD\r\n"
+ "KEY;TYPE=PGP;TYPE=x-test:V1\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_X509_CERT, NULL },
+ { NULL, E_CONTACT_PGP_CERT, "V1" },
+ { "BEGIN:VCARD\r\n"
+ "KEY;TYPE=x-test,x509:V1\r\n"
+ "KEY;TYPE=x-test,pgp:V2\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_X509_CERT, "V1" },
+ { NULL, E_CONTACT_PGP_CERT, "V2" },
+ { "BEGIN:VCARD\r\n"
+ "KEY:V1\r\n"
+ "KEY;TYPE=x-test:V2\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_X509_CERT, NULL },
+ { NULL, E_CONTACT_PGP_CERT, NULL }
+ };
+
+ test_type_param (datas, G_N_ELEMENTS (datas), check_value_key, (GDestroyNotify) e_contact_cert_free);
+}
+
+static void
+test_type_param_tel (void)
+{
+ TestData datas[] = {
+ { "BEGIN:VCARD\r\n"
+ "TEL;TYPE=" EVC_X_ASSISTANT ":V1\r\n"
+ "TEL;TYPE=work:V2\r\n"
+ "TEL;TYPE=work,voice:V3\r\n"
+ "TEL;TYPE=work;TYPE=fax:V4\r\n"
+ "TEL;TYPE=" EVC_X_CALLBACK ":V5\r\n"
+ "TEL;TYPE=car:V6\r\n"
+ "TEL;TYPE=" EVC_X_COMPANY ":V7\r\n"
+ "TEL;TYPE=voice,home:V8\r\n"
+ "TEL;TYPE=home:V9\r\n"
+ "TEL;TYPE=fax;Type=home:V10\r\n"
+ "TEL;TYPE=ISDN:V11\r\n"
+ "TEL;TYPE=cell:V12\r\n"
+ "TEL;TYPE=voice:V13\r\n"
+ "TEL;TYPE=fax:V14\r\n"
+ "TEL;TYPE=pager:V15\r\n"
+ "TEL;TYPE=pref:V16\r\n"
+ "TEL;TYPE=" EVC_X_RADIO ":V17\r\n"
+ "TEL;TYPE=" EVC_X_TELEX ":V18\r\n"
+ "TEL;TYPE=" EVC_X_TTYTDD ":V19\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_PHONE_ASSISTANT, "V1" },
+ { NULL, E_CONTACT_PHONE_BUSINESS, "V2" },
+ { NULL, E_CONTACT_PHONE_BUSINESS_2, "V3" },
+ { NULL, E_CONTACT_PHONE_BUSINESS_FAX, "V4" },
+ { NULL, E_CONTACT_PHONE_CALLBACK, "V5" },
+ { NULL, E_CONTACT_PHONE_CAR, "V6" },
+ { NULL, E_CONTACT_PHONE_COMPANY, "V7" },
+ { NULL, E_CONTACT_PHONE_HOME, "V8" },
+ { NULL, E_CONTACT_PHONE_HOME_2, "V9" },
+ { NULL, E_CONTACT_PHONE_HOME_FAX, "V10" },
+ { NULL, E_CONTACT_PHONE_ISDN, "V11" },
+ { NULL, E_CONTACT_PHONE_MOBILE, "V12" },
+ { NULL, E_CONTACT_PHONE_OTHER, "V13" },
+ { NULL, E_CONTACT_PHONE_OTHER_FAX, "V14" },
+ { NULL, E_CONTACT_PHONE_PAGER, "V15" },
+ { NULL, E_CONTACT_PHONE_PRIMARY, "V16" },
+ { NULL, E_CONTACT_PHONE_RADIO, "V17" },
+ { NULL, E_CONTACT_PHONE_TELEX, "V18" },
+ { NULL, E_CONTACT_PHONE_TTYTDD, "V19" },
+ { "BEGIN:VCARD\r\n"
+ "TEL;TYPE=" EVC_X_ASSISTANT ";Type=msg:V1\r\n"
+ "TEL;Type=msg;TYPE=work:V2\r\n"
+ "TEL;TYPE=work,msg;type=Voice:V3\r\n"
+ "TEL;TYPE=work;Type=msg;TYPE=fax:V4\r\n"
+ "TEL;TYPE=msg," EVC_X_CALLBACK ":V5\r\n"
+ "TEL;TYPE=msg,car:V6\r\n"
+ "TEL;TYPE=" EVC_X_COMPANY ",msg:V7\r\n"
+ "TEL;TYPE=voice,msg,home:V8\r\n"
+ "TEL;TYPE=home,msg:V9\r\n"
+ "TEL;TYPE=fax,msg;Type=home:V10\r\n"
+ "TEL;TYPE=msg,Isdn:V11\r\n"
+ "TEL;TYPE=cELL,msg:V12\r\n"
+ "TEL:V13\r\n"
+ "TEL;TYPE=fax,msg:V14\r\n"
+ "TEL;TYPE=pager,msg:V15\r\n"
+ "TEL;TYPE=pref,msg:V16\r\n"
+ "TEL;TYPE=msg," EVC_X_RADIO ":V17\r\n"
+ "TEL;Type=msg;TYPE=" EVC_X_TELEX ":V18\r\n"
+ "TEL;TYPE=" EVC_X_TTYTDD ";Type=msg:V19\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_PHONE_ASSISTANT, "V1" },
+ { NULL, E_CONTACT_PHONE_BUSINESS, "V2" },
+ { NULL, E_CONTACT_PHONE_BUSINESS_2, "V3" },
+ { NULL, E_CONTACT_PHONE_BUSINESS_FAX, "V4" },
+ { NULL, E_CONTACT_PHONE_CALLBACK, "V5" },
+ { NULL, E_CONTACT_PHONE_CAR, "V6" },
+ { NULL, E_CONTACT_PHONE_COMPANY, "V7" },
+ { NULL, E_CONTACT_PHONE_HOME, "V8" },
+ { NULL, E_CONTACT_PHONE_HOME_2, "V9" },
+ { NULL, E_CONTACT_PHONE_HOME_FAX, "V10" },
+ { NULL, E_CONTACT_PHONE_ISDN, "V11" },
+ { NULL, E_CONTACT_PHONE_MOBILE, "V12" },
+ { NULL, E_CONTACT_PHONE_OTHER, "V13" },
+ { NULL, E_CONTACT_PHONE_OTHER_FAX, "V14" },
+ { NULL, E_CONTACT_PHONE_PAGER, "V15" },
+ { NULL, E_CONTACT_PHONE_PRIMARY, "V16" },
+ { NULL, E_CONTACT_PHONE_RADIO, "V17" },
+ { NULL, E_CONTACT_PHONE_TELEX, "V18" },
+ { NULL, E_CONTACT_PHONE_TTYTDD, "V19" },
+ { "BEGIN:VCARD\r\n"
+ "TEL;Type=msg:V1\r\n"
+ "TEL;TYPE=msg;type=Voice:V2\r\n"
+ "TEL:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_PHONE_ASSISTANT, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_2, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_CALLBACK, NULL },
+ { NULL, E_CONTACT_PHONE_CAR, NULL },
+ { NULL, E_CONTACT_PHONE_COMPANY, NULL },
+ { NULL, E_CONTACT_PHONE_HOME, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_2, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_ISDN, NULL },
+ { NULL, E_CONTACT_PHONE_MOBILE, NULL },
+ { NULL, E_CONTACT_PHONE_OTHER, "V2" },
+ { NULL, E_CONTACT_PHONE_OTHER_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_PAGER, NULL },
+ { NULL, E_CONTACT_PHONE_PRIMARY, NULL },
+ { NULL, E_CONTACT_PHONE_RADIO, NULL },
+ { NULL, E_CONTACT_PHONE_TELEX, NULL },
+ { NULL, E_CONTACT_PHONE_TTYTDD, NULL },
+ { "BEGIN:VCARD\r\n"
+ "TEL;Type=msg:V1\r\n"
+ "TEL:V2\r\n"
+ "TEL;TYPE=msg;type=Voice:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_PHONE_ASSISTANT, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_2, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_CALLBACK, NULL },
+ { NULL, E_CONTACT_PHONE_CAR, NULL },
+ { NULL, E_CONTACT_PHONE_COMPANY, NULL },
+ { NULL, E_CONTACT_PHONE_HOME, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_2, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_ISDN, NULL },
+ { NULL, E_CONTACT_PHONE_MOBILE, NULL },
+ { NULL, E_CONTACT_PHONE_OTHER, "V2" },
+ { NULL, E_CONTACT_PHONE_OTHER_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_PAGER, NULL },
+ { NULL, E_CONTACT_PHONE_PRIMARY, NULL },
+ { NULL, E_CONTACT_PHONE_RADIO, NULL },
+ { NULL, E_CONTACT_PHONE_TELEX, NULL },
+ { NULL, E_CONTACT_PHONE_TTYTDD, NULL },
+ { "BEGIN:VCARD\r\n"
+ "TEL;Type=msg:V1\r\n"
+ "TEL;TYPE=msg;type=Fax:V2\r\n"
+ "TEL:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_PHONE_ASSISTANT, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_2, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_CALLBACK, NULL },
+ { NULL, E_CONTACT_PHONE_CAR, NULL },
+ { NULL, E_CONTACT_PHONE_COMPANY, NULL },
+ { NULL, E_CONTACT_PHONE_HOME, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_2, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_ISDN, NULL },
+ { NULL, E_CONTACT_PHONE_MOBILE, NULL },
+ { NULL, E_CONTACT_PHONE_OTHER, "V3" },
+ { NULL, E_CONTACT_PHONE_OTHER_FAX, "V2" },
+ { NULL, E_CONTACT_PHONE_PAGER, NULL },
+ { NULL, E_CONTACT_PHONE_PRIMARY, NULL },
+ { NULL, E_CONTACT_PHONE_RADIO, NULL },
+ { NULL, E_CONTACT_PHONE_TELEX, NULL },
+ { NULL, E_CONTACT_PHONE_TTYTDD, NULL },
+ { "BEGIN:VCARD\r\n"
+ "TEL;Type=msg:V1\r\n"
+ "TEL:V2\r\n"
+ "TEL;TYPE=msg;type=Fax:V3\r\n"
+ "END:VCARD\r\n",
+ E_CONTACT_PHONE_ASSISTANT, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_2, NULL },
+ { NULL, E_CONTACT_PHONE_BUSINESS_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_CALLBACK, NULL },
+ { NULL, E_CONTACT_PHONE_CAR, NULL },
+ { NULL, E_CONTACT_PHONE_COMPANY, NULL },
+ { NULL, E_CONTACT_PHONE_HOME, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_2, NULL },
+ { NULL, E_CONTACT_PHONE_HOME_FAX, NULL },
+ { NULL, E_CONTACT_PHONE_ISDN, NULL },
+ { NULL, E_CONTACT_PHONE_MOBILE, NULL },
+ { NULL, E_CONTACT_PHONE_OTHER, "V2" },
+ { NULL, E_CONTACT_PHONE_OTHER_FAX, "V3" },
+ { NULL, E_CONTACT_PHONE_PAGER, NULL },
+ { NULL, E_CONTACT_PHONE_PRIMARY, NULL },
+ { NULL, E_CONTACT_PHONE_RADIO, NULL },
+ { NULL, E_CONTACT_PHONE_TELEX, NULL },
+ { NULL, E_CONTACT_PHONE_TTYTDD, NULL }
+ };
+
+ test_type_param (datas, G_N_ELEMENTS (datas), NULL, NULL);
+}
+
+static void
+test_type_param_im (const gchar *im_attr,
+ gint first_im_field_id)
+{
+ TestData datas[] = {
+ { NULL, -1, "V1" }, /* vcard[0] */
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, NULL }, /* vcard[1] */
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, "V1" },
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, "V2" }, /* vcard[2] */
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, "V1" },
+ { NULL, -1, NULL },
+ { NULL, -1, NULL },
+ { NULL, -1, "V6" }, /* vcard[3] */
+ { NULL, -1, "V7" },
+ { NULL, -1, "V8" },
+ { NULL, -1, "V1" },
+ { NULL, -1, "V2" },
+ { NULL, -1, "V4" }
+ };
+ gchar *vcards[4];
+ gint ii;
+
+ vcards[0] = g_strdup_printf (
+ "BEGIN:VCARD\r\n"
+ "%s;Type=home:V1\r\n"
+ "END:VCARD\r\n",
+ im_attr);
+
+ vcards[1] = g_strdup_printf (
+ "BEGIN:VCARD\r\n"
+ "%s;TYPE=WORK:V1\r\n"
+ "END:VCARD\r\n",
+ im_attr);
+
+ vcards[2] = g_strdup_printf (
+ "BEGIN:VCARD\r\n"
+ "%s;TYPE=x-test,WORK:V1\r\n"
+ "%s;type=X-Test;tYPE=Home:V2\r\n"
+ "END:VCARD\r\n",
+ im_attr, im_attr);
+
+ vcards[3] = g_strdup_printf (
+ "BEGIN:VCARD\r\n"
+ "%s;type=WORK:V1\r\n"
+ "%s;TYPE=x-test,work:V2\r\n"
+ "%s:V3\r\n"
+ "%s;TYPE=WORK,x-test:V4\r\n"
+ "%s:V5\r\n"
+ "%s;type=X-Test;tYPE=Home:V6\r\n"
+ "%s;tYPE=Home;type=X-Test:V7\r\n"
+ "%s;type=Home:V8\r\n"
+ "END:VCARD\r\n",
+ im_attr, im_attr, im_attr, im_attr, im_attr, im_attr, im_attr, im_attr);
+
+ for (ii = 0; ii < G_N_ELEMENTS (datas); ii++) {
+ if (!(ii % 6)) {
+ g_assert_cmpint (ii / 6, <, G_N_ELEMENTS (vcards));
+
+ datas[ii].vcard_str = vcards[ii / 6];
+ }
+
+ datas[ii].field_id = first_im_field_id + (ii % 6);
+ }
+
+ test_type_param (datas, G_N_ELEMENTS (datas), NULL, NULL);
+
+ for (ii = 0; ii < G_N_ELEMENTS (vcards); ii++) {
+ g_free (vcards[ii]);
+ }
+}
+
+static void
+test_type_param_xaim (void)
+{
+ test_type_param_im (EVC_X_AIM, E_CONTACT_IM_AIM_HOME_1);
+}
+
+static void
+test_type_param_xgadugadu (void)
+{
+ test_type_param_im (EVC_X_GADUGADU, E_CONTACT_IM_GADUGADU_HOME_1);
+}
+
+static void
+test_type_param_xgoogletalk (void)
+{
+ test_type_param_im (EVC_X_GOOGLE_TALK, E_CONTACT_IM_GOOGLE_TALK_HOME_1);
+}
+
+static void
+test_type_param_xgroupwise (void)
+{
+ test_type_param_im (EVC_X_GROUPWISE, E_CONTACT_IM_GROUPWISE_HOME_1);
+}
+
+static void
+test_type_param_xicq (void)
+{
+ test_type_param_im (EVC_X_ICQ, E_CONTACT_IM_ICQ_HOME_1);
+}
+
+static void
+test_type_param_xjabber (void)
+{
+ test_type_param_im (EVC_X_JABBER, E_CONTACT_IM_JABBER_HOME_1);
+}
+
+static void
+test_type_param_xmsn (void)
+{
+ test_type_param_im (EVC_X_MSN, E_CONTACT_IM_MSN_HOME_1);
+}
+
+static void
+test_type_param_xskype (void)
+{
+ test_type_param_im (EVC_X_SKYPE, E_CONTACT_IM_SKYPE_HOME_1);
+}
+
+static void
+test_type_param_xyahoo (void)
+{
+ test_type_param_im (EVC_X_YAHOO, E_CONTACT_IM_YAHOO_HOME_1);
+}
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("https://gitlab.gnome.org/GNOME/evolution-data-server/issues/");
+
+ g_test_add_func ("/Contact/TypeParam/Email", test_type_param_email);
+ g_test_add_func ("/Contact/TypeParam/Adr", test_type_param_adr);
+ g_test_add_func ("/Contact/TypeParam/Label", test_type_param_label);
+ g_test_add_func ("/Contact/TypeParam/Key", test_type_param_key);
+ g_test_add_func ("/Contact/TypeParam/Tel", test_type_param_tel);
+ g_test_add_func ("/Contact/TypeParam/XAim", test_type_param_xaim);
+ g_test_add_func ("/Contact/TypeParam/XGadugadu", test_type_param_xgadugadu);
+ g_test_add_func ("/Contact/TypeParam/XGoogletalk", test_type_param_xgoogletalk);
+ g_test_add_func ("/Contact/TypeParam/XGroupwise", test_type_param_xgroupwise);
+ g_test_add_func ("/Contact/TypeParam/XIcq", test_type_param_xicq);
+ g_test_add_func ("/Contact/TypeParam/XJabber", test_type_param_xjabber);
+ g_test_add_func ("/Contact/TypeParam/XMsn", test_type_param_xmsn);
+ g_test_add_func ("/Contact/TypeParam/XSkype", test_type_param_xskype);
+ g_test_add_func ("/Contact/TypeParam/XYahoo", test_type_param_xyahoo);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]