This is my code:
let users
let sessions
export default class UsersDAO {
static async injectDB(conn) {
if (users && sessions) {
return
}
try {
users = await conn.db(process.env.MFLIX_NS).collection(“users”)
sessions = await conn.db(process.env.MFLIX_NS).collection(“sessions”)
} catch (e) {
console.error(Unable to establish collection handles in userDAO: ${e}
)
}
}
/**
Ticket: User Management
For this ticket, you will need to implement the following five methods:
- getUser
- addUser
- loginUser
- logoutUser
- getUserSession
You can find these methods below this comment. Make sure to read the comments
in each method to better understand the implementation.
The method deleteUser is already given to you.
*/
/**
- Finds a user in the
users
collection - @param {string} email - The email of the desired user
-
@returns {Object | null} Returns either a single user or nothing
*/
static async getUser(email) {
// TODO Ticket: User Management
// Retrieve the user document corresponding with the user’s email.
return await users.findOne({ user_id: email })
}
/**
- Adds a user to the
users
collection - @param {UserInfo} userInfo - The information of the user to add
-
@returns {DAOResponse} Returns either a “success” or an “error” Object
*/
static async addUser(userInfo) {
/**
Ticket: Durable Writes
Please increase the durability of this method by using a non-default write
concern with ``insertOne``.
*/
try {
// TODO Ticket: User Management
// Insert a user with the "name", "email", and "password" fields.
let { name, email, password } = userInfo;
// TODO Ticket: Durable Writes
// Use a more durable Write Concern for this operation.
let insertResult = await users.insertOne({ userInfo })
return { insertResult: userInfo, success: true }
} catch (e) {
if (String(e).startsWith("MongoError: E11000 duplicate key error")) {
return { error: "A user with the given email already exists." }
}
console.error(`Error occurred while adding new user, ${e}.`)
return { error: e }
}
}
/**
- Adds a user to the
sessions
collection - @param {string} email - The email of the user to login
- @param {string} jwt - A JSON web token representing the user’s claims
-
@returns {DAOResponse} Returns either a “success” or an “error” Object
*/
static async loginUser(email, jwt) {
try {
// TODO Ticket: User Management
// Use an UPSERT statement to update the “jwt” field in the document,
// matching the “user_id” field with the email passed to this function.
await sessions.updateOne(
{ user_id: email },
{ set: { jwt: jwt } }, { upsert: true } ) return { success: true } } catch (e) { console.error(`Error occurred while logging in user, {e}`)
return { error: e }
}
}
/**
- Removes a user from the
sessions
collection - @param {string} email - The email of the user to logout
-
@returns {DAOResponse} Returns either a “success” or an “error” Object
*/
static async logoutUser(email) {
try {
// TODO Ticket: User Management
// Delete the document in thesessions
collection matching the email.
await sessions.deleteOne({ user_id: email })
return { success: true }
} catch (e) {
console.error(Error occurred while logging out user, ${e}
)
return { error: e }
}
}
/**
- Gets a user from the
sessions
collection -
@param {string} email - The email of the user to search for in
sessions
- @returns {Object | null} Returns a user session Object, an “error” Object
- if something went wrong, or null if user was not found.
*/
static async getUserSession(email) {
try {
// TODO Ticket: User Management
// Retrieve the session document corresponding with the user’s email.
return sessions.findOne({ user_id: email })
} catch (e) {
console.error(Error occurred while retrieving user session, ${e}
)
return null
}
}
/**
- Removes a user from the
sessions
andusers
collections - @param {string} email - The email of the user to delete
-
@returns {DAOResponse} Returns either a “success” or an “error” Object
*/
static async deleteUser(email) {
try {
await users.deleteOne({ email })
await sessions.deleteOne({ user_id: email })
if (!(await this.getUser(email)) && !(await this.getUserSession(email))) {
return { success: true }
} else {
console.error(Deletion unsuccessful
)
return { error:Deletion unsuccessful
}
}
}
catch (e) {
console.error(Error occurred while deleting user, ${e}
)
return { error: e }
}
}
/**
-
Given a user’s email and an object of new preferences, update that user’s
-
data to include those preferences.
-
@param {string} email - The email of the user to update.
-
@param {Object} preferences - The preferences to include in the user’s data.
-
@returns {DAOResponse}
/
static async updatePreferences(email, preferences) {
try {
/*
Ticket: User PreferencesUpdate the “preferences” field in the corresponding user’s document to
reflect the new information in preferences.
*/preferences = preferences || {}
// TODO Ticket: User Preferences
// Use the data in “preferences” to update the user’s preferences.
const updateResponse = await users.updateOne(
{ someField: someValue },
{ $set: { someOtherField: someOtherValue } },
)if (updateResponse.matchedCount === 0) {
return { error: “No user found with that email” }
}
return updateResponse
} catch (e) {
console.error(
An error occurred while updating this user's preferences, ${e}
,
)
return { error: e }
}
}
static async checkAdmin(email) {
try {
const { isAdmin } = await this.getUser(email)
return isAdmin || false
} catch (e) {
return { error: e }
}
}
static async makeAdmin(email) {
try {
const updateResponse = users.updateOne(
{ email },
{ $set: { isAdmin: true } },
)
return updateResponse
} catch (e) {
return { error: e }
}
}
}
/**
- Parameter passed to addUser method
- @typedef UserInfo
- @property {string} name
- @property {string} email
-
@property {string} password
*/
/**
- Success/Error return object
- @typedef DAOResponse
- @property {boolean} [success] - Success
-
@property {string} [error] - Error
*/
And this is the specific problem:
static async addUser(userInfo) {
/**
Ticket: Durable Writes
Please increase the durability of this method by using a non-default write
concern with ``insertOne``.
*/
try {
// TODO Ticket: User Management
// Insert a user with the "name", "email", and "password" fields.
let { name, email, password } = userInfo;
// TODO Ticket: Durable Writes
// Use a more durable Write Concern for this operation.
let insertResult = await users.insertOne({ userInfo })
return { insertResult: userInfo, success: true }
} catch (e) {
if (String(e).startsWith("MongoError: E11000 duplicate key error")) {
return { error: "A user with the given email already exists." }
}
console.error(`Error occurred while adding new user, ${e}.`)
return { error: e }
}
}
And this is what is returned in my Terminal Console:
npm test -t user-management ⏎ ✭
server@1.0.0 test /Users/mariacam/Development/mflix-js
jest --passWithNoTests “user-management”
Determining test suites to run…Setup Mongo Connection
FAIL test/user-management.test.js
User Management
✕ it can add a new user to the database (45ms)
✓ it returns an error when trying to register duplicate user (23ms)
✓ it allows a user to login (58ms)
✓ it allows a user to logout (56ms)
● User Management › it can add a new user to the database
expect(received).toBeTruthy()
Received: undefined
29 | */
30 | const actual = await UsersDAO.addUser(testUser)
> 31 | expect(actual.success).toBeTruthy()
| ^
32 | expect(actual.error).toBeUndefined()
33 |
34 | // we should be able to get the user
at toBeTruthy (test/user-management.test.js:31:28)
at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
at node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13
Test Suites: 1 failed, 1 total
Tests: 1 failed, 3 passed, 4 total
Snapshots: 0 total
Time: 1.411s, estimated 3s
Ran all test suites matching /user-management/i.
Teardown Mongo Connection
npm ERR! Test failed. See above for more details.
I’m at a loss. This is the best outcome I have got so far.