user_management_api 0.0.16

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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +3 -0
  5. data/README.md +90 -0
  6. data/Rakefile +114 -0
  7. data/lib/user_management_api.rb +38 -0
  8. data/lib/user_management_api/answerbase_session_token.rb +6 -0
  9. data/lib/user_management_api/client.rb +108 -0
  10. data/lib/user_management_api/client_methods/answerbase_session_tokens.rb +15 -0
  11. data/lib/user_management_api/client_methods/registration_groups.rb +38 -0
  12. data/lib/user_management_api/client_methods/registrations.rb +54 -0
  13. data/lib/user_management_api/client_methods/urls.rb +65 -0
  14. data/lib/user_management_api/client_methods/users.rb +24 -0
  15. data/lib/user_management_api/config.rb +13 -0
  16. data/lib/user_management_api/connection_manager.rb +17 -0
  17. data/lib/user_management_api/entity.rb +132 -0
  18. data/lib/user_management_api/errors.rb +49 -0
  19. data/lib/user_management_api/lookup.rb +6 -0
  20. data/lib/user_management_api/paged_collection.rb +16 -0
  21. data/lib/user_management_api/railtie.rb +8 -0
  22. data/lib/user_management_api/registration.rb +20 -0
  23. data/lib/user_management_api/registration_group.rb +8 -0
  24. data/lib/user_management_api/user.rb +6 -0
  25. data/lib/user_management_api/version.rb +3 -0
  26. data/spec/integration/registration_groups_spec.rb +30 -0
  27. data/spec/integration/registrations_spec.rb +44 -0
  28. data/spec/integration/users_spec.rb +63 -0
  29. data/spec/spec_helper.rb +26 -0
  30. data/spec/support/client_context.rb +12 -0
  31. data/spec/support/integration_context.rb +29 -0
  32. data/spec/unit/client_methods/answerbase_session_tokens_spec.rb +68 -0
  33. data/spec/unit/client_methods/registration_groups_spec.rb +157 -0
  34. data/spec/unit/client_methods/registrations_spec.rb +131 -0
  35. data/spec/unit/client_methods/users_spec.rb +149 -0
  36. data/spec/unit/client_spec.rb +121 -0
  37. data/spec/unit/connection_manager_spec.rb +23 -0
  38. data/spec/unit/entity_spec.rb +93 -0
  39. data/spec/unit/registration_spec.rb +25 -0
  40. data/user_management_api.gemspec +32 -0
  41. metadata +264 -0
