scorm_engine 0.7.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/lib/scorm_engine/api/endpoints.rb +4 -0
  3. data/lib/scorm_engine/api/endpoints/configuration.rb +64 -0
  4. data/lib/scorm_engine/api/endpoints/courses/configuration.rb +1 -1
  5. data/lib/scorm_engine/api/endpoints/dispatches.rb +45 -2
  6. data/lib/scorm_engine/api/endpoints/registrations/configuration.rb +1 -1
  7. data/lib/scorm_engine/api/endpoints/tenants/configuration.rb +108 -0
  8. data/lib/scorm_engine/configuration.rb +4 -2
  9. data/lib/scorm_engine/faraday/connection.rb +10 -4
  10. data/lib/scorm_engine/faraday/request.rb +17 -4
  11. data/lib/scorm_engine/models.rb +2 -0
  12. data/lib/scorm_engine/models/dispatch_registration_count.rb +49 -0
  13. data/lib/scorm_engine/models/tenant_configuration.rb +34 -0
  14. data/lib/scorm_engine/version.rb +1 -1
  15. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Configuration/_get_app_configuration/is_successful.yml +64 -0
  16. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Configuration/_get_app_configuration/returns_settings_and_values.yml +64 -0
  17. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Configuration/_post_app_configuration/fails_when_settings_are_invalid.yml +48 -0
  18. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Configuration/_post_app_configuration/is_successful.yml +44 -0
  19. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Configuration/_post_app_configuration/persists_the_settings.yml +207 -0
  20. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Courses_Import/_get_course_import/successful_imports/works.yml +6 -6
  21. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Courses_Import/_get_course_import/unsuccessful_imports/fails_to_import_given_an_invalid_url.yml +7 -7
  22. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Courses_Import/_post_course_import/unsuccessful_imports/fails_to_import_a_previously_existing_course.yml +2 -2
  23. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Dispatches/_delete_dispatch_registration_count/is_successful.yml +30 -0
  24. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Dispatches/_delete_dispatch_registration_count/succeeds_even_when_id_is_invalid.yml +30 -0
  25. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Dispatches/_get_dispatch_registration_count/fails_when_id_is_invalid.yml +63 -0
  26. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Dispatches/_get_dispatch_registration_count/is_successful.yml +63 -0
  27. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Dispatches/_get_dispatch_registration_count/results/sucessfully_creates_the_dispatch_attributes.yml +63 -0
  28. data/spec/fixtures/vcr/ScormEngine_Api_Endpoints_Dispatches/_get_dispatch_registration_count/when_dispatch_has_registrations/knows_it_s_registration_count.yml +63 -0
  29. data/spec/scorm_engine/api/endpoints/configuration_spec.rb +51 -0
  30. data/spec/scorm_engine/api/endpoints/courses/import_spec.rb +1 -1
  31. data/spec/scorm_engine/api/endpoints/dispatches_spec.rb +47 -1
  32. data/spec/scorm_engine/api/endpoints/tenants/configuration_spec.rb +126 -0
  33. data/spec/scorm_engine/faraday/connection_spec.rb +23 -5
  34. data/spec/scorm_engine/models/dispatch_registration_count_spec.rb +42 -0
  35. data/spec/scorm_engine/models/tenant_configuration_spec.rb +16 -0
  36. data/spec/support/scorm_engine.rb +1 -1
  37. data/spec/support/vcr.rb +1 -0
  38. metadata +33 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96f9e3115cb5345e489c54e9d49ac10dd67b1b2bb7dbd30878a222c5eca3dde5
4
- data.tar.gz: a64f2c8ce1dcc564e71d06a020324e947406020e5930f24a5f59b91b377d47c5
3
+ metadata.gz: 125a0882006861786fcc335c3656cd75b69d832669ae34c9b7e6a93969137580
4
+ data.tar.gz: f33e66667a0866bf8bf133c6a0a9cddcca990a02e4737fc2c4f7f1ef53ecac6e
5
5
  SHA512:
