smarteru 0.0.1 → 0.0.4

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
- SHA1:
3
- metadata.gz: 811c7b26440c9f22c4b5d41f6ec6a460e361d75d
4
- data.tar.gz: 548cbb83653d4cee166a5ca60050b12fc4a065c6
2
+ SHA256:
3
+ metadata.gz: 5b9a09b604285fcf6277b75b5844190f09994387214d03d2969e8db7dbe701ec
4
+ data.tar.gz: f1a43226645c1bd28eece5216bf7a45a43747016f9ca43c7a56081bd87f95f93
5
5
  SHA512:
6
- metadata.gz: a5f2c67db38f87430695c4df2181f4661ddf56ee62dcb35263e44b466465377606058ce4974559730de273c3209b10cf349ed2e90208f971201aadbfa8fe29c1
7
- data.tar.gz: 6581fb66f399816bf60e23a88696b3737c2d37122658c0ce18c04d9a47700365ea9e789a666f46d673766ffbe8980cef6e5d03de62eb22210bea9781d1beb42d
6
+ metadata.gz: a49703f950673e5c851aaddd7f4beb5a3aca23aa8597c4b78e7dcd3a9334be10b4166d0e2d4233263ccaabfd286e9df26a04d098c6865f76564d5dcbb7efbabf
7
+ data.tar.gz: 0406a8dcec0eaf5ddb0897483ed2e102b3ccb58286e490aeca046847473fda293d281995b79646c213d8d549d1f48f8c040d0f4bca4d07e4abe432a2d63a7782
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'rubygems'
4
3
  require 'bundler'
4
+
5
5
  begin
6
6
  Bundler.setup(:default, :development)
7
7
  rescue Bundler::BundlerError => e
@@ -9,7 +9,6 @@ rescue Bundler::BundlerError => e
9
9
  $stderr.puts "Run `bundle install` to install missing gems"
10
10
  exit e.status_code
11
11
  end
12
- require 'rake'
13
12
 
14
13
  require 'rake/testtask'
15
14
  Rake::TestTask.new(:test) do |test|
@@ -1,9 +1,11 @@
1
1
  require 'rest-client'
2
- require 'libxml'
3
- require 'xmlhasher'
2
+ require 'nori'
4
3
 
4
+ require 'smarteru/error'
5
5
  require 'smarteru/client'
6
6
  require 'smarteru/response'
7
+ require 'smarteru/resources/base'
8
+ require 'smarteru/resources/users'
7
9
 
8
10
  module Smarteru
9
11
  API_HOST = 'api.smarteru.com'
@@ -1,8 +1,7 @@
1
1
  module Smarteru
2
2
  class Client
3
- attr_reader :account_api_key, :user_api_key,
4
- :use_ssl, :verify_ssl, :ssl_ca_file,
5
- :api_url
3
+ attr_accessor :account_api_key, :user_api_key
4
+ attr_reader :use_ssl, :verify_ssl, :ssl_ca_file, :api_url, :fail_on_error
6
5
 
7
6
  # Create an instance of an API client
8
7
  #
@@ -10,13 +9,14 @@ module Smarteru
10
9
  # * +options+ - Access credentials and options hash, required keys are: account_api_key, user_api_key
11
10
  # ==== Example
12
11
  # client = Smarteru::Client.new({account_api_key: 'abc', user_api_key: 'abc'})
13
- def initialize options = {}
14
- @account_api_key = options[:account_api_key]
15
- @user_api_key = options[:user_api_key]
12
+ def initialize(options = {})
13
+ @account_api_key = options[:account_api_key] || ENV['SMARTERU_ACCOUNT_API_KEY']
14
+ @user_api_key = options[:user_api_key] || ENV['SMARTERU_USER_API_KEY']
16
15
  @use_ssl = options[:use_ssl] || true
17
16
  @verify_ssl = options[:verify_ssl]
18
17
  @ssl_ca_file = options[:ssl_ca_file]
19
- @api_url = "#{use_ssl ? 'https' : 'http'}://#{API_HOST}/#{API_VERSION}/"
18
+ @api_url = (@use_ssl ? 'https' : 'http') + "://#{API_HOST}/#{API_VERSION}/"
19
+ @fail_on_error = options[:fail_on_error] != false
20
20
  end
21
21
 
22
22
  # Make an API request
@@ -32,14 +32,24 @@ module Smarteru
32
32
  # })
33
33
  def request(operation, data)
