Skip to content

Commit

Permalink
Tests for src/resolvers/Mutations/addUserImage (#931)
Browse files Browse the repository at this point in the history
* 100% code coverage for addUserImage

* started tests for uploadImage.ts

* 100% test coverage for uploadImage.ts
  • Loading branch information
kb-0311 authored Jan 29, 2023
1 parent d76bef4 commit 078cfb4
Show file tree
Hide file tree
Showing 3 changed files with 317 additions and 48 deletions.
4 changes: 3 additions & 1 deletion src/utilities/uploadImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ export const uploadImage = async (

const newImagePath = `images/${id}-${filename}`;

if (oldImagePath) {
if (oldImagePath !== null) {
console.log("oldImagePath is not null");

logger.info("old image should be deleted");

// If user/organization already has an image delete it from the API
Expand Down
178 changes: 131 additions & 47 deletions tests/resolvers/Mutation/addUserImage.spec.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,45 @@
import "dotenv/config";
import {
// Document,
Types,
} from "mongoose";
// import { Interface_User, User } from "../../../src/models";
import { Document, Types } from "mongoose";
import { Interface_User, User } from "../../../src/models";
import { connect, disconnect } from "../../../src/db";
import { MutationAddUserImageArgs } from "../../../src/types/generatedGraphQLTypes";
import { addUserImage as addUserImageResolver } from "../../../src/resolvers/Mutation/addUserImage";
import { USER_NOT_FOUND } from "../../../src/constants";
// import { nanoid } from "nanoid";
import { beforeAll, afterAll, describe, it, expect } from "vitest";
import { USER_NOT_FOUND, USER_NOT_FOUND_MESSAGE } from "../../../src/constants";
import {
beforeAll,
afterAll,
describe,
it,
expect,
afterEach,
vi,
} from "vitest";
import { nanoid } from "nanoid";

// let testUser:Interface_User & Document<any, any, Interface_User>
let testUser: Interface_User & Document<any, any, Interface_User>;

beforeAll(async () => {
await connect();

// testUser = await User.create({
// email: `email${nanoid().toLowerCase()}@gmail.com`,
// password: "password",
// firstName: "firstName",
// lastName: "lastName",
// appLanguageCode: "en",
// });
testUser = await User.create({
email: `email${nanoid().toLowerCase()}@gmail.com`,
password: "password",
firstName: "firstName",
lastName: "lastName",
appLanguageCode: "en",
});
});

afterAll(async () => {
await disconnect();
});

describe("resolvers -> Mutation -> addUserImage", () => {
afterEach(() => {
vi.restoreAllMocks();
vi.doUnmock("../../../src/constants");
vi.resetModules();
});
it(`throws NotFoundError if no user exists with _id === context.userId`, async () => {
try {
const args: MutationAddUserImageArgs = {
Expand All @@ -45,36 +55,110 @@ describe("resolvers -> Mutation -> addUserImage", () => {
expect(error.message).toEqual(USER_NOT_FOUND);
}
});
it(`throws NotFoundError if no user exists with _id === context.userId // IN_PRODUCTION=true`, async () => {
const { requestContext } = await import("../../../src/libraries");

const spy = vi
.spyOn(requestContext, "translate")
.mockImplementationOnce((message) => `Translated ${message}`);

try {
const args: MutationAddUserImageArgs = {
file: "",
};

const context = {
userId: Types.ObjectId().toString(),
};

// it(`sets image field to null for organization with _id === args.organizationId
// and returns the updated organization`, async () => {
// await User.updateOne(
// {
// _id: testUser._id,
// },
// {
// $set: {
// image: 'image',
// },
// }
// );

// const args: MutationAddUserImageArgs = {
// file: '',
// };

// const context = {
// userId: testUser._id,
// };

// const addUserImagePayload = await addUserImageResolver?.({}, args, context);

// const updatedTestUser = await User.findOne({
// _id: testUser._id,
// }).lean();

// expect(addUserImagePayload).toEqual(updatedTestUser);

// expect(addUserImagePayload?.image).toEqual(null);
// });
vi.doMock("../../../src/constants", async () => {
const actualConstants: object = await vi.importActual(
"../../../src/constants"
);
return {
...actualConstants,
IN_PRODUCTION: true,
};
});
const { addUserImage: addUserImageResolverUserError } = await import(
"../../../src/resolvers/Mutation/addUserImage"
);
await addUserImageResolverUserError?.({}, args, context);
} catch (error: any) {
expect(spy).toHaveBeenLastCalledWith(USER_NOT_FOUND_MESSAGE);
expect(error.message).toEqual(`Translated ${USER_NOT_FOUND_MESSAGE}`);
}
});
it(`When Image is given, updates current user's user object and returns the object when Image is in DB path`, async () => {
const uploadImage = await import("../../../src/utilities");

const spy = vi
.spyOn(uploadImage, "uploadImage")
.mockImplementationOnce(async () => {
return {
newImagePath: "newImagePath",
imageAlreadyInDbPath: "imageAlreadyInDbPath",
};
});

const args: MutationAddUserImageArgs = {
file: "newImageFile.png",
};

const context = {
userId: testUser._id,
};

const { addUserImage: addUserImageResolverUserError } = await import(
"../../../src/resolvers/Mutation/addUserImage"
);
const addUserImagePayload = await addUserImageResolverUserError?.(
{},
args,
context
);

expect(spy).toHaveBeenCalledTimes(1);
expect(addUserImagePayload).toEqual({
...testUser.toObject(),

image: "imageAlreadyInDbPath",
});
});
it(`When Image is given, updates current user's user object and returns the object when Image is not in DB path`, async () => {
const uploadImage = await import("../../../src/utilities");

const spy = vi
.spyOn(uploadImage, "uploadImage")
.mockImplementationOnce(async () => {
return {
newImagePath: "newImagePath",
imageAlreadyInDbPath: "",
};
});

const args: MutationAddUserImageArgs = {
file: "newImageFile.png",
};

const context = {
userId: testUser._id,
};

const { addUserImage: addUserImageResolverUserError } = await import(
"../../../src/resolvers/Mutation/addUserImage"
);
const addUserImagePayload = await addUserImageResolverUserError?.(
{},
args,
context
);

expect(spy).toHaveBeenCalledTimes(1);
expect(addUserImagePayload).toEqual({
...testUser.toObject(),

image: "newImagePath",
});
});
});
183 changes: 183 additions & 0 deletions tests/utilities/uploadImage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
require("dotenv").config();
import { nanoid } from "nanoid";
import fs from "fs";
import {
afterAll,
afterEach,
beforeAll,
describe,
expect,
it,
vi,
} from "vitest";
import { connect, disconnect } from "../../src/db";
import { Interface_User, User } from "../../src/models";
import { Document } from "mongoose";
import path from "path";

let testUser: Interface_User & Document<any, any, Interface_User>;

beforeAll(async () => {
await connect();

testUser = await User.create({
email: `email${nanoid().toLowerCase()}@gmail.com`,
password: "password",
firstName: "firstName",
lastName: "lastName",
appLanguageCode: "en",
});
fs.mkdir(path.join(__dirname, "../../src/images"), (err) => {
if (err) {
throw err;
}
});
const img =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0" +
"NAAAAKElEQVQ4jWNgYGD4Twzu6FhFFGYYNXDUwGFpIAk2E4dHDRw1cDgaCAASFOffhEIO" +
"3gAAAABJRU5ErkJggg==";
const data = img.replace(/^data:image\/\w+;base64,/, "");
const buf = Buffer.from(data, "base64");
await fs.writeFile(
path.join(__dirname, "../../src/images/image.png"),
buf,
(error) => {
if (error) console.log(error);
}
);
});

afterAll(async () => {
fs.unlink(path.join(__dirname, "../../src/images/image.png"), (err) => {
if (err) throw err;
});
fs.rm(
path.join(__dirname, "../../src/images"),
{ recursive: true },
(err) => {
if (err) {
throw err;
}
}
);
await disconnect();
});

describe("utilities -> uploadImage", () => {
afterEach(async () => {
vi.resetModules();
vi.restoreAllMocks();
});

it("should create a new Image", async () => {
const pngImage: any = {
filename: "image.png",
createReadStream: () => {
return fs.createReadStream(
path.join(__dirname, "../../src/images/image.png")
);
},
};

const imageAlreadyInDbFile = await import(
"../../src/utilities/imageAlreadyInDbCheck"
);

const mockedImageAlreadyInDb = vi
.spyOn(imageAlreadyInDbFile, "imageAlreadyInDbCheck")
.mockImplementation(
async (oldImagePath: string | null, newImagePath: string) => {
console.log(oldImagePath, newImagePath);

return "";
}
);

const { uploadImage } = await import("../../src/utilities/uploadImage");

const uploadImagePayload = await uploadImage(pngImage, null);

const testUserObj = await User.findByIdAndUpdate(
{
_id: testUser.id,
},
{
$set: {
image: uploadImagePayload.newImagePath,
},
},
{
new: true,
}
).lean();

expect(mockedImageAlreadyInDb).toHaveBeenCalledWith(
null,
testUserObj?.image
);
expect(uploadImagePayload?.newImagePath).toEqual(testUserObj?.image);
});

it("should create a new Image when an old Image Path already Exists", async () => {
const pngImage: any = {
filename: "image.png",
createReadStream: () => {
return fs.createReadStream(
path.join(__dirname, "../../src/images/image.png")
);
},
};

const imageAlreadyInDbFile = await import(
"../../src/utilities/imageAlreadyInDbCheck"
);

const mockedImageAlreadyInDb = vi
.spyOn(imageAlreadyInDbFile, "imageAlreadyInDbCheck")
.mockImplementation(
async (oldImagePath: string | null, newImagePath: string) => {
console.log(oldImagePath, newImagePath);

return newImagePath;
}
);

const { uploadImage } = await import("../../src/utilities/uploadImage");

const testUserBeforeObj = await User.findById({
_id: testUser.id,
});
const oldImagePath = testUserBeforeObj?.image!;
console.log(oldImagePath);

const deleteDuplicatedImage = await import(
"../../src/utilities/deleteImage"
);

const mockedDeleteImage = vi
.spyOn(deleteDuplicatedImage, "deleteImage")
.mockImplementation(async () => {});

const uploadImagePayload = await uploadImage(pngImage, oldImagePath);

const testUserObj = await User.findByIdAndUpdate(
{
_id: testUser.id,
},
{
$set: {
image: uploadImagePayload.newImagePath,
},
},
{
new: true,
}
).lean();
expect(mockedDeleteImage).toBeCalledWith(oldImagePath, testUserObj?.image);
expect(mockedImageAlreadyInDb).toHaveBeenCalledWith(
oldImagePath,
testUserObj?.image
);
expect(uploadImagePayload?.newImagePath).toEqual(testUserObj?.image);
});
});

0 comments on commit 078cfb4

Please sign in to comment.