6
- metadata.gz: 15dae198e937cfe18146767424e8361a7464372137dda3123a78cabcd87f3b9d0d2da92e566dfa82f942f3955caff1246160311ea403a2afb084fd95f5503ba9
7
- data.tar.gz: 189edb44a0f257a82336efdb39e4876b47c16a021cc49d81db2644aac2068167d7b06193e80e52dfc0fc4c1866d1ce635f5f8564c32958cbccab013bb8c46d1b
6
+ metadata.gz: 2b845922b85e20a822b7d519e1d919ce61333c89da2525a9eb3d37ace034b1e525a53a43a77229eb8804179f25ff541c4afcbd1ccff4851f140cbb48e301ceb6
7
+ data.tar.gz: d221c2aee2b0761b9ce568bf428c724ba7451224bf74e96a5ad6610ff89e8174fdcf2350b1089ba923f2d3576a9eb2e2aa99edfcf17e781fc709556b9ba37399
@@ -1,4 +1,5 @@
1
1
  require_relative "endpoints/about"
2
+ require_relative "endpoints/configuration"
2
3
  require_relative "endpoints/courses"
3
4
  require_relative "endpoints/courses/configuration"
4
5
  require_relative "endpoints/courses/import"
@@ -8,11 +9,13 @@ require_relative "endpoints/ping"
8
9
  require_relative "endpoints/registrations"
9
10
  require_relative "endpoints/registrations/configuration"
10
11
  require_relative "endpoints/registrations/launch_history"
12
+ require_relative "endpoints/tenants/configuration"
11
13
 
12
14
  module ScormEngine
13
15
  module Api
14
16
  module Endpoints
15
17
  include About
18
+ include Configuration
16
19
  include Courses
17
20
  include Courses::Configuration
18
21
  include Courses::Import
@@ -22,6 +25,7 @@ module ScormEngine
22
25
  include Registrations
23
26
  include Registrations::Configuration
24
27
  include Registrations::LaunchHistory
28
+ include Tenants::Configuration
25
29
 
26
30
  private
27
31
 
@@ -0,0 +1,64 @@
1
+ module ScormEngine
2
+ module Api
3
+ module Endpoints
4
+ module Configuration
5
+ #
6
+ # Get the application settings currently configured in Engine.
7
+ #
8
+ # @see http://rustici-docs.s3.amazonaws.com/engine/20.1.x/api/apiV2.html#/appManagement/GetApplicationConfiguration
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # @option options [Boolean] :for_tenant
13
+ # Indicates whether the configuration effective for the current tenant should be fetched.
14
+ # If false or not specified, will return configuration settings for the application in general.
15
+ #
16
+ # @return [ScormEngine::Response]
17
+ #
18
+ def get_app_configuration(options = {})
19
+ api_v2(without_tenant: !options.fetch(:for_tenant, false)) do
20
+ response = get("appManagement/configuration")
21
+
22
+ result = OpenStruct.new
23
+
24
+ response.body["settingItems"].each do |setting|
25
+ result[setting["id"]] = setting["effectiveValue"]
26
+ end
27
+
28
+ Response.new(raw_response: response, result: result)
29
+ end
30
+ end
31
+
32
+ #
33
+ # Set one or more application settings in Engine.
34
+ #
35
+ # @see http://rustici-docs.s3.amazonaws.com/engine/20.1.x/api/apiV2.html#/appManagement/SetApplicationConfiguration
36
+ #
37
+ # @param [Hash] options
38
+ #
39
+ # @option [Hash] settings
40
+ # The configuration settings to be updated.
41
+ #
42
+ # @option options [Boolean] :for_tenant
43
+ # Indicates whether the configuration should be set for the current tenant.
44
+ # If false or not specified, will update configuration settings for the application in general.
45
+ #
46
+ # @return [ScormEngine::Response]
47
+ #
48
+ def post_app_configuration(options = {})
49
+ require_options(options, :settings)
50
+
51
+ api_v2(without_tenant: !options.fetch(:for_tenant, false)) do
52
+ settings = options.delete(:settings)
53
+
54
+ body = { settings: settings.map { |k, v| { "settingId" => k, "value" => v.to_s } } }
55
+
56
+ response = post("appManagement/configuration", {}, body)
57
+
58
+ Response.new(raw_response: response)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,5 +1,5 @@
1
1
  #
2
- # TODO: Consider consolidating this and Registrations::Configuration, but only
2
+ # TODO: Consider consolidating this and [Registrations|Tenants]::Configuration, but only
3
3
  # after we're sure they are really 99.9% the same in terms of functionality.
4
4
  #
5
5
  module ScormEngine
@@ -272,8 +272,7 @@ module ScormEngine
272
272
 
273
273
  options = options.dup
274
274
  dispatch_id = options.delete(:dispatch_id)
275
- options[:type] ||= "SCORM12"
276
- options[:type]&.upcase!
275
+ options[:type] = options[:type]&.upcase || "SCORM12"
277
276
 
