allscripts_unity_client 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/.gitignore +20 -0
  2. data/.travis.yml +3 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +22 -0
  5. data/README.md +180 -0
  6. data/Rakefile +7 -0
  7. data/allscripts_unity_client.gemspec +39 -0
  8. data/lib/allscripts_unity_client.rb +43 -0
  9. data/lib/allscripts_unity_client/client.rb +594 -0
  10. data/lib/allscripts_unity_client/client_driver.rb +95 -0
  11. data/lib/allscripts_unity_client/json_client_driver.rb +110 -0
  12. data/lib/allscripts_unity_client/json_unity_request.rb +33 -0
  13. data/lib/allscripts_unity_client/json_unity_response.rb +27 -0
  14. data/lib/allscripts_unity_client/soap_client_driver.rb +128 -0
  15. data/lib/allscripts_unity_client/timezone.rb +99 -0
  16. data/lib/allscripts_unity_client/unity_request.rb +63 -0
  17. data/lib/allscripts_unity_client/unity_response.rb +110 -0
  18. data/lib/allscripts_unity_client/utilities.rb +66 -0
  19. data/lib/allscripts_unity_client/version.rb +3 -0
  20. data/spec/allscripts_unity_client_spec.rb +57 -0
  21. data/spec/client_driver_spec.rb +71 -0
  22. data/spec/client_spec.rb +406 -0
  23. data/spec/factories/allscripts_unity_client_parameters_factory.rb +13 -0
  24. data/spec/factories/client_driver_factory.rb +14 -0
  25. data/spec/factories/client_factory.rb +7 -0
  26. data/spec/factories/json_client_driver_factory.rb +3 -0
  27. data/spec/factories/json_unity_request_factory.rb +3 -0
  28. data/spec/factories/json_unity_response_factory.rb +3 -0
  29. data/spec/factories/magic_request_factory.rb +33 -0
  30. data/spec/factories/soap_client_driver_factory.rb +3 -0
  31. data/spec/factories/timezone_factory.rb +7 -0
  32. data/spec/factories/unity_request_factory.rb +10 -0
  33. data/spec/factories/unity_response_factory.rb +8 -0
  34. data/spec/fixtures/attributes_hash.yml +15 -0
  35. data/spec/fixtures/date_hash.yml +8 -0
  36. data/spec/fixtures/date_string_hash.yml +8 -0
  37. data/spec/fixtures/error.json +3 -0
  38. data/spec/fixtures/get_providers.json +69 -0
  39. data/spec/fixtures/get_providers.xml +119 -0
  40. data/spec/fixtures/get_providers_json.yml +65 -0
  41. data/spec/fixtures/get_providers_xml.yml +270 -0
  42. data/spec/fixtures/get_security_token.json +1 -0
  43. data/spec/fixtures/get_security_token.xml +7 -0
  44. data/spec/fixtures/get_server_info.json +10 -0
  45. data/spec/fixtures/get_server_info.xml +40 -0
  46. data/spec/fixtures/get_server_info_json.yml +8 -0
  47. data/spec/fixtures/get_server_info_xml.yml +55 -0
  48. data/spec/fixtures/no_attributes_hash.yml +7 -0
  49. data/spec/fixtures/retire_security_token.json +1 -0
  50. data/spec/fixtures/retire_security_token.xml +5 -0
  51. data/spec/fixtures/soap_fault.xml +13 -0
  52. data/spec/fixtures/string_keyed_hash.yml +8 -0
  53. data/spec/fixtures/symbol_keyed_hash.yml +8 -0
  54. data/spec/json_client_driver_spec.rb +209 -0
  55. data/spec/json_unity_request_spec.rb +37 -0
  56. data/spec/json_unity_response_spec.rb +44 -0
  57. data/spec/soap_client_driver_spec.rb +201 -0
  58. data/spec/spec_helper.rb +44 -0
  59. data/spec/support/fixture_loader.rb +22 -0
  60. data/spec/support/shared_examples_for_client_driver.rb +139 -0
  61. data/spec/support/shared_examples_for_unity_request.rb +94 -0
  62. data/spec/support/shared_examples_for_unity_response.rb +26 -0
  63. data/spec/timezone_spec.rb +161 -0
  64. data/spec/unity_request_spec.rb +37 -0
  65. data/spec/unity_response_spec.rb +36 -0
  66. data/spec/utilities_spec.rb +69 -0
  67. metadata +323 -0
