|
187 | 187 | end |
188 | 188 |
|
189 | 189 | describe 'GET /api/v1/airlines/to-airport' do |
190 | | - let(:destination_airport_code) { 'MRS' } |
| 190 | + let(:destination_airport_code) { 'JFK' } |
191 | 191 | let(:limit) { '10' } |
192 | 192 | let(:offset) { '0' } |
193 | 193 | let(:expected_airlines) do |
194 | | - [ |
195 | | - { |
196 | | - 'callsign' => 'AIRFRANS', |
197 | | - 'country' => 'France', |
198 | | - 'iata' => 'AF', |
199 | | - 'icao' => 'AFR', |
200 | | - 'name' => 'Air France' |
201 | | - }, |
202 | | - { |
203 | | - 'callsign' => 'SPEEDBIRD', |
204 | | - 'country' => 'United Kingdom', |
205 | | - 'iata' => 'BA', |
206 | | - 'icao' => 'BAW', |
207 | | - 'name' => 'British Airways' |
208 | | - }, |
209 | | - { |
210 | | - 'callsign' => 'AIRLINAIR', |
211 | | - 'country' => 'France', |
212 | | - 'iata' => 'A5', |
213 | | - 'icao' => 'RLA', |
214 | | - 'name' => 'Airlinair' |
215 | | - }, |
216 | | - { |
217 | | - 'callsign' => 'STARWAY', |
218 | | - 'country' => 'France', |
219 | | - 'iata' => 'SE', |
220 | | - 'icao' => 'SEU', |
221 | | - 'name' => 'XL Airways France' |
222 | | - }, |
223 | | - { |
224 | | - 'callsign' => 'TWINJET', |
225 | | - 'country' => 'France', |
226 | | - 'iata' => 'T7', |
227 | | - 'icao' => 'TJT', |
228 | | - 'name' => 'Twin Jet' |
229 | | - }, |
230 | | - { |
231 | | - 'callsign' => 'EASY', |
232 | | - 'country' => 'United Kingdom', |
233 | | - 'iata' => 'U2', |
234 | | - 'icao' => 'EZY', |
235 | | - 'name' => 'easyJet' |
236 | | - }, |
237 | | - { |
238 | | - 'callsign' => 'AMERICAN', |
239 | | - 'country' => 'United States', |
240 | | - 'iata' => 'AA', |
241 | | - 'icao' => 'AAL', |
242 | | - 'name' => 'American Airlines' |
243 | | - }, |
244 | | - { |
245 | | - 'callsign' => 'CORSICA', |
246 | | - 'country' => 'France', |
247 | | - 'iata' => 'XK', |
248 | | - 'icao' => 'CCM', |
249 | | - 'name' => 'Corse-Mediterranee' |
250 | | - } |
251 | | - ] |
| 194 | + # frozen_string_literal: true |
| 195 | + |
| 196 | + require 'rails_helper' |
| 197 | + |
| 198 | + RSpec.describe 'Airlines API', type: :request do |
| 199 | + describe 'GET /api/v1/airlines/{id}' do |
| 200 | + let(:airline_id) { 'airline_10' } |
| 201 | + let(:expected_airline) do |
| 202 | + { |
| 203 | + 'name' => '40-Mile Air', |
| 204 | + 'iata' => 'Q5', |
| 205 | + 'icao' => 'MLA', |
| 206 | + 'callsign' => 'MILE-AIR', |
| 207 | + 'country' => 'United States' |
| 208 | + } |
| 209 | + end |
| 210 | + |
| 211 | + it 'returns the airline' do |
| 212 | + get "/api/v1/airlines/#{airline_id}" |
| 213 | + |
| 214 | + expect(response).to have_http_status(:ok) |
| 215 | + expect(response.content_type).to eq('application/json; charset=utf-8') |
| 216 | + expect(JSON.parse(response.body)).to eq(expected_airline) |
| 217 | + end |
| 218 | + end |
| 219 | + |
| 220 | + describe 'POST /api/v1/airlines/{id}' do |
| 221 | + let(:airline_id) { 'airline_post' } |
| 222 | + let(:airline_params) do |
| 223 | + { |
| 224 | + 'name' => '40-Mile Air', |
| 225 | + 'iata' => 'Q5', |
| 226 | + 'icao' => 'MLA', |
| 227 | + 'callsign' => 'MILE-AIR', |
| 228 | + 'country' => 'United States' |
| 229 | + } |
| 230 | + end |
| 231 | + |
| 232 | + context 'when the airline is created successfully' do |
| 233 | + it 'returns the created airline' do |
| 234 | + post "/api/v1/airlines/#{airline_id}", params: { airline: airline_params } |
| 235 | + |
| 236 | + expect(response).to have_http_status(:created) |
| 237 | + expect(response.content_type).to eq('application/json; charset=utf-8') |
| 238 | + expect(JSON.parse(response.body)).to include(airline_params) |
| 239 | + rescue StandardError => e |
| 240 | + puts e |
| 241 | + ensure |
| 242 | + delete "/api/v1/airlines/#{airline_id}" |
| 243 | + end |
| 244 | + end |
| 245 | + |
| 246 | + context 'when the airline already exists' do |
| 247 | + let(:airline_id) { 'airline_137' } |
| 248 | + it 'returns a conflict error' do |
| 249 | + post "/api/v1/airlines/#{airline_id}", params: { airline: airline_params } |
| 250 | + |
| 251 | + expect(response).to have_http_status(:conflict) |
| 252 | + expect(JSON.parse(response.body)).to include({ 'error' => "Airline with ID #{airline_id} already exists" }) |
| 253 | + end |
| 254 | + end |
| 255 | + end |
| 256 | + |
| 257 | + describe 'PUT /api/v1/airlines/{id}' do |
| 258 | + let(:airline_id) { 'airline_put' } |
| 259 | + |
| 260 | + let(:current_params) do |
| 261 | + { |
| 262 | + 'name' => '40-Mile Air', |
| 263 | + 'iata' => 'U5', |
| 264 | + 'icao' => 'UPD', |
| 265 | + 'callsign' => 'MILE-AIR', |
| 266 | + 'country' => 'United States' |
| 267 | + } |
| 268 | + end |
| 269 | + let(:updated_params) do |
| 270 | + { |
| 271 | + 'name' => '41-Mile Air', |
| 272 | + 'iata' => 'U6', |
| 273 | + 'icao' => 'UPE', |
| 274 | + 'callsign' => 'UPDA-AIR', |
| 275 | + 'country' => 'Updated States' |
| 276 | + } |
| 277 | + end |
| 278 | + |
| 279 | + context 'when the airline is updated successfully' do |
| 280 | + it 'returns the updated airline' do |
| 281 | + put "/api/v1/airlines/#{airline_id}", params: { airline: updated_params } |
| 282 | + |
| 283 | + expect(response).to have_http_status(:ok) |
| 284 | + expect(response.content_type).to eq('application/json; charset=utf-8') |
| 285 | + expect(JSON.parse(response.body)).to include(updated_params) |
| 286 | + rescue StandardError => e |
| 287 | + puts e |
| 288 | + ensure |
| 289 | + puts "Deleting airline with ID #{airline_id}" |
| 290 | + delete "/api/v1/airlines/#{airline_id}" |
| 291 | + end |
| 292 | + end |
| 293 | + |
| 294 | + context 'when the airline is not updated successfully' do |
| 295 | + it 'returns a bad request error' do |
| 296 | + post "/api/v1/airlines/#{airline_id}", params: { airline: current_params } |
| 297 | + |
| 298 | + expect(response).to have_http_status(:created) |
| 299 | + expect(response.content_type).to eq('application/json; charset=utf-8') |
| 300 | + expect(JSON.parse(response.body)).to include(current_params) |
| 301 | + |
| 302 | + put "/api/v1/airlines/#{airline_id}", params: { airline: { name: '' } } |
| 303 | + |
| 304 | + expect(response).to have_http_status(:bad_request) |
| 305 | + expect(JSON.parse(response.body)).to include({ 'error' => 'Invalid request', |
| 306 | + 'message' => 'Missing fields: iata, icao, callsign, country' }) |
| 307 | + rescue StandardError => e |
| 308 | + puts e |
| 309 | + ensure |
| 310 | + delete "/api/v1/airlines/#{airline_id}" |
| 311 | + end |
| 312 | + end |
| 313 | + end |
| 314 | + |
| 315 | + describe 'DELETE /api/v1/airlines/{id}' do |
| 316 | + let(:airline_id) { 'airline_delete' } |
| 317 | + let(:airline_params) do |
| 318 | + { |
| 319 | + 'name' => '40-Mile Air', |
| 320 | + 'iata' => 'Q5', |
| 321 | + 'icao' => 'MLA', |
| 322 | + 'callsign' => 'MILE-AIR', |
| 323 | + 'country' => 'United States' |
| 324 | + } |
| 325 | + end |
| 326 | + |
| 327 | + context 'when the airline is deleted successfully' do |
| 328 | + it 'returns a success message' do |
| 329 | + post "/api/v1/airlines/#{airline_id}", params: { airline: airline_params } |
| 330 | + |
| 331 | + delete "/api/v1/airlines/#{airline_id}" |
| 332 | + |
| 333 | + expect(response).to have_http_status(:accepted) |
| 334 | + expect(JSON.parse(response.body)).to eq({ 'message' => 'Airline deleted successfully' }) |
| 335 | + end |
| 336 | + end |
| 337 | + |
| 338 | + context 'when the airline does not exist' do |
| 339 | + it 'returns a not found error' do |
| 340 | + delete "/api/v1/airlines/#{airline_id}" |
| 341 | + |
| 342 | + expect(response).to have_http_status(:not_found) |
| 343 | + expect(JSON.parse(response.body)).to eq({ 'error' => "Airline with ID #{airline_id} not found" }) |
| 344 | + end |
| 345 | + end |
| 346 | + end |
| 347 | + |
| 348 | + describe 'GET /api/v1/airlines/list' do |
| 349 | + let(:country) { 'United States' } |
| 350 | + let(:limit) { '10' } |
| 351 | + let(:offset) { '0' } |
| 352 | + let(:expected_airlines) do |
| 353 | + [ |
| 354 | + { 'name' => '40-Mile Air', 'iata' => 'Q5', 'icao' => 'MLA', 'callsign' => 'MILE-AIR', |
| 355 | + 'country' => 'United States' }, |
| 356 | + { 'name' => 'Texas Wings', 'iata' => 'TQ', 'icao' => 'TXW', 'callsign' => 'TXW', |
| 357 | + 'country' => 'United States' }, |
| 358 | + { 'name' => 'Atifly', 'iata' => 'A1', 'icao' => 'A1F', 'callsign' => 'atifly', |
| 359 | + 'country' => 'United States' }, |
| 360 | + { 'name' => 'Locair', 'iata' => 'ZQ', 'icao' => 'LOC', 'callsign' => 'LOCAIR', |
| 361 | + 'country' => 'United States' }, |
| 362 | + { 'name' => 'SeaPort Airlines', 'iata' => 'K5', 'icao' => 'SQH', 'callsign' => 'SASQUATCH', |
| 363 | + 'country' => 'United States' }, |
| 364 | + { 'name' => 'Alaska Central Express', 'iata' => 'KO', 'icao' => 'AER', 'callsign' => 'ACE AIR', |
| 365 | + 'country' => 'United States' }, |
| 366 | + { 'name' => 'AirTran Airways', 'iata' => 'FL', 'icao' => 'TRS', 'callsign' => 'CITRUS', |
| 367 | + 'country' => 'United States' }, |
| 368 | + { 'name' => 'U.S. Air', 'iata' => '-+', 'icao' => '--+', 'callsign' => nil, |
| 369 | + 'country' => 'United States' }, |
| 370 | + { 'name' => 'PanAm World Airways', 'iata' => 'WQ', 'icao' => 'PQW', 'callsign' => nil, |
| 371 | + 'country' => 'United States' }, |
| 372 | + { 'name' => 'Bemidji Airlines', 'iata' => 'CH', 'icao' => 'BMJ', 'callsign' => 'BEMIDJI', |
| 373 | + 'country' => 'United States' } |
| 374 | + ] |
| 375 | + end |
| 376 | + |
| 377 | + it 'returns a list of airlines for a given country' do |
| 378 | + get '/api/v1/airlines/list', params: { country:, limit:, offset: } |
| 379 | + |
| 380 | + expect(response).to have_http_status(:ok) |
| 381 | + expect(response.content_type).to eq('application/json; charset=utf-8') |
| 382 | + expect(JSON.parse(response.body)).to eq(expected_airlines) |
| 383 | + end |
| 384 | + end |
| 385 | + |
| 386 | + describe 'GET /api/v1/airlines/to-airport' do |
| 387 | + let(:destination_airport_code) { 'JFK' } |
| 388 | + let(:limit) { '10' } |
| 389 | + let(:offset) { '0' } |
| 390 | + let(:expected_airlines) do |
| 391 | + [ |
| 392 | + { |
| 393 | + 'callsign' => 'SPEEDBIRD', |
| 394 | + 'country' => 'United Kingdom', |
| 395 | + 'iata' => 'BA', |
| 396 | + 'icao' => 'BAW', |
| 397 | + 'name' => 'British Airways' |
| 398 | + }, |
| 399 | + { |
| 400 | + 'callsign' => 'AIRFRANS', |
| 401 | + 'country' => 'France', |
| 402 | + 'iata' => 'AF', |
| 403 | + 'icao' => 'AFR', |
| 404 | + 'name' => 'Air France' |
| 405 | + }, |
| 406 | + { |
| 407 | + 'callsign' => 'DELTA', |
| 408 | + 'country' => 'United States', |
| 409 | + 'iata' => 'DL', |
| 410 | + 'icao' => 'DAL', |
| 411 | + 'name' => 'Delta Air Lines' |
| 412 | + }, |
| 413 | + { |
| 414 | + 'callsign' => 'AMERICAN', |
| 415 | + 'country' => 'United States', |
| 416 | + 'iata' => 'AA', |
| 417 | + 'icao' => 'AAL', |
| 418 | + 'name' => 'American Airlines' |
| 419 | + }, |
| 420 | + { |
| 421 | + 'callsign' => 'HAWAIIAN', |
| 422 | + 'country' => 'United States', |
| 423 | + 'iata' => 'HA', |
| 424 | + 'icao' => 'HAL', |
| 425 | + 'name' => 'Hawaiian Airlines' |
| 426 | + }, |
| 427 | + { |
| 428 | + 'callsign' => 'JETBLUE', |
| 429 | + 'country' => 'United States', |
| 430 | + 'iata' => 'B6', |
| 431 | + 'icao' => 'JBU', |
| 432 | + 'name' => 'JetBlue Airways' |
| 433 | + }, |
| 434 | + { |
| 435 | + 'callsign' => 'FLAGSHIP', |
| 436 | + 'country' => 'United States', |
| 437 | + 'iata' => '9E', |
| 438 | + 'icao' => 'FLG', |
| 439 | + 'name' => 'Pinnacle Airlines' |
| 440 | + }, |
| 441 | + { |
| 442 | + 'callsign' => 'SUN COUNTRY', |
| 443 | + 'country' => 'United States', |
| 444 | + 'iata' => 'SY', |
| 445 | + 'icao' => 'SCX', |
| 446 | + 'name' => 'Sun Country Airlines' |
| 447 | + }, |
| 448 | + { |
| 449 | + 'callsign' => 'UNITED', |
| 450 | + 'country' => 'United States', |
| 451 | + 'iata' => 'UA', |
| 452 | + 'icao' => 'UAL', |
| 453 | + 'name' => 'United Airlines' |
| 454 | + }, |
| 455 | + { |
| 456 | + 'callsign' => 'U S AIR', |
| 457 | + 'country' => 'United States', |
| 458 | + 'iata' => 'US', |
| 459 | + 'icao' => 'USA', |
| 460 | + 'name' => 'US Airways' |
| 461 | + } |
| 462 | + ] |
| 463 | + end |
| 464 | + |
| 465 | + context 'when destinationAirportCode is provided' do |
| 466 | + it 'returns a list of airlines flying to the destination airport' do |
| 467 | + get '/api/v1/airlines/to-airport', |
| 468 | + params: { destinationAirportCode: destination_airport_code, limit:, offset: } |
| 469 | + |
| 470 | + expect(response).to have_http_status(:ok) |
| 471 | + expect(response.content_type).to eq('application/json; charset=utf-8') |
| 472 | + expect(JSON.parse(response.body)).to eq(expected_airlines) |
| 473 | + end |
| 474 | + end |
| 475 | + |
| 476 | + context 'when destinationAirportCode is not provided' do |
| 477 | + it 'returns a bad request error' do |
| 478 | + get '/api/v1/airlines/to-airport', params: { limit:, offset: } |
| 479 | + |
| 480 | + expect(response).to have_http_status(:bad_request) |
| 481 | + expect(JSON.parse(response.body)).to eq({ 'message' => 'Destination airport code is required' }) |
| 482 | + end |
| 483 | + end |
| 484 | + end |
| 485 | + end |
252 | 486 | end |
253 | 487 |
|
254 | 488 | context 'when destinationAirportCode is provided' do |
|
0 commit comments