34
34
  opts = {
35
- method: :post,
36
- url: api_url,
37
- payload: {'Package' => body(operation, data)},
35
+ method: :post,
36
+ url: api_url,
37
+ payload: { 'Package' => body(operation, data) },
38
38
  content_type: :xml,
39
- verify_ssl: verify_ssl,
40
- ssl_ca_file: ssl_ca_file
41
- }
42
- Response.new(RestClient::Request.execute(opts))
39
+ verify_ssl: verify_ssl,
40
+ ssl_ca_file: ssl_ca_file }
41
+
42
+ response = RestClient::Request.execute(opts)
43
+ response = Response.new(response)
44
+
45
+ if !response.success? && fail_on_error
46
+ fail Error.new(response)
47
+ end
48
+ response
49
+ end
50
+
51
+ def users
52
+ @users ||= Resources::Users.new(self)
43
53
  end
44
54
 
45
55
  private
@@ -67,20 +77,23 @@ module Smarteru
67
77
  # * +parameters+ - Parameters hash
68
78
  def body_parameters(parameters)
69
79
  parameters_xml = ''
70
- parameters.each_pair do |k,v|
80
+ parameters.each_pair do |k, v|
71
81
  key = parameter_key(k)
72
82
 
73
- case v
83
+ val = case v
74
84
  when Hash
75
- val = body_parameters(v)
85
+ body_parameters(v)
76
86
  when Array
77
- val = v.map {|i| body_parameters(i) }.join('')
87
+ v.map { |i| body_parameters(i) }.join('')
88
+ when nil
89
+ ''
78
90
  else
79
- val = "<![CDATA[#{v}]]>"
91
+ "<![CDATA[#{v}]]>"
80
92
  end
81
93
 
82
94
  parameters_xml << "<#{key}>#{val}</#{key}>"
83
95
  end
96
+
84
97
  parameters_xml
85
98
  end
86
99
 
@@ -0,0 +1,12 @@
1
+ module Smarteru
2
+ class Error < StandardError
3
+ attr_reader :response, :code
4
+
5
+ def initialize(response)
6
+ @response = response
7
+ @code = response.error[:error][:error_id]
8
+ super(response.error[:error][:error_message])
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Smarteru
2
+ module Resources
3
+ class Base
4
+ attr_reader :client
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,110 @@
1
+ module Smarteru
2
+ module Resources
3
+ class Users < Base
4
+ def get(id_or_email)
5
+ params = { user: normalize_id_param(id_or_email) }
6
+
7
+ response = client.request('getUser', params)
8
+ response.success? ? response.result[:user] : response
9
+ rescue Error => e
10
+ return nil if e.code == 'GU:03'
11
+ fail e
12
+ end
13
+
14
+ def create(info = {})
15
+ validate!(info, :email, :employee_i_d, :given_name, :surname, :group)
16
+
17
+ params = create_params(info)
18
+
19
+ client.request('createUser', params)
20
+ end
21
+
22
+ def update(id_or_email, info = {})
23
+ params = { user:
24
+ { identifier: normalize_id_param(id_or_email),
25
+ info: info,
26
+ profile: nil,
27
+ groups: nil } }
28
+
29
+ client.request('updateUser', params)
30
+ end
31
+
32
+ def update_employee_id(id_or_email, new_employee_id)
33
+ update(id_or_email, employee_i_d: new_employee_id)
34
+ end
35
+
36
+ def signin(id_or_email)
37
+ params = { security: normalize_id_param(id_or_email) }
38
+
39
+ client.request('requestExternalAuthorization', params)
40
+ end
41
+
42
+ def enroll(id_or_email, group, module_id)
43
+ params = {
44
+ learning_module_enrollment: {
45
+ enrollment: {
46
+ user: normalize_id_param(id_or_email),
47
+ group_name: group,
48
+ learning_module_i_d: module_id } } }
49
+
50
+ client.request('enrollLearningModules', params)
51
+ end
52
+
53
+ def learner_report(id_or_email, group)
54
+ params = {
55
+ report: {
56
+ filters: {
57
+ groups: {
58
+ group_names: {
59
+ group_name: group } },
60
+ learning_modules: nil,
61
+ users: {
62
+ user_identifier: normalize_id_param(id_or_email, :email_address) } },
63
+ columns: [
64
+ { column_name: 'ENROLLED_DATE' },
65
+ { column_name: 'COMPLETED_DATE' },
66
+ { column_name: 'DUE_DATE' },
67
+ { column_name: 'LAST_ACCESSED_DATE' },
68
+ { column_name: 'STARTED_DATE' } ],
69
+ custom_fields: nil } }
70
+
71
+ response = client.request('getLearnerReport', params)
72
+ [ response.result[:learner_report][:learner] ].flatten.compact
73
+ end
74
+
75
+ def enrolled?(id_or_email, group, course_name)
76
+ enrollments = learner_report(id_or_email, group)
77
+ enrollments.any? { |e| e[:course_name] == course_name }
78
+ end
79
+
80
+ private
81
+
82
+ DEFAULT_CREATE_INFO = {
83
+ learner_notifications: 1,
84
+ supervisor_notifications: 0,
85
+ send_email_to: 'Self' }
86
+
87
+ def create_params(info)
88
+ group = info.delete(:group)
89
+
90
+ { user: {
91
+ info: info.merge(DEFAULT_CREATE_INFO),
92
+ profile: { home_group: group },
93
+ groups: {
94
+ group: {
95
+ group_name: group,
96
+ group_permissions: nil } } } }
97
+ end
98
+
99
+ def normalize_id_param(value, email_field_name = :email)
100
+ value =~ /@/ ? { email_field_name => value } : { employee_i_d: value }
101
+ end
102
+
103
+ def validate!(params, *args)
104
+ args.each do |arg|
105
+ fail(":#{arg} required to create user") unless params.include?(arg)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -1,39 +1,39 @@
1
1
  module Smarteru
