Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 56 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@ You will need to create both a `.env` file in the root directory and a `.env.loc
- `DB_PORT`: The port number the database is running on.
- `SERVER_PORT`: The port number for the backend server (default: 3000).

### Client `.env.local` (example.env.local provided in client)

**Required Variables:**
- `NEXT_PUBLIC_API_BASE_URL`: The base URL for API fetch requests (`http://localhost:3000` for local development or `http://<VM_IP>:3000` for deployment).
- `PORT`: The port number for the frontend server.
**Note:** The frontend uses relative URLs with Next.js rewrites to communicate with the backend. No environment variables are required for the client in Docker setups.

---

Expand All @@ -72,12 +68,11 @@ You can run the entire Pixel to Pattern stack locally using Docker Compose.
```
2. Ensure Docker and Docker Compose are installed.
3. Create a `.env` file in the root directory with the necessary credentials listed above.
4. Create a `.env.local` file in the client directory with the credentials listed above.
5. Build and start all services:
4. Build and start all services:
```bash
docker compose up --build
```
6. Visit [http://localhost:3001](http://localhost:3001) to access the application.
5. Visit [http://localhost:3001](http://localhost:3001) to access the application.

To stop containers:
```bash
Expand Down Expand Up @@ -107,7 +102,7 @@ These steps apply only if you wish to run **Pixel to Pattern** manually without
```bash
git clone https://github.com/AlexanderORuban/Pixel-to-Pattern.git
```
2. In the root directory, create a `.env` file and a `.env.local` file in the client directory as described above.
2. In the root directory, create a `.env` file as described above.
3. **Install dependencies** in the root, `server/`, and `client/` directories:
```bash
npm install
Expand Down Expand Up @@ -136,10 +131,8 @@ These steps apply only if you wish to run **Pixel to Pattern** manually without
docker push ghcr.io/<UserName>/<BackendContainer>:latest
```
4. **Build and push the frontend container:**
Replace the `.env.local` base URL with your VM’s IP address, or use the following commands:
```bash
docker build --no-cache -t ghcr.io/<Username>/<FrontendContainer>:latest --build-arg NEXT_PUBLIC_API_BASE_URL=http://<VM_IP>:3000 ./client
docker run --rm ghcr.io/<UserName>/<FrontendContainer>:latest printenv | grep NEXT_PUBLIC_API_BASE_URL
docker build --no-cache -t ghcr.io/<Username>/<FrontendContainer>:latest ./client
docker push ghcr.io/<UserName>/<FrontendContainer>:latest
```

Expand Down Expand Up @@ -212,7 +205,7 @@ These steps apply only if you wish to run **Pixel to Pattern** manually without
```

- **Environment variables not loading:**
Ensure `.env` and `.env.local` files are in the correct directories and not ignored by `.dockerignore`.
Ensure the `.env` file is in the root directory and not ignored by `.dockerignore`.

- **Containers not starting:**
Check logs for detailed errors:
Expand All @@ -225,4 +218,53 @@ These steps apply only if you wish to run **Pixel to Pattern** manually without
Test with:
```bash
docker exec -it db mysql -u root -p
```
```

---

## Backend Unit Tests & Integration Tests

This project includes **unit tests** for the backend using **Jest**.

### Running the Tests

Run all backend unit tests and integration tests:

```bash
cd server
npm install
docker exec -it backend npm test
```
---

## Frontend Unit Tests

This project includes **unit tests** for the frontend using **Jest**.

### Running the Tests

Run all frontend unit tests and generate a coverage report:

```bash
cd client
npm install
npm test
```
### Running the Cypress Tests

Run all cypress tests inside the client:

```bash
cd client
npm install
npm install cypress --save-dev
```
#### Run two terminals for Cypress testing:
- docker compose up --build (Docker Deployment)
- npx cypress open (Open Cypress UI Window)

## 📊 Generate a Coverage Report (if not automatic)
```
npm test -- --coverage
```
---
3 changes: 3 additions & 0 deletions client/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# Node coverage reports
coverage/
5 changes: 4 additions & 1 deletion client/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ COPY . .
# Expose PORT 3001 for frontend server to run on
EXPOSE 3001

# Temporarily disable Babel to allow Next.js to use SWC during build
RUN mv babel.config.js babel.config.ignore || true

# Build the Next.js app for production
RUN npm run build

# Define default command to start the frontend
CMD ["npm", "start"]
CMD ["npm", "start"]
6 changes: 6 additions & 0 deletions client/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
presets: [
["@babel/preset-env", { targets: { node: "current" } }],
["@babel/preset-react", { runtime: "automatic" }]
],
};
8 changes: 8 additions & 0 deletions client/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const { defineConfig } = require("cypress");

module.exports = defineConfig({
e2e: {
baseUrl: "http://localhost:3001",
supportFile: "cypress/support/e2e.js",
},
});
9 changes: 9 additions & 0 deletions client/cypress/e2e/homepage.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
describe("Homepage Loads", () => {
it("should load the homepage", () => {
cy.visit("/");

// Check that the NavBar is present
cy.get("nav").should("exist");
});
});

5 changes: 5 additions & 0 deletions client/cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
25 changes: 25 additions & 0 deletions client/cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
17 changes: 17 additions & 0 deletions client/cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ***********************************************************
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'
2 changes: 0 additions & 2 deletions client/example.env.local

This file was deleted.

15 changes: 15 additions & 0 deletions client/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// jest.config.js
module.exports = {
testEnvironment: "jsdom",
transform: {
"^.+\\.[tj]sx?$": ["babel-jest", { configFile: "./babel.config.js" }],
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest using Vitest for the front end instead of Jest as Jest is experimental when it comes to ESM/Modules and causes more issues while Vitest is very React friendly

moduleFileExtensions: ["js", "jsx"],
moduleNameMapper: {
"\\.(css|less|scss|sass)$": "identity-obj-proxy",
},
setupFilesAfterEnv: ["@testing-library/jest-dom"],
testPathIgnorePatterns: [
"/node_modules/",
],
};
20 changes: 19 additions & 1 deletion client/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
// Proxy API routes to the backend service when the frontend receives relative requests
async rewrites() {
return [
{
source: '/patterns',
destination: 'http://backend:3000/patterns',
},
{
source: '/patterns/:id',
destination: 'http://backend:3000/patterns/:id',
},
{
source: '/update/:id',
destination: 'http://backend:3000/update/:id',
},
];
},
};

export default nextConfig;
Loading