Skip to content

Commit

Permalink
Merge branch 'develop' into api_fail_docker
Browse files Browse the repository at this point in the history
  • Loading branch information
prayanshchh authored Dec 21, 2024
2 parents 338a7b8 + 039b0f1 commit bb63fc2
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 18 deletions.
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
"rimraf": "^6.0.1",
"supertest": "^7.0.0",
"tsx": "^4.19.1",
"typescript": "^5.5.4",
"typescript": "^5.6.2",
"vitest": "^2.1.3"
},
"overrides": {
Expand Down
51 changes: 41 additions & 10 deletions setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fs from "fs";
import inquirer from "inquirer";
import path from "path";
import type { ExecException } from "child_process";
import { exec, spawn } from "child_process";
import { exec, spawn, execSync } from "child_process";
import { MongoClient } from "mongodb";
import { MAXIMUM_IMAGE_SIZE_LIMIT_KB } from "./src/constants";
import {
Expand Down Expand Up @@ -466,6 +466,25 @@ export async function mongoDB(): Promise<void> {
For Docker setup
*/

function getDockerComposeCommand(): { command: string; args: string[] } {
let dockerComposeCmd = "docker-compose"; // Default to v1
let args = ["-f", "docker-compose.dev.yaml", "up", "--build", "-d"];

try {
// Test if 'docker compose' works (v2)
execSync("docker compose version", { stdio: "ignore" });
dockerComposeCmd = "docker";
args = ["compose", ...args]; // Prefix 'compose' for v2
} catch (error) {
console.log(error);
dockerComposeCmd =
process.platform === "win32" ? "docker-compose.exe" : "docker-compose";
}

return { command: dockerComposeCmd, args };
}

const DOCKER_COMPOSE_TIMEOUT_MS = 300000;
async function runDockerComposeWithLogs(): Promise<void> {
// Check if Docker daemon is running
try {
Expand All @@ -479,35 +498,47 @@ async function runDockerComposeWithLogs(): Promise<void> {
dockerCheck.on("close", (code) =>
code === 0
? resolve(null)
: reject(new Error("Docker daemon not running")),
: reject(
new Error(
"Docker daemon not running. Please ensure Docker Desktop is running and try again.",
),
),
);
});
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(
`Docker daemon is not running. Please start Docker and try again. Details: ${errorMessage}`,
`Docker daemon check failed. Please ensure:
1. Docker Desktop is installed and running
2. You have necessary permissions
3. Docker service is healthy
Details: ${errorMessage}`,
);
}

return new Promise((resolve, reject) => {
const { command, args } = getDockerComposeCommand();
let isCompleted = false;

const dockerCompose = spawn(command, args, { stdio: "inherit" });

const timeout = setTimeout(() => {
if (isCompleted) return;
dockerCompose.kill();
reject(new Error("Docker compose operation timed out after 5 minutes"));
}, 300000);

const dockerCompose = spawn(
process.platform === "win32" ? "docker-compose.exe" : "docker-compose",
["-f", "docker-compose.dev.yaml", "up", "--build", "-d"],
{ stdio: "inherit" },
);
}, DOCKER_COMPOSE_TIMEOUT_MS);

dockerCompose.on("error", (error) => {
if (isCompleted) return;
isCompleted = true;
clearTimeout(timeout);
console.error("Error running docker-compose:", error);
reject(error);
});

dockerCompose.on("close", (code) => {
if (isCompleted) return;
isCompleted = true;
clearTimeout(timeout);
if (code === 0) {
console.log("Docker Compose completed successfully.");
Expand Down
2 changes: 1 addition & 1 deletion src/resolvers/Mutation/createVenue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const createVenue: MutationResolvers["createVenue"] = async (
}

// Check if the venue name provided is an empty string.
if (!args.data?.name ?? "") {
if (!(args.data?.name ?? "")) {
throw new errors.InputValidationError(
requestContext.translate(VENUE_NAME_MISSING_ERROR.MESSAGE),
VENUE_NAME_MISSING_ERROR.CODE,
Expand Down
2 changes: 1 addition & 1 deletion src/typeDefs/unions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// import { gql } from "graphql-tag";

// // Place fields alphabetically to ensure easier lookup and navigation.
// Place fields alphabetically to ensure easier lookup and navigation.
// export const unions = gql``;
76 changes: 76 additions & 0 deletions tests/resolvers/Mutation/createVenue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,82 @@ describe("resolvers -> Mutation -> createVenue", () => {
}
});

it(`throws InputValidationError if the venue name is undefined`, async () => {
try {
await Organization.findByIdAndUpdate(
{
_id: testOrganization?._id,
},
{
$push: {
admins: [testUser?.id],
},
},
);

const args: MutationCreateVenueArgs = {
data: {
capacity: 10,
name: undefined as unknown as string,
organizationId: testOrganization?.id,
},
};

const context = {
userId: testUser?.id,
};

const { createVenue } = await import(
"../../../src/resolvers/Mutation/createVenue"
);
await createVenue?.({}, args, context);
} catch (error: unknown) {
if (error instanceof InputValidationError) {
expect(error.message).toEqual(VENUE_NAME_MISSING_ERROR.MESSAGE);
} else {
fail(`Expected InputValidationError, but got ${error}`);
}
}
});

it(`throws InputValidationError if the venue name is null`, async () => {
try {
await Organization.findByIdAndUpdate(
{
_id: testOrganization?._id,
},
{
$push: {
admins: [testUser?.id],
},
},
);

const args: MutationCreateVenueArgs = {
data: {
capacity: 10,
name: null as unknown as string,
organizationId: testOrganization?.id,
},
};

const context = {
userId: testUser?.id,
};

const { createVenue } = await import(
"../../../src/resolvers/Mutation/createVenue"
);
await createVenue?.({}, args, context);
} catch (error: unknown) {
if (error instanceof InputValidationError) {
expect(error.message).toEqual(VENUE_NAME_MISSING_ERROR.MESSAGE);
} else {
fail(`Expected InputValidationError, but got ${error}`);
}
}
});

it(`throws ConflictError if a venue with same place already exists in the organization`, async () => {
try {
const args: MutationCreateVenueArgs = {
Expand Down
1 change: 1 addition & 0 deletions tests/resolvers/Query/getVolunteerRanks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ describe("resolvers -> Query -> getVolunteerRanks", () => {
},
{},
)) as unknown as VolunteerRank[];

expect(volunteerRanks[0].hoursVolunteered).toEqual(6);
expect(volunteerRanks[0].user._id).toEqual(testUser1?._id);
expect(volunteerRanks[0].rank).toEqual(1);
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"strict": true /* Enable all strict type-checking options. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
"resolveJsonModule": true /* Allow to import JSON files */
"resolveJsonModule": true /* Allow to import JSON files */,
"noUncheckedSideEffectImports": true /* Checks if module's path exists. */
}
}

0 comments on commit bb63fc2

Please sign in to comment.