Skip to content

Commit

Permalink
Mongodb setup bug + tests (PalisadoesFoundation#2257)
Browse files Browse the repository at this point in the history
* Refactor MongoDB.ts to use existingMongoDbUrls variable instead of an array

* added tests

* clear mock after each

* .

* Update schema.graphql

* Update schema.graphql

* Update schema.graphql

* Update schema.graphql

* Update pre-commit

* Revert "Update pre-commit"

This reverts commit 6134b5a.

* Update pre-commit

* comment
  • Loading branch information
pranshugupta54 authored Apr 29, 2024
1 parent 107780b commit 85c2684
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 32 deletions.
13 changes: 11 additions & 2 deletions setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,17 @@ export async function superAdmin(): Promise<void> {

// Get the mongodb url
/**
* The `mongoDB` function connects to a MongoDB database by asking for a URL, checking the connection,
* and updating the environment variable with the URL.
* The `mongoDB` function manages the connection to a MongoDB database.
* It performs the following steps:
* 1. Checks if there is an existing MongoDB URL in the environment variables.
* 2. If an existing URL is found, it attempts to establish a connection to the URL.
* - If the connection is successful, it returns the URL.
* - If the connection fails, it returns null.
* 3. If a URL is returned from the previous step (i.e., a successful connection was made), it prompts the user to either keep the existing URL or change it.
* 4. If null is returned from the previous step (i.e., no successful connection was made), it prompts the user to enter a new MongoDB URL.
* 5. It then enters a loop where it continues to prompt the user for a MongoDB URL until a successful connection can be made.
* 6. Once a successful connection is made, it saves the MongoDB URL to the environment variables.
* This function is part of the initial setup process and is designed to ensure a valid MongoDB connection before proceeding.
*/
export async function mongoDB(): Promise<void> {
let DB_URL = process.env.MONGO_DB_URL;
Expand Down
61 changes: 33 additions & 28 deletions src/setup/MongoDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,45 @@ import inquirer from "inquirer";
import { MongoClient } from "mongodb";

/**
* Function to check if Existing MongoDB instance is running
* The function `checkExistingMongoDB` checks for an existing MongoDB connection by iterating through a
* list of URLs and testing the connection using the `checkConnection` function.
* @returns The function `checkExistingMongoDB` returns a promise that resolves to a string or null.
* The `checkExistingMongoDB` function checks for an existing MongoDB URL in the environment variables and attempts to establish a connection.
*
* It performs the following steps:
* 1. Retrieves the MongoDB URL from the environment variables.
* 2. If no URL is found, it immediately returns null.
* 3. If a URL is found, it attempts to establish a connection using the `checkConnection` function.
* - If the connection is successful (i.e., `checkConnection` returns true), it returns the URL.
* - If the connection fails (i.e., `checkConnection` returns false), it returns null.
*
* This function is used during the initial setup process to check if a valid MongoDB connection can be made with the existing URL in the environment variables.
* @returns A promise that resolves to a string (if a connection could be made to the existing URL) or null (if no existing URL or connection could not be made).
*/
export async function checkExistingMongoDB(): Promise<string | null> {
const existingMongoDbUrls = [
process.env.MONGO_DB_URL,
"mongodb://localhost:27017",
];
const existingMongoDbUrls = process.env.MONGO_DB_URL;

for (const url of existingMongoDbUrls) {
if (!url) {
continue;
}

const isConnected = await checkConnection(url);
if (isConnected) {
return url;
}
if (!existingMongoDbUrls) {
return null;
}

return null;
const isConnected = await checkConnection(existingMongoDbUrls);
if (isConnected) {
return existingMongoDbUrls;
} else return null;
}

// Check the connection to MongoDB with the specified URL.
/**
* The function `checkConnection` is an asynchronous function that checks the connection to a MongoDB
* database using the provided URL and returns a boolean value indicating whether the connection was
* successful or not.
* @param url - The `url` parameter is a string that represents the connection URL for the
* MongoDB server. It typically includes the protocol (e.g., `mongodb://`), the host and port
* information, and any authentication credentials if required.
* @returns a Promise that resolves to a boolean value. The boolean value indicates whether the
* connection to the MongoDB server was successful (true) or not (false).
* The `checkConnection` function attempts to establish a connection to a MongoDB instance using a provided URL.
*
* @param url - The MongoDB connection URL.
* @returns A promise that resolves to a boolean indicating whether the connection was successful (true) or not (false).
*
* It performs the following steps:
* 1. Tries to establish a connection to the MongoDB instance using the provided URL with a server selection timeout of 1000 milliseconds.
* 2. If the connection is successful, it closes the connection and returns true.
* 3. If the connection fails, it logs an error message and returns false.
* - If the error is an instance of the Error class, it logs the error message.
* - If the error is not an instance of the Error class, it logs a generic error message and the error itself.
*
* This function is used during the initial setup process to test the MongoDB connection.
*/
export async function checkConnection(url: string): Promise<boolean> {
console.log("\nChecking MongoDB connection....");
Expand All @@ -54,6 +58,7 @@ export async function checkConnection(url: string): Promise<boolean> {
);
} else {
console.log(`\nConnection to MongoDB failed. Please try again.\n`);
console.log(error);
}
return false;
}
Expand All @@ -71,7 +76,7 @@ export async function askForMongoDBUrl(): Promise<string> {
type: "input",
name: "url",
message: "Enter your MongoDB URL:",
default: process.env.MONGO_DB_URL,
default: "mongodb://localhost:27017",
},
]);

Expand Down
62 changes: 60 additions & 2 deletions tests/setup/checkExistingMongoDB.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,66 @@
import { expect, it, describe } from "vitest";
import { checkExistingMongoDB } from "../../src/setup/MongoDB";
import { expect, it, describe, vi, afterEach } from "vitest";
import { checkConnection, checkExistingMongoDB } from "../../src/setup/MongoDB";
import { MongoClient } from "mongodb";

describe("Setup -> checkExistingMongoDB", () => {
afterEach(() => {
// Clear all mocks after each test
vi.restoreAllMocks();
});
it("should return the first valid URL when a connection is found", async () => {
const result = await checkExistingMongoDB();
expect(result).toBe(process.env.MONGO_DB_URL);
});

it("should return null if MONGO_DB_URL is not set", async () => {
process.env.MONGO_DB_URL = "";
const result = await checkExistingMongoDB();
expect(result).toBeNull();
});

it("should return null if checkConnection returns false", async () => {
// Set the environment variable
process.env.MONGO_DB_URL = "mongodb://testUrl";

// Spy on the checkConnection function to return false
vi.spyOn(MongoClient, "connect").mockImplementation(() => {
throw new Error("Test error");
});

// Call the function
const result = await checkExistingMongoDB();

// Check that the result is null
expect(result).toBeNull();
});

it("should return false and log error when connection fails", async () => {
// Spy on the MongoClient.connect function to throw an error
vi.spyOn(MongoClient, "connect").mockImplementation(() => {
throw new Error("Test error");
});

// Call the function with a test URL
const result = await checkConnection("mongodb://testUrl");

// Check that the result is false
expect(result).toBe(false);
});

it("should return false and log error when connection fails with unknown error type", async () => {
// Spy on the MongoClient.connect function to throw an Non-Error
vi.spyOn(MongoClient, "connect").mockImplementation(() => {
throw "Test error";
});

// Call the function with a test URL
const result = await checkConnection("mongodb://testUrl");

// Check that the result is false
expect(result).toBe(false);
});
it("should return the first valid URL when a connection is found", async () => {
process.env.MONGO_DB_URL = "mongodb://localhost:27017/talawa-api";
const result = await checkExistingMongoDB();
expect(result).toBe(process.env.MONGO_DB_URL);
});
Expand Down

0 comments on commit 85c2684

Please sign in to comment.