[folks] Initial implementation of the tracker backend
- From: Raul Gutierrez Segales <raulgs src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] Initial implementation of the tracker backend
- Date: Mon, 21 Mar 2011 15:15:56 +0000 (UTC)
commit 6a2253b8110f04e904b022e9fc21f66f3153a78a
Author: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
Date: Tue Feb 15 17:13:30 2011 +0000
Initial implementation of the tracker backend
backends/Makefile.am | 13 +
backends/tracker/Makefile.am | 63 ++
backends/tracker/lib/Makefile.am | 115 +++
.../tracker/lib/folks-tracker-uninstalled.pc.in | 12 +
backends/tracker/lib/folks-tracker.deps | 4 +
backends/tracker/lib/folks-tracker.pc.in | 15 +
backends/tracker/lib/trf-persona-store.vala | 1028 ++++++++++++++++++++
backends/tracker/lib/trf-persona.vala | 982 +++++++++++++++++++
backends/tracker/lib/trf-util.vala | 139 +++
backends/tracker/tr-backend-factory.vala | 59 ++
backends/tracker/tr-backend.vala | 120 +++
configure.ac | 39 +
tests/Makefile.am | 17 +
tests/lib/Makefile.am | 13 +
tests/lib/tracker/Makefile.am | 51 +
tests/lib/tracker/backend.vala | 544 +++++++++++
tests/tools/Makefile.am | 1 +
tests/tools/tracker.sh | 34 +
tests/tools/with-session-bus-tracker.sh | 45 +
tests/tracker/Makefile.am | 253 +++++
tests/tracker/add-contact.vala | 147 +++
tests/tracker/additional-names-updates.vala | 163 +++
tests/tracker/avatar-details-interface.vala | 169 ++++
tests/tracker/avatar-updates.vala | 177 ++++
tests/tracker/birthday-details-interface.vala | 150 +++
tests/tracker/birthday-updates.vala | 181 ++++
tests/tracker/data/avatar-01.jpg | Bin 0 -> 1157 bytes
tests/tracker/data/backend-tracker-only.ini | 6 +
tests/tracker/default-contact.vala | 144 +++
tests/tracker/email-details-interface.vala | 150 +++
tests/tracker/emails-updates.vala | 207 ++++
tests/tracker/family-name-updates.vala | 160 +++
tests/tracker/favourite-details-interface.vala | 166 ++++
tests/tracker/favourite-updates.vala | 182 ++++
tests/tracker/fullname-updates.vala | 153 +++
tests/tracker/gender-details-interface.vala | 143 +++
tests/tracker/given-name-updates.vala | 158 +++
tests/tracker/im-details-interface.vala | 160 +++
tests/tracker/imaddresses-updates.vala | 197 ++++
tests/tracker/individual-retrieval.vala | 138 +++
tests/tracker/name-details-interface.vala | 188 ++++
tests/tracker/nickname-updates.vala | 153 +++
tests/tracker/note-details-interface.vala | 151 +++
tests/tracker/phone-details-interface.vala | 149 +++
tests/tracker/phones-updates.vala | 196 ++++
.../tracker/postal-address-details-interface.vala | 176 ++++
tests/tracker/prefix-name-updates.vala | 155 +++
tests/tracker/remove-contact.vala | 140 +++
tests/tracker/role-details-interface.vala | 138 +++
tests/tracker/suffix-name-updates.vala | 158 +++
tests/tracker/url-details-interface.vala | 150 +++
tests/tracker/website-updates.vala | 175 ++++
52 files changed, 8427 insertions(+), 0 deletions(-)
---
diff --git a/backends/Makefile.am b/backends/Makefile.am
index cd023e8..02ae4f0 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -3,4 +3,17 @@ SUBDIRS = \
key-file \
$(NULL)
+if ENABLE_TRACKER
+SUBDIRS += tracker
+endif
+
+DIST_SUBDIRS = \
+ telepathy \
+ key-file \
+ $(NULL)
+
+if ENABLE_TRACKER
+DIST_SUBDIRS += tracker
+endif
+
-include $(top_srcdir)/git.mk
diff --git a/backends/tracker/Makefile.am b/backends/tracker/Makefile.am
new file mode 100644
index 0000000..80e9ae8
--- /dev/null
+++ b/backends/tracker/Makefile.am
@@ -0,0 +1,63 @@
+SUBDIRS = lib
+
+BACKEND_NAME = "tracker"
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/folks \
+ -I$(top_srcdir)/backends/tracker/lib \
+ -include $(CONFIG_HEADER) \
+ -DPACKAGE_DATADIR=\"$(pkgdatadir)\" \
+ -DBACKEND_NAME=\"$(BACKEND_NAME)\" \
+ -DG_LOG_DOMAIN=\"$(BACKEND_NAME)\" \
+ $(NULL)
+
+VALAFLAGS += \
+ --vapidir=. \
+ --vapidir=vapi \
+ --vapidir=$(top_builddir)/backends/tracker/lib \
+ --vapidir=$(top_srcdir)/folks \
+ $(addprefix --pkg ,$(folks_backend_tracker_deps)) \
+ $(NULL)
+
+backenddir = $(BACKEND_DIR)/tracker
+backend_LTLIBRARIES = libfolks-backend-tracker.la
+
+libfolks_backend_tracker_la_SOURCES = \
+ tr-backend.vala \
+ tr-backend-factory.vala \
+ $(NULL)
+
+folks_backend_tracker_deps = \
+ folks \
+ folks-tracker \
+ gee-1.0 \
+ gio-2.0 \
+ gobject-2.0 \
+ tracker-sparql-0.10 \
+ $(NULL)
+
+libfolks_backend_tracker_la_CFLAGS = \
+ $(GIO_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GEE_CFLAGS) \
+ $(TRACKER_SPARQL_CFLAGS) \
+ $(NULL)
+
+libfolks_backend_tracker_la_LIBADD = \
+ $(GIO_LIBS) \
+ $(GLIB_LIBS) \
+ $(GEE_LIBS) \
+ $(top_builddir)/folks/libfolks.la \
+ $(TRACKER_SPARQL_LIBS) \
+ lib/libfolks-tracker.la \
+ $(NULL)
+
+libfolks_backend_tracker_la_LDFLAGS = -shared -fPIC -module -avoid-version
+
+GITIGNOREFILES = \
+ folks-backend-tracker.vapi \
+ $(libfolks_backend_tracker_la_SOURCES:.vala=.c) \
+ libfolks_backend_tracker_la_vala.stamp \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/backends/tracker/lib/Makefile.am b/backends/tracker/lib/Makefile.am
new file mode 100644
index 0000000..d4a8b80
--- /dev/null
+++ b/backends/tracker/lib/Makefile.am
@@ -0,0 +1,115 @@
+BACKEND_NAME = "tracker"
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/folks \
+ -include $(CONFIG_HEADER) \
+ -DPACKAGE_DATADIR=\"$(pkgdatadir)\" \
+ -DBACKEND_NAME=\"$(BACKEND_NAME)\" \
+ -DG_LOG_DOMAIN=\"$(BACKEND_NAME)\" \
+ $(NULL)
+
+VAPIGENFLAGS += \
+ --vapidir=. \
+ --vapidir=$(top_srcdir)/folks
+
+folks_trackerdir = $(libdir)
+folks_tracker_LTLIBRARIES = libfolks-tracker.la
+
+CLEANFILES =
+
+##################################################################
+# Support library
+##################################################################
+
+pkgconfig_in = folks-tracker.pc.in
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(pkgconfig_in:.in=)
+
+libfolks_tracker_la_vala.stamp:
+
+folks_tracker_valasources = \
+ trf-persona.vala \
+ trf-persona-store.vala \
+ trf-util.vala \
+ $(NULL)
+
+libfolks_tracker_la_SOURCES = \
+ $(folks_tracker_valasources) \
+ $(NULL)
+
+libfolks_tracker_la_VALAFLAGS = \
+ --vapidir=. \
+ --vapidir=$(top_srcdir)/folks \
+ --pkg folks \
+ --pkg gobject-2.0 \
+ --pkg gio-2.0 \
+ --pkg gee-1.0 \
+ --pkg tracker-sparql-0.10 \
+ --vapi folks-tracker.vapi \
+ -H folks-tracker.h \
+ $(NULL)
+
+folks_backend_tracker_deps = \
+ folks \
+ gee-1.0 \
+ gio-2.0 \
+ gobject-2.0 \
+ tracker-sparql-0.10 \
+ $(NULL)
+
+libfolks_tracker_la_CFLAGS = \
+ $(GIO_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GEE_CFLAGS) \
+ $(TRACKER_SPARQL_CFLAGS) \
+ $(NULL)
+
+libfolks_tracker_la_LIBADD = \
+ $(GIO_LIBS) \
+ $(GLIB_LIBS) \
+ $(GEE_LIBS) \
+ $(top_builddir)/folks/libfolks.la \
+ $(TRACKER_SPARQL_LIBS) \
+ $(NULL)
+
+# The quoting here is unnecessary but harmless, and has the useful side-effect
+# that vim quickfix mode (:make) doesn't interpret the libtool --mode=link
+# command as an error message in a bizarrely named file
+libfolks_tracker_la_LDFLAGS = \
+ -version-info "$(LT_CURRENT)":"$(LT_REVISION)":"$(LT_AGE)" \
+ -export-symbols-regex "^(TRF|trf)_.*|" \
+ $(NULL)
+
+folks_tracker_includedir = $(includedir)/folks
+folks_tracker_include_HEADERS = \
+ folks-tracker.h \
+ $(NULL)
+
+vapidir = $(datadir)/vala/vapi
+dist_vapi_DATA = \
+ folks-tracker.vapi \
+ folks-tracker.deps \
+ $(NULL)
+
+##################################################################
+# General
+##################################################################
+
+CLEANFILES += \
+ $(pkgconfig_in:.in=) \
+ folks-tracker-uninstalled.pc \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ $(folks_tracker_valasources:.vala=.c) \
+ libfolks_tracker_la_vala.stamp \
+ folks-tracker.h \
+ folks-tracker.vapi \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(pkgconfig_in) \
+ $(MAINTAINERCLEANFILES) \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/backends/tracker/lib/folks-tracker-uninstalled.pc.in b/backends/tracker/lib/folks-tracker-uninstalled.pc.in
new file mode 100644
index 0000000..51a096b
--- /dev/null
+++ b/backends/tracker/lib/folks-tracker-uninstalled.pc.in
@@ -0,0 +1,12 @@
+prefix=
+exec_prefix=
+abs_top_srcdir= abs_top_srcdir@
+abs_top_builddir= abs_top_builddir@
+vapidir= abs_top_srcdir@/folks
+
+Name: Folks Tracker support library (uninstalled copy)
+Description: Tracker support library for the Folks meta-contacts library
+Version: @VERSION@
+Requires: folks glib-2.0 gobject-2.0 gee-1.0 tracker-sparql-0.10
+Libs: ${abs_top_builddir}/backends/telepathy/libfolks-tracker.la
+Cflags: -I${abs_top_srcdir} -I${abs_top_srcdir}/backends/tracker -I${abs_top_builddir}
diff --git a/backends/tracker/lib/folks-tracker.deps b/backends/tracker/lib/folks-tracker.deps
new file mode 100644
index 0000000..841bba3
--- /dev/null
+++ b/backends/tracker/lib/folks-tracker.deps
@@ -0,0 +1,4 @@
+glib-2.0
+gobject-2.0
+folks
+tracker-sparql-0.10
\ No newline at end of file
diff --git a/backends/tracker/lib/folks-tracker.pc.in b/backends/tracker/lib/folks-tracker.pc.in
new file mode 100644
index 0000000..bff6680
--- /dev/null
+++ b/backends/tracker/lib/folks-tracker.pc.in
@@ -0,0 +1,15 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+bindir= bindir@
+includedir= includedir@
+datarootdir= datarootdir@
+datadir= datadir@
+vapidir= datadir@/vala/vapi
+
+Name: Folks tracker support library
+Description: Tracker support library for the Folks meta-contacts library
+Version: @VERSION@
+Requires: folks glib-2.0 gobject-2.0 gee-1.0 tracker-sparql-0.10
+Libs: -L${libdir} -lfolks-tracker
+Cflags: -I${includedir} -I${includedir}/folks
diff --git a/backends/tracker/lib/trf-persona-store.vala b/backends/tracker/lib/trf-persona-store.vala
new file mode 100644
index 0000000..ce43a11
--- /dev/null
+++ b/backends/tracker/lib/trf-persona-store.vala
@@ -0,0 +1,1028 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Travis Reitter <travis reitter collabora co uk>
+ * Philip Withnall <philip withnall collabora co uk>
+ * Marco Barisione <marco barisione collabora co uk>
+ * Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ */
+
+using Folks;
+using GLib;
+using Tracker;
+using Tracker.Sparql;
+
+extern const string BACKEND_NAME;
+
+internal enum Trf.Fields
+{
+ TRACKER_ID,
+ FULL_NAME,
+ FAMILY_NAME,
+ GIVEN_NAME,
+ ADDITIONAL_NAMES,
+ PREFIXES,
+ SUFFIXES,
+ NICKNAME,
+ BIRTHDAY,
+ AVATAR_URL,
+ IM_ADDRESSES,
+ PHONES,
+ EMAILS,
+ URLS,
+ FAVOURITE,
+ CONTACT_URN,
+ ROLES,
+ NOTE,
+ GENDER,
+ POSTAL_ADDRESS
+}
+
+internal enum Trf.AfflInfoFields
+{
+ IM_TRACKER_ID,
+ IM_PROTOCOL,
+ IM_ACCOUNT_ID,
+ AFFL_TRACKER_ID,
+ AFFL_ROLE,
+ AFFL_ORG,
+ AFFL_POBOX,
+ AFFL_DISTRICT,
+ AFFL_COUNTY,
+ AFFL_LOCALITY,
+ AFFL_POSTALCODE,
+ AFFL_STREET_ADDRESS,
+ AFFL_ADDRESS_LOCATION,
+ AFFL_EXTENDED_ADDRESS,
+ AFFL_COUNTRY,
+ AFFL_REGION,
+ AFFL_EMAIL,
+ AFFL_PHONE,
+ AFFL_WEBSITE,
+ AFFL_BLOG,
+ AFFL_URL
+}
+
+internal enum Trf.PostalAddressFields
+{
+ TRACKER_ID,
+ POBOX,
+ DISTRICT,
+ COUNTY,
+ LOCALITY,
+ POSTALCODE,
+ STREET_ADDRESS,
+ ADDRESS_LOCATION,
+ EXTENDED_ADDRESS,
+ COUNTRY,
+ REGION
+}
+
+internal enum Trf.UrlsFields
+{
+ TRACKER_ID,
+ BLOG,
+ WEBSITE,
+ URL
+}
+
+internal enum Trf.RoleFields
+{
+ TRACKER_ID,
+ ROLE,
+ DEPARTMENT
+}
+
+internal enum Trf.IMFields
+{
+ TRACKER_ID,
+ PROTO,
+ ID
+}
+
+internal enum Trf.PhoneFields
+{
+ TRACKER_ID,
+ PHONE
+}
+
+internal enum Trf.EmailFields
+{
+ TRACKER_ID,
+ EMAIL
+}
+
+internal enum Trf.TagFields
+{
+ TRACKER_ID
+}
+
+/**
+ * A persona store.
+ * It will create { link Persona}s for each contacts on the main addressbook.
+ */
+public class Trf.PersonaStore : Folks.PersonaStore
+{
+ private const string _OBJECT_NAME = "org.freedesktop.Tracker1";
+ private const string _OBJECT_IFACE = "org.freedesktop.Tracker1.Resources";
+ private const string _OBJECT_PATH = "/org/freedesktop/Tracker1/Resources";
+ private HashTable<string, Persona> _personas;
+ private bool _is_prepared = false;
+ private static const int _default_timeout = 100;
+ private Resources _resources_object;
+ private Tracker.Sparql.Connection _connection;
+ private static Gee.TreeMap<string, string> _urn_prefix = null;
+ private static Gee.TreeMap<string, int> _prefix_tracker_id = null;
+ private static const string _INITIAL_QUERY =
+ "SELECT " +
+ "tracker:id(?_contact) " +
+ "nco:fullname(?_contact) " +
+ "nco:nameFamily(?_contact) " +
+ "nco:nameGiven(?_contact) " +
+ "nco:nameAdditional(?_contact) " +
+ "nco:nameHonorificPrefix(?_contact) " +
+ "nco:nameHonorificSuffix(?_contact) " +
+ "nco:nickname(?_contact) " +
+ "nco:birthDate(?_contact) " +
+ "nie:url(nco:photo(?_contact)) " +
+
+ /* keep synced with Trf.IMFields */
+ "(SELECT " +
+ "GROUP_CONCAT ( " +
+ " fn:concat(tracker:id(?affl),'\t'," +
+ " tracker:coalesce(nco:imProtocol(?a),''), " +
+ "'\t', tracker:coalesce(nco:imID(?a),'')),'\\n') " +
+ "WHERE { ?_contact nco:hasAffiliation ?affl. " +
+ " ?affl nco:hasIMAddress ?a } ) " +
+
+ /* keep synced with Trf.PhoneFields */
+ "(SELECT " +
+ "GROUP_CONCAT " +
+ " (fn:concat(tracker:id(?affl),'\t', " +
+ " nco:phoneNumber(?aff_number)), " +
+ "'\\n') " +
+ "WHERE { ?_contact nco:hasAffiliation ?affl . " +
+ " ?affl nco:hasPhoneNumber ?aff_number } ) " +
+
+ /* keep synced with Trf.EmailFields */
+ "(SELECT " +
+ "GROUP_CONCAT " +
+ " (fn:concat(tracker:id(?affl), '\t', " +
+ " nco:emailAddress(?emailaddress)), " +
+ "',') " +
+ "WHERE { ?_contact nco:hasAffiliation ?affl . " +
+ " ?affl nco:hasEmailAddress ?emailaddress }) " +
+
+ /* keep synced with Trf.UrlsFields */
+ " (SELECT " +
+ "GROUP_CONCAT " +
+ " (fn:concat(tracker:id(?affl), '\t'," +
+ " tracker:coalesce(nco:blogUrl(?affl),'')," +
+ " '\t'," +
+ " tracker:coalesce(nco:websiteUrl(?affl),'')" +
+ " , '\t'," +
+ " tracker:coalesce(nco:url(?affl),''))," +
+ " '\\n') " +
+ "WHERE { ?_contact nco:hasAffiliation ?affl } )" +
+
+ /* keep synced with Trf.TagFields */
+ "(SELECT " +
+ "GROUP_CONCAT(tracker:id(?_tag), " +
+ "',') " +
+ "WHERE { ?_contact nao:hasTag " +
+ "?_tag }) " +
+
+ "?_contact " +
+
+ /* keep synced with Trf.RoleFields */
+ "(SELECT " +
+ "GROUP_CONCAT " +
+ " (fn:concat(tracker:id(?affl), '\t', " +
+ " tracker:coalesce(nco:role(?affl),''), '\t', " +
+ " tracker:coalesce(nco:department(?affl),'')), " +
+ "'\\n') " +
+ "WHERE { ?_contact nco:hasAffiliation " +
+ "?affl }) " +
+
+ "nco:note(?_contact) " +
+ "tracker:id(nco:gender(?_contact)) " +
+
+ /* keep synced with Trf.PostalAddressFields*/
+ "(SELECT " +
+ "GROUP_CONCAT " +
+ " (fn:concat(tracker:id(?affl), '\t', " +
+ " tracker:coalesce(nco:pobox(?postal),'')" +
+ " , '\t', " +
+ " tracker:coalesce(nco:district(?postal),'')" +
+ " , '\t', " +
+ " tracker:coalesce(nco:county(?postal),'')" +
+ " , '\t', " +
+ " tracker:coalesce(nco:locality(?postal),'')" +
+ " , '\t', " +
+ " tracker:coalesce(nco:postalcode(?postal),'')" +
+ " , '\t', " +
+ " tracker:coalesce(nco:streetAddress(?postal)" +
+ " ,''), '\t', " +
+ " tracker:coalesce(nco:addressLocation(?postal)" +
+ " ,''), '\t', " +
+ " tracker:coalesce(nco:extendedAddress(?postal)" +
+ " ,''), '\t', " +
+ " tracker:coalesce(nco:country(?postal),'')" +
+ " , '\t', " +
+ " tracker:coalesce(nco:region(?postal),'')), " +
+ "'\\n') " +
+ "WHERE { ?_contact nco:hasAffiliation " +
+ "?affl . ?affl nco:hasPostalAddress ?postal }) " +
+
+ "{ ?_contact a nco:PersonContact . } " +
+ "ORDER BY tracker:id(?_contact) ";
+
+
+ /**
+ * The type of persona store this is.
+ *
+ * See { link Folks.PersonaStore.type_id}.
+ */
+ public override string type_id { get { return BACKEND_NAME; } }
+
+ /**
+ * Whether this PersonaStore can add { link Folks.Persona}s.
+ *
+ * See { link Folks.PersonaStore.can_add_personas}.
+ *
+ * @since UNRELEASED
+ */
+ public override MaybeBool can_add_personas
+ {
+ get { return MaybeBool.FALSE; }
+ }
+
+ /**
+ * Whether this PersonaStore can set the alias of { link Folks.Persona}s.
+ *
+ * See { link Folks.PersonaStore.can_alias_personas}.
+ *
+ * @since UNRELEASED
+ */
+ public override MaybeBool can_alias_personas
+ {
+ get { return MaybeBool.FALSE; }
+ }
+
+ /**
+ * Whether this PersonaStore can set the groups of { link Folks.Persona}s.
+ *
+ * See { link Folks.PersonaStore.can_group_personas}.
+ *
+ * @since UNRELEASED
+ */
+ public override MaybeBool can_group_personas
+ {
+ get { return MaybeBool.FALSE; }
+ }
+
+ /**
+ * Whether this PersonaStore can remove { link Folks.Persona}s.
+ *
+ * See { link Folks.PersonaStore.can_remove_personas}.
+ *
+ * @since UNRELEASED
+ */
+ public override MaybeBool can_remove_personas
+ {
+ get { return MaybeBool.FALSE; }
+ }
+
+ /**
+ * Whether this PersonaStore has been prepared.
+ *
+ * See { link Folks.PersonaStore.is_prepared}.
+ *
+ * @since UNRELEASED
+ */
+ public override bool is_prepared
+ {
+ get { return this._is_prepared; }
+ }
+
+ /**
+ * The { link Persona}s exposed by this PersonaStore.
+ *
+ * See { link Folks.PersonaStore.personas}.
+ */
+ public override HashTable<string, Persona> personas
+ {
+ get { return this._personas; }
+ }
+
+ /**
+ * Create a new PersonaStore.
+ *
+ * Create a new persona store to store the { link Persona}s for the contacts
+ */
+ public PersonaStore ()
+ {
+ Object (id: BACKEND_NAME, display_name: BACKEND_NAME);
+ this._personas = new HashTable<string, Persona> (str_hash, str_equal);
+ debug ("Initial query : \n%s\n", this._INITIAL_QUERY);
+ }
+
+ /**
+ * Add a new { link Persona} to the PersonaStore.
+ *
+ * See { link Folks.PersonaStore.add_persona_from_details}.
+ */
+ public override async Folks.Persona? add_persona_from_details (
+ HashTable<string, Value?> details) throws Folks.PersonaStoreError
+ {
+ throw new PersonaStoreError.READ_ONLY (
+ "Personas cannot be added to this store.");
+ }
+
+ /**
+ * Remove a { link Persona} from the PersonaStore.
+ *
+ * See { link Folks.PersonaStore.remove_persona}.
+ */
+ public override async void remove_persona (Folks.Persona persona)
+ throws Folks.PersonaStoreError
+ {
+ throw new PersonaStoreError.READ_ONLY (
+ "Personas cannot be removed from this store.");
+ }
+
+ /**
+ * Prepare the PersonaStore for use.
+ *
+ * TODO: we should throw different errors dependening on what went wrong
+ * when we were trying to setup the PersonaStore.
+ *
+ * See { link Folks.PersonaStore.prepare}.
+ */
+ public override async void prepare () throws GLib.Error
+ {
+ lock (this._is_prepared)
+ {
+ if (!this._is_prepared)
+ {
+ try
+ {
+ this._connection = Tracker.Sparql.Connection.get ();
+
+ yield this._build_predicates_table ();
+ yield this._do_add_contacts (this._INITIAL_QUERY);
+
+ /* Don't add a match rule for all signals from Tracker but
+ * only for GraphUpdated with the specific class we need. We
+ * don't want to be woken up for irrelevent updates on the
+ * graph.
+ */
+ this._resources_object = yield GLib.Bus.get_proxy<Resources> (
+ BusType.SESSION,
+ this._OBJECT_NAME,
+ this._OBJECT_PATH,
+ DBusProxyFlags.DO_NOT_CONNECT_SIGNALS |
+ DBusProxyFlags.DO_NOT_LOAD_PROPERTIES);
+ this._resources_object.g_connection.signal_subscribe
+ (this._OBJECT_NAME, this._OBJECT_IFACE,
+ "GraphUpdated", this._OBJECT_PATH,
+ Trf.OntologyDefs.PERSON_CLASS, GLib.DBusSignalFlags.NONE,
+ this._graph_updated_cb);
+ }
+ catch (GLib.IOError e1)
+ {
+ warning ("Could not connect to D-Bus service: %s",
+ e1.message);
+ throw new PersonaStoreError.INVALID_ARGUMENT (e1.message);
+ }
+ catch (Tracker.Sparql.Error e2)
+ {
+ warning ("Error fetching SPARQL connection handler: %s",
+ e2.message);
+ throw new PersonaStoreError.INVALID_ARGUMENT (e2.message);
+ }
+ catch (GLib.DBusError e3)
+ {
+ warning ("Could not connect to D-Bus service: %s",
+ e3.message);
+ throw new PersonaStoreError.INVALID_ARGUMENT (e3.message);
+ }
+ }
+ }
+ }
+
+ public int get_favorite_id ()
+ {
+ return this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NAO_FAVORITE);
+ }
+
+ public int get_gender_male_id ()
+ {
+ return this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_MALE);
+ }
+
+ public int get_gender_female_id ()
+ {
+ return this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_FEMALE);
+ }
+
+ private async void _build_predicates_table ()
+ {
+ if (this._prefix_tracker_id != null)
+ {
+ return;
+ }
+
+ yield this._build_urn_prefix_table ();
+
+ this._prefix_tracker_id = new Gee.TreeMap<string, int> ();
+
+ string query = "SELECT ";
+ foreach (var urn_t in this._urn_prefix.keys)
+ {
+ query += " tracker:id(" + urn_t + ")";
+ }
+ query += " WHERE {} ";
+
+ try
+ {
+ Sparql.Cursor cursor = yield this._connection.query_async (query);
+
+ while (cursor.next ())
+ {
+ int i=0;
+ foreach (var urn in this._urn_prefix.keys)
+ {
+ var tracker_id = (int) cursor.get_integer (i);
+ var prefix = this._urn_prefix.get (urn).dup ();
+ this._prefix_tracker_id.set (prefix, tracker_id);
+ i++;
+ }
+ }
+ }
+ catch (Tracker.Sparql.Error e1)
+ {
+ warning ("Couldn't build predicates table: %s %s", query, e1.message);
+ }
+ catch (GLib.Error e2)
+ {
+ warning ("Couldn't build predicates table: %s %s", query, e2.message);
+ }
+ }
+
+ private async void _build_urn_prefix_table ()
+ {
+ if (this._urn_prefix != null)
+ {
+ return;
+ }
+ this._urn_prefix = new Gee.TreeMap<string, string> ();
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#fullname>",
+ Trf.OntologyDefs.NCO_FULLNAME);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#nameFamily>",
+ Trf.OntologyDefs.NCO_FAMILY);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#nameGiven>",
+ Trf.OntologyDefs.NCO_GIVEN);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#nameAdditional>",
+ Trf.OntologyDefs.NCO_ADDITIONAL);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#nameHonorificSuffix>",
+ Trf.OntologyDefs.NCO_SUFFIX);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#nameHonorificPrefix>",
+ Trf.OntologyDefs.NCO_PREFIX);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#nickname>",
+ Trf.OntologyDefs.NCO_NICKNAME);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.RDF_URL_PREFIX + "22-rdf-syntax-ns#type>",
+ Trf.OntologyDefs.RDF_TYPE);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#PersonContact>",
+ Trf.OntologyDefs.NCO_PERSON);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#websiteUrl>",
+ Trf.OntologyDefs.NCO_WEBSITE);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#blogUrl>",
+ Trf.OntologyDefs.NCO_BLOG);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NAO_URL_PREFIX + "nao#predefined-tag-favorite>",
+ Trf.OntologyDefs.NAO_FAVORITE);
+ this._urn_prefix.set (Trf.OntologyDefs.NAO_URL_PREFIX + "nao#hasTag>",
+ Trf.OntologyDefs.NAO_TAG);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#hasEmailAddress>",
+ Trf.OntologyDefs.NCO_HAS_EMAIL);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#hasPhoneNumber>",
+ Trf.OntologyDefs.NCO_HAS_PHONE);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#hasAffiliation>",
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#birthDate>",
+ Trf.OntologyDefs.NCO_BIRTHDAY);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#note>",
+ Trf.OntologyDefs.NCO_NOTE);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#gender>",
+ Trf.OntologyDefs.NCO_GENDER);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#gender-male>",
+ Trf.OntologyDefs.NCO_MALE);
+ this._urn_prefix.set (
+ Trf.OntologyDefs.NCO_URL_PREFIX + "nco#gender-female>",
+ Trf.OntologyDefs.NCO_FEMALE);
+ this._urn_prefix.set (Trf.OntologyDefs.NCO_URL_PREFIX + "nco#photo>",
+ Trf.OntologyDefs.NCO_PHOTO);
+ }
+
+ private void _graph_updated_cb (DBusConnection connection,
+ string sender_name, string object_path, string interface_name,
+ string signal_name, Variant parameters)
+ {
+ string class_name = "";
+ VariantIter iter_del = null;
+ VariantIter iter_ins = null;
+
+ parameters.get("(sa(iiii)a(iiii))", &class_name, &iter_del, &iter_ins);
+
+ if (class_name != Trf.OntologyDefs.PERSON_CLASS)
+ {
+ return;
+ }
+
+ var removed_personas = new Queue<Persona> ();
+ var added_personas = new Queue<Persona> ();
+
+ var nco_person_id =
+ this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_PERSON);
+ var rdf_type_id = this._prefix_tracker_id.get (Trf.OntologyDefs.RDF_TYPE);
+
+ Event e = Event ();
+
+ while (iter_del.next
+ ("(iiii)", &e.graph_id, &e.subject_id, &e.pred_id, &e.object_id))
+ {
+ var p_id = Trf.Persona.build_iid (this.id, e.subject_id.to_string ());
+ var persona = this._personas.lookup (p_id);
+ if (persona != null)
+ {
+ if (e.pred_id == rdf_type_id &&
+ e.object_id == nco_person_id)
+ {
+ removed_personas.push_tail (persona);
+ _personas.remove (persona.iid);
+ }
+ else
+ {
+ this._do_update (persona, e, false);
+ }
+ }
+ }
+
+ while (iter_ins.next
+ ("(iiii)", &e.graph_id, &e.subject_id, &e.pred_id, &e.object_id))
+ {
+ var subject_tracker_id = e.subject_id.to_string ();
+ var p_id = Trf.Persona.build_iid (this.id, subject_tracker_id);
+ var persona = this._personas.lookup (p_id);
+ if (persona == null)
+ {
+ persona = new Trf.Persona (this, subject_tracker_id);
+ this._personas.insert (persona.iid, persona);
+ added_personas.push_tail (persona);
+ }
+ this._do_update (persona, e);
+ }
+
+ if (removed_personas.length > 0)
+ {
+ this.personas_changed (null, removed_personas.head, null, null, 0);
+ }
+
+ if (added_personas.length > 0)
+ {
+ this.personas_changed (added_personas.head, null, null, null, 0);
+ }
+ }
+
+ private async void _do_add_contacts (string query)
+ {
+ try {
+ var added_personas = new Queue<Persona> ();
+ Sparql.Cursor cursor = yield this._connection.query_async (query);
+
+ while (cursor.next ())
+ {
+ int tracker_id = (int) cursor.get_integer (Trf.Fields.TRACKER_ID);
+ var p_id = Trf.Persona.build_iid (this.id, tracker_id.to_string ());
+ if (this._personas.lookup (p_id) == null)
+ {
+ var persona = new Trf.Persona (this,
+ tracker_id.to_string (), cursor);
+ this._personas.insert (persona.iid, persona);
+ added_personas.push_tail (persona);
+ }
+ }
+
+ if (added_personas.length > 0)
+ {
+ this.personas_changed (added_personas.head, null, null, null, 0);
+ }
+ } catch (GLib.Error e) {
+ warning ("Couldn't perform queries: %s %s", query, e.message);
+ }
+ }
+
+ private void _do_update (Persona p, Event e, bool adding = true)
+ {
+ if (e.pred_id ==
+ this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_FULLNAME))
+ {
+ string fullname = "";
+ if (adding)
+ {
+ fullname =
+ this._get_property (e.subject_id, Trf.OntologyDefs.NCO_FULLNAME);
+ }
+ p._update_full_name (fullname);
+ }
+ else if (e.pred_id ==
+ this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_NICKNAME))
+ {
+ string nickname = "";
+ if (adding)
+ {
+ nickname =
+ this._get_property (
+ e.subject_id, Trf.OntologyDefs.NCO_NICKNAME);
+ }
+ p._update_nickname (nickname);
+ }
+ else if (e.pred_id ==
+ this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_FAMILY))
+ {
+ string family_name = "";
+ if (adding)
+ {
+ family_name = this._get_property
+ (e.subject_id, Trf.OntologyDefs.NCO_FAMILY);
+ }
+ p._update_family_name (family_name);
+ }
+ else if (e.pred_id ==
+ this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_GIVEN))
+ {
+ string given_name = "";
+ if (adding)
+ {
+ given_name = this._get_property (
+ e.subject_id, Trf.OntologyDefs.NCO_GIVEN);
+ }
+ p._update_given_name (given_name);
+ }
+ else if (e.pred_id ==
+ this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_ADDITIONAL))
+ {
+ string additional_name = "";
+ if (adding)
+ {
+ additional_name = this._get_property
+ (e.subject_id, Trf.OntologyDefs.NCO_ADDITIONAL);
+ }
+ p._update_additional_names (additional_name);
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_SUFFIX))
+ {
+ string suffix_name = "";
+ if (adding)
+ {
+ suffix_name = this._get_property
+ (e.subject_id, Trf.OntologyDefs.NCO_SUFFIX);
+ }
+ p._update_suffixes (suffix_name);
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_PREFIX))
+ {
+ string prefix_name = "";
+ if (adding)
+ {
+ prefix_name = this._get_property
+ (e.subject_id, Trf.OntologyDefs.NCO_PREFIX);
+ }
+ p._update_prefixes (prefix_name);
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ ("nao:hasTag"))
+ {
+ if (e.object_id == this.get_favorite_id ())
+ {
+ if (adding)
+ {
+ p.is_favourite = true;
+ }
+ else
+ {
+ p.is_favourite = false;
+ }
+ }
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_HAS_EMAIL))
+ {
+ if (adding)
+ {
+ var email = this._get_property (
+ e.object_id,
+ Trf.OntologyDefs.NCO_EMAIL_PROP,
+ Trf.OntologyDefs.NCO_EMAIL);
+ p._add_email (email, e.object_id.to_string ());
+ }
+ else
+ {
+ p._remove_email (e.object_id.to_string ());
+ }
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_HAS_PHONE))
+ {
+ if (adding)
+ {
+ var phone = this._get_property (
+ e.object_id, Trf.OntologyDefs.NCO_PHONE_PROP,
+ Trf.OntologyDefs.NCO_PHONE);
+ p._add_phone (phone, e.object_id.to_string ());
+ }
+ else
+ {
+ p._remove_phone (e.object_id.to_string ());
+ }
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_HAS_AFFILIATION))
+ {
+ if (adding)
+ {
+ var affl_info = this._get_affl_info (e.subject_id.to_string (),
+ e.object_id.to_string ());
+
+ debug ("affl_info : %s", affl_info.to_string ());
+
+ if (affl_info.im_tracker_id != null)
+ {
+ p._add_im_address (affl_info.affl_tracker_id,
+ affl_info.im_proto, affl_info.im_account_id);
+ }
+
+ if (affl_info.affl_tracker_id != null)
+ {
+ if (affl_info.title != null ||
+ affl_info.org != null)
+ {
+ p._add_role (affl_info.affl_tracker_id, affl_info.title,
+ affl_info.org);
+ }
+ }
+
+ if (affl_info.postal_address != null)
+ p._add_postal_address (affl_info.postal_address);
+
+ if (affl_info.phone != null)
+ p._add_phone (affl_info.phone, e.object_id.to_string ());
+
+ if (affl_info.email != null)
+ p._add_email (affl_info.email, e.object_id.to_string ());
+
+ if (affl_info.website != null)
+ p._add_url (affl_info.website,
+ affl_info.affl_tracker_id, "website");
+
+ if (affl_info.blog != null)
+ p._add_url (affl_info.blog,
+ affl_info.affl_tracker_id, "blog");
+
+ if (affl_info.url != null)
+ p._add_url (affl_info.url,
+ affl_info.affl_tracker_id, "url");
+ }
+ else
+ {
+ p._remove_im_address (e.object_id.to_string ());
+ p._remove_role (e.object_id.to_string ());
+ p._remove_postal_address (e.object_id.to_string ());
+ p._remove_phone (e.object_id.to_string ());
+ p._remove_email (e.object_id.to_string ());
+ p._remove_url (e.object_id.to_string ());
+ }
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_BIRTHDAY))
+ {
+ string bday = "";
+ if (adding)
+ {
+ bday = this._get_property (
+ e.subject_id, Trf.OntologyDefs.NCO_BIRTHDAY);
+ }
+ p._set_birthday (bday);
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_NOTE))
+ {
+ string note = "";
+ if (adding)
+ {
+ note = this._get_property (
+ e.subject_id, Trf.OntologyDefs.NCO_NOTE);
+ }
+ p._set_note (note);
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_GENDER))
+ {
+ if (adding)
+ {
+ p._set_gender (e.object_id);
+ }
+ else
+ {
+ p._set_gender (0);
+ }
+ }
+ else if (e.pred_id == this._prefix_tracker_id.get
+ (Trf.OntologyDefs.NCO_PHOTO))
+ {
+ string avatar_url = "";
+ if (adding)
+ {
+ avatar_url = this._get_property (e.object_id,
+ Trf.OntologyDefs.NIE_URL, Trf.OntologyDefs.NFO_IMAGE);
+ }
+ p._set_avatar (avatar_url);
+ }
+ }
+
+ private string _get_property
+ (int subject_tracker_id, string property,
+ string subject_type = Trf.OntologyDefs.NCO_PERSON)
+ {
+ string ret = "";
+ const string query_template =
+ "SELECT ?property WHERE" +
+ " { ?p a %s ; " +
+ " %s ?property " +
+ " . FILTER(tracker:id(?p) = %d ) }";
+
+ string query = query_template.printf (subject_type,
+ property, subject_tracker_id);
+
+ try
+ {
+ Sparql.Cursor cursor = this._connection.query (query);
+ while (cursor.next ())
+ {
+ var prop = cursor.get_string (0);
+ if (prop != null)
+ {
+ ret = prop.dup ();
+ }
+ }
+ }
+ catch (Tracker.Sparql.Error e1)
+ {
+ warning ("Couldn't fetch propery: %s %s", query, e1.message);
+ }
+ catch (GLib.Error e2)
+ {
+ warning ("Couldn't fetch property: %s %s", query, e2.message);
+ }
+
+ return ret;
+ }
+
+ /*
+ * This should be kept in sync with Trf.AfflInfoFields
+ */
+ private Trf.AfflInfo _get_affl_info (
+ string person_id, string affiliation_id)
+ {
+ Trf.AfflInfo affl_info = new Trf.AfflInfo ();
+ const string query_template =
+ "SELECT " +
+ "tracker:id(?i) " +
+ "nco:imProtocol(?i) " +
+ "nco:imID(?i) " +
+ "tracker:id(?a) " +
+ "nco:role(?a) " +
+ "nco:org(?a) " +
+ "nco:pobox(?postal) " +
+ "nco:district(?postal) " +
+ "nco:county(?postal) " +
+ "nco:locality(?postal) " +
+ "nco:postalcode(?postal) " +
+ "nco:streetAddress(?postal) " +
+ "nco:addressLocation(?postal) " +
+ "nco:extendedAddress(?postal) " +
+ "nco:country(?postal) " +
+ "nco:region(?postal) " +
+ "nco:emailAddress(?e) " +
+ "nco:phoneNumber(?number) " +
+ "nco:websiteUrl(?a) " +
+ "nco:blogUrl(?a) " +
+ "nco:url(?a) " +
+ " WHERE { ?p a nco:PersonContact ; nco:hasAffiliation ?a . " +
+ " OPTIONAL { ?a nco:hasIMAddress ?i } . " +
+ " OPTIONAL { ?a nco:hasPostalAddress ?postal } . " +
+ " OPTIONAL { ?a nco:hasEmailAddress ?e } . " +
+ " OPTIONAL { ?a nco:hasPhoneNumber ?number } " +
+ " FILTER(tracker:id(?p) = %s" +
+ " && tracker:id(?a) = %s" +
+ " ) } ";
+
+ string query = query_template.printf (person_id, affiliation_id);
+
+ debug ("_get_affl_info: %s", query);
+
+ try
+ {
+ Sparql.Cursor cursor = this._connection.query (query);
+ while (cursor.next ())
+ {
+ affl_info.im_tracker_id = cursor.get_string
+ (Trf.AfflInfoFields.IM_TRACKER_ID).dup ();
+ affl_info.im_proto = cursor.get_string
+ (Trf.AfflInfoFields.IM_PROTOCOL).dup ();
+ affl_info.im_account_id = cursor.get_string
+ (Trf.AfflInfoFields.IM_ACCOUNT_ID).dup ();
+ affl_info.affl_tracker_id = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_TRACKER_ID).dup ();
+ affl_info.title = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_ROLE).dup ();
+ affl_info.org = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_ORG).dup ();
+
+ var po_box = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_POBOX).dup ();
+ var extension = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_EXTENDED_ADDRESS).dup ();
+ var street = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_STREET_ADDRESS).dup ();
+ var locality = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_LOCALITY).dup ();
+ var region = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_REGION).dup ();
+ var postal_code = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_POSTALCODE).dup ();
+ var country = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_COUNTRY).dup ();
+
+ List<string> types = new List<string> ();
+
+ affl_info.postal_address = new Folks.PostalAddress (
+ po_box, extension, street, locality, region, postal_code,
+ country, null, (owned) types, affl_info.affl_tracker_id);
+
+ affl_info.email = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_EMAIL).dup ();
+ affl_info.phone = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_PHONE).dup ();
+
+ affl_info.website = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_WEBSITE).dup ();
+ affl_info.blog = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_BLOG).dup ();
+ affl_info.url = cursor.get_string
+ (Trf.AfflInfoFields.AFFL_URL).dup ();
+ }
+ }
+ catch (Tracker.Sparql.Error e1)
+ {
+ warning ("Couldn't fetch affiliation info: %s %s",
+ query, e1.message);
+ }
+ catch (GLib.Error e2)
+ {
+ warning ("Couldn't fetch affiliation info: %s %s",
+ query, e2.message);
+ }
+
+ return affl_info;
+ }
+}
diff --git a/backends/tracker/lib/trf-persona.vala b/backends/tracker/lib/trf-persona.vala
new file mode 100644
index 0000000..47b5a2d
--- /dev/null
+++ b/backends/tracker/lib/trf-persona.vala
@@ -0,0 +1,982 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Travis Reitter <travis reitter collabora co uk>
+ * Marco Barisione <marco barisione collabora co uk>
+ * Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ */
+
+using Gee;
+using GLib;
+using Folks;
+using Tracker;
+using Tracker.Sparql;
+
+/**
+ * A persona subclass which represents a single nco:Contact.
+ */
+public class Trf.Persona : Folks.Persona,
+ AvatarDetails,
+ BirthdayDetails,
+ EmailDetails,
+ FavouriteDetails,
+ GenderDetails,
+ ImDetails,
+ NameDetails,
+ NoteDetails,
+ PhoneDetails,
+ PostalAddressDetails,
+ RoleDetails,
+ UrlDetails
+{
+ private const string[] _linkable_properties =
+ {"im-addresses", "email-addresses"};
+ private GLib.List<FieldDetails> _phone_numbers;
+ private GLib.List<FieldDetails> _email_addresses;
+ private weak Sparql.Cursor _cursor;
+ private string _tracker_id;
+
+ /**
+ * { inheritDoc}
+ */
+ public GLib.List<FieldDetails> phone_numbers
+ {
+ get { return this._phone_numbers; }
+ private set
+ {
+ this._phone_numbers = new GLib.List<FieldDetails> ();
+ foreach (unowned FieldDetails ps in value)
+ {
+ this._phone_numbers.prepend (ps);
+ }
+ this._phone_numbers.reverse ();
+ }
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public GLib.List<FieldDetails> email_addresses
+ {
+ get { return this._email_addresses; }
+ private set
+ {
+ this._email_addresses = new GLib.List<FieldDetails> ();
+ foreach (unowned FieldDetails e in value)
+ {
+ this._email_addresses.prepend (e);
+ }
+ this._email_addresses.reverse ();
+ }
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override string[] linkable_properties
+ {
+ get { return this._linkable_properties; }
+ }
+
+ /**
+ * An avatar for the Persona.
+ *
+ * See { link Folks.Avatar.avatar}.
+ */
+ public File avatar { get; set; }
+
+ /**
+ * { inheritDoc}
+ */
+ public StructuredName structured_name { get; private set; }
+
+ /**
+ * { inheritDoc}
+ */
+ public string full_name { get; private set; }
+
+ private string _nickname;
+ /**
+ * { inheritDoc}
+ */
+ public string nickname { get { return this._nickname; } }
+
+ /**
+ * { inheritDoc}
+ */
+ public Gender gender { get; private set; }
+
+ private HashSet<Role> _roles =
+ new HashSet<Role> ((GLib.HashFunc) Role.hash,
+ (GLib.EqualFunc) Role.equal);
+
+ public DateTime birthday { get; set; }
+
+ public string calendar_event_id { get; set; }
+
+ /**
+ * { inheritDoc}
+ */
+ public HashSet<Role> roles
+ {
+ get { return this._roles; }
+ private set
+ {
+ this._roles = value;
+ this.notify_property ("roles");
+ }
+ }
+
+ private HashSet<Note> _notes =
+ new HashSet<Note> ((GLib.HashFunc) Note.hash,
+ (GLib.EqualFunc) Note.equal);
+
+ /**
+ * { inheritDoc}
+ */
+ public HashSet<Note> notes
+ {
+ get { return this._notes; }
+ private set
+ {
+ this._notes = notes;
+ this.notify_property ("notes");
+ }
+ }
+
+ private GLib.List<FieldDetails> _urls;
+ /**
+ * { inheritDoc}
+ */
+ public GLib.List<FieldDetails> urls
+ {
+ get { return this._urls; }
+ private set
+ {
+ this._urls = new GLib.List<FieldDetails> ();
+ foreach (unowned FieldDetails ps in value)
+ this._urls.prepend (ps);
+ this._urls.reverse ();
+ }
+ }
+
+ private GLib.List<PostalAddress> _postal_addresses =
+ new GLib.List<PostalAddress> ();
+ /**
+ * { inheritDoc}
+ */
+ public GLib.List<PostalAddress> postal_addresses
+ {
+ get { return this._postal_addresses; }
+ private set
+ {
+ this._postal_addresses = new GLib.List<PostalAddress> ();
+ foreach (PostalAddress pa in value)
+ this._postal_addresses.prepend (pa);
+ this._postal_addresses.reverse ();
+ this.notify_property ("postal-addresses");
+ }
+ }
+
+ private HashTable<string, HashTable<string, string>> _tracker_ids_ims =
+ new HashTable<string, HashTable<string, string>> (str_hash, str_equal);
+
+ private HashTable<string, LinkedHashSet<string>> _im_addresses =
+ new HashTable<string, LinkedHashSet<string>> (str_hash, str_equal);
+ /**
+ * { inheritDoc}
+ */
+ public HashTable<string, LinkedHashSet<string>> im_addresses
+ {
+ get { return this._im_addresses; }
+ private set {}
+ }
+
+ /**
+ * Whether this contact is a user-defined favourite.
+ */
+ public bool is_favourite { get; set; }
+
+ /**
+ * Build a IID.
+ *
+ * @param store_id the { link PersonaStore.id}
+ * @param tracker_id the tracker id belonging to nco:PersonContact
+ * @return a valid IID
+ *
+ * @since UNRELEASED
+ */
+ internal static string build_iid (string store_id, string tracker_id)
+ {
+ return "%s:%s".printf (store_id, tracker_id);
+ }
+
+ /**
+ * Create a new persona.
+ *
+ * Create a new persona for the { link PersonaStore} `store`, representing
+ * the nco:Contact whose details are stored in the cursor.
+ */
+ public Persona (PersonaStore store, string tracker_id,
+ Sparql.Cursor? cursor = null)
+ {
+ string uid = this.build_uid (BACKEND_NAME, store.id, tracker_id);
+ string iid = this.build_iid (store.id, tracker_id);
+ bool is_user = false;
+ string fullname = "";
+
+ if (cursor != null)
+ {
+ fullname = cursor.get_string (Trf.Fields.FULL_NAME).dup ();
+ var contact_urn = cursor.get_string (Trf.Fields.CONTACT_URN);
+ if (contact_urn == Trf.OntologyDefs.DEFAULT_CONTACT_URN)
+ {
+ is_user = true;
+ }
+ }
+
+ debug ("Creating new Trf.Persona with id '%s'", fullname);
+
+ Object (display_id: fullname,
+ uid: uid,
+ iid: iid,
+ store: store,
+ gender: Gender.UNSPECIFIED,
+ is_user: is_user);
+
+ this.full_name = fullname;
+ this._tracker_id = tracker_id;
+ this.structured_name = new StructuredName (null, null, null, null, null);
+
+ if (cursor != null)
+ {
+ this._cursor = cursor;
+ this._update ();
+ }
+ }
+
+ ~Persona ()
+ {
+ debug ("Destroying Trf.Persona '%s': %p", this.uid, this);
+ }
+
+ internal void _update_full_name (string? fn)
+ {
+ if (fn != null && this.full_name != fn)
+ {
+ this.full_name = fn;
+ }
+ }
+
+ internal void _update_nickname (string? nickname)
+ {
+ if (nickname != null && this._nickname != nickname)
+ {
+ this._nickname = nickname;
+ this.notify_property ("nickname");
+ }
+ }
+
+ internal void _update_family_name (string? family_name)
+ {
+ if (family_name != null)
+ {
+ this.structured_name.family_name = family_name;
+ }
+ }
+
+ internal void _update_given_name (string? given_name)
+ {
+ if (given_name != null)
+ {
+ this.structured_name.given_name = given_name;
+ }
+ }
+
+ internal void _update_additional_names (string? additional_names)
+ {
+ if (additional_names != null)
+ {
+ this.structured_name.additional_names = additional_names;
+ }
+ }
+
+ internal void _update_prefixes (string? prefixes)
+ {
+ if (prefixes != null)
+ {
+ this.structured_name.prefixes = prefixes;
+ }
+ }
+
+ internal void _update_suffixes (string? suffixes)
+ {
+ if (suffixes != null)
+ {
+ this.structured_name.suffixes = suffixes;
+ }
+ }
+
+ internal void _update ()
+ {
+ this._update_names ();
+ this._update_avatar ();
+ this._update_im_addresses ();
+ this._update_phones ();
+ this._update_email_addresses ();
+ this._update_urls ();
+ this._update_favourite ();
+ this._update_roles ();
+ this._update_bday ();
+ this._update_note ();
+ this._update_gender ();
+ this._update_postal_addresses ();
+ }
+
+ private void _update_postal_addresses ()
+ {
+ string postal_field = this._cursor.get_string
+ (Trf.Fields.POSTAL_ADDRESS).dup ();
+
+ if (postal_field == null)
+ {
+ return;
+ }
+
+ GLib.List<PostalAddress> postal_addresses =
+ new GLib.List<PostalAddress> ();
+
+ string[] addresses_a = postal_field.split ("\n");
+
+ foreach (var a in addresses_a)
+ {
+ bool address_empty = true;
+ string[] a_info = a.split ("\t");
+ for (int i = 0; i < a_info.length; i++)
+ {
+ if (a_info[i] != null && a_info[i] != "")
+ {
+ address_empty = false;
+ break;
+ }
+ }
+
+ if (address_empty)
+ continue;
+
+ GLib.List<string> types = new GLib.List<string> ();
+
+ var pa = new PostalAddress (a_info[Trf.PostalAddressFields.POBOX],
+ a_info[Trf.PostalAddressFields.EXTENDED_ADDRESS],
+ a_info[Trf.PostalAddressFields.STREET_ADDRESS],
+ a_info[Trf.PostalAddressFields.LOCALITY],
+ a_info[Trf.PostalAddressFields.REGION],
+ a_info[Trf.PostalAddressFields.POSTALCODE],
+ a_info[Trf.PostalAddressFields.COUNTRY],
+ null, (owned) types,
+ a_info[Trf.PostalAddressFields.TRACKER_ID]);
+
+ postal_addresses.prepend ((owned) pa);
+ }
+
+ postal_addresses.reverse ();
+ this.postal_addresses = (owned) postal_addresses;
+ }
+
+ internal bool _add_postal_address (PostalAddress postal_address)
+ {
+ foreach (unowned PostalAddress pa in this._postal_addresses)
+ {
+ if (postal_address.equal (pa))
+ {
+ return false;
+ }
+ }
+
+ this._postal_addresses.append (postal_address);
+ this.notify_property ("postal-addresses");
+ return true;
+ }
+
+ internal bool _remove_postal_address (string tracker_id)
+ {
+ foreach (unowned PostalAddress pa in this._postal_addresses)
+ {
+ if (pa.uid == tracker_id)
+ {
+ this._postal_addresses.remove (pa);
+ this.notify_property ("postal-addresses");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void _update_gender ()
+ {
+ string gender = this._cursor.get_string (Trf.Fields.GENDER).dup ();
+ int gender_id = 0;
+
+ if (gender != null)
+ {
+ gender_id = int.parse (gender);
+ }
+
+ this._set_gender (gender_id);
+ }
+
+ internal void _set_gender (int gender_id)
+ {
+ if (gender_id == 0)
+ {
+ this.gender = Gender.UNSPECIFIED;
+ }
+ else
+ {
+ var trf_store = (Trf.PersonaStore) this.store;
+
+ if (gender_id == trf_store.get_gender_male_id ())
+ {
+ this.gender = Gender.MALE;
+ }
+ else if (gender_id == trf_store.get_gender_female_id ())
+ {
+ this.gender = Gender.FEMALE;
+ }
+ }
+ }
+
+ private void _update_note ()
+ {
+ string note = this._cursor.get_string (Trf.Fields.NOTE).dup ();
+ this._set_note (note);
+ }
+
+ internal void _set_note (string? note_content)
+ {
+ if (note_content != null)
+ {
+ var note = new Note (note_content);
+ this._notes.add ((owned) note);
+ }
+ else
+ {
+ this._notes.clear ();
+ }
+ this.notify_property ("notes");
+ }
+
+ private void _update_bday ()
+ {
+ string bday = this._cursor.get_string (Trf.Fields.BIRTHDAY).dup ();
+ this._set_birthday (bday);
+ }
+
+ internal void _set_birthday (string? birthday)
+ {
+ if (birthday != null && birthday != "")
+ {
+ TimeVal t = TimeVal ();
+ t.from_iso8601 (birthday);
+ this.birthday = new DateTime.from_timeval_utc (t);
+ }
+ else
+ {
+ if (this.birthday != null)
+ {
+ this.birthday = null;
+ }
+ }
+ }
+
+ private void _update_roles ()
+ {
+ string roles_field = this._cursor.get_string (
+ Trf.Fields.ROLES).dup ();
+
+ if (roles_field == null)
+ {
+ return;
+ }
+
+ HashSet<Role> roles = new HashSet<Role> (
+ (GLib.HashFunc) Role.hash,
+ (GLib.EqualFunc) Role.equal);
+
+ string[] roles_a = roles_field.split ("\n");
+
+ foreach (var r in roles_a)
+ {
+ string[] r_info = r.split ("\t");
+ var tracker_id = r_info[Trf.RoleFields.TRACKER_ID];
+ var title = r_info[Trf.RoleFields.ROLE];
+ var organisation = r_info[Trf.RoleFields.DEPARTMENT];
+
+ var role = new Role (title, organisation, tracker_id);
+ roles.add (role);
+ }
+
+ this._roles = roles;
+ }
+
+ internal bool _add_role (string tracker_id, string? title, string? org)
+ {
+ var role = new Role (title, org, tracker_id);
+ if (this._roles.add (role))
+ {
+ this.notify_property ("roles");
+ return true;
+ }
+ return false;
+ }
+
+ internal bool _remove_role (string tracker_id)
+ {
+ foreach (var r in this._roles)
+ {
+ if (r.uid == tracker_id)
+ {
+ this._roles.remove (r);
+ this.notify_property ("roles");
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void _update_names ()
+ {
+ string fullname = this._cursor.get_string (Trf.Fields.FULL_NAME).dup ();
+ this._update_full_name (fullname);
+
+ string nickname = this._cursor.get_string (Trf.Fields.NICKNAME).dup ();
+ this._update_nickname (nickname);
+
+ string family_name = this._cursor.get_string (
+ Trf.Fields.FAMILY_NAME).dup ();
+ this._update_family_name (family_name);
+
+ string given_name = this._cursor.get_string (
+ Trf.Fields.GIVEN_NAME).dup ();
+ this._update_given_name (given_name);
+
+ string additional_names = this._cursor.get_string (
+ Trf.Fields.ADDITIONAL_NAMES).dup ();
+ this._update_additional_names (additional_names);
+
+ string prefixes = this._cursor.get_string (Trf.Fields.PREFIXES).dup ();
+ this._update_prefixes (prefixes);
+
+ string suffixes = this._cursor.get_string (Trf.Fields.SUFFIXES).dup ();
+ this._update_suffixes (suffixes);
+ }
+
+ private void _update_avatar ()
+ {
+ string avatar_url = this._cursor.get_string (
+ Trf.Fields.AVATAR_URL).dup ();
+ this._set_avatar (avatar_url);
+ }
+
+ internal bool _set_avatar (string? avatar_url)
+ {
+ File _avatar = null;
+ if (avatar_url != null && avatar_url != "")
+ {
+ _avatar = File.new_for_uri (avatar_url);
+ }
+ this.avatar = _avatar;
+ return true;
+ }
+
+ private void _update_im_addresses ()
+ {
+ string addresses = this._cursor.get_string (
+ Trf.Fields.IM_ADDRESSES).dup ();
+
+ if (addresses == null)
+ {
+ return;
+ }
+
+ this._im_addresses.remove_all ();
+
+ string[] addresses_a = addresses.split ("\n");
+
+ foreach (var addr in addresses_a)
+ {
+ string[] addr_info = addr.split ("\t");
+ var tracker_id = addr_info[Trf.IMFields.TRACKER_ID];
+ var proto = addr_info[Trf.IMFields.PROTO];
+ var account_id = addr_info[Trf.IMFields.ID];
+
+ this._add_im_address (tracker_id, proto, account_id, false);
+ }
+
+ this.notify_property ("im-addresses");
+ }
+
+ internal bool _add_im_address (string tracker_id, string im_proto,
+ string account_id, bool notify = true)
+ {
+ LinkedHashSet<string> im_address_array;
+
+ try
+ {
+ var account_id_copy = account_id.dup ();
+ var normalised_addr = (owned) normalise_im_address
+ ((owned) account_id_copy, im_proto);
+
+ im_address_array = this._im_addresses.lookup (im_proto);
+ if (im_address_array == null)
+ {
+ im_address_array = new LinkedHashSet<string> ();
+ im_address_array.add ((owned) normalised_addr);
+ var proto_copy = im_proto.dup ();
+ this._im_addresses.insert ((owned) proto_copy,
+ (owned) im_address_array);
+ }
+ else
+ {
+ im_address_array.add (normalised_addr);
+ }
+
+ var im_proto_hash = new HashTable<string, string> (str_hash,
+ str_equal);
+ var proto_copy_2 = im_proto.dup ();
+ var account_id_copy_2 = account_id.dup ();
+ im_proto_hash.insert ((owned) proto_copy_2,
+ (owned) account_id_copy_2);
+ var tracker_id_copy = tracker_id.dup ();
+ this._tracker_ids_ims.insert ((owned) tracker_id_copy,
+ (owned) im_proto_hash);
+
+ if (notify)
+ {
+ this.notify_property ("im-addresses");
+ }
+ }
+ catch (Folks.ImDetailsError e)
+ {
+ GLib.warning (
+ "Problem when trying to normalise address: %s\n",
+ e.message);
+ }
+
+ return true;
+ }
+
+ internal bool _remove_im_address (string tracker_id, bool notify = true)
+ {
+ var proto_im = this._tracker_ids_ims.lookup (tracker_id);
+
+ if (proto_im == null)
+ return false;
+
+ var proto = proto_im.get_keys ().nth_data (0);
+ var im_addr = proto_im.lookup (proto);
+
+ var im_list = this._im_addresses.lookup (proto);
+ if (im_list != null)
+ {
+ foreach (var addr_iter in im_list)
+ {
+ if (addr_iter == im_addr)
+ {
+ im_list.remove (im_addr);
+ this._tracker_ids_ims.remove (tracker_id);
+ if (notify)
+ {
+ this.notify_property ("im-addresses");
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private void _update_phones ()
+ {
+ string phones_field = this._cursor.get_string (Trf.Fields.PHONES).dup ();
+
+ if (phones_field == null)
+ {
+ return;
+ }
+
+ var phones = new GLib.List<FieldDetails> ();
+ string[] phones_a = phones_field.split ("\n");
+
+ foreach (var p in phones_a)
+ {
+ if (p != null && p != "")
+ {
+ string[] p_info = p.split ("\t");
+ var fd = new FieldDetails (p_info[Trf.PhoneFields.PHONE]);
+ fd.set_parameter ("tracker_id",
+ p_info[Trf.PhoneFields.TRACKER_ID]);
+ phones.prepend ((owned) fd);
+ }
+ }
+
+ phones.reverse ();
+ this.phone_numbers = phones;
+ }
+
+ internal bool _add_phone (string phone, string tracker_id)
+ {
+ bool found = false;
+
+ foreach (var p in this._phone_numbers)
+ {
+ var current_tracker_id =
+ p.get_parameter_values ("tracker_id").nth_data (0);
+ if (tracker_id == current_tracker_id)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ var fd = new FieldDetails (phone);
+ fd.set_parameter ("tracker_id", tracker_id);
+ this._phone_numbers.prepend ((owned) fd);
+ this.notify_property ("phone-numbers");
+ }
+
+ return !found;
+ }
+
+ internal bool _remove_phone (string tracker_id)
+ {
+ bool found = false;
+
+ foreach (var p in this._phone_numbers)
+ {
+ var current_tracker_id = p.get_parameter_values
+ ("tracker_id").nth_data(0);
+ if (tracker_id == current_tracker_id)
+ {
+ this._phone_numbers.remove (p);
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ {
+ this.notify_property ("phone-numbers");
+ }
+
+ return found;
+ }
+
+ internal bool _add_email (string addr, string tracker_id)
+ {
+ bool found = false;
+
+ foreach (var e in this._email_addresses)
+ {
+ var current_tracker_id =
+ e.get_parameter_values ("tracker_id").nth_data (0);
+ if (tracker_id == current_tracker_id)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ var fd = new FieldDetails (addr);
+ fd.set_parameter ("tracker_id", tracker_id);
+ this._email_addresses.prepend ((owned) fd);
+ this.notify_property ("email-addresses");
+ }
+
+ return !found;
+ }
+
+ internal bool _remove_email (string tracker_id)
+ {
+ bool found = false;
+
+ foreach (var e in this._email_addresses)
+ {
+ var current_tracker_id =
+ e.get_parameter_values ("tracker_id").nth_data(0);
+ if (tracker_id == current_tracker_id)
+ {
+ this._email_addresses.remove (e);
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ {
+ this.notify_property ("email-addresses");
+ }
+
+ return found;
+ }
+
+ private void _update_email_addresses ()
+ {
+ string emails_field = this._cursor.get_string (Trf.Fields.EMAILS).dup ();
+
+ if (emails_field == null)
+ {
+ return;
+ }
+
+ var email_addresses = new GLib.List<FieldDetails> ();
+ string[] emails_a = emails_field.split (",");
+
+ foreach (var e in emails_a)
+ {
+ if (e != null && e != "")
+ {
+ string[] id_addr = e.split ("\t");
+ var fd = new FieldDetails (id_addr[Trf.EmailFields.EMAIL]);
+ fd.set_parameter ("tracker_id",
+ id_addr[Trf.EmailFields.TRACKER_ID]);
+ email_addresses.prepend ((owned) fd);
+ }
+ }
+
+ email_addresses.reverse ();
+ this.email_addresses = email_addresses;
+ }
+
+ private void _update_urls ()
+ {
+ var urls = new GLib.List<FieldDetails> ();
+ var _urls_field = this._cursor.get_string (Trf.Fields.URLS).dup ();
+
+ if (_urls_field == null)
+ return;
+
+ string[] urls_table = _urls_field.split ("\n");
+
+ foreach (var row in urls_table)
+ {
+ string[] u = row.split ("\t");
+ var tracker_id = u[Trf.UrlsFields.TRACKER_ID];
+
+ for (int i=1; i< u.length; i++)
+ {
+ if (u[i] == null || u[i] == "")
+ continue;
+
+ string type = "";
+ switch (i)
+ {
+ case Trf.UrlsFields.BLOG:
+ type = "blog";
+ break;
+ case Trf.UrlsFields.WEBSITE:
+ type = "website";
+ break;
+ case Trf.UrlsFields.URL:
+ type = "url";
+ break;
+ }
+
+ var fd = new FieldDetails (u[i]);
+ fd.set_parameter ("tracker_id", tracker_id);
+ fd.set_parameter ("type", type);
+ urls.prepend ((owned) fd);
+ }
+ }
+
+ urls.reverse ();
+ this.urls = urls;
+ }
+
+ internal bool _add_url (string url, string tracker_id, string type = "")
+ {
+ bool found = false;
+
+ foreach (var p in this._urls)
+ {
+ var t_id = p.get_parameter_values ("tracker_id").nth_data (0);
+ if (tracker_id == t_id)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ var fd = new FieldDetails (url);
+ fd.set_parameter ("tracker_id", tracker_id);
+ fd.set_parameter ("type", type);
+ this._urls.prepend ((owned) fd);
+ this.notify_property ("urls");
+ }
+
+ return !found;
+ }
+
+ internal bool _remove_url (string tracker_id)
+ {
+ bool found = false;
+
+ foreach (var u in this._urls)
+ {
+ var current_tracker_id = u.get_parameter_values
+ ("tracker_id").nth_data(0);
+ if (tracker_id == current_tracker_id)
+ {
+ this._urls.remove (u);
+ found = true;
+ }
+ }
+
+ if (found)
+ this.notify_property ("urls");
+
+ return found;
+ }
+
+ private void _update_favourite ()
+ {
+ var favourite = this._cursor.get_string (Trf.Fields.FAVOURITE).dup ();
+
+ this.is_favourite = false;
+
+ if (favourite != null)
+ {
+ var trf_store = (Trf.PersonaStore) this.store;
+ int favorite_tracker_id = trf_store.get_favorite_id ();
+ foreach (var tag in favourite.split (","))
+ {
+ if (int.parse (tag) == favorite_tracker_id)
+ {
+ this.is_favourite = true;
+ }
+ }
+ }
+ }
+}
diff --git a/backends/tracker/lib/trf-util.vala b/backends/tracker/lib/trf-util.vala
new file mode 100644
index 0000000..5e93687
--- /dev/null
+++ b/backends/tracker/lib/trf-util.vala
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ */
+
+
+using Gee;
+using Tracker;
+using Tracker.Sparql;
+
+public struct Event
+{
+ int graph_id;
+ int subject_id;
+ int pred_id;
+ int object_id;
+}
+
+[DBus (name = "org.freedesktop.Tracker1.Resources")]
+private interface Resources : DBusProxy {
+ [DBus (name = "GraphUpdated")]
+ public signal void graph_updated
+ (string class_name, Event[] deletes, Event[] inserts);
+}
+
+internal class Trf.AfflInfo : Object
+{
+ public string im_tracker_id { get; set; }
+
+ public string im_proto { get; set; }
+
+ public string im_account_id { get; set; }
+
+ public string affl_tracker_id { get; set; }
+
+ public string title { get; set; }
+
+ public string org { get; set; }
+
+ public Folks.PostalAddress postal_address;
+
+ public string email { get; set; }
+
+ public string phone { get; set; }
+
+ public string website { get; set; }
+
+ public string blog { get; set; }
+
+ public string url { get; set; }
+
+ public string to_string ()
+ {
+ string ret = " { ";
+ bool first = true;
+ unowned ParamSpec[] properties = this.get_class ().list_properties ();
+
+ foreach (unowned ParamSpec pspec in properties)
+ {
+ var property = pspec.get_name ();
+ var prop_value = Value (pspec.value_type);
+ this.get_property (property, ref prop_value);
+ string value = prop_value.get_string ();
+
+ if (first == false)
+ ret += ", ";
+
+ ret += "%s : %s".printf (property, value);
+ first = false;
+ }
+
+ ret += " } ";
+
+ return ret;
+ }
+}
+
+public class Trf.OntologyDefs : Object
+{
+ public static const string DEFAULT_CONTACT_URN =
+ "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#default-contact-me";
+ public static const string PERSON_CLASS =
+ "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#PersonContact";
+ public static const string NCO_FULLNAME = "nco:fullname";
+ public static const string NCO_FAMILY = "nco:nameFamily";
+ public static const string NCO_GIVEN = "nco:nameGiven";
+ public static const string NCO_ADDITIONAL = "nco:nameAdditional";
+ public static const string NCO_SUFFIX = "nco:nameHonorificSuffix";
+ public static const string NCO_PREFIX = "nco:nameHonorificPrefix";
+ public static const string NCO_NICKNAME = "nco:nickname";
+ public static const string RDF_TYPE = "ns:type";
+ public static const string NCO_PERSON = "nco:PersonContact";
+ public static const string NCO_WEBSITE = "nco:websiteUrl";
+ public static const string NCO_BLOG = "nco:blogUrl";
+ public static const string NAO_FAVORITE = "nao:predefined-tag-favorite";
+ public static const string NAO_TAG = "nao:hasTag";
+ public static const string NCO_HAS_EMAIL = "nco:hasEmailAddress";
+ public static const string NCO_EMAIL = "nco:EmailAddress";
+ public static const string NCO_EMAIL_PROP = "nco:emailAddress";
+ public static const string NCO_HAS_PHONE = "nco:hasPhoneNumber";
+ public static const string NCO_PHONE = "nco:PhoneNumber";
+ public static const string NCO_PHONE_PROP = "nco:phoneNumber";
+ public static const string NCO_HAS_AFFILIATION = "nco:hasAffiliation";
+ public static const string NCO_AFFILIATION = "nco:Affiliation";
+ public static const string NCO_BIRTHDAY = "nco:birthDate";
+ public static const string NCO_NOTE = "nco:note";
+ public static const string NCO_GENDER = "nco:gender";
+ public static const string NCO_MALE = "nco:gender-male";
+ public static const string NCO_FEMALE = "nco:gender-female";
+ public static const string NCO_PHOTO = "nco:photo";
+ public static const string NIE_URL = "nie:url";
+ public static const string NFO_IMAGE = "nfo:Image";
+ public static const string NCO_IMADDRESS = "nco:IMAddress";
+ public static const string NCO_HAS_IMADDRESS = "nco:hasIMAddress";
+ public static const string NCO_IMPROTOCOL = "nco:imProtocol";
+ public static const string NCO_IMID = "nco:imID";
+ public static const string NCO_POSTAL_ADDRESS = "nco:PostalAddress";
+ public static const string NCO_URL_PREFIX =
+ "<http://www.semanticdesktop.org/ontologies/2007/03/22/";
+ public static const string NAO_URL_PREFIX =
+ "<http://www.semanticdesktop.org/ontologies/2007/08/15/";
+ public static const string RDF_URL_PREFIX =
+ "<http://www.w3.org/1999/02/";
+}
diff --git a/backends/tracker/tr-backend-factory.vala b/backends/tracker/tr-backend-factory.vala
new file mode 100644
index 0000000..c3ff71e
--- /dev/null
+++ b/backends/tracker/tr-backend-factory.vala
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
+ * Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * Travis Reitter <travis reitter collabora co uk>
+ * Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ * This file was originally part of Rygel.
+ */
+
+using Folks;
+using Folks.Backends.Tr;
+
+private BackendFactory _backend_factory = null;
+
+/**
+ * The tracker backend module entry point.
+ */
+public void module_init (BackendStore backend_store)
+{
+ _backend_factory = new BackendFactory (backend_store);
+}
+
+/**
+ * The tracker backend module exit point.
+ */
+public void module_finalize (BackendStore backend_store)
+{
+ _backend_factory = null;
+}
+
+/**
+ * A backend factory to create a single { link Backend}.
+ */
+public class Folks.Backends.Tr.BackendFactory : Object
+{
+ /**
+ * { inheritDoc}
+ */
+ public BackendFactory (BackendStore backend_store)
+ {
+ backend_store.add_backend (new Backend ());
+ }
+}
diff --git a/backends/tracker/tr-backend.vala b/backends/tracker/tr-backend.vala
new file mode 100644
index 0000000..ef98afb
--- /dev/null
+++ b/backends/tracker/tr-backend.vala
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Travis Reitter <travis reitter collabora co uk>
+ * Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ */
+
+using Folks;
+using Folks.Backends.Tr;
+using GLib;
+
+extern const string BACKEND_NAME;
+
+/**
+ * A backend which connects to Tracker and creates a { link PersonaStore}
+ * for each service.
+ */
+public class Folks.Backends.Tr.Backend : Folks.Backend
+{
+ private bool _is_prepared = false;
+ private HashTable<string, PersonaStore> _persona_stores;
+
+ /**
+ * { inheritDoc}
+ */
+ public override string name { get { return BACKEND_NAME; } }
+
+ /**
+ * { inheritDoc}
+ */
+ public override HashTable<string, PersonaStore> persona_stores
+ {
+ get { return this._persona_stores; }
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public Backend ()
+ {
+ this._persona_stores = new HashTable<string, PersonaStore>
+ (str_hash, str_equal);
+ }
+
+ /**
+ * Whether this Backend has been prepared.
+ *
+ * See { link Folks.Backend.is_prepared}.
+ */
+ public override bool is_prepared
+ {
+ get { return this._is_prepared; }
+ }
+
+ /**
+ * { inheritDoc}
+ *
+ */
+ public override async void prepare () throws GLib.Error
+ {
+ lock (this._is_prepared)
+ {
+ if (!this._is_prepared)
+ {
+ this._add_default_persona_store ();
+ this._is_prepared = true;
+ this.notify_property ("is-prepared");
+ }
+ }
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override async void unprepare () throws GLib.Error
+ {
+ this._persona_stores.foreach ((k, v) =>
+ {
+ this.persona_store_removed ((PersonaStore) v);
+ });
+
+ this._persona_stores.remove_all ();
+ this.notify_property ("persona-stores");
+
+ this._is_prepared = false;
+ this.notify_property ("is-prepared");
+ }
+
+ /**
+ * Add a the default Persona Store.
+ */
+ private void _add_default_persona_store ()
+ {
+ var store = new Trf.PersonaStore ();
+ this._persona_stores.insert (store.id, store);
+ store.removed.connect (this._store_removed_cb);
+ this.notify_property ("persona-stores");
+ this.persona_store_added (store);
+ }
+
+ private void _store_removed_cb (Folks.PersonaStore store)
+ {
+ this.persona_store_removed (store);
+ this.persona_stores.remove (store.id);
+ }
+}
diff --git a/configure.ac b/configure.ac
index 9f68dc1..15c4def 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,6 +66,14 @@ AC_SUBST([LT_AGE])
FOLKS_MAJOR_MINOR_VERSION=folks_major_minor_version
AC_SUBST([FOLKS_MAJOR_MINOR_VERSION])
+AC_ARG_ENABLE(tracker-backend,
+ AC_HELP_STRING([--enable-tracker-backend],
+ [ build the Tracker backend]),
+ enable_tracker_backend=$enableval,
+ enable_tracker_backend=no )
+
+AM_CONDITIONAL([ENABLE_TRACKER], [test "x$enable_tracker_backend" = "xyes"])
+
# -----------------------------------------------------------
# Dependencies
# -----------------------------------------------------------
@@ -74,6 +82,7 @@ GLIB_REQUIRED=2.24.0
TP_GLIB_REQUIRED=0.13.1
VALA_REQUIRED=0.11.6
VALADOC_REQUIRED=0.2.1
+TRACKER_SPARQL_REQUIRED=0.10
PKG_CHECK_MODULES([GLIB],
[glib-2.0 >= $GLIB_REQUIRED
@@ -86,6 +95,11 @@ PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1])
PKG_CHECK_MODULES([GEE], [gee-1.0 < 0.7])
PKG_CHECK_MODULES([TP_GLIB], [telepathy-glib >= $TP_GLIB_REQUIRED])
+if test x$enable_tracker_backend = xyes; then
+ PKG_CHECK_MODULES([TRACKER_SPARQL],
+ [tracker-sparql-0.10 >= $TRACKER_SPARQL_REQUIRED])
+fi
+
#
# Vala building options -- allows tarball builds without installing Vala
#
@@ -160,6 +174,10 @@ if test "x$enable_vala" = "xyes" ; then
gio-2.0
gee-1.0])
+ if test x$enable_tracker_backend = xyes; then
+ VALA_CHECK_PACKAGES([tracker-sparql-0.10])
+ fi
+
# this will set HAVE_INTROSPECTION
GOBJECT_INTROSPECTION_REQUIRE([0.9.12])
fi
@@ -186,8 +204,17 @@ AC_SUBST([BACKEND_KF])
BACKEND_TP='$(top_builddir)/backends/telepathy/.libs/libfolks-backend-telepathy.so'
AC_SUBST([BACKEND_TP])
+if test x$enable_tracker_backend = xyes; then
+ BACKEND_TRACKER='$(top_builddir)/backends/tracker/.libs/libfolks-backend-tracker.so'
+ AC_SUBST([BACKEND_TRACKER])
+fi
+
# All of the backend libraries in our tree; to be used by the tests
BACKEND_UNINST_PATH='$(BACKEND_KF):$(BACKEND_TP)'
+if test x$enable_tracker_backend = xyes; then
+ TRACKER_BACKEND_UNINST_PATH='$(BACKEND_TRACKER)'
+ BACKEND_UNINST_PATH="$BACKEND_UNINST_PATH:$TRACKER_BACKEND_UNINST_PATH"
+fi
AC_SUBST([BACKEND_UNINST_PATH])
# -----------------------------------------------------------
@@ -348,6 +375,17 @@ AC_CONFIG_FILES([
tools/inspect/Makefile
])
+if test x$enable_tracker_backend = xyes; then
+AC_CONFIG_FILES([
+ backends/tracker/lib/folks-tracker.pc
+ backends/tracker/lib/folks-tracker-uninstalled.pc
+ backends/tracker/Makefile
+ backends/tracker/lib/Makefile
+ tests/tracker/Makefile
+ tests/lib/tracker/Makefile
+])
+fi
+
AC_OUTPUT
echo "
@@ -362,6 +400,7 @@ Configure summary:
Tests.......................: ${have_tp_glib_for_tests}
Import tool.................: ${with_import_tool}
Inspector tool..............: ${with_inspect_tool}
+ Tracker backend.............: ${enable_tracker_backend}
"
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 76d6432..c10d4c5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -7,6 +7,23 @@ SUBDIRS = \
telepathy \
$(NULL)
+if ENABLE_TRACKER
+SUBDIRS += tracker
+endif
+
+DIST_SUBDIRS = \
+ data \
+ lib \
+ tools \
+ folks \
+ key-file \
+ telepathy \
+ $(NULL)
+
+if ENABLE_TRACKER
+DIST_SUBDIRS += tracker
+endif
+
TESTS_ENVIRONMENT = \
abs_top_builddir= abs_top_builddir@ \
abs_top_srcdir= abs_top_srcdir@ \
diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am
index 8f633b7..497f3bb 100644
--- a/tests/lib/Makefile.am
+++ b/tests/lib/Makefile.am
@@ -3,6 +3,19 @@ SUBDIRS = \
telepathy \
$(NULL)
+if ENABLE_TRACKER
+SUBDIRS += tracker
+endif
+
+DIST_SUBDIRS = \
+ key-file \
+ telepathy \
+ $(NULL)
+
+if ENABLE_TRACKER
+DIST_SUBDIRS += tracker
+endif
+
noinst_LTLIBRARIES = libfolks-test.la
libfolks_test_la_SOURCES = test-case.vala
diff --git a/tests/lib/tracker/Makefile.am b/tests/lib/tracker/Makefile.am
new file mode 100644
index 0000000..31cda54
--- /dev/null
+++ b/tests/lib/tracker/Makefile.am
@@ -0,0 +1,51 @@
+VALAFLAGS += \
+ --library=tracker-test \
+ --header=tracker-test.h \
+ --vapidir=$(top_srcdir)/folks \
+ --vapidir=$(top_srcdir)/backends/tracker/lib \
+ --vapidir=. \
+ --pkg gobject-2.0 \
+ --pkg gio-2.0 \
+ --pkg gee-1.0 \
+ --pkg folks \
+ --pkg tracker-sparql-0.10 \
+ --pkg folks-tracker \
+ $(NULL)
+
+noinst_LTLIBRARIES = libtracker-test.la
+
+libtracker_test_la_SOURCES = \
+ backend.vala \
+ $(NULL)
+
+libtracker_test_la_CFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GEE_CFLAGS) \
+ $(TRACKER_SPARQL_CFLAGS) \
+ -I$(top_srcdir)/folks \
+ -I$(top_srcdir)/backends/tracker/lib \
+ $(NULL)
+
+libtracker_test_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(GEE_LIBS) \
+ $(top_builddir)/folks/libfolks.la \
+ $(top_builddir)/backends/tracker/libfolks-backend-tracker.la \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ tracker-test.vapi \
+ tracker-test.h \
+ $(NULL)
+
+EXTRA_DIST = \
+ tracker-test.vapi \
+ tracker-test.h \
+ $(NULL)
+
+GITIGNOREFILES = \
+ $(libtracker_test_la_SOURCES:.vala=.c) \
+ libtracker_test_la_vala.stamp \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/tests/lib/tracker/backend.vala b/tests/lib/tracker/backend.vala
new file mode 100644
index 0000000..01a6394
--- /dev/null
+++ b/tests/lib/tracker/backend.vala
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors :Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker;
+using Tracker.Sparql;
+
+errordomain TrackerTest.BackendSetupError
+{
+ ADD_CONTACT_FAILED,
+}
+
+public class TrackerTest.Backend
+{
+ public static const string URN = "urn:contact";
+ public static const string URLS = "nco:urls";
+ public bool debug { get; set; }
+ private GLib.List<Gee.HashMap<string, string>> _contacts;
+ private Tracker.Sparql.Connection _connection;
+
+
+ public Backend ()
+ {
+ this.debug = false;
+ this._contacts = new GLib.List<Gee.HashMap<string, string>> ();
+ }
+
+ public void add_contact (Gee.HashMap<string, string> c)
+ {
+ var contact = this._copy_hash_map (c);
+ this._contacts.prepend (contact);
+ }
+
+ /* Remove contacts */
+ public void tear_down ()
+ {
+
+ }
+
+ public void reset ()
+ {
+ this._contacts = new GLib.List<Gee.HashMap<string, string>> ();
+ }
+
+ /* Insert contacts */
+ public void set_up ()
+ {
+ try
+ {
+ this._setup_connection ();
+ this._add_contacts ();
+ }
+ catch (BackendSetupError e)
+ {
+ GLib.warning ("unable to create test data: %s\n", e.message);
+ }
+ }
+
+ public bool update_contact (string contact_urn, string predicate,
+ string literal_subject)
+ {
+ const string delete_query_t = "DELETE { %s %s ?a } WHERE " +
+ "{ ?p a nco:PersonContact " +
+ " ; %s ?a . FILTER(?p = %s ) } ";
+ const string update_query_t = "INSERT { %s %s '%s' } ";
+
+ string delete_query = delete_query_t.printf (contact_urn, predicate,
+ predicate, contact_urn);
+ if (this._do_update_query (delete_query) == false)
+ {
+ GLib.warning ("Couldn't delete the old triplet");
+ return false;
+ }
+
+ string update_query = update_query_t.printf (contact_urn, predicate,
+ literal_subject);
+ if (this._do_update_query (update_query) == false)
+ {
+ GLib.warning ("Couldn't insert the triplet");
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool update_favourite (string contact_urn, bool is_favourite)
+ {
+ string q = "";
+
+ if (is_favourite)
+ {
+ q += "INSERT { ";
+ }
+ else
+ {
+ q += "DELETE { ";
+ }
+ q += contact_urn + " nao:hasTag nao:predefined-tag-favorite } ";
+
+ if (this._do_update_query (q) == false)
+ {
+ GLib.warning ("Couldn't change favourite status");
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool remove_contact (string tracker_id)
+ {
+ string delete_query = "DELETE { ?p a nco:PersonContact } ";
+ delete_query += "WHERE { ?p a nco:PersonContact . FILTER(tracker:id(?p) ";
+ delete_query += "= " + tracker_id + ") } ";
+
+ if (this._do_update_query (delete_query) == false)
+ {
+ GLib.warning ("Couldn't delete the contact");
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool remove_triplet (string subject_urn, string pred,
+ string object_urn)
+ {
+ var builder = new Tracker.Sparql.Builder.update ();
+ builder.delete_open (null);
+ builder.subject (subject_urn);
+ builder.predicate (pred);
+ builder.object (object_urn);
+ builder.delete_close ();
+
+ if (this._do_update_query (builder.result) == false)
+ {
+ GLib.warning ("Couldn't delete triplet with query: %s\n",
+ builder.result);
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool insert_triplet (string subject_iri, string pred,
+ string object_iri,
+ string? pred_b = null, string? obj_literal_b = null,
+ string? pred_c = null, string? obj_literal_c = null)
+ {
+ var builder = new Tracker.Sparql.Builder.update ();
+ builder.insert_open (null);
+ builder.subject (subject_iri);
+ builder.predicate (pred);
+ builder.object (object_iri);
+
+ if (pred_b != null)
+ {
+ builder.predicate (pred_b);
+ builder.object_string (obj_literal_b);
+ }
+
+ if (pred_c != null)
+ {
+ builder.predicate (pred_c);
+ builder.object_string (obj_literal_c);
+ }
+
+ builder.insert_close ();
+
+ if (this._do_update_query (builder.result) == false)
+ {
+ GLib.warning ("Couldn't insert triplet with query: %s\n",
+ builder.result);
+ return false;
+ }
+
+ return true;
+ }
+
+ private bool _do_update_query (string query)
+ {
+ bool ret = false;
+
+ if (this.debug)
+ {
+ GLib.stdout.printf ("_do_update_query : %s\n", query);
+ }
+
+ try
+ {
+ this._connection.update (query);
+ ret = true;
+ }
+ catch (Tracker.Sparql.Error e1)
+ {
+ GLib.warning ("Problem getting connection : %s\n", e1.message);
+ }
+ catch (GLib.IOError e2)
+ {
+ GLib.warning ("Problem saving data : %s\n", e2.message);
+ }
+ catch (GLib.DBusError e3)
+ {
+ GLib.warning ("Problem with the D-Bus connection : %s\n", e3.message);
+ }
+
+ return ret;
+ }
+
+ private Gee.HashMap<string, string> _copy_hash_map (
+ Gee.HashMap<string, string> orig)
+ {
+ Gee.HashMap<string, string> copy = new Gee.HashMap<string, string> ();
+ foreach (var k in orig.keys)
+ {
+ var v = orig.get (k);
+ copy.set (k.dup (), v.dup ());
+ }
+ return copy;
+ }
+
+ private void _setup_connection () throws BackendSetupError
+ {
+ try
+ {
+ this._connection = Tracker.Sparql.Connection.get ();
+ }
+ catch (GLib.IOError e1)
+ {
+ throw new BackendSetupError.ADD_CONTACT_FAILED
+ ("Could not connect to D-Bus service : %s\n", e1.message);
+ }
+ catch (Tracker.Sparql.Error e2)
+ {
+ throw new BackendSetupError.ADD_CONTACT_FAILED
+ ("Error fetching SPARQL connection handler : %s\n", e2.message);
+ }
+ catch (GLib.DBusError e3)
+ {
+ throw new BackendSetupError.ADD_CONTACT_FAILED
+ ("Error fetching SPARQL connection handler : %s\n", e3.message);
+ }
+ }
+
+ private void _add_contacts () throws BackendSetupError
+ {
+ string query = "";
+
+ this._contacts.reverse ();
+ foreach (var c in this._contacts)
+ {
+ query = query + "\n" + this._get_insert_query (c);
+ }
+
+ try
+ {
+ this._connection.update (query);
+ }
+ catch (Tracker.Sparql.Error e1)
+ {
+ throw new BackendSetupError.ADD_CONTACT_FAILED
+ ("Problem getting connection : %s\n", e1.message);
+ }
+ catch (GLib.IOError e2)
+ {
+ throw new BackendSetupError.ADD_CONTACT_FAILED
+ ("Error fetching SPARQL connection handler : %s\n", e2.message);
+ }
+ catch (GLib.DBusError e3)
+ {
+ throw new BackendSetupError.ADD_CONTACT_FAILED
+ ("Could not connect to D-Bus service : %s\n", e3.message);
+ }
+ }
+
+ private string _get_insert_query (Gee.HashMap<string, string> contact)
+ {
+ const string q_photo_uri_t = " . <%s> a nfo:Image, " +
+ "nie:DataObject ; nie:url '%s' ; nie:title '%s' ";
+ const string im_addr_t = " . <%s> a nco:IMAddress, " +
+ "nie:InformationElement; nco:imProtocol " +
+ "'%s' ; nco:imID '%s'; " +
+ "nco:imNickname '%s'; " +
+ "nco:imPresence nco:presence-status-available " +
+ " . <%smyimaccount> a nco:IMAccount; " +
+ "nco:imDisplayName '%s'; nco:hasIMContact " +
+ "<%s> ";
+ const string affl_t = " . <%smyaffiliation> a nco:Affiliation " +
+ " . <%smyaffiliation> nco:hasIMAddress " +
+ " <%s> ";
+ const string af_t = " . <affl:001> a nco:Affiliation; " +
+ "nco:role '%s'; nco:department '%s' ";
+ const string postal_t = " . <affl:001> a nco:Affiliation ; " +
+ "nco:hasPostalAddress <postal:001> . " +
+ " <postal:001> a nco:PostalAddress ; " +
+ "nco:pobox '%s'; " +
+ "nco:district '%s'; " +
+ "nco:county '%s'; " +
+ "nco:locality '%s'; " +
+ "nco:postalcode '%s'; " +
+ "nco:streetAddress '%s'; " +
+ "nco:addressLocation '%s'; " +
+ "nco:extendedAddress '%s'; " +
+ "nco:country '%s'; " +
+ "nco:region '%s' ";
+
+ string urn_contact;
+ if (contact.unset (this.URN, out urn_contact) == false)
+ {
+ urn_contact = "_:x";
+ }
+
+ string photo_uri = "";
+ string q = "INSERT { " + urn_contact + " a nco:PersonContact ";
+ Gee.HashMap<string, string> addresses = null;
+ string[] phones = null;
+ string[] emails = null;
+ string[] urls = null;
+ string affiliation = "";
+ string postal_address = "";
+
+ foreach (var k in contact.keys)
+ {
+ string v = contact.get (k);
+ if (k == Trf.OntologyDefs.NCO_PHOTO)
+ {
+ photo_uri = v;
+ v = "<" + v + ">";
+ }
+ else if (k == Trf.OntologyDefs.NCO_IMADDRESS)
+ {
+ addresses = this._parse_addrs (v);
+ k = "";
+ v = "";
+ foreach (var addr in addresses.keys)
+ {
+ string vtemp;
+ vtemp = " nco:hasAffiliation [ a nco:Affiliation ; ";
+ vtemp += "nco:hasIMAddress <" + addr + "> ] ";
+ if (v != "")
+ {
+ v += "; ";
+ }
+ v += vtemp;
+ }
+ }
+ else if (k == Trf.OntologyDefs.NCO_PHONE_PROP)
+ {
+ phones = v.split (",");
+ k = "";
+ v = this._build_relation (Trf.OntologyDefs.NCO_HAS_AFFILIATION,
+ phones);
+ }
+ else if (k == Trf.OntologyDefs.NCO_EMAIL_PROP)
+ {
+ emails = v.split (",");
+ k = "";
+ v = this._build_relation (Trf.OntologyDefs.NCO_HAS_AFFILIATION,
+ emails);
+ }
+ else if (k == this.URLS)
+ {
+ urls = v.split (",");
+ k = "";
+ v = this._build_relation (Trf.OntologyDefs.NCO_HAS_AFFILIATION,
+ urls);
+ }
+ else if (k == Trf.OntologyDefs.NAO_TAG)
+ {
+ v = Trf.OntologyDefs.NAO_FAVORITE;
+ }
+ else if (k == Trf.OntologyDefs.NCO_HAS_AFFILIATION)
+ {
+ affiliation = v;
+ v = "<affl:001>";
+ }
+ else if (k == Trf.OntologyDefs.NCO_GENDER)
+ {
+
+ }
+ else if (k == Trf.OntologyDefs.NCO_POSTAL_ADDRESS)
+ {
+ postal_address = v;
+ k = Trf.OntologyDefs.NCO_HAS_AFFILIATION;
+ v = "<affl:001>";
+ }
+ else
+ {
+ v = "'" + v + "'";
+ }
+
+ q += "; ";
+ string s = k + " " + v;
+ q += s;
+ }
+
+ if (photo_uri != "")
+ {
+ q += q_photo_uri_t.printf (photo_uri, photo_uri, photo_uri);
+ }
+
+ if (addresses != null && addresses.size > 0)
+ {
+ foreach (var addr in addresses.keys)
+ {
+ string proto = addresses.get (addr);
+ string q1 = im_addr_t.printf (addr, proto, addr, addr, addr,
+ addr, addr);
+
+ string q2 = affl_t.printf (addr, addr, addr);
+
+ q += "%s%s".printf (q1, q2);
+ }
+ }
+
+ if (phones != null && phones.length > 0)
+ {
+ foreach (var p in phones)
+ {
+ var phone_urn = "<phone:%s>".printf (p);
+ var affl = "<%s>".printf (p);
+ this.insert_triplet (phone_urn, "a", Trf.OntologyDefs.NCO_PHONE,
+ Trf.OntologyDefs.NCO_PHONE_PROP, p);
+ this.insert_triplet (affl, "a", Trf.OntologyDefs.NCO_AFFILIATION);
+ this.insert_triplet (affl,
+ Trf.OntologyDefs.NCO_HAS_PHONE, phone_urn);
+ }
+ }
+
+ if (emails != null && emails.length > 0)
+ {
+ foreach (var p in emails)
+ {
+ var email_urn = "<email:%s>".printf (p);
+ var affl = "<%s>".printf (p);
+ this.insert_triplet (email_urn, "a", Trf.OntologyDefs.NCO_EMAIL,
+ Trf.OntologyDefs.NCO_EMAIL_PROP, p);
+ this.insert_triplet (affl, "a", Trf.OntologyDefs.NCO_AFFILIATION);
+ this.insert_triplet (affl,
+ Trf.OntologyDefs.NCO_HAS_EMAIL, email_urn);
+ }
+ }
+
+ if (urls != null && urls.length > 0)
+ {
+ int i = 0;
+ foreach (var p in urls)
+ {
+ string website_type = "";
+ var affl = "<%s>".printf (p);
+ switch (i % 3)
+ {
+ case 0:
+ website_type = Trf.OntologyDefs.NCO_WEBSITE;
+ break;
+ case 1:
+ website_type = Trf.OntologyDefs.NCO_BLOG;
+ break;
+ case 2:
+ website_type = "nco:url";
+ break;
+ }
+
+ this.insert_triplet (affl, "a", Trf.OntologyDefs.NCO_AFFILIATION,
+ website_type, p);
+ i++;
+ }
+ }
+
+ if (affiliation != "")
+ {
+ string[] role_info = affiliation.split (",");
+ q += af_t.printf (role_info[0], role_info[1]);
+ }
+
+ if (postal_address != "")
+ {
+ string[] postal_info = postal_address.split (":");
+ q += postal_t.printf (postal_info[0], postal_info[1],
+ postal_info[2], postal_info[3], postal_info[4],
+ postal_info[5], postal_info[6], postal_info[7],
+ postal_info[8], postal_info[9]);
+ }
+
+ q += " . }";
+
+ if (this.debug)
+ {
+ GLib.stdout.printf ("_get_insert_query : %s\n", q);
+ }
+
+ return q;
+ }
+
+ private Gee.HashMap<string, string> _parse_addrs (string addr_s)
+ {
+ Gee.HashMap<string, string> ret = new Gee.HashMap<string, string> ();
+ string[] im_addrs = addr_s.split (",");
+
+ foreach (var a in im_addrs)
+ {
+ string[] info = a.split ("#");
+ string proto = info[0];
+ string addr = info[1];
+
+ ret.set ((owned) addr, (owned) proto);
+ }
+
+ return ret;
+ }
+
+ private string _build_relation (string predicate, string[] objects)
+ {
+ string ret = "";
+
+ foreach (var obj in objects)
+ {
+ string vtemp1;
+ vtemp1 = " " + predicate + " <" + obj + "> ";
+ if (ret != "")
+ {
+ ret += "; ";
+ }
+ ret += vtemp1;
+ }
+
+ return ret;
+ }
+}
\ No newline at end of file
diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am
index bb36dd2..bf328f0 100644
--- a/tests/tools/Makefile.am
+++ b/tests/tools/Makefile.am
@@ -1,5 +1,6 @@
EXTRA_DIST = \
with-session-bus.sh \
+ with-session-bus-tracker.sh \
manager-file.py \
$(NULL)
diff --git a/tests/tools/tracker.sh b/tests/tools/tracker.sh
new file mode 100644
index 0000000..f2b2eca
--- /dev/null
+++ b/tests/tools/tracker.sh
@@ -0,0 +1,34 @@
+#
+# Helper functions to start your own Tracker instance. This depends
+# on you having your own D-Bus session bus started (first).
+#
+#
+# Copyright (C) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.
+
+tracker_tmpdir=$(mktemp -d)
+
+tracker_init_settings () {
+ export XDG_DATA_HOME=$tracker_tmpdir/.local
+ export XDG_CACHE_HOME=$tracker_tmpdir/.cache
+ export XDG_CONFIG_HOME=$tracker_tmpdir/.config
+}
+
+# This should be called on INT TERM and EXIT
+tracker_cleanup () {
+ rm -rf $tracker_tmpdir
+ rm -rf $tracker_tmpdir
+}
+
+tracker_start () {
+ tracker-control -rs > /dev/null 2>&1
+}
+
+tracker_stop () {
+ tracker_cleanup
+ tracker-control -r > /dev/null 2>&1
+}
+
diff --git a/tests/tools/with-session-bus-tracker.sh b/tests/tools/with-session-bus-tracker.sh
new file mode 100755
index 0000000..e0c10b7
--- /dev/null
+++ b/tests/tools/with-session-bus-tracker.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# with-session-bus.sh - run a program with a temporary D-Bus session daemon
+#
+# interesting bits have been move into dbus to permit reusability
+#
+# Copyright (C) 2007-2008 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.
+
+
+cur_dir=`dirname $0`
+
+. $cur_dir"/dbus-session.sh"
+. $cur_dir"/tracker.sh"
+
+dbus_parse_args $@
+while test "z$1" != "z--"; do
+ shift
+done
+shift
+if test "z$1" = "z"; then dbus_usage; fi
+
+cleanup ()
+{
+ tracker_stop
+ dbus_stop
+}
+
+trap cleanup INT HUP TERM
+
+tracker_init_settings
+dbus_init 0
+
+dbus_start
+tracker_start
+
+e=0
+"$@" || e=$?
+
+trap - INT HUP TERM
+cleanup
+
+exit $e
diff --git a/tests/tracker/Makefile.am b/tests/tracker/Makefile.am
new file mode 100644
index 0000000..5793a8d
--- /dev/null
+++ b/tests/tracker/Makefile.am
@@ -0,0 +1,253 @@
+AM_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GEE_CFLAGS) \
+ $(TRACKER_SPARQL_CFLAGS) \
+ -I$(top_srcdir)/folks \
+ -I$(top_srcdir)/backends/tracker/lib \
+ -I$(top_srcdir)/tests/lib \
+ -I$(top_srcdir)/tests/lib/tracker \
+ -include $(CONFIG_HEADER) \
+ $(NULL)
+
+LDADD = \
+ $(top_builddir)/tests/lib/libfolks-test.la \
+ $(top_builddir)/tests/lib/tracker/libtracker-test.la \
+ $(top_builddir)/backends/tracker/lib/libfolks-tracker.la \
+ $(top_builddir)/folks/libfolks.la \
+ $(GLIB_LIBS) \
+ $(GEE_LIBS) \
+ $(TRACKER_SPARQL_LIBS) \
+ -L$(top_srcdir)/backends/tracker/lib \
+ $(NULL)
+
+RUN_WITH_PRIVATE_BUS = $(top_srcdir)/tests/tools/with-session-bus-tracker.sh
+
+AM_VALAFLAGS = \
+ --vapidir=. \
+ --vapidir=$(top_srcdir)/folks \
+ --vapidir=$(top_srcdir)/backends/tracker/lib \
+ --vapidir=$(top_srcdir)/tests/lib \
+ --vapidir=$(top_srcdir)/tests/lib/tracker \
+ --pkg gobject-2.0 \
+ --pkg gio-2.0 \
+ --pkg gee-1.0 \
+ --pkg folks \
+ --pkg folks-test \
+ --pkg folks-tracker \
+ --pkg tracker-sparql-0.10 \
+ --pkg tracker-test \
+ $(NULL)
+
+# in order from least to most complex
+noinst_PROGRAMS = \
+ individual-retrieval \
+ name-details-interface \
+ avatar-details-interface \
+ im-details-interface \
+ phone-details-interface \
+ email-details-interface \
+ url-details-interface \
+ favourite-details-interface \
+ fullname-updates \
+ add-contact \
+ default-contact \
+ remove-contact \
+ nickname-updates \
+ family-name-updates \
+ given-name-updates \
+ additional-names-updates \
+ prefix-name-updates \
+ suffix-name-updates \
+ website-updates \
+ favourite-updates \
+ emails-updates \
+ phones-updates \
+ imaddresses-updates \
+ role-details-interface \
+ birthday-details-interface \
+ birthday-updates \
+ note-details-interface \
+ gender-details-interface \
+ postal-address-details-interface \
+ avatar-updates \
+ $(NULL)
+
+backend_store_key_file=$(srcdir)/data/backend-tracker-only.ini
+avatar_file=$(srcdir)/data/avatar-01.jpg
+TESTS_ENVIRONMENT = \
+ GCONF_DEFAULT_SOURCE_PATH= abs_top_srcdir@/tests/data/gconf.path \
+ FOLKS_BACKEND_PATH=$(BACKEND_UNINST_PATH) \
+ FOLKS_BACKEND_STORE_KEY_FILE_PATH=$(backend_store_key_file) \
+ AVATAR_FILE_PATH=$(avatar_file) \
+ $(RUN_WITH_PRIVATE_BUS) \
+ --session \
+ --
+TESTS = $(noinst_PROGRAMS)
+
+individual_retrieval_SOURCES = \
+ individual-retrieval.vala \
+ $(NULL)
+
+name_details_interface_SOURCES = \
+ name-details-interface.vala \
+ $(NULL)
+
+avatar_details_interface_SOURCES = \
+ avatar-details-interface.vala \
+ $(NULL)
+
+im_details_interface_SOURCES = \
+ im-details-interface.vala \
+ $(NULL)
+
+phone_details_interface_SOURCES = \
+ phone-details-interface.vala \
+ $(NULL)
+
+email_details_interface_SOURCES = \
+ email-details-interface.vala \
+ $(NULL)
+
+url_details_interface_SOURCES = \
+ url-details-interface.vala \
+ $(NULL)
+
+favourite_details_interface_SOURCES = \
+ favourite-details-interface.vala \
+ $(NULL)
+
+fullname_updates_SOURCES = \
+ fullname-updates.vala \
+ $(NULL)
+
+add_contact_SOURCES = \
+ add-contact.vala \
+ $(NULL)
+
+default_contact_SOURCES = \
+ default-contact.vala \
+ $(NULL)
+
+remove_contact_SOURCES = \
+ remove-contact.vala \
+ $(NULL)
+
+nickname_updates_SOURCES = \
+ nickname-updates.vala \
+ $(NULL)
+
+family_name_updates_SOURCES = \
+ family-name-updates.vala \
+ $(NULL)
+
+given_name_updates_SOURCES = \
+ given-name-updates.vala \
+ $(NULL)
+
+additional_names_updates_SOURCES = \
+ additional-names-updates.vala \
+ $(NULL)
+
+prefix_name_updates_SOURCES = \
+ prefix-name-updates.vala \
+ $(NULL)
+
+suffix_name_updates_SOURCES = \
+ suffix-name-updates.vala \
+ $(NULL)
+
+website_updates_SOURCES = \
+ website-updates.vala \
+ $(NULL)
+
+favourite_updates_SOURCES = \
+ favourite-updates.vala \
+ $(NULL)
+
+emails_updates_SOURCES = \
+ emails-updates.vala \
+ $(NULL)
+
+phones_updates_SOURCES = \
+ phones-updates.vala \
+ $(NULL)
+
+imaddresses_updates_SOURCES = \
+ imaddresses-updates.vala \
+ $(NULL)
+
+role_details_interface_SOURCES = \
+ role-details-interface.vala \
+ $(NULL)
+
+birthday_details_interface_SOURCES = \
+ birthday-details-interface.vala \
+ $(NULL)
+
+birthday_updates_SOURCES = \
+ birthday-updates.vala \
+ $(NULL)
+
+note_details_interface_SOURCES = \
+ note-details-interface.vala \
+ $(NULL)
+
+gender_details_interface_SOURCES = \
+ gender-details-interface.vala \
+ $(NULL)
+
+postal_address_details_interface_SOURCES = \
+ postal-address-details-interface.vala \
+ $(NULL)
+
+avatar_updates_SOURCES = \
+ avatar-updates.vala \
+ $(NULL)
+
+CLEANFILES = \
+ *.pid \
+ *.address \
+ $(TESTS) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ $(addsuffix .c,$(noinst_PROGRAMS)) \
+ individual_retrieval_vala.stamp \
+ name_details_interface_vala.stamp \
+ avatar_details_interface_vala.stamp \
+ im_details_interface_vala.stamp \
+ phone_details_interface_vala.stamp \
+ email_details_interface_vala.stamp \
+ url_details_interface_vala.stamp \
+ favourite_details_interface_vala.stamp \
+ fullname_updates_vala.stamp \
+ add_contact_vala.stamp \
+ default_contact_vala.stamp \
+ remove_contact_vala.stamp \
+ nickname_updates_vala.stamp \
+ family_name_updates_vala.stamp \
+ given_name_updates_vala.stamp \
+ additional_names_updates_vala.stamp \
+ prefix_name_updates_vala.stamp \
+ suffix_name_updates_vala.stamp \
+ website_updates_vala.stamp \
+ favourite_updates_vala.stamp \
+ emails_updates_vala.stamp \
+ phones_updates_vala.stamp \
+ imaddresses_updates_vala.stamp \
+ role_details_interface_vala.stamp \
+ birthday_details_interface_vala.stamp \
+ birthday_updates_vala.stamp \
+ note_details_interface_vala.stamp \
+ gender_details_interface_vala.stamp \
+ postal_address_details_interface_vala.stamp \
+ avatar_updates_vala.stamp \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(MAINTAINERCLEANFILES) \
+ $(backend_store_key_file) \
+ $(srcdir)/data/avatar-01.jpg \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/tests/tracker/add-contact.vala b/tests/tracker/add-contact.vala
new file mode 100644
index 0000000..79ed324
--- /dev/null
+++ b/tests/tracker/add-contact.vala
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class AddContactTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private bool _contact_added;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private GLib.MainLoop _main_loop;
+
+ public AddContactTests ()
+ {
+ base ("AddContactTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test adding contacts ", this.test_add_contact);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_add_contact ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ this._persona_fullname = "persona #1";
+ this._contact_added = false;
+
+ var store = BackendStore.dup ();
+
+ this._test_add_contact_async (store, (o, r) =>
+ {
+ this._test_add_contact_async.end (r);
+ });
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+ assert (this._contact_added == true);
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_add_contact_async (BackendStore store)
+ {
+ yield store.prepare ();
+
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+
+ try
+ {
+ yield this._aggregator.prepare ();
+
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ string full_name = i.full_name;
+ i.notify["full-name"].connect (this._notify_full_name_cb);
+ if (full_name != null)
+ {
+ if (full_name == this._persona_fullname)
+ {
+ this._contact_added = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_full_name_cb ()
+ {
+ GLib.List<Individual> individuals =
+ this._aggregator.individuals.get_values ();
+ foreach (unowned Individual i in individuals)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ this._contact_added = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new AddContactTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/additional-names-updates.vala b/tests/tracker/additional-names-updates.vala
new file mode 100644
index 0000000..8a0ac9a
--- /dev/null
+++ b/tests/tracker/additional-names-updates.vala
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class AdditionalNamesUpdatesTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_additional_names_found;
+ private string _updated_additional_names;
+ private string _individual_id;
+ private GLib.MainLoop _main_loop;
+ private bool _initial_additional_names_found;
+ private string _contact_urn;
+ private string _initial_additional_names;
+
+ public AdditionalNamesUpdatesTests ()
+ {
+ base ("AdditionalNamesUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("additional names updates",
+ this.test_additional_names_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_additional_names_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ string initial_fullname = "persona #1";
+ this._initial_additional_names = "additional name #1";
+ this._updated_additional_names = "updated additional name #1";
+ this._contact_urn = "<urn:contact001>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_ADDITIONAL,
+ this._initial_additional_names);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_additional_names_found = false;
+ this._updated_additional_names_found = false;
+ this._individual_id = "";
+
+ var store = BackendStore.dup ();
+ _test_additional_names_updates_async (store);
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_additional_names_found == true);
+ assert (this._updated_additional_names_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_additional_names_updates_async (BackendStore store)
+ {
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ i.structured_name.notify["additional-names"].connect
+ (this._notify_additional_names_cb);
+ var additional_names = i.structured_name.additional_names;
+ if (additional_names == this._initial_additional_names)
+ {
+ this._individual_id = i.id;
+ this._initial_additional_names_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_ADDITIONAL,
+ this._updated_additional_names);
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_additional_names_cb ()
+ {
+ var i = this._aggregator.individuals.lookup (this._individual_id);
+
+ if (i == null)
+ return;
+
+ var additional_names = i.structured_name.additional_names;
+
+ if (additional_names == this._updated_additional_names)
+ {
+ this._updated_additional_names_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new AdditionalNamesUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/avatar-details-interface.vala b/tests/tracker/avatar-details-interface.vala
new file mode 100644
index 0000000..5fd0f33
--- /dev/null
+++ b/tests/tracker/avatar-details-interface.vala
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class AvatarDetailsInterfaceTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private string _avatar_uri;
+ private bool _avatars_are_equal;
+ private GLib.MainLoop _main_loop;
+ IndividualAggregator _aggregator;
+
+ public AvatarDetailsInterfaceTests ()
+ {
+ base ("AvatarDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test avatar details interface",
+ this.test_avatar_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_avatar_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ string avatar_path = Environment.get_variable ("AVATAR_FILE_PATH");
+ var temp_file = GLib.File.new_for_path (avatar_path);
+ var full_avatar_path = temp_file.get_path ();
+ this._avatar_uri = "file://" + full_avatar_path;
+ this._avatars_are_equal = false;
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #1");
+ c1.set (Trf.OntologyDefs.NCO_PHOTO, this._avatar_uri);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
+
+ test_avatar_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+ assert (this._avatars_are_equal);
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void test_avatar_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+
+ /* Set up the aggregator */
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = ((Folks.NameDetails) i).full_name;
+ if (full_name != null)
+ {
+ i.notify["avatar"].connect (this._notify_avatar_cb);
+ if (i.avatar != null)
+ {
+ var src_avatar = File.new_for_uri (this._avatar_uri);
+ this._avatars_are_equal =
+ this._compare_files (src_avatar, i.avatar);
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+
+ private void _notify_avatar_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual individual = (Folks.Individual) individual_obj;
+ var src_avatar = File.new_for_uri (this._avatar_uri);
+ this._avatars_are_equal = this._compare_files (src_avatar,
+ individual.avatar);
+ this._main_loop.quit ();
+ }
+
+ private bool _compare_files (File a, File b)
+ {
+ string content_a = "a";
+ string content_b = "b";
+
+ try
+ {
+ a.load_contents (null, out content_a);
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("couldn't load file a");
+ }
+
+ try
+ {
+ b.load_contents (null, out content_b);
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("couldn't load file b");
+ }
+
+ return content_a == content_b;
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new AvatarDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/avatar-updates.vala b/tests/tracker/avatar-updates.vala
new file mode 100644
index 0000000..8f77cc4
--- /dev/null
+++ b/tests/tracker/avatar-updates.vala
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class AvatarUpdatesTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_avatar_found;
+ private string _updated_avatar;
+ private string _individual_id;
+ private GLib.MainLoop _main_loop;
+ private bool _initial_avatar_found;
+ private string _initial_fullname;
+ private string _initial_avatar;
+ private string _contact_urn;
+ private string _photo_urn;
+
+ public AvatarUpdatesTests ()
+ {
+ base ("AvatarUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("avatar updates", this.test_avatar_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_avatar_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_avatar = "file:///tmp/avatar-01";
+ this._contact_urn = "<urn:contact001>";
+ this._photo_urn = "<" + this._initial_avatar + ">";
+ this._updated_avatar = "file:///tmp/avatar-02";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_PHOTO, this._initial_avatar);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_avatar_found = false;
+ this._updated_avatar_found = false;
+ this._individual_id = "";
+
+ test_avatar_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_avatar_found == true);
+ assert (this._updated_avatar_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void test_avatar_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname)
+ {
+ i.notify["avatar"].connect (this._notify_avatar_cb);
+ this._individual_id = i.id;
+
+ if (i.avatar != null &&
+ i.avatar.get_uri () == this._initial_avatar)
+ {
+ this._initial_avatar_found = true;
+
+ this._tracker_backend.remove_triplet (this._contact_urn,
+ Trf.OntologyDefs.NCO_PHOTO, this._photo_urn);
+
+ string photo_urn_2 = "<" + this._updated_avatar;
+ photo_urn_2 += ">";
+ this._tracker_backend.insert_triplet (photo_urn_2,
+ "a", "nfo:Image, nie:DataObject",
+ Trf.OntologyDefs.NIE_URL,
+ this._updated_avatar);
+
+ this._tracker_backend.insert_triplet
+ (this._contact_urn,
+ Trf.OntologyDefs.NCO_PHOTO, photo_urn_2);
+
+ }
+ }
+
+ assert (removed == null);
+ }
+ }
+
+ private void _notify_avatar_cb ()
+ {
+ var i = this._aggregator.individuals.lookup (this._individual_id);
+ if (i == null)
+ return;
+
+ if (i.avatar != null &&
+ i.avatar.get_uri () == this._updated_avatar)
+ {
+ this._main_loop.quit ();
+ this._updated_avatar_found = true;
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new AvatarUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/birthday-details-interface.vala b/tests/tracker/birthday-details-interface.vala
new file mode 100644
index 0000000..b6ab65c
--- /dev/null
+++ b/tests/tracker/birthday-details-interface.vala
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class BirthdayDetailsInterfaceTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private bool _found_birthday;
+ private DateTime _dobj;
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private string _fullname;
+
+ public BirthdayDetailsInterfaceTests ()
+ {
+ base ("BirthdayDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("test birthday details interface",
+ this.test_birthay_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_birthay_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._fullname = "persona #1";
+ string birthday = "2001-10-26T20:32:52Z";
+ TimeVal t = TimeVal ();
+ t.from_iso8601 (birthday);
+ this._dobj = new DateTime.from_timeval_utc (t);
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname);
+ c1.set (Trf.OntologyDefs.NCO_BIRTHDAY, birthday);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
+
+ this._found_birthday = false;
+
+ this._test_birthay_details_interface ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_birthday == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_birthay_details_interface ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ if (i.full_name == this._fullname)
+ {
+ i.notify["birthday"].connect (this._notify_birthday_cb);
+ if (i.birthday != null)
+ {
+ if (i.birthday.compare (this._dobj) == 0)
+ {
+ this._found_birthday = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+ assert (removed == null);
+ }
+
+ void _notify_birthday_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual individual = (Folks.Individual) individual_obj;
+ if (individual.birthday != null &&
+ individual.birthday.compare (this._dobj) == 0)
+ {
+ this._found_birthday = true;
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new BirthdayDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/birthday-updates.vala b/tests/tracker/birthday-updates.vala
new file mode 100644
index 0000000..7562970
--- /dev/null
+++ b/tests/tracker/birthday-updates.vala
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class BirthdayUpdatesTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _initial_birthday;
+ private string _updated_birthday;
+ private string _individual_id;
+ private bool _initial_birthday_found;
+ private bool _updated_birthday_found;
+ private string _contact_urn;
+ private DateTime _initial_bday_obj;
+ private DateTime _updated_bday_obj;
+ private string _initial_fullname;
+ private GLib.MainLoop _main_loop;
+
+ public BirthdayUpdatesTests ()
+ {
+ base ("BirthdayUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("birthday updates", this.test_birthday_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_birthday_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_birthday = "2001-10-26T20:32:52Z";
+ this._updated_birthday = "1991-10-26T20:32:52Z";
+ this._contact_urn = "<urn:contact001>";
+
+ TimeVal t1 = TimeVal ();
+ t1.from_iso8601 (this._initial_birthday);
+ this._initial_bday_obj = new DateTime.from_timeval_utc (t1);
+
+ TimeVal t2 = TimeVal ();
+ t2.from_iso8601 (this._updated_birthday);
+ this._updated_bday_obj = new DateTime.from_timeval_utc (t2);
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_BIRTHDAY, this._initial_birthday);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_birthday_found = false;
+ this._updated_birthday_found = false;
+ this._individual_id = "";
+
+ test_birthday_updates_async ();
+
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_birthday_found == true);
+ assert (this._updated_birthday_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void test_birthday_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ /* Set up the aggregator */
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname)
+ {
+ i.notify["birthday"].connect (this._notify_birthday_cb);
+ if (i.birthday != null &&
+ i.birthday.compare (this._initial_bday_obj) == 0)
+ {
+ this._individual_id = i.id;
+ this._initial_birthday_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_BIRTHDAY, this._updated_birthday);
+ }
+ }
+ }
+ assert (removed == null);
+ }
+
+ void _notify_birthday_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+
+ if (i.birthday == null)
+ {
+ return;
+ }
+
+ if (i.birthday.compare (this._initial_bday_obj) == 0)
+ {
+ this._individual_id = i.id;
+ this._initial_birthday_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_BIRTHDAY, this._updated_birthday);
+ }
+ else if (i.birthday.compare (this._updated_bday_obj) == 0)
+ {
+ this._updated_birthday_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new BirthdayUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/data/avatar-01.jpg b/tests/tracker/data/avatar-01.jpg
new file mode 100644
index 0000000..36e5465
Binary files /dev/null and b/tests/tracker/data/avatar-01.jpg differ
diff --git a/tests/tracker/data/backend-tracker-only.ini b/tests/tracker/data/backend-tracker-only.ini
new file mode 100644
index 0000000..c274f45
--- /dev/null
+++ b/tests/tracker/data/backend-tracker-only.ini
@@ -0,0 +1,6 @@
+[tracker]
+enabled=true
+
+[all-others]
+enabled=false
+
diff --git a/tests/tracker/default-contact.vala b/tests/tracker/default-contact.vala
new file mode 100644
index 0000000..bacd4d0
--- /dev/null
+++ b/tests/tracker/default-contact.vala
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class DefaultContactTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private bool _found_default_user;
+ private bool _found_not_user;
+ private bool _found_unknown_user;
+ private GLib.MainLoop _main_loop;
+ private string _fullname_persona;
+ private IndividualAggregator _aggregator;
+ public DefaultContactTests ()
+ {
+ base ("DefaultContactTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test default contact", this.test_default_contact);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_default_contact ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._fullname_persona = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname_persona);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._found_default_user = false;
+ this._found_not_user = false;
+ this._found_unknown_user = false;
+
+ _test_default_contact_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_default_user == true);
+ assert (this._found_not_user == true);
+ assert (this._found_unknown_user == false);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_default_contact_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = i.full_name;
+ if (full_name != null && full_name == this._fullname_persona
+ && i.is_user == false)
+ {
+ this._found_not_user = true;
+ }
+ else if (i.is_user == true)
+ {
+ this._found_default_user = true;
+ }
+ else
+ {
+ this._found_unknown_user = true;
+ }
+ }
+
+ if (this._found_not_user &&
+ this._found_default_user)
+ this._main_loop.quit ();
+
+ assert (removed == null);
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new DefaultContactTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/email-details-interface.vala b/tests/tracker/email-details-interface.vala
new file mode 100644
index 0000000..a2f3821
--- /dev/null
+++ b/tests/tracker/email-details-interface.vala
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class EmailDetailsInterfaceTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private int _num_emails;
+ private bool _found_email_1;
+ private bool _found_email_2;
+
+ public EmailDetailsInterfaceTests ()
+ {
+ base ("EmailDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test email details interface",
+ this.test_email_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_email_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #1");
+ c1.set (Trf.OntologyDefs.NCO_EMAIL_PROP,
+ "test1 example org,test2 example org");
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._num_emails = 0;
+ this._found_email_1 = false;
+ this._found_email_2 = false;
+
+ this._test_email_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._num_emails == 2);
+ assert (this._found_email_1 == true);
+ assert (this._found_email_2 == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_email_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = i.full_name;
+ if (full_name != null)
+ {
+ foreach (var email in i.email_addresses)
+ {
+ if (email.value == "test1 example org")
+ {
+ this._found_email_1 = true;
+ this._num_emails++;
+ }
+ else if (email.value == "test2 example org")
+ {
+ this._found_email_2 = true;
+ this._num_emails++;
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+
+ if (this._found_email_1 &&
+ this._found_email_2 &&
+ this._num_emails == 2)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new EmailDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/emails-updates.vala b/tests/tracker/emails-updates.vala
new file mode 100644
index 0000000..683235c
--- /dev/null
+++ b/tests/tracker/emails-updates.vala
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class EmailsUpdatesTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private GLib.MainLoop _main_loop;
+ private string _individual_id;
+ private bool _initial_email_found;
+ private string _initial_fullname_1;
+ private bool _updated_email_found;
+ private string _email_1;
+ private string _email_2;
+ private string _contact_urn_1;
+
+ public EmailsUpdatesTests ()
+ {
+ base ("EmailsUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("emails updates", this.test_emails_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_emails_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname_1 = "persona #1";
+ this._contact_urn_1 = "<urn:contact001>";
+ this._email_1 = "persona-addr-1 example org";
+ this._email_2 = "persona-addr-2 example org";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn_1);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname_1);
+ c1.set (Trf.OntologyDefs.NCO_EMAIL_PROP, this._email_1);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._individual_id = "";
+ this._initial_email_found = false;
+ this._updated_email_found = false;
+
+ this._test_emails_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_email_found == true);
+
+ bool initial_email_found_again = false;
+
+ var i = this._aggregator.individuals.lookup (this._individual_id);
+ if (i != null)
+ {
+ foreach (unowned FieldDetails fd in i.email_addresses)
+ {
+ var email = fd.value;
+ if (email == this._email_1)
+ {
+ initial_email_found_again = true;
+ }
+ }
+ }
+
+ assert (initial_email_found_again == false);
+ assert (this._updated_email_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_emails_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname_1)
+ {
+ this._individual_id = i.id;
+ i.notify["email-addresses"].connect (this._notify_email_cb);
+
+ foreach (unowned FieldDetails fd in i.email_addresses)
+ {
+ var email = fd.value;
+ if (email == this._email_1)
+ {
+ this._initial_email_found = true;
+
+ var urn_email_1 = "<" + this._email_1 + ">";
+ this._tracker_backend.remove_triplet (this._contact_urn_1,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION, urn_email_1);
+
+ var urn_email_2 = "<email:" + this._email_2 + ">";
+ this._tracker_backend.insert_triplet (urn_email_2,
+ "a", Trf.OntologyDefs.NCO_EMAIL,
+ Trf.OntologyDefs.NCO_EMAIL_PROP,
+ this._email_2);
+
+ var affl_2 = "<" + this._email_2 + ">";
+ this._tracker_backend.insert_triplet
+ (affl_2,
+ "a", Trf.OntologyDefs.NCO_AFFILIATION);
+
+ this._tracker_backend.insert_triplet
+ (affl_2,
+ Trf.OntologyDefs.NCO_HAS_EMAIL, urn_email_2);
+
+ this._tracker_backend.insert_triplet
+ (this._contact_urn_1,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION, affl_2);
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_email_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual individual = (Folks.Individual) individual_obj;
+
+ if (this._individual_id != individual.id)
+ return;
+
+ foreach (unowned FieldDetails fd in individual.email_addresses)
+ {
+ var email = fd.value;
+ if (email == this._email_2)
+ {
+ this._updated_email_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new EmailsUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/family-name-updates.vala b/tests/tracker/family-name-updates.vala
new file mode 100644
index 0000000..dbcb7ee
--- /dev/null
+++ b/tests/tracker/family-name-updates.vala
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class FamilyNameUpdatesTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private GLib.MainLoop _main_loop;
+ private bool _initial_family_name_found;
+ private bool _updated_family_name_found;
+ private string _updated_family_name;
+ private string _individual_id;
+ private string _initial_fullname;
+ private string _initial_family_name;
+ private string _contact_urn;
+
+
+ public FamilyNameUpdatesTests ()
+ {
+ base ("FamilyNameUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("family name updates", this.test_family_name_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_family_name_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_family_name = "family name #1";
+ this._updated_family_name = "updated family #1";
+ this._contact_urn = "<urn:contact001>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_FAMILY, this._initial_family_name);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_family_name_found = false;
+ this._updated_family_name_found = false;
+ this._individual_id = "";
+
+ this._test_family_name_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_family_name_found == true);
+ assert (this._updated_family_name_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_family_name_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ i.structured_name.notify["family-name"].connect
+ (this._notify_family_name_cb);
+ var family_name = i.structured_name.family_name;
+ if (family_name == this._initial_family_name)
+ {
+ this._individual_id = i.id;
+ this._initial_family_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_FAMILY, this._updated_family_name);
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_family_name_cb ()
+ {
+ var i = this._aggregator.individuals.lookup (this._individual_id);
+ if (i == null)
+ return;
+
+ var family_name = i.structured_name.family_name;
+ if (family_name == this._updated_family_name)
+ {
+ this._updated_family_name_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new FamilyNameUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/favourite-details-interface.vala b/tests/tracker/favourite-details-interface.vala
new file mode 100644
index 0000000..3994f8e
--- /dev/null
+++ b/tests/tracker/favourite-details-interface.vala
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class FavouriteDetailsInterfaceTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private GLib.MainLoop _main_loop;
+ private string _fullname_p1;
+ private string _fullname_p2;
+ private string _fullname_p3;
+ private bool _found_p1;
+ private bool _found_p2;
+ private bool _found_p3;
+ private IndividualAggregator _aggregator;
+
+ public FavouriteDetailsInterfaceTests ()
+ {
+ base ("FavouriteDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test favourite details interface",
+ this.test_favourite_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_favourite_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ Gee.HashMap<string, string> c2 = new Gee.HashMap<string, string> ();
+ Gee.HashMap<string, string> c3 = new Gee.HashMap<string, string> ();
+ this._fullname_p1 = "favourite persona #1";
+ this._fullname_p2 = "favourite persona #2";
+ this._fullname_p3 = "favourite persona #3";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname_p1);
+ c1.set (Trf.OntologyDefs.NAO_TAG, "");
+ this._tracker_backend.add_contact (c1);
+
+ c2.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname_p2);
+ c2.set (Trf.OntologyDefs.NAO_TAG, "");
+ this._tracker_backend.add_contact (c2);
+
+ c3.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname_p3);
+ this._tracker_backend.add_contact (c3);
+
+ this._tracker_backend.set_up ();
+
+ this._found_p1 = false;
+ this._found_p2 = false;
+ this._found_p3 = false;
+
+ this._test_favourite_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ return false;
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_p1 == true);
+ assert (this._found_p2 == true);
+ assert (this._found_p3 == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_favourite_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = i.full_name;
+ if (full_name != null)
+ {
+ if (full_name == this._fullname_p1)
+ {
+ assert (i.is_favourite == true);
+ this._found_p1 = true;
+ }
+ else if (full_name == this._fullname_p2)
+ {
+ assert (i.is_favourite == true);
+ this._found_p2 = true;
+ }
+ else if (full_name == this._fullname_p3)
+ {
+ assert (i.is_favourite == false);
+ this._found_p3 = true;
+ }
+ }
+ }
+
+ assert (removed == null);
+
+ if (this._found_p1 &&
+ this._found_p2 &&
+ this._found_p3)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new FavouriteDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/favourite-updates.vala b/tests/tracker/favourite-updates.vala
new file mode 100644
index 0000000..32fd628
--- /dev/null
+++ b/tests/tracker/favourite-updates.vala
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class FavouriteUpdatesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _is_favourite_1;
+ private string _individual_id_1;
+ private bool _is_favourite_2;
+ private string _individual_id_2;
+ private string _initial_fullname_1;
+ private string _contact_urn_1;
+ private string _initial_fullname_2;
+ private string _contact_urn_2;
+
+ public FavouriteUpdatesTests ()
+ {
+ base ("FavouriteUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("favourite update", this.test_favourite_update);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_favourite_update ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ Gee.HashMap<string, string> c2 = new Gee.HashMap<string, string> ();
+ this._initial_fullname_1 = "persona #1";
+ this._contact_urn_1 = "<urn:contact001>";
+ this._initial_fullname_2 = "persona #2";
+ this._contact_urn_2 = "<urn:contact002>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn_1);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname_1);
+ this._tracker_backend.add_contact (c1);
+
+ c2.set (TrackerTest.Backend.URN, this._contact_urn_2);
+ c2.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname_2);
+ c2.set (Trf.OntologyDefs.NAO_TAG, "");
+ this._tracker_backend.add_contact (c2);
+
+ this._tracker_backend.set_up ();
+
+ this._is_favourite_1 = false;
+ this._individual_id_1 = "";
+ this._is_favourite_2 = true;
+ this._individual_id_2 = "";
+
+ this._test_favourite_update_async ();
+
+ // this timer is slightly higher than usual because sleep
+ // to ensure a (usually delayed) INSERT event has happened
+ Timeout.add_seconds (7, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._is_favourite_1 == true);
+ assert (this._is_favourite_2 == false);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_favourite_update_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname_1)
+ {
+ i.notify["is-favourite"].connect
+ (this._notify_favourite_cb);
+ this._individual_id_1 = i.id;
+ this._tracker_backend.update_favourite (this._contact_urn_1,
+ true);
+ }
+ else if (i.full_name == this._initial_fullname_2)
+ {
+ i.notify["is-favourite"].connect
+ (this._notify_favourite_cb);
+ this._individual_id_2 = i.id;
+ // HACK: we need to make sure the INSERT event was delivered
+ Timeout.add_seconds (1, () =>
+ {
+ this._tracker_backend.update_favourite
+ (this._contact_urn_2, false);
+ return false;
+ });
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_favourite_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.id == this._individual_id_1)
+ {
+ this._is_favourite_1 = i.is_favourite;
+ }
+ else if (i.id == this._individual_id_2)
+ {
+ this._is_favourite_2 = i.is_favourite;
+ }
+
+ if (this._is_favourite_1 == true &&
+ this._is_favourite_2 == false)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new FavouriteUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/fullname-updates.vala b/tests/tracker/fullname-updates.vala
new file mode 100644
index 0000000..30cfd63
--- /dev/null
+++ b/tests/tracker/fullname-updates.vala
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class FullnameUpdatesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_name_found;
+ private bool _deleted_name_found;
+ private string _updated_fullname;
+ private string _individual_id;
+ private string _initial_fullname;
+ private string _contact_urn;
+ private bool _initial_name_found;
+
+ public FullnameUpdatesTests ()
+ {
+ base ("FullnameUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("fullname updates", this.test_fullname_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_fullname_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ this._initial_fullname = "persona #1";
+ this._updated_fullname = "updated persona #1";
+ this._contact_urn = "<urn:contact001>";
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_name_found = false;
+ this._updated_name_found = false;
+ this._deleted_name_found = false;
+ this._individual_id = "";
+
+ this._test_fullname_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_name_found == true);
+ assert (this._updated_name_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_fullname_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname)
+ {
+ i.notify["full-name"].connect (this._notify_full_name_cb);
+ this._individual_id = i.id;
+ this._initial_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_FULLNAME, this._updated_fullname);
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_full_name_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+
+ if (i.full_name == this._updated_fullname)
+ {
+ this._updated_name_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new FullnameUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/gender-details-interface.vala b/tests/tracker/gender-details-interface.vala
new file mode 100644
index 0000000..5644277
--- /dev/null
+++ b/tests/tracker/gender-details-interface.vala
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class GenderDetailsInterfaceTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private TrackerTest.Backend _tracker_backend;
+ private bool _found_gender;
+ private string _gender;
+ private string _fullname;
+
+ public GenderDetailsInterfaceTests ()
+ {
+ base ("GenderDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("test gender details interface",
+ this.test_gender_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_gender_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._fullname = "persona #1";
+ this._gender = Trf.OntologyDefs.NCO_MALE;
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname);
+ c1.set (Trf.OntologyDefs.NCO_GENDER, this._gender);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
+
+ this._found_gender = false;
+
+ this._test_gender_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ return false;
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_gender == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_gender_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._fullname)
+ {
+ i.notify["gender"].connect (this._notify_gender_cb);
+ if (i.gender == Gender.MALE)
+ {
+ this._found_gender = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ assert (removed == null);
+ }
+
+ void _notify_gender_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual individual = (Folks.Individual) individual_obj;
+ if (individual.gender == Gender.MALE)
+ {
+ this._found_gender = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new GenderDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/given-name-updates.vala b/tests/tracker/given-name-updates.vala
new file mode 100644
index 0000000..463fb0d
--- /dev/null
+++ b/tests/tracker/given-name-updates.vala
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class GivenNameUpdatesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_given_name_found;
+ private string _updated_given_name;
+ private string _individual_id;
+ private string _initial_fullname;
+ private string _initial_given_name;
+ private string _contact_urn;
+ private bool _initial_given_name_found;
+
+ public GivenNameUpdatesTests ()
+ {
+ base ("GivenNameUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("given name updates", this.test_given_name_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_given_name_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_given_name = "given name #1";
+ this._updated_given_name = "updated given #1";
+ this._contact_urn = "<urn:contact001>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_GIVEN, this._initial_given_name);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_given_name_found = false;
+ this._updated_given_name_found = false;
+ this._individual_id = "";
+
+ this._test_given_name_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_given_name_found == true);
+ assert (this._updated_given_name_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_given_name_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ i.structured_name.notify["given-name"].connect
+ (this._notify_given_name_cb);
+ var given_name = i.structured_name.given_name;
+ if (given_name == this._initial_given_name)
+ {
+ this._individual_id = i.id;
+ this._initial_given_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_GIVEN, this._updated_given_name);
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_given_name_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.StructuredName structured_name =
+ (Folks.StructuredName) individual_obj;
+
+ var given_name = structured_name.given_name;
+ if (given_name == this._updated_given_name)
+ {
+ this._updated_given_name_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new GivenNameUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/im-details-interface.vala b/tests/tracker/im-details-interface.vala
new file mode 100644
index 0000000..a1b6acd
--- /dev/null
+++ b/tests/tracker/im-details-interface.vala
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class ImDetailsInterfaceTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private int _num_addrs;
+ private bool _found_addr_1;
+ private bool _found_addr_2;
+ private string _fullname;
+
+ public ImDetailsInterfaceTests ()
+ {
+ base ("ImDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test im details interface",
+ this.test_im_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_im_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._fullname = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname);
+ c1.set (Trf.OntologyDefs.NCO_IMADDRESS,
+ "jabber#test1 example org,aim#test2 example org");
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._num_addrs = 0;
+ this._found_addr_1 = false;
+ this._found_addr_2 = false;
+
+ this._test_im_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._num_addrs == 2);
+ assert (this._found_addr_1 == true);
+ assert (this._found_addr_2 == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_im_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = i.full_name;
+ if (full_name == this._fullname)
+ {
+ foreach (var proto in i.im_addresses.get_keys ())
+ {
+ var addrs = i.im_addresses.lookup (proto);
+
+ if (proto == "jabber")
+ {
+ if (addrs.contains ("test1 example org"))
+ {
+ this._found_addr_1 = true;
+ this._num_addrs++;
+ }
+ }
+ else if (proto == "aim")
+ {
+ if (addrs.contains ("test2 example org"))
+ {
+ this._found_addr_2 = true;
+ this._num_addrs++;
+ }
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+
+ if (this._num_addrs == 2 &&
+ this._found_addr_1 == true &&
+ this._found_addr_2 == true)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new ImDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/imaddresses-updates.vala b/tests/tracker/imaddresses-updates.vala
new file mode 100644
index 0000000..1eb29d1
--- /dev/null
+++ b/tests/tracker/imaddresses-updates.vala
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class IMAddressesUpdatesTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private GLib.MainLoop _main_loop;
+ private string _initial_fullname_1;
+ private string _contact_urn_1;
+ private string _imaddress_proto_1;
+ private string _imaddress_1;
+ private string _imaddress_2;
+ private string _proto_2;
+ private string _individual_id;
+ private bool _initial_imaddress_found;
+ private bool _updated_imaddr_found;
+
+ public IMAddressesUpdatesTests ()
+ {
+ base ("IMAddressesUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("im addresses updates", this.test_imaddresses_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_imaddresses_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname_1 = "persona #1";
+ this._contact_urn_1 = "<urn:contact001>";
+ this._imaddress_proto_1 = "jabber#test1 example org";
+ this._imaddress_1 = "test1 example org";
+ this._imaddress_2 = "test2 example org";
+ this._proto_2 = "aim";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn_1);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname_1);
+ c1.set (Trf.OntologyDefs.NCO_IMADDRESS, this._imaddress_proto_1);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
+
+ this._individual_id = "";
+ this._initial_imaddress_found = false;
+ this._updated_imaddr_found = false;
+
+ this._test_imaddresses_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_imaddress_found == true);
+ assert (this._updated_imaddr_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_imaddresses_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname_1)
+ {
+ this._individual_id = i.id;
+
+ foreach (unowned string proto in i.im_addresses.get_keys ())
+ {
+ var addrs = i.im_addresses.lookup (proto);
+ var im_address_iter = addrs.get (0);
+ if (im_address_iter == this._imaddress_1)
+ {
+ i.notify["im-addresses"].connect (this._notify_im_cb);
+ this._initial_imaddress_found = true;
+ this._do_im_addr_update ();
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_im_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ foreach (unowned string proto in i.im_addresses.get_keys ())
+ {
+ var addrs = i.im_addresses.lookup (proto);
+ var im_address_iter = addrs.get (0);
+ if (im_address_iter == this._imaddress_2)
+ {
+ this._updated_imaddr_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+
+ private void _do_im_addr_update ()
+ {
+ var urn_affil_1 = "<" + this._imaddress_1 + "myaffiliation>";
+ this._tracker_backend.remove_triplet (this._contact_urn_1,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION, urn_affil_1);
+
+ var urn_imaddr_2 = "<" + this._imaddress_2 + ">";
+ this._tracker_backend.insert_triplet
+ (urn_imaddr_2,
+ "a", Trf.OntologyDefs.NCO_IMADDRESS,
+ Trf.OntologyDefs.NCO_IMPROTOCOL, this._proto_2,
+ Trf.OntologyDefs.NCO_IMID, this._imaddress_2);
+
+ var urn_affil_2 = "<" + this._imaddress_2;
+ urn_affil_2 += "myaffiliation>";
+ this._tracker_backend.insert_triplet
+ (urn_affil_2,
+ "a", Trf.OntologyDefs.NCO_AFFILIATION);
+
+ this._tracker_backend.insert_triplet
+ (urn_affil_2,
+ Trf.OntologyDefs.NCO_HAS_IMADDRESS, urn_imaddr_2);
+
+ this._tracker_backend.insert_triplet
+ (this._contact_urn_1,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION, urn_affil_2);
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new IMAddressesUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/individual-retrieval.vala b/tests/tracker/individual-retrieval.vala
new file mode 100644
index 0000000..41f80bf
--- /dev/null
+++ b/tests/tracker/individual-retrieval.vala
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class IndividualRetrievalTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private TrackerTest.Backend _tracker_backend;
+ private Gee.HashMap<string, string> _c1;
+ private Gee.HashMap<string, string> _c2;
+
+ public IndividualRetrievalTests ()
+ {
+ base ("IndividualRetrieval");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("singleton individuals", this.test_singleton_individuals);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_singleton_individuals ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ this._c1 = new Gee.HashMap<string, string> ();
+ this._c2 = new Gee.HashMap<string, string> ();
+
+ this._c1.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #1");
+ this._tracker_backend.add_contact (this._c1);
+ this._c2.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #2");
+ this._tracker_backend.add_contact (this._c2);
+ this._tracker_backend.set_up ();
+
+ this._test_singleton_individuals_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._c1.size == 0);
+ assert (this._c2.size == 0);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_singleton_individuals_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = ((Folks.NameDetails) i).full_name;
+ if (full_name != null)
+ {
+ if (this._c1.get (Trf.OntologyDefs.NCO_FULLNAME) == full_name)
+ {
+ this._c1.unset (Trf.OntologyDefs.NCO_FULLNAME);
+ }
+
+ if (this._c2.get (Trf.OntologyDefs.NCO_FULLNAME) == full_name)
+ {
+ this._c2.unset (Trf.OntologyDefs.NCO_FULLNAME);
+ }
+ }
+ }
+
+ if (this._c1.size == 0 &&
+ this._c2.size == 0)
+ this._main_loop.quit ();
+
+ assert (removed == null);
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new IndividualRetrievalTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/name-details-interface.vala b/tests/tracker/name-details-interface.vala
new file mode 100644
index 0000000..0aa6eb5
--- /dev/null
+++ b/tests/tracker/name-details-interface.vala
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class NameDetailsInterfaceTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private GLib.MainLoop _main_loop;
+ private Gee.HashMap<string, string> _c1;
+ private Gee.HashMap<string, string> _c2;
+
+ public NameDetailsInterfaceTests ()
+ {
+ base ("NameDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test name details interface",
+ this.test_name_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_name_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ this._c1 = new Gee.HashMap<string, string> ();
+ this._c2 = new Gee.HashMap<string, string> ();
+
+ this._c1.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #1");
+ this._c1.set (Trf.OntologyDefs.NCO_NICKNAME, "p #1");
+ this._c1.set (Trf.OntologyDefs.NCO_FAMILY, "p #1 Family");
+ this._c1.set (Trf.OntologyDefs.NCO_GIVEN, "p #1 Given");
+ this._c1.set (Trf.OntologyDefs.NCO_ADDITIONAL, "p #1 Additional");
+ this._c1.set (Trf.OntologyDefs.NCO_PREFIX, "Mr");
+ this._c1.set (Trf.OntologyDefs.NCO_SUFFIX, "Jr");
+ this._tracker_backend.add_contact (this._c1);
+
+ this._c2.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #2");
+ this._c2.set (Trf.OntologyDefs.NCO_NICKNAME, "p #2");
+ this._tracker_backend.add_contact (this._c2);
+
+ this._tracker_backend.set_up ();
+
+ this._test_name_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._c1.size == 0);
+ assert (this._c2.size == 0);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_name_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = ((Folks.NameDetails) i).full_name;
+ if (full_name != null)
+ {
+ StructuredName sname =
+ ((Folks.NameDetails) i).structured_name;
+
+ if (full_name == "persona #1")
+ {
+ this._c1.unset (Trf.OntologyDefs.NCO_FULLNAME);
+
+ string nickname = ((Folks.NameDetails) i).nickname;
+ assert (this._c1.get (Trf.OntologyDefs.NCO_NICKNAME) ==
+ nickname);
+ this._c1.unset (Trf.OntologyDefs.NCO_NICKNAME);
+
+ string family = sname.family_name ;
+ assert (this._c1.get (Trf.OntologyDefs.NCO_FAMILY) ==
+ family);
+ this._c1.unset (Trf.OntologyDefs.NCO_FAMILY);
+
+ string given = sname.given_name;
+ assert (this._c1.get (Trf.OntologyDefs.NCO_GIVEN) == given);
+ this._c1.unset (Trf.OntologyDefs.NCO_GIVEN);
+
+ string additional = sname.additional_names;
+ assert (this._c1.get (Trf.OntologyDefs.NCO_ADDITIONAL) ==
+ additional);
+ this._c1.unset (Trf.OntologyDefs.NCO_ADDITIONAL);
+
+ string prefix = sname.prefixes;
+ assert (this._c1.get (Trf.OntologyDefs.NCO_PREFIX) ==
+ prefix);
+ this._c1.unset (Trf.OntologyDefs.NCO_PREFIX);
+
+ string suffix = sname.suffixes;
+ assert (this._c1.get (Trf.OntologyDefs.NCO_SUFFIX) ==
+ suffix);
+ this._c1.unset (Trf.OntologyDefs.NCO_SUFFIX);
+
+ assert (sname.is_empty () == false);
+ }
+ else if (full_name == "persona #2")
+ {
+ this._c2.unset (Trf.OntologyDefs.NCO_FULLNAME);
+
+ string nickname = ((Folks.NameDetails) i).nickname;
+ assert (this._c2.get (Trf.OntologyDefs.NCO_NICKNAME) ==
+ nickname);
+ this._c2.unset (Trf.OntologyDefs.NCO_NICKNAME);
+
+ assert (sname.is_empty () == true);
+ }
+ }
+ }
+
+ assert (removed == null);
+
+ if (this._c1.size == 0 &&
+ this._c2.size == 0)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new NameDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/nickname-updates.vala b/tests/tracker/nickname-updates.vala
new file mode 100644
index 0000000..e3e39d4
--- /dev/null
+++ b/tests/tracker/nickname-updates.vala
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class NicknameUpdatesTests : Folks.TestCase
+{
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_nickname_found;
+ private bool _initial_nickname_found = false;
+ private string _updated_nickname;
+ private string _individual_id;
+ private GLib.MainLoop _main_loop;
+ private string _initial_fullname;
+ private string _initial_nickname;
+ private string _contact_urn;
+
+ public NicknameUpdatesTests ()
+ {
+ base ("NicknameUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("nickname updates", this.test_nickname_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_nickname_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_nickname = "nickname #1";
+ this._updated_nickname = "updated nickname #1";
+ this._contact_urn = "<urn:contact001>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_NICKNAME, this._initial_nickname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_nickname_found = false;
+ this._updated_nickname_found = false;
+ this._individual_id = "";
+
+ this._test_nickname_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_nickname_found == true);
+ assert (this._updated_nickname_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_nickname_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.nickname == this._initial_nickname)
+ {
+ i.notify["nickname"].connect (this._notify_nickname_cb);
+ this._individual_id = i.id;
+ this._initial_nickname_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_NICKNAME, this._updated_nickname);
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_nickname_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.nickname == this._updated_nickname)
+ {
+ this._updated_nickname_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new NicknameUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/note-details-interface.vala b/tests/tracker/note-details-interface.vala
new file mode 100644
index 0000000..da8ec55
--- /dev/null
+++ b/tests/tracker/note-details-interface.vala
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class NoteDetailsInterfaceTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private TrackerTest.Backend _tracker_backend;
+ private bool _found_note;
+ private string _note;
+ private string _fullname = "persona #1";
+
+ public NoteDetailsInterfaceTests ()
+ {
+ base ("NoteDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("test note details interface",
+ this.test_note_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_note_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._fullname = "persona #1";
+ this._note = "this is a note";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname);
+ c1.set (Trf.OntologyDefs.NCO_NOTE, this._note);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._found_note = false;
+
+ this._test_note_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_note == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_note_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._fullname)
+ {
+ i.notify["notes"].connect (this._notify_note_cb);
+ foreach (var n in i.notes)
+ {
+ if (n.content == this._note)
+ {
+ this._found_note = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ void _notify_note_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual individual = (Folks.Individual) individual_obj;
+ foreach (var n in individual.notes)
+ {
+ if (n.content == this._note)
+ {
+ this._found_note = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new NoteDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/phone-details-interface.vala b/tests/tracker/phone-details-interface.vala
new file mode 100644
index 0000000..e37cc2c
--- /dev/null
+++ b/tests/tracker/phone-details-interface.vala
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class PhoneDetailsInterfaceTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private TrackerTest.Backend _tracker_backend;
+ private int _num_phones = 0;
+ private bool _found_phone_1 = false;
+ private bool _found_phone_2 = false;
+
+ public PhoneDetailsInterfaceTests ()
+ {
+ base ("PhoneDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test phone details interface",
+ this.test_phone_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_phone_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #1");
+ c1.set (Trf.OntologyDefs.NCO_PHONE_PROP, "12345,54321");
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._num_phones = 0;
+ this._found_phone_1 = false;
+ this._found_phone_2 = false;
+
+ this._test_phone_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._num_phones == 2);
+ assert (this._found_phone_1 == true);
+ assert (this._found_phone_2 == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_phone_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = i.full_name;
+ if (full_name != null)
+ {
+ foreach (var phone in i.phone_numbers)
+ {
+ if (phone.value == "12345")
+ {
+ this._found_phone_1 = true;
+ this._num_phones++;
+ }
+ else if (phone.value == "54321")
+ {
+ this._found_phone_2 = true;
+ this._num_phones++;
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+
+ if (this._num_phones == 2 &&
+ this._found_phone_1 == true &&
+ this._found_phone_2 == true)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new PhoneDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/phones-updates.vala b/tests/tracker/phones-updates.vala
new file mode 100644
index 0000000..c2113d6
--- /dev/null
+++ b/tests/tracker/phones-updates.vala
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class PhonesUpdatesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _initial_fullname_1;
+ private string _contact_urn_1;
+ private string _phone_1;
+ private string _phone_2;
+ private string _individual_id;
+ private bool _initial_phone_found;
+ private bool _initial_phone_found_again;
+ private bool _updated_phone_found;
+
+ public PhonesUpdatesTests ()
+ {
+ base ("PhonesUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("phones updates", this.test_phones_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_phones_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname_1 = "persona #1";
+ this._contact_urn_1 = "<urn:contact001>";
+ this._phone_1 = "12345";
+ this._phone_2 = "54321";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn_1);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname_1);
+ c1.set (Trf.OntologyDefs.NCO_PHONE_PROP, this._phone_1);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._individual_id = "";
+ this._initial_phone_found = false;
+ this._initial_phone_found_again = false;
+ this._updated_phone_found = false;
+
+ this._test_phones_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_phone_found == true);
+ assert (this._initial_phone_found_again == false);
+ assert (this._updated_phone_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_phones_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname_1)
+ {
+ this._individual_id = i.id;
+
+ i.notify["phone-numbers"].connect (this._notify_phones_cb);
+
+ foreach (unowned FieldDetails fd in i.phone_numbers)
+ {
+ var phone = fd.value;
+ if (phone == this._phone_1)
+ {
+ this._initial_phone_found = true;
+ this._update_phone ();
+ }
+ }
+ }
+ }
+ assert (removed == null);
+ }
+
+ private void _notify_phones_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ foreach (unowned FieldDetails fd in i.phone_numbers)
+ {
+ var phone = fd.value;
+ if (phone == this._phone_1)
+ {
+ this._initial_phone_found_again = true;
+ }
+ if (phone == this._phone_2)
+ {
+ this._updated_phone_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+
+ private void _update_phone ()
+ {
+ var urn_phone_1 = "<" + this._phone_1 + ">";
+ this._tracker_backend.remove_triplet (this._contact_urn_1,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION, urn_phone_1);
+
+ var urn_phone_2 = "<phone:" + this._phone_2 + ">";
+ this._tracker_backend.insert_triplet (urn_phone_2,
+ "a", Trf.OntologyDefs.NCO_PHONE,
+ Trf.OntologyDefs.NCO_PHONE_PROP,
+ this._phone_2);
+
+ var affl_2 = "<" + this._phone_2 + ">";
+ this._tracker_backend.insert_triplet
+ (affl_2,
+ "a", Trf.OntologyDefs.NCO_AFFILIATION);
+ this._tracker_backend.insert_triplet
+ (affl_2,
+ Trf.OntologyDefs.NCO_HAS_PHONE, urn_phone_2);
+
+ this._tracker_backend.insert_triplet
+ (this._contact_urn_1,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION, affl_2);
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new PhonesUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/postal-address-details-interface.vala b/tests/tracker/postal-address-details-interface.vala
new file mode 100644
index 0000000..8b9d023
--- /dev/null
+++ b/tests/tracker/postal-address-details-interface.vala
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class PostalAddressDetailsInterfaceTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private TrackerTest.Backend _tracker_backend;
+ private string _pobox = "12345";
+ private string _district = "example district";
+ private string _county = "example country";
+ private string _locality = "example locality";
+ private string _postalcode = "example postalcode";
+ private string _street = "example street";
+ private string _address = "example address";
+ private string _extended = "example extended address";
+ private string _country = "example country";
+ private string _region = "example region";
+ private PostalAddress _postal_address;
+ private bool _found_postal_address;
+ private string _fullname;
+
+ public PostalAddressDetailsInterfaceTests ()
+ {
+ base ("PostalAddressDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test postal address details interface",
+ this.test_postal_address_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_postal_address_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._fullname = "persona #1";
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname);
+
+ GLib.List<string> types = new GLib.List<string> ();
+ this._postal_address = new PostalAddress (
+ this._pobox,
+ this._extended,
+ this._street,
+ this._locality,
+ this._region,
+ this._postalcode,
+ this._country,
+ null, types, "tracker_id");
+
+ // nco:pobox, nco:district, nco:county, nco:locality, nco:postalcode,
+ // nco:streetAddress
+ // nco:addressLocation, nco:extendedAddress, nco:country, nco:region
+ string postal_info = this._pobox + ":";
+ postal_info += this._district + ":";
+ postal_info += this._county + ":";
+ postal_info += this._locality + ":";
+ postal_info += this._postalcode + ":";
+ postal_info += this._street + ":";
+ postal_info += this._address + ":";
+ postal_info += this._extended + ":";
+ postal_info += this._country + ":";
+ postal_info += this._region;
+
+ c1.set (Trf.OntologyDefs.NCO_POSTAL_ADDRESS, postal_info);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
+
+ this._found_postal_address = false;
+
+ this._test_postal_address_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_postal_address == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_postal_address_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ if (i.full_name == this._fullname)
+ {
+ foreach (var p in i.postal_addresses)
+ {
+ /* We copy the tracker_id - we don't know it.
+ * Although we could get it from the 1st
+ * personas iid; there is no real need.
+ */
+ this._postal_address.uid = p.uid;
+
+ if (p.equal (this._postal_address))
+ {
+ this._found_postal_address = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new PostalAddressDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/prefix-name-updates.vala b/tests/tracker/prefix-name-updates.vala
new file mode 100644
index 0000000..c547c94
--- /dev/null
+++ b/tests/tracker/prefix-name-updates.vala
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class PrefixNameUpdatesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_prefix_name_found;
+ private bool _initial_prefix_name_found;
+ private string _updated_prefix_name;
+ private string _individual_id;
+ private string _initial_fullname;
+ private string _initial_prefix_name;
+ private string _contact_urn;
+
+ public PrefixNameUpdatesTests ()
+ {
+ base ("PrefixNameUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("prefix name updates", this.test_prefix_name_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_prefix_name_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_prefix_name = "prefix name #1";
+ this._updated_prefix_name = "updated prefix #1";
+ this._contact_urn = "<urn:contact001>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_PREFIX, this._initial_prefix_name);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_prefix_name_found = false;
+ this._updated_prefix_name_found = false;
+ this._individual_id = "";
+
+ this._test_prefix_name_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_prefix_name_found == true);
+ assert (this._updated_prefix_name_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_prefix_name_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ var prefix_name = i.structured_name.prefixes;
+ if (prefix_name == this._initial_prefix_name)
+ {
+ i.structured_name.notify["prefixes"].connect
+ (this._notify_prefix_name_cb);
+ this._individual_id = i.id;
+ this._initial_prefix_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_PREFIX, this._updated_prefix_name);
+ }
+ }
+ assert (removed == null);
+ }
+
+ private void _notify_prefix_name_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.StructuredName sname = (Folks.StructuredName) individual_obj;
+ var prefix_name = sname.prefixes;
+ if (prefix_name == this._updated_prefix_name)
+ {
+ this._updated_prefix_name_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new PrefixNameUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/remove-contact.vala b/tests/tracker/remove-contact.vala
new file mode 100644
index 0000000..b94379c
--- /dev/null
+++ b/tests/tracker/remove-contact.vala
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class RemoveContactTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _contact_added;
+ private bool _contact_removed;
+ private string _individual_id;
+ private string _persona_fullname;
+
+ public RemoveContactTests ()
+ {
+ base ("RemoveContactTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test removing contacts ", this.test_remove_contact);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_remove_contact ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ this._persona_fullname = "persona #1";
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
+
+ this._contact_added = false;
+ this._contact_removed = false;
+ this._individual_id = "";
+
+ this._test_remove_contact_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._contact_added == true);
+ assert (this._contact_removed == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_remove_contact_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ string full_name = i.full_name;
+ if (full_name == this._persona_fullname)
+ {
+ this._contact_added = true;
+ this._individual_id = i.id;
+ var contact_id = i.personas.nth_data (0).iid.split (":")[1];
+ this._tracker_backend.remove_contact (contact_id);
+ }
+ }
+
+ foreach (unowned Individual i in added)
+ {
+ if (i.id == this._individual_id)
+ {
+ this._contact_removed = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new RemoveContactTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/role-details-interface.vala b/tests/tracker/role-details-interface.vala
new file mode 100644
index 0000000..ebe9c1a
--- /dev/null
+++ b/tests/tracker/role-details-interface.vala
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class RoleDetailsInterfaceTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private TrackerTest.Backend _tracker_backend;
+ private bool _found_role;
+ private string _fullname;
+ private string _affiliaton;
+
+ public RoleDetailsInterfaceTests ()
+ {
+ base ("RoleDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("test role details interface",
+ this.test_role_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_role_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._fullname = "persona #1";
+ this._affiliaton = "boss,Company";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._fullname);
+ c1.set (Trf.OntologyDefs.NCO_HAS_AFFILIATION, this._affiliaton);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._found_role = false;
+
+ this._test_role_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_role == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_role_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ if (i.full_name == this._fullname)
+ {
+ foreach (var role in i.roles)
+ {
+ if (role.title == "boss" &&
+ role.organisation_name == "Company")
+ {
+ this._found_role = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new RoleDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/suffix-name-updates.vala b/tests/tracker/suffix-name-updates.vala
new file mode 100644
index 0000000..0696567
--- /dev/null
+++ b/tests/tracker/suffix-name-updates.vala
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SuffixNameUpdatesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_suffix_name_found;
+ private bool _deleted_suffix_name_found;
+ private bool _initial_suffix_name_found;
+ private string _updated_suffix_name;
+ private string _individual_id;
+ private string _initial_fullname;
+ private string _initial_suffix_name;
+ private string _contact_urn;
+
+ public SuffixNameUpdatesTests ()
+ {
+ base ("SuffixNameUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("suffix name updates", this.test_suffix_name_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_suffix_name_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_suffix_name = "suffix name #1";
+ this._updated_suffix_name = "updated suffix #1";
+ this._contact_urn = "<urn:contact001>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_SUFFIX, this._initial_suffix_name);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_suffix_name_found = false;
+ this._updated_suffix_name_found = false;
+ this._deleted_suffix_name_found = false;
+ this._individual_id = "";
+
+ this._test_suffix_name_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_suffix_name_found == true);
+ assert (this._updated_suffix_name_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_suffix_name_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ var suffix_name = i.structured_name.suffixes;
+ if (suffix_name == this._initial_suffix_name)
+ {
+ i.structured_name.notify["suffixes"].connect
+ (this._notify_suffix_name_cb);
+ this._individual_id = i.id;
+ this._initial_suffix_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_SUFFIX, this._updated_suffix_name);
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_suffix_name_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.StructuredName sname = (Folks.StructuredName) individual_obj;
+ var suffix_name = sname.suffixes;
+ if (suffix_name == this._updated_suffix_name)
+ {
+ this._updated_suffix_name_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SuffixNameUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/url-details-interface.vala b/tests/tracker/url-details-interface.vala
new file mode 100644
index 0000000..0d17caf
--- /dev/null
+++ b/tests/tracker/url-details-interface.vala
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class UrlDetailsInterfaceTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private IndividualAggregator _aggregator;
+ private TrackerTest.Backend _tracker_backend;
+ private string _blog_url;
+ private string _website_url;
+ private string _urls;
+ private bool _found_blog;
+ private bool _found_website;
+
+ public UrlDetailsInterfaceTests ()
+ {
+ base ("UrlDetailsInterfaceTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("test url details interface",
+ this.test_url_details_interface);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_url_details_interface ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._blog_url = "http://blog.example.org";
+ this._website_url = "http://www.example.org";
+ this._urls = "%s,%s".printf (this._blog_url, this._website_url);
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #1");
+ c1.set (TrackerTest.Backend.URLS, this._urls);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._found_blog = false;
+ this._found_website = false;
+
+ this._test_url_details_interface_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_blog == true);
+ assert (this._found_website == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_url_details_interface_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (Individual i in added)
+ {
+ string full_name = i.full_name;
+ if (full_name != null)
+ {
+ foreach (var url in i.urls)
+ {
+ if (url.value == this._blog_url)
+ {
+ this._found_blog = true;
+ }
+ else if (url.value == this._website_url)
+ {
+ this._found_website = true;
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+
+ if (this._found_blog &&
+ this._found_website)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new UrlDetailsInterfaceTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/website-updates.vala b/tests/tracker/website-updates.vala
new file mode 100644
index 0000000..d7689d8
--- /dev/null
+++ b/tests/tracker/website-updates.vala
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class WebsiteUpdatesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private bool _updated_website_found;
+ private bool _deleted_website_found;
+ private bool _initial_website_found;
+ private string _updated_website;
+ private string _individual_id;
+ private string _initial_fullname;
+ private string _initial_website;
+ private string _contact_urn;
+
+ public WebsiteUpdatesTests ()
+ {
+ base ("WebsiteUpdates");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+ this._tracker_backend.debug = false;
+
+ this.add_test ("websites updates", this.test_website_updates);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_website_updates ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._initial_fullname = "persona #1";
+ this._initial_website = "www.example1.org";
+ this._updated_website = "www.example2.org";
+ this._contact_urn = "<urn:contact001>";
+
+ c1.set (TrackerTest.Backend.URN, this._contact_urn);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
+ c1.set (TrackerTest.Backend.URLS, this._initial_website);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_website_found = false;
+ this._updated_website_found = false;
+ this._deleted_website_found = false;
+ this._individual_id = "";
+
+ this._test_website_updates_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_website_found == true);
+ assert (this._updated_website_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_website_updates_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._initial_fullname)
+ {
+ i.notify["urls"].connect
+ (this._notify_website_cb);
+
+ this._individual_id = i.id;
+
+ foreach (unowned FieldDetails fd in i.urls)
+ {
+ var website = fd.value;
+ if (website == this._initial_website)
+ {
+ this._initial_website_found = true;
+ string affl = "<affl:website>";
+ this._tracker_backend.insert_triplet (affl,
+ "a", Trf.OntologyDefs.NCO_AFFILIATION,
+ Trf.OntologyDefs.NCO_WEBSITE, this._updated_website);
+ this._tracker_backend.insert_triplet (this._contact_urn,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION,
+ affl);
+ }
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_website_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+
+ foreach (unowned FieldDetails fd in i.urls)
+ {
+ var website = fd.value;
+ if (website == this._updated_website)
+ {
+ this._updated_website_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new WebsiteUpdatesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]