growthtribe_xapi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
data/lib/xapi/agent.rb ADDED
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ require 'xapi/tcapi_version'
3
+ module Xapi
4
+ # Agent model class
5
+ class Agent
6
+
7
+ attr_accessor :name, :mbox, :mbox_sha1_sum, :open_id, :account, :object_type
8
+
9
+ def initialize(options={}, &block)
10
+ @object_type = 'Agent'
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
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ require 'json'
3
+ module Xapi
4
+ # Agent Account model class
5
+ class AgentAccount
6
+
7
+ attr_accessor :homePage, :name
8
+
9
+ def initialize(options={}, &block)
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.name = attributes['name'] if attributes['name']
14
+ self.homePage = attributes['homePage'] if attributes['homePage']
15
+ else
16
+ self.homePage = options.fetch(:home_page, nil)
17
+ self.name =options.fetch(:name, nil)
18
+
19
+ if block_given?
20
+ block[self]
21
+ end
22
+ end
23
+ end
24
+
25
+ def serialize(version)
26
+ node = {}
27
+ node['name'] = name if name
28
+ node['homePage'] = homePage if homePage
29
+ node
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # Attachment Class
4
+ class Attachment
5
+
6
+ attr_accessor :display, :description, :content_type, :length, :sha2
7
+ attr_reader :usage_type, :file_url
8
+
9
+ def initialize(options={}, &block)
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.usage_type = attributes['usageType'] if attributes['usageType']
14
+ self.display = attributes['display'] if attributes['display']
15
+ self.description = attributes['description'] if attributes['description']
16
+ self.content_type = attributes['contentType'] if attributes['contentType']
17
+ self.length = attributes['length'] if attributes['length']
18
+ self.sha2 = attributes['sha2'] if attributes['sha2']
19
+ self.file_url = attributes['fileUrl'] if attributes['fileUrl']
20
+ else
21
+ self.usage_type = options.fetch(:usage_type, nil)
22
+ self.display = options.fetch(:display, nil)
23
+ self.description = options.fetch(:description, nil)
24
+ self.content_type = options.fetch(:content_type, nil)
25
+ self.length = options.fetch(:length, nil)
26
+ self.sha2 = options.fetch(:sha2, nil)
27
+ self.file_url = options.fetch(:file_url, nil)
28
+
29
+ if block_given?
30
+ block[self]
31
+ end
32
+ end
33
+ end
34
+
35
+ def usage_type=(value)
36
+ if value.is_a?(String)
37
+ @usage_type = Addressable::URI.parse(value)
38
+ else
39
+ @usage_type = value
40
+ end
41
+ end
42
+
43
+ def file_url=(value)
44
+ if value.is_a?(String)
45
+ @file_url = Addressable::URI.parse(value)
46
+ else
47
+ @file_url = value
48
+ end
49
+ end
50
+
51
+ def serialize(version)
52
+ node = {}
53
+ node['usageType'] = usage_type.to_s if usage_type
54
+ node['display'] = display if display
55
+ node['description'] = description if description
56
+ node['contentType'] = content_type if content_type
57
+ node['length'] = length if length
58
+ node['sha2'] = sha2 if sha2
59
+ node['fileUrl'] = file_url.to_s if file_url
60
+ node
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # Context Class Description
4
+ class Context
5
+
6
+ attr_accessor :registration, :instructor, :team, :context_activities, :revision
7
+ attr_accessor :platform, :language, :statement, :extensions
8
+
9
+ def initialize(options={}, &block)
10
+ json = options.fetch(:json, nil)
11
+ if json
12
+ attributes = JSON.parse(json)
13
+ self.registration = attributes['registration'] if attributes['registration']
14
+ self.instructor = Xapi::Agent.new(json: attributes['instructor'].to_json) if attributes['instructor']
15
+ self.team = Xapi::Team.new(json: attributes['team'].to_json) if attributes['team']
16
+ self.context_activities = Xapi::ContextActivities.new(json: attributes['contextActivities'].to_json) if attributes['contextActivities']
17
+ self.revision = attributes['revision'] if attributes['revision']
18
+ self.platform = attributes['platform'] if attributes['platform']
19
+ self.language = attributes['language'] if attributes['language']
20
+ self.statement = Xapi::StatementRef.new(json: attributes['statement'].to_json) if attributes['statement']
21
+ self.extensions = attributes['extensions'] if attributes['extensions']
22
+ else
23
+ self.registration = options.fetch(:registration, nil)
24
+ self.instructor = options.fetch(:instructor, nil)
25
+ self.team = options.fetch(:team, nil)
26
+ self.context_activities = options.fetch(:context_activities, nil)
27
+ self.revision = options.fetch(:revision, nil)
28
+ self.platform = options.fetch(:platform, nil)
29
+ self.language = options.fetch(:language, nil)
30
+ self.extensions = options.fetch(:extensions, nil)
31
+
32
+ if block_given?
33
+ block[self]
34
+ end
35
+ end
36
+ end
37
+
38
+ def serialize(version)
39
+ node = {}
40
+ node['registration'] = registration if registration
41
+ node['instructor'] = instructor.serialize(version) if instructor
42
+ node['team'] = team.serialize(version) if team
43
+ node['contextActivities'] = context_activities.serialize(version) if context_activities
44
+ node['revision'] = revision if revision
45
+ node['platform'] = platform if platform
46
+ node['language'] = language if language
47
+ node['statement'] = statement.serialize(version) if statement
48
+ node['extensions'] = extensions if extensions
49
+
50
+ node
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # ContextActivities Model class
4
+ class ContextActivities
5
+
6
+ attr_accessor :parent, :grouping, :other, :category
7
+
8
+ def initialize(options={}, &block)
9
+ json = options.fetch(:json, nil)
10
+ if json
11
+ attributes = JSON.parse(json)
12
+ if attributes['parent']
13
+ if attributes['parent'].is_a?(Array)
14
+ self.parent = attributes['parent'].map {|element| Activity.new(json: element.to_json)}
15
+ else
16
+ self.parent = [Activity.new(json: attributes['parent'].to_json)]
17
+ end
18
+ end
19
+
20
+ if attributes['grouping']
21
+ if attributes['grouping'].is_a?(Array)
22
+ self.grouping = attributes['grouping'].map {|element| Activity.new(json: element.to_json)}
23
+ else
24
+ self.grouping = [Activity.new(json: attributes['grouping'].to_json)]
25
+ end
26
+ end
27
+
28
+ if attributes['other']
29
+ if attributes['other'].is_a?(Array)
30
+ self.other = attributes['other'].map {|element| Activity.new(json: element.to_json)}
31
+ else
32
+ self.other = [Activity.new(json: attributes['other'].to_json)]
33
+ end
34
+ end
35
+
36
+ if attributes['category']
37
+ if attributes['category'].is_a?(Array)
38
+ self.category = attributes['category'].map {|element| Activity.new(json: element.to_json)}
39
+ else
40
+ self.category = [Activity.new(json: attributes['category'].to_json)]
41
+ end
42
+ end
43
+ else
44
+ self.parent = options.fetch(:parent, nil)
45
+ self.grouping = options.fetch(:grouping, nil)
46
+ self.other = options.fetch(:other, nil)
47
+ self.category = options.fetch(:category, nil)
48
+
49
+ if block_given?
50
+ block[self]
51
+ end
52
+ end
53
+ end
54
+
55
+ def serialize(version)
56
+ node = {}
57
+ if parent && parent.any?
58
+ if version == Xapi::TCAPIVersion::V095 && parent.size > 1
59
+ raise Xapi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (parent)"
60
+ end
61
+ if version == Xapi::TCAPIVersion::V095
62
+ node['parent'] = parent.first.serialize(version)
63
+ else
64
+ node['parent'] = parent.map {|element| element.serialize(version)}
65
+ end
66
+ end
67
+
68
+ if grouping && grouping.any?
69
+ if version == Xapi::TCAPIVersion::V095 && grouping.size > 1
70
+ raise Xapi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (grouping)"
71
+ end
72
+ if version == Xapi::TCAPIVersion::V095
73
+ node['grouping'] = grouping.first.serialize(version)
74
+ else
75
+ node['grouping'] = grouping.map {|element| element.serialize(version)}
76
+ end
77
+ end
78
+
79
+ if other && other.any?
80
+ if version == Xapi::TCAPIVersion::V095 && other.size > 1
81
+ raise Xapi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (other)"
82
+ end
83
+ if version == Xapi::TCAPIVersion::V095
84
+ node['other'] = other.first.serialize(version)
85
+ else
86
+ node['other'] = other.map {|element| element.serialize(version)}
87
+ end
88
+ end
89
+
90
+ if category && category.any?
91
+ if version.ordinal >= Xapi::TCAPIVersion::V100.ordinal
92
+ node['category'] = category.map {|element| element.serialize(version)}
93
+ else
94
+ raise Xapi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support the category context activity"
95
+ end
96
+ end
97
+
98
+ node
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module Documents
4
+ class ActivityProfileDocument < Document
5
+
6
+ attr_accessor :activity
7
+
8
+ def initialize(&block)
9
+ super(&block)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module Documents
4
+ class AgentProfileDocument < Document
5
+
6
+ attr_accessor :agent
7
+
8
+ def initialize(&block)
9
+ super(&block)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module Documents
4
+ class Document
5
+
6
+ attr_accessor :id, :etag, :timestamp, :content_type, :content
7
+
8
+ def initialize(&block)
9
+ if block_given?
10
+ block[self]
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+
18
+ require_relative 'activity_profile_document'
19
+ require_relative 'agent_profile_document'
20
+ require_relative 'state_document'
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module Documents
4
+ class StateDocument < Document
5
+
6
+ attr_accessor :activity, :agent, :registration
7
+
8
+ def initialize(&block)
9
+ super(&block)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+
data/lib/xapi/enum.rb ADDED
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module Enum
4
+ CONVERT_PROC = Proc.new do
5
+ @values = constants.sort.collect{|c| const_get(c)}.freeze
6
+
7
+ @values.each_with_index do |value, idx|
8
+ the_symbol = constants.find{|c| const_get(c) == value}
9
+ sig = class << value ; self end
10
+ sig.send :define_method, :name, proc{the_symbol}
11
+ sig.send :define_method, :ordinal, proc{idx}
12
+
13
+ if value.is_a? Hash
14
+ value.each do |k, v|
15
+ sig.send :define_method, k, (v.is_a?(Proc) ? v : proc{v})
16
+ end
17
+ end
18
+ value.freeze
19
+ end
20
+
21
+ class << self
22
+ alias :value_of :const_get
23
+ end
24
+
25
+ module_function
26
+ def each
27
+ @values.each { |v| yield v }
28
+ end
29
+ def values
30
+ @values
31
+ end
32
+ extend Enumerable
33
+
34
+ freeze
35
+ end
36
+
37
+ def self.extended extending_obj
38
+ extending_obj.module_eval &CONVERT_PROC
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ module Errors
4
+
5
+ # Raised when an incompatible version is used
6
+ IncompatibleTCAPIVersion = Class.new(StandardError)
7
+
8
+ end
9
+ end
data/lib/xapi/group.rb ADDED
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ module Xapi
3
+ # Group model class
4
+ class Group < Agent
5
+
6
+ attr_accessor :members
7
+
8
+ def initialize(options={}, &block)
9
+ super(options, &block)
10
+
11
+ @object_type = 'Group'
12
+ @members = []
13
+ json = options.fetch(:json, nil)
14
+ if json
15
+ attributes = JSON.parse(json)
16
+ attributes['member'].each do |member|
17
+ members << Agent.new(json: member.to_json)
18
+ end
19
+ else
20
+ self.members = options.fetch(:members, nil)
21
+
22
+ if block_given?
23
+ block[self]
24
+ end
25
+ end
26
+ end
27
+
28
+ def serialize(version)
29
+ node = super(version)
30
+ if members.any?
31
+ node['member'] = members.map {|member| member.serialize(version)}
32
+ end
33
+ node
34
+ end
35
+
36
+ end
37
+ end