forked from NEWROPE/scnnr-ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
polling_manager_spec.rb
159 lines (126 loc) · 5.51 KB
/
polling_manager_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Scnnr::PollingManager do
let(:manager) { described_class.new(timeout) }
describe '.start' do
subject(:result) { described_class.start(client, options, &block) }
let(:timeout) { Scnnr::PollingManager::MAX_TIMEOUT * 3 }
let(:client) { instance_double(Scnnr::Client) }
let(:options) { { api_key: 'test', timeout: timeout, public: true } }
let(:block) { proc { finished_recognition } }
let(:queued_recognition) { Scnnr::Recognition.new('state' => 'queued') }
let(:finished_recognition) { Scnnr::Recognition.new('state' => 'finished') }
it 'passes the max timeout and other options to the block' do
expect(block).to receive(:call).with({
api_key: 'test', timeout: Scnnr::PollingManager::MAX_TIMEOUT, public: true
}).and_return(finished_recognition)
result
end
context 'when the block returns a finished recognition' do
let(:block) { proc { finished_recognition } }
it 'immediately returns the recognition' do
expect(client).not_to receive(:fetch)
expect(subject).to eq finished_recognition
end
end
context 'when the first fetch attempt finishes' do
let(:block) { proc { queued_recognition } }
it 'returns the finished recognition' do
expect(client).to receive(:fetch).with(
queued_recognition.id, hash_including(polling: false, timeout: Scnnr::PollingManager::MAX_TIMEOUT)
).and_return(finished_recognition)
expect(subject).to eq finished_recognition
end
end
context 'when the timeout is exceeded' do
let(:block) { proc { queued_recognition } }
it 'times out with the queued recognition' do
expect(client).to receive(:fetch).with(
queued_recognition.id, hash_including(polling: false, timeout: Scnnr::PollingManager::MAX_TIMEOUT)
).twice.and_return(queued_recognition)
expect { subject }.to raise_error(Scnnr::TimeoutError) do |e|
expect(e.recognition).to eq queued_recognition
end
end
end
end
describe '#polling' do
subject { manager.polling(client, recognition_id, options) }
let(:client) { Scnnr::Client.new }
let(:recognition_id) { 'dummy_id' }
let(:options) { {} }
context 'when timeout is 0' do
let(:timeout) { 0 }
context 'and finished recognition returns' do
let(:recognition) { Scnnr::Recognition.new('state' => 'finished') }
it do
expect(client).to(receive(:fetch).with(recognition_id, hash_including(timeout: anything, polling: false))
.once { recognition })
expect { subject }.not_to change(manager, :timeout)
end
end
context 'and not finished recognition returns' do
let(:recognition) { Scnnr::Recognition.new }
it do
expect(client).to(receive(:fetch).with(recognition_id, hash_including(timeout: anything, polling: false))
.once { recognition })
expect { subject }.not_to change(manager, :timeout)
end
end
end
context 'when timeout is greater than 0' do
let(:timeout) { rand(1..100) }
context 'and finished recognition returns' do
let(:recognition) { Scnnr::Recognition.new('state' => 'finished') }
it do
expect(client).to(receive(:fetch).with(recognition_id, hash_including(timeout: anything, polling: false))
.once { recognition })
expect { subject }.to change(manager, :timeout)
.from(timeout).to([timeout - Scnnr::PollingManager::MAX_TIMEOUT, 0].max)
expect(subject).to eq recognition
end
end
context 'and finished recognition fails' do
let(:recognition) { Scnnr::Recognition.new('state' => 'error') }
it do
expect(client).to(receive(:fetch).with(recognition_id, hash_including(timeout: anything, polling: false))
.once { recognition })
expect { subject }.to change(manager, :timeout)
.from(timeout).to([timeout - Scnnr::PollingManager::MAX_TIMEOUT, 0].max)
expect(subject).to eq recognition
end
end
context 'and not finished recognition returns' do
let(:recognition) { Scnnr::Recognition.new('state' => 'queued') }
let(:times) { (Float(timeout) / Scnnr::PollingManager::MAX_TIMEOUT).ceil }
it do
expect(client).to(receive(:fetch).with(recognition_id, hash_including(timeout: anything, polling: false))
.exactly(times).times { recognition })
expect { subject }.to raise_error(Scnnr::TimeoutError) do |e|
expect(e.recognition).to eq recognition
end
end
end
end
context 'when timeout is Float::INFINITY' do
context 'and finished recognition returns' do
let(:recognition) { Scnnr::Recognition.new('state' => 'finished') }
let(:timeout) { Float::INFINITY }
it do
expect(client).to(receive(:fetch).with(recognition_id, hash_including(timeout: anything, polling: false))
.once { recognition })
expect { subject }.not_to change(manager, :timeout)
end
end
end
context 'when timeout is neither Integer nor Float::INFINITY' do
let(:recognition) { nil }
let(:timeout) { nil }
it do
expect(client).to(receive(:fetch).with(recognition_id, hash_including(timeout: anything, polling: false))
.exactly(0).times { recognition })
expect { subject }.to raise_error(ArgumentError)
end
end
end
end