github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/integration/assets/service_broker/spec/service_broker_spec.rb (about) 1 require 'spec_helper' 2 require 'json' 3 require 'timeout' 4 5 describe ServiceBroker do 6 before do 7 post '/config/reset' 8 end 9 10 describe 'GET /v2/catalog' do 11 it 'returns a non-empty catalog' do 12 get '/v2/catalog' 13 response = last_response 14 expect(response.body).to be 15 expect(JSON.parse(response.body)).to be 16 end 17 end 18 19 describe 'POST /v2/catalog' do 20 it 'changes the catalog' do 21 get '/v2/catalog' 22 first_response = last_response 23 expect(first_response.body).to be 24 25 post '/v2/catalog' 26 27 get '/v2/catalog' 28 second_response = last_response 29 expect(second_response.body).to eq(first_response.body) 30 end 31 end 32 33 describe 'PUT /v2/service_instances/:id' do 34 it 'returns 200 with an empty JSON body' do 35 put '/v2/service_instances/fakeIDThough', {}.to_json 36 expect(last_response.status).to eq(200) 37 expect(JSON.parse(last_response.body)).to be_empty 38 end 39 40 context 'when the plan is configured as async_only' do 41 before do 42 config = { 43 max_fetch_service_instance_requests: 1, 44 behaviors: { 45 provision: { 46 'fake-async-plan-guid' => { 47 sleep_seconds: 0, 48 async_only: true, 49 status: 202, 50 body: {} 51 }, 52 default: { 53 sleep_seconds: 0, 54 status: 202, 55 body: {} 56 } 57 } 58 } 59 }.to_json 60 61 post '/config', config 62 end 63 64 65 context 'request is for an async plan' do 66 it 'returns as usual if it does include accepts_incomplete' do 67 put '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json 68 69 expect(last_response.status).to eq(202) 70 end 71 72 it 'rejects request if it does not include accepts_incomplete' do 73 put '/v2/service_instances/fake-guid', {plan_id: 'fake-async-plan-guid'}.to_json 74 75 expect(last_response.status).to eq(422) 76 expect(last_response.body).to eq( 77 { 78 'error' => 'AsyncRequired', 79 'description' => 'This service plan requires client support for asynchronous service operations.' 80 }.to_json 81 ) 82 end 83 end 84 85 end 86 end 87 88 describe 'PATCH /v2/service_instance/:id' do 89 context 'when updating to an async plan' do 90 it 'returns a 202' do 91 patch '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json 92 expect(last_response.status).to eq(202) 93 end 94 end 95 96 context 'when updating to a sync plan' do 97 it 'returns a 200' do 98 patch '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-plan-guid'}.to_json 99 expect(last_response.status).to eq(200) 100 end 101 end 102 103 context 'when the plan is configured as async_only' do 104 before do 105 config = { 106 max_fetch_service_instance_requests: 1, 107 behaviors: { 108 update: { 109 'fake-async-plan-guid' => { 110 sleep_seconds: 0, 111 async_only: true, 112 status: 202, 113 body: {} 114 }, 115 default: { 116 sleep_seconds: 0, 117 status: 202, 118 body: {} 119 } 120 } 121 } 122 }.to_json 123 124 post '/config', config 125 end 126 127 128 context 'request is for an async plan' do 129 it 'returns as usual if it does include accepts_incomplete' do 130 patch '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json 131 132 expect(last_response.status).to eq(202) 133 end 134 135 it 'rejects request if it does not include accepts_incomplete' do 136 patch '/v2/service_instances/fake-guid', {plan_id: 'fake-async-plan-guid'}.to_json 137 138 expect(last_response.status).to eq(422) 139 expect(last_response.body).to eq( 140 { 141 'error' => 'AsyncRequired', 142 'description' => 'This service plan requires client support for asynchronous service operations.' 143 }.to_json 144 ) 145 end 146 end 147 148 end 149 end 150 151 describe 'DELETE /v2/service_instances/:id' do 152 before do 153 put '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json 154 expect(last_response.status).to eq(202) 155 end 156 157 context 'when the plan is configured as async_only' do 158 before do 159 config = { 160 max_fetch_service_instance_requests: 1, 161 behaviors: { 162 deprovision: { 163 'fake-async-plan-guid' => { 164 sleep_seconds: 0, 165 async_only: true, 166 status: 202, 167 body: {} 168 }, 169 default: { 170 sleep_seconds: 0, 171 status: 202, 172 body: {} 173 } 174 } 175 } 176 }.to_json 177 178 post '/config', config 179 end 180 181 182 context 'request is for an async plan' do 183 it 'returns as usual if it does include accepts_incomplete' do 184 delete '/v2/service_instances/fake-guid?accepts_incomplete=true' 185 186 expect(last_response.status).to eq(202) 187 end 188 189 it 'rejects request if it does not include accepts_incomplete' do 190 delete '/v2/service_instances/fake-guid' 191 192 expect(last_response.status).to eq(422) 193 expect(last_response.body).to eq( 194 { 195 'error' => 'AsyncRequired', 196 'description' => 'This service plan requires client support for asynchronous service operations.' 197 }.to_json 198 ) 199 end 200 end 201 end 202 end 203 204 describe 'configuration management' do 205 before do 206 post '/config/reset' 207 end 208 209 def provision 210 put '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json 211 end 212 213 def deprovision 214 delete '/v2/service_instances/fake-guid?plan_id=fake-plan-guid', {}.to_json 215 end 216 217 def update 218 patch '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json 219 end 220 221 def bind 222 put '/v2/service_instances/fake-guid/service_bindings/binding-gui', {plan_id: 'fake-plan-guid'}.to_json 223 end 224 225 def unbind 226 delete '/v2/service_instances/fake-guid/service_bindings/binding-gui?plan_id=fake-plan-guid', {}.to_json 227 end 228 229 [:provision, :deprovision, :update, :bind, :unbind].each do |action| 230 context "for a #{action} operation" do 231 before do 232 put '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json unless action == :provision 233 put '/v2/service_instances/fake-guid/service_bindings/binding-gui', {plan_id: 'fake-plan-guid'}.to_json if action == :unbind 234 end 235 236 it 'should change the response using a json body' do 237 config = { 238 behaviors: { 239 action => { 240 default: { 241 status: 400, 242 sleep_seconds: 0, 243 body: {} 244 } 245 } 246 } 247 }.to_json 248 249 post '/config', config 250 251 send(action) 252 expect(last_response.status).to eq(400) 253 expect(last_response.body).to eq('{}') 254 end 255 256 it 'should change the response using an invalid json body' do 257 config = { 258 behaviors: { 259 action => { 260 default: { 261 status: 201, 262 sleep_seconds: 0, 263 raw_body: 'foo' 264 } 265 } 266 } 267 }.to_json 268 269 post '/config', config 270 271 send(action) 272 expect(last_response.status).to eq(201) 273 expect(last_response.body).to eq 'foo' 274 end 275 276 it 'should cause the action to sleep' do 277 config = { 278 behaviors: { 279 action => { 280 default: { 281 status: 200, 282 sleep_seconds: 1.1, 283 body: {} 284 } 285 } 286 } 287 }.to_json 288 289 post '/config', config 290 291 292 expect do 293 Timeout::timeout(1) do 294 send(action) 295 end 296 end.to raise_error(Timeout::Error) 297 end 298 299 it 'can be customized on a per-plan basis' do 300 config = { 301 behaviors: { 302 action => { 303 'fake-plan-guid' => { 304 status: 200, 305 sleep_seconds: 0, 306 raw_body: 'fake-plan body' 307 }, 308 default: { 309 status: 400, 310 sleep_seconds: 0, 311 body: {} 312 } 313 } 314 } 315 }.to_json 316 317 post '/config', config 318 319 send(action) 320 expect(last_response.status).to eq(200) 321 expect(last_response.body).to eq('fake-plan body') 322 end 323 end 324 end 325 326 context 'for a fetch operation' do 327 before do 328 put '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json 329 end 330 331 it 'should change the response using a json body' do 332 config = { 333 max_fetch_service_instance_requests: 1, 334 behaviors: { 335 fetch: { 336 default: { 337 in_progress: { 338 status: 200, 339 sleep_seconds: 0, 340 body: {} 341 }, 342 finished: { 343 status: 400, 344 sleep_seconds: 0, 345 body: { foo: :bar } 346 } 347 } 348 } 349 } 350 }.to_json 351 352 post '/config', config 353 354 get '/v2/service_instances/fake-guid/last_operation' 355 expect(last_response.status).to eq(200) 356 expect(last_response.body).to eq('{}') 357 358 get '/v2/service_instances/fake-guid/last_operation' 359 expect(last_response.status).to eq(400) 360 expect(last_response.body).to eq({ foo: :bar }.to_json) 361 end 362 363 it 'should change the response using an invalid json body' do 364 config = { 365 max_fetch_service_instance_requests: 1, 366 behaviors: { 367 fetch: { 368 default: { 369 in_progress: { 370 status: 200, 371 sleep_seconds: 0, 372 raw_body: 'cheese' 373 }, 374 finished: { 375 status: 400, 376 sleep_seconds: 0, 377 raw_body: 'cake' 378 } 379 } 380 } 381 } 382 }.to_json 383 384 post '/config', config 385 386 get '/v2/service_instances/fake-guid/last_operation' 387 expect(last_response.status).to eq(200) 388 expect(last_response.body).to eq 'cheese' 389 390 get '/v2/service_instances/fake-guid/last_operation' 391 expect(last_response.status).to eq(400) 392 expect(last_response.body).to eq 'cake' 393 end 394 395 it 'should cause the action to sleep' do 396 config = { 397 max_fetch_service_instance_requests: 1, 398 behaviors: { 399 fetch: { 400 default: { 401 in_progress: { 402 status: 200, 403 sleep_seconds: 1.1, 404 body: {} 405 }, 406 finished: { 407 status: 200, 408 sleep_seconds: 0.6, 409 body: { } 410 } 411 } 412 } 413 } 414 }.to_json 415 416 post '/config', config 417 418 expect do 419 Timeout::timeout(1) do 420 get '/v2/service_instances/fake-guid/last_operation' 421 end 422 end.to raise_error(Timeout::Error) 423 424 expect do 425 Timeout::timeout(0.5) do 426 get '/v2/service_instances/fake-guid/last_operation' 427 end 428 end.to raise_error(Timeout::Error) 429 end 430 431 it 'honors max_fetch_service_instance_request' do 432 config = { 433 max_fetch_service_instance_requests: 2, 434 behaviors: { 435 fetch: { 436 default: { 437 in_progress: { 438 status: 200, 439 sleep_seconds: 0, 440 body: {} 441 }, 442 finished: { 443 status: 400, 444 sleep_seconds: 0, 445 body: { foo: :bar } 446 } 447 } 448 } 449 } 450 }.to_json 451 452 post '/config', config 453 454 get '/v2/service_instances/fake-guid/last_operation' 455 expect(last_response.status).to eq(200) 456 expect(last_response.body).to eq('{}') 457 458 get '/v2/service_instances/fake-guid/last_operation' 459 expect(last_response.status).to eq(200) 460 expect(last_response.body).to eq('{}') 461 462 get '/v2/service_instances/fake-guid/last_operation' 463 expect(last_response.status).to eq(400) 464 expect(last_response.body).to eq({ foo: :bar }.to_json) 465 end 466 467 it 'can be customized on a per-plan basis' do 468 config = { 469 max_fetch_service_instance_requests: 1, 470 behaviors: { 471 fetch: { 472 'fake-plan-guid' => { 473 in_progress: { 474 status: 200, 475 sleep_seconds: 0, 476 body: { foo: 'bar' } 477 }, 478 finished: { 479 status: 201, 480 sleep_seconds: 0, 481 body: { foo: 'baz' } 482 } 483 }, 484 default: { 485 in_progress: { 486 status: 200, 487 sleep_seconds: 0, 488 body: {} 489 }, 490 finished: { 491 status: 400, 492 sleep_seconds: 0, 493 body: { foo: :bar } 494 } 495 } 496 } 497 } 498 }.to_json 499 500 post '/config', config 501 502 get '/v2/service_instances/fake-guid/last_operation' 503 expect(last_response.status).to eq(200) 504 expect(last_response.body).to eq({ foo: 'bar' }.to_json) 505 506 get '/v2/service_instances/fake-guid/last_operation' 507 expect(last_response.status).to eq(201) 508 expect(last_response.body).to eq({ foo: 'baz' }.to_json) 509 end 510 end 511 512 it 'should allow resetting the configuration to its defaults' do 513 get '/config' 514 data = last_response.body 515 516 config = { 517 behaviors: { 518 provision: { 519 default: { 520 status: 400, 521 sleep_seconds: 0, 522 body: {} 523 } 524 } 525 } 526 }.to_json 527 post '/config', config 528 529 post '/config/reset' 530 expect(last_response.status).to eq(200) 531 532 get '/config' 533 expect(last_response.body).to eq(data) 534 end 535 536 it 'should be able to restore a previously saved configuration' do 537 get '/config' 538 data = last_response.body 539 540 post '/config', data 541 expect(last_response.status).to eq(200) 542 expect(last_response.body).to eq(data) 543 end 544 end 545 end