Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/codehunt101/prince-theatre
This application renders a group of classic movies and compares the prices of two well-known streaming providers.
https://github.com/codehunt101/prince-theatre
httparty jest material-ui rails rails-api react rspec
Last synced: 16 days ago
JSON representation
This application renders a group of classic movies and compares the prices of two well-known streaming providers.
- Host: GitHub
- URL: https://github.com/codehunt101/prince-theatre
- Owner: CodeHunt101
- Created: 2022-02-22T06:09:57.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2022-02-28T08:27:48.000Z (almost 3 years ago)
- Last Synced: 2024-11-24T23:12:09.960Z (3 months ago)
- Topics: httparty, jest, material-ui, rails, rails-api, react, rspec
- Language: Ruby
- Homepage:
- Size: 573 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Prince's theatre
The place you'll find the best deals for movies, guaranteed!
### Contents
- [Description](#description)
- [Technologies used](#technologies-used)
- [Responsiveness](#responsiveness)
- [API key](#api-key)
- [Context](#context)
- [Instructions](#instructions)
- [How to install and run](#how-to-install-and-run)
- [Rails tests instructions](#rails-tests-instructions)
- [React tests instructions](#react-tests-instructions)
- [Architecture (MVC)](#architecture-mvc)
- [Models and Controllers](#models--controllers)
- [Views](#views)
- [Assumptions](#assumptions)
- [Trade-offs](#trade-offs)
- [Opportunities of improvement](#opportunities-of-improvement)---
## Description
This application renders a group of classic movies and compares the prices of two well-known streaming providers, "Filmworld" and "Cinemaworld".
It displays movie posters, titles, actors, and the most important thing: prices!
The cheapest streaming providers are highlighted in green, and other ones have a strikethrough and are red coloured.This app was deployed to Heroku:
https://prince-theatre-app.herokuapp.com/
### Technologies used:
🧰 Programming Languages
![](https://img.shields.io/badge/JavaScript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black)
![](https://img.shields.io/badge/ruby-%23CC342D.svg?style=for-the-badge&logo=ruby&logoColor=white)🧰 Frameworks/Libraries
![](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB)
![](https://img.shields.io/badge/rails-%23CC0000.svg?style=for-the-badge&logo=ruby-on-rails&logoColor=white)
![](https://img.shields.io/badge/materialui-%230081CB.svg?style=for-the-badge&logo=material-ui&logoColor=white)Other worth mentioning frameworks/libraries/gems used are:
- RSpec (Ruby testing tool)
- Jest (JavaScript testing framework)
- HTTParty (Remote URLs fetching tool for Ruby)### Responsiveness:
This application is fully responsive. It adapts to any screen size.
### API Key:
- The API key is safely stored in an environment variable in both development and production modes.
- If you are going to clone this repository, make sure you have a valid API Key.---
## Context:
- The core customer problem to solve in this project is to allow users to see which of the two streaming providers are streaming a particular movie at a cheaper price.
- The information about the movies is available upon authentication from an external API. A secret API key is required.
- _React_ was the chosen JavaScript library for building the user interface (Front-End) as declarative views make code more predictable and easier to debug.
- Since an API key is required, it's crucial to account for _security concerns_. That was an important reason it was decided to have a full-stack application and **_store the API key in the Back-End side_** through an environment variable.
- _Ruby on Rails_ (or simply _Rails_) was the chosen Ruby framework for the Back-End as it can help build structured Model-View-Controller (MVC) architectures. Rails handles the models and controllers for this app, and React takes care of the views as mentioned above.
- All the communication between the app and the external API is performed by Rails. The models handle the external API's information and prepare the required information to be sent to the Front-End from the controllers.
- The Back-End takes care of the entire logic, including finding the lowest prices. The job from the Front-End is rendering the information from the Rails API generated by the server.
- _Material UI_ was the React UI library for layouts and stylings.
---
## Instructions
### How to install and run:
1. Clone this repository.
2. Please make sure you are using **Ruby 2.7.4**; otherwise, go to _Gemfile_ and change the ruby version to the one you currently have (I encourage you to use **Ruby 2.7.4** to avoid incompatibility issues). Then please run the following to install **Rails** and all the dependencies needed for this project:
```
bundle install
```3. To install all the **React** dependencies needed for this project, please run from the root directory:
```
npm install --prefix client
```4. Create a _.env_ file in the root directory to store your API key in an environment variable. Name it API_KEY.
```
API_KEY = your_api_key
```5. To call the server run:
```
rails server
```6. Run the following to display the app in the browser:
```
npm start --prefix client
```Ports from server and client are already set to be different, so there is no need to specify them. Port 3000 is assigned to Rails and Port 4000 to React.
## Rails tests instructions:
- Most of the relevant unit tests are in Rails since the entire logic is handled from the server
- For Ruby on Rails (server), RSpec was the designated testing tool.
- Test files for ruby and configuration files are located in _spec/_To execute the tests from Ruby on Rails, please run from the **root** directory:
```
rspec
```It will automatically run all the tests where green means a test passed and red means it didn't pass.
## React tests instructions:
- For React (client), Jest was the designated testing tool.
- Test files for React and configuration files are located in _app/client/src/_
- Tests for specific components are located in the same component's folderTo execute the tests from React, please run from the **root** directory:
```
npm test --prefix client
```If an error is thrown before the watcher is set up and tests are run, please execute the following:
```
npm i -D --exact [email protected]
```---
## Architecture (MVC)
### Models & Controllers:
- The _Rails_ server handles the logic of the app from the **GetMovies** (_app/models/get_movies.rb_) and **Movie** (_app/models/movie.rb_) models.
- The movies details are sent to the Client from **Api::V1::MoviesController** (_app/controllers/api/v1/movies_controller.rb_) as JSON.
- The _Rails API routes_ are stored in _config/routes.rb_### Views:
- All the files (components and tests) are grouped by features and are located in _app/client/src/components/_. The components structure is the following:
```
App.js
|
|-->Header.js
|
|-->Movies.js
|
|-->Movie.js
|
|-->CinemaMoviePrice.js
```- The _Movies_ component can access the _Rails API routes_ and pass props that contain the movies information to its children components.
- Some stylings, layouts, and animations that are not implemented from Material UI are stored in _client/src/index.css_ and _client/src/App.css_.
---
## Assumptions
- The general information such as Movie titles and actors are the same at both endpoints. Therefore, those two attributes are rendered from Filmworld, assuming that the Cinemaworld attributes will be the same.
- The core problem to solve is to compare prices, so it is assumed that prices might not be the same.
- Since the API is unreliable, it is assumed that sometimes it will not return the movie's information. However, there is already an implementation that retries fetching the data ten times in case a non-desired status code is returned. It handles errors if the API is still unable to return the movie's information after ten retries.
---
## Trade-offs
- Initially, only one endpoint was needed from the Rails API to retrieve everything required, such as the movie's details, prices by cinema, and display the lowest price. However, the way the API was generated wasn't efficient, so the rendering of the movie cards in production was slow. The trade-off for this situation was excluding the prices from the initial endpoint and adding a second endpoint that retrieves them. Now the rendering time is much more efficient in production, although now two endpoints are required.
- For the ease of the user experience, pagination was decided as the means to render the movie cards. The current amount of data is low, so client-side pagination would quickly render the data with just one query. However, if the dataset gets much more extensive, switching to server-side pagination for stability and scalability will be necessary.
- The app is scalable, which means it is possible to add more streaming providers (endpoints), and the app will still find the lowest prices. However, it relies on the assumption mentioned above of sharing the same data as the other streaming providers.
---
## Opportunities for improvement
- The tests from _Jest_ can be more robust: at this point, these can test the essential information that should be rendered to the front-end.
- The _RSpec_ test to determine the cheapest prices could test all movies in one go: at this point, it can accept multiple endpoints (more than the two already provided), but it can do so as long as a single movie index is given.
- Add a sort and filtering feature: by adding this feature, the user experience will improve as users won't have to look at every page to find the movie they're looking for.
- Add a database:
- It could improve the site's performance as it won't have to request data from an external API every time a user loads the page. Periodic database updates from the background might be needed if implemented.
- It would allow users to track how much money they have saved by selecting the cheapest cinemas.- Use Redux for state management: thinking about scalability, having Redux for state management could be helpful as it manages states in a single place.
Thank you for your time!