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
60 changes: 60 additions & 0 deletions code/express-server-tests/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Import express
import express from 'express';

// Create the app object using the express function
const app = express();
const PORT = 4000;

// 1. Home endpoint - returns HTML h1 header with banner
app.get('/', (req, res) => {
res.send('<h1>Welcome to My Express Server!</h1>');
});

// 2. About endpoint - sends a short sentence about yourself
app.get('/about', (req, res) => {
res.send('I am a web development student learning Express.js and automated testing.');
});

// 3. Greet endpoint - greets person by name using route parameters
app.get('/greet/:userName', (req, res) => {
const { userName } = req.params;
res.send(`Hello ${userName}, welcome to my server!`);
});

// 4. Favorite endpoint - uses query strings
app.get('/favorite', (req, res) => {
const { fave } = req.query;

if (fave !== undefined) {
res.send(`My favorite thing is ${fave}`);
} else {
res.send('Please tell me your favorite thing by adding ?fave=something to the URL');
}
});

// Extra Challenge: Handle multiple query parameters
app.get('/favorites', (req, res) => {
const queryParams = Object.keys(req.query);

if (queryParams.length === 0) {
res.send('Please tell me your favorites by adding query parameters like ?color=blue&food=pizza');
} else {
const favorites = queryParams.map(key => {
return `My favorite ${key} is ${req.query[key]}`;
});
res.send(favorites.join('. ') + '.');
}
});

// Set up listener on port 4000
// Only start server if this file is run directly (not during testing)
if (process.argv[1] === new URL(import.meta.url).pathname) {
app.listen(PORT, () => {
console.log(`🚀 Server is running on http://localhost:${PORT}`);
console.log('📡 Server started successfully!');
console.log('Press Ctrl+C to stop the server');
});
}

// Export app for testing
export default app;
143 changes: 143 additions & 0 deletions code/express-server-tests/app.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { describe, it, expect } from 'vitest';
import request from 'supertest';
import app from './app.js';

describe('Express Server Tests', () => {

// Test for home endpoint (/)
describe('GET /', () => {
it('should return HTML h1 header with banner', async () => {
const response = await request(app)
.get('/')
.expect(200);

expect(response.text).toBe('<h1>Welcome to My Express Server!</h1>');
});
});

// Test for about endpoint (/about) - Required Test #1
describe('GET /about', () => {
it('should send a static string about yourself', async () => {
const response = await request(app)
.get('/about')
.expect(200);

// Use .toBe() to compare as specified in requirements
expect(response.text).toBe('I am a web development student learning Express.js and automated testing.');
});
});

// Test for greet endpoint (/greet/:userName) - Required Test #2
describe('GET /greet/:userName', () => {
// First request and assertion with different input
it('should greet person by name - test with "John"', async () => {
const response = await request(app)
.get('/greet/John')
.expect(200);

expect(response.text).toBe('Hello John, welcome to my server!');
});

// Second request and assertion with different input
it('should greet person by name - test with "Sarah"', async () => {
const response = await request(app)
.get('/greet/Sarah')
.expect(200);

expect(response.text).toBe('Hello Sarah, welcome to my server!');
});

// Additional test with special characters
it('should handle names with spaces and special characters', async () => {
const response = await request(app)
.get('/greet/Mary Jane')
.expect(200);

expect(response.text).toBe('Hello Mary Jane, welcome to my server!');
});
});

// Test for favorite endpoint (/favorite) - Required Test #3
describe('GET /favorite', () => {
// First request and assertion - with query string
it('should return favorite thing when fave query is provided', async () => {
const response = await request(app)
.get('/favorite?fave=eating')
.expect(200);

expect(response.text).toBe('My favorite thing is eating');
});

// Second request and assertion - with different query string
it('should handle different favorite things', async () => {
const response = await request(app)
.get('/favorite?fave=coding')
.expect(200);

expect(response.text).toBe('My favorite thing is coding');
});

// Test what happens when query string is missing
it('should return sensible message when fave query is missing', async () => {
const response = await request(app)
.get('/favorite')
.expect(200);

expect(response.text).toBe('Please tell me your favorite thing by adding ?fave=something to the URL');
});

// Additional test with empty query parameter
it('should handle empty fave query parameter', async () => {
const response = await request(app)
.get('/favorite?fave=')
.expect(200);

expect(response.text).toBe('My favorite thing is ');
});

// Test with multiple query parameters (only fave should be used)
it('should only use fave parameter when multiple queries provided', async () => {
const response = await request(app)
.get('/favorite?fave=music&other=ignored')
.expect(200);

expect(response.text).toBe('My favorite thing is music');
});
});

// Bonus tests for extra challenge endpoint
describe('GET /favorites (Extra Challenge)', () => {
it('should handle multiple query parameters', async () => {
const response = await request(app)
.get('/favorites?color=orange&food=stew')
.expect(200);

expect(response.text).toBe('My favorite color is orange. My favorite food is stew.');
});

it('should handle single query parameter', async () => {
const response = await request(app)
.get('/favorites?animal=cat')
.expect(200);

expect(response.text).toBe('My favorite animal is cat.');
});

it('should handle three query parameters', async () => {
const response = await request(app)
.get('/favorites?color=blue&sport=soccer&season=summer')
.expect(200);

expect(response.text).toBe('My favorite color is blue. My favorite sport is soccer. My favorite season is summer.');
});

it('should return helpful message when no query parameters provided', async () => {
const response = await request(app)
.get('/favorites')
.expect(200);

expect(response.text).toBe('Please tell me your favorites by adding query parameters like ?color=blue&food=pizza');
});
});

});
Loading