schematichq 1.4.9 → 1.4.10
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 +4 -4
- data/.fern/metadata.json +2 -2
- data/.fern/replay.lock +344 -2
- data/WASM_VERSION +1 -1
- data/lib/schematic/catalogs/client.rb +480 -0
- data/lib/schematic/catalogs/types/create_catalog_request_body.rb +13 -0
- data/lib/schematic/catalogs/types/create_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/delete_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_configuration_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_credit_bundles_in_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_derived_features_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_plans_in_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/list_catalogs_params.rb +15 -0
- data/lib/schematic/catalogs/types/list_catalogs_request.rb +14 -0
- data/lib/schematic/catalogs/types/list_catalogs_response.rb +12 -0
- data/lib/schematic/catalogs/types/update_catalog_configuration_request_body.rb +20 -0
- data/lib/schematic/catalogs/types/update_catalog_request_body.rb +14 -0
- data/lib/schematic/catalogs/types/update_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/update_configuration_response.rb +12 -0
- data/lib/schematic/checkout/client.rb +69 -0
- data/lib/schematic/checkout/types/get_company_billing_details_response.rb +12 -0
- data/lib/schematic/checkout/types/update_company_billing_details_request_body.rb +15 -0
- data/lib/schematic/checkout/types/update_company_billing_details_response.rb +12 -0
- data/lib/schematic/client.rb +6 -1
- data/lib/schematic/components/client.rb +37 -0
- data/lib/schematic/components/types/bind_catalog_request_body.rb +12 -0
- data/lib/schematic/components/types/bind_catalog_response.rb +12 -0
- data/lib/schematic/dataexports/client.rb +76 -0
- data/lib/schematic/dataexports/types/create_data_export_request_body.rb +3 -3
- data/lib/schematic/dataexports/types/get_data_export_response.rb +12 -0
- data/lib/schematic/dataexports/types/list_data_exports_params.rb +15 -0
- data/lib/schematic/dataexports/types/list_data_exports_request.rb +14 -0
- data/lib/schematic/dataexports/types/list_data_exports_response.rb +12 -0
- data/lib/schematic/planbundle/types/create_custom_plan_bundle_request_body.rb +1 -0
- data/lib/schematic/types/audit_log_export_metadata.rb +13 -0
- data/lib/schematic/types/catalog_config_ordered_bundle.rb +9 -0
- data/lib/schematic/types/catalog_config_ordered_bundle_response_data.rb +9 -0
- data/lib/schematic/types/catalog_config_ordered_entitlement.rb +10 -0
- data/lib/schematic/types/catalog_config_ordered_entitlement_response_data.rb +10 -0
- data/lib/schematic/types/catalog_config_ordered_plan.rb +10 -0
- data/lib/schematic/types/catalog_config_ordered_plan_response_data.rb +10 -0
- data/lib/schematic/types/catalog_configuration_response_data.rb +19 -0
- data/lib/schematic/types/catalog_credit_bundle_i_ds_response_data.rb +9 -0
- data/lib/schematic/types/catalog_derived_feature_response_data.rb +11 -0
- data/lib/schematic/types/catalog_derived_features_response_data.rb +9 -0
- data/lib/schematic/types/catalog_plan_i_ds_response_data.rb +9 -0
- data/lib/schematic/types/catalog_response_data.rb +22 -0
- data/lib/schematic/types/company_billing_address_view.rb +14 -0
- data/lib/schematic/types/company_billing_checkout_settings.rb +11 -0
- data/lib/schematic/types/company_billing_details_response_data.rb +13 -0
- data/lib/schematic/types/company_billing_details_view.rb +13 -0
- data/lib/schematic/types/company_feature_usage_export_metadata.rb +25 -0
- data/lib/schematic/types/company_plan_detail_response_data.rb +1 -0
- data/lib/schematic/types/component_response_data.rb +1 -0
- data/lib/schematic/types/create_entitlement_in_bundle_request_body.rb +1 -0
- data/lib/schematic/types/credits_auto_topup_success.rb +12 -0
- data/lib/schematic/types/credits_credit_purchase_success.rb +14 -0
- data/lib/schematic/types/credits_webhook_company_summary.rb +10 -0
- data/lib/schematic/types/credits_webhook_credit_summary.rb +10 -0
- data/lib/schematic/types/customer_billing_address.rb +14 -0
- data/lib/schematic/types/data_export_metadata.rb +14 -0
- data/lib/schematic/types/data_export_output_file_type.rb +3 -14
- data/lib/schematic/types/data_export_response_data.rb +3 -3
- data/lib/schematic/types/data_export_type.rb +3 -14
- data/lib/schematic/types/feature_entitlement.rb +1 -0
- data/lib/schematic/types/plan_catalog_membership_response_data.rb +10 -0
- data/lib/schematic/types/plan_detail_response_data.rb +1 -0
- data/lib/schematic/types/plan_group_plan_detail_response_data.rb +1 -0
- data/lib/schematic/types/plan_view_public_response_data.rb +1 -0
- data/lib/schematic/types/preview_subscription_discount_response_data.rb +19 -0
- data/lib/schematic/types/preview_subscription_finance_response_data.rb +2 -0
- data/lib/schematic/types/rulesengine_feature_entitlement.rb +1 -0
- data/lib/schematic/types/rulesengine_warning_tier.rb +10 -0
- data/lib/schematic/types/upsert_company_request_body.rb +2 -0
- data/lib/schematic/types/warning_tier.rb +10 -0
- data/lib/schematic/types/webhook_request_type.rb +2 -0
- data/lib/schematic/version.rb +1 -1
- data/lib/schematic/wasm/rulesengine.wasm +0 -0
- data/lib/schematic.rb +91 -38
- data/reference.md +1231 -48
- metadata +55 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 677e9663f6096839ed9c6bd6cfcc614d5591878ab699d4c3ea042a5517d4be13
|
|
4
|
+
data.tar.gz: b585b4c5f09b418cee556f125d195f2c16fd9137636c1d38208f90012f85f5f5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0b82a52c15011754abfc68b7e76a8ab65a27932afa63d1036b86b59e81ff41099e14e18335555762e1e7f9c04bde39628677f477c5a8a300623db8f121bdf80
|
|
7
|
+
data.tar.gz: f26162008e22f054c4465d307f07bc7c237cd88940e295ab5229163330d0620df1c373a488dd160be3ec5b13214c14645c31a6fb0f0c1acb5caf2a67db18e3e4
|
data/.fern/metadata.json
CHANGED
data/.fern/replay.lock
CHANGED
|
@@ -36,5 +36,347 @@ generations:
|
|
|
36
36
|
cli_version: unknown
|
|
37
37
|
generator_versions:
|
|
38
38
|
fernapi/fern-ruby-sdk: 1.1.13
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
- commit_sha: dfe70dc9f1f1787aa5b55f6802739898633c35c7
|
|
40
|
+
tree_hash: 114498346f315168be50ca9bf5c9f463bcfe3303
|
|
41
|
+
timestamp: 2026-07-22T19:30:43.525Z
|
|
42
|
+
cli_version: unknown
|
|
43
|
+
generator_versions:
|
|
44
|
+
fernapi/fern-ruby-sdk: 1.1.13
|
|
45
|
+
current_generation: dfe70dc9f1f1787aa5b55f6802739898633c35c7
|
|
46
|
+
patches:
|
|
47
|
+
- id: patch-5da692c2
|
|
48
|
+
content_hash: sha256:e652287219a0a709e16112ced444e6472c6fa8bdfe888edf868caaf9769a9472
|
|
49
|
+
original_commit: 5da692c20aef08577d900f9a860b5f78a549418e
|
|
50
|
+
original_message: inject host time into datastream wasm rules engine (SCHY-471)
|
|
51
|
+
original_author: Christopher Brady <chris@schematichq.com>
|
|
52
|
+
base_generation: dfe70dc9f1f1787aa5b55f6802739898633c35c7
|
|
53
|
+
files:
|
|
54
|
+
- test/rules_engine_clock_test.rb
|
|
55
|
+
patch_content: |
|
|
56
|
+
diff --git a/test/rules_engine_clock_test.rb b/test/rules_engine_clock_test.rb
|
|
57
|
+
new file mode 100644
|
|
58
|
+
index 0000000..8711b5e
|
|
59
|
+
--- /dev/null
|
|
60
|
+
+++ b/test/rules_engine_clock_test.rb
|
|
61
|
+
@@ -0,0 +1,75 @@
|
|
62
|
+
+# frozen_string_literal: true
|
|
63
|
+
+
|
|
64
|
+
+require_relative "test_helper"
|
|
65
|
+
+require "minitest/autorun"
|
|
66
|
+
+
|
|
67
|
+
+# Regression for SCHY-471.
|
|
68
|
+
+#
|
|
69
|
+
+# A company-override entitlement rule whose metric condition uses a
|
|
70
|
+
+# calendar/billing metric period drives the engine into the metric-period-reset
|
|
71
|
+
+# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
72
|
+
+# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
73
|
+
+# its default value for a company that is legitimately entitled. The host now
|
|
74
|
+
+# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
75
|
+
+class RulesEngineClockTest < Minitest::Test
|
|
76
|
+
+ def setup
|
|
77
|
+
+ @engine = Schematic::RulesEngine.new
|
|
78
|
+
+ @engine.initialize!
|
|
79
|
+
+ # The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
80
|
+
+ # (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
81
|
+
+ skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
82
|
+
+ end
|
|
83
|
+
+
|
|
84
|
+
+ def flag
|
|
85
|
+
+ {
|
|
86
|
+
+ "id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
87
|
+
+ "environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
88
|
+
+ }
|
|
89
|
+
+ end
|
|
90
|
+
+
|
|
91
|
+
+ # Usage 40 < allocation 100, so the override grants the feature.
|
|
92
|
+
+ def entitled_company
|
|
93
|
+
+ {
|
|
94
|
+
+ "id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
95
|
+
+ "keys" => { "id" => "co_entitled" },
|
|
96
|
+
+ "metrics" => [{
|
|
97
|
+
+ "account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
98
|
+
+ "event_subtype" => "api-calls", "period" => "current_month",
|
|
99
|
+
+ "month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
100
|
+
+ }],
|
|
101
|
+
+ "rules" => [{
|
|
102
|
+
+ "id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
103
|
+
+ "environment_id" => "env_1", "name" => "Company Override",
|
|
104
|
+
+ "rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
105
|
+
+ "condition_groups" => [],
|
|
106
|
+
+ "conditions" => [
|
|
107
|
+
+ {
|
|
108
|
+
+ "id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
109
|
+
+ "condition_type" => "company", "operator" => "eq",
|
|
110
|
+
+ "resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
111
|
+
+ },
|
|
112
|
+
+ {
|
|
113
|
+
+ "id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
114
|
+
+ "condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
115
|
+
+ "metric_value" => 100, "metric_period" => "current_month",
|
|
116
|
+
+ "metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
117
|
+
+ }
|
|
118
|
+
+ ]
|
|
119
|
+
+ }]
|
|
120
|
+
+ }
|
|
121
|
+
+ end
|
|
122
|
+
+
|
|
123
|
+
+ def test_billing_metric_override_evaluates_without_trapping
|
|
124
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
125
|
+
+
|
|
126
|
+
+ assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
127
|
+
+ assert_match(/override/i, result[:reason].to_s)
|
|
128
|
+
+ end
|
|
129
|
+
+
|
|
130
|
+
+ def test_billing_metric_override_populates_reset_at
|
|
131
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
132
|
+
+
|
|
133
|
+
+ refute_nil result[:feature_usage_reset_at],
|
|
134
|
+
+ "reset-at should be computed from the injected host time"
|
|
135
|
+
+ end
|
|
136
|
+
+end
|
|
137
|
+
theirs_snapshot:
|
|
138
|
+
test/rules_engine_clock_test.rb: |
|
|
139
|
+
# frozen_string_literal: true
|
|
140
|
+
|
|
141
|
+
require_relative "test_helper"
|
|
142
|
+
require "minitest/autorun"
|
|
143
|
+
|
|
144
|
+
# Regression for SCHY-471.
|
|
145
|
+
#
|
|
146
|
+
# A company-override entitlement rule whose metric condition uses a
|
|
147
|
+
# calendar/billing metric period drives the engine into the metric-period-reset
|
|
148
|
+
# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
149
|
+
# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
150
|
+
# its default value for a company that is legitimately entitled. The host now
|
|
151
|
+
# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
152
|
+
class RulesEngineClockTest < Minitest::Test
|
|
153
|
+
def setup
|
|
154
|
+
@engine = Schematic::RulesEngine.new
|
|
155
|
+
@engine.initialize!
|
|
156
|
+
# The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
157
|
+
# (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
158
|
+
skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def flag
|
|
162
|
+
{
|
|
163
|
+
"id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
164
|
+
"environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Usage 40 < allocation 100, so the override grants the feature.
|
|
169
|
+
def entitled_company
|
|
170
|
+
{
|
|
171
|
+
"id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
172
|
+
"keys" => { "id" => "co_entitled" },
|
|
173
|
+
"metrics" => [{
|
|
174
|
+
"account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
175
|
+
"event_subtype" => "api-calls", "period" => "current_month",
|
|
176
|
+
"month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
177
|
+
}],
|
|
178
|
+
"rules" => [{
|
|
179
|
+
"id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
180
|
+
"environment_id" => "env_1", "name" => "Company Override",
|
|
181
|
+
"rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
182
|
+
"condition_groups" => [],
|
|
183
|
+
"conditions" => [
|
|
184
|
+
{
|
|
185
|
+
"id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
186
|
+
"condition_type" => "company", "operator" => "eq",
|
|
187
|
+
"resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
191
|
+
"condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
192
|
+
"metric_value" => 100, "metric_period" => "current_month",
|
|
193
|
+
"metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
}]
|
|
197
|
+
}
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_billing_metric_override_evaluates_without_trapping
|
|
201
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
202
|
+
|
|
203
|
+
assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
204
|
+
assert_match(/override/i, result[:reason].to_s)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def test_billing_metric_override_populates_reset_at
|
|
208
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
209
|
+
|
|
210
|
+
refute_nil result[:feature_usage_reset_at],
|
|
211
|
+
"reset-at should be computed from the injected host time"
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
user_owned: true
|
|
215
|
+
- id: patch-ee61788c
|
|
216
|
+
content_hash: sha256:e652287219a0a709e16112ced444e6472c6fa8bdfe888edf868caaf9769a9472
|
|
217
|
+
original_commit: ee61788c5a83fce5dd5768b2536391459550d176
|
|
218
|
+
original_message: fix rubocop offenses in clock regression test (SCHY-471)
|
|
219
|
+
original_author: Christopher Brady <chris@schematichq.com>
|
|
220
|
+
base_generation: dfe70dc9f1f1787aa5b55f6802739898633c35c7
|
|
221
|
+
files:
|
|
222
|
+
- test/rules_engine_clock_test.rb
|
|
223
|
+
patch_content: |
|
|
224
|
+
diff --git a/test/rules_engine_clock_test.rb b/test/rules_engine_clock_test.rb
|
|
225
|
+
new file mode 100644
|
|
226
|
+
index 0000000..8711b5e
|
|
227
|
+
--- /dev/null
|
|
228
|
+
+++ b/test/rules_engine_clock_test.rb
|
|
229
|
+
@@ -0,0 +1,75 @@
|
|
230
|
+
+# frozen_string_literal: true
|
|
231
|
+
+
|
|
232
|
+
+require_relative "test_helper"
|
|
233
|
+
+require "minitest/autorun"
|
|
234
|
+
+
|
|
235
|
+
+# Regression for SCHY-471.
|
|
236
|
+
+#
|
|
237
|
+
+# A company-override entitlement rule whose metric condition uses a
|
|
238
|
+
+# calendar/billing metric period drives the engine into the metric-period-reset
|
|
239
|
+
+# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
240
|
+
+# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
241
|
+
+# its default value for a company that is legitimately entitled. The host now
|
|
242
|
+
+# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
243
|
+
+class RulesEngineClockTest < Minitest::Test
|
|
244
|
+
+ def setup
|
|
245
|
+
+ @engine = Schematic::RulesEngine.new
|
|
246
|
+
+ @engine.initialize!
|
|
247
|
+
+ # The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
248
|
+
+ # (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
249
|
+
+ skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
250
|
+
+ end
|
|
251
|
+
+
|
|
252
|
+
+ def flag
|
|
253
|
+
+ {
|
|
254
|
+
+ "id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
255
|
+
+ "environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
256
|
+
+ }
|
|
257
|
+
+ end
|
|
258
|
+
+
|
|
259
|
+
+ # Usage 40 < allocation 100, so the override grants the feature.
|
|
260
|
+
+ def entitled_company
|
|
261
|
+
+ {
|
|
262
|
+
+ "id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
263
|
+
+ "keys" => { "id" => "co_entitled" },
|
|
264
|
+
+ "metrics" => [{
|
|
265
|
+
+ "account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
266
|
+
+ "event_subtype" => "api-calls", "period" => "current_month",
|
|
267
|
+
+ "month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
268
|
+
+ }],
|
|
269
|
+
+ "rules" => [{
|
|
270
|
+
+ "id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
271
|
+
+ "environment_id" => "env_1", "name" => "Company Override",
|
|
272
|
+
+ "rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
273
|
+
+ "condition_groups" => [],
|
|
274
|
+
+ "conditions" => [
|
|
275
|
+
+ {
|
|
276
|
+
+ "id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
277
|
+
+ "condition_type" => "company", "operator" => "eq",
|
|
278
|
+
+ "resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
279
|
+
+ },
|
|
280
|
+
+ {
|
|
281
|
+
+ "id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
282
|
+
+ "condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
283
|
+
+ "metric_value" => 100, "metric_period" => "current_month",
|
|
284
|
+
+ "metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
285
|
+
+ }
|
|
286
|
+
+ ]
|
|
287
|
+
+ }]
|
|
288
|
+
+ }
|
|
289
|
+
+ end
|
|
290
|
+
+
|
|
291
|
+
+ def test_billing_metric_override_evaluates_without_trapping
|
|
292
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
293
|
+
+
|
|
294
|
+
+ assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
295
|
+
+ assert_match(/override/i, result[:reason].to_s)
|
|
296
|
+
+ end
|
|
297
|
+
+
|
|
298
|
+
+ def test_billing_metric_override_populates_reset_at
|
|
299
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
300
|
+
+
|
|
301
|
+
+ refute_nil result[:feature_usage_reset_at],
|
|
302
|
+
+ "reset-at should be computed from the injected host time"
|
|
303
|
+
+ end
|
|
304
|
+
+end
|
|
305
|
+
theirs_snapshot:
|
|
306
|
+
test/rules_engine_clock_test.rb: |
|
|
307
|
+
# frozen_string_literal: true
|
|
308
|
+
|
|
309
|
+
require_relative "test_helper"
|
|
310
|
+
require "minitest/autorun"
|
|
311
|
+
|
|
312
|
+
# Regression for SCHY-471.
|
|
313
|
+
#
|
|
314
|
+
# A company-override entitlement rule whose metric condition uses a
|
|
315
|
+
# calendar/billing metric period drives the engine into the metric-period-reset
|
|
316
|
+
# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
317
|
+
# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
318
|
+
# its default value for a company that is legitimately entitled. The host now
|
|
319
|
+
# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
320
|
+
class RulesEngineClockTest < Minitest::Test
|
|
321
|
+
def setup
|
|
322
|
+
@engine = Schematic::RulesEngine.new
|
|
323
|
+
@engine.initialize!
|
|
324
|
+
# The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
325
|
+
# (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
326
|
+
skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def flag
|
|
330
|
+
{
|
|
331
|
+
"id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
332
|
+
"environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
333
|
+
}
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Usage 40 < allocation 100, so the override grants the feature.
|
|
337
|
+
def entitled_company
|
|
338
|
+
{
|
|
339
|
+
"id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
340
|
+
"keys" => { "id" => "co_entitled" },
|
|
341
|
+
"metrics" => [{
|
|
342
|
+
"account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
343
|
+
"event_subtype" => "api-calls", "period" => "current_month",
|
|
344
|
+
"month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
345
|
+
}],
|
|
346
|
+
"rules" => [{
|
|
347
|
+
"id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
348
|
+
"environment_id" => "env_1", "name" => "Company Override",
|
|
349
|
+
"rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
350
|
+
"condition_groups" => [],
|
|
351
|
+
"conditions" => [
|
|
352
|
+
{
|
|
353
|
+
"id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
354
|
+
"condition_type" => "company", "operator" => "eq",
|
|
355
|
+
"resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
359
|
+
"condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
360
|
+
"metric_value" => 100, "metric_period" => "current_month",
|
|
361
|
+
"metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
362
|
+
}
|
|
363
|
+
]
|
|
364
|
+
}]
|
|
365
|
+
}
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def test_billing_metric_override_evaluates_without_trapping
|
|
369
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
370
|
+
|
|
371
|
+
assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
372
|
+
assert_match(/override/i, result[:reason].to_s)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def test_billing_metric_override_populates_reset_at
|
|
376
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
377
|
+
|
|
378
|
+
refute_nil result[:feature_usage_reset_at],
|
|
379
|
+
"reset-at should be computed from the injected host time"
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
user_owned: true
|
data/WASM_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.6.0
|