growthtribe_xapi 0.0.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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +28 -0
  3. data/CHANGELOG.md +2 -0
  4. data/CONTRIBUTING.md +7 -0
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +78 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +299 -0
  9. data/Rakefile +12 -0
  10. data/bin/rspec +29 -0
  11. data/lib/growthtribe_xapi.rb +2 -0
  12. data/lib/xapi.rb +224 -0
  13. data/lib/xapi/about.rb +15 -0
  14. data/lib/xapi/activity.rb +37 -0
  15. data/lib/xapi/activity_definition.rb +131 -0
  16. data/lib/xapi/agent.rb +44 -0
  17. data/lib/xapi/agent_account.rb +33 -0
  18. data/lib/xapi/attachment.rb +64 -0
  19. data/lib/xapi/context.rb +54 -0
  20. data/lib/xapi/context_activities.rb +102 -0
  21. data/lib/xapi/documents/activity_profile_document.rb +15 -0
  22. data/lib/xapi/documents/agent_profile_document.rb +15 -0
  23. data/lib/xapi/documents/document.rb +20 -0
  24. data/lib/xapi/documents/state_document.rb +15 -0
  25. data/lib/xapi/enum.rb +42 -0
  26. data/lib/xapi/errors.rb +9 -0
  27. data/lib/xapi/group.rb +37 -0
  28. data/lib/xapi/interaction_component.rb +32 -0
  29. data/lib/xapi/interaction_type.rb +58 -0
  30. data/lib/xapi/lrs_response.rb +14 -0
  31. data/lib/xapi/query_result_format.rb +6 -0
  32. data/lib/xapi/remote_lrs.rb +416 -0
  33. data/lib/xapi/result.rb +46 -0
  34. data/lib/xapi/score.rb +39 -0
  35. data/lib/xapi/statement.rb +53 -0
  36. data/lib/xapi/statement_ref.rb +31 -0
  37. data/lib/xapi/statements/statements_base.rb +70 -0
  38. data/lib/xapi/statements_query.rb +42 -0
  39. data/lib/xapi/statements_query_v095.rb +42 -0
  40. data/lib/xapi/statements_result.rb +17 -0
  41. data/lib/xapi/sub_statement.rb +19 -0
  42. data/lib/xapi/tcapi_version.rb +27 -0
  43. data/lib/xapi/team.rb +44 -0
  44. data/lib/xapi/team_analytics_query.rb +36 -0
  45. data/lib/xapi/verb.rb +35 -0
  46. data/lib/xapi/version.rb +4 -0
  47. data/spec/fixtures/about.json +10 -0
  48. data/spec/fixtures/statement.json +33 -0
  49. data/spec/spec_helper.rb +107 -0
  50. data/spec/support/helpers.rb +60 -0
  51. data/spec/xapi/activity_definition_spec.rb +37 -0
  52. data/spec/xapi/activity_spec.rb +23 -0
  53. data/spec/xapi/agent_account_spec.rb +13 -0
  54. data/spec/xapi/agent_spec.rb +24 -0
  55. data/spec/xapi/attachment_spec.rb +26 -0
  56. data/spec/xapi/context_activities_spec.rb +57 -0
  57. data/spec/xapi/context_spec.rb +32 -0
  58. data/spec/xapi/group_spec.rb +15 -0
  59. data/spec/xapi/interaction_component_spec.rb +18 -0
  60. data/spec/xapi/remote_lrs_spec.rb +46 -0
  61. data/spec/xapi/result_spec.rb +24 -0
  62. data/spec/xapi/score_spec.rb +12 -0
  63. data/spec/xapi/statement_ref_spec.rb +19 -0
  64. data/spec/xapi/statement_spec.rb +73 -0
  65. data/spec/xapi/sub_statement_spec.rb +30 -0
  66. data/spec/xapi/verb_spec.rb +17 -0
  67. data/xapi.gemspec +30 -0
  68. metadata +244 -0
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ require 'active_support/duration'
3
+
4
+ module Xapi
5
+ # Result Model class
6
+ class Result
7
+
8
+ attr_accessor :score, :success, :completion, :duration, :response, :extensions
9
+
10
+ def initialize(options={}, &block)
11
+ json = options.fetch(:json, nil)
12
+ if json
13
+ attributes = JSON.parse(json)
14
+ self.score = Xapi::Score.new(json: attributes['score'].to_json) if attributes['score']
15
+ self.success = attributes['success'] unless attributes['success'].nil?
16
+ self.completion = attributes['completion'] unless attributes['completion'].nil?
17
+ self.duration = ActiveSupport::Duration.parse(attributes['duration']) if attributes['duration']
18
+ self.response = attributes['response'] if attributes['response']
19
+ self.extensions = attributes['extensions'] if attributes['extensions']
20
+ else
21
+ self.score = options.fetch(:score, nil)
22
+ self.success = options.fetch(:success, nil)
23
+ self.completion = options.fetch(:completion, nil)
24
+ self.duration = options.fetch(:duration, nil)
25
+ self.response = options.fetch(:response, nil)
26
+ self.extensions = options.fetch(:extensions, nil)
27
+
28
+ if block_given?
29
+ block[self]
30
+ end
31
+ end
32
+ end
33
+
34
+ def serialize(version)
35
+ node = {}
36
+ node['score'] = score.serialize(version) if score
37
+ node['success'] = success unless success.nil?
38
+ node['completion'] = completion unless completion.nil?
39
+ node['duration'] = duration.iso8601 if duration
40
+ node['response'] = response if response
41
+ node['extensions'] = extensions if extensions
42
+
43
+ node
44
+ end
45
+ end
46
+ end
data/lib/xapi/score.rb ADDED
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # Score model class
4
+ class Score
5
+
6
+ attr_accessor :scaled, :raw, :min, :max
7
+
8
+ def initialize(options={}, &block)
9
+ json = options.fetch(:json, nil)
10
+ if json
11
+ attributes = JSON.parse(json)
12
+ self.scaled = attributes['scaled'] if attributes['scaled']
13
+ self.raw = attributes['raw'] if attributes['raw']
14
+ self.min = attributes['min'] if attributes['min']
15
+ self.max = attributes['max'] if attributes['max']
16
+ else
17
+ self.scaled = options.fetch(:scaled, nil)
18
+ self.raw = options.fetch(:raw, nil)
19
+ self.min = options.fetch(:min, nil)
20
+ self.max = options.fetch(:max, nil)
21
+
22
+ if block_given?
23
+ block[self]
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ def serialize(version)
30
+ node = {}
31
+ node['scaled'] = scaled if scaled
32
+ node['raw'] = raw if raw
33
+ node['min'] = min if min
34
+ node['max'] = max if max
35
+ node
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # Statement Class
4
+ class Statement < Statements::StatementsBase
5
+
6
+ attr_accessor :id, :stored, :authority, :version, :voided
7
+
8
+ def initialize(options={}, &block)
9
+ super(options, &block)
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.id = attributes['id'] if attributes['id']
14
+ self.stored = Time.parse(attributes['stored']) if attributes['stored']
15
+ self.authority = Xapi::Agent.new(json: attributes['authority'].to_json) if attributes['authority']
16
+ self.version = attributes['version'] if attributes['version']
17
+ self.voided = attributes['voided'] if attributes['voided']
18
+ else
19
+ self.id = options.fetch(:id, nil)
20
+ self.stored = options.fetch(:stored, nil)
21
+ self.authority = options.fetch(:authority, nil)
22
+ self.version = options.fetch(:version, nil)
23
+ self.voided = options.fetch(:voided, nil)
24
+
25
+ if block_given?
26
+ block[self]
27
+ end
28
+ end
29
+ end
30
+
31
+ def serialize(version)
32
+ node = super(version)
33
+
34
+ node['id'] = id if id
35
+ node['stored'] = stored.strftime('%FT%T%:z') if stored
36
+ node['authority'] = authority.serialize(version) if authority
37
+
38
+ if version == Xapi::TCAPIVersion::V095
39
+ node['voided'] = voided if voided
40
+ end
41
+
42
+ if version.ordinal >= Xapi::TCAPIVersion::V100.ordinal
43
+ node['version'] = version.to_s if version
44
+ end
45
+ node
46
+ end
47
+
48
+ def stamp(id: SecureRandom.uuid, timestamp: Time.now)
49
+ @id = id
50
+ @timestamp = timestamp
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # StatementRef Class used when referencing another statement from a statement's object property
4
+ class StatementRef
5
+
6
+ attr_accessor :object_type, :id
7
+
8
+ def initialize(options={}, &block)
9
+ @object_type = 'StatementRef'
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.id = attributes['id'] if attributes['id']
14
+ else
15
+ self.id = options.fetch(:id, nil)
16
+
17
+ if block_given?
18
+ block[self]
19
+ end
20
+ end
21
+ end
22
+
23
+ def serialize(version)
24
+ node = {}
25
+ node['id'] = id if id
26
+ node['objectType'] = object_type
27
+ node
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module Statements
4
+ class StatementsBase
5
+
6
+ attr_accessor :actor, :verb, :object, :result, :context, :timestamp, :attachments, :voided
7
+
8
+ def initialize(options={}, &block)
9
+ @attachments = []
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.actor = attributes['actor']['member'] ? Xapi::Group.new(json: attributes['actor'].to_json) : Xapi::Agent.new(json: attributes['actor'].to_json) if attributes['actor']
14
+ self.verb = Xapi::Verb.new(json: attributes['verb'].to_json) if attributes['verb']
15
+ object_node = attributes['object']
16
+ if object_node
17
+ case object_node['objectType']
18
+ when 'Group', 'Agent'
19
+ self.object = Xapi::Agent.new(json: object_node.to_json)
20
+ when 'StatementRef'
21
+ self.object = Xapi::StatementRef.new(json: object_node.to_json)
22
+ when 'SubStatement'
23
+ self.object = Xapi::SubStatement.new(json: object_node.to_json)
24
+ else
25
+ self.object = Xapi::Activity.new(json: object_node.to_json)
26
+ end
27
+ end
28
+ self.result = Xapi::Result.new(json: attributes['result'].to_json) if attributes['result']
29
+ self.context = Xapi::Context.new(json: attributes['context'].to_json) if attributes['context']
30
+ self.timestamp = Time.parse(attributes['timestamp']) if attributes['timestamp']
31
+ self.voided = attributes['voided'] if attributes['voided']
32
+ if attributes['attachments']
33
+ attributes['attachments'].each do |attachment|
34
+ attachments << Xapi::Attachment.new(json: attachment.to_json)
35
+ end
36
+ end
37
+ else
38
+ self.actor = options.fetch(:actor, nil)
39
+ self.verb = options.fetch(:verb, nil)
40
+ self.object = options.fetch(:object, nil)
41
+ self.result = options.fetch(:result, nil)
42
+ self.context = options.fetch(:context, nil)
43
+ self.timestamp = options.fetch(:timestamp, nil)
44
+ self.attachments = options.fetch(:attachments, nil)
45
+ self.voided = options.fetch(:voided, nil)
46
+
47
+ if block_given?
48
+ block[self]
49
+ end
50
+ end
51
+ end
52
+
53
+ def serialize(version)
54
+ node = {}
55
+ node['actor'] = actor.serialize(version)
56
+ node['verb'] = verb.serialize(version)
57
+ node['object'] = object.serialize(version)
58
+ node['result'] = result.serialize(version) if result
59
+ node['context'] = context.serialize(version) if context
60
+ node['timestamp'] = timestamp.strftime('%FT%T%:z') if timestamp
61
+ if version.ordinal >= Xapi::TCAPIVersion::V100.ordinal
62
+ if attachments && attachments.any?
63
+ node['attachments'] = attachments.map {|element| element.serialize(version)}
64
+ end
65
+ end
66
+ node
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ class StatementsQuery
4
+
5
+ attr_accessor :version, :verb_id
6
+ attr_accessor :agent, :activity_id, :registration, :related_activities, :related_agents
7
+ attr_accessor :stored_since, :stored_until, :limit, :format, :ascending
8
+
9
+ def initialize(&block)
10
+ self.version = TCAPIVersion::V101
11
+ if block_given?
12
+ block[self]
13
+ end
14
+ end
15
+
16
+ def verb_id=(value)
17
+ if value.is_a?(Verb)
18
+ @verb_id = value.id
19
+ else
20
+ @verb_id = value
21
+ end
22
+ end
23
+
24
+ def parameter_map
25
+ params = {}
26
+ params['agent'] = agent.object_type.eql?("Group") ? {"account": {"homePage": agent.account.homePage, "name": agent.account.name}}.to_json : {"mbox":agent.mbox}.to_json if agent
27
+ params['verb'] = verb_id.to_s if verb_id
28
+ params['activity'] = activity_id.to_s if activity_id
29
+ params['registration'] = registration if registration
30
+ params['related_activities'] = related_activities if related_activities
31
+ params['related_agents'] = related_agents if related_agents
32
+ params['since'] = stored_since.strftime('%FT%T%:z') if stored_since
33
+ params['until'] = stored_until.strftime('%FT%T%:z') if stored_until
34
+ params['limit'] = limit if limit
35
+ params['format'] = format if format
36
+ params['ascending'] = ascending if ascending
37
+
38
+ params
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ class StatementsQueryV095
4
+
5
+ attr_reader :version, :verb_id
6
+ attr_accessor :object, :registration, :context, :actor, :stored_since, :stored_until, :limit
7
+ attr_accessor :authoritative, :sparse, :instructor, :ascending
8
+
9
+ def initialize(&block)
10
+ self.version = TCAPIVersion::V095
11
+ if block_given?
12
+ block[self]
13
+ end
14
+ end
15
+
16
+ def verb_id=(value)
17
+ if value.is_a?(Verb)
18
+ @verb_id = value.id
19
+ else
20
+ @verb_id = Addressable::URI.parse(value)
21
+ end
22
+ end
23
+
24
+ def parameter_map
25
+ params = {}
26
+ params['verb'] = verb_id.to_s if verb_id
27
+ params['object'] = object.serialize(version) if object
28
+ params['registration'] = registration if registration
29
+ params['context'] = context if context
30
+ params['actor'] = actor if actor
31
+ params['since'] = stored_since.strftime('%FT%T%:z') if stored_since
32
+ params['until'] = stored_until.strftime('%FT%T%:z') if stored_until
33
+ params['limit'] = limit if limit
34
+ params['authoritative'] = authoritative if authoritative
35
+ params['sparse'] = sparse if sparse
36
+ params['instructor'] = instructor.serialize(version) if instructor
37
+ params['ascending'] = ascending if ascending
38
+
39
+ params
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # Statements result model class, returned by LRS calls to get multiple statements
4
+ class StatementsResult
5
+
6
+ attr_accessor :statements, :more_url
7
+
8
+ def initialize(options={})
9
+ json = options.fetch(:json, nil)
10
+ self.statements = []
11
+ if json
12
+ self.statements = json['statements'].map {|statement| Statement.new(json: statement.to_json)} if json['statements']
13
+ self.more_url = json['more'] if json['more']
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ class SubStatement < Statements::StatementsBase
4
+
5
+ attr_accessor :object_type
6
+
7
+ def initialize(options={}, &block)
8
+ @object_type = 'SubStatement'
9
+ super(options, &block)
10
+ end
11
+
12
+ def serialize(version)
13
+ node = super(version)
14
+ node['objectType'] = object_type
15
+ node
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module TCAPIVersion
4
+
5
+ V101 = {
6
+ to_s: '1.0.1',
7
+ get_value: proc{'1.0.1'}
8
+ }
9
+
10
+ V100 = {
11
+ to_s: '1.0.0',
12
+ get_value: proc{'1.0.0'}
13
+ }
14
+
15
+ V095 = {
16
+ to_s: '0.95',
17
+ get_value: proc{'0.95'}
18
+ }
19
+
20
+ def latest_version
21
+ V101
22
+ end
23
+
24
+ extend Xapi::Enum
25
+
26
+ end
27
+ end
data/lib/xapi/team.rb ADDED
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ require 'xapi/tcapi_version'
3
+ module Xapi
4
+ # Team model class
5
+ class Team
6
+
7
+ attr_accessor :name, :mbox, :mbox_sha1_sum, :open_id, :account, :object_type
8
+
9
+ def initialize(options={}, &block)
10
+ @object_type = 'Group'
11
+ json = options.fetch(:json, nil)
12
+ if json
13
+ attributes = JSON.parse(json)
14
+ self.name = attributes['name'] if attributes['name']
15
+ self.mbox = attributes['mbox'] if attributes['mbox']
16
+ self.mbox_sha1_sum = attributes['mbox_sha1sum'] if attributes['mbox_sha1sum']
17
+ self.open_id = attributes['openid'] if attributes['openid']
18
+ self.account = AgentAccount.new(json: attributes['account'].to_json) if attributes['account']
19
+ else
20
+ self.name = options.fetch(:name, nil)
21
+ self.mbox = options.fetch(:mbox, nil)
22
+ self.mbox_sha1_sum = options.fetch(:mbox_sha1_sum, nil)
23
+ self.open_id = options.fetch(:open_id, nil)
24
+ self.account = options.fetch(:account, nil)
25
+
26
+ if block_given?
27
+ block[self]
28
+ end
29
+ end
30
+ end
31
+
32
+ def serialize(version)
33
+ node = {}
34
+ node['objectType'] = object_type
35
+ node['name'] = name if name
36
+ node['mbox'] = mbox if mbox
37
+ node['mbox_sha1sum'] = mbox_sha1_sum if mbox_sha1_sum
38
+ node['openid'] = open_id if open_id
39
+ node['account'] = account.serialize(version) if account
40
+ node
41
+ end
42
+
43
+ end
44
+ end