gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: add logic to preserve and possib


From: gnunet
Subject: [taler-merchant] branch master updated: add logic to preserve and possibly update minimum_age in contract terms
Date: Fri, 22 Mar 2024 14:05:46 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 6d41df4f add logic to preserve and possibly update minimum_age in 
contract terms
6d41df4f is described below

commit 6d41df4ffbc0d921aecb265ecb49b15df5c7178e
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Mar 22 14:05:42 2024 +0100

    add logic to preserve and possibly update minimum_age in contract terms
---
 .../taler-merchant-httpd_private-post-orders.c     | 15 ++++++
 src/include/taler_merchant_service.h               | 44 ++++++++++++++++
 src/include/taler_merchant_testing_lib.h           | 25 ++++++++-
 src/lib/merchant_api_post_products.c               | 58 +++++++++++++++++---
 src/testing/test_merchant_api.c                    | 33 ++++++++++++
 src/testing/testing_api_cmd_merchant_get_order.c   | 61 +++++++++++++++++++++-
 src/testing/testing_api_cmd_post_products.c        | 28 ++++++----
 7 files changed, 245 insertions(+), 19 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c 
b/src/backend/taler-merchant-httpd_private-post-orders.c
index be8b8d1d..6be11f16 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -330,6 +330,11 @@ struct OrderContext
      */
     const json_t *extra;
 
+    /**
+     * Minimum age required by the order.
+     */
+    uint32_t minimum_age;
+
   } parse_order;
 
   /**
@@ -1322,6 +1327,9 @@ serialize_order (struct OrderContext *oc)
     GNUNET_JSON_pack_allow_null (
       GNUNET_JSON_pack_string ("fulfillment_url",
                                oc->parse_order.fulfillment_url)),
+    GNUNET_JSON_pack_allow_null (
+      GNUNET_JSON_pack_uint64 ("minimum_age",
+                               oc->parse_order.minimum_age)),
     GNUNET_JSON_pack_array_incref ("products",
                                    oc->merge_inventory.products),
     GNUNET_JSON_pack_data_auto ("h_wire",
@@ -1575,6 +1583,10 @@ parse_order (struct OrderContext *oc)
       GNUNET_JSON_spec_timestamp ("delivery_date",
                                   &oc->parse_order.delivery_date),
       NULL),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_uint32 ("minimum_age",
+                               &oc->parse_order.minimum_age),
+      NULL),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_relative_time ("auto_refund",
                                       &oc->parse_order.auto_refund),
@@ -1996,6 +2008,9 @@ merge_inventory (struct OrderContext *oc)
                           ip->product_id);
         return;
       }
+      oc->parse_order.minimum_age
+        = GNUNET_MAX (oc->parse_order.minimum_age,
+                      pd.minimum_age);
       {
         json_t *p;
 
diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 6ddf3ee4..263a6fec 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -1662,6 +1662,50 @@ TALER_MERCHANT_products_post (
   void *cb_cls);
 
 
+/**
+ * Make a POST /products request to add a product to the
+ * inventory.
+ *
+ * @param ctx the context
+ * @param backend_url HTTP base URL for the backend
+ * @param product_id identifier to use for the product
+ * @param description description of the product
+ * @param description_i18n Map from IETF BCP 47 language tags to localized 
descriptions
+ * @param unit unit in which the product is measured (liters, kilograms, 
packages, etc.)
+ * @param price the price for one @a unit of the product, zero is used to 
imply that
+ *              this product is not sold separately or that the price is not 
fixed and
+ *              must be supplied by the front-end.  If non-zero, price must 
include
+ *              applicable taxes.
+ * @param image base64-encoded product image
+ * @param taxes list of taxes paid by the merchant
+ * @param total_stock in @a units, -1 to indicate "infinite" (i.e. electronic 
books)
+ * @param address where the product is in stock
+ * @param next_restock when the next restocking is expected to happen, 0 for 
unknown,
+ *                     #GNUNET_TIME_UNIT_FOREVER_ABS for 'never'.
+ * @param minimum_age minimum age the buyer must have
+ * @param cb function to call with the backend's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_MERCHANT_ProductsPostHandle *
+TALER_MERCHANT_products_post2 (
+  struct GNUNET_CURL_Context *ctx,
+  const char *backend_url,
+  const char *product_id,
+  const char *description,
+  const json_t *description_i18n,
+  const char *unit,
+  const struct TALER_Amount *price,
+  const char *image,
+  const json_t *taxes,
+  int64_t total_stock,
+  const json_t *address,
+  struct GNUNET_TIME_Timestamp next_restock,
+  uint32_t minimum_age,
+  TALER_MERCHANT_ProductsPostCallback cb,
+  void *cb_cls);
+
+
 /**
  * Cancel POST /products operation.
  *
diff --git a/src/include/taler_merchant_testing_lib.h 
b/src/include/taler_merchant_testing_lib.h
index 85613fa6..b1de5292 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -315,9 +315,10 @@ TALER_TESTING_cmd_merchant_delete_instance (const char 
*label,
  * @param image base64-encoded product image
  * @param taxes list of taxes paid by the merchant
  * @param total_stock in @a units, -1 to indicate "infinite" (i.e. electronic 
books)
+ * @param minimum_age minimum age required for buying this product
  * @param address where the product is in stock
  * @param next_restock when the next restocking is expected to happen, 0 for 
unknown,
- *                     #GNUNET_TIME_UNIT_FOREVER_ABS for 'never'.
+ *                     #GNUNET_TIME_UNIT_FOREVER_TS for 'never'.
  * @param http_status expected HTTP response code.
  * @return the command.
  */