278
277
  response = get("dispatches/#{dispatch_id}/zip", options)
279
278
 
@@ -289,6 +288,49 @@ module ScormEngine
289
288
  Response.new(raw_response: response, result: result)
290
289
  end
291
290
 
291
+ #
292
+ # Get the registration count and last reset time of a dispatch.
293
+ #
294
+ # @see http://rustici-docs.s3.amazonaws.com/engine/2017.1.x.dispatch/api-dispatch.html#tenant__dispatches__dispatchId__registrationCount_get
295
+ #
296
+ # @param [Hash] options
297
+ #
298
+ # @option options [String] :dispatch_id
299
+ # The ID of the dispatch to get.
300
+ #
301
+ # @return [ScormEngine::Models::DispatchRegistrationCount]
302
+ #
303
+ def get_dispatch_registration_count(options = {})
304
+ require_options(options, :dispatch_id)
305
+
306
+ response = get("dispatches/#{options[:dispatch_id]}/registrationCount")
307
+
308
+ # merge options to pick up dispatch_id which isn't passed back in the response
309
+ result = response.success? ? ScormEngine::Models::DispatchRegistrationCount.new_from_api({ "id" => options[:dispatch_id] }.merge(response.body)) : nil
310
+
311
+ Response.new(raw_response: response, result: result)
312
+ end
313
+
314
+ #
315
+ # Reset the registration count and last reset time of a dispatch.
316
+ #
317
+ # @see http://rustici-docs.s3.amazonaws.com/engine/2017.1.x.dispatch/api-dispatch.html#tenant__dispatches__dispatchId__registrationCount_delete
318
+ #
319
+ # @param [Hash] options
320
+ #
321
+ # @option options [String] :dispatch_id
322
+ # The ID of the dispatch to get.
323
+ #
324
+ # @return [ScormEngine::Response]
325
+ #
326
+ def delete_dispatch_registration_count(options = {})
327
+ require_options(options, :dispatch_id)
328
+
329
+ response = delete("dispatches/#{options[:dispatch_id]}/registrationCount")
330
+
331
+ Response.new(raw_response: response)
332
+ end
333
+
292
334
  private
293
335
 
294
336
  def coerce_dispatch_options(options = {})
@@ -301,6 +343,7 @@ module ScormEngine
301
343
 
302
344
  def coerce_expiration_date(date)
303
345
  return date if date == "none"
346
+
304
347
  date = date.is_a?(String) ? Date.parse(date) : date
305
348
  date&.iso8601 # might be nil
306
349
  rescue ArgumentError # unparsable date string
@@ -1,5 +1,5 @@
1
1
  #
2
- # TODO: Consider consolidating this and Courses::Configuration, but only after we're
2
+ # TODO: Consider consolidating this and [Courses|Tenants]::Configuration, but only after we're
3
3
  # sure they are really 99.9% the same in terms of functionality.
4
4
  #
5
5
  module ScormEngine
