strongmind-platform-sdk 3.14.4 → 3.16.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c8d7fba2bd7c29bb50193764ee0177989cbdaf4a18cf1d80d42c9f49a57e530
4
- data.tar.gz: 669138b0b82b556b6318b80160dab2a09e0e86bce4eee61509ba2d0d10544288
3
+ metadata.gz: 3a1edd6d82d545f5eddfb8d75754772ac371342c6cefad44e9aefcc20715aaa8
4
+ data.tar.gz: 886694afaafd66bb2ea6a23fce81799a1b0ddc1e759c381621db87e48cbe6ba1
5
5
  SHA512:
6
- metadata.gz: 33e360e0d9b7881e42099c3cd683ed505822abb6aea08e96e5facd25eb7b9f1e43dafb80fc3a1fba9efd4d59ae4d0e1c962ad9a28085c02fa9715c0bc226c29f
7
- data.tar.gz: b0d3ff1f51ffdd542402c0f2806a8034f6511529029ee5e972a43f2d2573fa066226b1cc69fefaf627ffff80b9022ef08e4ad18086f4e1a38c721b55ff8c93e9
6
+ metadata.gz: 034e4a645e9186b314b33c29f2ae4459ed60975459f77a2ef1519901f09e4c147354bfb04b548b8dac71eb6ef06bd18bdf80bee8f10fba5bc2825a7b6856fce7
7
+ data.tar.gz: 62d48e2122d0d11c1233dc2f4e99b2a7a03c5afc017690729c819b650f71661089b76d41d9f2fa5e83e63d00b20eb78c812ca4d1ac7bcfa0bb99084c5b3cd4b6
data/Gemfile CHANGED
@@ -8,16 +8,23 @@ gem "strongmind-oneroster-client", "~> 2.0.3"
8
8
  # Specify your gem's dependencies in platform_sdk-ruby-sdk.gemspec
9
9
  gemspec
10
10
 
11
- gem "factory_bot"
12
- gem "faker"
13
11
  gem "faraday"
14
12
  gem "faraday-retry"
15
13
  gem "jwt", "~> 1.5", ">= 1.5.4"
16
14
  gem "learnosity-sdk", "~> 0.2.2"
17
15
  gem "multi_json"
18
16
  gem "rake", "~> 13.0"
19
- gem "rspec", "~> 3.6", ">= 3.6.0"
17
+ gem "rspec"
20
18
  gem "rubocop"
21
19
  gem "sentry-ruby"
22
20
  gem "webmock"
21
+ gem 'activesupport', '~> 7.1', '>= 7.1.3.2'
22
+
23
+ group :development, :test do
24
+ gem "sqlite3", "~> 1.4"
25
+ gem 'rspec-rails', '~> 6.1.0'
26
+ gem 'faker'
27
+ gem "factory_bot"
28
+ gem 'timecop'
29
+ end
23
30
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- strongmind-platform-sdk (3.14.4)
4
+ strongmind-platform-sdk (3.16.0)
5
+ activesupport (~> 7.1)
5
6
  aws-sdk-secretsmanager (~> 1.66)
6
7
  faraday (~> 2.5, >= 2.5.2)
7
8
  faraday-retry
@@ -16,105 +17,275 @@ PATH
16
17
  GEM
17
18
  remote: https://rubygems.org/
18
19
  specs:
