Slurpin is an app that allows you to find ramen places in Berlin and rate their bowls.
After registering as a user, you can:
- check out ramen places in Berlin and their checkins
- see the recent checkins and like them
- add a new checkin, along with a review and rating
- edit an existing checkin
- check profiles of other users and their checkins
- edit their own profile
The backend API is built in Node.js and Express, using PostgreSQL database, node-postgres for parameterized queries, and JWT authentication. Integration testing is done with Jest.
The client app (SPA) is built with React, uses Redux (with redux-thunk) for state management, React Router for navigation and routing, and Ant Design as UI library. End-to-end testing is done with Cypress.
- Optimize mobile views
- Add possibility to upload checkin and user profile photos (S3?)
- Optimize DB schema and queries for checkin likes (store array of userIds in checkin table?)
- Implement refresh tokens
- Install PostgreSQL locally, i.e.
- packages and installers - follow instructions
- homebrew - see below
brew install postgresql
- Start
psql
in terminal and connect to any database, i.e.
- if you installed via package/installer, open the pre-installed
psql
shell script and provide the requested inputs to connect to default database (according to the inputs you provided during installation) - if you installed via homebrew, type
psql localhost
to connect to default database (no password by default)
- Run the script from
db.sql
, i.e.
\i /absolute/path/to/slurpin/server/db/db.sql
If it runs correctly, you should see something like this in psql
terminal.
CREATE DATABASE
You are now connected to database "slurpin" as user "postgres".
CREATE EXTENSION
CREATE TABLE
CREATE TABLE
CREATE TYPE
CREATE TABLE
CREATE TABLE
CREATE FUNCTION
CREATE TRIGGER
CREATE TRIGGER
CREATE TRIGGER
CREATE FUNCTION
CREATE TRIGGER
CREATE FUNCTION
CREATE TRIGGER
INSERT 0 5
INSERT 0 3
INSERT 0 5
INSERT 0 1
INSERT 0 1
- Install dependencies while in the
server
folder
npm install
- Install dependencies while in the
client
folder
npm install
- Create
.env
file inserver
folder, i.e. with the PG database defaults you used earlier, and a JWT_SECRET
PGHOST=localhost
PGUSER=postgres
PGDATABASE=slurpin
PGPASSWORD=yourpassword
PGPORT=5432
JWT_SECRET=yoursecret
- Start the
server
in development mode from its folder (defaults to port 3000)
npm run dev
- Create
.env
file withPORT=3001
inclient
folder and start theclient
from its folder
npm start
-
Check if the
baseURL
inclient/src/api.js
matches your client app URL (i.e. defaulthttp://localhost:3001
). -
Launch the client app in the browser, register an account, log in and you should see the first few checkins in the feed that were imported while running
db.sql
script.
-
Connect to a default database (i.e.
localhost
) viapsql
(see instructions above). -
Run
test_db.sql
script
\i /absolute/path/to/slurpin/server/db/test_db.sql
If it runs correctly, you should see something like this in psql
terminal.
CREATE DATABASE
You are now connected to database "slurpin_test" as user "postgres".
CREATE EXTENSION
CREATE TABLE
CREATE TABLE
CREATE TYPE
CREATE TABLE
CREATE TABLE
CREATE FUNCTION
CREATE TRIGGER
CREATE TRIGGER
CREATE TRIGGER
CREATE FUNCTION
CREATE TRIGGER
CREATE FUNCTION
CREATE TRIGGER
INSERT 0 5
INSERT 0 3
INSERT 0 5
INSERT 0 1
INSERT 0 1
- Run the tests from the
server
folder
npm run test
You should see the test results in the terminal, i.e.
> server@1.0.0 test /your/path/to/slurpin/server
> NODE_ENV=test jest --verbose --runInBand
PASS routes/__tests__/checkins.test.js
/checkins GET
✓ returns an array of checkins (40 ms)
/checkins POST
✓ works correctly with valid inputs (41 ms)
does not working with invalid inputs, i.e.
✓ missing personId (10 ms)
✓ invalid rating (30 ms)
/checkins/:checkinId
✓ GET returns the checkin with valid id (25 ms)
✓ GET returns error with malformatted ID (6 ms)
✓ PATCH returns error for non matching personId (22 ms)
✓ PATCH works correctly for matching personId (27 ms)
✓ DELETE returns error for non matching personId (6 ms)
✓ DELETE works correctly for matching personId (12 ms)
/checkins/:checkinId/like
✓ PUT adds a like correctly (12 ms)
PASS routes/__tests__/places.test.js
✓ /places GET returns an array of places (30 ms)
/places POST
✓ works correctly with valid inputs (22 ms)
✓ does not work with invalid inputs (34 ms)
✓ does not work with missing inputs (29 ms)
/places/:placeId
✓ GET returns the place with valid id (8 ms)
✓ GET returns error with malformatted ID (4 ms)
✓ PUT edits correctly (33 ms)
✓ /places/:placeId/checkins GET returns the array of checkins (6 ms)
PASS routes/__tests__/persons.test.js
/persons
✓ GET returns the array of persons (31 ms)
/persons/:personId
✓ GET returns the person object (14 ms)
✓ PATCH allows username edit for matching personId (29 ms)
✓ /likes returns an array of checkin IDs (7 ms)
PASS routes/__tests__/auth.test.js
✓ Registers and new user successfully (121 ms)
login route works correctly
✓ with invalid credentials (84 ms)
✓ with valid credentials (71 ms)
PASS ./app.test.js
✓ Health check route returns json (4 ms)
✓ Unknown route returns 404 (1 ms)
Test Suites: 5 passed, 5 total
Tests: 28 passed, 28 total
Snapshots: 0 total
Time: 2.354 s
Ran all test suites.
pawelcebula@Pawels-Air server %
-
Set up the test database (see above)
-
Start the server from the
server
folder
npm run start:test
- Start the client from
client
folder
npm start
- Launch the Cypress test runner from
client
folder
- 4.a. Browser test runner
npm run cypress:open
In the popup window that opens, select preferred broswer in the top right corner (i.e. Chrome)
Run all tests by clicking on Run X integrations specs
below the browser selection dropdown
- 4.b. Console test runner (video recording is off by default - can be modified in
cypress.json
)
npm run cypress:run
Once the tests are finished, you should see something like this
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ auth.spec.js 00:15 5 5 - - - │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ feed.spec.js 00:09 3 3 - - - │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ new_checkin.spec.js 00:14 3 3 - - - │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ place_detail.spec.js 00:09 2 2 - - - │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ places.spec.js 00:08 3 3 - - - │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ profile.spec.js 00:15 6 6 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! 01:12 22 22 - - -