smarteru 0.0.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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