19
- activesupport (6.1.7.7)
20
+ actioncable (7.1.3.2)
21
+ actionpack (= 7.1.3.2)
22
+ activesupport (= 7.1.3.2)
23
+ nio4r (~> 2.0)
24
+ websocket-driver (>= 0.6.1)
25
+ zeitwerk (~> 2.6)
26
+ actionmailbox (7.1.3.2)
27
+ actionpack (= 7.1.3.2)
28
+ activejob (= 7.1.3.2)
29
+ activerecord (= 7.1.3.2)
30
+ activestorage (= 7.1.3.2)
31
+ activesupport (= 7.1.3.2)
32
+ mail (>= 2.7.1)
33
+ net-imap
34
+ net-pop
35
+ net-smtp
36
+ actionmailer (7.1.3.2)
37
+ actionpack (= 7.1.3.2)
38
+ actionview (= 7.1.3.2)
39
+ activejob (= 7.1.3.2)
40
+ activesupport (= 7.1.3.2)
41
+ mail (~> 2.5, >= 2.5.4)
42
+ net-imap
43
+ net-pop
44
+ net-smtp
45
+ rails-dom-testing (~> 2.2)
46
+ actionpack (7.1.3.2)
47
+ actionview (= 7.1.3.2)
48
+ activesupport (= 7.1.3.2)
49
+ nokogiri (>= 1.8.5)
50
+ racc
51
+ rack (>= 2.2.4)
52
+ rack-session (>= 1.0.1)
53
+ rack-test (>= 0.6.3)
54
+ rails-dom-testing (~> 2.2)
55
+ rails-html-sanitizer (~> 1.6)
56
+ actiontext (7.1.3.2)
57
+ actionpack (= 7.1.3.2)
58
+ activerecord (= 7.1.3.2)
59
+ activestorage (= 7.1.3.2)
60
+ activesupport (= 7.1.3.2)
61
+ globalid (>= 0.6.0)
62
+ nokogiri (>= 1.8.5)
63
+ actionview (7.1.3.2)
64
+ activesupport (= 7.1.3.2)
65
+ builder (~> 3.1)
66
+ erubi (~> 1.11)
67
+ rails-dom-testing (~> 2.2)
68
+ rails-html-sanitizer (~> 1.6)
69
+ activejob (7.1.3.2)
70
+ activesupport (= 7.1.3.2)
71
+ globalid (>= 0.3.6)
72
+ activemodel (7.1.3.2)
73
+ activesupport (= 7.1.3.2)
74
+ activerecord (7.1.3.2)
75
+ activemodel (= 7.1.3.2)
76
+ activesupport (= 7.1.3.2)
77
+ timeout (>= 0.4.0)
78
+ activestorage (7.1.3.2)
79
+ actionpack (= 7.1.3.2)
80
+ activejob (= 7.1.3.2)
81
+ activerecord (= 7.1.3.2)
82
+ activesupport (= 7.1.3.2)
83
+ marcel (~> 1.0)
84
+ activesupport (7.1.3.2)
85
+ base64
86
+ bigdecimal
20
87
  concurrent-ruby (~> 1.0, >= 1.0.2)
88
+ connection_pool (>= 2.2.5)
89
+ drb
21
90
  i18n (>= 1.6, < 2)
22
91
  minitest (>= 5.1)
92
+ mutex_m
23
93
  tzinfo (~> 2.0)
24
- zeitwerk (~> 2.3)
25
94
  addressable (2.8.6)
26
95
  public_suffix (>= 2.0.2, < 6.0)
27
96
  ast (2.4.2)
28
97
  aws-eventstream (1.3.0)
29
- aws-partitions (1.925.0)
30
- aws-sdk-cloudwatch (1.90.0)
98
+ aws-partitions (1.929.0)
99
+ aws-sdk-cloudwatch (1.91.0)
31
100
  aws-sdk-core (~> 3, >= 3.193.0)
32
101
  aws-sigv4 (~> 1.1)
33
- aws-sdk-core (3.194.1)
102
+ aws-sdk-core (3.196.1)
34
103
  aws-eventstream (~> 1, >= 1.3.0)
35
104
  aws-partitions (~> 1, >= 1.651.0)
36
105
  aws-sigv4 (~> 1.8)
37
106
  jmespath (~> 1, >= 1.6.1)
38
- aws-sdk-secretsmanager (1.92.0)
107
+ aws-sdk-secretsmanager (1.93.0)
39
108
  aws-sdk-core (~> 3, >= 3.193.0)
40
109
  aws-sigv4 (~> 1.1)
41
110
  aws-sigv4 (1.8.0)
42
111
  aws-eventstream (~> 1, >= 1.0.2)
43
- bigdecimal (3.1.6)
112
+ base64 (0.2.0)
113
+ bigdecimal (3.1.8)
114
+ builder (3.2.4)
44
115
  concurrent-ruby (1.2.3)
45
116
  connection_pool (2.4.1)
46
117
  crack (1.0.0)
