Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add guides and update readme with links to new project board #479

Merged
merged 14 commits into from
Apr 11, 2024
54 changes: 12 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,64 +8,34 @@ This means that we need to be sure that you can create and deploy Full Stack app

## Challenge

In this project you will be building up a small project that allows you to share your favourite Youtube videos with the world. We will be starting up with a very small MVP (Minimal Viable Product), and built on top of it to make it nicer and more useful.
In this project, you will be building up a small project that allows you to share your favourite YouTube videos with the world. We will be starting up with a very small MVP (Minimal Viable Product), and build on top of it to make it nicer and more useful.

## Levels
## User stories 👩🏽‍💻

The project requirements are split into several levels that you should complete during each week of this project.
Most of the core features for this project have been captured on **user story** issues. You can view all the user story issues on the project planning board: [User story issues](https://github.com/orgs/CodeYourFuture/projects/169/views/3). User story issues define a particular feature through a user story. They also link through to other issues you'll need to implement for this user story to be complete.

You can find each of the levels split into separate files, linked below.
## Requirements

**Note:** Some of the levels are optional which means that you can build a working project without them. However, to make something really impressive you will need to complete as much as you can.
All the requirements for this project are captured as issues that you can find on this planning board: [Full Stack Assessment Planner](https://github.com/orgs/CodeYourFuture/projects/169/views/2)

**Note:** Some of the issues are optional which means that you can build a working project without them. However, to make something really impressive you will need to complete as much as you can.

### Week 1 - Minimal Viable Product

- [Level 100](./requirements/100.md)
- Defining requirements
- [Level 105](./requirements/105.md)
- Setting up the project
- [Level 110](./requirements/110.md)
- Building up the data model
- [Level 120](./requirements/120.md)
- Implementing the API
- [Level 130](./requirements/130.md)
- Implementing the frontend
- [Level 150](./requirements/150.md)
- Checking MVP adheres to the acceptance criteria
- [Level 199](./requirements/199.md) (Optional)
- Implementing code quality improvements
[Week 1 issues](https://github.com/orgs/CodeYourFuture/projects/169/views/2?filterQuery=sprint%3A1)

### Week 2 - Additional features

- [Level 200](./requirements/200.md)
- UX Improvements
- [Level 210](./requirements/210.md)
- Support for adding videos
- [Level 220](./requirements/220.md)
- Support for the removal of videos
- [Level 299](./requirements/299.md) (Optional)
- Implementing optional new features
[Week 2 issues](https://github.com/orgs/CodeYourFuture/projects/169/views/2?filterQuery=sprint%3A2)

### Week 3 - Finalizing project

- [Level 300](./requirements/300.md)
- Allowing rating of videos
- [Level 350](./requirements/350.md)
- Submitting solution for evaluation
- [Level 399](./requirements/399.md) (Optional)
- Making project viable as a portfolio piece
[Week 3 issues](https://github.com/orgs/CodeYourFuture/projects/169/views/2?filterQuery=sprint%3A3)

### Week 4 - Stretch goals

- Use this week as an extra time to implement missing required and optional features from previous weeks.
- [Level 499](./requirements/499.md) (Optional)
- Additional stretch goals to make your project really stand out

## Getting Started

Fork this repository and then clone it to your computer.

Progress to [Level 100](./requirements/100.md) when you are ready.
Use extra time this week to implement missing required and optional features from previous weeks.
[Week 4 issues](https://github.com/orgs/CodeYourFuture/projects/169/views/2?filterQuery=sprint%3A4)

## Sample Solution

Expand Down
106 changes: 106 additions & 0 deletions guides/code-quality/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Code quality improvements (Optional)
Dedekind561 marked this conversation as resolved.
Show resolved Hide resolved

While the following work items are completely optional, they will help you to make fewer mistakes as you continue with future requirements. It is generally a good idea to have them when working on projects of any size.

## 1) Proper error handling

You should make your system to be designed with error handling in mind. For example if the database cannot be accessed when you call `GET /api/videos`, then your backend endpoint should return a properly formatted error message with a HTTP `500` error code.

Here is an example response:

```json
{ "success": false, "error": "Could not connect to the database" }
```

**Note:** You can design how you return error messages differently than the above example. You could also try and merge the error and non-error response styles into one. For example the standard `200` response on the same endpoint could be something like the following:

```json
{"success":true,"videos":[(...)]}
```

Once you do this on the backend you should also change your frontend, to make sure it handles errors that are received. For example if your frontend receives an error like above it might show a message like `"Could not connect to the database, please reload the page at a later time"`. Remember, real users don't look in the console, so you'll need to work how where you want to display this error to the users so they see it.

**Note:** Once you add this feature, make sure you keep handling errors properly during the week 2 and week 3 requirements as well.

## 2) Prettying and linting

It is also usually a good idea to make sure that your code is formatted based on a single standard throughout, and also passes basic checks. There are two projects that can usually help you with that:

- `prettier` is a formatter that makes sure that your code is formatted the same way throughout. For example all files use `tab` characters for indenting.
- `eslint` is a linter that checks the code for common coding mistakes and warns you if it encounters any of them. It can also automatically fix some mistakes.

Let's set up both of them!

### `prettier`

First install prettier into your `package.json` file:

```sh
npm install prettier --save-dev
```

Next you will need a `.prettierrc` file in the root directory. We have already provided one for your convenience.

You can now run prettier to check your files:

```sh
npm exec prettier -- --check .
```

And also to automatically fix them:

```sh
npm exec prettier -- --write .
```

If you don't want to type out these commands you can add them as `scripts` into your `package.json` file. For example you can add a line like:

```json
"prettier": "prettier --write ."
```

to the scripts section, and then you'll be able to automatically pretty your files by typing:

```sh
npm run prettier
```

### `eslint`

Installing `eslint` is similar, but to get the most out of it you will need to install multiple projects:

```sh
npm install eslint eslint-config-prettier eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-refresh eslint-plugin-react-hooks eslint-plugin-n eslint-plugin-jest eslint-plugin-jest-dom eslint-plugin-vitest eslint-plugin-testing-library @codeyourfuture/eslint-config-standard --save-dev
```

This will install `eslint`, and a couple plugins that help you with validating tests, JSX code and React components, like proper `useEffect` usage.

You will also need to have multiple `.eslintrc.json` files, one for each project, tailored to that project's needs. These have also all been provided already.

Once you have everything in place you can run the linter to check for common code mistakes:

```sh
npm exec eslint .
```

You can also ask it to fix any issues it can automatically fix:

```sh
npm exec eslint -- --fix .
```

Same as for `prettier`, you might want to add these commands to your `package.json` for easier access.

### Checks during PRs

It is a good idea to enforce running both the linter and prettier during PRs. One way to do that is to make sure GitHub runs these checks for every PR, blocking the PR in case the code doesn't pass these checks. We have already prepared the `.github/workflows/enforce-linting.yml` file that you can use to run checks on GitHub manually. If you also uncomment the `pull_request` line, you will enable GitHub to run these checks automatically on every PR.

To confirm, the top of the file should look like this:

```yaml
on:
workflow_dispatch:
pull_request:
```

**Note:** Make sure to have a full read of this file and try to figure out what it does.
37 changes: 37 additions & 0 deletions guides/db-setup/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Local database setup ⚙️

## Initiating local database

Once you have your schema ready, make sure you create a new database for yourself locally. For example, let's call it `videorec`. From a shell use `createdb` to create a new database for yourself:

```bash
createdb videorec
```

Once it is created you can now try to load your file into the database using `psql`:

```bash
psql -d videorec < db/initdb.sql
```

**Note:** Depending on how postgresql was installed for you, you might need to add some connectivity details to both `createdb` and `psql`:

```bash
psql -h localhost -U username -d videorec < db/initdb.sql
```

In this example, we ask postgres to connect to your local database through `localhost` and use `username` as the user.

## Re-running the script

It is advised to make sure that the `initdb.sql` script can be run multiple times, and each run would reset the database to a known initial state. One way to do it is to add some SQL code to the start that would delete tables in case they exist, something like:

```sql
DROP TABLE IF EXISTS videos CASCADE;
```

Try running your `initdb.sql` script multiple times with the `psql` code above to make sure every time you get a fresh and clean database without errors.

## Sample data

You will need some example video data in your database. Please check [the example data](./data/example_data.csv), and modify your `initdb.sql`. Add the relevant `INSERT INTO` calls that will add all of this example data every time you run `initdb.sql`.
74 changes: 74 additions & 0 deletions guides/e2e-tests/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# End-to-end tests 🧪

While unit and integration tests usually only check part of the stack (like the frontend tests only check the frontend but don't connect to the backend), end-to-end (E2E) tests are specifically designed to check the interaction of the entirety of the stack - frontend, backend and database.

## Playwright

The biggest E2E frameworks are Selenium, Cypress and Playwright. Each of them allow you to run a browser instance and automate what happens inside it. For this requirement, we picked Playwright as the framework.

For example you can write Playwright code that opens up your application, then clicks the "Remove video" button on the page, checking that the video is indeed removed from the website.

## Setup

Just with the other tests, we have helped you get started by setting up a test runner for your feature tests, and adding a couple tests to `e2e/tests/features.test.js`. These tests would go through the website and check that you can do all of the required features.

**Note:** for this to work you need to make sure you have setup the test backend database. If you haven't done so please refer to that section to set up your test database first.

To run your end-to-end tests there are three steps you need to do:

1. Install Playwright browsers

Playwright will use its own browsers instead of the one installed on your computer. To install the browsers type

```sh
npx playwright install
```

You'll only need to do this once.

2. Stop any running server

Playwright will start up your backend and frontend automatically, but it will not be able to do that properly if you're already running them

3. Start the feature tests:

```sh
npm run test:e2e
```

This command will run the test in the background. If you want to check what Playwright does in the browser you can use

```sh
npm run test:e2e:headed
```

This will start up the browsers in the foreground. Both options will then click around very quickly trying to run the features - adding and deleting videos as well as ranking existing videos up and down.

(Playwright also has a full UI mode where you can play around with your tests. This is accessible via `npm run test:e2e:ui`)

**Note:** just like with the other pre-created tests this might fail depending on how you have implemented your frontend, backend and database parts. Please check the test code and update it to make sure it runs successfully. Some changes that you need to do will be similar to the level 299 frontend tests - like if you don't have a `"Remove video"` button but have something else you need to change the code to find that button. Similarly, the current test assumes that the HTML structure of your video components look like the one below:

```html
<div class="video">
<h1>
<a href="...">The title of the Video</a>
</h1>
<iframe (...)></iframe>
</div>
```

Here to get from the title to the video container you need to go two levels up. First from `<a>` to `<h1>`, then from this `<h1>` to `<div class="video">`. If your website is structured differently you will need to update this in the tests.
Dedekind561 marked this conversation as resolved.
Show resolved Hide resolved

## Enable PR tests

Tests are useful to run every time you create a PR to make sure you don't accidentally add or change code that breaks existing functionality. You can go to `.github/workflows/run-e2e.yml` and remove the comment from the line that says `pull_request:`. This will run the `npm run test:e2e` call every time you create a new PR blocking merging in case tests fail.

## Add new test cases

You might want to add tests to cover some additional scenarios. For example if you have opted into doing the ordering feature you might want to add a test that checks that sorting by ascending and descending really updates the page to sort accordingly.

## Next Level

Once finished please check if you have missed any optional features before, and finish them. If you have done all of them, then congratulations, you have finished this exercise 100%!

Feel free to use this project as part of your portfolio. You might also use it as a base project to start with testing out new ideas, frameworks or deployment services.
62 changes: 62 additions & 0 deletions guides/setup/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Setting up the project 🧰

We have set up an initial project for you to help with some of the complexities of the assessment. This project requires Node.JS version 20 or later. Make sure you have at least Node version 20 running:

```sh
node -v
```

The version number should be `v20.6.0` or higher:

```
v20.8.0
```

If this is lower, like `v18.18.2`, or `v20.5.5` you will need to install a more recent version of Node.JS. Refer to the [node installation guides](https://nodejs.org/en/download/package-manager) for your operating system. For Ubuntu based systems [NodeSource](https://github.com/nodesource/distributions) is usually a good way to do it.

Once you have confirmed that your node version is recent enough you can install the requirements. Change directory to the root of your monorepo. Then run the following commands:

```sh
npm install
```

Then to start up your frontend and backend locally, you can run

```sh
npm run dev
```

To confirm your server is running go to

```url
http://127.0.0.1:3100/health
```

in your browser. If the server is running you'll see a message saying

```json
OK
```

## Before you commit your changes

Read this [article on .gitignore](https://sabe.io/blog/git-ignore-node_modules). We have set up a basic `.gitignore` file for you.

## Frontend setup

Since we are using a monorepo, you can launch the frontend the same way you launch the backend. Run the following command in the root of your repo:

```sh
npm run dev
```

The code you put under `client/src` will then be accessible on http://localhost:3000

## Monorepo

The project is set up to run as a monorepo, where both the [`client`](../../client/) and [`server`](../../server/) source code live in the same git repository and are linked together. When using monorepos, there is some boilerplate code required to make sure both the frontend and the backend application can work at the same time and are accessible on the same URL. To kickstart your development we have set up this boilerplate code for you already. Feel free to look at the code, but generally you won't need to edit them if you follow the proposals in this guide.

If you are interested you can read more about what they do in the following places:

- [Client vite settings](../client/vite.config.js)
- [Server frontend middleware](../server/app.js)
Loading
Loading