@@ -0,0 +1,108 @@
1
+ #
2
+ # TODO: Consider consolidating this and [Courses|Registrations]::Configuration, but only
3
+ # after we're sure they are really 99.9% the same in terms of functionality.
4
+ #
5
+ module ScormEngine
6
+ module Api
7
+ module Endpoints
8
+ module Tenants
9
+ module Configuration
10
+
11
+ #
12
+ # Returns the effective value of every setting at this level, as well
13
+ # as the effective value of any setting at a more specific level.
14
+ #
15
+ # @see http://rustici-docs.s3.amazonaws.com/engine/2017.1.x/api.html#tenant__configuration_get
16
+ #
17
+ # @return [ScormEngine::Models::TenantConfiguration]
18
+ #
19
+ def get_tenant_configuration
20
+ response = get("configuration")
21
+
22
+ result = response.success? ? ScormEngine::Models::TenantConfiguration.new_from_api(response.body) : nil
23
+
24
+ Response.new(raw_response: response, result: result)
25
+ end
26
+
27
+ #
28
+ # Bulk set configuration settings via POST request.
29
+ #
30
+ # @see http://rustici-docs.s3.amazonaws.com/engine/2017.1.x/api.html#tenant__configuration_post
31
+ #
32
+ # @param [Hash] options
33
+ #
34
+ # @option options [Hash] :settings
35
+ # Key/value pairs of configuration options to set.
36
+ #
37
+ # @return [ScormEngine::Response]
38
+ #
39
+ def post_tenant_configuration(options = {})
40
+ require_options(options, :settings)
41
+
42
+ options = options.dup
43
+ settings = options.delete(:settings)
44
+
45
+ body = { settings: settings.map { |k, v| { "settingId" => k, "value" => v.to_s } } }
46
+
47
+ response = post("configuration", options, body)
48
+
49
+ Response.new(raw_response: response)
50
+ end
51
+
52
+ #
53
+ # Returns the effective value for this configuration setting for the resource being configured.
54
+ #
55
+ # @see http://rustici-docs.s3.amazonaws.com/engine/2017.1.x/api.html#tenant__configuration__settingId__get
56
+ #
57
+ # @param [Hash] options
58
+ #
59
+ # @option options [String] :setting_id
60
+ # The ID of the setting to get.
61
+ #
62
+ # @return [String]
63
+ #
64
+ def get_tenant_configuration_setting(options = {})
65
+ require_options(options, :setting_id)
66
+
67
+ options = options.dup
68
+ setting_id = options.delete(:setting_id)
69
+
70
+ response = get("configuration/#{setting_id}", options)
71
+
72
+ result = response.success? ? response.body["value"] : nil
73
+
74
+ Response.new(raw_response: response, result: result)
75
+ end
76
+
77
+ #
78
+ # Sets the value for this configuration setting, for the resource being configured.
79
+ #
80
+ # @see http://rustici-docs.s3.amazonaws.com/engine/2017.1.x/api.html#tenant__configuration__settingId__put
81
+ #
82
+ # @param [Hash] options
83
+ #
84
+ # @option options [String] :setting_id
85
+ # The ID of the setting to set.
86
+ #
87
+ # @option options [String] :value ("")
88
+ # The value of the setting to set.
89
+ #
90
+ # @return [ScormEngine::Response]
91
+ #
92
+ def put_tenant_configuration_setting(options = {})
93
+ require_options(options, :setting_id)
94
+
95
+ options = options.dup
96
+ setting_id = options.delete(:setting_id)
97
+
98
+ body = { value: options.delete(:value).to_s }
99
+
100
+ response = put("configuration/#{setting_id}", options, body)
101
+
102
+ Response.new(raw_response: response)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -10,8 +10,9 @@ module ScormEngine
10
10
  end
11
11
 
12
12
  class Configuration
13
- # http://rustici-docs.s3.amazonaws.com/engine/2017.1.x/api.html
14
- attr_accessor :protocol, :host, :path_prefix
13
+ # Legacy v1 API: http://rustici-docs.s3.amazonaws.com/engine/2017.1.x/api.html
14
+ # Latest v2 API: https://rustici-docs.s3.amazonaws.com/engine/20.1.x/api/apiV2.html
15
+ attr_accessor :protocol, :host, :path_prefix, :v2_path_prefix
15
16
 
16
17
  # http://rustici-docs.s3.amazonaws.com/engine/2017.1.x/Architecture-API.html#api-authentication
17
18
  attr_accessor :username, :password
@@ -28,6 +29,7 @@ module ScormEngine
28
29
  @protocol = ENV.fetch("SCORM_ENGINE_PROTOCOL", "https")
29
30
  @host = ENV["SCORM_ENGINE_HOST"]
30
31
  @path_prefix = ENV.fetch("SCORM_ENGINE_PATH_PREFIX", "/ScormEngineInterface/api/v1/")
32
+ @v2_path_prefix = ENV.fetch("SCORM_ENGINE_V2_PATH_PREFIX", "/ScormEngineInterface/api/v2/")
31
33
 
32
34
  @username = ENV["SCORM_ENGINE_USERNAME"]
33
35
  @password = ENV["SCORM_ENGINE_PASSWORD"]
@@ -5,18 +5,24 @@ module ScormEngine
5
5
  module Faraday
6
6
  module Connection
7
7
 
8
- def base_uri
8
+ def base_uri(version: 1)
9
9
  uri = URI("")
10
10
  uri.scheme = ScormEngine.configuration.protocol
11
11
  uri.host = ScormEngine.configuration.host
12
- uri.path = ScormEngine.configuration.path_prefix
12
+
13
+ uri.path = if version == 2
14
+ ScormEngine.configuration.v2_path_prefix
15
+ else
16
+ ScormEngine.configuration.path_prefix
17
+ end
18
+
13
19
  URI(uri.to_s) # convert URI::Generic to URI:HTTPS
14
20
  end
15
21
 
16
22
  private
17
23
 
