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 }