allscripts_unity_client 1.0.3

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 (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