Skip to content

Commit 5fb9ad6

Browse files
committed
Add a test:watch task
1 parent e22a5b4 commit 5fb9ad6

File tree

2 files changed

+50
-205
lines changed

2 files changed

+50
-205
lines changed

README.md

Lines changed: 48 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This project grew out of wanting to prepare for an interview for a job that woul
44

55
* Angular instead of React/NextJS
66
* Angular Material instead of AWS Amplify's UI library. (I do, however, use Tailwind CSS in both.)
7-
* Postgres instead of DynamoDB (Sql vs NoSQL)
7+
* Postgres instead of DynamoDB (SQL vs NoSQL)
88
* REST (using a NodeJS/Express backend) vs GraphQL (using Amplify and AppSync)
99
* This project has nothing in regard to authentication (yet), while the Amplify project implemented authentication right at the beginning.
1010

@@ -34,6 +34,37 @@ I also have some mounts so that
3434
* devcontainer can communicate with the host's Docker daemon
3535
* the AWS credentials and configuration are available within the devcontainer.
3636

37+
### NOTE
38+
39+
I'm having a peculiar issue with bind mounts in `docker-compose.yml` when I try to use a relative reference. For example, the following *should* (I believe) bind the `backend` directory within root directory of my app (`interview-prep`) in the devcontainer to the `/app/backend` directory within the backend service:
40+
```yaml
41+
services:
42+
backend:
43+
volumes:
44+
- ./backend:/app/backend
45+
```
46+
Unfortunately, I get an error saying...
47+
```
48+
Attaching to frontend-1
49+
Error response from daemon: Mounts denied:
50+
The path /workspaces/interview-prep/backend is not shared from the host and is not known to Docker.
51+
You can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.
52+
See https://docs.docker.com/desktop/mac for more info.
53+
```
54+
That error isn't helpful, as `workspaces` isn't even a "real" directory and can't be added to shared paths. In any event, I wouldn't want every user of a project to have to specify a directory on his or her host machine; a devcontainer shouldn't require that. I can get around the error by supplying a full, absolute path, e.g., `/Users/davidsilva/Dev/interview-prep/backend:/app/backend`, or by doing what I'm doing until I can figure out the relative directory thing -- namely, setting an environment variable in `devcontainer.json`,
55+
```json
56+
"remoteEnv": {
57+
"HOST_PROJECT_PATH": "${localWorkspaceFolder}"
58+
},
59+
```
60+
and using `HOST_PROJECT_PATH` in `docker-compose.yml`:
61+
```yaml
62+
services:
63+
backend:
64+
volumes:
65+
- ${HOST_PROJECT_PATH}/backend:/app/backend
66+
```
67+
3768
## Frontend
3869
3970
The frontend app, which uses Angular 18, is pretty simple: featurewise, it allows listing, creating and editing users and products.
@@ -68,7 +99,7 @@ Both the frontend and backend apps use an NPM package `@onyxdevtutorials/intervi
6899

69100
## Workflow and Continuous Integration (CI)
70101

71-
TO COME.
102+
`.gihub/workflows/ci.yml` runs the frontend and backend tests when there are pushes to or pull requests on specified branches. The results can be viewed in the GitHub UI.
72103

73104
## Building the App
74105

@@ -94,220 +125,33 @@ Prerequisites:
94125

95126
1. `docker-compose --env-file .env.test up backend-tests`
96127

97-
Other options for running backend tests:
128+
To view test and coverage reports in a web browser:
98129

99130
1. Bring up the backend with `docker-compose --env-file .env.test up backend`
100131
1. In a separate terminal window, `cd` into `backend`.
101132
1. `npm run test:coverage`. That will run all the tests and a coverage report.
102133
1. `npm run serve:report`. This will bring up a pretty web page at `http://localhost:8080/` where you should be able to look at test and coverage reports.
103134

104-
Note: I thought it would be nice to a live web display of test results and coverage but that's problematic. Practically speaking it's probably best or easiest just to run `npm run test:watch` as you make code changes; that will present the familiar terminal based interface to give you feedback on particular code you change and tests you write.
135+
#### Note
136+
137+
I thought it would be nice to have a *live* web display of test results and coverage but that's problematic. Practically speaking it's probably best or easiest just to run `npm run test:watch` as you make code changes; that will present the familiar terminal based interface to give you feedback on particular code you change and tests you write.
105138

106139
### Frontend
107140