47
118
  bigdecimal
48
119
  rexml
49
- diff-lcs (1.5.0)
120
+ crass (1.0.6)
121
+ date (3.3.4)
122
+ diff-lcs (1.5.1)
123
+ drb (2.2.1)
124
+ erubi (1.12.0)
50
125
  ethon (0.16.0)
51
126
  ffi (>= 1.15.0)
52
- factory_bot (6.4.5)
127
+ factory_bot (6.4.6)
53
128
  activesupport (>= 5.0.0)
54
- faker (2.22.0)
129
+ faker (3.3.1)
55
130
  i18n (>= 1.8.11, < 2)
56
- faraday (2.7.7)
57
- faraday-net_http (>= 2.0, < 3.1)
58
- ruby2_keywords (>= 0.0.4)
59
- faraday-net_http (3.0.2)
60
- faraday-retry (2.1.0)
131
+ faraday (2.9.0)
132
+ faraday-net_http (>= 2.0, < 3.2)
133
+ faraday-net_http (3.1.0)
134
+ net-http
135
+ faraday-retry (2.2.1)
61
136
  faraday (~> 2.0)
62
- ffi (1.15.5)
137
+ ffi (1.16.3)
138
+ globalid (1.2.1)
139
+ activesupport (>= 6.1)
63
140
  hashdiff (1.1.0)
64
- i18n (1.14.1)
141
+ i18n (1.14.5)
65
142
  concurrent-ruby (~> 1.0)
143
+ io-console (0.7.2)
144
+ irb (1.13.1)
145
+ rdoc (>= 4.0.0)
146
+ reline (>= 0.4.2)
66
147
  jmespath (1.6.2)
67
- json (2.6.3)
148
+ json (2.7.2)
68
149
  jwt (1.5.6)
150
+ language_server-protocol (3.17.0.3)
69
151
  learnosity-sdk (0.2.2)
70
152
  sys-uname (>= 1.0)
71
- minitest (5.22.2)
153
+ loofah (2.22.0)
154
+ crass (~> 1.0.2)
155
+ nokogiri (>= 1.12.0)
156
+ mail (2.8.1)
157
+ mini_mime (>= 0.1.1)
158
+ net-imap
159
+ net-pop
160
+ net-smtp
161
+ marcel (1.0.4)
162
+ mini_mime (1.1.5)
163
+ mini_portile2 (2.8.6)
164
+ minitest (5.22.3)
72
165
  multi_json (1.15.0)
73
- parallel (1.23.0)
74
- parser (3.2.2.1)
166
+ mutex_m (0.2.0)
167
+ net-http (0.4.1)
168
+ uri
169
+ net-imap (0.4.11)
170
+ date
171
+ net-protocol
172
+ net-pop (0.1.2)
173
+ net-protocol
174
+ net-protocol (0.2.2)
175
+ timeout
176
+ net-smtp (0.5.0)
177
+ net-protocol
178
+ nio4r (2.7.3)
179
+ nokogiri (1.16.5)
180
+ mini_portile2 (~> 2.8.2)
181
+ racc (~> 1.4)
182
+ nokogiri (1.16.5-x86_64-darwin)
183
+ racc (~> 1.4)
184
+ nokogiri (1.16.5-x86_64-linux)
185
+ racc (~> 1.4)
186
+ parallel (1.24.0)
187
+ parser (3.3.1.0)
75
188
  ast (~> 2.4.1)