18
- def connection
19
- @connection ||= ::Faraday.new(url: base_uri.to_s) do |faraday|
24
+ def connection(version: 1)
25
+ @connection ||= ::Faraday.new(url: base_uri(version: version).to_s) do |faraday|
20
26
  faraday.headers["User-Agent"] = "ScormEngine Ruby Gem #{ScormEngine::VERSION}"
21
27
 
22
28
  faraday.basic_auth(ScormEngine.configuration.username, ScormEngine.configuration.password)
@@ -17,15 +17,28 @@ module ScormEngine
17
17
  request(:delete, path, options)
18
18
  end
19
19
 
20
+ def api_v2(without_tenant: false)
21
+ @api_version = 2
22
+ @without_tenant = without_tenant
23
+
24
+ yield
25
+ ensure
26
+ @api_version = 1
27
+ end
28
+
20
29
  private
21
30
 
22
31
  def request(method, path, options, body = nil)
23
- # "more" pagination urls are fully qualified
24
- path = "#{tenant}/#{path}" unless path =~ %r{\Ahttps?://}
32
+ connection(version: @api_version).send(method) do |request|
33
+ if @api_version == 2
34
+ request.headers["engineTenantName"] = tenant unless @without_tenant
35
+ else
36
+ # "more" pagination urls are fully qualified
37
+ path = "#{tenant}/#{path}" unless path =~ %r{\Ahttps?://}
38
+ end
25
39
 
26
- options = coerce_options(options)
40
+ options = coerce_options(options)
27
41
 
28
- connection.send(method) do |request|
29
42
  case method
30
43
  when :get, :delete
31
44
  request.url(path, options)
@@ -4,6 +4,7 @@ require_relative "models/course_configuration"
4
4
  require_relative "models/course_import"
5
5
  require_relative "models/destination"
6
6
  require_relative "models/dispatch"
7
+ require_relative "models/dispatch_registration_count"
7
8
  require_relative "models/dispatch_zip"
8
9
  require_relative "models/learner"
9
10
  require_relative "models/registration"
@@ -11,3 +12,4 @@ require_relative "models/registration_activity_detail"
11
12
  require_relative "models/registration_configuration"
12
13
  require_relative "models/registration_launch_history"
13
14
  require_relative "models/registration_runtime_interaction"
15
+ require_relative "models/tenant_configuration"
@@ -0,0 +1,49 @@
1
+ require "date"
2
+
3
+ module ScormEngine
4
+ module Models
5
+ class DispatchRegistrationCount < Base
6
+ # @attr
7
+ # The external identification of this dispatch.
8
+ # @return [String]
9
+ attr_accessor :id
10
+
11
+ # @attr
12
+ # The registration count for this dispatch.
13
+ # @return [Integer]
14
+ attr_accessor :registration_count
15
+
16
+ # @attr
17
+ # The date and time of the last count reset, if any.
18
+ # @return [DateTime]
19
+ attr_accessor :last_reset_at
20
+
21
+ def self.new_from_api(options = {})
22
+ this = new
23
+
24
+ this.options = options.dup
25
+ this.id = options["id"]
26
+ this.registration_count = options["registrationCount"].to_i
27
+ this.last_reset_at = get_last_reset_time(options)
28
+
29
+ this
30
+ end
31
+
32
+ #
33
+ # Extract and normalize the last reset datetime from the API options.
34
+ #
35
+ # @param [Hash] options
36
+ # The API options hash
37
+ #
38
+ # @return [Time]
39
+ # a date/time or nil if undefined.
40
+ #
41
+ def self.get_last_reset_time(options = {})
42
+ time = options["lastResetTime"]
43
+ return if time.nil? || time == "none"
44
+
45
+ Time.parse(time)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,34 @@
1
+ module ScormEngine
2
+ module Models
3
+ class TenantConfiguration < Base
4
+ # @attr
5
+ #
6
+ # @return [Hash]
7
+ attr_accessor :settings
8
+
9
+ def self.new_from_api(options = {})
10
+ this = new
11
+
12
+ this.options = options.dup
13
+ this.settings = get_settings_from_api(options)
14
+ this
15
+ end
16
+
17
+ #
18
+ # Extract and normalize the settings from the API options.
19
+ #
20
+ # @param [Hash] options
21
+ # The API options hash
22
+ #
23
+ # @return [Hash]
24
+ # A hash of key/value pairs.
25
+ #
26
+ def self.get_settings_from_api(options = {})
27
+ options["configurationItems"].reduce({}) do |m, o|
28
+ m[o["id"]] = o["value"]
29
+ m
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end