gini-api 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gini::Api::Document::Extractions do
4
+
5
+ before do
6
+ expect(Gini::Api::OAuth).to \
7
+ receive(:new) { oauth }
8
+
9
+ api.login(auth_code: '1234567890')
10
+ api.token.stub(:get).with(
11
+ location,
12
+ {
13
+ headers: {
14
+ accept: header
15
+ }
16
+ }
17
+ ).and_return(OAuth2::Response.new(response))
18
+ end
19
+
20
+ let(:api) do
21
+ Gini::Api::Client.new(
22
+ client_id: 'gini-rspec',
23
+ client_secret: 'secret',
24
+ oauth_site: 'https://rspec-oauth.gini.net',
25
+ log: (Logger.new '/dev/null'),
26
+ )
27
+ end
28
+
29
+ let(:oauth) do
30
+ double('Gini::Api::OAuth',
31
+ :token => 'TOKEN',
32
+ :destroy => nil
33
+ )
34
+ end
35
+
36
+ let(:header) { 'application/vnd.gini.v1+json' }
37
+ let(:location) { 'https://api.gini.net/document/aaa-bbb-ccc/extractions' }
38
+ let(:response) do
39
+ double('Response',
40
+ status: 200,
41
+ headers: {
42
+ 'content-type' => header
43
+ },
44
+ body: {
45
+ extractions: {
46
+ payDate: {
47
+ entity: 'date',
48
+ value: '2012-06-20',
49
+ candidates: 'dates'
50
+ }
51
+ },
52
+ candidates: {
53
+ dates: [
54
+ {
55
+ entity: 'date',
56
+ value: '2012-06-20'
57
+ },
58
+ {
59
+ entity: 'date',
60
+ value: '2012-05-10'
61
+ },
62
+ ]
63
+ }
64
+ }.to_json
65
+ )
66
+ end
67
+
68
+ subject(:extractions) { Gini::Api::Document::Extractions.new(api, location) }
69
+
70
+ it { should respond_to(:update) }
71
+ it { should respond_to(:[]) }
72
+ it { should respond_to(:raw) }
73
+
74
+ describe '#update' do
75
+
76
+ it 'populates instance vars' do
77
+ expect(extractions.payDate).to be_a(Hash)
78
+ expect(extractions.payDate[:entity]).to eq('date')
79
+ extractions.update
80
+ end
81
+
82
+ it 'saves raw response' do
83
+ expect(extractions.raw).to eql(JSON.parse(response.body, symbolize_names: true))
84
+ extractions.update
85
+ end
86
+
87
+ context 'failed extraction fetch' do
88
+
89
+ let(:response) { double('Response', :status => 404, env: {}, body: {}) }
90
+
91
+ it 'raises exception' do
92
+ expect { extractions.update }.to \
93
+ raise_error(Gini::Api::DocumentError, /Failed to fetch extractions from #{location}/)
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ describe '#[]' do
101
+
102
+ context 'with invalid key' do
103
+
104
+ it 'raises exception' do
105
+ expect { extractions[:unknown] }.to \
106
+ raise_error(Gini::Api::DocumentError, /Invalid extraction key unknown/)
107
+ end
108
+
109
+ end
110
+
111
+ context 'with valid key' do
112
+
113
+ it 'returns extraction value' do
114
+ expect(extractions[:payDate]).to eql('2012-06-20')
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gini::Api::Document::Layout do
4
+
5
+ let(:status) { 200 }
6
+ let(:body) { '' }
7
+ let(:api) { double('API', :request => response) }
8
+ let(:location) { 'http://api.gini.net/document/aaa-bbb-ccc/extractions' }
9
+ let(:response) do
10
+ double('Response',
11
+ status: status,
12
+ body: body
13
+ )
14
+ end
15
+
16
+ subject(:layout) { Gini::Api::Document::Layout.new(api, location) }
17
+
18
+ it { should respond_to(:to_xml) }
19
+ it { should respond_to(:to_json) }
20
+
21
+ describe '#to_xml' do
22
+
23
+ let(:body) { '<XML>' }
24
+
25
+ before do
26
+ expect(api).to \
27
+ receive(:request).with(
28
+ :get,
29
+ location,
30
+ type: 'xml'
31
+ ) { response }
32
+ end
33
+
34
+ it do
35
+ expect(layout.to_xml).to eql('<XML>')
36
+ end
37
+
38
+ context 'without layout' do
39
+
40
+ let(:status) { 404 }
41
+
42
+ it do
43
+ expect(layout.to_xml).to be_nil
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ describe '#to_json' do
51
+
52
+ let(:body) { '{JSON}' }
53
+
54
+ before do
55
+ expect(api).to \
56
+ receive(:request).with(
57
+ :get,
58
+ location
59
+ )
60
+ end
61
+
62
+ it do
63
+ expect(layout.to_json).to eql('{JSON}')
64
+ end
65
+
66
+ context 'without layout' do
67
+
68
+ let(:status) { 404 }
69
+
70
+ it do
71
+ expect(layout.to_json).to be_nil
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,289 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gini::Api::Document do
4
+
5
+ before do
6
+ expect(Gini::Api::OAuth).to receive(:new) do
7
+ double('Gini::Api::OAuth', token: 'TOKEN', destroy: nil)
8
+ end
9
+ api.login(auth_code: '1234567890')
10
+ api.token.stub(:get).with(
11
+ location,
12
+ { headers: { accept: header } }
13
+ ).and_return(OAuth2::Response.new(response))
14
+ end
15
+
16
+ let(:api) do
17
+ Gini::Api::Client.new(
18
+ client_id: 'gini-rspec',
19
+ client_secret: 'secret',
20
+ log: Logger.new('/dev/null')
21
+ )
22
+ end
23
+
24
+ let(:header) { 'application/vnd.gini.v1+json' }
25
+ let(:location) { 'https://api.gini.net/documents/aaa-bbb-ccc' }
26
+ let(:response) do
27
+ double('Response', {
28
+ status: 200,
29
+ headers: { 'content-type' => header },
30
+ body: {
31
+ a: 1,
32
+ b: 2,
33
+ progress: 'PENDING',
34
+ _links: {
35
+ extractions: "#{location}/extractions",
36
+ layout: "#{location}/layout",
37
+ processed: "#{location}/processed"
38
+ }
39
+ }.to_json
40
+ })
41
+ end
42
+
43
+ subject(:document) { Gini::Api::Document.new(api, location) }
44
+
45
+ it { should respond_to(:update) }
46
+ it { should respond_to(:poll) }
47
+ it { should respond_to(:processed) }
48
+ it { should respond_to(:extractions) }
49
+ it { should respond_to(:layout) }
50
+ it { should respond_to(:pages) }
51
+
52
+ it 'does accept duration' do
53
+ expect(document.duration).to be_nil
54
+ document.duration = 'test'
55
+ expect(document.duration).to eql('test')
56
+ end
57
+
58
+ describe '#update' do
59
+
60
+ it 'does set instance vars' do
61
+ expect(document.a).to eql(1)
62
+ expect(document.b).to eql(2)
63
+ end
64
+
65
+ context 'with unknown document' do
66
+
67
+ let(:response) { double('Response', status: 404, env: {}, body: {}) }
68
+
69
+ it do
70
+ expect { Gini::Api::Document.new(api, location) }.to \
71
+ raise_error(Gini::Api::DocumentError, /Failed to fetch document data/)
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ describe '#poll' do
79
+
80
+ context 'without code block' do
81
+ let(:response) do
82
+ double('Response', {
83
+ status: 200,
84
+ headers: { 'content-type' => header },
85
+ body: {
86
+ a: 1,
87
+ b: 2,
88
+ progress: 'COMPLETED',
89
+ _links: { extractions: 'ex', layout: 'lay' }
90
+ }.to_json
91
+ })
92
+ end
93
+
94
+ it do
95
+ expect(document.poll(0)).to be_nil
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+
102
+ describe '#processed' do
103
+
104
+ let(:pd_response) do
105
+ double('Response', {
106
+ status: 200,
107
+ headers: { 'content-type' => 'application/octet-stream' },
108
+ body: '1001'
109
+ })
110
+ end
111
+
112
+ it do
113
+ api.token.stub(:get).with(
114
+ "#{location}/processed",
115
+ { headers: { accept: 'application/octet-stream' } }
116
+ ).and_return(OAuth2::Response.new(pd_response))
117
+ expect(document.processed).to eql('1001')
118
+ end
119
+
120
+ context 'with status != 200' do
121
+
122
+ let(:pd_response) do
123
+ double('Response', {
124
+ status: 500,
125
+ headers: { 'content-type' => 'application/octet-stream' },
126
+ body: {},
127
+ env: {}
128
+ })
129
+ end
130
+
131
+ it do
132
+ api.token.stub(:get).with(
133
+ "#{location}/processed",
134
+ { headers: { accept: 'application/octet-stream' } }
135
+ ).and_return(OAuth2::Response.new(pd_response))
136
+ expect { document.processed }.to raise_error(Gini::Api::DocumentError)
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+
143
+ describe '#extractions' do
144
+
145
+ let(:ex_response) do
146
+ double('Response', {
147
+ status: 200,
148
+ headers: { 'content-type' => header },
149
+ body: {
150
+ extractions: { payDate: {} },
151
+ candidates: {}
152
+ }.to_json
153
+ })
154
+ end
155
+
156
+ it do
157
+ api.token.stub(:get).with(
158
+ "#{location}/extractions",
159
+ { headers: { accept: header } }
160
+ ).and_return(OAuth2::Response.new(ex_response))
161
+ expect(document.extractions).to be_a(Gini::Api::Document::Extractions)
162
+ end
163
+
164
+ end
165
+
166
+ describe '#layout' do
167
+
168
+ it do
169
+ expect(document.layout).to be_a Gini::Api::Document::Layout
170
+ end
171
+
172
+ end
173
+
174
+ describe '#pages' do
175
+
176
+ let(:response) do
177
+ double('Response', {
178
+ status: 200,
179
+ headers: { 'content-type' => header },
180
+ body: {
181
+ pages: [
182
+ {
183
+ :pageNumber => 1,
184
+ :images =>
185
+ {
186
+ :"750x900" => "750x900",
187
+ :"1280x1810" => "1280x1810"
188
+ }
189
+ },
190
+ {
191
+ :pageNumber => 2,
192
+ :images => {
193
+ :"750x900" => "750x900",
194
+ :"1280x1810" => "1280x1810"
195
+ }
196
+ }
197
+ ]
198
+ }.to_json
199
+ })
200
+ end
201
+
202
+ it do
203
+ expect(document.pages).to be_an(Array)
204
+ expect(document.pages[0][:"750x900"]).to eql("750x900")
205
+ expect(document.pages[1][:"750x900"]).to eql("750x900")
206
+ expect{document.pages[2][:"750x900"]}.to raise_error(NoMethodError)
207
+ end
208
+
209
+ end
210
+
211
+ describe '#submit_feedback' do
212
+
213
+ let(:response) do
214
+ double('Response', {
215
+ status: 200,
216
+ headers: { 'content-type' => header },
217
+ body: {
218
+ a: 1,
219
+ b: 2,
220
+ progress: 'PENDING',
221
+ _links: {
222
+ extractions: "#{location}/extractions"
223
+ }
224
+ }.to_json
225
+ })
226
+ end
227
+
228
+ context 'succeeds' do
229
+
230
+ let(:fb_response) { double('Response', status: 204) }
231
+
232
+ it do
233
+ document.stub(:extractions) { double('Extractions').as_null_object }
234
+ api.token.stub(:put).with(
235
+ "#{location}/extractions/bic",
236
+ {
237
+ headers: { 'content-type' => header },
238
+ body: { value: 'XXXXXXXX' }.to_json
239
+ }
240
+ ).and_return(OAuth2::Response.new(fb_response))
241
+
242
+ expect(document.submit_feedback(:bic, 'XXXXXXXX')).to be_nil
243
+ end
244
+
245
+ end
246
+
247
+ context 'failes' do
248
+
249
+ let(:fb_response) { double('Response', status: 204) }
250
+
251
+ it 'on invalid label' do
252
+ document.stub(:extractions) { double('Extractions', bic: nil) }
253
+ api.token.stub(:put).with(
254
+ "#{location}/extractions/bic",
255
+ {
256
+ headers: { 'content-type' => header },
257
+ body: { value: 'XXXXXXXX' }.to_json
258
+ }
259
+ ).and_return(OAuth2::Response.new(fb_response))
260
+
261
+ expect { document.submit_feedback(:bic, 'XXXXXXXX') }.to \
262
+ raise_error(Gini::Api::DocumentError, /Unknown label bic/)
263
+ end
264
+
265
+ end
266
+
267
+ context 'failes' do
268
+
269
+ let(:fb_response) { double('Response', status: 404, body: {}, env: {}) }
270
+
271
+ it 'on invalid http code' do
272
+ document.stub(:extractions) { double('Extractions').as_null_object }
273
+ api.token.stub(:put).with(
274
+ "#{location}/extractions/bic",
275
+ {
276
+ headers: { 'content-type' => header },
277
+ body: { value: 'XXXXXXXX' }.to_json
278
+ }
279
+ ).and_return(OAuth2::Response.new(fb_response))
280
+
281
+ expect { document.submit_feedback(:bic, 'XXXXXXXX') }.to \
282
+ raise_error(Gini::Api::DocumentError, /Failed to submit feedback for label bic/)
283
+ end
284
+
285
+ end
286
+
287
+ end
288
+
289
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gini::Api::DocumentSet do
4
+
5
+ before do
6
+ allow(Gini::Api::Document).to \
7
+ receive(:new) { Gini::Api::Document }
8
+ end
9
+
10
+ let(:api) { double('API') }
11
+ let(:data) do
12
+ { totalCount: 2,
13
+ documents:[
14
+ {
15
+ _links: { document: 'dummy' }
16
+ },
17
+ {
18
+ _links: { document: 'dummy' }
19
+ }
20
+ ]
21
+ }
22
+ end
23
+
24
+ subject(:set) { Gini::Api::DocumentSet.new(api, data) }
25
+
26
+ it { should respond_to(:total) }
27
+ it { should respond_to(:documents) }
28
+ it { should respond_to(:each) }
29
+ it { should respond_to(:sort) }
30
+
31
+ it do
32
+ expect(set.total).to eql(2)
33
+ end
34
+
35
+ it do
36
+ expect(set.documents.length).to eql(2)
37
+ expect(set.documents[0]).to eql(Gini::Api::Document)
38
+ end
39
+
40
+ it '#each yields documents' do
41
+ expect { |b| set.each(&b) }.to yield_successive_args(Gini::Api::Document, Gini::Api::Document)
42
+ end
43
+ end
@@ -0,0 +1,155 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gini::Api::Error do
4
+
5
+ let(:location) { 'https://api.rspec/v0/documents/aaa-bbb-ccc' }
6
+ let(:api) do
7
+ double('API',
8
+ token: double('Token')
9
+ )
10
+ end
11
+ let(:response) do
12
+ double('Response',
13
+ status: 200,
14
+ body: {
15
+ a: 1,
16
+ b: 2,
17
+ progress: 'PENDING',
18
+ _links: {
19
+ extractions: 'ex',
20
+ layout: 'lay'
21
+ }
22
+ }.to_json
23
+ )
24
+ end
25
+
26
+ before do
27
+ api.token.stub(:get).and_return(response)
28
+ end
29
+
30
+ context 'without request obj' do
31
+
32
+ subject(:ex) { Gini::Api::Error.new('Error message') }
33
+
34
+ it do
35
+ expect(ex.message).to eql('Error message')
36
+ end
37
+
38
+ it do
39
+ expect(ex.api_response).to be_nil
40
+ should respond_to(:api_response)
41
+ end
42
+
43
+ it do
44
+ expect(ex.api_method).to be_nil
45
+ should respond_to(:api_method)
46
+ end
47
+
48
+ it do
49
+ expect(ex.api_url).to be_nil
50
+ should respond_to(:api_url)
51
+ end
52
+
53
+ it do
54
+ expect(ex.api_status).to be_nil
55
+ should respond_to(:api_status)
56
+ end
57
+
58
+ it do
59
+ expect(ex.api_message).to be_nil
60
+ should respond_to(:api_message)
61
+ end
62
+
63
+ it do
64
+ expect(ex.api_request_id).to be_nil
65
+ should respond_to(:api_request_id)
66
+ end
67
+
68
+ it do
69
+ expect(ex.docid).to be_nil
70
+ should respond_to(:docid)
71
+ end
72
+
73
+ it 'does accept docid' do
74
+ expect(ex.docid).to be_nil
75
+ ex.docid = 'abc-123'
76
+ expect(ex.docid).to eql('abc-123')
77
+ end
78
+
79
+ end
80
+
81
+ context 'with request obj' do
82
+
83
+ let(:request) do
84
+ double('Request',
85
+ status: 500,
86
+ body: {
87
+ message: 'Validation of the request entity failed',
88
+ requestId: '8896f9dc-260d-4133-9848-c54e5715270f'
89
+ }.to_json,
90
+ env: {
91
+ method: :post,
92
+ url: 'https://api.gini.net/abc-123',
93
+ }
94
+ )
95
+ end
96
+
97
+ subject(:ex) { Gini::Api::Error.new('Error message', request) }
98
+
99
+ it do
100
+ expect(ex.api_response).to eql(request)
101
+ end
102
+
103
+ it do
104
+ expect(ex.api_method).to eql(:post)
105
+ end
106
+
107
+ it do
108
+ expect(ex.api_status).to eql(500)
109
+ end
110
+
111
+ it do
112
+ expect(ex.api_url).to \
113
+ eql('https://api.gini.net/abc-123')
114
+ end
115
+
116
+ it do
117
+ expect(ex.api_message).to \
118
+ eql('Validation of the request entity failed')
119
+ end
120
+
121
+ it do
122
+ expect(ex.api_request_id).to \
123
+ eql('8896f9dc-260d-4133-9848-c54e5715270f')
124
+ end
125
+
126
+ it do
127
+ expect(ex.api_error).to \
128
+ eql('POST https://api.gini.net/abc-123 : 500 - Validation of the request entity failed (request Id: 8896f9dc-260d-4133-9848-c54e5715270f)')
129
+ end
130
+
131
+ end
132
+
133
+ context 'with unparsable body' do
134
+
135
+ let(:request) do
136
+ double('Request',
137
+ status: 500,
138
+ body: 'NO Json. Sorry',
139
+ env: {
140
+ method: :post,
141
+ url: 'https://api.gini.net/abc-123',
142
+ }
143
+ )
144
+ end
145
+
146
+ subject(:ex) { Gini::Api::Error.new('Error message', request) }
147
+
148
+ it 'ignores message and request_id' do
149
+ expect(ex.api_message).to eql('undef')
150
+ expect(ex.api_request_id).to eql('undef')
151
+ end
152
+
153
+ end
154
+
155
+ end