76
- public_suffix (5.0.4)
77
- rack (3.0.10)
189
+ racc
190
+ psych (5.1.2)
191
+ stringio
192
+ public_suffix (5.0.5)
193
+ racc (1.7.3)
194
+ rack (3.0.11)
195
+ rack-session (2.0.0)
196
+ rack (>= 3.0.0)
197
+ rack-test (2.1.0)
198
+ rack (>= 1.3)
199
+ rackup (2.1.0)
200
+ rack (>= 3)
201
+ webrick (~> 1.8)
202
+ rails (7.1.3.2)
203
+ actioncable (= 7.1.3.2)
204
+ actionmailbox (= 7.1.3.2)
205
+ actionmailer (= 7.1.3.2)
206
+ actionpack (= 7.1.3.2)
207
+ actiontext (= 7.1.3.2)
208
+ actionview (= 7.1.3.2)
209
+ activejob (= 7.1.3.2)
210
+ activemodel (= 7.1.3.2)
211
+ activerecord (= 7.1.3.2)
212
+ activestorage (= 7.1.3.2)
213
+ activesupport (= 7.1.3.2)
214
+ bundler (>= 1.15.0)
215
+ railties (= 7.1.3.2)
216
+ rails-dom-testing (2.2.0)
217
+ activesupport (>= 5.0.0)
218
+ minitest
219
+ nokogiri (>= 1.6)
220
+ rails-html-sanitizer (1.6.0)
221
+ loofah (~> 2.21)
222
+ nokogiri (~> 1.14)
223
+ railties (7.1.3.2)
224
+ actionpack (= 7.1.3.2)
225
+ activesupport (= 7.1.3.2)
226
+ irb
227
+ rackup (>= 1.0.0)
228
+ rake (>= 12.2)
229
+ thor (~> 1.0, >= 1.2.2)
230
+ zeitwerk (~> 2.6)
78
231
  rainbow (3.1.1)
79
- rake (13.0.6)
232
+ rake (13.2.1)
233
+ rdoc (6.6.3.1)
234
+ psych (>= 4.0.0)
80
235
  redis-client (0.22.1)
81
236
  connection_pool
82
- regexp_parser (2.8.0)
83
- rexml (3.2.5)
84
- rspec (3.12.0)
85
- rspec-core (~> 3.12.0)
86
- rspec-expectations (~> 3.12.0)
87
- rspec-mocks (~> 3.12.0)
88
- rspec-core (3.12.2)
89
- rspec-support (~> 3.12.0)
90
- rspec-expectations (3.12.3)
237
+ regexp_parser (2.9.1)
238
+ reline (0.5.7)
239
+ io-console (~> 0.5)
240
+ rexml (3.2.6)
241
+ rspec (3.13.0)
242
+ rspec-core (~> 3.13.0)
243
+ rspec-expectations (~> 3.13.0)
244
+ rspec-mocks (~> 3.13.0)
245
+ rspec-core (3.13.0)
246
+ rspec-support (~> 3.13.0)
247
+ rspec-expectations (3.13.0)
91
248
  diff-lcs (>= 1.2.0, < 2.0)
92
- rspec-support (~> 3.12.0)
93
- rspec-mocks (3.12.5)
249
+ rspec-support (~> 3.13.0)
250
+ rspec-mocks (3.13.1)
94
251
  diff-lcs (>= 1.2.0, < 2.0)
95
- rspec-support (~> 3.12.0)
96
- rspec-support (3.12.0)
97
- rubocop (1.51.0)
252
+ rspec-support (~> 3.13.0)
253
+ rspec-rails (6.1.2)
254
+ actionpack (>= 6.1)
255
+ activesupport (>= 6.1)
256
+ railties (>= 6.1)
257
+ rspec-core (~> 3.13)
258
+ rspec-expectations (~> 3.13)
259
+ rspec-mocks (~> 3.13)
260
+ rspec-support (~> 3.13)
261
+ rspec-support (3.13.1)
262
+ rubocop (1.63.5)
98
263
  json (~> 2.3)
264
+ language_server-protocol (>= 3.17.0)
99
265
  parallel (~> 1.10)
100
- parser (>= 3.2.0.0)
266
+ parser (>= 3.3.0.2)
101
267
  rainbow (>= 2.2.2, < 4.0)
102
268
  regexp_parser (>= 1.8, < 3.0)
103
269
  rexml (>= 3.2.5, < 4.0)
104
- rubocop-ast (>= 1.28.0, < 2.0)
270
+ rubocop-ast (>= 1.31.1, < 2.0)
105
271
  ruby-progressbar (~> 1.7)
106
272
  unicode-display_width (>= 2.4.0, < 3.0)
107
- rubocop-ast (1.28.1)
108
- parser (>= 3.2.1.0)
273
+ rubocop-ast (1.31.3)
274
+ parser (>= 3.3.1.0)
109
275
  ruby-progressbar (1.13.0)
