synthra 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +4 -0
  3. data/.rubocop.yml +40 -0
  4. data/.yardopts +18 -0
  5. data/ACCESS_DOCS.md +116 -0
  6. data/ADVANCED_FEATURES_SUMMARY.md +245 -0
  7. data/CHANGELOG.md +498 -0
  8. data/CODE_OF_CONDUCT.md +122 -0
  9. data/CONTRIBUTING.md +307 -0
  10. data/DOCUMENTATION.md +204 -0
  11. data/DOCUMENTATION_GUIDE.md +194 -0
  12. data/LICENSE +22 -0
  13. data/README.md +1458 -0
  14. data/Rakefile +128 -0
  15. data/benchmark/README.md +591 -0
  16. data/benchmark/batch_generation.rb +63 -0
  17. data/benchmark/engine_comparison.rb +295 -0
  18. data/benchmark/single_record.rb +108 -0
  19. data/benchmark/streaming.rb +74 -0
  20. data/docs/ACTIVERECORD_INFERENCE.md +524 -0
  21. data/docs/API_SERVER.md +278 -0
  22. data/docs/CONFIG_FILE.md +315 -0
  23. data/docs/DATA_CONTRACTS.md +312 -0
  24. data/docs/ENHANCED_REPL.md +304 -0
  25. data/docs/FACTORY_BOT.md +271 -0
  26. data/docs/GITHUB_ACTION.md +420 -0
  27. data/docs/GRAPHQL_EXPORT.md +303 -0
  28. data/docs/GRAPHQL_FEDERATION.md +651 -0
  29. data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
  30. data/docs/LSP.md +189 -0
  31. data/docs/MIGRATION_GENERATOR.md +547 -0
  32. data/docs/MOCK_SERVER.md +280 -0
  33. data/docs/NATIVE_ENGINE.md +298 -0
  34. data/docs/OPENAPI_EXPORT.md +252 -0
  35. data/docs/PERFORMANCE_MODE.md +228 -0
  36. data/docs/PERSONAS.md +547 -0
  37. data/docs/PROPERTY_TESTING.md +284 -0
  38. data/docs/PROTOBUF_EXPORT.md +276 -0
  39. data/docs/QUALITY_METRICS.md +555 -0
  40. data/docs/QUICK_REFERENCE.md +88 -0
  41. data/docs/RAILS_ENGINE.md +404 -0
  42. data/docs/RAILS_INTEGRATION.md +454 -0
  43. data/docs/README.md +175 -0
  44. data/docs/REPL_QUICK_REFERENCE.md +149 -0
  45. data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
  46. data/docs/SCENARIOS.md +576 -0
  47. data/docs/SECURITY_TESTING.md +318 -0
  48. data/docs/SNAPSHOT_TESTING.md +308 -0
  49. data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
  50. data/docs/TERRAFORM_EXPORT.md +447 -0
  51. data/docs/TIME_TRAVEL.md +507 -0
  52. data/docs/USAGE_GUIDE.md +980 -0
  53. data/docs/WEBHOOK_SIMULATOR.md +579 -0
  54. data/docs/advanced_features.md +183 -0
  55. data/docs/api_reference.md +153 -0
  56. data/docs/behaviors.md +138 -0
  57. data/docs/best_practices.md +191 -0
  58. data/docs/dsl_reference.md +172 -0
  59. data/docs/examples.md +162 -0
  60. data/docs/generation_modes.md +125 -0
  61. data/docs/getting_started.md +92 -0
  62. data/docs/index.html +177 -0
  63. data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
  64. data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
  65. data/docs/troubleshooting.md +215 -0
  66. data/docs/type_reference.md +224 -0
  67. data/examples/hostile_mode_demo.rb +64 -0
  68. data/exe/synthra +6 -0
  69. data/ext/synthra_native/Cargo.lock +972 -0
  70. data/ext/synthra_native/Cargo.toml +46 -0
  71. data/ext/synthra_native/extconf.rb +41 -0
  72. data/ext/synthra_native/src/generator.rs +397 -0
  73. data/ext/synthra_native/src/lib.rs +229 -0
  74. data/ext/synthra_native/src/types.rs +1485 -0
  75. data/lib/generators/synthra/install_generator.rb +86 -0
  76. data/lib/generators/synthra/templates/api_response.dsl +15 -0
  77. data/lib/generators/synthra/templates/fake_data.rake +116 -0
  78. data/lib/generators/synthra/templates/synthra.yml +31 -0
  79. data/lib/generators/synthra/templates/synthra_support.rb +19 -0
  80. data/lib/generators/synthra/templates/user.dsl +11 -0
  81. data/lib/synthra/activerecord_inference.rb +394 -0
  82. data/lib/synthra/api.rb +381 -0
  83. data/lib/synthra/api_server.rb +718 -0
  84. data/lib/synthra/behaviors/applicator.rb +165 -0
  85. data/lib/synthra/behaviors/base.rb +155 -0
  86. data/lib/synthra/behaviors/close_connection.rb +60 -0
  87. data/lib/synthra/behaviors/deprecated.rb +100 -0
  88. data/lib/synthra/behaviors/failure.rb +69 -0
  89. data/lib/synthra/behaviors/latency.rb +103 -0
  90. data/lib/synthra/behaviors/partial_data.rb +83 -0
  91. data/lib/synthra/behaviors/randomize_order.rb +74 -0
  92. data/lib/synthra/behaviors/registry.rb +238 -0
  93. data/lib/synthra/behaviors/simulate_error.rb +79 -0
  94. data/lib/synthra/cli/commands/base.rb +105 -0
  95. data/lib/synthra/cli/commands/diff.rb +227 -0
  96. data/lib/synthra/cli/commands/docs.rb +67 -0
  97. data/lib/synthra/cli/commands/export.rb +150 -0
  98. data/lib/synthra/cli/commands/generate.rb +72 -0
  99. data/lib/synthra/cli/commands/import.rb +80 -0
  100. data/lib/synthra/cli/commands/lint.rb +53 -0
  101. data/lib/synthra/cli/commands/live.rb +57 -0
  102. data/lib/synthra/cli/commands/seed.rb +99 -0
  103. data/lib/synthra/cli/commands/validate.rb +28 -0
  104. data/lib/synthra/cli.rb +2471 -0
  105. data/lib/synthra/config_file.rb +129 -0
  106. data/lib/synthra/configuration.rb +281 -0
  107. data/lib/synthra/contracts_registry.rb +408 -0
  108. data/lib/synthra/database_seeder.rb +268 -0
  109. data/lib/synthra/deterministic_ids.rb +218 -0
  110. data/lib/synthra/documentation_generator.rb +414 -0
  111. data/lib/synthra/engine.rb +251 -0
  112. data/lib/synthra/errors.rb +1169 -0
  113. data/lib/synthra/export/base.rb +85 -0
  114. data/lib/synthra/export/csv.rb +101 -0
  115. data/lib/synthra/export/graphql.rb +266 -0
  116. data/lib/synthra/export/graphql_federation.rb +377 -0
  117. data/lib/synthra/export/graphviz.rb +258 -0
  118. data/lib/synthra/export/javascript.rb +327 -0
  119. data/lib/synthra/export/json_data.rb +61 -0
  120. data/lib/synthra/export/json_schema.rb +290 -0
  121. data/lib/synthra/export/openapi.rb +514 -0
  122. data/lib/synthra/export/protobuf.rb +483 -0
  123. data/lib/synthra/export/python.rb +560 -0
  124. data/lib/synthra/export/sql.rb +381 -0
  125. data/lib/synthra/export/sql_insert.rb +152 -0
  126. data/lib/synthra/export/terraform.rb +501 -0
  127. data/lib/synthra/export/type_mapping.rb +389 -0
  128. data/lib/synthra/export/typescript.rb +300 -0
  129. data/lib/synthra/export/xml_data.rb +104 -0
  130. data/lib/synthra/export/yaml_data.rb +56 -0
  131. data/lib/synthra/export.rb +404 -0
  132. data/lib/synthra/factory_bot_integration.rb +157 -0
  133. data/lib/synthra/field.rb +440 -0
  134. data/lib/synthra/functions/registry.rb +104 -0
  135. data/lib/synthra/generator/context.rb +372 -0
  136. data/lib/synthra/generator/engine.rb +336 -0
  137. data/lib/synthra/generator/faker_adapter.rb +425 -0
  138. data/lib/synthra/generator/modes.rb +444 -0
  139. data/lib/synthra/generator/resolver.rb +256 -0
  140. data/lib/synthra/generator/rng.rb +273 -0
  141. data/lib/synthra/generator/streamer.rb +63 -0
  142. data/lib/synthra/generator/uniqueness.rb +118 -0
  143. data/lib/synthra/initializer.rb +97 -0
  144. data/lib/synthra/limits.rb +279 -0
  145. data/lib/synthra/live_preview.rb +518 -0
  146. data/lib/synthra/loader_config.rb +78 -0
  147. data/lib/synthra/lsp/server.rb +689 -0
  148. data/lib/synthra/migration_generator.rb +301 -0
  149. data/lib/synthra/mixin.rb +174 -0
  150. data/lib/synthra/mock_server.rb +458 -0
  151. data/lib/synthra/native_engine.rb +304 -0
  152. data/lib/synthra/openapi_importer.rb +228 -0
  153. data/lib/synthra/output/json_formatter.rb +40 -0
  154. data/lib/synthra/output/ndjson_formatter.rb +55 -0
  155. data/lib/synthra/parser/ast.rb +1287 -0
  156. data/lib/synthra/parser/lexer.rb +1152 -0
  157. data/lib/synthra/parser/parser.rb +1664 -0
  158. data/lib/synthra/parser/tokens.rb +461 -0
  159. data/lib/synthra/performance_mode.rb +364 -0
  160. data/lib/synthra/personas.rb +397 -0
  161. data/lib/synthra/property_testing.rb +172 -0
  162. data/lib/synthra/quality_metrics.rb +405 -0
  163. data/lib/synthra/rails_test_helper.rb +248 -0
  164. data/lib/synthra/registry.rb +533 -0
  165. data/lib/synthra/relationships.rb +193 -0
  166. data/lib/synthra/repl/enhanced_repl.rb +607 -0
  167. data/lib/synthra/repl/formatter.rb +191 -0
  168. data/lib/synthra/scenarios.rb +423 -0
  169. data/lib/synthra/schema.rb +605 -0
  170. data/lib/synthra/schema_inheritance.rb +104 -0
  171. data/lib/synthra/schema_versioning.rb +212 -0
  172. data/lib/synthra/snapshot_testing.rb +199 -0
  173. data/lib/synthra/time_travel.rb +338 -0
  174. data/lib/synthra/type_definitions.rb +274 -0
  175. data/lib/synthra/types/address_location/addresses.rb +125 -0
  176. data/lib/synthra/types/address_location/airports.rb +200 -0
  177. data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
  178. data/lib/synthra/types/address_location/locations.rb +406 -0
  179. data/lib/synthra/types/base.rb +48 -0
  180. data/lib/synthra/types/commerce_products/commerce.rb +119 -0
  181. data/lib/synthra/types/commerce_products/companies.rb +71 -0
  182. data/lib/synthra/types/commerce_products/construction.rb +126 -0
  183. data/lib/synthra/types/commerce_products/products.rb +205 -0
  184. data/lib/synthra/types/core/collections.rb +513 -0
  185. data/lib/synthra/types/core/defaults.rb +76 -0
  186. data/lib/synthra/types/core/enums.rb +102 -0
  187. data/lib/synthra/types/core/identifiers.rb +445 -0
  188. data/lib/synthra/types/core/primitives.rb +586 -0
  189. data/lib/synthra/types/core/references.rb +466 -0
  190. data/lib/synthra/types/core/sequences.rb +304 -0
  191. data/lib/synthra/types/crypto/crypto.rb +162 -0
  192. data/lib/synthra/types/date_time/dates.rb +387 -0
  193. data/lib/synthra/types/finance_banking/banking.rb +424 -0
  194. data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
  195. data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
  196. data/lib/synthra/types/formula.rb +184 -0
  197. data/lib/synthra/types/health_medical/medical.rb +150 -0
  198. data/lib/synthra/types/hostile_payloads.rb +122 -0
  199. data/lib/synthra/types/json_array.rb +51 -0
  200. data/lib/synthra/types/media_entertainment/media.rb +62 -0
  201. data/lib/synthra/types/naughty_string.rb +30 -0
  202. data/lib/synthra/types/personal_names/chinese.rb +41 -0
  203. data/lib/synthra/types/personal_names/identifiers.rb +187 -0
  204. data/lib/synthra/types/personal_names/names.rb +246 -0
  205. data/lib/synthra/types/personal_names/national_id.rb +89 -0
  206. data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
  207. data/lib/synthra/types/regex.rb +248 -0
  208. data/lib/synthra/types/registry.rb +182 -0
  209. data/lib/synthra/types/repeating_element.rb +50 -0
  210. data/lib/synthra/types/scenario.rb +29 -0
  211. data/lib/synthra/types/technology_internet/apps.rb +67 -0
  212. data/lib/synthra/types/technology_internet/communication.rb +162 -0
  213. data/lib/synthra/types/technology_internet/devices.rb +80 -0
  214. data/lib/synthra/types/technology_internet/formats.rb +139 -0
  215. data/lib/synthra/types/technology_internet/networking.rb +143 -0
  216. data/lib/synthra/types/template.rb +92 -0
  217. data/lib/synthra/types/text_content/business.rb +128 -0
  218. data/lib/synthra/types/text_content/colors.rb +70 -0
  219. data/lib/synthra/types/text_content/misc.rb +237 -0
  220. data/lib/synthra/types/text_content/security.rb +130 -0
  221. data/lib/synthra/types/text_content/text_generation.rb +532 -0
  222. data/lib/synthra/types/travel/travel.rb +150 -0
  223. data/lib/synthra/utils/string_distance.rb +133 -0
  224. data/lib/synthra/validator/dsl_validator.rb +339 -0
  225. data/lib/synthra/validator/path_validator.rb +615 -0
  226. data/lib/synthra/version.rb +35 -0
  227. data/lib/synthra/webhook_simulator.rb +341 -0
  228. data/lib/synthra.rb +259 -0
  229. data/schemas/address.dsl +16 -0
  230. data/schemas/api_response.dsl +8 -0
  231. data/schemas/error_payload.dsl +9 -0
  232. data/schemas/order.dsl +10 -0
  233. data/schemas/order_item.dsl +8 -0
  234. data/schemas/payment.dsl +11 -0
  235. data/schemas/social_post.dsl +13 -0
  236. data/schemas/user.dsl +10 -0
  237. data/scripts/batch_fix_all.rb +96 -0
  238. data/scripts/delete_old_files.rb +32 -0
  239. data/scripts/fix_all_grouped_files.rb +137 -0
  240. data/scripts/fix_all_indentation.rb +48 -0
  241. data/scripts/fix_all_syntax.rb +124 -0
  242. data/scripts/fix_grouped_files.rb +184 -0
  243. data/scripts/fix_syntax_errors.rb +108 -0
  244. data/scripts/group_domain_types.rb +112 -0
  245. data/scripts/group_domain_types_fixed.rb +150 -0
  246. data/scripts/merge_domains_to_one_file.rb +68 -0
  247. data/scripts/move_existing_types.rb +130 -0
  248. data/scripts/split_grouped_types.rb +142 -0
  249. data/tech_docs/README.md +134 -0
  250. data/tech_docs/advanced/streaming.md +405 -0
  251. data/tech_docs/advanced/thread_safety.md +253 -0
  252. data/tech_docs/api/overview.md +485 -0
  253. data/tech_docs/appendices/type_chart.md +193 -0
  254. data/tech_docs/basic_concepts.md +383 -0
  255. data/tech_docs/behaviors/overview.md +346 -0
  256. data/tech_docs/dsl/complex_types.md +790 -0
  257. data/tech_docs/dsl/core_types.md +464 -0
  258. data/tech_docs/dsl/datetime_types.md +325 -0
  259. data/tech_docs/dsl/field_modifiers.md +414 -0
  260. data/tech_docs/dsl/grammar.md +431 -0
  261. data/tech_docs/dsl/schema_definition.md +399 -0
  262. data/tech_docs/export/README.md +276 -0
  263. data/tech_docs/installation.md +273 -0
  264. data/tech_docs/integration/ci_cd.md +707 -0
  265. data/tech_docs/integration/ci_cd_guide.md +579 -0
  266. data/tech_docs/integration/factory_bot.md +485 -0
  267. data/tech_docs/integration/rails.md +630 -0
  268. data/tech_docs/integration/rspec.md +449 -0
  269. data/tech_docs/modes/overview.md +350 -0
  270. data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
  271. data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
  272. data/tech_docs/quick_start.md +256 -0
  273. data/tech_docs/templates/README.md +805 -0
  274. data/tech_docs/tutorials/advanced.md +371 -0
  275. data/tech_docs/tutorials/getting_started.md +189 -0
  276. data/tech_docs/tutorials/intermediate.md +231 -0
  277. data/tech_docs/tutorials/template_gallery.md +569 -0
  278. data/tech_example/01_basic_usage.rb +238 -0
  279. data/tech_example/02_types_demo.rb +336 -0
  280. data/tech_example/04_cli_usage.md +429 -0
  281. data/tech_example/05_database_seeding.rb +283 -0
  282. data/tech_example/07_rspec_integration.rb +359 -0
  283. data/tech_example/10_custom_types.rb +387 -0
  284. data/tech_example/12_behaviors.rb +372 -0
  285. data/tech_example/13_twitter_dm_example.rb +120 -0
  286. data/tech_example/14_exact_json_structure.rb +253 -0
  287. data/tech_example/16_lsp_server.rb +56 -0
  288. data/tech_example/17_property_testing.rb +92 -0
  289. data/tech_example/18_enhanced_repl.rb +120 -0
  290. data/tech_example/19_security_fuzzing.rb +145 -0
  291. data/tech_example/NEW_FEATURES.md +169 -0
  292. data/tech_example/README.md +118 -0
  293. data/tech_example/schemas/api_response.dsl +123 -0
  294. data/tech_example/schemas/ecommerce.dsl +121 -0
  295. data/tech_example/schemas/twitter_dm.dsl +109 -0
  296. data/tech_example/schemas/user.dsl +36 -0
  297. data/vscode-extension/README.md +246 -0
  298. data/vscode-extension/language-configuration.json +31 -0
  299. data/vscode-extension/package.json +55 -0
  300. data/vscode-extension/snippets/fakedatadsl.json +198 -0
  301. data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
  302. metadata +478 -0
