/*
 * libsyncml - A syncml protocol implementation
 * Copyright (C) 2009  Michael Bell <michael.bell@opensync.org>
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 */

#include "tests/support.h"

#include <libsyncml/dev_inf_api/sml_dev_inf_data_store.h>

START_TEST (dev_inf_data_store_create)
{
	setup_testbed(NULL);

	GError *error = NULL;
	SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new(NULL, &error);
	sml_fail_unless(datastore == NULL, "The source reference must be set.");
	sml_fail_unless(error != NULL, "The error must be set on failure.");
	g_error_free(error);
	error = NULL;

	datastore = sml_dev_inf_data_store_new("contacts", &error);
	sml_fail_unless(datastore != NULL, "%s", error?error->message:"No GError set.");
	g_object_unref(datastore);
}
END_TEST

START_TEST (dev_inf_data_store_empty_set)
{
	setup_testbed(NULL);

	GError *error = NULL;
	SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error);
	sml_fail_unless(datastore != NULL, NULL);

	/* enforce SourceRef name */

	sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, "", &error) == FALSE, "A data store must have a SourceRef.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* the following parameters can be NULL or 0 */

	sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, NULL, &error), "%s", error?error->message:"No GError set.");
	sml_dev_inf_data_store_set_max_guid_size(datastore, 0);
	sml_dev_inf_data_store_set_max_id(datastore, 0);
	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, TRUE);
	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, FALSE);

	/* The unknown SyncCap removes all configured SyncCaps. */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE);
	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE);

	/* RxPref/TxPref must be set */

	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, NULL, &error) == FALSE, "A data store must have a RxPref.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, NULL, &error) == FALSE, "A data store must have a TxPref.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* Rx/Tx does not accept empty values */

	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	g_object_unref(datastore);
}
END_TEST

START_TEST (dev_inf_data_store_empty_get)
{
	setup_testbed(NULL);

	GError *error = NULL;
	SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error);
	sml_fail_unless(datastore != NULL, NULL);

	SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error);
	sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set.");

	/* enforce SourceRef name */

	sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	const gchar *source_ref = sml_dev_inf_data_store_get_source_ref(datastore);
	sml_fail_unless(source_ref != NULL, "The SourceRef must always be available.");
	sml_fail_unless(strcmp(source_ref, "Contacts") == 0, "The original SourceRef was damaged.");

	/* the following parameters can be NULL or 0 */

	sml_fail_unless(sml_dev_inf_data_store_get_display_name(datastore) == NULL, "The default display name is empty.");
	sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, NULL, &error), "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_get_display_name(datastore) == NULL, "The default display name was overwritten.");

	sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 0, "The default MaxGUIDSize is 0.");
	sml_dev_inf_data_store_set_max_guid_size(datastore, 0);
	sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 0, "The default MaxGUIDSize was overwritten");

	sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 0, "The default MaxID is 0.");
	sml_dev_inf_data_store_set_max_id(datastore, 0);
	sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 0, "The default MaxID was overwritten");

	sml_fail_unless(sml_dev_inf_data_store_get_support_hierarchical_sync(datastore) == FALSE, "The default SupportsHierarchicalSync is FALSE.");
	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_get_support_hierarchical_sync(datastore) == TRUE, "SupportsHierarchicalSync must be TRUE.");
	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, FALSE);
	sml_fail_unless(sml_dev_inf_data_store_get_support_hierarchical_sync(datastore) == FALSE, "SupportsHierarchicalSync must be FALSE.");

	/* The unknown SyncCap is set if no other SynCap is set. */

	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == TRUE, "The default SyncCap is no SyncCap.");
	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE);
	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE);
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == TRUE, "The default SyncCap was overwritten.");

	/* RxPref/TxPref must be set */

	sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == NULL, "The default RxPref is NULL.");
	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, NULL, &error) == FALSE, "A data store must have a RxPref.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == NULL, "The default RxPref is NULL.");
	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == ct, "The RxPref was not set correctly.");
	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, NULL, &error) == FALSE, "A data store must have a RxPref.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == ct, "The RxPref was overwritten.");

	sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == NULL, "The default TxPref is NULL.");
	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, NULL, &error) == FALSE, "A data store must have a TxPref.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == NULL, "The default TxPref is NULL.");
	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == ct, "The TxPref was not set correctly.");
	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, NULL, &error) == FALSE, "A data store must have a TxPref.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == ct, "The TxPref was overwritten.");

	/* Rx/Tx does not accept empty values */

	sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 0, "The default Rx list is empty.");
	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 0, "The default Rx list must be still empty.");
	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is a new content type in the Rx list.");
	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is still one content type in the Rx list.");

	sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 0, "The default Tx list is empty.");
	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 0, "The default Tx list must be still empty.");
	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is a new content type in the Tx list.");
	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is still one content type in the Tx list.");

	g_object_unref(ct);
	g_object_unref(datastore);
}
END_TEST