110
- ruby2_keywords (0.0.5)
111
- sentry-ruby (5.16.1)
276
+ sentry-ruby (5.17.3)
277
+ bigdecimal
112
278
  concurrent-ruby (~> 1.0, >= 1.0.2)
113
279
  sidekiq (7.2.4)
114
280
  concurrent-ruby (< 2)
115
281
  connection_pool (>= 2.3.0)
116
282
  rack (>= 2.2.4)
117
283
  redis-client (>= 0.19.0)
284
+ sqlite3 (1.7.3)
285
+ mini_portile2 (~> 2.8.0)
286
+ sqlite3 (1.7.3-x86_64-darwin)
287
+ sqlite3 (1.7.3-x86_64-linux)
288
+ stringio (3.1.0)
118
289
  strongmind-oneroster-client (2.0.3)
119
290
  json (~> 2.1, >= 2.1.0)
120
291
  typhoeus (~> 1.0, >= 1.0.1)
@@ -123,17 +294,24 @@ GEM
123
294
  sidekiq (>= 5.0, < 8.0)
124
295
  sys-uname (1.2.3)
125
296
  ffi (~> 1.1)
126
- typhoeus (1.4.0)
297
+ thor (1.3.1)
298
+ timecop (0.9.8)
299
+ timeout (0.4.1)
300
+ typhoeus (1.4.1)
127
301
  ethon (>= 0.9.0)
128
302
  tzinfo (2.0.6)
129
303
  concurrent-ruby (~> 1.0)
130
- unicode-display_width (2.4.2)
304
+ unicode-display_width (2.5.0)
131
305
  uri (0.13.0)
132
- webmock (3.22.0)
306
+ webmock (3.23.0)
133
307
  addressable (>= 2.8.0)
134
308
  crack (>= 0.3.2)
135
309
  hashdiff (>= 0.4.0, < 2.0.0)
136
- zeitwerk (2.6.13)
310
+ webrick (1.8.1)
311
+ websocket-driver (0.7.6)
312
+ websocket-extensions (>= 0.1.0)
313
+ websocket-extensions (0.1.5)
314
+ zeitwerk (2.6.14)
137
315
 
138
316
  PLATFORMS
139
317
  ruby
@@ -141,6 +319,7 @@ PLATFORMS
141
319
  x86_64-linux
142
320
 
143
321
  DEPENDENCIES
322
+ activesupport (~> 7.1, >= 7.1.3.2)
144
323
  factory_bot
145
324
  faker
146
325
  faraday
@@ -148,12 +327,16 @@ DEPENDENCIES
148
327
  jwt (~> 1.5, >= 1.5.4)
149
328
  learnosity-sdk (~> 0.2.2)
150
329
  multi_json
330
+ rails (~> 7.1)
151
331
  rake (~> 13.0)
152
- rspec (~> 3.6, >= 3.6.0)
332
+ rspec
333
+ rspec-rails (~> 6.1.0)
153
334
  rubocop
154
335
  sentry-ruby
336
+ sqlite3 (~> 1.4)
155
337
  strongmind-oneroster-client (~> 2.0.3)
156
338
  strongmind-platform-sdk!
339
+ timecop
157
340
  webmock
158
341
 
159
342
  BUNDLED WITH