@@ -0,0 +1,149 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe UserManagementApi::ClientMethods::RegistrationGroups do
4
+
5
+ include_context 'client context'
6
+
7
+ describe '#user' do
8
+
9
+ it 'makes a GET request to the correct URL' do
10
+ stub = stub_request(:get, "#{base_uri}/users/#{unique_id}")
11
+ client.user(unique_id)
12
+
13
+ expect(stub).to have_been_requested.times(1)
14
+ end
15
+
16
+ it 'passes the auth header' do
17
+ stub = stub_request(:get, "#{base_uri}/users/#{unique_id}").with({headers: { 'Authorization' => "Token token=\"#{token}\""}})
18
+ client.user(unique_id)
19
+ expect(stub).to have_been_requested.times(1)
20
+ end
21
+
22
+ it 'returns nil when an invalid id is passed' do
23
+ stub = stub_request(:get, "#{base_uri}/users/#{unique_id}").to_return(:status => 404)
24
+
25
+ expect(client.user(unique_id)).to be_nil
26
+
27
+ expect(stub).to have_been_requested.times(1)
28
+ end
29
+
30
+ it 'raises an error when the remote server returns a 401' do
31
+ stub = stub_request(:get, "#{base_uri}/users/#{unique_id}").to_return(:status => 401)
32
+
33
+ expect { client.user(unique_id) }.to raise_error(UserManagementApi::TokenError)
34
+
35
+ expect(stub).to have_been_requested.times(1)
36
+ end
37
+
38
+ it 'raises an error when the remote server encounters an error' do
39
+ stub = stub_request(:get, "#{base_uri}/users/#{unique_id}").to_return(:status => 500)
40
+
41
+ expect { client.user(unique_id) }.to raise_error(UserManagementApi::ServerError)
42
+
43
+ expect(stub).to have_been_requested.times(1)
44
+ end
45
+
46
+ it 'returns a User object' do
47
+ stub = stub_request(:get, "#{base_uri}/users/#{unique_id}").to_return(body: MultiJson.dump(user_json))
48
+
49
+ user = client.user(unique_id)
50
+
51
+ expect(user).not_to be_nil
52
+ expect(user).to be_a(UserManagementApi::User)
53
+ expect(user.first_name).to eq 'Roland'
54
+
55
+ expect(stub).to have_been_requested.times(1)
56
+ end
57
+
58
+ end
59
+
60
+ describe '#users_by_email' do
61
+
62
+ let(:url) { "#{base_uri}/users/by_email" }
63
+
64
+ it 'makes a GET to the correct url' do
65
+ stub = stub_request(:get, url).with(query: {email: 'email@email.com'})
66
+ client.users_by_email('email@email.com')
67
+
68
+ expect(stub).to have_been_requested.times(1)
69
+ end
70
+
71
+ it 'returns an array of users' do
72
+ stub = stub_request(:get, url).
73
+ with(query: {email: 'email@email.com'}).
74
+ to_return(body: MultiJson.dump([user_json, user_json]))
75
+
76
+ users = client.users_by_email('email@email.com')
77
+
78
+ expect(users).to be_a Array
79
+ expect(users.length).to eq 2
80
+ expect(users.first).to be_a UserManagementApi::User
81
+
82
+ expect(stub).to have_been_requested.times(1)
83
+ end
84
+
85
+ it 'accepts arrays of emails' do
86
+ stub = stub_request(:get, url).with(query: {email: ['1@mail.com', '2@mail.com']})
87
+ client.users_by_email(['1@mail.com', '2@mail.com'])
88
+
89
+ expect(stub).to have_been_requested.times(1)
90
+ end
91
+ end
92
+
93
+ describe '#create_user' do
94
+ it 'makes a POST to the correct url' do
95
+ stub = stub_request(:post, "#{base_uri}/users")
96
+ client.create_user(UserManagementApi::User.new)
97
+
98
+ expect(stub).to have_been_requested.times(1)
99
+ end
100
+
101
+ it 'raises a UnprocessableEntityError on a 422' do
102
+ stub = stub_request(:post, "#{base_uri}/users").to_return(status: 422, body: MultiJson.dump({first_name: ['Cannot be blank']}))
103
+
104
+ expect { client.create_user(UserManagementApi::User.new) }.to raise_error(UserManagementApi::UnprocessableEntityError)
105
+
106
+ expect(stub).to have_been_requested.times(1)
107
+ end
108
+
109
+ it 'returns a User object' do
110
+ stub = stub_request(:post, "#{base_uri}/users").to_return(body: MultiJson.dump(user_json))
111
+
112
+ user = client.create_user(UserManagementApi::User.new)
113
+
114
+ expect(user).not_to be_nil
115
+ expect(user).to be_a(UserManagementApi::User)
116
+
117
+ expect(stub).to have_been_requested.times(1)
118
+ end
119
+ end
120
+
121
+ describe '#update_user' do
122
+ it 'makes a PUT to the correct url' do
123
+ stub = stub_request(:put, "#{base_uri}/users/#{unique_id}")
124
+ client.update_user(UserManagementApi::User.new(unique_id: unique_id))
125
+
126
+ expect(stub).to have_been_requested.times(1)
127
+ end
128
+
129
+ it 'raises a UnprocessableEntityError on a 422' do
130
+ stub = stub_request(:put, "#{base_uri}/users/#{unique_id}").to_return(status: 422, body: MultiJson.dump({first_name: ['Cannot be blank']}))
131
+
132
+ expect { client.update_user(UserManagementApi::User.new(unique_id: unique_id)) }.to raise_error(UserManagementApi::UnprocessableEntityError)
133
+
134
+ expect(stub).to have_been_requested.times(1)
135
+ end
136
+
137
+ it 'returns a User object' do
138
+ stub = stub_request(:put, "#{base_uri}/users/#{unique_id}").to_return(body: MultiJson.dump(user_json))
139
+
140
+ user = client.update_user(UserManagementApi::User.new(unique_id: unique_id))
141
+
142
+ expect(user).not_to be_nil
143
+ expect(user).to be_a(UserManagementApi::User)
144
+
145
+ expect(stub).to have_been_requested.times(1)
146
+ end
147
+ end
148
+
149
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe UserManagementApi::Client do
4
+
5
+ before(:each) do
6
+ UserManagementApi::Config.reset!
7
+ end
8
+
9
+ describe '#new' do
10
+ it 'rejects base_uri params with a path' do
11
+ expect { UserManagementApi::Client.new('http://example.com/path', 'token') }.to raise_error(UserManagementApi::ClientConfigurationError)
12
+ end
13
+
14
+ it 'creates a client with the given params' do
15
+ client = UserManagementApi::Client.new('http://example.com/', 'token')
16
+ expect(client).not_to be_nil
17
+ expect(client.token).to eq 'token'
18
+ expect(client.base_api_uri).to match /http:\/\/example.com\//
19
+ end
20
+
21
+ it 'appends the correct path to the given base_uri' do
22
+ client = UserManagementApi::Client.new('http://example.com/', 'token')
23
+ expect(client.base_api_uri).to eq 'http://example.com/api/v1'
24
+ end
25
+
26
+ it 'requires a uri and token' do
27
+ expect { UserManagementApi::Client.new(nil, 'token') }.to raise_error(UserManagementApi::ClientConfigurationError)
28
+ expect { UserManagementApi::Client.new('http://example.com', nil) }.to raise_error(UserManagementApi::ClientConfigurationError)
29
+ end
30
+
31
+ it 'uses configured values if available' do
32
+ UserManagementApi::Config.with_config(base_uri: 'http://configured.com', access_token: 'configured') do
33
+ client = UserManagementApi::Client.new
34
+ expect(client.token).to eq 'configured'
35
+ expect(client.base_api_uri).to match /http:\/\/configured.com\//
36
+ end
37
+ end
38
+
39
+ it 'allows configured values to be overridden' do
40
+ UserManagementApi::Config.with_config(base_uri: 'http://configured.com', access_token: 'configured') do
41
+ client = UserManagementApi::Client.new(nil, 'paramed')
42
+ expect(client.token).to eq 'paramed'
43
+ expect(client.base_api_uri).to match /http:\/\/configured.com\//
44
+ end
45
+ end
46
+ end
47
+
48
+ context 'valid client' do
49
+
50
+ include_context 'client context'
51
+
52
+ describe '#create_registration_url' do
53
+ it 'returns the right URL' do
54
+ expect(client.create_registration_url('ipumsi')).to eq "#{uri}/ipumsi/registration/new"
55
+ end
56
+
57
+ it 'appends the optional return_url' do
58
+ expect(client.create_registration_url('ipumsi', 'http://google.com')).to eq "#{uri}/ipumsi/registration/new?return_url=#{CGI.escape('http://google.com')}"
59
+ end
60
+
61
+ it 'appends any additional parameters' do
62
+ expect(client.create_registration_url('ipumsi', 'http://google.com', a: 1)).to eq "#{uri}/ipumsi/registration/new?return_url=#{CGI.escape('http://google.com')}&a=1"
63
+ end
64
+ end
65
+
66
+ describe '#create_account_url' do
67
+ it 'returns the right URL' do
68
+ expect(client.create_account_url('ipumsi')).to eq "#{uri}/ipumsi/user/new"
69
+ end
70
+
71
+ it 'appends the optional return_url' do
72
+ expect(client.create_account_url('ipumsi', 'http://google.com')).to eq "#{uri}/ipumsi/user/new?return_url=#{CGI.escape('http://google.com')}"
73
+ end
74
+
75
+ it 'appends any additional parameters' do
76
+ expect(client.create_account_url('ipumsi', 'http://google.com', a: 1)).to eq "#{uri}/ipumsi/user/new?return_url=#{CGI.escape('http://google.com')}&a=1"
77
+ end
78
+ end
79
+
80
+ describe '#edit_registration_url' do
81
+ it 'returns the right URL' do
82
+ expect(client.edit_registration_url('ipumsi')).to eq "#{uri}/ipumsi/registration/edit"
83
+ end
84
+
85
+ it 'appends the optional return_url' do
86
+ expect(client.edit_registration_url('ipumsi', 'http://google.com')).to eq "#{uri}/ipumsi/registration/edit?return_url=#{CGI.escape('http://google.com')}"
87
+ end
88
+ end
89
+
90
+ describe '#join_class_group_url' do
91
+ it 'returns the right URL' do
92
+ expect(client.join_class_group_url('ipumsi')).to eq "#{uri}/ipumsi/registration_groups/select"
93
+ expect(client.join_class_group_url).to eq "#{uri}/registration_groups/select"
94
+ end
95
+
96
+ it 'appends the optional return_url' do
97
+ expect(client.join_class_group_url('ipumsi', 'http://google.com')).to eq "#{uri}/ipumsi/registration_groups/select?return_url=#{CGI.escape('http://google.com')}"
98
+ end
99
+ end
100
+
101
+ describe '#admin_url' do
102
+ it 'returns the right URL' do
103
+ expect(client.admin_url).to eq "#{uri}/admin"
104
+ end
105
+ end
106
+
107
+ describe '#admin_pending_registration_url' do
108
+ it 'returns the right URL' do
109
+ expect(client.admin_pending_registration_url('ipumsi')).to eq "#{uri}/admin/registrations/pending/ipumsi"
110
+ end
111
+ end
112
+
113
+ describe '#admin_pending_registration_groups_url' do
114
+ it 'returns the right URL' do
115
+ expect(client.admin_pending_registration_groups_url('ipumsi')).to eq "#{uri}/admin/registration_groups/pending/ipumsi"
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe UserManagementApi::ConnectionManager do
4
+
5
+ it 'should not allow creating instances' do
6
+ expect { UserManagementApi::ConnectionManager.new }.to raise_error(NoMethodError)
7
+ end
8
+
9
+ describe '.get_connection' do
10
+
11
+ let(:connection) { UserManagementApi::ConnectionManager.get_connection('http://example.com', 'token') }
12
+
13
+ it 'should set the base_uri' do
14
+ expect(connection.url_prefix.to_s).to eq 'http://example.com/'
15
+ end
16
+
17
+ it 'should set the authorization token header' do
18
+ expect(connection.headers['Authorization']).to eq "Token token=\"token\""
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe UserManagementApi::Entity do
4
+
5
+ class TestEntity < UserManagementApi::Entity
6
+ attributes :name, :id
7
+ entity_attribute :field, UserManagementApi::Lookup
8
+ end
9
+
10
+ class ChildTestEntity < TestEntity
11
+ attribute :another_field
12
+ entity_attribute :how_did_you_hear, UserManagementApi::Lookup
13
+ end
14
+
15
+ class OtherTestEntity < UserManagementApi::Entity
16
+ entity_attribute :occupation, UserManagementApi::Lookup
17
+ end
18
+
19
+ before(:each) do
20
+ UserManagementApi::Config.reset!
21
+ end
22
+
23
+ describe '.entity_attribute' do
24
+
25
+ it 'should keep separate lists for each type' do
26
+ expect(TestEntity._entity_properties.keys).to contain_exactly :field
27
+ expect(ChildTestEntity._entity_properties.keys).to contain_exactly :field, :how_did_you_hear
28
+ expect(OtherTestEntity._entity_properties.keys).to contain_exactly :occupation
29
+
30
+ expect(TestEntity._properties).to contain_exactly :name, :id
31
+ expect(ChildTestEntity._properties).to contain_exactly :name, :id, :another_field
32
+ expect(OtherTestEntity._properties.length).to eq 0
33
+ end
34
+
35
+ end
36
+
37
+ describe 'serialization' do
38
+
39
+ it 'serializes entities' do
40
+ entity = TestEntity.new
41
+ entity.field = UserManagementApi::Lookup.new
42
+ entity.field.id = 5
43
+ entity.field.label = 'label'
44
+ entity.field.text = 'text'
45
+ entity.name = 'name'
46
+ entity.id = 1
47
+
48
+ json = entity.as_json
49
+ expect(json).to eq({ field: { id: 5, label: 'label', text: 'text'}, name: 'name', id: 1 })
50
+ end
51
+
52
+ it 'handles nil entity properties' do
53
+ entity = TestEntity.new
54
+ entity.field = nil
55
+ expect(entity.as_json[:field]).to be_nil
56
+ end
57
+
58
+ end
59
+
60
+ describe 'deserialization' do
61
+ it 'populates the objects' do
62
+ json = { field: { id: 5, label: 'label', text: 'text'}, name: 'name', id: 1 }
63
+ entity = TestEntity.new(json)
64
+ expect(entity.name).to eq 'name'
65
+ expect(entity.field).to be_a UserManagementApi::Lookup
66
+ expect(entity.field.label).to eq 'label'
67
+ end
68
+
69
+ it 'populates nil entities' do
70
+ json = { field: nil, name: 'name', id: 1 }
71
+ entity = TestEntity.new(json)
72
+ expect(entity.field).to be_nil
73
+ end
74
+ end
75
+
76
+ it 'treats equality correctly' do
77
+ a = TestEntity.new({ field: { id: 5, label: 'label', text: 'text'}, name: 'name', id: 1 })
78
+ b = TestEntity.new({ field: { id: 5, label: 'label', text: 'text'}, name: 'name', id: 1 })
79
+ c = TestEntity.new
80
+ d = ChildTestEntity.new({ field: { id: 5, label: 'label', text: 'text'}, name: 'name', id: 1 })
81
+
82
+ expect(a).to eq b
83
+ expect(a).not_to eq c
84
+ expect(a).not_to eq d
85
+
86
+ expect(a.equal? b).to be_falsey
87
+
88
+ b.field.id = 7
89
+ expect(a).not_to eq b
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe UserManagementApi::Registration do
4
+
5
+ describe 'Status methods' do
6
+
7
+ it 'returns true for the correct status' do
8
+ r = UserManagementApi::Registration.new
9
+
10
+ r.status = UserManagementApi::Registration::STATUS[:pending]
11
+ expect(r.is_pending?).to be_truthy
12
+ expect(r.is_denied?).to be_falsey
13
+
14
+ r.status = UserManagementApi::Registration::STATUS[:denied]
15
+ expect(r.is_pending?).to be_falsey
16
+ expect(r.is_denied?).to be_truthy
17
+
18
+ r.status = UserManagementApi::Registration::STATUS[:expired]
19
+ expect(r.is_email_pending?).to be_falsey
20
+ expect(r.is_expired?).to be_truthy
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'user_management_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "user_management_api"
8
+ spec.version = UserManagementApi::VERSION
9
+ spec.authors = ["Dan Elbert"]
10
+ spec.email = ["delbert@umn.edu"]
11
+ spec.homepage = 'https://github.umn.edu/mpc/user_management_api'
12
+ spec.summary = %q{Client library for the User Management App API}
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_runtime_dependency "multi_json", "~> 1.0"
20
+ spec.add_runtime_dependency "faraday", "~> 0.9.0"
21
+ spec.add_runtime_dependency "confiture", "~> 0.1.4"
22
+ spec.add_runtime_dependency "activesupport", ">= 3.2.0"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec", "~> 3.4.0"
27
+ spec.add_development_dependency "ci_reporter_rspec", "~> 1.0.0"
28
+ spec.add_development_dependency "simplecov", "~> 0.9.0"
29
+ spec.add_development_dependency "simplecov-rcov", "~> 0.2.3"
30
+ spec.add_development_dependency "webmock", "~> 1.22.5"
31
+ spec.add_development_dependency "oj", "~> 2.10.2"
32
+ end