@@ -333,6 +334,7 @@ TALER_TESTING_cmd_merchant_post_products2 (
   const char *image,
   json_t *taxes,
   int64_t total_stock,
+  uint32_t minimum_age,
   json_t *address,
   struct GNUNET_TIME_Timestamp next_restock,
   unsigned int http_status);
@@ -865,6 +867,27 @@ TALER_TESTING_cmd_merchant_get_order3 (
   unsigned int expected_http_status);
 
 
+/**
+ * Define a GET /private/orders/$ORDER_ID CMD.
+ *
+ * @param label the command label
+ * @param merchant_url base URL of the merchant which will
+ *        serve the request.
+ * @param order_reference reference to a command that created an order.
+ * @param osc expected order status
+ * @param expected_min_age expected minimum age for the contract
+ * @param expected_http_status expected HTTP response code for the request.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_merchant_get_order4 (
+  const char *label,
+  const char *merchant_url,
+  const char *order_reference,
+  enum TALER_MERCHANT_OrderStatusCode osc,
+  uint32_t expected_min_age,
+  unsigned int expected_http_status);
+
+
 /**
  * Start a long poll for GET /private/orders/$ORDER_ID.
  */
diff --git a/src/lib/merchant_api_post_products.c 
b/src/lib/merchant_api_post_products.c
index 2a5b9a9b..0f09f397 100644
--- a/src/lib/merchant_api_post_products.c
+++ b/src/lib/merchant_api_post_products.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020-2021 Taler Systems SA
+  Copyright (C) 2020-2024 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
@@ -159,7 +159,7 @@ handle_post_products_finished (void *cls,
 
 
 struct TALER_MERCHANT_ProductsPostHandle *
-TALER_MERCHANT_products_post (
+TALER_MERCHANT_products_post2 (
   struct GNUNET_CURL_Context *ctx,
   const char *backend_url,
   const char *product_id,
@@ -172,6 +172,7 @@ TALER_MERCHANT_products_post (
   int64_t total_stock,
   const json_t *address,
   struct GNUNET_TIME_Timestamp next_restock,
+  uint32_t minimum_age,
   TALER_MERCHANT_ProductsPostCallback cb,
   void *cb_cls)
 {
@@ -183,20 +184,26 @@ TALER_MERCHANT_products_post (
                              product_id),
     GNUNET_JSON_pack_string ("description",
                              description),
-    GNUNET_JSON_pack_object_incref ("description_i18n",
-                                    (json_t *) description_i18n),
+    GNUNET_JSON_pack_allow_null (
+      GNUNET_JSON_pack_object_incref ("description_i18n",
+                                      (json_t *) description_i18n)),
     GNUNET_JSON_pack_string ("unit",
                              unit),
     TALER_JSON_pack_amount ("price",
                             price),
     GNUNET_JSON_pack_string ("image",
                              image),
-    GNUNET_JSON_pack_array_incref ("taxes",
-                                   (json_t *) taxes),
+    GNUNET_JSON_pack_allow_null (
+      GNUNET_JSON_pack_array_incref ("taxes",
+                                     (json_t *) taxes)),
     GNUNET_JSON_pack_uint64 ("total_stock",
                              total_stock),
-    GNUNET_JSON_pack_object_incref ("address",
-                                    (json_t *) address),
+    GNUNET_JSON_pack_allow_null (
+      GNUNET_JSON_pack_uint64 ("minimum_age",
+                               minimum_age)),
+    GNUNET_JSON_pack_allow_null (
+      GNUNET_JSON_pack_object_incref ("address",
+                                      (json_t *) address)),
     GNUNET_JSON_pack_allow_null (
       GNUNET_JSON_pack_timestamp ("next_restock",
                                   next_restock)));
@@ -235,6 +242,41 @@ TALER_MERCHANT_products_post (
 }
 
 
+struct TALER_MERCHANT_ProductsPostHandle *
+TALER_MERCHANT_products_post (
+  struct GNUNET_CURL_Context *ctx,
+  const char *backend_url,
+  const char *product_id,
+  const char *description,
+  const json_t *description_i18n,
+  const char *unit,
+  const struct TALER_Amount *price,
+  const char *image,
+  const json_t *taxes,
+  int64_t total_stock,
+  const json_t *address,
+  struct GNUNET_TIME_Timestamp next_restock,
+  TALER_MERCHANT_ProductsPostCallback cb,
+  void *cb_cls)
+{
+  return TALER_MERCHANT_products_post2 (ctx,
+                                        backend_url,
+                                        product_id,
+                                        description,
+                                        description_i18n,
+                                        unit,
+                                        price,
+                                        image,
+                                        taxes,
+                                        total_stock,
+                                        address,
+                                        next_restock,
+                                        0,
+                                        cb,
+                                        cb_cls);
+}
+
+
 void
 TALER_MERCHANT_products_post_cancel (
   struct TALER_MERCHANT_ProductsPostHandle *pph)
diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c
index e9b492b3..ed07bce6 100644
--- a/src/testing/test_merchant_api.c
+++ b/src/testing/test_merchant_api.c
@@ -599,6 +599,20 @@ run (void *cls,
                                               "a product",
                                               "EUR:1",
                                               MHD_HTTP_NO_CONTENT),
+    TALER_TESTING_cmd_merchant_post_products2 ("post-products-p4",
+                                               merchant_url,
+                                               "product-4age",
+                                               "an age-restricted product",
+                                               NULL,
+                                               "unit",
+                                               "EUR:1",
+                                               "", /* image */
+                                               NULL,
+                                               4,
+                                               16 /* minimum age */,
+                                               NULL,
+                                               GNUNET_TIME_UNIT_FOREVER_TS,
+                                               MHD_HTTP_NO_CONTENT),
     TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3",
                                               merchant_url,
                                               "product-3",
@@ -673,6 +687,25 @@ run (void *cls,
                                              "product-3/3",
                                              "lock-product-p3",
                                              NULL),
+    TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p4-age",
+                                             cred.cfg,
+                                             merchant_url,
+                                             MHD_HTTP_OK,
+                                             "order-p4-age",
+                                             GNUNET_TIME_UNIT_ZERO_TS,
+                                             GNUNET_TIME_UNIT_FOREVER_TS,
+                                             false,
+                                             "EUR:5.0",
+                                             "x-taler-bank",
+                                             "product-4age",
+                                             "", /* locks */
+                                             NULL),
+    TALER_TESTING_cmd_merchant_get_order4 ("get-order-merchant-p4-age",
+                                           merchant_url,
+                                           "create-proposal-p4-age",
+                                           TALER_MERCHANT_OSC_CLAIMED,
+                                           16,
+                                           MHD_HTTP_OK),
     TALER_TESTING_cmd_merchant_delete_order ("delete-order-paid",
                                              merchant_url,
                                              "1",
diff --git a/src/testing/testing_api_cmd_merchant_get_order.c 
b/src/testing/testing_api_cmd_merchant_get_order.c
index 1b235c93..6301c9f6 100644
--- a/src/testing/testing_api_cmd_merchant_get_order.c
+++ b/src/testing/testing_api_cmd_merchant_get_order.c
@@ -105,6 +105,11 @@ struct MerchantGetOrderState
    */
   const char *repurchase_order_ref;
 
+  /**
+   * Expected minimum age.
+   */
+  unsigned int expected_min_age;
+
   /**
    * True if we should pass the 'allow_refunded_for_repurchase' flag.
    */
@@ -176,7 +181,9 @@ merchant_get_order_cb (
     if (gos->osc != osr->details.ok.status)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Order paid does not match\n");
+                  "Order paid does not match: %d vs %d\n",
+                  gos->osc,
+                  osr->details.ok.status);
       TALER_TESTING_interpreter_fail (gos->is);
       return;
     }
@@ -187,6 +194,17 @@ merchant_get_order_cb (
         const struct TALER_TESTING_Command *order_cmd;
         struct TALER_Amount refunded_total;
 
+        if ( (0 != gos->expected_min_age) &&
+             (gos->expected_min_age !=
+              json_integer_value (
+                json_object_get (
+                  osr->details.ok.details.paid.contract_terms,
+                  "minimum_age"))) )
+        {
+          GNUNET_break (0);
+          TALER_TESTING_interpreter_fail (gos->is);
+          return;
+        }
         order_cmd = TALER_TESTING_interpreter_lookup_command (
           gos->is,
           gos->order_reference);
@@ -422,6 +440,17 @@ merchant_get_order_cb (
       break;
     case TALER_MERCHANT_OSC_CLAIMED:
       /* FIXME: Check contract terms... */
+      if ( (0 != gos->expected_min_age) &&
+           (gos->expected_min_age !=
+            json_integer_value (
+              json_object_get (
+                osr->details.ok.details.claimed.contract_terms,
+                "minimum_age"))) )
+      {
+        GNUNET_break (0);
+        TALER_TESTING_interpreter_fail (gos->is);
+        return;
+      }
       break;
     case TALER_MERCHANT_OSC_UNPAID:
       {
@@ -754,6 +783,36 @@ TALER_TESTING_cmd_merchant_get_order3 (
 }
 
 
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_merchant_get_order4 (
+  const char *label,
+  const char *merchant_url,
+  const char *order_reference,
+  enum TALER_MERCHANT_OrderStatusCode osc,
+  uint32_t expected_min_age,
+  unsigned int expected_http_status)
+{
+  struct MerchantGetOrderState *gos;
+
+  gos = GNUNET_new (struct MerchantGetOrderState);
+  gos->merchant_url = merchant_url;
+  gos->order_reference = order_reference;
+  gos->osc = osc;
+  gos->expected_min_age = expected_min_age;
+  gos->http_status = expected_http_status;
+  {
+    struct TALER_TESTING_Command cmd = {
+      .cls = gos,
+      .label = label,
+      .run = &merchant_get_order_run,
+      .cleanup = &merchant_get_order_cleanup
+    };
+
+    return cmd;
+  }
+}
+
+
 struct MerchantPollOrderConcludeState
 {
   /**
diff --git a/src/testing/testing_api_cmd_post_products.c 
b/src/testing/testing_api_cmd_post_products.c
index e98ea3c5..4ffafddc 100644
--- a/src/testing/testing_api_cmd_post_products.c
+++ b/src/testing/testing_api_cmd_post_products.c
@@ -94,6 +94,11 @@ struct PostProductsState
    */
   json_t *address;
 
+  /**
+   * Minimum age requirement to use for the product.
+   */
+  unsigned int minimum_age;
+
   /**
    * when the next restocking is expected to happen, 0 for unknown,
    */
@@ -168,7 +173,7 @@ post_products_run (void *cls,
   struct PostProductsState *pis = cls;
 
   pis->is = is;
-  pis->iph = TALER_MERCHANT_products_post (
+  pis->iph = TALER_MERCHANT_products_post2 (
     TALER_TESTING_interpreter_get_context (is),
     pis->merchant_url,
     pis->product_id,
@@ -181,6 +186,7 @@ post_products_run (void *cls,
     pis->total_stock,
     pis->address,
     pis->next_restock,
+    pis->minimum_age,
     &post_products_cb,
     pis);
   GNUNET_assert (NULL != pis->iph);
@@ -197,7 +203,7 @@ post_products_run (void *cls,
  * @param index index number of the object to extract.
  * @return #GNUNET_OK on success
  */
-static int
+static enum GNUNET_GenericReturnValue
 post_products_traits (void *cls,
                       const void **ret,
                       const char *trait,
@@ -265,6 +271,7 @@ TALER_TESTING_cmd_merchant_post_products2 (
   const char *image,
   json_t *taxes,
   int64_t total_stock,
+  uint32_t minimum_age,
   json_t *address,
   struct GNUNET_TIME_Timestamp next_restock,
   unsigned int http_status)
@@ -288,6 +295,7 @@ TALER_TESTING_cmd_merchant_post_products2 (
   pis->image = GNUNET_strdup (image);
   pis->taxes = taxes; /* ownership taken */
   pis->total_stock = total_stock;
+  pis->minimum_age = minimum_age;
   pis->address = address; /* ownership taken */
   pis->next_restock = next_restock;
   {
@@ -305,12 +313,13 @@ TALER_TESTING_cmd_merchant_post_products2 (
 
 
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_merchant_post_products (const char *label,
-                                          const char *merchant_url,
-                                          const char *product_id,
-                                          const char *description,
-                                          const char *price,
-                                          unsigned int http_status)
+TALER_TESTING_cmd_merchant_post_products (
+  const char *label,
+  const char *merchant_url,
+  const char *product_id,
+  const char *description,
+  const char *price,
+  unsigned int http_status)
 {
   return TALER_TESTING_cmd_merchant_post_products2 (
     label,
@@ -322,7 +331,8 @@ TALER_TESTING_cmd_merchant_post_products (const char *label,
     price,
     "",
     json_array (),
-    4,
+    4, /* total stock */
+    0, /* minimum age */
     json_pack ("{s:s}", "street", "my street"),
     GNUNET_TIME_UNIT_ZERO_TS,
     http_status);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]