@@ -0,0 +1,72 @@
1
+ require 'active_support/concern'
2
+
3
+ module PlatformSdk
4
+ module ActiveRecord
5
+
6
+ module DataPipelineable
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ after_create -> { send_to_pipeline('created') }
11
+ before_destroy -> { send_to_pipeline('destroyed') }
12
+ after_update -> { send_to_pipeline('modified') }
13
+ end
14
+
15
+ def pipeline_payload(action)
16
+ {
17
+ "noun": pipeline_noun,
18
+ "identifiers": pipeline_identifiers,
19
+ "meta": pipeline_meta,
20
+ "data": pipeline_data(action),
21
+ "envelope_version": '1.0.0',
22
+ "message_timestamp": Time.current.utc.iso8601
23
+ }
24
+ end
25
+
26
+ def pipeline_noun
27
+ "StrongMind.Central.#{self.class.name}"
28
+ end
29
+
30
+ def pipeline_identifiers
31
+ {
32
+ "id": id
33
+ }
34
+ end
35
+
36
+ def pipeline_meta
37
+ {
38
+ "source": 'strongmind-central'
39
+ }
40
+ end
41
+
42
+ def pipeline_data(action)
43
+ data_hash = { action: }.merge!(attributes.symbolize_keys)
44
+
45
+ data_hash.merge!(pipeline_additional_attributes)
46
+
47
+ data_hash
48
+ end
49
+
50
+ def pipeline_additional_attributes
51
+ {}
52
+ end
53
+
54
+ def one_roster_pipeline_payload(deleted: false)
55
+ {}
56
+ end
57
+
58
+ def send_to_pipeline(action)
59
+ credentials = {
60
+ pipeline_host: ENV.fetch('DATA_PIPELINE_HOST', 'stage-di-data-pipeline-api.strongmind.com'),
61
+ pipeline_username: ENV.fetch('DATA_PIPELINE_USERNAME', 'canvas_prod'),
62
+ pipeline_password: ENV.fetch('DATA_PIPELINE_PASSWORD', '')
63
+ }
64
+ client = PlatformSdk::DataPipeline::Client.new(credentials)
65
+ client.post(pipeline_payload(action)) unless Rails.env.development?
66
+ return unless respond_to?(:one_roster_data_type) && !Rails.env.development?
67
+
68
+ client.post(one_roster_pipeline_payload(deleted: action == "destroyed"))
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,42 @@
1
+ module PlatformSdk
2
+ module Central
3
+ class Client
4
+ attr_reader :access_token, :base_url, :conn
5
+
6
+ def initialize(base_url, access_token, conn: nil)
7
+ @access_token = access_token
8
+ @base_url = base_url
9
+ @conn = conn || build_connection
10
+ end
11
+
12
+ def user(uid)
13
+ resource_path = "/api/users/#{uid}"
14
+ response = get(resource_path)
15
+ response.body
16
+ end
17
+
18
+ private
19
+
20
+ def build_connection
21
+ Faraday.new(@base_url) do |faraday|
22
+ faraday.headers = default_headers
23
+ faraday.adapter Faraday.default_adapter
24
+ faraday.response :json, content_type: /\bjson$/, parser_options: { symbolize_names: true }
25
+ faraday.response :raise_error
26
+ end
27
+ end
28
+
29
+ def default_headers
30
+ {
31
+ "Content-Type" => "application/json",
32
+ "Authorization" => "Bearer #{access_token}"
33
+ }
34
+ end
35
+
36
+ def get(path, params = {})
37
+ @conn.get(path, params)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "platform_sdk/central/client"
4
+
5
+ module PlatformSdk
6
+ module Central
7
+ class Error < StandardError; end
8
+ end
9
+ end
@@ -0,0 +1,81 @@
1
+ module PlatformSdk
2
+ module SpecSupport
3
+ RSpec.shared_examples "DataPipelineable" do | data = nil|
4
+ let(:pipeline_payload) do
5
+ {
6
+ "noun": "StrongMind.Central.#{described_class.name}",
7
+ "identifiers": { "id": record.id },
8
+ "meta": { "source": 'strongmind-central' },
9
+ "data": data || default_data,
10
+ "envelope_version": '1.0.0',
11
+ "message_timestamp": Time.current.utc.iso8601
12
+ }
13
+ end
14
+ let(:default_data) do
15
+ {
16
+ action:
17
+ }.merge!(record.attributes.symbolize_keys)
18
+ end
19
+ let(:record) { build(described_class.to_s.downcase.to_sym) }
20
+ let(:data_pipeline_client) { double(PlatformSdk::DataPipeline::Client)}
21
+
22
+ before do
23
+ allow(PlatformSdk::DataPipeline::Client).to receive(:new).and_return(data_pipeline_client)
24
+ allow(data_pipeline_client).to receive(:post)
25
+ Timecop.freeze(DateTime.parse('2024-06-09 04:20:00'))
26
+ end
27
+
28
+ context 'after_create callbacks' do
29
+ let(:action) { 'created' }
30
+
31
+ it "defines an after_create callback" do
32
+ record.save!
33
+ expect(data_pipeline_client).to have_received(:post).with(pipeline_payload)
34
+ end
35
+ end
36
+
37
+ context 'before_destroy callbacks' do
38
+ let(:action) { 'destroyed' }
39
+
40
+ it "defines an after_destroy callback" do
41
+ record.save!
42
+ record.destroy
43
+ expect(data_pipeline_client).to have_received(:post).with(pipeline_payload)
44
+ end
45
+ end
46
+
47
+ context 'after_update callbacks' do
48
+ let(:action) { 'modified' }
49
+
50
+ it "defines an after_update callback" do
51
+ record.save!
52
+ column = column_to_update(record)
53
+ update_record(record, column)
54
+ expect(data_pipeline_client).to have_received(:post).with(pipeline_payload)
55
+ end
56
+ end
57
+
58
+ def column_to_update(record)
59
+ [:string, :integer, :boolean].each do |type|
60
+ if record.class.columns.select { |c| c.sql_type_metadata.type == type }.any?
61
+ return record.class.columns.select { |c| c.sql_type_metadata.type == type }.first.name
62
+ end
63
+ end
64
+ end
65
+
66
+ def update_record(record, column)
67
+ column_class = record[column]
68
+ case column_class
69
+ when String
70
+ record.update!(column => 'new value')
71
+ when Integer
72
+ record.update!(column => 69)
73
+ when Boolean
74
+ record.update!(column => !record[column])
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlatformSdk
4
+ module SpecSupport
5
+ RSpec.shared_examples "OneRosterDataPipelineable" do |record_keys|
6
+ let(:data) do
7
+ record_keys.each_with_object({}) do |key, hash|
8
+ if key == "_type"
9
+ hash[:type] = record.try(key)
10
+ next
11
+ end
12
+ hash[key.to_sym] = record.try(key)
13
+ end
14
+ end
15
+ let(:pipeline_payload) do
16
+ {
17
+ "noun": "StrongMind.Platform.OneRoster.#{record.one_roster_data_type.capitalize}",
18
+ "identifiers": { "sourcedId": record.roster_id },
19
+ "meta": {
20
+ "version": "3",
21
+ "source": "Central OneRoster API"
22
+ },
23
+ "data": one_roster_common_data.merge!(data),
24
+ "envelope_version": "1.0.0",
25
+ "message_timestamp": Time.current.utc.iso8601
26
+ }
27
+ end
28
+ let(:record) { build(described_class.to_s.downcase.to_sym) }
29
+ let(:one_roster_common_data) do
30
+ {
31
+ "sourcedId": record.roster_id,
32
+ "status": record.status,
33
+ "dateLastModified": record.updated_at,
34
+ "metadata": record.metadata
35
+ }
36
+ end
37
+ let(:data_pipeline_client) { double(PlatformSdk::DataPipeline::Client) }
38
+
39
+ before do
40
+ allow(PlatformSdk::DataPipeline::Client).to receive(:new).and_return(data_pipeline_client)
41
+ allow(data_pipeline_client).to receive(:post)
42
+ Timecop.freeze(DateTime.parse("2024-06-09 04:20:00"))
43
+ end
44
+
45
+ context "after_create callbacks" do
46
+ let(:action) { "created" }
47
+
48
+ it "defines an after_create callback" do
49
+ record.save!
50
+ expect(data_pipeline_client).to have_received(:post).with(pipeline_payload)
51
+ end
52
+ end
53
+
54
+ context "before_destroy callbacks" do
55
+ let(:action) { "destroyed" }
56
+ let(:one_roster_common_data_deleted) do
57
+ one_roster_common_data.merge(
58
+ "status": "tobedeleted"
59
+ )
60
+ end
61
+
62
+ let(:pipeline_payload_deleted) do
63
+ pipeline_payload.merge("data": one_roster_common_data_deleted)
64
+ end
65
+
66
+ it "defines an after_destroy callback" do
67
+ record.save!
68
+ record.destroy
69
+ expect(data_pipeline_client).to have_received(:post).with(pipeline_payload)
70
+ expect(data_pipeline_client).to have_received(:post).with(pipeline_payload_deleted)
71
+ end
72
+ end
73
+
74
+ context "after_update callbacks" do
75
+ let(:action) { "modified" }
76
+
77
+ it "defines an after_update callback" do
78
+ record.save!
79
+ column = column_to_update(record)
80
+ update_record(record, column)
81
+ expect(data_pipeline_client).to have_received(:post).with(pipeline_payload)
82
+ end
83
+ end
84
+
85
+ def column_to_update(record)
86
+ %i[string integer boolean].each do |type|
87
+ if record.class.columns.select { |c| c.sql_type_metadata.type == type }.any?
88
+ return record.class.columns.select { |c| c.sql_type_metadata.type == type }.first.name
89
+ end
90
+ end
91
+ end
92
+
93
+ def update_record(record, column)
94
+ column_class = record[column]
95
+ case column_class
96
+ when String
97
+ record.update!(column => "new value")
98
+ when Integer
99
+ record.update!(column => 69)
100
+ when Boolean
101
+ record.update!(column => !record[column])
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'platform_sdk/spec_support/shared_examples/data_pipelineable_examples'
4
+ require 'platform_sdk/spec_support/shared_examples/one_roster_data_pipelineable_examples'
5
+
6
+ module PlatformSdk
7
+ module SpecSupport
8
+ end
9
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PlatformSdk
4
- VERSION = "3.14.4"
4
+ VERSION = "3.16.0"
5
5
  end
