|
54 | 54 | it 'should return the variation id on success without retrying' do |
55 | 55 | client = described_class.new(mock_http_client, nil, spy_logger) |
56 | 56 | mock_response = double('response', status_code: 200, json: {'predictions' => [{'variationId' => 'abc123'}]}) |
57 | | - allow(mock_http_client).to receive(:post).and_return(mock_response) |
| 57 | + allow(mock_http_client).to receive(:post).and_return(mock_response) |
58 | 58 | result = client.fetch_decision(rule_id, user_id, attributes, cmab_uuid) |
59 | 59 | expect(result).to eq('abc123') |
60 | 60 | expect(mock_http_client).to have_received(:post).with( |
|
65 | 65 | timeout: 10 |
66 | 66 | ) |
67 | 67 | ).once |
| 68 | + expect(Kernel).not_to have_received(:sleep) |
68 | 69 | end |
69 | 70 |
|
70 | 71 | it 'should return HTTP exception without retrying' do |
|
76 | 77 | end.to raise_error(Optimizely::CmabFetchError, /Connection error/) |
77 | 78 | expect(mock_http_client).to have_received(:post).once |
78 | 79 | expect(spy_logger).to have_received(:log).with(Logger::ERROR, a_string_including('Connection error')) |
| 80 | + expect(Kernel).not_to have_received(:sleep) |
79 | 81 | end |
80 | 82 |
|
81 | 83 | it 'should not return 200 status without retrying' do |
|
96 | 98 | ) |
97 | 99 | ).once |
98 | 100 | expect(spy_logger).to have_received(:log).with(Logger::ERROR, a_string_including('500')) |
| 101 | + expect(Kernel).not_to have_received(:sleep) |
99 | 102 | end |
100 | 103 |
|
101 | 104 | it 'should return invalid json without retrying' do |
|
117 | 120 | ) |
118 | 121 | ).once |
119 | 122 | expect(spy_logger).to have_received(:log).with(Logger::ERROR, a_string_including('Invalid CMAB fetch response')) |
| 123 | + expect(Kernel).not_to have_received(:sleep) |
120 | 124 | end |
121 | 125 |
|
122 | 126 | it 'should return invalid response structure without retrying' do |
|
137 | 141 | ) |
138 | 142 | ).once |
139 | 143 | expect(spy_logger).to have_received(:log).with(Logger::ERROR, a_string_including('Invalid CMAB fetch response')) |
| 144 | + expect(Kernel).not_to have_received(:sleep) |
140 | 145 | end |
141 | 146 |
|
142 | 147 | it 'should return the variation id on first try with retry config but no retry needed' do |
|
168 | 173 | success_response = double('response', status_code: 200, json: {'predictions' => [{'variationId' => 'xyz456'}]}) |
169 | 174 |
|
170 | 175 | # First two calls fail, third succeeds |
171 | | - call_sequence = [failure_response, failure_response, success_response] |
172 | | - allow(mock_http_client).to receive(:post) { call_sequence.shift } |
| 176 | + allow(mock_http_client).to receive(:post).and_return(failure_response, failure_response, success_response) |
173 | 177 |
|
174 | 178 | result = client_with_retry.fetch_decision(rule_id, user_id, attributes, cmab_uuid) |
175 | 179 |
|
176 | 180 | expect(result).to eq('xyz456') |
177 | 181 | expect(mock_http_client).to have_received(:post).exactly(3).times |
178 | 182 |
|
179 | | - # Verify all HTTP calls used correct parameters |
180 | | - # This expectation should not be here if you want to count calls. |
181 | | - # It would be better to assert that the last call had the correct parameters, |
182 | | - # or that *any* call had the correct parameters. |
183 | | - # For this test, verifying the total call count and sleep times is more relevant. |
184 | | - # If you want to check the arguments for each of the 3 calls, you'd need a different approach. |
185 | | - # For now, let's remove this specific `with` expectation to avoid conflicts with `exactly(3).times`. |
186 | | - # expect(mock_http_client).to have_received(:post).with( |
187 | | - # expected_url, |
188 | | - # hash_including( |
189 | | - # json: expected_body, |
190 | | - # headers: expected_headers, |
191 | | - # timeout: 10 |
192 | | - # ) |
193 | | - # ) |
194 | | - |
195 | 183 | # Verify retry logging |
196 | | - expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 1) after 0.01 seconds...') |
197 | | - expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 2) after 0.02 seconds...') |
| 184 | + expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 1) after 0.01 seconds...').once |
| 185 | + expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 2) after 0.02 seconds...').once |
198 | 186 |
|
199 | 187 | # Verify sleep was called with correct backoff times |
200 | 188 | expect(Kernel).to have_received(:sleep).with(0.01).once |
201 | 189 | expect(Kernel).to have_received(:sleep).with(0.02).once |
| 190 | + expect(Kernel).not_to have_received(:sleep).with(0.08) |
202 | 191 | end |
203 | 192 |
|
204 | 193 | it 'should exhausts all retry attempts' do |
|
214 | 203 | client_with_retry.fetch_decision(rule_id, user_id, attributes, cmab_uuid) |
215 | 204 | end.to raise_error(Optimizely::CmabFetchError) |
216 | 205 |
|
217 | | - # Verify all attempts were made (1 initial + 3 retries) |
| 206 | + # Verify all attempts were made (1 initial + 3 retries = 4 calls) |
218 | 207 | expect(mock_http_client).to have_received(:post).exactly(4).times |
219 | 208 |
|
220 | 209 | # Verify retry logging |
221 | | - expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 1) after 0.01 seconds...') |
222 | | - expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 2) after 0.02 seconds...') |
223 | | - expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 3) after 0.08 seconds...') |
| 210 | + expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 1) after 0.01 seconds...').once |
| 211 | + expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 2) after 0.02 seconds...').once |
| 212 | + expect(spy_logger).to have_received(:log).with(Logger::INFO, 'Retrying CMAB request (attempt 3) after 0.08 seconds...').once |
224 | 213 |
|
225 | 214 | # Verify sleep was called for each retry |
226 | 215 | expect(Kernel).to have_received(:sleep).with(0.01).once |
|
0 commit comments