START_TEST (dev_inf_data_store_filled_set)
{
	setup_testbed(NULL);

	GError *error = NULL;
	SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error);
	sml_fail_unless(datastore != NULL, NULL);

	SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error);
	sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set.");

	/* enforce SourceRef name */

	sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, "AddressBook", &error), "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* the following parameters can be NULL or 0 */

	sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, "address book", &error), "%s", error?error->message:"No GError set.");

	sml_dev_inf_data_store_set_max_guid_size(datastore, 128);
	sml_dev_inf_data_store_set_max_guid_size(datastore, 0);

	sml_dev_inf_data_store_set_max_id(datastore, 1000000000);
	sml_dev_inf_data_store_set_max_id(datastore, 0);

	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, TRUE);
	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, FALSE);

	/* The unknown SyncCap is set if no other SynCap is set. */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE);
	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE);
	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, FALSE);
	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE); /* has no effect */
	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); /* deletes all SyncCaps */

	/* RxPref/TxPref must be set */

	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");

	/* Rx/Tx does not accept empty values */

	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");

	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");

	g_object_unref(ct);
	g_object_unref(datastore);
}
END_TEST

START_TEST (dev_inf_data_store_filled_get)
{
	setup_testbed(NULL);

	GError *error = NULL;
	SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error);
	sml_fail_unless(datastore != NULL, NULL);

	SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error);
	sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set.");

	/* enforce SourceRef name */

	sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, "AddressBook", &error), "%s", error?error->message:"No GError set.");
	const gchar *source_ref = sml_dev_inf_data_store_get_source_ref(datastore);
	sml_fail_unless(source_ref != NULL, "The SourceRef must always be available.");
	sml_fail_unless(strcmp(source_ref, "AddressBook") == 0, "The SourceRef was not copied correctly.");
	
	sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	source_ref = sml_dev_inf_data_store_get_source_ref(datastore);
	sml_fail_unless(source_ref != NULL, "The SourceRef was erased.");
	sml_fail_unless(strcmp(source_ref, "AddressBook") == 0, "The SourceRef was overwritten.");

	/* the following parameters can be NULL or 0 */

	sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, "address book", &error), "%s", error?error->message:"No GError set.");
	const gchar *display_name = sml_dev_inf_data_store_get_display_name(datastore);
	sml_fail_unless(display_name != NULL, "The DisplayName was erased.");
	sml_fail_unless(strcmp(display_name, "address book") == 0, "The DisplayName was not copied correctly.");

	sml_dev_inf_data_store_set_max_guid_size(datastore, 128);
	sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 128, "The MaxGUIDSize was not copied correctly.");
	sml_dev_inf_data_store_set_max_guid_size(datastore, 0);
	sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 0, "The MaxGUIDSize was not copied correctly.");

	sml_dev_inf_data_store_set_max_id(datastore, 1000000000);
	sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 1000000000, "The MaxID was not copied correctly.");
	sml_dev_inf_data_store_set_max_id(datastore, 0);
	sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 0, "The MaxID was not copied correctly.");

	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_get_support_hierarchical_sync(datastore) == TRUE, "SupportsHierarchicalSync must be TRUE.");
	sml_dev_inf_data_store_set_support_hierarchical_sync(datastore, FALSE);
	sml_fail_unless(sml_dev_inf_data_store_get_support_hierarchical_sync(datastore) == FALSE, "SupportsHierarchicalSync must be FALSE.");

	/* The unknown SyncCap is set if no other SynCap is set. */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY) == TRUE, "The Two-Way SyncCap was lost.");
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be a Two-Way SyncCap.");

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == TRUE, "The Slow-Sync SyncCap was lost.");
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY) == TRUE, "The Two-Way SyncCap was lost.");
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be two SyncCaps.");

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, FALSE);
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY) == FALSE, "The Two-Way SyncCap was not removed.");
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == TRUE, "The Slow-Sync SyncCap was lost.");
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be a Slow-Sync SyncCap.");

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE); /* has no effect */
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == TRUE, "The Slow-Sync SyncCap was lost.");
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be a Slow-Sync SyncCap.");

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); /* deletes all SyncCaps */
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == FALSE, "The Slow-Sync SyncCap was not removed.");
	sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == TRUE, "The default SyncCap was restored.");

	/* RxPref/TxPref must be set */

	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == ct, "The RxPref was not set correctly.");

	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == ct, "The TxPref was not set correctly.");

	/* Rx/Tx does not accept empty values */

	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is a new content type in the Rx list.");
	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is still one content type in the Rx list.");
	sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 2, "There are two content types in the Rx list.");

	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is a new content type in the Tx list.");
	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;
	sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is still one content type in the Tx list.");
	sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 2, "There are two content types in the Tx list.");

	g_object_unref(ct);
	g_object_unref(datastore);
}
END_TEST