data/lib/platform_sdk.rb CHANGED
@@ -15,6 +15,9 @@ require "platform_sdk/learnosity_api"
15
15
  require "platform_sdk/canvas_api"
16
16
  require "platform_sdk/bynder"
17
17
  require "platform_sdk/events"
18
+ require "platform_sdk/central"
19
+ require "platform_sdk/active_record/data_pipelineable"
20
+ require "platform_sdk/spec_support"
18
21
 
19
22
  module PlatformSdk
20
23
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strongmind-platform-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.14.4
4
+ version: 3.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Platform Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-10 00:00:00.000000000 Z
11
+ date: 2024-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -156,6 +156,34 @@ dependencies:
156
156
  - - ">="
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: activesupport
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '7.1'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '7.1'
173
+ - !ruby/object:Gem::Dependency
174
+ name: rails
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '7.1'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '7.1'
159
187
  description: Includes a wrapper for the swagger generated OneRoster management clients
160
188
  email:
161
189
  - horseshoes@strongmind.com
@@ -177,12 +205,15 @@ files:
177
205
  - Rakefile
178
206
  - docs/identity_installation_in_rails.md
179
207
  - lib/platform_sdk.rb
208
+ - lib/platform_sdk/active_record/data_pipelineable.rb
180
209
  - lib/platform_sdk/aws.rb