2
2
  class Response
3
- attr_reader :data, :hash, :parser
3
+ attr_reader :data, :hash, :opts
4
4
 
5
5
  # Initializes an API response
6
6
  #
7
7
  # ==== Attributes
8
8
  # * +resp+ - RestClient response from the API
9
- def initialize(res)
9
+ def initialize(res, opts = {})
10
10
  @data = res
11
- @parser = XmlHasher::Parser.new(
12
- snakecase: true,
13
- ignore_namespaces: true,
14
- string_keys: false
11
+ opts[:parser] ||= Nori.new(
12
+ parser: :rexml,
13
+ convert_tags_to: lambda { |tag| tag.snakecase.to_sym }
15
14
  )
15
+ @opts = opts
16
16
  end
17
17
 
18
18
  # Hash representation of response data
19
- def to_hash
20
- return @hash if @hash
21
- @hash = parser.parse(data.to_s.gsub(/\<!\[CDATA\[(.+)\]\]\>/) {$1})
19
+ def hash
20
+ @hash ||= opts[:parser].parse(data.to_s.gsub(/\<!\[CDATA\[([^\]]+)\]\]\>/) {$1})
22
21
  end
23
22
 
24
23
  # Return true/false based on the API response status
25
24
  def success?
26
- to_hash[:smarter_u][:result] == 'Success'
25
+ hash[:smarter_u][:result] == 'Success'
27
26
  rescue
28
27
  false
29
28
  end
30
29
 
31
30
  def result
32
- to_hash[:smarter_u][:info]
31
+ hash[:smarter_u][:info]
33
32
  end
34
33
 
35
34
  def error
36
- to_hash[:smarter_u][:errors]
35
+ errors = hash[:smarter_u][:errors]
36
+ errors.is_a?(Hash) ? errors : nil
37
37
  end
38
38
  end
39
39
  end
@@ -1,3 +1,3 @@
1
1
  module Smarteru
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -1,45 +1,133 @@
1
- require 'helper'
1
+ require 'test_helper'
2
2
 
3
3
  class TestSmarteru < Test::Unit::TestCase
4
-
5
4
  def setup
