HW2: Book your Taxi!
After the success of the Strelsau Taxi Ordering System (STRS), the authorities of Strelsau (Ruritania) have decided to extend it so that the taxi allocation relies on travel costs instead of the shortest distance.
General information:
- The homework can be completed in pairs (2-person team).
- Submission deadline: Friday 06.11 at 23:59
- The code with the solution must be pushed into a private repository (only one repository per pair/solution). You can use GitHub, Bitbucket, or GitLab, as you prefer.
- Please add all the teachers to your repo -- the emails are posted on the home page of the course website.
- If you use Bitbucket, make sure you didn’t reach the user limit. In case you have reached the limit, you can upgrade your plan by using your UT email account.
- You must provide a solution based on the requirements described in this narrative. If you are not sure about a requirement, please ask your TA for clarification.
- The commits should show clear evidence of the participation of all team members.
- Once you complete the homework, submit a link to your repository via Moodle.
Description
The system must support two types of users: customer and taxi driver. For each user, the system must store: full name, age, email, and password. The email is used as the username to login into the system. Besides, the system must guarantee the emails stored in the database are unique and have a valid format, and that each user is an adult (i.e., 18 years old or older).
When booking a taxi, a customer provides the pickup and dropoff addresses and the estimated distance to cover on the entire journey. Note that you can calculate the distance from the pickup-dropoff destinations. During this iteration of the project, Strelsau’s authorities will be equally satisfied no matter if you calculate the distance automatically, or you ask the customer to provide it as input. However, they ask you to check that the pickup and dropoff addresses are not empty and different, and the distance is never a negative number.
Once the customer submits the booking request, the system should automatically select the available taxi that covers the desired distance at the lowest price. If many taxis offer the same price, the system will choose the one with the lowest number of completed rides. If there is no taxi available at the moment of booking, the system must display a message that notifies the user about it; otherwise, the system must show the information about the booked taxi to the customer. This information must include taxi capacity (number of seats), the price for the entire journey (based on the distance), the taxi location (or optionally the distance to the pickup address), and the full name of the taxi driver. Note that you should calculate the price of the journey based on the estimated distance; thus, you should store the cost per kilometre of each taxi to make such calculation.
You might use/extend the following associations introduced in handout #7 “Phoenix: database associations and queries”.
In addition, the application must support the following operations:
- create_booking: The system should display a booking form (view) in which customers provide the booking information. This view should inform whether the booking is accepted or rejected according to the rules described above.
- display_booking_list: The system should display the list of bookings made by the user (history). For example, a customer called John made 3 bookings (two of them were accepted and one was rejected due to taxi availability). When John is logged in the system, it should list all these 3 bookings, and allows Jhon to select any of them and see its full information (see the operation display_booking_info below). Note that Jhon must only see his bookings and not the bookings made by other users.
- display_booking_info: the system should display the information about a given booking, i.e., pickup and dropoff address as well as the information about the allocated taxi.
- complete_ride: the system should display a form in which the taxi driver notifies the completion of the ride corresponding to a booking. Note that, the system must validate that the user invoking the operation is the taxi driver who received the booking allocation.
Note that your solution must include database migrations, the corresponding routes, the implementation of the logic related the operations, and the required views and templates. Your implementation must guarantee that only authorized users perform the operations. If a non-authorized user tries to execute the action, then it should be notified accordingly.
In addition, the entities managed by the system (i.e. Taxi, Booking and Allocation) should transit on the following statuses:
Booking:
- ACCEPTED: The system automatically updates this state after successfully allocating a taxi to a customer when they invoke the operation create_booking.
- REJECTED: The system automatically updates this state if no taxi is available to satisfy a booking request when a customer invokes the operation create_booking.
Taxi:
- BUSY: The system automatically updates this state after allocating a taxi to a customer when they invoke the operation create_booking.
- AVAILABLE: The system updates this state when the taxi driver invokes the function complete_ride.
Allocation:
- ALLOCATED: The system automatically updates this state after allocating a taxi to a customer when they invoke the operation create_booking. This status holds from the moment system allocates the taxi for a booking, until the moment the corresponding taxi driver invokes the function complete_ride.
- COMPLETED: The system updates this state when the taxi driver invokes the function complete_ride.
Although one could fulfil the requirements described above without having an entity Allocation, Strelsau’s authorities have plans to extend the application in the future by extending this initial solution. For this reason, they explicitly require to have at least the three mentioned entities (i.e., Taxi, Booking, and Allocation) in the current solution.
Your task
You must implement a web application that corresponds to the scenario described above by using Phoenix and following a BDD/TDD approach. As such, the web application is expected to have an interface that allows a final user to interact with it. Solutions of type API will not be considered.
As part of the BDD cycle, you must provide Gherkin user stories that are in line with the scenario, and implement the corresponding acceptance tests that cover the operation create_booking (i.e., including the acceptance and rejection of bookings).
As part of the TDD cycle, you must write unit and/or integration tests that verify the logic of the operation create_booking. You may include several assertions in a single test or write several test cases; both approaches will be fine as long as the cases described in the scenario are covered. As a starting point, you can use the code we developed in any of the lecture/lab sessions, and modify/add all the components you need to implement the homework.
Please commit the code to your repository as often as you can, and use informative commit messages so we can check you are following the BDD/TDD cycle. Unlike Homework 1, you don't have to use a specific naming convention in your commits messages but we expect you to follow the cycle.
Grading
You can get a maximum of 4 points for this homework. Team members receive equal grades. Overall, the grade is determined based on:
- If the written tests cover the cases described in the requirement specification (narrative)
- If the provided implementation fulfils the requirements described by the narrative.
In particular, the points are distributed as follow:
points | |
(BDD) Specification of Gherkin user stories capturing the operation create_booking | 0.4 |
(BDD) Implementation of white_bread steps of the features (acceptance tests) | 0.8 |
(TDD) Unit or integration tests covering the requirements (restrictions) of operation create_booking | 0.8 |
Setup of the application routes | 0.2 |
Setup and implementation of entities (via migrations) | 0.4 |
Implementation of controllers/logic | 1 |
Implementation of views and templates | 0.4 |