maytes-api-client-rb 0.1.1
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.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/LICENSE +21 -0
- data/README.md +47 -0
- data/Rakefile +10 -0
- data/docs/CancelCheckout409Response.md +24 -0
- data/docs/CancelCheckoutRequest.md +18 -0
- data/docs/CancelCheckoutResponse.md +18 -0
- data/docs/CaptureCheckout409Response.md +24 -0
- data/docs/CaptureCheckout422Response.md +24 -0
- data/docs/CaptureCheckoutRequest.md +24 -0
- data/docs/CaptureCheckoutResponse.md +18 -0
- data/docs/Checkout.md +48 -0
- data/docs/CheckoutCancelled.md +22 -0
- data/docs/CheckoutCaptured.md +28 -0
- data/docs/CheckoutCreated.md +24 -0
- data/docs/CheckoutDiscount.md +30 -0
- data/docs/CheckoutFee.md +32 -0
- data/docs/CreateCheckout401Response.md +24 -0
- data/docs/CreateCheckout409Response.md +24 -0
- data/docs/CreateCheckout422Response.md +24 -0
- data/docs/CreateCheckoutRequest.md +44 -0
- data/docs/CreateCheckoutResponse.md +18 -0
- data/docs/CreateRefundRequest.md +20 -0
- data/docs/CustomerData.md +22 -0
- data/docs/DefaultApi.md +633 -0
- data/docs/DigitalGoodsCustomData.md +18 -0
- data/docs/DigitalGoodsLineItem.md +38 -0
- data/docs/DonationLineItem.md +36 -0
- data/docs/ErrorResponseDto.md +24 -0
- data/docs/Fee.md +24 -0
- data/docs/FeeBreakdownLine.md +24 -0
- data/docs/FoodBeverageLineItem.md +36 -0
- data/docs/GetCheckout404Response.md +24 -0
- data/docs/GetCheckout422Response.md +24 -0
- data/docs/GetCheckoutResponse.md +18 -0
- data/docs/GetSettlementResponse.md +18 -0
- data/docs/HealthResponse.md +18 -0
- data/docs/LineItem.md +94 -0
- data/docs/ListSettlementsResponse.md +18 -0
- data/docs/OAuthTokenRequest.md +30 -0
- data/docs/OAuthTokenResponse.md +26 -0
- data/docs/OtherLineItem.md +36 -0
- data/docs/PhysicalGoodsCustomData.md +20 -0
- data/docs/PhysicalGoodsLineItem.md +38 -0
- data/docs/RefundCheckout402Response.md +24 -0
- data/docs/RefundCheckout409Response.md +24 -0
- data/docs/ServiceCustomData.md +18 -0
- data/docs/ServiceLineItem.md +38 -0
- data/docs/Settlement.md +52 -0
- data/docs/Tax.md +22 -0
- data/docs/TicketCustomData.md +40 -0
- data/docs/TicketLineItem.md +38 -0
- data/docs/TicketSeating.md +24 -0
- data/lib/maytes_api_client/api/default_api.rb +642 -0
- data/lib/maytes_api_client/api_client.rb +397 -0
- data/lib/maytes_api_client/api_error.rb +58 -0
- data/lib/maytes_api_client/api_model_base.rb +88 -0
- data/lib/maytes_api_client/configuration.rb +316 -0
- data/lib/maytes_api_client/managed_client.rb +140 -0
- data/lib/maytes_api_client/models/cancel_checkout409_response.rb +258 -0
- data/lib/maytes_api_client/models/cancel_checkout_request.rb +147 -0
- data/lib/maytes_api_client/models/cancel_checkout_response.rb +164 -0
- data/lib/maytes_api_client/models/capture_checkout409_response.rb +258 -0
- data/lib/maytes_api_client/models/capture_checkout422_response.rb +258 -0
- data/lib/maytes_api_client/models/capture_checkout_request.rb +218 -0
- data/lib/maytes_api_client/models/capture_checkout_response.rb +164 -0
- data/lib/maytes_api_client/models/checkout.rb +483 -0
- data/lib/maytes_api_client/models/checkout_cancelled.rb +202 -0
- data/lib/maytes_api_client/models/checkout_captured.rb +266 -0
- data/lib/maytes_api_client/models/checkout_created.rb +242 -0
- data/lib/maytes_api_client/models/checkout_discount.rb +329 -0
- data/lib/maytes_api_client/models/checkout_fee.rb +351 -0
- data/lib/maytes_api_client/models/create_checkout401_response.rb +258 -0
- data/lib/maytes_api_client/models/create_checkout409_response.rb +258 -0
- data/lib/maytes_api_client/models/create_checkout422_response.rb +258 -0
- data/lib/maytes_api_client/models/create_checkout_request.rb +444 -0
- data/lib/maytes_api_client/models/create_checkout_response.rb +164 -0
- data/lib/maytes_api_client/models/create_refund_request.rb +212 -0
- data/lib/maytes_api_client/models/customer_data.rb +168 -0
- data/lib/maytes_api_client/models/digital_goods_custom_data.rb +148 -0
- data/lib/maytes_api_client/models/digital_goods_line_item.rb +414 -0
- data/lib/maytes_api_client/models/donation_line_item.rb +405 -0
- data/lib/maytes_api_client/models/error_response_dto.rb +227 -0
- data/lib/maytes_api_client/models/fee.rb +271 -0
- data/lib/maytes_api_client/models/fee_breakdown_line.rb +266 -0
- data/lib/maytes_api_client/models/food_beverage_line_item.rb +405 -0
- data/lib/maytes_api_client/models/get_checkout404_response.rb +258 -0
- data/lib/maytes_api_client/models/get_checkout422_response.rb +258 -0
- data/lib/maytes_api_client/models/get_checkout_response.rb +164 -0
- data/lib/maytes_api_client/models/get_settlement_response.rb +164 -0
- data/lib/maytes_api_client/models/health_response.rb +164 -0
- data/lib/maytes_api_client/models/line_item.rb +65 -0
- data/lib/maytes_api_client/models/list_settlements_response.rb +166 -0
- data/lib/maytes_api_client/models/o_auth_token_request.rb +244 -0
- data/lib/maytes_api_client/models/o_auth_token_response.rb +251 -0
- data/lib/maytes_api_client/models/other_line_item.rb +405 -0
- data/lib/maytes_api_client/models/physical_goods_custom_data.rb +173 -0
- data/lib/maytes_api_client/models/physical_goods_line_item.rb +431 -0
- data/lib/maytes_api_client/models/refund_checkout402_response.rb +258 -0
- data/lib/maytes_api_client/models/refund_checkout409_response.rb +258 -0
- data/lib/maytes_api_client/models/service_custom_data.rb +148 -0
- data/lib/maytes_api_client/models/service_line_item.rb +414 -0
- data/lib/maytes_api_client/models/settlement.rb +526 -0
- data/lib/maytes_api_client/models/tax.rb +202 -0
- data/lib/maytes_api_client/models/ticket_custom_data.rb +333 -0
- data/lib/maytes_api_client/models/ticket_line_item.rb +431 -0
- data/lib/maytes_api_client/models/ticket_seating.rb +176 -0
- data/lib/maytes_api_client/version.rb +15 -0
- data/lib/maytes_api_client/webhook_verifier.rb +212 -0
- data/lib/maytes_api_client.rb +95 -0
- data/maytes_api_client.gemspec +39 -0
- data/spec/api/default_api_spec.rb +145 -0
- data/spec/models/cancel_checkout409_response_spec.rb +58 -0
- data/spec/models/cancel_checkout_request_spec.rb +36 -0
- data/spec/models/cancel_checkout_response_spec.rb +36 -0
- data/spec/models/capture_checkout409_response_spec.rb +58 -0
- data/spec/models/capture_checkout422_response_spec.rb +58 -0
- data/spec/models/capture_checkout_request_spec.rb +54 -0
- data/spec/models/capture_checkout_response_spec.rb +36 -0
- data/spec/models/checkout_cancelled_spec.rb +48 -0
- data/spec/models/checkout_captured_spec.rb +66 -0
- data/spec/models/checkout_created_spec.rb +54 -0
- data/spec/models/checkout_discount_spec.rb +76 -0
- data/spec/models/checkout_fee_spec.rb +86 -0
- data/spec/models/checkout_spec.rb +126 -0
- data/spec/models/create_checkout401_response_spec.rb +58 -0
- data/spec/models/create_checkout409_response_spec.rb +58 -0
- data/spec/models/create_checkout422_response_spec.rb +58 -0
- data/spec/models/create_checkout_request_spec.rb +118 -0
- data/spec/models/create_checkout_response_spec.rb +36 -0
- data/spec/models/create_refund_request_spec.rb +42 -0
- data/spec/models/customer_data_spec.rb +48 -0
- data/spec/models/digital_goods_custom_data_spec.rb +36 -0
- data/spec/models/digital_goods_line_item_spec.rb +100 -0
- data/spec/models/donation_line_item_spec.rb +94 -0
- data/spec/models/error_response_dto_spec.rb +54 -0
- data/spec/models/fee_breakdown_line_spec.rb +58 -0
- data/spec/models/fee_spec.rb +54 -0
- data/spec/models/food_beverage_line_item_spec.rb +94 -0
- data/spec/models/get_checkout404_response_spec.rb +58 -0
- data/spec/models/get_checkout422_response_spec.rb +58 -0
- data/spec/models/get_checkout_response_spec.rb +36 -0
- data/spec/models/get_settlement_response_spec.rb +36 -0
- data/spec/models/health_response_spec.rb +36 -0
- data/spec/models/line_item_spec.rb +44 -0
- data/spec/models/list_settlements_response_spec.rb +36 -0
- data/spec/models/o_auth_token_request_spec.rb +72 -0
- data/spec/models/o_auth_token_response_spec.rb +60 -0
- data/spec/models/other_line_item_spec.rb +94 -0
- data/spec/models/physical_goods_custom_data_spec.rb +42 -0
- data/spec/models/physical_goods_line_item_spec.rb +100 -0
- data/spec/models/refund_checkout402_response_spec.rb +58 -0
- data/spec/models/refund_checkout409_response_spec.rb +58 -0
- data/spec/models/service_custom_data_spec.rb +36 -0
- data/spec/models/service_line_item_spec.rb +100 -0
- data/spec/models/settlement_spec.rb +138 -0
- data/spec/models/tax_spec.rb +48 -0
- data/spec/models/ticket_custom_data_spec.rb +106 -0
- data/spec/models/ticket_line_item_spec.rb +100 -0
- data/spec/models/ticket_seating_spec.rb +54 -0
- data/spec/spec_helper.rb +111 -0
- metadata +295 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# Bundled with the generated SDK via bin/postprocess-ruby.sh.
|
|
4
|
+
#
|
|
5
|
+
# Lives at build/ruby-client/lib/maytes_api_client/webhook_verifier.rb after
|
|
6
|
+
# `make generate-ruby`. Required from the gem's root file so consumers do:
|
|
7
|
+
#
|
|
8
|
+
# require 'maytes_api_client'
|
|
9
|
+
# event = MaytesApiClient.verify_webhook_signature(raw_body, header, secret)
|
|
10
|
+
#
|
|
11
|
+
# Verifies the `X-Maytes-Signature` header on an inbound webhook delivery and
|
|
12
|
+
# returns the parsed event. Merchants must never hand-roll this — see the four
|
|
13
|
+
# sharp edges below, each of which silently produces either a security hole or
|
|
14
|
+
# an outage:
|
|
15
|
+
#
|
|
16
|
+
# 1. RAW BODY. The signature covers the exact bytes we sent. Verifying
|
|
17
|
+
# against re-serialised JSON (params.to_json) fails for any body whose key
|
|
18
|
+
# order or number formatting differs after a parse/emit round-trip. This
|
|
19
|
+
# is the single most common webhook integration bug.
|
|
20
|
+
# 2. MULTIPLE `v1=` ENTRIES. During a signing-secret rotation grace window
|
|
21
|
+
# the header carries TWO signatures (current secret first, previous
|
|
22
|
+
# second) and the delivery is valid if EITHER matches. A verifier that
|
|
23
|
+
# reads only the first `v1=` works perfectly until the first rotation,
|
|
24
|
+
# then rejects live traffic. See §7 of the webhook spec.
|
|
25
|
+
# 3. CONSTANT-TIME COMPARISON. A plain == on digests leaks how much of a
|
|
26
|
+
# forged signature was correct, which is enough to recover a valid
|
|
27
|
+
# signature one byte at a time.
|
|
28
|
+
# 4. REPLAY WINDOW. The `t=` timestamp is the anti-replay anchor; a captured
|
|
29
|
+
# delivery stays valid forever without a freshness check.
|
|
30
|
+
#
|
|
31
|
+
# Verification and JSON parsing are deliberately fused into ONE call: the
|
|
32
|
+
# method takes the raw body and hands back the parsed event, so there is no
|
|
33
|
+
# intermediate state in which a caller can parse first and verify second.
|
|
34
|
+
#
|
|
35
|
+
# Algorithm (webhook spec §6.1):
|
|
36
|
+
# signed_payload = "#{t}.#{raw_body}"
|
|
37
|
+
# signature = lowercase_hex( HMAC_SHA256(signing_secret, signed_payload) )
|
|
38
|
+
|
|
39
|
+
require 'json'
|
|
40
|
+
require 'openssl'
|
|
41
|
+
|
|
42
|
+
module MaytesApiClient
|
|
43
|
+
# Default anti-replay window, in seconds (webhook spec §6.1 advises ~5 min).
|
|
44
|
+
DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300
|
|
45
|
+
|
|
46
|
+
# Raised when an inbound delivery is not authentic. Respond 400 and do NOT
|
|
47
|
+
# act on the body.
|
|
48
|
+
#
|
|
49
|
+
# `reason` is one of:
|
|
50
|
+
# :malformed_header — header absent or missing `t=` / `v1=`
|
|
51
|
+
# :timestamp_out_of_tolerance — `t=` too far from now; possible replay
|
|
52
|
+
# :no_matching_signature — wrong secret, or the body was modified
|
|
53
|
+
# :invalid_json — signature valid but body wasn't JSON
|
|
54
|
+
class WebhookSignatureError < StandardError
|
|
55
|
+
attr_reader :reason
|
|
56
|
+
|
|
57
|
+
def initialize(reason, message)
|
|
58
|
+
@reason = reason
|
|
59
|
+
super(message)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# A verified webhook event (webhook spec §6).
|
|
64
|
+
#
|
|
65
|
+
# `data` is left as an open hash because its shape varies per `type` —
|
|
66
|
+
# branch on `type`, then read the fields that event documents. Ignore
|
|
67
|
+
# unrecognised fields: additive changes do NOT bump `api_version`.
|
|
68
|
+
MaytesWebhookEvent = Struct.new(
|
|
69
|
+
:id, # Stable event id — identical across every retry. Deduplicate on this.
|
|
70
|
+
:type, # e.g. 'checkout.authorized', 'checkout.voided', 'webhook.test'.
|
|
71
|
+
:api_version, # Envelope schema version, e.g. '2026-06'.
|
|
72
|
+
:created_at, # When the event occurred.
|
|
73
|
+
:data, # Per-event payload.
|
|
74
|
+
keyword_init: true,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Verify an inbound Maytes webhook delivery and return the parsed event.
|
|
78
|
+
#
|
|
79
|
+
# Pass the **raw** request body — the exact bytes, before any JSON parsing.
|
|
80
|
+
#
|
|
81
|
+
# post '/webhooks/maytes' do
|
|
82
|
+
# begin
|
|
83
|
+
# event = MaytesApiClient.verify_webhook_signature(
|
|
84
|
+
# request.body.read, # raw body
|
|
85
|
+
# request.env['HTTP_X_MAYTES_SIGNATURE'],
|
|
86
|
+
# ENV.fetch('MAYTES_WEBHOOK_SECRET'),
|
|
87
|
+
# )
|
|
88
|
+
# rescue MaytesApiClient::WebhookSignatureError
|
|
89
|
+
# halt 400
|
|
90
|
+
# end
|
|
91
|
+
# # ... handle event.type
|
|
92
|
+
# status 200
|
|
93
|
+
# end
|
|
94
|
+
#
|
|
95
|
+
# `tolerance_seconds: 0` skips the freshness check entirely — TEST ONLY, for
|
|
96
|
+
# replaying a stored delivery in a fixture. Never 0 in production: it makes
|
|
97
|
+
# any captured delivery replayable forever.
|
|
98
|
+
#
|
|
99
|
+
# @raise [WebhookSignatureError] if the delivery is not authentic.
|
|
100
|
+
def self.verify_webhook_signature(
|
|
101
|
+
raw_body,
|
|
102
|
+
signature_header,
|
|
103
|
+
signing_secret,
|
|
104
|
+
tolerance_seconds: DEFAULT_WEBHOOK_TOLERANCE_SECONDS
|
|
105
|
+
)
|
|
106
|
+
timestamp, signatures = parse_webhook_signature_header(signature_header)
|
|
107
|
+
|
|
108
|
+
if tolerance_seconds.positive?
|
|
109
|
+
unless timestamp.match?(/\A\d+\z/)
|
|
110
|
+
raise WebhookSignatureError.new(
|
|
111
|
+
:malformed_header,
|
|
112
|
+
'X-Maytes-Signature carries a non-numeric t= value.',
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
if (Time.now.to_i - timestamp.to_i).abs > tolerance_seconds
|
|
116
|
+
raise WebhookSignatureError.new(
|
|
117
|
+
:timestamp_out_of_tolerance,
|
|
118
|
+
"Webhook timestamp is outside the #{tolerance_seconds}s tolerance — possible replay.",
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
body = raw_body.to_s.dup.force_encoding(Encoding::BINARY)
|
|
124
|
+
expected = OpenSSL::HMAC.hexdigest('SHA256', signing_secret, "#{timestamp}.#{body}")
|
|
125
|
+
|
|
126
|
+
# ANY match wins — during a rotation grace window the current secret's
|
|
127
|
+
# signature and the previous secret's signature are both present.
|
|
128
|
+
matched = signatures.any? { |candidate| secure_compare_digest(expected, candidate) }
|
|
129
|
+
unless matched
|
|
130
|
+
raise WebhookSignatureError.new(
|
|
131
|
+
:no_matching_signature,
|
|
132
|
+
'No v1 signature matched the computed HMAC — wrong signing secret, ' \
|
|
133
|
+
'or the body was modified in transit.',
|
|
134
|
+
)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
parse_webhook_envelope(body)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# @api private
|
|
141
|
+
def self.parse_webhook_signature_header(header)
|
|
142
|
+
if header.nil? || header.strip.empty?
|
|
143
|
+
raise WebhookSignatureError.new(:malformed_header, 'Missing X-Maytes-Signature header.')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
timestamp = nil
|
|
147
|
+
signatures = []
|
|
148
|
+
|
|
149
|
+
header.split(',').each do |part|
|
|
150
|
+
trimmed = part.strip
|
|
151
|
+
if trimmed.start_with?('t=')
|
|
152
|
+
timestamp = trimmed[2..]
|
|
153
|
+
elsif trimmed.start_with?('v1=')
|
|
154
|
+
signatures << trimmed[3..]
|
|
155
|
+
end
|
|
156
|
+
# Unknown schemes (a future v2=) are ignored, not fatal — forward
|
|
157
|
+
# compatibility: we may add a scheme alongside v1 before removing v1.
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
if timestamp.nil? || timestamp.empty? || signatures.empty?
|
|
161
|
+
raise WebhookSignatureError.new(
|
|
162
|
+
:malformed_header,
|
|
163
|
+
'X-Maytes-Signature is malformed — expected `t=<unix>,v1=<hex>`.',
|
|
164
|
+
)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
[timestamp, signatures]
|
|
168
|
+
end
|
|
169
|
+
private_class_method :parse_webhook_signature_header
|
|
170
|
+
|
|
171
|
+
# Length is checked first because fixed_length_secure_compare raises on a
|
|
172
|
+
# length mismatch — and length is not a secret.
|
|
173
|
+
#
|
|
174
|
+
# OpenSSL.fixed_length_secure_compare only exists in the openssl gem >= 2.2
|
|
175
|
+
# (Ruby 3.0+); on older rubies we fall back to an XOR-accumulate loop, which
|
|
176
|
+
# is constant-time for the equal-length inputs the guard above guarantees.
|
|
177
|
+
# Without the fallback this raises NoMethodError on every valid delivery.
|
|
178
|
+
#
|
|
179
|
+
# @api private
|
|
180
|
+
def self.secure_compare_digest(expected, candidate)
|
|
181
|
+
return false unless candidate.is_a?(String) && candidate.bytesize == expected.bytesize
|
|
182
|
+
|
|
183
|
+
if OpenSSL.respond_to?(:fixed_length_secure_compare)
|
|
184
|
+
OpenSSL.fixed_length_secure_compare(expected, candidate)
|
|
185
|
+
else
|
|
186
|
+
difference = 0
|
|
187
|
+
expected.bytes.zip(candidate.bytes) { |a, b| difference |= a ^ b }
|
|
188
|
+
difference.zero?
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
private_class_method :secure_compare_digest
|
|
192
|
+
|
|
193
|
+
# @api private
|
|
194
|
+
def self.parse_webhook_envelope(body)
|
|
195
|
+
parsed = JSON.parse(body.dup.force_encoding(Encoding::UTF_8))
|
|
196
|
+
raise JSON::ParserError, 'not an object' unless parsed.is_a?(Hash)
|
|
197
|
+
|
|
198
|
+
MaytesWebhookEvent.new(
|
|
199
|
+
id: parsed['id'].to_s,
|
|
200
|
+
type: parsed['type'].to_s,
|
|
201
|
+
api_version: parsed['api_version'].to_s,
|
|
202
|
+
created_at: parsed['created_at'].to_s,
|
|
203
|
+
data: parsed['data'].is_a?(Hash) ? parsed['data'] : {},
|
|
204
|
+
)
|
|
205
|
+
rescue JSON::ParserError, ArgumentError
|
|
206
|
+
raise WebhookSignatureError.new(
|
|
207
|
+
:invalid_json,
|
|
208
|
+
'Signature verified but the body is not valid JSON.',
|
|
209
|
+
)
|
|
210
|
+
end
|
|
211
|
+
private_class_method :parse_webhook_envelope
|
|
212
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Maytes API
|
|
3
|
+
|
|
4
|
+
#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.22.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
# Common files
|
|
14
|
+
require 'maytes_api_client/api_client'
|
|
15
|
+
require 'maytes_api_client/api_error'
|
|
16
|
+
require 'maytes_api_client/api_model_base'
|
|
17
|
+
require 'maytes_api_client/version'
|
|
18
|
+
require 'maytes_api_client/configuration'
|
|
19
|
+
|
|
20
|
+
# Models
|
|
21
|
+
require 'maytes_api_client/models/cancel_checkout409_response'
|
|
22
|
+
require 'maytes_api_client/models/cancel_checkout_request'
|
|
23
|
+
require 'maytes_api_client/models/cancel_checkout_response'
|
|
24
|
+
require 'maytes_api_client/models/capture_checkout409_response'
|
|
25
|
+
require 'maytes_api_client/models/capture_checkout422_response'
|
|
26
|
+
require 'maytes_api_client/models/capture_checkout_request'
|
|
27
|
+
require 'maytes_api_client/models/capture_checkout_response'
|
|
28
|
+
require 'maytes_api_client/models/checkout'
|
|
29
|
+
require 'maytes_api_client/models/checkout_cancelled'
|
|
30
|
+
require 'maytes_api_client/models/checkout_captured'
|
|
31
|
+
require 'maytes_api_client/models/checkout_created'
|
|
32
|
+
require 'maytes_api_client/models/checkout_discount'
|
|
33
|
+
require 'maytes_api_client/models/checkout_fee'
|
|
34
|
+
require 'maytes_api_client/models/create_checkout401_response'
|
|
35
|
+
require 'maytes_api_client/models/create_checkout409_response'
|
|
36
|
+
require 'maytes_api_client/models/create_checkout422_response'
|
|
37
|
+
require 'maytes_api_client/models/create_checkout_request'
|
|
38
|
+
require 'maytes_api_client/models/create_checkout_response'
|
|
39
|
+
require 'maytes_api_client/models/create_refund_request'
|
|
40
|
+
require 'maytes_api_client/models/customer_data'
|
|
41
|
+
require 'maytes_api_client/models/digital_goods_custom_data'
|
|
42
|
+
require 'maytes_api_client/models/digital_goods_line_item'
|
|
43
|
+
require 'maytes_api_client/models/donation_line_item'
|
|
44
|
+
require 'maytes_api_client/models/error_response_dto'
|
|
45
|
+
require 'maytes_api_client/models/fee'
|
|
46
|
+
require 'maytes_api_client/models/fee_breakdown_line'
|
|
47
|
+
require 'maytes_api_client/models/food_beverage_line_item'
|
|
48
|
+
require 'maytes_api_client/models/get_checkout404_response'
|
|
49
|
+
require 'maytes_api_client/models/get_checkout422_response'
|
|
50
|
+
require 'maytes_api_client/models/get_checkout_response'
|
|
51
|
+
require 'maytes_api_client/models/get_settlement_response'
|
|
52
|
+
require 'maytes_api_client/models/health_response'
|
|
53
|
+
require 'maytes_api_client/models/line_item'
|
|
54
|
+
require 'maytes_api_client/models/list_settlements_response'
|
|
55
|
+
require 'maytes_api_client/models/o_auth_token_request'
|
|
56
|
+
require 'maytes_api_client/models/o_auth_token_response'
|
|
57
|
+
require 'maytes_api_client/models/other_line_item'
|
|
58
|
+
require 'maytes_api_client/models/physical_goods_custom_data'
|
|
59
|
+
require 'maytes_api_client/models/physical_goods_line_item'
|
|
60
|
+
require 'maytes_api_client/models/refund_checkout402_response'
|
|
61
|
+
require 'maytes_api_client/models/refund_checkout409_response'
|
|
62
|
+
require 'maytes_api_client/models/service_custom_data'
|
|
63
|
+
require 'maytes_api_client/models/service_line_item'
|
|
64
|
+
require 'maytes_api_client/models/settlement'
|
|
65
|
+
require 'maytes_api_client/models/tax'
|
|
66
|
+
require 'maytes_api_client/models/ticket_custom_data'
|
|
67
|
+
require 'maytes_api_client/models/ticket_line_item'
|
|
68
|
+
require 'maytes_api_client/models/ticket_seating'
|
|
69
|
+
|
|
70
|
+
# APIs
|
|
71
|
+
require 'maytes_api_client/api/default_api'
|
|
72
|
+
|
|
73
|
+
module MaytesApiClient
|
|
74
|
+
class << self
|
|
75
|
+
# Customize default settings for the SDK using block.
|
|
76
|
+
# MaytesApiClient.configure do |config|
|
|
77
|
+
# config.username = "xxx"
|
|
78
|
+
# config.password = "xxx"
|
|
79
|
+
# end
|
|
80
|
+
# If no block given, return the default Configuration object.
|
|
81
|
+
def configure
|
|
82
|
+
if block_given?
|
|
83
|
+
yield(Configuration.default)
|
|
84
|
+
else
|
|
85
|
+
Configuration.default
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Hand-written extra (post-processed in by sdks/backend-sdk/bin/postprocess-ruby.sh)
|
|
92
|
+
require 'maytes_api_client/managed_client'
|
|
93
|
+
|
|
94
|
+
# Hand-written extra (post-processed in by sdks/backend-sdk/bin/postprocess-ruby.sh)
|
|
95
|
+
require 'maytes_api_client/webhook_verifier'
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
=begin
|
|
4
|
+
#Maytes API
|
|
5
|
+
|
|
6
|
+
#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
7
|
+
|
|
8
|
+
The version of the OpenAPI document: 1.0.0
|
|
9
|
+
|
|
10
|
+
Generated by: https://openapi-generator.tech
|
|
11
|
+
Generator version: 7.22.0
|
|
12
|
+
|
|
13
|
+
=end
|
|
14
|
+
|
|
15
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
16
|
+
require "maytes_api_client/version"
|
|
17
|
+
|
|
18
|
+
Gem::Specification.new do |s|
|
|
19
|
+
s.name = "maytes-api-client-rb"
|
|
20
|
+
s.version = MaytesApiClient::VERSION
|
|
21
|
+
s.platform = Gem::Platform::RUBY
|
|
22
|
+
s.authors = ["Maytes"]
|
|
23
|
+
s.email = []
|
|
24
|
+
s.homepage = "https://developers.maytes.co"
|
|
25
|
+
s.summary = "Official Ruby client for the Maytes API"
|
|
26
|
+
s.description = "Official Ruby client for the Maytes API — create, capture and cancel checkouts, with OAuth2 token management and webhook signature verification."
|
|
27
|
+
s.license = "MIT"
|
|
28
|
+
s.required_ruby_version = ">= 2.7"
|
|
29
|
+
s.metadata = { "homepage_uri" => "https://developers.maytes.co", "source_code_uri" => "https://github.com/kttipay/maytes-api-client-rb", "bug_tracker_uri" => "https://github.com/kttipay/maytes-api-client-rb/issues", "documentation_uri" => "https://developers.maytes.co" }
|
|
30
|
+
|
|
31
|
+
s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'
|
|
32
|
+
|
|
33
|
+
s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0'
|
|
34
|
+
|
|
35
|
+
s.files = `find *`.split("\n").uniq.sort.select { |f| !f.empty? }
|
|
36
|
+
s.test_files = `find spec/*`.split("\n")
|
|
37
|
+
s.executables = []
|
|
38
|
+
s.require_paths = ["lib"]
|
|
39
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Maytes API
|
|
3
|
+
|
|
4
|
+
#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.22.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'spec_helper'
|
|
14
|
+
require 'json'
|
|
15
|
+
|
|
16
|
+
# Unit tests for MaytesApiClient::DefaultApi
|
|
17
|
+
# Automatically generated by openapi-generator (https://openapi-generator.tech)
|
|
18
|
+
# Please update as you see appropriate
|
|
19
|
+
describe 'DefaultApi' do
|
|
20
|
+
before do
|
|
21
|
+
# run before each test
|
|
22
|
+
@api_instance = MaytesApiClient::DefaultApi.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after do
|
|
26
|
+
# run after each test
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe 'test an instance of DefaultApi' do
|
|
30
|
+
it 'should create an instance of DefaultApi' do
|
|
31
|
+
expect(@api_instance).to be_instance_of(MaytesApiClient::DefaultApi)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# unit tests for cancel_checkout
|
|
36
|
+
# Cancel authorized checkout
|
|
37
|
+
# @param checkout_uuid
|
|
38
|
+
# @param cancel_checkout_request
|
|
39
|
+
# @param [Hash] opts the optional parameters
|
|
40
|
+
# @return [CancelCheckoutResponse]
|
|
41
|
+
describe 'cancel_checkout test' do
|
|
42
|
+
it 'should work' do
|
|
43
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# unit tests for capture_checkout
|
|
48
|
+
# Capture authorized checkout
|
|
49
|
+
# @param checkout_uuid
|
|
50
|
+
# @param capture_checkout_request
|
|
51
|
+
# @param [Hash] opts the optional parameters
|
|
52
|
+
# @return [CaptureCheckoutResponse]
|
|
53
|
+
describe 'capture_checkout test' do
|
|
54
|
+
it 'should work' do
|
|
55
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# unit tests for create_checkout
|
|
60
|
+
# Create a new checkout
|
|
61
|
+
# @param create_checkout_request
|
|
62
|
+
# @param [Hash] opts the optional parameters
|
|
63
|
+
# @return [CreateCheckoutResponse]
|
|
64
|
+
describe 'create_checkout test' do
|
|
65
|
+
it 'should work' do
|
|
66
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# unit tests for get_checkout
|
|
71
|
+
# Get checkout details
|
|
72
|
+
# @param checkout_uuid
|
|
73
|
+
# @param [Hash] opts the optional parameters
|
|
74
|
+
# @option opts [String] :merchant_order_id
|
|
75
|
+
# @return [GetCheckoutResponse]
|
|
76
|
+
describe 'get_checkout test' do
|
|
77
|
+
it 'should work' do
|
|
78
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# unit tests for get_health
|
|
83
|
+
# Health check
|
|
84
|
+
# @param [Hash] opts the optional parameters
|
|
85
|
+
# @return [HealthResponse]
|
|
86
|
+
describe 'get_health test' do
|
|
87
|
+
it 'should work' do
|
|
88
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# unit tests for get_o_auth_token
|
|
93
|
+
# Issue an access token
|
|
94
|
+
# @param o_auth_token_request
|
|
95
|
+
# @param [Hash] opts the optional parameters
|
|
96
|
+
# @return [OAuthTokenResponse]
|
|
97
|
+
describe 'get_o_auth_token test' do
|
|
98
|
+
it 'should work' do
|
|
99
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# unit tests for get_settlement
|
|
104
|
+
# Get a settlement by UUID
|
|
105
|
+
# @param uuid Settlement UUID
|
|
106
|
+
# @param [Hash] opts the optional parameters
|
|
107
|
+
# @return [GetSettlementResponse]
|
|
108
|
+
describe 'get_settlement test' do
|
|
109
|
+
it 'should work' do
|
|
110
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# unit tests for list_settlements
|
|
115
|
+
# List settlements for this merchant
|
|
116
|
+
# Returns settlements for the authenticated merchant. Default sort: created_at ASC.
|
|
117
|
+
# @param [Hash] opts the optional parameters
|
|
118
|
+
# @option opts [Object] :offset Pagination offset (default 0)
|
|
119
|
+
# @option opts [Object] :limit Max records to return (default 50, max 200)
|
|
120
|
+
# @option opts [String] :sort_dir Sort direction (default: asc)
|
|
121
|
+
# @option opts [String] :sort_by Field to sort by (default: created_at)
|
|
122
|
+
# @option opts [Object] :created_before Include settlements created at or before this ISO-8601 timestamp
|
|
123
|
+
# @option opts [Object] :created_after Include settlements created at or after this ISO-8601 timestamp
|
|
124
|
+
# @option opts [String] :status Filter by status
|
|
125
|
+
# @return [ListSettlementsResponse]
|
|
126
|
+
describe 'list_settlements test' do
|
|
127
|
+
it 'should work' do
|
|
128
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# unit tests for refund_checkout
|
|
133
|
+
# Refund a captured checkout
|
|
134
|
+
# Initiates a full refund of the captured payment. Returns 204 immediately; Stripe confirms asynchronously via webhook. Poll GET /checkouts/:uuid for status and refund details.
|
|
135
|
+
# @param checkout_uuid
|
|
136
|
+
# @param create_refund_request
|
|
137
|
+
# @param [Hash] opts the optional parameters
|
|
138
|
+
# @return [nil]
|
|
139
|
+
describe 'refund_checkout test' do
|
|
140
|
+
it 'should work' do
|
|
141
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Maytes API
|
|
3
|
+
|
|
4
|
+
#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.22.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'spec_helper'
|
|
14
|
+
require 'json'
|
|
15
|
+
require 'date'
|
|
16
|
+
|
|
17
|
+
# Unit tests for MaytesApiClient::CancelCheckout409Response
|
|
18
|
+
# Automatically generated by openapi-generator (https://openapi-generator.tech)
|
|
19
|
+
# Please update as you see appropriate
|
|
20
|
+
describe MaytesApiClient::CancelCheckout409Response do
|
|
21
|
+
#let(:instance) { MaytesApiClient::CancelCheckout409Response.new }
|
|
22
|
+
|
|
23
|
+
describe 'test an instance of CancelCheckout409Response' do
|
|
24
|
+
it 'should create an instance of CancelCheckout409Response' do
|
|
25
|
+
# uncomment below to test the instance creation
|
|
26
|
+
#expect(instance).to be_instance_of(MaytesApiClient::CancelCheckout409Response)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'test attribute "message"' do
|
|
31
|
+
it 'should work' do
|
|
32
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe 'test attribute "error"' do
|
|
37
|
+
it 'should work' do
|
|
38
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe 'test attribute "code"' do
|
|
43
|
+
it 'should work' do
|
|
44
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
45
|
+
# validator = Petstore::EnumTest::EnumAttributeValidator.new('String', ["session_not_voidable"])
|
|
46
|
+
# validator.allowable_values.each do |value|
|
|
47
|
+
# expect { instance.code = value }.not_to raise_error
|
|
48
|
+
# end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe 'test attribute "metadata"' do
|
|
53
|
+
it 'should work' do
|
|
54
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Maytes API
|
|
3
|
+
|
|
4
|
+
#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.22.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'spec_helper'
|
|
14
|
+
require 'json'
|
|
15
|
+
require 'date'
|
|
16
|
+
|
|
17
|
+
# Unit tests for MaytesApiClient::CancelCheckoutRequest
|
|
18
|
+
# Automatically generated by openapi-generator (https://openapi-generator.tech)
|
|
19
|
+
# Please update as you see appropriate
|
|
20
|
+
describe MaytesApiClient::CancelCheckoutRequest do
|
|
21
|
+
#let(:instance) { MaytesApiClient::CancelCheckoutRequest.new }
|
|
22
|
+
|
|
23
|
+
describe 'test an instance of CancelCheckoutRequest' do
|
|
24
|
+
it 'should create an instance of CancelCheckoutRequest' do
|
|
25
|
+
# uncomment below to test the instance creation
|
|
26
|
+
#expect(instance).to be_instance_of(MaytesApiClient::CancelCheckoutRequest)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'test attribute "merchant_order_id"' do
|
|
31
|
+
it 'should work' do
|
|
32
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Maytes API
|
|
3
|
+
|
|
4
|
+
#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.22.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'spec_helper'
|
|
14
|
+
require 'json'
|
|
15
|
+
require 'date'
|
|
16
|
+
|
|
17
|
+
# Unit tests for MaytesApiClient::CancelCheckoutResponse
|
|
18
|
+
# Automatically generated by openapi-generator (https://openapi-generator.tech)
|
|
19
|
+
# Please update as you see appropriate
|
|
20
|
+
describe MaytesApiClient::CancelCheckoutResponse do
|
|
21
|
+
#let(:instance) { MaytesApiClient::CancelCheckoutResponse.new }
|
|
22
|
+
|
|
23
|
+
describe 'test an instance of CancelCheckoutResponse' do
|
|
24
|
+
it 'should create an instance of CancelCheckoutResponse' do
|
|
25
|
+
# uncomment below to test the instance creation
|
|
26
|
+
#expect(instance).to be_instance_of(MaytesApiClient::CancelCheckoutResponse)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'test attribute "data"' do
|
|
31
|
+
it 'should work' do
|
|
32
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Maytes API
|
|
3
|
+
|
|
4
|
+
#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.22.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'spec_helper'
|
|
14
|
+
require 'json'
|
|
15
|
+
require 'date'
|
|
16
|
+
|
|
17
|
+
# Unit tests for MaytesApiClient::CaptureCheckout409Response
|
|
18
|
+
# Automatically generated by openapi-generator (https://openapi-generator.tech)
|
|
19
|
+
# Please update as you see appropriate
|
|
20
|
+
describe MaytesApiClient::CaptureCheckout409Response do
|
|
21
|
+
#let(:instance) { MaytesApiClient::CaptureCheckout409Response.new }
|
|
22
|
+
|
|
23
|
+
describe 'test an instance of CaptureCheckout409Response' do
|
|
24
|
+
it 'should create an instance of CaptureCheckout409Response' do
|
|
25
|
+
# uncomment below to test the instance creation
|
|
26
|
+
#expect(instance).to be_instance_of(MaytesApiClient::CaptureCheckout409Response)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'test attribute "message"' do
|
|
31
|
+
it 'should work' do
|
|
32
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe 'test attribute "error"' do
|
|
37
|
+
it 'should work' do
|
|
38
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe 'test attribute "code"' do
|
|
43
|
+
it 'should work' do
|
|
44
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
45
|
+
# validator = Petstore::EnumTest::EnumAttributeValidator.new('String', ["not_capturable"])
|
|
46
|
+
# validator.allowable_values.each do |value|
|
|
47
|
+
# expect { instance.code = value }.not_to raise_error
|
|
48
|
+
# end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe 'test attribute "metadata"' do
|
|
53
|
+
it 'should work' do
|
|
54
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|