6
- @client = Smarteru::Client.new(ACCESS_CREDENTIALS)
7
- end
8
-
9
- def test_request_get_group
10
- stub_request = stub_v2_api_call('getGroup', request_payload('getGroup.xml'))
11
- response = @client.request('getGroup', {group: {name: 'MyGroup'}})
12
- assert_equal(response.data, expected_body('getGroup.xml'))
13
- assert_requested(stub_request)
14
- end
15
-
16
- def test_response_result_hash
17
- stub_request = stub_v2_api_call('getGroup', request_payload('getGroup.xml'))
18
- response = @client.request('getGroup', {group: {name: 'MyGroup'}})
19
- assert_equal(response.result, {
20
- group: {
21
- name: "MyGroup",
22
- group_id: nil,
23
- created_date: "2015-01-22 23:42:55.553",
24
- modified_date: "2015-01-23 01:25:02.013",
25
- description: {
26
- p: "Group Description ..."
27
- },
28
- home_group_message: {
29
- p: "Welcome to The Group"
30
- },
31
- notification_emails: nil,
32
- user_count: "2",
33
- learning_module_count: "2",
34
- tags: nil,
35
- status: "Active"
36
- }
37
- })
38
- end
39
-
40
- def test_response_success_method
41
- stub_request = stub_v2_api_call('getGroup', request_payload('getGroup.xml'))
42
- response = @client.request('getGroup', {group: {name: 'MyGroup'}})
43
- assert_equal(true, response.success?)
5
+ @client = Smarteru::Client.new(
6
+ account_api_key: 'C3FE6BE08120A82DB9C4555A5C0E46AF',
7
+ user_api_key: '*623jec3nad4!aic5rlg*$mrg8n4$itd^vy62xut')
8
+ # replace values w/ actual keys to run/test vcr cassettes
9
+ # @client = Smarteru::Client.new(
10
+ # account_api_key: 'foo',
11
+ # user_api_key: 'bar')
12
+ end
13
+
14
+ GROUP_PARAMS = { group: { name: 'PowurU' } }
15
+ def test_invalid_api_keys
16
+ @client.account_api_key = 'foo'
17
+ @client.user_api_key = 'bar'
18
+
19
+ VCR.use_cassette('invalid_api_keys') do
20
+ assert_raise_kind_of(Smarteru::Error) do
21
+ @client.request('getGroup', GROUP_PARAMS)
22
+ end
23
+ end
24
+ end
25
+
26
+ def test_get_group
27
+ with_request('get_group', 'getGroup', GROUP_PARAMS) do |response|
28
+ assert_true response.success?
29
+ assert_not_nil response.result[:group]
30
+ end
31
+ end
32
+
33
+ def test_get_user
34
+ email = 'vduplessie@gmail.com'
35
+
36
+ VCR.use_cassette('get_user') do
37
+ response = @client.users.get(email)
38
+ assert_not_nil response[:email] == email
39
+ assert_not_nil response[:status] == 'Active'
40
+ end
41
+ end
42
+
43
+ def test_get_nonexistant_user
44
+ VCR.use_cassette('get_nonexistant_user') do
45
+ response = @client.users.get('noop@eyecuelab.com')
46
+ assert_nil response
47
+ end
48
+ end
49
+
50
+ def test_update_user
51
+ VCR.use_cassette('update_user') do
52
+ employee_id = 'powur.com:4242'
53
+ response = @client.users.update('vduplessie@gmail.com', employee_i_d: employee_id)
54
+ assert_true response.success?
55
+ assert_true response.result.keys.include?(:employee_id)
56
+ assert_equal response.result[:employee_id], employee_id
57
+ end
58
+ end
59
+
60
+ def test_update_employee_id
61
+ VCR.use_cassette('update_employee_id') do
62
+ employee_id = 'powur.com:4242'
63
+ response = @client.users.update_employee_id('vduplessie@gmail.com', employee_id)
64
+ assert_true response.success?
65
+ assert_true response.result.keys.include?(:employee_id)
66
+ assert_equal response.result[:employee_id], employee_id
67
+ end
68
+ end
69
+
70
+ def test_create_user
71
+ employee_id = 'test.eyecuelab.com:42'
72
+ params = {
73
+ email: 'foo@eyecuelab.com',
74
+ employee_i_d: employee_id,
75
+ given_name: 'Test',
76
+ surname: 'User',
77
+ password: 'password',
78
+ group: 'PowurU' }
79
+
80
+ VCR.use_cassette('create_user') do
81
+ response = @client.users.create(params)
82
+ assert_true response.success?
83
+ assert_true response.result.keys.include?(:employee_id)
84
+ assert_equal response.result[:employee_id], employee_id
85
+ end
86
+ end
87
+
88
+ def test_signin_user
89
+ VCR.use_cassette('signin_user') do
90
+ response = @client.users.signin('5258029611')
91
+ assert_true response.success?
92
+ assert_true response.result.keys.include?(:redirect_path)
93
+ end
94
+ end
95
+
96
+ def test_enroll_user
97
+ VCR.use_cassette('enroll_user') do
98
+ response = @client.users.enroll('5258029611', 'PowurU', '8319')
99
+ assert_true response.success?
100
+ assert_true response.result.keys.include?(:enrollments)
101
+ end
102
+ end
103
+
104
+ def test_learner_report
105
+ VCR.use_cassette('learner_report') do
106
+ response = @client.users.learner_report('5258029611', 'PowurU')
107
+ assert_kind_of Array, response
108
+ end
109
+ end
110
+
111
+ def test_enrolled_true
112
+ VCR.use_cassette('enrolled_true') do
113
+ response = @client.users.enrolled?('foo@eyecuelab.com', 'PowurU', 'Fast Impact Training (FIT)')
114
+ assert_true response
115
+ end
116
+ end
117
+
118
+ def test_enrolled_false
119
+ VCR.use_cassette('enrolled_false') do
120
+ response = @client.users.enrolled?('foo@eyecuelab.com', 'PowurU', 'Cert Pro')
121
+ assert_false response
122
+ end
123
+ end
124
+
125
+ private
126
+
127
+ def with_request(cassette, method, params)
128
+ VCR.use_cassette(cassette) do
129
+ response = @client.request(method, params)
130
+ yield(response) if block_given?
131
+ end
44
132
  end
45
133
  end