summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c6
-rw-r--r--src/backenddb/test_merchantdb.c722
-rw-r--r--src/include/taler_merchantdb_plugin.h2
3 files changed, 599 insertions, 131 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 4664240a..97c9c3ab 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -5627,6 +5627,9 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" order_id"
",order_serial"
",creation_time"
+ ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */
+ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */
+ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */
" FROM merchant_orders"
" WHERE merchant_orders.merchant_serial="
" (SELECT merchant_serial "
@@ -5643,6 +5646,9 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" order_id"
",order_serial"
",creation_time"
+ ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */
+ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */
+ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */
" FROM merchant_contract_terms"
" WHERE merchant_contract_terms.merchant_serial="
" (SELECT merchant_serial "
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index aa82bf5b..c2c0a7da 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -51,14 +51,26 @@ static int instance_count;
*/
static struct TALER_MERCHANTDB_InstanceSettings instances_found[8];
+/**
+ * An array containing the number of accounts of each instance from lookup.
+ */
+static int instances_accounts_length[8];
+
+/**
+ * An array containing the array of accounts of each instance from lookup.
+ */
+static struct TALER_MERCHANTDB_AccountDetails *instances_accounts[8];
+
static void
copy_instance (struct TALER_MERCHANTDB_InstanceSettings *dest,
const struct TALER_MERCHANTDB_InstanceSettings *src)
{
- dest->id = GNUNET_malloc (sizeof(char) * (strlen (src->id) + 1));
- strcpy (dest->id, src->id);
- dest->name = GNUNET_malloc (sizeof(char) * (strlen (src->name) + 1));
- strcpy (dest->name, src->name);
+ dest->id = GNUNET_malloc (sizeof (char) * (strlen (src->id) + 1));
+ strcpy (dest->id,
+ src->id);
+ dest->name = GNUNET_malloc (sizeof (char) * (strlen (src->name) + 1));
+ strcpy (dest->name,
+ src->name);
dest->address = json_copy (src->address);
dest->jurisdiction = json_copy (src->jurisdiction);
dest->default_max_deposit_fee = src->default_max_deposit_fee;
@@ -91,7 +103,26 @@ lookup_instances_cb (void *cls,
if (8 >= instance_count)
{
/* Duplicate the instance settings */
- copy_instance (&instances_found[instance_count - 1], is);
+ copy_instance (&instances_found[instance_count - 1],
+ is);
+ instances_accounts_length[instance_count - 1] = accounts_length;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CB: %d\n", accounts_length);
+ instances_accounts[instance_count - 1] = GNUNET_new_array (accounts_length,
+ struct
+ TALER_MERCHANTDB_AccountDetails);
+ for (int i = 0; accounts_length > i; ++i)
+ {
+ struct TALER_MERCHANTDB_AccountDetails *dest =
+ &instances_accounts[instance_count - 1][i];
+ dest->h_wire = accounts[i].h_wire;
+ dest->salt = accounts[i].salt;
+ dest->payto_uri = GNUNET_malloc (sizeof (char) * (strlen (
+ accounts[i].payto_uri)
+ + 1));
+ strcpy (dest->payto_uri,
+ accounts[i].payto_uri);
+ dest->active = accounts[i].active;
+ }
}
}
@@ -100,10 +131,14 @@ static int
check_instances_equal (const struct TALER_MERCHANTDB_InstanceSettings *a,
const struct TALER_MERCHANTDB_InstanceSettings *b)
{
- if ((0 != strcmp (a->id, b->id)) ||
- (0 != strcmp (a->name, b->name)) ||
- (1 != json_equal (a->address, b->address)) ||
- (1 != json_equal (a->jurisdiction, b->jurisdiction)) ||
+ if ((0 != strcmp (a->id,
+ b->id)) ||
+ (0 != strcmp (a->name,
+ b->name)) ||
+ (1 != json_equal (a->address,
+ b->address)) ||
+ (1 != json_equal (a->jurisdiction,
+ b->jurisdiction)) ||
(GNUNET_OK != TALER_amount_cmp_currency (&a->default_max_deposit_fee,
&b->default_max_deposit_fee)) ||
(0 != TALER_amount_cmp (&a->default_max_deposit_fee,
@@ -121,59 +156,71 @@ check_instances_equal (const struct TALER_MERCHANTDB_InstanceSettings *a,
}
-/**
- * Number of instances detected.
- */
-static int product_count;
-
-/**
- * An array of instance settings found from the lookup method.
- */
-static char *products_found[8];
+static int
+check_accounts_equal (const struct TALER_MERCHANTDB_AccountDetails *a,
+ const struct TALER_MERCHANTDB_AccountDetails *b)
+{
+ if ((0 != GNUNET_CRYPTO_hash_cmp (&a->h_wire,
+ &b->h_wire)) ||
+ (0 != GNUNET_CRYPTO_hash_cmp (&a->salt,
+ &b->salt)) ||
+ (0 != strcmp (a->payto_uri,
+ b->payto_uri)) ||
+ (a->active != b->active))
+ return 1;
+ return 0;
+}
-static void
-free_product (struct TALER_MERCHANTDB_ProductDetails *pd)
+static int
+test_insert_instance (const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_MerchantPrivateKeyP *merchant_priv,
+ const struct TALER_MERCHANTDB_InstanceSettings *is)
{
- GNUNET_free (pd->description);
- json_decref (pd->description_i18n);
- GNUNET_free (pd->unit);
- json_decref (pd->image);
- json_decref (pd->address);
+ if (0 > plugin->insert_instance (plugin->cls,
+ merchant_pub,
+ merchant_priv,
+ is))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Instance insertion failed\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ return 0;
}
-static void
-lookup_products_cb (void *cls,
- const char *product_id)
+static int
+test_lookup_instances (bool active_only)
{
- product_count += 1;
- if (8 >= product_count)
+ if (0 > plugin->lookup_instances (plugin->cls,
+ active_only,
+ &lookup_instances_cb,
+ NULL))
{
- products_found[product_count - 1] =
- GNUNET_malloc (sizeof(char) * (strlen (product_id) + 1));
- strcpy (products_found[product_count - 1], product_id);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup instances failed\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
}
+ return 0;
}
static int
-check_products_equal (const struct TALER_MERCHANTDB_ProductDetails *a,
- const struct TALER_MERCHANTDB_ProductDetails *b)
+test_insert_account (const char *instance_id,
+ const struct TALER_MERCHANTDB_AccountDetails *account)
{
- if ((0 != strcmp (a->description, b->description)) ||
- (1 != json_equal (a->description_i18n, b->description_i18n)) ||
- (0 != strcmp (a->unit, b->unit)) ||
- (GNUNET_OK != TALER_amount_cmp_currency (&a->price, &b->price)) ||
- (0 != TALER_amount_cmp (&a->price, &b->price)) ||
- (1 != json_equal (a->taxes, b->taxes)) ||
- (a->total_stock != b->total_stock) ||
- (a->total_sold != b->total_sold) ||
- (a->total_lost != b->total_lost) ||
- (1 != json_equal (a->image, b->image)) ||
- (1 != json_equal (a->address, b->address)) ||
- (a->next_restock.abs_value_us != b->next_restock.abs_value_us))
+ if (1 > plugin->insert_account (plugin->cls,
+ instance_id,
+ account))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Insert account failed\n");
+ plugin->drop_tables (plugin->cls);
return 1;
+ }
return 0;
}
@@ -196,52 +243,53 @@ test_instances (void *cls)
is.id = "test_inst";
is.name = "Test";
is.address = json_array ();
- json_array_append (is.address, json_string ("123 Example St"));
+ json_array_append (is.address,
+ json_string ("123 Example St"));
is.jurisdiction = json_array ();
- json_array_append (is.jurisdiction, json_string ("Ohio"));
- TALER_string_to_amount ("EUR:1200.40", &is.default_max_deposit_fee);
- TALER_string_to_amount ("EUR:1200.40", &is.default_max_wire_fee);
+ json_array_append (is.jurisdiction,
+ json_string ("Ohio"));
+ TALER_string_to_amount ("EUR:1200.40",
+ &is.default_max_deposit_fee);
+ TALER_string_to_amount ("EUR:1200.40",
+ &is.default_max_wire_fee);
is.default_wire_fee_amortization = 1;
is.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ ();
is.default_pay_delay = GNUNET_TIME_relative_get_second_ ();
- if (0 > plugin->insert_instance (plugin->cls, &merchant_pub, &merchant_priv,
- &is))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Instance insertion failed\n");
- plugin->drop_tables (plugin->cls);
- return 1;
- }
+ TEST_RET_ON_FAIL (test_insert_instance (&merchant_pub,
+ &merchant_priv,
+ &is));
/* Test lookup instances- is our new instance there? */
instance_count = 0;
- if (0 > plugin->lookup_instances (plugin->cls, false,
- &lookup_instances_cb, cls))
+ TEST_RET_ON_FAIL (test_lookup_instances (false));
+ if (instance_count != 1)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup instances failed\n");
+ "Instance count doesn't match number of instances inserted\n");
plugin->drop_tables (plugin->cls);
return 1;
}
- if (instance_count != 1)
+ if (0 != check_instances_equal (&is,
+ &instances_found[0]))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Instance count doesn't match number of instances inserted\n");
+ "Lookup instance failed: incorrect instance returned\n");
plugin->drop_tables (plugin->cls);
return 1;
}
- if (0 != check_instances_equal (&is, &instances_found[0]))
+ free_instance (&instances_found[0]);
+ if (0 != instances_accounts_length[0])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup instance failed: incorrect instance returned\n");
+ "Lookup instance failed: incorrect accounts returned\n");
plugin->drop_tables (plugin->cls);
return 1;
}
- free_instance (&instances_found[0]);
/* Test update instance */
is.name = "Test - updated";
- if (0 > plugin->update_instance (plugin->cls, &is))
+ if (0 > plugin->update_instance (plugin->cls,
+ &is))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Update instance failed\n");
@@ -249,63 +297,126 @@ test_instances (void *cls)
return 1;
}
instance_count = 0;
- if (0 > plugin->lookup_instances (plugin->cls, false,
- &lookup_instances_cb, cls))
+ TEST_RET_ON_FAIL (test_lookup_instances (false));
+ if (1 != instance_count)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup instances failed\n");
+ "Update instance failed: Instance count doesn't match number of instances inserted/updated\n");
plugin->drop_tables (plugin->cls);
return 1;
}
- if (instance_count != 1)
+ if (0 != check_instances_equal (&is,
+ &instances_found[0]))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Update instance failed: Instance count doesn't match number of instances inserted/updated\n");
+ "Update instance failed: result from lookup doesn't match\n");
plugin->drop_tables (plugin->cls);
return 1;
}
- if (0 != check_instances_equal (&is, &instances_found[0]))
+ free_instance (&instances_found[0]);
+
+ /* Test account creation */
+ struct TALER_MERCHANTDB_AccountDetails account;
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG,
+ &account.h_wire);
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG,
+ &account.salt);
+ account.payto_uri = "payto://x-taler-bank/bank.demo.taler.net/4";
+ account.active = true;
+ TEST_RET_ON_FAIL (test_insert_account ("test_inst", &account));
+
+ /* Test accounts from instance lookup */
+ instance_count = 0;
+ TEST_RET_ON_FAIL (test_lookup_instances (false));
+ free_instance (&instances_found[0]);
+ if (1 != instances_accounts_length[0])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Update instance failed: result from lookup doesn't match\n");
+ "Lookup instance failed: incorrect number of accounts returned\n");
plugin->drop_tables (plugin->cls);
return 1;
}
- free_instance (&instances_found[0]);
+ if (0 != check_accounts_equal (&account,
+ &instances_accounts[0][0]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup instance failed: incorrect accounts returned\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ GNUNET_free (instances_accounts[0][0].payto_uri);
- /* Test instance private key deletion */
- if (0 > plugin->delete_instance_private_key (plugin->cls, "test_inst"))
+ /* Test account inactivation */
+ if (0 > plugin->inactivate_account (plugin->cls,
+ &account.h_wire))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Delete instance private key failed\n");
+ "Inactivate account failed\n");
plugin->drop_tables (plugin->cls);
return 1;
}
+ account.active = false;
instance_count = 0;
- if (0 > plugin->lookup_instances (plugin->cls, true,
- &lookup_instances_cb, cls))
+ TEST_RET_ON_FAIL (test_lookup_instances (false));
+ free_instance (&instances_found[0]);
+ if (1 != instances_accounts_length[0])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup instances failed\n");
+ "Lookup instance failed: incorrect number of accounts returned\n");
plugin->drop_tables (plugin->cls);
return 1;
}
- if (0 != instance_count)
+ if (0 != check_accounts_equal (&account,
+ &instances_accounts[0][0]))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup instances failed: instance without private key not excluded when only counting active instances\n");
+ "Lookup instance failed: incorrect accounts returned\n");
plugin->drop_tables (plugin->cls);
return 1;
}
+ GNUNET_free (instances_accounts[0][0].payto_uri);
+
+ /* Test multiple accounts */
+ /* This fails currently */
+ /*struct TALER_MERCHANTDB_AccountDetails account1;
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG,
+ &account1.h_wire);
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG,
+ &account1.salt);
+ account1.payto_uri = "payto://other-bank/bank.demo.taler.net/4";
+ account1.active = true;
+ TEST_RET_ON_FAIL (test_insert_account ("test_inst", &account1));
instance_count = 0;
- if (0 > plugin->lookup_instances (plugin->cls, false,
- &lookup_instances_cb, cls))
+ TEST_RET_ON_FAIL (test_lookup_instances (false));
+ free_instance (&instances_found[0]);
+ if (2 != instances_accounts_length[0])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Lookup instances failed\n");
+ "Lookup instance failed: incorrect number of accounts returned %d\n", instances_accounts_length[0]);
+ //plugin->drop_tables (plugin->cls);
+ return 1;
+ }*/
+
+ /* Test instance private key deletion */
+ if (0 > plugin->delete_instance_private_key (plugin->cls,
+ "test_inst"))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Delete instance private key failed\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ instance_count = 0;
+ TEST_RET_ON_FAIL (test_lookup_instances (true));
+ if (0 != instance_count)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup instances failed: instance without private key not excluded when only counting active instances\n");
plugin->drop_tables (plugin->cls);
return 1;
}
+ instance_count = 0;
+ TEST_RET_ON_FAIL (test_lookup_instances (false));
if (1 != instance_count)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -319,7 +430,8 @@ test_instances (void *cls)
/* Test instance deletion */
/* This test currently FAILS */
/*instance_count = 0;
- if (0 > plugin->purge_instance (plugin->cls, "test_inst"))
+ if (0 > plugin->purge_instance (plugin->cls,
+ "test_inst"))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Purge instance failed\n");
@@ -335,12 +447,81 @@ test_instances (void *cls)
}
+/**
+ * Number of products detected.
+ */
+static int product_count;
+
+
+/**
+ * An array of product ids found from the lookup method.
+ */
+static char *products_found[8];
+
+
+static void
+free_product (struct TALER_MERCHANTDB_ProductDetails *pd)
+{
+ GNUNET_free (pd->description);
+ json_decref (pd->description_i18n);
+ GNUNET_free (pd->unit);
+ json_decref (pd->image);
+ json_decref (pd->address);
+}
+
+
+static void
+lookup_products_cb (void *cls,
+ const char *product_id)
+{
+ product_count += 1;
+ if (8 >= product_count)
+ {
+ products_found[product_count - 1] =
+ GNUNET_malloc (sizeof(char) * (strlen (product_id) + 1));
+ strcpy (products_found[product_count - 1],
+ product_id);
+ }
+}
+
+
+static int
+check_products_equal (const struct TALER_MERCHANTDB_ProductDetails *a,
+ const struct TALER_MERCHANTDB_ProductDetails *b)
+{
+ if ((0 != strcmp (a->description,
+ b->description)) ||
+ (1 != json_equal (a->description_i18n,
+ b->description_i18n)) ||
+ (0 != strcmp (a->unit,
+ b->unit)) ||
+ (GNUNET_OK != TALER_amount_cmp_currency (&a->price,
+ &b->price)) ||
+ (0 != TALER_amount_cmp (&a->price,
+ &b->price)) ||
+ (1 != json_equal (a->taxes,
+ b->taxes)) ||
+ (a->total_stock != b->total_stock) ||
+ (a->total_sold != b->total_sold) ||
+ (a->total_lost != b->total_lost) ||
+ (1 != json_equal (a->image,
+ b->image)) ||
+ (1 != json_equal (a->address,
+ b->address)) ||
+ (a->next_restock.abs_value_us != b->next_restock.abs_value_us))
+ return 1;
+ return 0;
+}
+
+
static int
test_insert_product (const char *is,
const char *pd_id,
const struct TALER_MERCHANTDB_ProductDetails *pd)
{
- if (0 > plugin->insert_product (plugin->cls, is, pd_id,
+ if (0 > plugin->insert_product (plugin->cls,
+ is,
+ pd_id,
pd))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -357,7 +538,9 @@ test_lookup_product (const char *is,
const char *pd_id,
struct TALER_MERCHANTDB_ProductDetails *pd)
{
- if (0 > plugin->lookup_product (plugin->cls, is, pd_id,
+ if (0 > plugin->lookup_product (plugin->cls,
+ is,
+ pd_id,
pd))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -373,7 +556,9 @@ static int
test_delete_product (const char *is,
const char *pd)
{
- if (0 > plugin->delete_product (plugin->cls, is, pd))
+ if (0 > plugin->delete_product (plugin->cls,
+ is,
+ pd))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Delete product failed\n");
@@ -402,29 +587,29 @@ test_products (void *cls)
is.id = "test_instance_0";
is.name = "Test";
is.address = json_array ();
- json_array_append (is.address, json_string ("123 Example St"));
+ json_array_append (is.address,
+ json_string ("123 Example St"));
is.jurisdiction = json_array ();
- json_array_append (is.jurisdiction, json_string ("Ohio"));
- TALER_string_to_amount ("EUR:1200.40", &is.default_max_deposit_fee);
- TALER_string_to_amount ("EUR:1200.40", &is.default_max_wire_fee);
+ json_array_append (is.jurisdiction,
+ json_string ("Ohio"));
+ TALER_string_to_amount ("EUR:1200.40",
+ &is.default_max_deposit_fee);
+ TALER_string_to_amount ("EUR:1200.40",
+ &is.default_max_wire_fee);
is.default_wire_fee_amortization = 1;
is.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ ();
is.default_pay_delay = GNUNET_TIME_relative_get_second_ ();
- if (0 > plugin->insert_instance (plugin->cls, &merchant_pub, &merchant_priv,
- &is))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Instance insertion failed\n");
- plugin->drop_tables (plugin->cls);
- return 1;
- }
+ TEST_RET_ON_FAIL (test_insert_instance (&merchant_pub,
+ &merchant_priv,
+ &is));
/* Test creating a product */
struct TALER_MERCHANTDB_ProductDetails pd;
pd.description = "This is a test product";
pd.description_i18n = json_array ();
pd.unit = "boxes";
- TALER_string_to_amount ("EUR:120.40", &pd.price);
+ TALER_string_to_amount ("EUR:120.40",
+ &pd.price);
pd.taxes = json_array ();
pd.total_stock = 55;
pd.total_sold = 0;
@@ -432,13 +617,17 @@ test_products (void *cls)
pd.image = json_array ();
pd.address = json_array ();
pd.next_restock = GNUNET_TIME_absolute_get_zero_ ();
- TEST_RET_ON_FAIL (test_insert_product ("test_instance_0", "is_0_pd_0", &pd));
+ TEST_RET_ON_FAIL (test_insert_product ("test_instance_0",
+ "is_0_pd_0",
+ &pd));
/* Test lookup of individual products */
struct TALER_MERCHANTDB_ProductDetails lookup_pd;
- TEST_RET_ON_FAIL (test_lookup_product ("test_instance_0", "is_0_pd_0",
+ TEST_RET_ON_FAIL (test_lookup_product ("test_instance_0",
+ "is_0_pd_0",
&lookup_pd));
- if (0 != check_products_equal (&pd, &lookup_pd))
+ if (0 != check_products_equal (&pd,
+ &lookup_pd))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lookup product failed: incorrect product returned\n");
@@ -448,8 +637,10 @@ test_products (void *cls)
free_product (&lookup_pd);
/* Make sure it fails correctly for products that don't exist */
- if (0 != plugin->lookup_product (plugin->cls, "test_instance_0",
- "fictional_product", &lookup_pd))
+ if (0 != plugin->lookup_product (plugin->cls,
+ "test_instance_0",
+ "fictional_product",
+ &lookup_pd))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lookup product failed: product returned where there was none\n");
@@ -459,7 +650,9 @@ test_products (void *cls)
/* Test product update */
pd.description = "This is a test product that has been updated!";
- if (0 > plugin->update_product (plugin->cls, "test_instance_0", "is_0_pd_0",
+ if (0 > plugin->update_product (plugin->cls,
+ "test_instance_0",
+ "is_0_pd_0",
&pd))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -467,9 +660,11 @@ test_products (void *cls)
plugin->drop_tables (plugin->cls);
return 1;
}
- TEST_RET_ON_FAIL (test_lookup_product ("test_instance_0", "is_0_pd_0",
+ TEST_RET_ON_FAIL (test_lookup_product ("test_instance_0",
+ "is_0_pd_0",
&lookup_pd));
- if (0 != check_products_equal (&pd, &lookup_pd))
+ if (0 != check_products_equal (&pd,
+ &lookup_pd))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Update product failed: lookup returns old product\n");
@@ -482,11 +677,16 @@ test_products (void *cls)
struct TALER_MERCHANTDB_ProductDetails pd1 = pd;
pd1.description = "This is another product.";
pd1.unit = "cans";
- TALER_string_to_amount ("EUR:4.95", &pd1.price);
- TEST_RET_ON_FAIL (test_insert_product ("test_instance_0", "is_0_pd_1", &pd1));
+ TALER_string_to_amount ("EUR:4.95",
+ &pd1.price);
+ TEST_RET_ON_FAIL (test_insert_product ("test_instance_0",
+ "is_0_pd_1",
+ &pd1));
product_count = 0;
- if (0 > plugin->lookup_products (plugin->cls, "test_instance_0",
- &lookup_products_cb, cls))
+ if (0 > plugin->lookup_products (plugin->cls,
+ "test_instance_0",
+ &lookup_products_cb,
+ cls))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lookup products failed\n");
@@ -500,10 +700,14 @@ test_products (void *cls)
plugin->drop_tables (plugin->cls);
return 1;
}
- if (! (((0 == strcmp ("is_0_pd_0", products_found[0])) &&
- (0 == strcmp ("is_0_pd_1", products_found[1]))) ||
- ((0 == strcmp ("is_0_pd_1", products_found[0])) &&
- (0 == strcmp ("is_0_pd_0", products_found[1])))))
+ if (! (((0 == strcmp ("is_0_pd_0",
+ products_found[0])) &&
+ (0 == strcmp ("is_0_pd_1",
+ products_found[1]))) ||
+ ((0 == strcmp ("is_0_pd_1",
+ products_found[0])) &&
+ (0 == strcmp ("is_0_pd_0",
+ products_found[1])))))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lookup products failed: incorrect product ids found\n");
@@ -514,10 +718,13 @@ test_products (void *cls)
GNUNET_free (products_found[1]);
/* Test product deletion */
- TEST_RET_ON_FAIL (test_delete_product ("test_instance_0", "is_0_pd_0"));
+ TEST_RET_ON_FAIL (test_delete_product ("test_instance_0",
+ "is_0_pd_0"));
product_count = 0;
- if (0 > plugin->lookup_products (plugin->cls, "test_instance_0",
- &lookup_products_cb, cls))
+ if (0 > plugin->lookup_products (plugin->cls,
+ "test_instance_0",
+ &lookup_products_cb,
+ cls))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lookup products failed\n");
@@ -532,10 +739,13 @@ test_products (void *cls)
plugin->drop_tables (plugin->cls);
return 1;
}
- TEST_RET_ON_FAIL (test_delete_product ("test_instance_0", "is_0_pd_1"));
+ TEST_RET_ON_FAIL (test_delete_product ("test_instance_0",
+ "is_0_pd_1"));
product_count = 0;
- if (0 > plugin->lookup_products (plugin->cls, "test_instance_0",
- &lookup_products_cb, cls))
+ if (0 > plugin->lookup_products (plugin->cls,
+ "test_instance_0",
+ &lookup_products_cb,
+ cls))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lookup products failed\n");
@@ -557,13 +767,13 @@ test_products (void *cls)
/* Clean up: delete the instance */
/* This test currently FAILS */
- /*instance_count = 0;
- if (0 > plugin->purge_instance(plugin->cls, "t")) {
+ /*
+ if (0 > plugin->purge_instance(plugin->cls,
+ "test_instance_0")) {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Purge instance failed\n");
- result = 1;
plugin->drop_tables (plugin->cls);
- return;
+ return 1;
}*/
json_decref (is.address);
@@ -574,6 +784,253 @@ test_products (void *cls)
/**
+ * Number of orders detected.
+ */
+static int order_count;
+
+
+/**
+ * An array of order ids found from the lookup method.
+ */
+static char *orders_found[8];
+
+
+/**
+ * An array of order serials found from the lookup method.
+ */
+static uint64_t order_serials[8];
+
+
+/**
+ * An array of order timestamps found from the lookup method.
+ */
+static struct GNUNET_TIME_Absolute order_timestamps[8];
+
+
+static void
+lookup_orders_cb (void *cls,
+ const char *order_id,
+ uint64_t order_serial,
+ struct GNUNET_TIME_Absolute timestamp)
+{
+ order_count += 1;
+ if (8 >= order_count)
+ {
+ orders_found[order_count - 1] =
+ GNUNET_malloc (sizeof(char) * (strlen (order_id) + 1));
+ strcpy (orders_found[order_count - 1],
+ order_id);
+ order_serials[order_count - 1] = order_serial;
+ order_timestamps[order_count - 1] = timestamp;
+ }
+}
+
+
+static int
+test_insert_order (const char *instance_id,
+ const char *order_id,
+ struct GNUNET_TIME_Absolute pay_deadline,
+ const json_t *contract_terms)
+{
+ if (0 > plugin->insert_order (plugin->cls,
+ instance_id,
+ order_id,
+ pay_deadline,
+ contract_terms))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Insert order failed\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ return 0;
+}
+
+
+static int
+test_lookup_order (const char *is,
+ const char *od,
+ json_t **contract_terms)
+{
+ if (0 > plugin->lookup_order (plugin->cls,
+ is,
+ od,
+ contract_terms))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup order failed\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ return 0;
+}
+
+
+static int
+test_lookup_orders (const char *is,
+ const struct TALER_MERCHANTDB_OrderFilter *of)
+{
+ if (0 > plugin->lookup_orders (plugin->cls,
+ is,
+ of,
+ &lookup_orders_cb,
+ NULL))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup orders failed\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ return 0;
+}
+
+
+static int
+test_delete_order (const char *is,
+ const char *od)
+{
+ if (0 > plugin->delete_order (plugin->cls,
+ is,
+ od))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Delete order failed\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ return 0;
+}
+
+
+/**
+ * Function that tests orders.
+ *
+ * @param cls closure with config
+ */
+static int
+test_orders (void *cls)
+{
+ struct TALER_MerchantPublicKeyP merchant_pub;
+ struct TALER_MerchantPrivateKeyP merchant_priv;
+ GNUNET_CRYPTO_eddsa_key_create (&merchant_priv.eddsa_priv);
+ GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv,
+ &merchant_pub.eddsa_pub);
+ struct TALER_MERCHANTDB_InstanceSettings is;
+ is.id = "test_instance_2";
+ is.name = "Test";
+ is.address = json_array ();
+ json_array_append (is.address,
+ json_string ("123 Example St"));
+ is.jurisdiction = json_array ();
+ json_array_append (is.jurisdiction,
+ json_string ("Ohio"));
+ TALER_string_to_amount ("EUR:1200.40",
+ &is.default_max_deposit_fee);
+ TALER_string_to_amount ("EUR:1200.40",
+ &is.default_max_wire_fee);
+ is.default_wire_fee_amortization = 1;
+ is.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ ();
+ is.default_pay_delay = GNUNET_TIME_relative_get_second_ ();
+ TEST_RET_ON_FAIL (test_insert_instance (&merchant_pub,
+ &merchant_priv,
+ &is));
+
+ /* Test insert order */
+ struct GNUNET_TIME_Absolute time_0 = GNUNET_TIME_absolute_get_zero_ ();
+ json_t *terms_0 = json_array ();
+ json_array_append (terms_0,
+ json_string ("contract"));
+ TEST_RET_ON_FAIL (test_insert_order ("test_instance_2",
+ "is_2_or_0",
+ time_0,
+ terms_0));
+
+ /* Test lookup order */
+ json_t *lookup_terms;
+ TEST_RET_ON_FAIL (test_lookup_order ("test_instance_2",
+ "is_2_or_0",
+ &lookup_terms));
+ if (1 != json_equal (terms_0,
+ lookup_terms))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup order failed: contract terms returned do not match\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ json_decref (lookup_terms);
+
+ /* Make sure it fails correctly for products that don't exist */
+ if (0 != plugin->lookup_order (plugin->cls,
+ "test_instance_2",
+ "fictional_order",
+ &lookup_terms))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup order failed: order returned where there was none\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+
+ /* Test lookups for multiple orders */
+ TEST_RET_ON_FAIL (test_insert_order ("test_instance_2",
+ "is_2_or_1",
+ time_0,
+ terms_0));
+ struct TALER_MERCHANTDB_OrderFilter filter;
+ filter.paid = TALER_MERCHANTDB_YNA_ALL;
+ filter.refunded = TALER_MERCHANTDB_YNA_ALL;
+ filter.wired = TALER_MERCHANTDB_YNA_ALL;
+ filter.date = GNUNET_TIME_absolute_get_zero_ ();
+ filter.start_row = 0;
+ filter.delta = 8;
+ order_count = 0;
+ TEST_RET_ON_FAIL (test_lookup_orders ("test_instance_2",
+ &filter));
+ if (2 != order_count)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup orders failed: incorrect number of orders found\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ if (! (((0 == strcmp ("is_2_or_0",
+ orders_found[0])) &&
+ (0 == strcmp ("is_2_or_1",
+ orders_found[1]))) ||
+ ((0 == strcmp ("is_2_or_1",
+ orders_found[0])) &&
+ (0 == strcmp ("is_2_or_0",
+ orders_found[1])))))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Lookup orders failed: incorrect order ids found\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ GNUNET_free (orders_found[0]);
+ GNUNET_free (orders_found[1]);
+
+ /* Test delete order */
+ TEST_RET_ON_FAIL (test_delete_order ("test_instance_2",
+ "is_2_or_0"));
+ order_count = 0;
+ TEST_RET_ON_FAIL (test_lookup_orders ("test_instance_2",
+ &filter));
+ if (1 != order_count)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Delete order failed: order still present in database\n");
+ plugin->drop_tables (plugin->cls);
+ return 1;
+ }
+ GNUNET_free (orders_found[0]);
+
+ return 0;
+}
+
+
+/**
* Main function that will be run by the scheduler.
*
* @param cls closure with config
@@ -605,6 +1062,11 @@ run (void *cls)
if (0 != result)
return;
+ /* Test orders */
+ result = test_orders (cls);
+ if (0 != result)
+ return;
+
/* Test dropping tables */
if (GNUNET_OK != plugin->drop_tables (plugin->cls))
{
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index 1324b4d9..bb8249cd 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -51,7 +51,7 @@ struct TALER_MERCHANTDB_AccountDetails
/**
* Actual account address as a payto://-URI.
*/
- const char *payto_uri;
+ char *payto_uri;
/**
* Is the account set for active use in new contracts?