Hey!
It will be hot this summer in Montreal with the Osheaga festival! Assuming we're not stuck with another wave of COVID-19, it will also be a rocking festival! Your challenge is to build a promotional app that allows a traveler from Quebec City to find one-way departure schedules for the festival's opening weekend.
Write a native Busbud app that:
- Has a simple onboarding screen that will open the search
- Lists all the departures for a given origin city (Quebec - geohash: f2m673) and a given destination city (Montreal - geohash: f25dvk) for a given day (the 28th of August 2021) for 1 adult.
For each item, we want, at least, to see the departure time, the arrival time, the location name and the price (use
prices.total
of thedeparture
).
- Challenge is submitted as pull request against this repo (fork it and create a pull request).
- The repo should include 3 screenshots under the /screenshots folder to show the app usage.
- Change the README.md to explain your solution, the issues, the way you solved them...
In order to complete this challenge, you will be making requests to napi.busbud.com
, Busbud's production API.
For all requests, you MUST provide the following HTTP headers:
Header | Value |
---|---|
Accept | application/vnd.busbud+json; version=2; profile=https://schema.busbud.com/v2/ |
X-Busbud-Token | The token provided in the challenge invitation email. |
To get departure results, search is initialized via the following endpoint:
https://napi.busbud.com/x-departures/:origin/:destination/:outbound_date
PATH PARAMS
origin
: Origin's geohashdestination
: Destination's geohashoutbound_date
: Outbound departure date, ISO 8061 date
QUERY PARAMS:
adult
: Number of adultschild
: Number of childrensenior
: Number of seniorslang
: ISO 639-1 (2 letter code) language code (supported values includeen
,fr
,es
, and a few others)currency
: ISO 4217 currency code (supported values includeCAD
,USD
,EUR
, and a few others)
The response looks like:
{
"origin_city_id": "375dd5879001acbd84a4683dedf9eed1",
"destination_city_id": "375dd5879001acbd84a4683ded9c875b",
"cities": [
{ City },
{ City }
],
"locations": [
{ Location }
{ Location }
],
"operators": [
{ Operator },
{ Operator }
],
"departures": [
{ XDeparture },
{ XDeparture }
],
"complete": false,
"ttl": 900,
"is_valid_route": true
}
Where a City is like:
{
"id": "375dd5879001acbd84a4683deda84183",
"locale": "en",
"region_id": 6417,
"name": "New York",
"lat": 40.71427,
"lon": -74.00597,
"geohash": "dr5reg",
"timezone": "America/New_York",
"image_url": "/images/promos/city-blocks/new-york.jpg",
"legacy_url_form": "NewYork,NewYork,UnitedStates",
"full_name": "New York, New York, United States",
"region": {
"id": 6417,
"locale": "en",
"country_code2": "US",
"name": "New York",
"country": {
"code2": "US",
"locale": "en",
"code3": "USA",
"name": "United States",
"continent": "NA",
"default_locale": "en",
"default_currency": "USD",
"population": 310232863
}
}
}
Where a Location is like:
{
"id": 3970,
"city_id": "375dd5879001acbd84a4683dedfb933e",
"name": "Métro Bonaventure Bus Station",
"address": [
"997 Rue St-Antoine Ouest",
"Montreal, QC H3C 1A6"
],
"type": "transit_station",
"lat": 45.4988273060484,
"lon": -73.5644745826722,
"geohash": "f25dvfzcz"
}
Where an Operator is like:
{
"id": "bfc27cd544ca49c18d000f2bc00c58c0",
"source_id": 155,
"profile_id": 111,
"name": "Greyhound",
"url": null,
"logo_url": "https://busbud-pubweb-assets-staging.global.ssl.fastly.net/images-service/operator-logos/greyhound.png?hash=1{&height,width}",
"display_name": "Greyhound",
"sellable": true,
"fuzzy_prices": false,
"sell_tickets_cutoff": {
"hours": 1
},
"amenities": {
"classes": {
"Normal": {
"display_name": "Economy",
"wifi": true,
"toilet": true,
"ac": true,
"food": false,
"refreshment": false,
"power_outlets": true,
"tv": false,
"bus_attendant": false,
"leg_room": false
},
"Economy": {
"display_name": "Economy",
"wifi": true,
"toilet": true,
"ac": true,
"food": false,
"refreshment": false,
"power_outlets": true,
"tv": false,
"bus_attendant": false,
"leg_room": false
}
}
},
"source": "greyhound_us",
"referral_deal": false,
"display_url": null,
"fraud_check": "iovation",
"terms": {
"refund": false,
"exchange": true,
"bag_allowed": true,
"piece_of_id": false,
"boarding_requirement": "printed_tkt",
"extra_bag_policy": true,
"use_new_ticket": false,
"exchange_cutoff": 24,
"nb_checked_bags": 1,
"kg_by_bag": 25,
"nb_carry_on": 1,
"extra_bag_cost": 1500
}
}
And an XDeparture is :
{
"id": "7c5dd26a",
"source_id": 155,
"checkout_type": "new",
"operator_id": "bfc27cd544ca49c18d000f2bc00c58c0",
"origin_location_id": 1942,
"destination_location_id": 1938,
"class": "Economy",
"class_name": "Economy",
"amenities": {
"display_name": "Economy",
"wifi": true,
"toilet": true,
"ac": true,
"food": false,
"refreshment": false,
"power_outlets": true,
"tv": false,
"bus_attendant": false,
"leg_room": false
},
"available_seats": 55,
"prices": {
"total": 5200,
"breakdown": {
"base": 5200
},
"categories": {},
"discounted": false
},
"ticket_types": [
"print"
],
"departure_timezone": "America/New_York",
"arrival_timezone": "America/Montreal",
"departure_time": "2016-01-14T00:01:00",
"arrival_time": "2016-01-14T07:55:00"
}
While "complete" is false, you need to call :
https://napi.busbud.com/x-departures/:origin/:destination/:outbound_date/poll
With all the same parameters that the previous endpoint, plus:
index
: Index from which to return new departures
The response is:
{
"departures": [
{ XDeparture },
{ XDeparture }
],
"operators": [
{ Operator },
{ Operator }
],
"complete": true,
"ttl": 900
}