@@ -0,0 +1 @@
1
+ "8BDB220C-189D-4627-80A8-AF9BF2192B87"
@@ -0,0 +1,7 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <s:Body>
3
+ <GetSecurityTokenResponse xmlns="http://www.allscripts.com/Unity">
4
+ <GetSecurityTokenResult>581EE97E-8C3E-49D8-B2DA-05A80AD48C46</GetSecurityTokenResult>
5
+ </GetSecurityTokenResponse>
6
+ </s:Body>
7
+ </s:Envelope>
@@ -0,0 +1,10 @@
1
+ [{
2
+ "getserverinfoinfo": [{
3
+ "ServerDateTimeOffset": "2013-10-29T10:30:45.0292000-04:00",
4
+ "ServerTime": "2013-10-29T10:30:45",
5
+ "uaibornondate": "10/07/2013",
6
+ "ProductVersion": "11.2.3.32.000",
7
+ "System": "Enterprise EHR",
8
+ "ServerTimeZone": "Eastern Standard Time"
9
+ }]
10
+ }]
@@ -0,0 +1,40 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <s:Body>
3
+ <MagicResponse xmlns="http://www.allscripts.com/Unity">
4
+ <MagicResult>
5
+ <xs:schema id="getserverinforesponse" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
6
+ <xs:element name="getserverinforesponse" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
7
+ <xs:complexType>
8
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
9
+ <xs:element name="getserverinfoinfo">
10
+ <xs:complexType>
11
+ <xs:sequence>
12
+ <xs:element name="ServerTimeZone" type="xs:string" minOccurs="0"/>
13
+ <xs:element name="ServerTime" type="xs:string" minOccurs="0"/>
14
+ <xs:element name="ServerDateTimeOffset" type="xs:string" minOccurs="0"/>
15
+ <xs:element name="System" type="xs:string" minOccurs="0"/>
16
+ <xs:element name="ProductVersion" type="xs:string" minOccurs="0"/>
17
+ <xs:element name="uaibornondate" type="xs:string" minOccurs="0"/>
18
+ </xs:sequence>
19
+ </xs:complexType>
20
+ </xs:element>
21
+ </xs:choice>
22
+ </xs:complexType>
23
+ </xs:element>
24
+ </xs:schema>
25
+ <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
26
+ <getserverinforesponse xmlns="">
27
+ <getserverinfoinfo diffgr:id="getserverinfoinfo1" msdata:rowOrder="0">
28
+ <ServerTimeZone>Eastern Standard Time</ServerTimeZone>
29
+ <ServerTime>2013-10-24T18:41:43</ServerTime>
30
+ <ServerDateTimeOffset>2013-10-24T18:41:43.6130000-04:00</ServerDateTimeOffset>
31
+ <System>Enterprise EHR</System>
32
+ <ProductVersion>11.2.3.32.000</ProductVersion>
33
+ <uaibornondate>10/07/2013</uaibornondate>
34
+ </getserverinfoinfo>
35
+ </getserverinforesponse>
36
+ </diffgr:diffgram>
37
+ </MagicResult>
38
+ </MagicResponse>
39
+ </s:Body>
40
+ </s:Envelope>
@@ -0,0 +1,8 @@
1
+ ---
2
+ - getserverinfoinfo:
3
+ - ServerDateTimeOffset: '2013-10-29T10:32:42.6932000-04:00'
4
+ ServerTime: '2013-10-29T10:32:42'
5
+ uaibornondate: 10/07/2013
6
+ ProductVersion: 11.2.3.32.000
7
+ System: Enterprise EHR
8
+ ServerTimeZone: Eastern Standard Time
@@ -0,0 +1,55 @@
1
+ ---
2
+ :magic_response:
3
+ :magic_result:
4
+ :schema:
5
+ :element:
6
+ :complex_type:
7
+ :choice:
8
+ :element:
9
+ :complex_type:
10
+ :sequence:
11
+ :element:
12
+ - :@name: ServerTimeZone
13
+ :@type: xs:string
14
+ :@min_occurs: '0'
15
+ - :@name: ServerTime
16
+ :@type: xs:string
17
+ :@min_occurs: '0'
18
+ - :@name: ServerDateTimeOffset
19
+ :@type: xs:string
20
+ :@min_occurs: '0'
21
+ - :@name: System
22
+ :@type: xs:string
23
+ :@min_occurs: '0'
24
+ - :@name: ProductVersion
25
+ :@type: xs:string
26
+ :@min_occurs: '0'
27
+ - :@name: uaibornondate
28
+ :@type: xs:string
29
+ :@min_occurs: '0'
30
+ :@name: getserverinfoinfo
31
+ :@min_occurs: '0'
32
+ :@max_occurs: unbounded
33
+ :@name: getserverinforesponse
34
+ :@msdata:is_data_set: 'true'
35
+ :@msdata:use_current_locale: 'true'
36
+ :@xmlns:xs: http://www.w3.org/2001/XMLSchema
37
+ :@xmlns: ''
38
+ :@xmlns:msdata: urn:schemas-microsoft-com:xml-msdata
39
+ :@id: getserverinforesponse
40
+ :diffgram:
41
+ :getserverinforesponse:
42
+ :getserverinfoinfo:
43
+ :server_time_zone: Eastern Standard Time
44
+ :server_time: !ruby/object:DateTime 2013-10-24 13:52:49.000000000 -05:00
45
+ :server_date_time_offset: !ruby/object:DateTime 2013-10-24 17:52:49.000000000
46
+ -05:00
47
+ :system: Enterprise EHR
48
+ :product_version: 11.2.3.32.000
49
+ :uaibornondate: 10/07/2013
50
+ :@diffgr:id: getserverinfoinfo1
51
+ :@msdata:row_order: '0'
52
+ :@xmlns: ''
53
+ :@xmlns:diffgr: urn:schemas-microsoft-com:xml-diffgram-v1
54
+ :@xmlns:msdata: urn:schemas-microsoft-com:xml-msdata
55
+ :@xmlns: http://www.allscripts.com/Unity
@@ -0,0 +1,7 @@
1
+ ---
2
+ :normal_key_2: true
3
+ :array_of_attributes:
4
+ - :value:
5
+ :value: true
6
+ - :value: true
7
+ - :value: true
@@ -0,0 +1 @@
1
+ <RetireSecurityTokenResponse xmlns="http://www.allscripts.com/Unity"/>
@@ -0,0 +1,5 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <s:Body>
3
+ <RetireSecurityTokenResponse xmlns="http://www.allscripts.com/Unity" />
4
+ </s:Body>
5
+ </s:Envelope>
@@ -0,0 +1,13 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <s:Body>
3
+ <s:Fault>
4
+ <faultcode>s:Client</faultcode>
5
+ <faultstring xml:lang="en-US">Magic Error - Action: GetProviders - As a Security precaution, you have been logged out due to inactivity.</faultstring>
6
+ <detail>
7
+ <UnityFault xmlns="http://schemas.datacontract.org/2004/07/Allscripts.UAI.Unity.UnityService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
8
+ <ErrorMessage>Magic Error - Action: GetProviders - As a Security precaution, you have been logged out due to inactivity.</ErrorMessage>
9
+ </UnityFault>
10
+ </detail>
11
+ </s:Fault>
12
+ </s:Body>
13
+ </s:Envelope>
@@ -0,0 +1,8 @@
1
+ ---
2
+ key1: true
3
+ key2:
4
+ key3: true
5
+ key4:
6
+ - key5: true
7
+ - key6: true
8
+ - key7: true
@@ -0,0 +1,8 @@
1
+ ---
2
+ :key1: true
3
+ :key2:
4
+ :key3: true
5
+ :key4:
6
+ - :key5: true
7
+ - :key6: true
8
+ - :key7: true
@@ -0,0 +1,209 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'JSONClientDriver' do
4
+ it_behaves_like 'a client driver'
5
+
6
+ subject do
7
+ client_driver = FactoryGirl.build(:json_client_driver)
8
+ client_driver.security_token = SecureRandom.uuid
9
+ client_driver
10
+ end
11
+
12
+ let(:get_server_info) { FixtureLoader.load_file("get_server_info.json") }
13
+ let(:get_security_token) { FixtureLoader.load_file("get_security_token.json") }
14
+ let(:retire_security_token) { FixtureLoader.load_file("retire_security_token.json") }
15
+ let(:error) { FixtureLoader.load_json("error.json") }
16
+ let(:error_string) { "error: Username and Password not valid for any licenses on this server" }
17
+ let(:url) { Faker::Internet.url }
18
+
19
+ let(:hash) do
20
+ {
21
+ "test" => true
22
+ }
23
+ end
24
+
25
+ let(:json_hash) do
26
+ JSON.generate(hash)
27
+ end
28
+
29
+ describe '#initialize' do
30
+ context 'when nil is given for base_unity_url' do
31
+ it { expect { FactoryGirl.build(:json_client_driver, :base_unity_url => nil) }.to raise_error(ArgumentError) }
32
+ end
33
+
34
+ context 'when nil is given for username' do
35
+ it { expect { FactoryGirl.build(:json_client_driver, :username => nil) }.to raise_error(ArgumentError) }
36
+ end
37
+
38
+ context 'when nil is given for password' do
39
+ it { expect { FactoryGirl.build(:json_client_driver, :password => nil) }.to raise_error(ArgumentError) }
40
+ end
41
+
42
+ context 'when nil is given for appname' do
43
+ it { expect { FactoryGirl.build(:json_client_driver, :appname => nil) }.to raise_error(ArgumentError) }
44
+ end
45
+
46
+ context 'when given a base_unity_url with a trailing /' do
47
+ it 'sets @base_unity_url without the trailing /' do
48
+ client_driver = FactoryGirl.build(:json_client_driver, :base_unity_url => "http://www.example.com/")
49
+ expect(client_driver.base_unity_url).to eq("http://www.example.com")
50
+ end
51
+ end
52
+
53
+ context 'when nil is given for timezone' do
54
+ it 'sets @timezone to UTC' do
55
+ client_driver = FactoryGirl.build(:json_client_driver, :timezone => nil)
56
+ utc_timezone = FactoryGirl.build(:timezone, :zone_identifier => "UTC")
57
+ expect(client_driver.timezone.tzinfo).to eq(utc_timezone.tzinfo)
58
+ end
59
+ end
60
+
61
+ context 'when nil is given for logger' do
62
+ it 'sets @logger to Logger' do
63
+ client_driver = FactoryGirl.build(:json_client_driver, :logger => nil)
64
+ expect(client_driver.logger).to be_instance_of(Logger)
65
+ end
66
+ end
67
+
68
+ context 'when logger is set' do
69
+ it 'sets @logger to logger' do
70
+ logger = double("logger")
71
+ client_driver = FactoryGirl.build(:json_client_driver, :logger => logger)
72
+ expect(client_driver.logger).to be(logger)
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '#client_type' do
78
+ it { expect(subject.client_type).to be(:json) }
79
+ end
80
+
81
+ describe '#magic' do
82
+ before(:each) {
83
+ stub_request(:post, "http://www.example.com/Unity/UnityService.svc/json/MagicJson").to_return(:body => get_server_info)
84
+ allow(subject).to receive(:start_timer)
85
+ allow(subject).to receive(:end_timer)
86
+ allow(subject).to receive(:log_magic)
87
+ }
88
+
89
+ it 'should POST to /Unity/UnityService.svc/json/MagicJson' do
90
+ subject.magic
91
+ WebMock.should have_requested(:post, "http://www.example.com/Unity/UnityService.svc/json/MagicJson")
92
+ end
93
+
94
+ it 'should call start_timer' do
95
+ subject.magic
96
+ expect(subject).to have_received(:start_timer)
97
+ end
98
+
99
+ it 'should call end_timer' do
100
+ subject.magic
101
+ expect(subject).to have_received(:start_timer)
102
+ end
103
+
104
+ it 'should call log_magic' do
105
+ subject.magic
106
+ expect(subject).to have_received(:log_magic)
107
+ end
108
+ end
109
+
110
+ describe '#get_security_token!' do
111
+ before(:each) {
112
+ stub_request(:post, "http://www.example.com/Unity/UnityService.svc/json/GetToken").to_return(:body => get_security_token)
113
+ allow(subject).to receive(:start_timer)
114
+ allow(subject).to receive(:end_timer)
115
+ allow(subject).to receive(:log_get_security_token)
116
+ }
117
+
118
+ it 'should POST to /Unity/UnityService.svc/json/GetToken' do
119
+ subject.get_security_token!
120
+ WebMock.should have_requested(:post, "http://www.example.com/Unity/UnityService.svc/json/GetToken")
121
+ end
122
+
123
+ it 'should call start_timer' do
124
+ subject.get_security_token!
125
+ expect(subject).to have_received(:start_timer)
126
+ end
127
+
128
+ it 'should call end_timer' do
129
+ subject.get_security_token!
130
+ expect(subject).to have_received(:start_timer)
131
+ end
132
+
133
+ it 'should call log_get_security_token' do
134
+ subject.get_security_token!
135
+ expect(subject).to have_received(:log_get_security_token)
136
+ end
137
+ end
138
+
139
+ describe '#retire_security_token!' do
140
+ before(:each) {
141
+ stub_request(:post, "http://www.example.com/Unity/UnityService.svc/json/RetireSecurityToken").to_return(:body => retire_security_token)
142
+ allow(subject).to receive(:start_timer)
143
+ allow(subject).to receive(:end_timer)
144
+ allow(subject).to receive(:log_retire_security_token)
145
+ }
146
+
147
+ it 'should POST to /Unity/UnityService.svc/json/RetireSecurityToken' do
148
+ subject.retire_security_token!
149
+ WebMock.should have_requested(:post, "http://www.example.com/Unity/UnityService.svc/json/RetireSecurityToken")
150
+ end
151
+
152
+ it 'should call start_timer' do
153
+ subject.retire_security_token!
154
+ expect(subject).to have_received(:start_timer)
155
+ end
156
+
157
+ it 'should call end_timer' do
158
+ subject.retire_security_token!
159
+ expect(subject).to have_received(:start_timer)
160
+ end
161
+
162
+ it 'should call log_retire_security_token' do
163
+ subject.retire_security_token!
164
+ expect(subject).to have_received(:log_retire_security_token)
165
+ end
166
+ end
167
+
168
+ describe '#create_httpi_request' do
169
+ context 'when given url' do
170
+ it 'returns an HTTPI request with that url' do
171
+ expect(subject.send(:create_httpi_request, url, hash).url.to_s).to eq(url)
172
+ end
173
+ end
174
+
175
+ context 'when given data' do
176
+ it 'returns an HTTPI request with body set to that data' do
177
+ expect(subject.send(:create_httpi_request, url, hash).body).to eq(json_hash)
178
+ end
179
+ end
180
+
181
+ context 'when @proxy is nil' do
182
+ it 'returns an HTTPI request with proxy set to nil' do
183
+ subject.proxy = nil
184
+ expect(subject.send(:create_httpi_request, url, hash).proxy).to be_nil
185
+ end
186
+ end
187
+
188
+ context 'when @proxy is set' do
189
+ it 'return an HTTPI request with proxy set to @proxy' do
190
+ subject.proxy = url
191
+ expect(subject.send(:create_httpi_request, url, hash).proxy.to_s).to eq(url)
192
+ end
193
+ end
194
+ end
195
+
196
+ describe '#raise_if_response_error' do
197
+ context 'when given nil for response' do
198
+ it { expect { subject.send(:raise_if_response_error, nil) }.to raise_error(AllscriptsUnityClient::APIError) }
199
+ end
200
+
201
+ context 'when given error JSON' do
202
+ it { expect { subject.send(:raise_if_response_error, error) }.to raise_error(AllscriptsUnityClient::APIError) }
203
+ end
204
+
205
+ context 'when given error string' do
206
+ it { expect { subject.send(:raise_if_response_error, error_string) }.to raise_error(AllscriptsUnityClient::APIError) }
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'JSONUnityRequest' do
4
+ it_behaves_like 'a unity request'
5
+
6
+ subject { FactoryGirl.build(:json_unity_request) }
7
+
8
+ describe '#initialize' do
9
+ context 'when nil is given for parameters' do
10
+ it { expect { FactoryGirl.build(:json_unity_request, :parameters => nil) }.to raise_error(ArgumentError) }
11
+ end
12
+
13
+ context 'when nil is given for timezone' do
14
+ it { expect { FactoryGirl.build(:json_unity_request, :timezone => nil) }.to raise_error(ArgumentError) }
15
+ end
16
+
17
+ context 'when nil is given for appname' do
18
+ it { expect { FactoryGirl.build(:json_unity_request, :appname => nil) }.to raise_error(ArgumentError) }
19
+ end
20
+
21
+ context 'when nil is given for security_token' do
22
+ it { expect { FactoryGirl.build(:json_unity_request, :security_token => nil) }.to raise_error(ArgumentError) }
23
+ end
24
+ end
25
+
26
+ describe '#to_hash' do
27
+ it ':userid maps to AppUserID' do
28
+ subject.parameters = FactoryGirl.build(:magic_request, :userid => 'UserID')
29
+ expect(subject.to_hash['AppUserID']).to eq('UserID')
30
+ end
31
+
32
+ it ':data maps to Base64 encoded Data' do
33
+ subject.parameters = FactoryGirl.build(:magic_request, :data => 'data')
34
+ expect(subject.to_hash['Data']).to eq(['data'].pack('m'))
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'JSONUnityResponse' do
4
+ it_behaves_like 'a unity response'
5
+
6
+ subject { FactoryGirl.build(:json_unity_response, :response => get_server_info) }
7
+
8
+ let(:get_server_info) { FixtureLoader.load_yaml("get_server_info_json.yml") }
9
+ let(:get_providers) { FixtureLoader.load_yaml("get_providers_json.yml") }
10
+
11
+ describe '#initialize' do
12
+ context 'when nil is given for response' do
13
+ it { expect { FactoryGirl.build(:json_unity_response, :response => nil) }.to raise_error(ArgumentError) }
14
+ end
15
+
16
+ context 'when nil is given for timezone' do
17
+ it { expect { FactoryGirl.build(:json_unity_response, :timezone => nil) }.to raise_error(ArgumentError) }
18
+ end
19
+ end
20
+
21
+ describe '#to_hash' do
22
+ context 'when given a GetServerInfo JSON response hash' do
23
+ it 'strips Unity JSON wrappers' do
24
+ expect(subject.to_hash[:server_time_zone]).to_not be_nil
25
+ end
26
+ end
27
+
28
+ context 'when given empty response' do
29
+ it 'returns []' do
30
+ magic_response = get_providers
31
+ magic_response[0]["getprovidersinfo"] = []
32
+ subject.response = magic_response
33
+ expect(subject.to_hash).to eq([])
34
+ end
35
+ end
36
+
37
+ context 'when given a multiple item response' do
38
+ it 'returns an array' do
39
+ subject.response = get_providers
40
+ expect(subject.to_hash).to be_instance_of(Array)
41
+ end
42
+ end
43
+ end
44
+ end