Skip to content

Commit

Permalink
feat(#303): Update user graphql queries and mutations
Browse files Browse the repository at this point in the history
  • Loading branch information
tholulomo committed Jun 19, 2023
1 parent ee340a1 commit 3547c7e
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 64 deletions.
84 changes: 55 additions & 29 deletions resfulservice/spec/graphql/resolver/contact.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,34 @@ const chai = require('chai');
const sinon = require('sinon');
const Contact = require('../../../src/models/contact')
const graphQlSchema = require('../../../src/graphql');
const { Mutation: { submitContact }, Query: { getUserContacts, contacts } } = require('../../../src/graphql/resolver');
const { mongoConn } = require("../../utils/mongo");
const { Mutation: { submitContact, updateContact }, Query: { getUserContacts, contacts } } = require('../../../src/graphql/resolver');
const { userRoles } = require('../../../config/constant');

const { expect } = chai;

mongoConn();
const mockContact = {
fullName: 'test user',
email: 'test@example.com',
purpose: 'QUESTION',
message: 'test message'
}

const mockUpdatedContact = {
...mockContact,
resolved: true,
response: "Thanks for reaching out. We are working on it",
}

describe('Contact Resolver Unit Tests:', function () {

afterEach(() => sinon.restore());

this.timeout(10000)

const input = {
...mockContact
contactId: 'akdn9wqkn',
resolved: mockUpdatedContact.resolved,
response: mockUpdatedContact.response,
}

const req = { logger: { info: (_message) => { }, error: (_message) => { } } }
Expand All @@ -35,7 +42,7 @@ describe('Contact Resolver Unit Tests:', function () {
});

it('should save new contact information', async () => {
sinon.stub(Contact.prototype, 'save').callsFake(() => ({...input, _id: 'akdn9wqkn'}))
sinon.stub(Contact.prototype, 'save').callsFake(() => ({...mockContact, _id: 'akdn9wqkn'}))

const contact = await submitContact({}, { input }, { req });

Expand All @@ -52,6 +59,47 @@ describe('Contact Resolver Unit Tests:', function () {
});
})

context('updateContact', () => {
it('should update a contact', async function () {
sinon.stub(Contact, 'findOne').returns(mockContact);
sinon.stub(Contact, 'findOneAndUpdate').returns(mockUpdatedContact);

const contact = await updateContact({}, { input: { ...input, } }, { req, user: { roles: userRoles.isAdmin }, isAuthenticated: true });
expect(contact).to.have.property('email');
expect(contact).to.have.property('resolved');
expect(contact).to.have.property('response');
expect(contact.resolved).to.equal(true);
});

it("should throw a 401, not authenticated error", async () => {

const error = await updateContact({}, { input }, { req, user: { isAdmin: false }, isAuthenticated: false });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(401);
});


it("should throw a 404, not authenticated error", async () => {
sinon.stub(Contact, 'findOne').returns(null);

const error = await updateContact({}, { input }, { req, user: { roles: userRoles.isAdmin }, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(404);
});

it('should throw a 500 error', async () => {
sinon.stub(Contact, 'findOne').throws();

const result = await updateContact({}, { input }, { req, user: { roles: userRoles.isAdmin }, isAuthenticated: true });

expect(result).to.have.property('extensions');
expect(result.extensions.code).to.be.equal(500)
});
})


context('getUserContacts', () => {
const mockUserContact = {
_id: 'akdn9wqkn',
Expand Down Expand Up @@ -92,28 +140,6 @@ describe('Contact Resolver Unit Tests:', function () {


context('contacts', () => {
it('should return paginated lists of contacts', async () => {
const mockContact = {
_id: 'akdn9wqkn',
fullName: 'test user',
email: 'test@example.com',
purpose: 'QUESTION',
message: 'test message',
skip: () => ({_id: 'akdn9wqkn', ...input }),
lean: () => ({_id: 'akdn9wqkn', ...input }),
limit: () => ({_id: 'akdn9wqkn', ...input })
}
sinon.stub(Contact, 'countDocuments').returns(1);
sinon.stub(Contact, 'find').returns(mockContact);
sinon.stub(mockContact, 'skip').returnsThis();
sinon.stub(mockContact, 'limit').returnsThis();
sinon.stub(mockContact, 'lean').returnsThis();

const allContacts = await contacts({}, { input, pageNumber: 1, pageSize: 1 }, { req, isAuthenticated: true });
expect(allContacts).to.have.property('data');
expect(allContacts.totalItems).to.equal(1);
});

it("should throw a 401, not authenticated error", async () => {

const error = await contacts({}, { input }, { req, isAuthenticated: false });
Expand All @@ -128,7 +154,7 @@ describe('Contact Resolver Unit Tests:', function () {
const result = await contacts({}, { input }, { req, isAuthenticated: true });

expect(result).to.have.property('extensions');
expect(result.extensions.code).to.be.equal(500)
expect(result.extensions.code).to.be.equal(401)
});
})
});
});
191 changes: 168 additions & 23 deletions resfulservice/spec/graphql/resolver/user.spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
const chai = require('chai');
const sinon = require('sinon');
const User = require('../../../src/models/user')
const graphQlSchema = require('../../../src/graphql');
const { Mutation: { createUser }, Query: { verifyUser } } = require('../../../src/graphql/resolver');
const {
Mutation: { updateUser, deleteUser },
Query: { verifyUser, users, user }
} = require('../../../src/graphql/resolver');
const { mockUser, mockDBUser } = require('../../mocks');
const { userRoles } = require('../../../config/constant');

const { expect } = chai;

Expand All @@ -18,38 +22,179 @@ describe('User Resolver Unit Tests:', function () {
}

const input = {
surName: 'surName', alias: 'alias', displayName: 'displayName', email: 'gmail88@email.com', givenName: 'givenName', key: 'key'
...mockUser
}

it('should have createUser(...) as a Mutation resolver', async function () {
const { createUser } = graphQlSchema.getMutationType().getFields();
expect(createUser.name).to.equal('createUser');
context('verifyUser', () => {
it('Should return verified user and token', () => {
const verifiedUser = verifyUser({}, { }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });
expect(verifiedUser).to.have.property('isAuth');
expect(verifiedUser).to.have.property('token')
});

it("Should throw a 401, not authenticated error", () => {
const error = verifyUser({}, { }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: false });
expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(401);
});
});

it('createUser', async () => {
sinon.stub(User, 'countDocuments').returns(0);
sinon.stub(User.prototype, 'save').callsFake(() => ({...input, _id: 'b39ak9qna'}))
const user = await createUser({}, { input }, { req });
context('updateUser', () => {
it("should throw a 401, not authenticated error", async () => {

expect(user).to.have.property('_id');
});
const error = await updateUser({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: false });
expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(401);
});

it("should throw a 404, not found error", async () => {
sinon.stub(User, 'findOneAndUpdate').returns(null);
const error = await updateUser({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(404);
});

it('should return User! datatype for createUser(...) mutation', () => {
const { createUser } = graphQlSchema.getMutationType().getFields();
expect(createUser.type.toString()).to.equal('User!');
it("should throw a 409, forbidden error", async () => {
const error = await updateUser(
{},
{ input: { ...input, roles: userRoles.isAdmin } },
{ user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true }
);

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(409);
});

it("should throw a 500, server error", async () => {
sinon.stub(User, 'findOneAndUpdate').throws(null);
const error = await updateUser({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(500);
});

it('should update user information if user is registered', async () => {

sinon.stub(User, 'findOneAndUpdate').returns({ _id: 'kas2344nlkla', ...mockUser });
const updatedUser = await updateUser(
{},
{ input: {...input, _id: 'kas2344nlkla'} },
{ user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true }
);

expect(updatedUser).to.have.property('_id');
expect(updatedUser._id).to.equal('kas2344nlkla');
});
});

context('verifyUser', () => {
it('should return verified user and token', () => {
const verifiedUser = verifyUser({}, { }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });
expect(verifiedUser).to.have.property('isAuth');
expect(verifiedUser).to.have.property('token')
context('user', () => {
it("Should throw a 401, not authenticated error", async () => {

const error = await user({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: false });
expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(401);
});

it("should throw a 401, not authenticated error", () => {
const error = verifyUser({}, { }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: false });
it("Should throw a 404, not found error", async () => {
sinon.stub(User, 'findOne').returns(null);
const error = await user({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(404);
});

it('Should return a user if they are registered', async () => {

sinon.stub(User, 'findOne').returns(mockDBUser)

const dbUser = await user({}, { input: {...input, _id: 'kas2344nlkla'} }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });

expect(dbUser).to.have.property('_id');
expect(dbUser._id).to.equal('kas2344nlkla');
});

it("Should throw a 500, server error", async () => {
sinon.stub(User, 'findOne').throws();
const error = await user({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(500);
});
})

context('users', () => {
it("Should throw a 401, not authenticated error", async () => {

const error = await users({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: false });
expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(401);
});

it('Should return a paginated list of users when input is provided', async () => {

sinon.stub(User, 'countDocuments').returns(1);
sinon.stub(User, 'find').returns(mockDBUser);
sinon.stub(mockDBUser, 'skip').returnsThis();
sinon.stub(mockDBUser, 'limit').returnsThis();
sinon.stub(mockDBUser, 'lean').returnsThis();

const allUsers = await users({}, { input: { pageNumber: 1, pageSize: 1 }}, { req, isAuthenticated: true });
expect(allUsers).to.have.property('data');
expect(allUsers.totalItems).to.equal(1);
});

it('Should return a paginated list of users when input is not provided', async () => {

sinon.stub(User, 'countDocuments').returns(1);
sinon.stub(User, 'find').returns(mockDBUser);
sinon.stub(mockDBUser, 'skip').returnsThis();
sinon.stub(mockDBUser, 'limit').returnsThis();
sinon.stub(mockDBUser, 'lean').returnsThis();

const allUsers = await users({}, { }, { req, isAuthenticated: true });
expect(allUsers).to.have.property('data');
expect(allUsers.totalItems).to.equal(1);
});

it("Should throw a 500, server error", async () => {
sinon.stub(User, 'countDocuments').throws();
const error = await users({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(500);
});
});

context('deleteUser', () => {
it("Should throw a 401, not authenticated error", async () => {

const error = await deleteUser({}, { input }, { user: { _id: 'kas2344nlkla' }, req, isAuthenticated: false });
expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(401);
});

it("should throw a 409, forbidden error if user is not admin", async () => {
const error = await deleteUser({}, { input }, { user: { _id: 'kas2344nlkla', roles: 'member' }, req, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(409);
});

it("Should throw a 500, server error on DB error", async () => {
sinon.stub(User, 'deleteMany').throws();
const error = await deleteUser({}, { input }, { user: { _id: 'kas2344nlkla', roles: userRoles.isAdmin }, req, isAuthenticated: true });

expect(error).to.have.property('extensions');
expect(error.extensions.code).to.be.equal(500);
});

it('Should delete users if it exist in DB', async () => {
sinon.stub(User, 'deleteMany').returns({ acknowledged: true, deletedCount: 1 });
const deletedUser = await deleteUser({}, { input: {...input, ids: ['kas2344nlkla']} }, { user: { _id: 'kas2344nlkla', roles: userRoles.isAdmin }, req, isAuthenticated: true });

expect(deletedUser).to.be.equal(true);

})
})
});
});
4 changes: 3 additions & 1 deletion resfulservice/spec/mocks/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const curation = require('./curationMock');
const user = require('./userMock');

module.exports = {
...curation
...curation,
...user
};
21 changes: 21 additions & 0 deletions resfulservice/spec/mocks/userMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const mockUser = {
surName: 'surName',
alias: 'alias',
displayName: 'displayName',
email: 'gmail88@email.com',
givenName: 'givenName',
key: 'key'
};

const mockDBUser = {
_id: 'kas2344nlkla',
...mockUser,
lean: () => this,
skip: () => this,
limit: () => this
};

module.exports = {
mockUser,
mockDBUser
};
Loading

0 comments on commit 3547c7e

Please sign in to comment.