@@ -0,0 +1,579 @@
1
+ # Webhook Simulation
2
+
3
+ FakeDataDSL's Webhook Simulator lets you **send realistic webhook payloads** to your application, simulating events from external services like Stripe, GitHub, Twilio, and more.
4
+
5
+ ## Quick Start
6
+
7
+ ```ruby
8
+ # Configure the simulator
9
+ FakeDataDSL::WebhookSimulator.configure do |config|
10
+ config.endpoint = "http://localhost:3000/webhooks"
11
+ config.secret = "whsec_your_webhook_secret"
12
+ end
13
+
14
+ # Send a webhook
15
+ FakeDataDSL::WebhookSimulator.send(
16
+ "stripe.payment_intent.succeeded",
17
+ schema: "StripePaymentIntent"
18
+ )
19
+ ```
20
+
21
+ ## Basic Usage
22
+
23
+ ### Simple Webhook
24
+
25
+ ```ruby
26
+ # Send webhook with generated data
27
+ FakeDataDSL::WebhookSimulator.send(
28
+ "user.created",
29
+ schema: "User"
30
+ )
31
+
32
+ # With custom payload overrides
33
+ FakeDataDSL::WebhookSimulator.send(
34
+ "order.completed",
35
+ schema: "Order",
36
+ data: { status: "completed", total: 99.99 }
37
+ )
38
+ ```
39
+
40
+ ### With Delay
41
+
42
+ ```ruby
43
+ # Simulate network latency
44
+ FakeDataDSL::WebhookSimulator.send(
45
+ "payment.failed",
46
+ schema: "PaymentEvent",
47
+ delay: 2.seconds
48
+ )
49
+ ```
50
+
51
+ ### Batch Webhooks
52
+
53
+ ```ruby
54
+ # Send multiple webhooks in sequence
55
+ FakeDataDSL::WebhookSimulator.send_batch([
56
+ { event: "order.created", schema: "Order" },
57
+ { event: "payment.processing", schema: "Payment", delay: 1.second },
58
+ { event: "payment.succeeded", schema: "Payment", delay: 2.seconds },
59
+ { event: "order.completed", schema: "Order", delay: 3.seconds }
60
+ ])
61
+ ```
62
+
63
+ ## Configuration
64
+
65
+ ### Global Configuration
66
+
67
+ ```ruby
68
+ FakeDataDSL::WebhookSimulator.configure do |config|
69
+ # Target endpoint
70
+ config.endpoint = "http://localhost:3000/webhooks"
71
+
72
+ # Webhook secret for signatures
73
+ config.secret = ENV["WEBHOOK_SECRET"]
74
+
75
+ # Default headers
76
+ config.headers = {
77
+ "Content-Type" => "application/json",
78
+ "User-Agent" => "FakeDataDSL-WebhookSimulator/1.0"
79
+ }
80
+
81
+ # Timeout settings
82
+ config.timeout = 30
83
+ config.open_timeout = 5
84
+
85
+ # Retry settings
86
+ config.max_retries = 3
87
+ config.retry_delay = 1.second
88
+
89
+ # Logging
90
+ config.logger = Rails.logger
91
+ config.log_level = :info
92
+ end
93
+ ```
94
+
95
+ ### Per-Request Configuration
96
+
97
+ ```ruby
98
+ FakeDataDSL::WebhookSimulator.send(
99
+ "event.name",
100
+ schema: "Schema",
101
+ config: {
102
+ endpoint: "http://different-endpoint.com/hooks",
103
+ secret: "different_secret",
104
+ timeout: 60
105
+ }
106
+ )
107
+ ```
108
+
109
+ ## Webhook Signatures
110
+
111
+ ### Automatic Signing
112
+
113
+ Webhooks are automatically signed based on the provider type:
114
+
115
+ ```ruby
116
+ # Stripe-style signature (HMAC-SHA256)
117
+ FakeDataDSL::WebhookSimulator.send(
118
+ "payment_intent.succeeded",
119
+ schema: "StripePayment",
120
+ signature_type: :stripe
121
+ )
122
+ # Adds: Stripe-Signature: t=1234567890,v1=abc123...
123
+
124
+ # GitHub-style signature
125
+ FakeDataDSL::WebhookSimulator.send(
126
+ "push",
127
+ schema: "GitHubPush",
128
+ signature_type: :github
129
+ )
130
+ # Adds: X-Hub-Signature-256: sha256=abc123...
131
+
132
+ # Custom signature
133
+ FakeDataDSL::WebhookSimulator.send(
134
+ "custom.event",
135
+ schema: "Custom",
136
+ signature: ->(payload, secret) {
137
+ OpenSSL::HMAC.hexdigest("SHA512", secret, payload)
138
+ },
139
+ signature_header: "X-Custom-Signature"
140
+ )
141
+ ```
142
+
143
+ ### Supported Signature Types
144
+
145
+ | Provider | Type | Header |
146
+ |----------|------|--------|
147
+ | Stripe | `:stripe` | `Stripe-Signature` |
148
+ | GitHub | `:github` | `X-Hub-Signature-256` |
149
+ | Twilio | `:twilio` | `X-Twilio-Signature` |
150
+ | Shopify | `:shopify` | `X-Shopify-Hmac-SHA256` |
151
+ | Custom | `:custom` | Configurable |
152
+
153
+ ## Provider Presets
154
+
155
+ ### Stripe
156
+
157
+ ```ruby
158
+ FakeDataDSL::WebhookSimulator.stripe(
159
+ "payment_intent.succeeded",
160
+ data: {
161
+ amount: 2000,
162
+ currency: "usd",
163
+ customer: "cus_123"
164
+ }
165
+ )
166
+
167
+ # Uses built-in Stripe event schemas
168
+ # Automatically formats as Stripe webhook structure:
169
+ # {
170
+ # "id": "evt_...",
171
+ # "object": "event",
172
+ # "type": "payment_intent.succeeded",
173
+ # "data": { "object": { ... } }
174
+ # }
175
+ ```
176
+
177
+ ### GitHub
178
+
179
+ ```ruby
180
+ FakeDataDSL::WebhookSimulator.github(
181
+ "push",
182
+ repository: "owner/repo",
183
+ data: {
184
+ ref: "refs/heads/main",
185
+ commits: [{ message: "Update README" }]
186
+ }
187
+ )
188
+ ```
189
+
190
+ ### Twilio
191
+
192
+ ```ruby
193
+ FakeDataDSL::WebhookSimulator.twilio(
194
+ "message.received",
195
+ data: {
196
+ from: "+15551234567",
197
+ body: "Hello, world!"
198
+ }
199
+ )
200
+ ```
201
+
202
+ ### Custom Provider
203
+
204
+ ```ruby
205
+ FakeDataDSL::WebhookSimulator.register_provider(:my_service) do |config|
206
+ config.base_url = "https://my-service.com"
207
+ config.signature_type = :hmac_sha256
208
+ config.signature_header = "X-MyService-Signature"
209
+ config.event_wrapper = ->(event, data) {
210
+ {
211
+ event_type: event,
212
+ timestamp: Time.current.iso8601,
213
+ payload: data
214
+ }
215
+ }
216
+ end
217
+
218
+ # Use registered provider
219
+ FakeDataDSL::WebhookSimulator.my_service(
220
+ "user.updated",
221
+ schema: "User"
222
+ )
223
+ ```
224
+
225
+ ## Event Sequences
226
+
227
+ ### Define Sequences
228
+
229
+ ```ruby
230
+ # Define a sequence of related events
231
+ FakeDataDSL::WebhookSimulator.define_sequence(:checkout_flow) do
232
+ # Step 1: Cart created
233
+ step "cart.created", schema: "Cart"
234
+
235
+ # Step 2: Payment initiated (after 1 second)
236
+ step "payment.initiated", schema: "Payment", delay: 1.second
237
+
238
+ # Step 3: Payment succeeded (after 2 more seconds)
239
+ step "payment.succeeded", schema: "Payment", delay: 2.seconds
240
+
241
+ # Step 4: Order created
242
+ step "order.created", schema: "Order", delay: 500.milliseconds
243
+
244
+ # Step 5: Email sent
245
+ step "notification.sent", schema: "Notification", delay: 1.second
246
+ end
247
+ ```
248
+
249
+ ### Run Sequences
250
+
251
+ ```ruby
252
+ # Run the sequence
253
+ FakeDataDSL::WebhookSimulator.run_sequence(:checkout_flow)
254
+
255
+ # Run with shared context (data passed between steps)
256
+ FakeDataDSL::WebhookSimulator.run_sequence(:checkout_flow,
257
+ context: { user_id: "user_123", amount: 99.99 }
258
+ )
259
+
260
+ # Run with callbacks
261
+ FakeDataDSL::WebhookSimulator.run_sequence(:checkout_flow) do |step, response|
262
+ puts "Step #{step.name}: #{response.status}"
263
+ end
264
+ ```
265
+
266
+ ### Conditional Steps
267
+
268
+ ```ruby
269
+ FakeDataDSL::WebhookSimulator.define_sequence(:payment_flow) do
270
+ step "payment.initiated", schema: "Payment"
271
+
272
+ # Branch based on previous response
273
+ branch do |context|
274
+ if context[:payment_method] == "card"
275
+ step "payment.card.processing", schema: "CardPayment"
276
+ else
277
+ step "payment.bank.processing", schema: "BankPayment"
278
+ end
279
+ end
280
+
281
+ step "payment.completed", schema: "Payment"
282
+ end
283
+ ```
284
+
285
+ ## Testing Integration
286
+
287
+ ### RSpec Helpers
288
+
289
+ ```ruby
290
+ # spec/rails_helper.rb
291
+ require 'fake_data_dsl/webhook_simulator/rspec'
292
+
293
+ RSpec.configure do |config|
294
+ config.include FakeDataDSL::WebhookSimulator::RSpecHelpers
295
+ end
296
+ ```
297
+
298
+ ```ruby
299
+ # spec/webhooks/stripe_spec.rb
300
+ RSpec.describe "Stripe Webhooks", type: :request do
301
+ it "handles payment_intent.succeeded" do
302
+ simulate_webhook "stripe.payment_intent.succeeded",
303
+ schema: "StripePayment",
304
+ data: { amount: 5000 }
305
+
306
+ expect(response).to have_http_status(:ok)
307
+ expect(Payment.last.amount).to eq(50.00)
308
+ end
309
+
310
+ it "handles the full checkout sequence" do
311
+ simulate_webhook_sequence :checkout_flow
312
+
313
+ expect(Order.count).to eq(1)
314
+ expect(Order.last.status).to eq("completed")
315
+ end
316
+ end
317
+ ```
318
+
319
+ ### Minitest Helpers
320
+
321
+ ```ruby
322
+ # test/test_helper.rb
323
+ require 'fake_data_dsl/webhook_simulator/minitest'
324
+
325
+ class ActiveSupport::TestCase
326
+ include FakeDataDSL::WebhookSimulator::MinitestHelpers
327
+ end
328
+ ```
329
+
330
+ ```ruby
331
+ # test/integration/webhooks_test.rb
332
+ class WebhooksTest < ActionDispatch::IntegrationTest
333
+ test "handles stripe webhook" do
334
+ simulate_webhook "stripe.payment_intent.succeeded",
335
+ schema: "StripePayment"
336
+
337
+ assert_response :success
338
+ end
339
+ end
340
+ ```
341
+
342
+ ## Error Simulation
343
+
344
+ ### Simulate Failures
345
+
346
+ ```ruby
347
+ # Simulate webhook delivery failure
348
+ FakeDataDSL::WebhookSimulator.send(
349
+ "event.name",
350
+ schema: "Schema",
351
+ simulate_failure: true # Returns 500 error simulation
352
+ )
353
+
354
+ # Simulate timeout
355
+ FakeDataDSL::WebhookSimulator.send(
356
+ "event.name",
357
+ schema: "Schema",
358
+ simulate_timeout: true
359
+ )
360
+
361
+ # Simulate partial failure (intermittent)
362
+ FakeDataDSL::WebhookSimulator.send(
363
+ "event.name",
364
+ schema: "Schema",
365
+ failure_rate: 0.3 # 30% chance of failure
366
+ )
367
+ ```
368
+
369
+ ### Retry Testing
370
+
371
+ ```ruby
372
+ # Test retry behavior
373
+ FakeDataDSL::WebhookSimulator.send(
374
+ "event.name",
375
+ schema: "Schema",
376
+ fail_first_n: 2 # Fail first 2 attempts, succeed on 3rd
377
+ )
378
+ ```
379
+
380
+ ## Recording and Replay
381
+
382
+ ### Record Webhooks
383
+
384
+ ```ruby
385
+ # Record all webhooks sent
386
+ FakeDataDSL::WebhookSimulator.start_recording
387
+
388
+ # ... send webhooks ...
389
+
390
+ # Stop and save
391
+ recordings = FakeDataDSL::WebhookSimulator.stop_recording
392
+ recordings.save_to("spec/fixtures/webhooks/checkout_flow.json")
393
+ ```
394
+
395
+ ### Replay Recordings
396
+
397
+ ```ruby
398
+ # Replay recorded webhooks
399
+ FakeDataDSL::WebhookSimulator.replay("spec/fixtures/webhooks/checkout_flow.json")
400
+
401
+ # With timing
402
+ FakeDataDSL::WebhookSimulator.replay("recordings.json",
403
+ preserve_timing: true # Replay with original delays
404
+ )
405
+ ```
406
+
407
+ ## CLI Commands
408
+
409
+ ```bash
410
+ # Send single webhook
411
+ fake_data_dsl webhook send user.created \
412
+ --schema User \
413
+ --endpoint http://localhost:3000/webhooks \
414
+ --secret whsec_xxx
415
+
416
+ # Send with data override
417
+ fake_data_dsl webhook send payment.succeeded \
418
+ --schema Payment \
419
+ --data '{"amount": 9999}' \
420
+ --endpoint http://localhost:3000/webhooks
421
+
422
+ # Run sequence
423
+ fake_data_dsl webhook sequence checkout_flow \
424
+ --endpoint http://localhost:3000/webhooks
425
+
426
+ # Record mode
427
+ fake_data_dsl webhook record \
428
+ --output recordings/session.json \
429
+ --duration 60 # Record for 60 seconds
430
+
431
+ # Replay recordings
432
+ fake_data_dsl webhook replay recordings/session.json \
433
+ --endpoint http://localhost:3000/webhooks
434
+ ```
435
+
436
+ ## API Reference
437
+
438
+ ### WebhookSimulator.send
439
+
440
+ ```ruby
441
+ FakeDataDSL::WebhookSimulator.send(event_name, options = {})
442
+ ```
443
+
444
+ **Parameters:**
445
+ - `event_name` - Event type string (e.g., "user.created")
446
+ - `options[:schema]` - Schema name for payload generation
447
+ - `options[:data]` - Override data
448
+ - `options[:delay]` - Delay before sending
449
+ - `options[:endpoint]` - Override endpoint
450
+ - `options[:secret]` - Override secret
451
+ - `options[:signature_type]` - Signature type
452
+ - `options[:headers]` - Additional headers
453
+ - `options[:config]` - Full config override
454
+
455
+ **Returns:** `WebhookResponse` object
456
+
457
+ ### WebhookSimulator.send_batch
458
+
459
+ ```ruby
460
+ FakeDataDSL::WebhookSimulator.send_batch(webhooks)
461
+ ```
462
+
463
+ **Parameters:**
464
+ - `webhooks` - Array of webhook configurations
465
+
466
+ **Returns:** Array of `WebhookResponse` objects
467
+
468
+ ### WebhookSimulator.define_sequence
469
+
470
+ ```ruby
471
+ FakeDataDSL::WebhookSimulator.define_sequence(name, &block)
472
+ ```
473
+
474
+ **Parameters:**
475
+ - `name` - Sequence name
476
+ - `block` - Sequence definition block
477
+
478
+ ### WebhookSimulator.run_sequence
479
+
480
+ ```ruby
481
+ FakeDataDSL::WebhookSimulator.run_sequence(name, options = {}, &callback)
482
+ ```
483
+
484
+ **Parameters:**
485
+ - `name` - Sequence name
486
+ - `options[:context]` - Shared context data
487
+ - `callback` - Optional callback for each step
488
+
489
+ **Returns:** Array of `WebhookResponse` objects
490
+
491
+ ## Best Practices
492
+
493
+ ### 1. Use Consistent Secrets
494
+
495
+ ```ruby
496
+ # config/environments/test.rb
497
+ ENV["WEBHOOK_SECRET"] = "test_webhook_secret"
498
+
499
+ # spec/rails_helper.rb
500
+ FakeDataDSL::WebhookSimulator.configure do |config|
501
+ config.secret = ENV["WEBHOOK_SECRET"]
502
+ end
503
+ ```
504
+
505
+ ### 2. Test Error Handling
506
+
507
+ ```ruby
508
+ it "handles webhook failures gracefully" do
509
+ simulate_webhook "payment.failed",
510
+ schema: "FailedPayment",
511
+ data: { error_code: "card_declined" }
512
+
513
+ expect(response).to have_http_status(:ok)
514
+ expect(Payment.last.status).to eq("failed")
515
+ expect(User.last).to have_received_email(:payment_failed)
516
+ end
517
+ ```
518
+
519
+ ### 3. Use Sequences for Complex Flows
520
+
521
+ ```ruby
522
+ # Better than individual webhook tests
523
+ simulate_webhook_sequence :full_order_lifecycle
524
+
525
+ # Instead of:
526
+ simulate_webhook "order.created"
527
+ simulate_webhook "payment.succeeded"
528
+ simulate_webhook "order.shipped"
529
+ simulate_webhook "order.delivered"
530
+ ```
531
+
532
+ ### 4. Record Production Webhooks for Testing
533
+
534
+ ```ruby
535
+ # In development, record real webhooks
536
+ # Then replay in tests for realistic scenarios
537
+ ```
538
+
539
+ ## Troubleshooting
540
+
541
+ ### Signature Verification Failing
542
+
543
+ ```ruby
544
+ # Make sure secrets match
545
+ FakeDataDSL::WebhookSimulator.configure do |config|
546
+ config.secret = ENV["WEBHOOK_SECRET"] # Same as your app uses
547
+ end
548
+
549
+ # Debug signature
550
+ response = FakeDataDSL::WebhookSimulator.send(...)
551
+ puts response.request_headers["Stripe-Signature"]
552
+ ```
553
+
554
+ ### Timeout Issues
555
+
556
+ ```ruby
557
+ # Increase timeout
558
+ FakeDataDSL::WebhookSimulator.configure do |config|
559
+ config.timeout = 60
560
+ config.open_timeout = 10
561
+ end
562
+ ```
563
+
564
+ ### Endpoint Not Reachable
565
+
566
+ ```ruby
567
+ # Make sure your server is running
568
+ # In tests, use request specs not system specs
569
+ RSpec.describe "Webhooks", type: :request do
570
+ # This runs against the test server
571
+ end
572
+ ```
573
+
574
+ ## See Also
575
+
576
+ - [Mock Server](MOCK_SERVER.md)
577
+ - [API Server](API_SERVER.md)
578
+ - [Scenarios](SCENARIOS.md)
579
+ - [Testing Best Practices](best_practices.md)