108141
1. `docker-compose --env-file .env.test up frontend-tests` (At the moment I don't have any pretty web reports set up.)
109142

143+
Tests can also be run in watch mode so that they will be re-run as you make changes to code and tests:
110144

111-
112-
How to run the frontend app:
113-
114-
1. `cd frontend`
115-
1. `npm run start`
116-
1. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
117-
118-
### Backend
119-
120-
How to run the backend app:
121-
122-
1. `cd backend`
123-
1. `npm run dev` (The backend uses port 3000.)
124-
125-
## Building for Production
126-
127-
### Frontend
128-
145+
1. `docker-compose --env-file .env.local up backend` (to bring up the backend app and the db).
129146
1. `cd frontend`
130-
1. `npm run build` (The build artifacts will be stored in the `dist/` directory.)
131-
132-
### Backend
133-
134-
1. `cd backend`
135-
1. `npm run build` (compiled app will be in `dist/`)
136-
137-
## Running unit tests for frontend
138-
139-
TO COME. Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
140-
141-
## Running end-to-end tests
142-
143-
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
144-
145-
## Further help
146-
147-
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
148-
149-
## Run SSH Tunnel in Background
150-
151-
- Using port 5433 in order not to conflict with local db using standard 5432.
152-
- 107.22.66.121 is Elastic IP for bastion host
153-
`ssh -f -i <PATH TO KEY-PAIR PEM> -L 5433:interviewprepdbinstance.c92egeoumrf1.us-east-1.rds.amazonaws.com:5432 ec2-user@107.22.66.121 -N`
154-
- To keep SSH tunnel alive: `ssh -f -i <PATH TO KEY-PAIR PEM> -L 5433:interviewprepdbinstance.c92egeoumrf1.us-east-1.rds.amazonaws.com:5432 ec2-user@107.22.66.121 -N -o ServerAliveInterval=60 -o ServerAliveCountMax=3`
155-
156-
## Migrations
157-
158-
DB credentials and URLs are in `.env.local` and `.env.development`. Set the environment to be used: `export NODE_ENV=local` or `export NODE_ENV=production`.
159-
160-
Maybe obsolete:
161-
162-
You need an SSH tunnel to be able to run the migrations on the db in AWS. Check for a tunnel by using `ps aux | grep ssh`. It will look something like
163-
164-
```
165-
davidsilva 69319 0.0 0.0 410379280 1904 ?? Ss 12:34PM 0:00.01 ssh -f -i /Users/davidsilva/Downloads/OnyxKeyPair.pem -L 5433:interviewprepdbinstance.c92egeoumrf1.us-east-1.rds.amazonaws.com:5432 ec2-user@107.22.66.121 -N
166-
```
167-
168-
# SSH into Bastion Host
169-
170-
The security group only allows SSH connections from my VPN IP address.
171-
172-
- `ssh -i <PATH TO KEY-PAIR PEM> ec2-user@107.22.66.121`, where `107.22.66.121` is the IP of the bastion host.
173-
174-
# Run psql from Bastion Host
175-
176-
- `psql -h interviewprepdbinstance.c92egeoumrf1.us-east-1.rds.amazonaws.com -p 5432 -U dbadmin -d interviewprepdbinstance`. Supply password when prompted.
177-
- Example command: `\d products` (output the structure of the "products" table).
178-
179-
# SSH into `interview-prep-app-instance` via Bastion Host
180-
181-
- Start ssh agent if it isn't already running: `eval "$(ssh-agent -s)"`.
182-
- Add private key to the ssh agent: `ssh-add <PATH TO KEY-PAIR PEM>`.
183-
- SSH into the bastion host with agent forwarding: `ssh -A -i <PATH TO KEY-PAIR PEM> ec2-user@107.22.66.121`, where `107.22.66.121` is the Elastic IP of the bastion host.
184-
- SSH into app_instance `ssh ec2-user@10.0.5.216`, where `10.0.5.216` is the private IP address of `interview-prep-app-instance` (`i-06ce4967201932411`).
185-
186-
# How to Find Private IP Address of an EC2 Instance
187-
188-
`aws ec2 describe-instances --filters "Name=tag:Name,Values=<NAME OF YOUR INSTANCE>" --query 'Reservations[*].Instances[*].PrivateIpAddress' --output text`
189-
190-
# Steps to Dockerize Angular App, Push to AWS ECR Using AWS Copilot
191-
192-
- User/profile with AdministratorAccess. Options: Temporarily give the default user AdministratorAccess; create such a user for occassions like this; or (this would be hard) figure out exactly all the individual permissions you would need and create a user just with those permissions.
193-
194-
# Create the ECR repository
195-
196-
`aws ecr create-repository --repository-name interview-prep --region us-east-1 --profile aws-cli-user`
197-
198-
# Verify the repository
199-
200-
`aws ecr describe-repositories --region us-east-1 --profile aws-cli-user`
201-
202-
# Authenticate Docker to ECR
203-
204-
`aws ecr get-login-password --region us-east-1 --profile aws-cli-user | docker login --username AWS --password-stdin 909500381447.dkr.ecr.us-east-1.amazonaws.com`
205-
206-
# Build the Docker images
207-
208-
To run locally:
209-
210-
1. Authenticate Docker to ECR if necessary.
211-
1. From the app root directory (parent of frontend and backend) run `docker build -t interview-prep-frontend:latest -f frontend/Dockerfile .`
212-
1. `docker build -t interview-prep-backend:latest -f backend/Dockerfile .`
213-
214-
# Tag the Docker image
215-
216-
`docker tag interview-prep:latest 909500381447.dkr.ecr.us-east-1.amazonaws.com/interview-prep:latest`
217-
218-
# Push the Docker image to ECR
219-
220-
`docker push 909500381447.dkr.ecr.us-east-1.amazonaws.com/interview-prep:latest`
221-
222-
# Get IP Address of a Docker Container
223-
224-
`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_id>`
225-
E.g.,
226-
`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' c611004f5595`
227-
228-
# Check Docker Network Settings
229-
230-
`docker network ls`
231-
232-
# Inspect Docker Container
233-
234-
`docker inspect interview-prep-frontend-1`
235-
236-
# Check the disk space usage by Docker resources
237-
238-
`docker system df`
239-
240-
# Remove Unused Docker Images
241-
242-
`docker image prune -a`
243-
244-
# Remove Unused Docker Containers
245-
246-
`docker container prune`
247-
248-
# Remove Unused Docker Volumes
249-
250-
`docker volume prune`
251-
252-
# Remove Unused Docker Volume Usage
253-
254-
`docker network prune`
255-
256-
# List Docker Volumes
257-
258-
`docker volume ls`
259-
260-
# Inspect a Particular Docker Volume
261-
262-
`docker volume inspect <VOLUME NAME>`
263-
264-
# Run Frontend Tests
265-
266-
`docker-compose --env-file .env.local up frontend-tests`
267-
268-
Or to do a build, too:
269-
270-
`docker-compose --env-file .env.local up --build frontend-tests`
271-
272-
Or:
273-
274-
`docker-compose --env-file .env.local build --no-cache frontend-tests`
275-
276-
`docker-compose --env-file .env.local up frontend-tests`
277-
278-
# Run Backend Tests
279-
280-
`docker-compose --env-file .env.test build backend-tests`
281-
`docker-compose --env-file .env.test up backend-tests`
282-
283-
Run outside of Docker container:
284-
285-
`npm run test`
286-
287-
Could run in the background or in separate shell to have HTML reports loaded (and reloaded) in web browser:
288-
289-
`npm run serve:report`
290-
291-
# Shared
292-
293-
## Update, Build and Publish
294-
295-
1. Increase version number in `package.json`.
296-
1. `npm run build`
297-
1. `npm publish`
298-
299-
# Run the Whole App in Docker Locally
300-
301-
Everything except the tests will run because frontend is dependent upon backend, which is dependent upon db.
302-
`docker-compose --env-file .env.local up --build frontend`
303-
304-
# Database
305-
306-
With `interview-prep-db-1` up and running, you can access the db via psql using...
307-
308-
`docker exec -it interview-prep-db-1 psql -U interviewprep_admin -d interviewprepdbinstance`
309-
310-
## Run Migrations
147+
1. `npm run test:watch`
148+
1. In another terminal, `cd frontend` and `npm run start` (now tests will be re-run and you can see changes reflected in the web browser as you make changes to code and tests).
311149

312-
`docker-compose --env-file .env.local up migrate`
150+
## Version History
313151

152+
### 0.0.0
153+
- Created a frontend app with views for adding and updating users and products, with services to talk to the REST API of the backend.
154+
- Created a backend app to persist users and products in a PostgreSQL database and provide a REST API for the frontend.
155+
- Created unit and integration tests for frontend and backend.
156+
- Dockerized the application and set it up to use a devcontainer.
157+
- Created a GitHub workflow to run tests when there push to or pull request on development, stage or production branches.

frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"start": "ng serve --host 0.0.0.0 --port 4200",
77
"build": "ng build",
88
"watch": "ng build --watch --configuration development",
9-
"test": "ng test --no-watch"
9+
"test": "ng test --no-watch",
10+
"test:watch": "ng test"
1011
},
1112
"private": true,
1213
"dependencies": {

0 commit comments

Comments
 (0)