diff --git a/src/resolvers/Mutation/updateUserProfile.ts b/src/resolvers/Mutation/updateUserProfile.ts index d6844af867..f6c6fceae2 100644 --- a/src/resolvers/Mutation/updateUserProfile.ts +++ b/src/resolvers/Mutation/updateUserProfile.ts @@ -57,7 +57,7 @@ export const updateUserProfile: MutationResolvers["updateUserProfile"] = async ( } // Update User - const updatedUser = await User.findOneAndUpdate( + let updatedUser = await User.findOneAndUpdate( { _id: context.userId, }, @@ -128,9 +128,13 @@ export const updateUserProfile: MutationResolvers["updateUserProfile"] = async ( runValidators: true, }, ).lean(); - updatedUser!.image = updatedUser?.image - ? `${context.apiRootUrl}${updatedUser?.image}` - : null; + + if (updatedUser != null) { + updatedUser.image = updatedUser?.image + ? `${context.apiRootUrl}${updatedUser?.image}` + : null; + } + if (args.data == undefined) updatedUser = null; return updatedUser ?? ({} as InterfaceUser); }; diff --git a/tests/resolvers/Mutation/updateUserProfile.spec.ts b/tests/resolvers/Mutation/updateUserProfile.spec.ts index 846026af4a..201c0c2729 100644 --- a/tests/resolvers/Mutation/updateUserProfile.spec.ts +++ b/tests/resolvers/Mutation/updateUserProfile.spec.ts @@ -26,13 +26,18 @@ import { } from "vitest"; let MONGOOSE_INSTANCE: typeof mongoose; -let testUser: InterfaceUser & Document; -let testUser2: InterfaceUser & Document; + +type UserDocument = InterfaceUser & + Document, InterfaceUser>; +let testUser: UserDocument; +let testUser2: UserDocument; vi.mock("../../utilities/uploadEncodedImage", () => ({ uploadEncodedImage: vi.fn(), })); const email = `email${nanoid().toLowerCase()}@gmail.com`; +const date = new Date("2002-03-04T18:30:00.000Z"); + beforeAll(async () => { MONGOOSE_INSTANCE = await connect(); @@ -43,6 +48,7 @@ beforeAll(async () => { lastName: "lastName", appLanguageCode: "en", gender: null, + image: null, birthDate: null, educationGrade: null, employmentStatus: null, @@ -107,11 +113,13 @@ describe("resolvers -> Mutation -> updateUserProfile", () => { ); await updateUserProfileResolver?.({}, args, context); - } catch (error: any) { - expect(spy).toHaveBeenCalledWith(USER_NOT_FOUND_ERROR.MESSAGE); - expect(error.message).toEqual( - `Translated ${USER_NOT_FOUND_ERROR.MESSAGE}`, - ); + } catch (error) { + if (error instanceof Error) { + expect(spy).toHaveBeenCalledWith(USER_NOT_FOUND_ERROR.MESSAGE); + expect(error.message).toEqual( + `Translated ${USER_NOT_FOUND_ERROR.MESSAGE}`, + ); + } } }); @@ -135,11 +143,13 @@ describe("resolvers -> Mutation -> updateUserProfile", () => { await import("../../../src/resolvers/Mutation/updateUserProfile"); await updateUserProfileResolverUserError?.({}, args, context); - } catch (error: any) { - expect(spy).toHaveBeenLastCalledWith(USER_NOT_FOUND_ERROR.MESSAGE); - expect(error.message).toEqual( - `Translated ${USER_NOT_FOUND_ERROR.MESSAGE}`, - ); + } catch (error) { + if (error instanceof Error) { + expect(spy).toHaveBeenLastCalledWith(USER_NOT_FOUND_ERROR.MESSAGE); + expect(error.message).toEqual( + `Translated ${USER_NOT_FOUND_ERROR.MESSAGE}`, + ); + } } }); @@ -166,41 +176,15 @@ describe("resolvers -> Mutation -> updateUserProfile", () => { ); await updateUserProfileResolver?.({}, args, context); - } catch (error: any) { - expect(spy).toHaveBeenLastCalledWith(EMAIL_ALREADY_EXISTS_ERROR.MESSAGE); - expect(error.message).toEqual( - `Translated ${EMAIL_ALREADY_EXISTS_ERROR.MESSAGE}`, - ); - } - }); - - it(`throws ConflictError if args.data.email is already registered for another user`, async () => { - const { requestContext } = await import("../../../src/libraries"); - - const spy = vi - .spyOn(requestContext, "translate") - .mockImplementationOnce((message) => `Translated ${message}`); - - try { - const args: MutationUpdateUserProfileArgs = { - data: { - email: testUser.email, - }, - }; - - const context = { - userId: testUser._id, - }; - - const { updateUserProfile: updateUserProfileResolverEmailError } = - await import("../../../src/resolvers/Mutation/updateUserProfile"); - - await updateUserProfileResolverEmailError?.({}, args, context); - } catch (error: any) { - expect(spy).toHaveBeenLastCalledWith(EMAIL_ALREADY_EXISTS_ERROR.MESSAGE); - expect(error.message).toEqual( - `Translated ${EMAIL_ALREADY_EXISTS_ERROR.MESSAGE}`, - ); + } catch (error) { + if (error instanceof Error) { + expect(spy).toHaveBeenLastCalledWith( + EMAIL_ALREADY_EXISTS_ERROR.MESSAGE, + ); + expect(error.message).toEqual( + `Translated ${EMAIL_ALREADY_EXISTS_ERROR.MESSAGE}`, + ); + } } }); @@ -317,17 +301,19 @@ describe("resolvers -> Mutation -> updateUserProfile", () => { }); }); - it(`updates current user's user object and returns the object`, async () => { + it("When Image is give updates the current user's object with the uploaded image and returns it", async () => { const args: MutationUpdateUserProfileArgs = { - data: { - email: `email${nanoid().toLowerCase()}@gmail.com`, - firstName: "newFirstName", - lastName: "newLastName", - }, + data: {}, + file: "newImageFile.png", }; + vi.spyOn(uploadEncodedImage, "uploadEncodedImage").mockImplementation( + async (encodedImageURL: string) => encodedImageURL, + ); + const context = { userId: testUser._id, + apiRootUrl: BASE_URL, }; const updateUserProfilePayload = await updateUserProfileResolver?.( @@ -338,10 +324,10 @@ describe("resolvers -> Mutation -> updateUserProfile", () => { expect(updateUserProfilePayload).toEqual({ ...testUser.toObject(), - email: args.data?.email, + email: updateUserProfilePayload?.email, firstName: "newFirstName", lastName: "newLastName", - image: null, + image: BASE_URL + "newImageFile.png", updatedAt: expect.anything(), createdAt: expect.anything(), }); @@ -377,14 +363,301 @@ describe("resolvers -> Mutation -> updateUserProfile", () => { email: args.data?.email, firstName: "newFirstName", lastName: "newLastName", + image: BASE_URL + args.file, + updatedAt: expect.anything(), + createdAt: expect.anything(), + }); + }); + + it(`updates current user's user object when any single argument(birthdate) is given w/0 changing other fields `, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + birthDate: date, + }, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + const testUserobj = await User.findById({ _id: testUser.id }); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: testUserobj?.email, + firstName: testUserobj?.firstName, + lastName: testUserobj?.lastName, image: BASE_URL + "newImageFile.png", + birthDate: args.data?.birthDate, updatedAt: expect.anything(), createdAt: expect.anything(), }); }); - it("When Image is give updates the current user's object with the uploaded image and returns it", async () => { + + it(`updates current user's user object when any single argument(EducationGrade) is given w/0 changing other fields `, async () => { const args: MutationUpdateUserProfileArgs = { - data: {}, + data: { + educationGrade: "GRADUATE", + }, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + const testUserobj = await User.findById({ _id: testUser.id }); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: testUserobj?.email, + firstName: testUserobj?.firstName, + lastName: testUserobj?.lastName, + image: BASE_URL + "newImageFile.png", + birthDate: date, + educationGrade: args.data?.educationGrade, + updatedAt: expect.anything(), + createdAt: expect.anything(), + }); + }); + + it(`updates current user's user object when any single argument(EmployementStatus) is given w/0 changing other fields `, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + employmentStatus: "FULL_TIME", + }, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + const testUserobj = await User.findById({ _id: testUser.id }); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: testUserobj?.email, + firstName: testUserobj?.firstName, + lastName: testUserobj?.lastName, + image: BASE_URL + "newImageFile.png", + birthDate: date, + educationGrade: "GRADUATE", + employmentStatus: args.data?.employmentStatus, + updatedAt: expect.anything(), + createdAt: expect.anything(), + }); + }); + + it(`updates current user's user object when any single argument(Gender) is given w/0 changing other fields `, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + gender: "FEMALE", + }, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + const testUserobj = await User.findById({ _id: testUser.id }); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: testUserobj?.email, + firstName: testUserobj?.firstName, + lastName: testUserobj?.lastName, + image: BASE_URL + "newImageFile.png", + birthDate: date, + educationGrade: "GRADUATE", + employmentStatus: "FULL_TIME", + gender: args.data?.gender, + updatedAt: expect.anything(), + createdAt: expect.anything(), + }); + }); + + it(`updates current user's user object when any single argument(MaritalStatus) is given w/0 changing other fields `, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + maritalStatus: "SINGLE", + }, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + const testUserobj = await User.findById({ _id: testUser.id }); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: testUserobj?.email, + firstName: testUserobj?.firstName, + lastName: testUserobj?.lastName, + image: BASE_URL + "newImageFile.png", + birthDate: date, + educationGrade: "GRADUATE", + employmentStatus: "FULL_TIME", + gender: "FEMALE", + maritalStatus: args.data?.maritalStatus, + updatedAt: expect.anything(), + createdAt: expect.anything(), + }); + }); + + it(`updates current user's user object when any single argument(PhoneNumber) is given w/0 changing other fields `, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + phone: { + home: "020 89024004", + mobile: "+91 1234567890", + work: "+31 1234567890", + }, + }, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + const testUserobj = await User.findById({ _id: testUser.id }); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: testUserobj?.email, + firstName: testUserobj?.firstName, + lastName: testUserobj?.lastName, + image: BASE_URL + "newImageFile.png", + birthDate: date, + educationGrade: "GRADUATE", + employmentStatus: "FULL_TIME", + gender: "FEMALE", + maritalStatus: "SINGLE", + phone: args.data?.phone, + updatedAt: expect.anything(), + createdAt: expect.anything(), + }); + }); + + it(`updates current user's user object when any single argument(address) is given w/0 changing other fields `, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + address: { + city: "CityName", + countryCode: "123", + dependentLocality: "345", + line1: "Street ABC", + line2: "Near XYZ Park", + postalCode: "45672", + sortingCode: "234", + state: "StateName", + }, + }, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + const testUserobj = await User.findById({ _id: testUser.id }); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: testUserobj?.email, + firstName: testUserobj?.firstName, + lastName: testUserobj?.lastName, + image: BASE_URL + "newImageFile.png", + birthDate: date, + educationGrade: "GRADUATE", + employmentStatus: "FULL_TIME", + gender: "FEMALE", + maritalStatus: "SINGLE", + address: args.data?.address, + phone: { + home: "020 89024004", + mobile: "+91 1234567890", + work: "+31 1234567890", + }, + updatedAt: expect.anything(), + createdAt: expect.anything(), + }); + }); + + it(`updates current user's user object and returns the object`, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + email: `email${nanoid().toLowerCase()}@gmail.com`, + firstName: "newFirstName", + lastName: "newLastName", + birthDate: date, + educationGrade: "GRADUATE", + employmentStatus: "FULL_TIME", + gender: "FEMALE", + maritalStatus: "SINGLE", + address: { + city: "CityName", + countryCode: "123", + dependentLocality: "345", + line1: "Street ABC", + line2: "Near XYZ Park", + postalCode: "45672", + sortingCode: "234", + state: "StateName", + }, + phone: { + home: "020 89024004", + mobile: "+91 1234567890", + work: "+31 1234567890", + }, + }, file: "newImageFile.png", }; @@ -405,12 +678,38 @@ describe("resolvers -> Mutation -> updateUserProfile", () => { expect(updateUserProfilePayload).toEqual({ ...testUser.toObject(), - email: updateUserProfilePayload?.email, - firstName: "newFirstName", - lastName: "newLastName", - image: BASE_URL + "newImageFile.png", + email: args.data?.email, + firstName: args.data?.firstName, + lastName: args.data?.lastName, + image: BASE_URL + args.file, + birthDate: date, + educationGrade: args.data?.educationGrade, + employmentStatus: args.data?.employmentStatus, + gender: args.data?.gender, + maritalStatus: args.data?.maritalStatus, + address: args.data?.address, + phone: args.data?.phone, updatedAt: expect.anything(), createdAt: expect.anything(), }); }); + + it(`if data is undefined dont update the profile`, async () => { + const args: MutationUpdateUserProfileArgs = { + data: undefined, + }; + + const context = { + userId: testUser._id, + apiRootUrl: BASE_URL, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context, + ); + + expect(updateUserProfilePayload).toEqual({}); + }); });