181
210
  - lib/platform_sdk/aws/secrets_manager_client.rb
182
211
  - lib/platform_sdk/bynder.rb
183
212
  - lib/platform_sdk/bynder/client.rb
184
213
  - lib/platform_sdk/canvas_api.rb
185
214
  - lib/platform_sdk/canvas_api/client.rb
215
+ - lib/platform_sdk/central.rb
216
+ - lib/platform_sdk/central/client.rb
186
217
  - lib/platform_sdk/data_pipeline.rb
187
218
  - lib/platform_sdk/data_pipeline/data_pipeline_client.rb
188
219
  - lib/platform_sdk/edfi.rb
@@ -213,6 +244,9 @@ files:
213
244
  - lib/platform_sdk/power_school/client.rb
214
245
  - lib/platform_sdk/power_school/special_program.rb
215
246
  - lib/platform_sdk/sentry.rb
247
+ - lib/platform_sdk/spec_support.rb
248
+ - lib/platform_sdk/spec_support/shared_examples/data_pipelineable_examples.rb
249
+ - lib/platform_sdk/spec_support/shared_examples/one_roster_data_pipelineable_examples.rb
216
250
  - lib/platform_sdk/version.rb
217
251
  - sig/platform_sdk/identity/auth_client.rbs
218
252
  - sig/platform_sdk/learnosity_api/client.rbs