START_TEST (dev_inf_data_store_compliance)
{
	setup_testbed(NULL);

	GError *error = NULL;
	SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error);
	sml_fail_unless(datastore != NULL, NULL);

	SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error);
	sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set.");

	/* The compliance function will be tested first
	 * always with the error paramater present. */

	/* missing RxPref, TxPref and SyncCap */

	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "RxPref, TxPref and one SyncCap are required.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* missing RxPref and TxPref */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "RxPref and TxPref are required.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* missing TxPref and SyncCap */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "TxPref and one SyncCap are required.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* missing TxPref */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "TxPref is required.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* missing SyncCap */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "One SyncCap is required.");
	sml_fail_unless(error != NULL, "The error must be set if an error appears.");
	g_error_free(error);
	error = NULL;

	/* correct */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == TRUE, "%s", error?error->message:"No GError set.");

	/* The compliance function will be tested now
	 * always without the error paramater. */

	/* cleanup datastore because RxPref cannot be removed from the object */
	g_object_unref(datastore);
	datastore = sml_dev_inf_data_store_new("Contacts", &error);

	/* missing RxPref and SyncCap */

	sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, NULL) == FALSE, "RxPref and one SyncCap are required.");

	/* missing RxPref */

	sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE);
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, NULL) == FALSE, "RxPref is required.");

	/* correct */

	sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set.");
	sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, NULL) == TRUE, "All requirements should be present.");

	g_object_unref(ct);
	g_object_unref(datastore);
}
END_TEST

START_TEST (dev_inf_data_store_references)
{
	setup_testbed(NULL);

	GError *error = NULL;
	SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error);
	sml_fail_unless(datastore != NULL, NULL);

	g_object_ref(datastore);

	sml_fail_unless(sml_dev_inf_data_store_get_source_ref(datastore) != NULL, "The source reference was not set.");

	g_object_unref(datastore);

	sml_fail_unless(sml_dev_inf_data_store_get_source_ref(datastore) != NULL, "The source reference is already cleaned up.");

	g_object_unref(datastore);
}
END_TEST

@SML_TESTCASE_CODE@

