merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

test_contract.c (12916B)


      1 /*
      2   This file is part of TALER
      3   (C) 2015, 2021 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 
     17 /**
     18  * @file util/test_contract.c
     19  * @brief Tests for contract parsing/serializing
     20  * @author Iván Ávalos (ivan@avalos.me)
     21  */
     22 
     23 #include "platform.h"
     24 #include <gnunet/gnunet_util_lib.h>
     25 #include <gnunet/gnunet_common.h>
     26 #include <gnunet/gnunet_json_lib.h>
     27 #include "taler_merchant_util.h"
     28 #include <jansson.h>
     29 
     30 const char *contract_common = "{\n"
     31                               "  \"summary\": \"Test order\",\n"
     32                               "  \"summary_i18n\": {\n"
     33                               "    \"en\": \"Test order\",\n"
     34                               "    \"es\": \"Orden de prueba\"\n"
     35                               "  },\n"
     36                               "  \"order_id\": \"test\",\n"
     37                               "  \"public_reorder_url\": \"https://test.org/reorder\",\n"
     38                               "  \"fulfillment_url\": \"https://test.org/fulfillment\",\n"
     39                               "  \"fulfillment_message\": \"Thank you for your purchase!\",\n"
     40                               "  \"fulfillment_message_i18n\": {\n"
     41                               "    \"en\": \"Thank you for your purchase!\",\n"
     42                               "    \"es\": \"¡Gracias por su compra!\"\n"
     43                               "  },\n"
     44                               "  \"products\": [],\n"
     45                               "  \"timestamp\": {\"t_s\": 1736174497},\n"
     46                               "  \"refund_deadline\": {\"t_s\": 1736174497},\n"
     47                               "  \"pay_deadline\": {\"t_s\": 1736174497},\n"
     48                               "  \"wire_transfer_deadline\": {\"t_s\": 1736174497},\n"
     49                               "  \"merchant_pub\": \"F80MFRG8HVH6R9CQ47KRFQSJP3T6DBJ4K1D9B703RJY3Z39TBMJ0\",\n"
     50                               "  \"merchant_base_url\": \"https://test.org/merchant\",\n"
     51                               "  \"merchant\": {\n"
     52                               "    \"name\": \"Test merchant\",\n"
     53                               "    \"email\": \"test@test.org\",\n"
     54                               "    \"website\": \"https://test.org/merchant\",\n"
     55                               "    \"logo\": \"data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADRUlEQVRYhe2WXUgUURiG39l1Vt021C2piJAQyhXEXVNKysoSd8nywgLNn1CIMCLposCLxOii8KasC2+CFB1WRVASMpMUKiyIaLXyBwmhoh9Kzc1W929murAZ9+znZl2EXey5OvOc93zfO+ec+eZwZmuLjFVsmtVMHjYQNvBfGIhYSSAD6LcXYJ1RrzLO1AhzAg9oNHD0FGPBLSJ2bwuSjRE4U2rCydIdmJpxIae4C9wK8blQdUCWgaH7pepzZXUf3rx34eqFXcgwbwIANLUP40bjKzzuLIRBzwMATFY7ojgJL3pL1eRmqwAuhJNlDSiTTQebEcUv7pKjd9GMxSaouj9hHp+M0f4yeH0Sdh6xEwPkDOTu2QzuV4CVkltsAkYnptTxQI3CInkOFpsAHa9Byjbj7w2Ikoy6i9lMIh+nDfmWAFBS1UuYonX6OIY13zwEOWi9GQMv+8pwS3Awgtf3jjPJg5ME9wPZZH8Jw7r7JphzRQwAQIMwovZHZ/wkcF11Jj5/cRHumvfjVFES4Z/mRLVfe+0ZGVcNLHglMjg3eALff3gZlrs/ETnFnUSbdtiO0+XpDHN7RIz1FBKtKC3tg2rAtDUG35xuRqjjNdhd2EUC8BH0m9LraE2rrO5DXEwU4ZJ2qfyos6adXqw1RBKx0bBirQrZJj/MEyaKQKxeu4yBWTcitOybuT0i7t7OJ0G8flq7PD7KepryMb/AniOtFph1eqgB3TLLGpPVAsManmF3escx0HqUaB92HENH9wjDDHoeG7PpFxK4hWTjqspT1H6ykS7/pfrn2BCvJzzeGI0rDQ7CE2OXYtScTSfjjIFUq4CKolRGkJrXxhQZpQWyUOPbc9nSW5CXBLOVXRHGgIYDzl8eYAJqRD9JohSe+toswgK1eo3EsPJzPeSnRLag/8lHdYJy2ILru8L2ZSao/4Tg5ApzeaTFWD4Jw+MzwemWvw9YbAJkGRh5UAZg8ddssQmIitapCeZcXlhsAmqq0lX26Ok7bDlgR17Gesas2SaEvBeEvA8oTZaBgbYCGOP0aG534HrjCIam/XAPliFSp0VaXitkUcTQWx/ksQp13tdpF3JLaBH7awP/uq36nTBsIGxg1Q38BGj1Qe2GKmj3AAAAAElFTkSuQmCC\",\n"
     56                               "    \"address\": {},\n" // TODO
     57                               "    \"jurisdiction\": {}\n" // TODO
     58                               "  },\n"
     59                               "  \"h_wire\": \"WYEMPXPRA87Y1QBJAJSR5SMB8V3QN2MMHAKDAEN04XC8TQ6TBEJF5KAKT3Y8KKP9W0TW3A2PH1YB22EZJ9TA7HX1P5BFTJQ660GS1TG\",\n"
     60                               "  \"wire_method\": \"iban\",\n"
     61                               "  \"exchanges\": [],\n"
     62                               "  \"delivery_location\": {},\n" // TODO
     63                               "  \"delivery_date\": {\"t_s\": 1736174497},\n"
     64                               "  \"nonce\": \"\",\n" // TODO
     65                               "  \"auto_refund\": {\"d_us\": \"forever\"},\n"
     66                               "  \"extra\": {\n"
     67                               "    \"key0\": \"value0\",\n"
     68                               "    \"key1\": \"value1\",\n"
     69                               "    \"key2\": 2\n"
     70                               "  },\n"
     71                               "  \"minimum_age\": 100\n"
     72                               "}";
     73 
     74 const char *contract_v0 = "{\n"
     75                           "  \"version\": 0,\n"
     76                           "  \"amount\": \"KUDOS:10\",\n"
     77                           "  \"max_fee\": \"KUDOS:0.2\"\n"
     78                           "}";
     79 
     80 const char *contract_v1 = "{\n"
     81                           "  \"version\": 1,\n"
     82                           "  \"choices\": [\n"
     83                           "    {\n"
     84                           "      \"amount\": \"KUDOS:1\",\n"
     85                           "      \"max_fee\": \"KUDOS:0.5\",\n"
     86                           "      \"description\": \"Subscription in, discount out\",\n"
     87                           "      \"description_i18n\": {\n"
     88                           "        \"en\": \"This is a test choice\",\n"
     89                           "        \"es\": \"Esta es una opción de prueba\"\n"
     90                           "      },\n"
     91                           "      \"inputs\": [\n"
     92                           "        {\n"
     93                           "          \"type\": \"token\",\n"
     94                           "          \"token_family_slug\": \"test-subscription\",\n"
     95                           "          \"count\": 1\n"
     96                           "        }\n"
     97                           "      ],\n"
     98                           "      \"outputs\": [\n"
     99                           "        {\n"
    100                           "          \"type\": \"token\",\n"
    101                           "          \"token_family_slug\": \"test-discount\",\n"
    102                           "          \"count\": 2,\n"
    103                           "          \"key_index\": 0\n" // TODO
    104                           "        },\n"
    105                           "        {\n"
    106                           "          \"type\": \"tax-receipt\",\n"
    107                           "          \"donau_urls\": [\"a\", \"b\", \"c\"],\n"
    108                           "          \"amount\": \"KUDOS:10\"\n"
    109                           "        }\n"
    110                           "      ]\n"
    111                           "    }\n"
    112                           "  ],\n"
    113                           "  \"token_families\": {\n"
    114                           "    \"test-subscription\": {\n"
    115                           "      \"name\": \"Test subscription\",\n"
    116                           "      \"description\": \"This is a test subscription\",\n"
    117                           "      \"description_i18n\": {\n"
    118                           "        \"en\": \"This is a test subscription\",\n"
    119                           "        \"es\": \"Esta es una subscripción de prueba\"\n"
    120                           "      },\n"
    121                           "      \"keys\": [\n"
    122                           "        {\n"
    123                           "          \"cipher\": \"CS\",\n"
    124                           "          \"cs_pub\": \"AMGKHAWCF3Y32E64G6JV7TPP7KHE2C3QFMNZ8N66Q744FV3TH1D0\",\n"
    125                           "          \"signature_validity_start\": {\"t_s\": 1736174497},\n"
    126                           "          \"signature_validity_end\": {\"t_s\": 1736174497}\n"
    127                           "        }\n"
    128                           "      ],\n"
    129                           "      \"details\": {\n"
    130                           "        \"class\": \"subscription\",\n"
    131                           "        \"trusted_domains\": [\"a\", \"b\", \"c\"]\n"
    132                           "      },\n"
    133                           "      \"critical\": true\n"
    134                           "    },\n"
    135                           "    \"test-discount\": {\n"
    136                           "      \"name\": \"Test discount\",\n"
    137                           "      \"description\": \"This is a test discount\",\n"
    138                           "      \"description_i18n\": {\n"
    139                           "        \"en\": \"This is a test discount\",\n"
    140                           "        \"es\": \"Este es un descuento de prueba\"\n"
    141                           "      },\n"
    142                           "      \"keys\": [\n"
    143                           "        {\n"
    144                           "          \"cipher\": \"RSA\",\n"
    145                           "          \"rsa_pub\": \"040000YGF5DK0PKCN99J0V814C20Q54C82S3RE3GBVC2T4QXEP7N05ABAN5DG8BC3FTN33BSG15VFX2N9X95HE7GBDAHSYHG4G00VHDCV4E0W4HVYTZGN6SGPBMTAE1XMYBH5DFWT4TXPSEQB96AG3G65X6BPQ0WXSARD5NP2YR1CQB6GB0W2BSKZK1AXZN67GHB3HHAPFV8V584QF1DGDXEWN875RN4HYNH3AW4XZ9SP5A7J5MED56P0TXX5D8C1HPWHFD89GE6Q7J0Q3QKM18WAVAZJTF6PR3Q5T2C71ST0VTP42F16ZZRWS4CHSXHM5RW0BGH383VX4100AD61X6QQ99K12Q17EQZK5MSE6AGNK24SCAH06XTXA7WFC78V0ARJKFDX1M483GE9SX20XXFKSTQ6B8104002\",\n"
    146                           "          \"signature_validity_start\": {\"t_s\": 1736174497},\n"
    147                           "          \"signature_validity_end\": {\"t_s\": 1736174497}\n"
    148                           "        }\n"
    149                           "      ],\n"
    150                           "      \"details\": {\n"
    151                           "        \"class\": \"discount\",\n"
    152                           "        \"expected_domains\": [\"a\", \"b\", \"c\"]\n"
    153                           "      },\n"
    154                           "      \"critical\": true\n"
    155                           "    }\n"
    156                           "  }\n"
    157                           "}";
    158 
    159 
    160 int
    161 main (int argc,
    162       const char *const argv[])
    163 {
    164   (void) argc;
    165   (void) argv;
    166   GNUNET_log_setup ("test-contract",
    167                     "WARNING",
    168                     NULL);
    169 
    170   { // Contract v0
    171     json_t *common;
    172     json_t *v0;
    173     struct TALER_MERCHANT_Contract *v0_parsed;
    174     json_t *v0_serialized;
    175 
    176     common = json_loads (contract_common, 0, NULL);
    177     GNUNET_assert (NULL != common);
    178 
    179     v0 = json_loads (contract_v0, 0, NULL);
    180     GNUNET_assert (NULL != v0);
    181 
    182     GNUNET_assert (0 == json_object_update_new (v0, common));
    183 
    184     v0_parsed = TALER_MERCHANT_contract_parse (v0, false);
    185     GNUNET_assert (NULL != v0_parsed);
    186 
    187     v0_serialized = TALER_MERCHANT_contract_serialize (v0_parsed, false);
    188     GNUNET_assert (NULL != v0_serialized);
    189 
    190     GNUNET_assert (1 == json_equal (v0, v0_serialized));
    191 
    192     json_decref (v0_serialized);
    193     TALER_MERCHANT_contract_free (v0_parsed);
    194     json_decref (v0);
    195   }
    196 
    197   { // Contract v1
    198     json_t *common;
    199     json_t *v1;
    200     struct TALER_MERCHANT_Contract *v1_parsed;
    201     json_t *v1_serialized;
    202 
    203     common = json_loads (contract_common, 0, NULL);
    204     GNUNET_assert (NULL != common);
    205 
    206     v1 = json_loads (contract_v1, 0, NULL);
    207     GNUNET_assert (NULL != v1);
    208 
    209     GNUNET_assert (0 == json_object_update_new (v1, common));
    210 
    211     v1_parsed = TALER_MERCHANT_contract_parse (v1, false);
    212     GNUNET_assert (NULL != v1_parsed);
    213 
    214     v1_serialized = TALER_MERCHANT_contract_serialize (v1_parsed, false);
    215     GNUNET_assert (NULL != v1_serialized);
    216 
    217     GNUNET_assert (1 == json_equal (v1, v1_serialized));
    218 
    219     for (unsigned int i = 0;
    220          i < v1_parsed->details.v1.token_authorities_len;
    221          i++)
    222     {
    223       struct TALER_MERCHANT_ContractTokenFamily *in =
    224         &v1_parsed->details.v1.token_authorities[i];
    225       for (unsigned int j = 0; j < in->keys_len; j++)
    226       {
    227         struct TALER_MERCHANT_ContractTokenFamilyKey *inkey = &in->keys[j];
    228         struct TALER_MERCHANT_ContractTokenFamily out;
    229         struct TALER_MERCHANT_ContractTokenFamilyKey outkey;
    230         GNUNET_assert (GNUNET_OK == TALER_MERCHANT_find_token_family_key (
    231                          in->slug,
    232                          inkey->valid_after,
    233                          v1_parsed->details.v1.token_authorities,
    234                          v1_parsed->details.v1.token_authorities_len,
    235                          &out,
    236                          &outkey));
    237         GNUNET_assert (0 == GNUNET_memcmp (in, &out));
    238         GNUNET_assert (0 == GNUNET_memcmp (inkey, &outkey));
    239       }
    240     }
    241 
    242     json_decref (v1_serialized);
    243     TALER_MERCHANT_contract_free (v1_parsed);
    244     json_decref (v1);
    245   }
    246 
    247   return 0;
    248 }