Skip to content
Merged
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
33 changes: 33 additions & 0 deletions .github/workflows/server-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Server Tests

on:
push:
branches:
- main
paths:
- "server/**"
- ".github/workflows/server-tests.yml"
pull_request:
branches:
- main
paths:
- "server/**"
- ".github/workflows/server-tests.yml"

jobs:
test-server:
runs-on: ubuntu-latest
container:
image: node:18 # Specify the Node.js container image

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install dependencies in server directory
run: npm ci
working-directory: ./server

- name: Run tests in server directory
run: npm test
working-directory: ./server
12 changes: 12 additions & 0 deletions server/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
node: "current",
},
},
],
],
};
11 changes: 9 additions & 2 deletions server/config/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ const connectDB = async () => {
const conn = await mongoose.connect(`${dbURI}${dbName}`);
console.log(`MongoDB Connected: ${conn.connection.host}`);
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
console.error(`Error connecting to MongoDB: ${error.message}`);
// Exit process only if not in test environment
if (process.env.NODE_ENV !== "test") {
process.exit(1);
}
// Optional: If in test, maybe throw the error so tests can catch it if needed
// else {
// throw error;
// }
}
};

Expand Down
104 changes: 74 additions & 30 deletions server/config/redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,43 @@ let redisClient;
let redisEnabled = false;

try {
// *** ADD CHECK FOR TEST ENVIRONMENT ***
if (process.env.NODE_ENV === "test") {
console.log("Skipping Redis initialization in test environment.");
redisEnabled = false;
redisReadyPromise = Promise.resolve(false);
// Create dummy client immediately
redisClient = {
get: () => Promise.resolve(null),
set: () => Promise.resolve("OK"),
setex: () => Promise.resolve("OK"),
del: () => Promise.resolve(0),
exists: () => Promise.resolve(0),
expire: () => Promise.resolve(1),
flushall: () => Promise.resolve("OK"),
info: () => Promise.resolve(""),
dbsize: () => Promise.resolve(0),
pipeline: () => ({ del: () => ({}), exec: () => Promise.resolve([]) }),
connect: () => Promise.resolve(),
quit: () => Promise.resolve(),
scanStream: () => {
// Create a dummy event emitter that emits no data and ends immediately
const emitter = new EventEmitter();
setTimeout(() => {
emitter.emit("data", []);
emitter.emit("end");
}, 0);
return emitter;
},
on: () => {}, // Add dummy 'on' to prevent errors if called
removeAllListeners: () => {}, // Add dummy removeAllListeners
};
// Throw a dummy error to bypass the rest of the try block cleanly
// (This is a simple way to exit the try block early)
throw new Error("TEST_ENV_SKIP");
}
// *** END CHECK ***

console.log("Initializing Redis client...");

// Determine connection options
Expand Down Expand Up @@ -68,36 +105,43 @@ try {
}
}, 5000);
} catch (error) {
console.error("Failed to initialize Redis client:", error);
// Create a promise that resolves to false
redisReadyPromise = Promise.resolve(false);
// Create a dummy client to prevent app crashes if Redis is unavailable
redisClient = {
get: () => Promise.resolve(null),
set: () => Promise.resolve("OK"),
setex: () => Promise.resolve("OK"),
del: () => Promise.resolve(0),
exists: () => Promise.resolve(0),
expire: () => Promise.resolve(1),
flushall: () => Promise.resolve("OK"),
info: () => Promise.resolve(""),
dbsize: () => Promise.resolve(0),
pipeline: () => ({
del: () => ({}),
exec: () => Promise.resolve([]),
}),
connect: () => Promise.resolve(),
quit: () => Promise.resolve(),
scanStream: () => {
// Create a dummy event emitter that emits no data and ends immediately
const emitter = new EventEmitter();
setTimeout(() => {
emitter.emit("data", []);
emitter.emit("end");
}, 0);
return emitter;
},
};
// Catch the dummy error specifically, otherwise handle real errors
if (error.message !== "TEST_ENV_SKIP") {
console.error("Failed to initialize Redis client:", error);
// Ensure dummy client is created on real errors too
if (!redisClient) {
redisReadyPromise = Promise.resolve(false);
redisClient = {
get: () => Promise.resolve(null),
set: () => Promise.resolve("OK"),
setex: () => Promise.resolve("OK"),
del: () => Promise.resolve(0),
exists: () => Promise.resolve(0),
expire: () => Promise.resolve(1),
flushall: () => Promise.resolve("OK"),
info: () => Promise.resolve(""),
dbsize: () => Promise.resolve(0),
pipeline: () => ({
del: () => ({}),
exec: () => Promise.resolve([]),
}),
connect: () => Promise.resolve(),
quit: () => Promise.resolve(),
scanStream: () => {
// Create a dummy event emitter that emits no data and ends immediately
const emitter = new EventEmitter();
setTimeout(() => {
emitter.emit("data", []);
emitter.emit("end");
}, 0);
return emitter;
},
on: () => {}, // Add dummy 'on' to prevent errors if called
removeAllListeners: () => {}, // Add dummy removeAllListeners
};
}
}
// If it was the TEST_ENV_SKIP error, we've already set up the dummy client.
}

// Wait for Redis connection before continuing
Expand Down
Loading