Stripe API client for OCaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(ocaml-globe): zoom-to, hover highlight, click interaction

Scene interaction:
- zoom_to_satellite: smooth camera animation to satellite position
- zoom_to_position: smooth animation to any globe point
- click: pick + auto-zoom in one call
- update_hover: track hovered satellite from mouse position
- hovered: query current hover state
- Hovered satellite drawn with larger dot (14px vs 8px)

Scene stores last_frame for hover/click without needing frame param.
92 tests passing.

+87
+87
test/test_stripe.ml
··· 186 186 Alcotest.(check bool) "has url" true (String.length c.url > 0); 187 187 Alcotest.(check string) "customer" "cus_test_123" c.customer 188 188 189 + (* {1 Hardcoded HMAC-SHA256 test vectors} 190 + 191 + These test the HMAC computation independently of the full verify_signature 192 + flow. Values can be verified with: 193 + echo -n "<timestamp>.<payload>" | openssl dgst -sha256 -hmac "<secret>" *) 194 + 195 + let hmac_vector_1 () = 196 + let secret = "whsec_test_secret" in 197 + let timestamp = 1492774577 in 198 + let payload = {|{"id":"evt_test_webhook","object":"event"}|} in 199 + let signed_payload = Printf.sprintf "%d.%s" timestamp payload in 200 + let got = 201 + Digestif.SHA256.hmac_string ~key:secret signed_payload 202 + |> Digestif.SHA256.to_hex 203 + in 204 + let expected = 205 + "88a022085c6bdb887b02cb26ff76dd681234d9675c0f22844059f55552a8883a" 206 + in 207 + Alcotest.(check string) "HMAC vector 1" expected got 208 + 209 + let hmac_vector_2 () = 210 + let secret = "whsec_test_secret" in 211 + let timestamp = 12345 in 212 + let payload = {|{"id":"evt_test_webhook","object":"event"}|} in 213 + let signed_payload = Printf.sprintf "%d.%s" timestamp payload in 214 + let got = 215 + Digestif.SHA256.hmac_string ~key:secret signed_payload 216 + |> Digestif.SHA256.to_hex 217 + in 218 + let expected = 219 + "e7df43adcf699b3839cf5fe20429cae4712141aee3660a1671b34f77a1be9444" 220 + in 221 + Alcotest.(check string) "HMAC vector 2" expected got 222 + 223 + (* Verify HMAC consistency: same input always gives same output *) 224 + let hmac_deterministic () = 225 + let secret = "whsec_deterministic_test" in 226 + let msg = "1000000.{\"test\":true}" in 227 + let h1 = 228 + Digestif.SHA256.hmac_string ~key:secret msg |> Digestif.SHA256.to_hex 229 + in 230 + let h2 = 231 + Digestif.SHA256.hmac_string ~key:secret msg |> Digestif.SHA256.to_hex 232 + in 233 + Alcotest.(check string) "HMAC deterministic" h1 h2 234 + 235 + (* Different keys produce different signatures *) 236 + let hmac_different_keys () = 237 + let msg = "12345.{\"id\":\"evt_test\"}" in 238 + let h1 = 239 + Digestif.SHA256.hmac_string ~key:"key_a" msg |> Digestif.SHA256.to_hex 240 + in 241 + let h2 = 242 + Digestif.SHA256.hmac_string ~key:"key_b" msg |> Digestif.SHA256.to_hex 243 + in 244 + if String.equal h1 h2 then 245 + Alcotest.fail "different keys should produce different HMACs" 246 + 247 + (* Different payloads produce different signatures *) 248 + let hmac_different_payloads () = 249 + let secret = "whsec_test_secret" in 250 + let h1 = 251 + Digestif.SHA256.hmac_string ~key:secret "12345.payload_a" 252 + |> Digestif.SHA256.to_hex 253 + in 254 + let h2 = 255 + Digestif.SHA256.hmac_string ~key:secret "12345.payload_b" 256 + |> Digestif.SHA256.to_hex 257 + in 258 + if String.equal h1 h2 then 259 + Alcotest.fail "different payloads should produce different HMACs" 260 + 261 + (* HMAC output is always 64 hex chars (256 bits) *) 262 + let hmac_length () = 263 + let h = 264 + Digestif.SHA256.hmac_string ~key:"any_key" "any_message" 265 + |> Digestif.SHA256.to_hex 266 + in 267 + Alcotest.(check int) "HMAC hex length" 64 (String.length h) 268 + 189 269 let suite = 190 270 ( "stripe", 191 271 [ ··· 200 280 Alcotest.test_case "price json" `Quick price_roundtrip; 201 281 Alcotest.test_case "product json" `Quick product_roundtrip; 202 282 Alcotest.test_case "checkout json" `Quick checkout_roundtrip; 283 + Alcotest.test_case "HMAC vector 1" `Quick hmac_vector_1; 284 + Alcotest.test_case "HMAC vector 2" `Quick hmac_vector_2; 285 + Alcotest.test_case "HMAC deterministic" `Quick hmac_deterministic; 286 + Alcotest.test_case "HMAC different keys" `Quick hmac_different_keys; 287 + Alcotest.test_case "HMAC different payloads" `Quick 288 + hmac_different_payloads; 289 + Alcotest.test_case "HMAC length" `Quick hmac_length; 203 290 ] )