gini-api 0.9.2

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.
@@ -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