How can I resolve this promise? - promise

This is my code:
collector.on('collect', async (reaction, user) => {
console.log(reaction);
if (!user.bot) {
let role = reaction.message.guild.roles.cache.find(role => role.name === ra[emojiarray.indexOf(reaction)]);
await reaction.message.guild.members.fetch(user).roles.add(role);
}
});
Except I get the error UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'add' of undefined. I was told to resolve the promise, and I tried, but I guess I didn't do it right. How can I fix this?
Thanks!

You may need to await the fetch of the user, and then add the role to the user.
collector.on('collect', async (reaction, user) => {
console.log(reaction);
if (!user.bot) {
let role = reaction.message.guild.roles.cache.find(role => role.name === ra[emojiarray.indexOf(reaction)]);
let userMember = await reaction.message.guild.members.fetch(user);
userMember.roles.add(role);
}
});

Related

access req.cookie from supertest

I set a cookie and I usually access it like this when I need to test a "protected" request.
beforeAll(async () => {
await db.connect();
//sign my user and get the token
const response = await request(app).post("/gettoken").send(credentials);
TOKEN = response.headers["set-cookie"].pop().split(";")[0];
})
//test exemple
it("exemple", async () => {
const result = await request(app).post("/path").set(`Cookie`, TOKEN).send(data);
});
So far I had no problem with it but in one of my function that I want to test I have this line:
user = await getUser(req.cookies.token);
the function getUser is pretty simple:
const userToken = jwt.verify(token, process.env.JWTPRIVATEKEY);
user = await User.findOne({ _id: userToken.payload._id });
return user;
Seems like supertest does not work with req.cookies. Is there any way to set "req.cookies.token" during my test ?
I'm going to answer my own question but please, be aware that I have no idea why it works. Actually I was a bit desperate to not find any solution so I did try something without any hope but, surprisely, it worked.
so basically after restarting docker my console.log were all similars (npm run test vs test with postman)
module.exports.getUser = async (token) => {
console.log(token);
console.log(process.env.JWTPRIVATEKEY);
const userToken = jwt.verify(token, process.env.JWTPRIVATEKEY);
console.log(userToken.payload._id);
const user = await User.find({ _id: userToken.payload._id });
return user;
};
it("with success", async () => {
const question = {
title: "title",
content: "content",
};
const result = await request(app).post("/api/forum/question").set("Cookie", TOKEN).send(question);
console.log(result.body);
expect(result.status).toBe(200);
});
And I had this error:
{ error: { message: "Cannot read property '_id' of null" } }
I did change
const user = await User.findOne({ _id: userToken.payload._id });
by
const user = await User.find({ _id: userToken.payload._id });
And now it works as expected.
If someone can explain me why findOne was not working with test (but was ok with postman) I would be happy to understand... because to me, as beginner, it does not make any sense.

Page object does not return selector in Playwright

Using Microsoft's playwright, I have this testing code that works:
describe('When a user views a list of forms', () => {
let rows;
before(async() => {
await page.waitForSelector('tbody');
rows = await page.$$('tr');
});
it('should show a table of forms', async() => {
rows.length.should.equal(11);
});
I would like to break it out into a page object. I have this as my page object
class UserFormsPage {
constructor(page) {
this.page = page;
}
async rows() {
await this.page.waitForSelector('tbody');
return await this.page.$$('tr');
}
}
And this as my test:
describe.only('List Forms Widget', function() {
let page;
...
before(async function() {
const context = await this.browser.newContext();
page = await context.newPage();
const userFormsPage = new UserFormsPage(page);
...
describe('When a user views a list of forms', () => {
let rows;
...
before(async() => {
rows = await userFormsPage.rows();
});
it('should show a table of forms', async() => {
rows.length.should.equal(11);
});
But I get
1) List Forms Widget
When a user views a list of forms
"before all" hook for "should show a table of forms":
TypeError: Cannot read property 'rows' of undefined
Why is this?
Note: using native es modules in Node 16 if that matters
Your rows() method is async. Every async method returns a promise, so in your hook, rows = userFormsPage.rows(); will result only in Promise { <pending> }.
If you want the number, you have to await it:
before(async () => {
rows = await userFormsPage.rows();
});
Another problem seems to be that you don't have (at least not here in your question) any creation of the UserFormsPage object. The constructor expects page, but you don't seem to provide it.
I think the following should work
row = await (await userFormsPage.rows());

Nuxt.js and Laravel Api - 422 Displaying Error instead of Forms

[Error][1]
Hi Team,
Whenever I am receiving the error return from laravel the nuxt.js project displays the error on the page instead the HTML/Forms. How can i handle this.
Here is my php code
return response()->json([
'errors' => [
'email' => ['Sorry we cant find you with those details.'],
],
], 422);
Javascript
async submit() {
await this.$auth.loginWith("local", {
data: this.form
})
In your JavaScript you need to wrap your await promise inside a try catch block. Here's a fix for your JS.
try {
await this.$auth.loginWith("local", {
data: this.form
})
} catch (e) {
return;
}
This is an old question at this point, but I thought I'd post the full code since I was pretty stumped and didn't find many great answers out there:
async handleSubmit() {
try {
const authResponse = await this.$auth.loginWith('local', {
data: this.formData
});
const { status, data } = authResponse;
if (status === 200)
this.createFlashAlert({ 'success': 'Login successful' });
} catch (error) {
if (error.response.status === 422)
this.createFlashAlert(error.response.data);
}
}
So the checklist:
Wrap the login call in a try/catch if you're using async await syntax (be sure to make it an async function i.e. async handleSubmit.
in the catch block, use the error.response object, this is an axios thing. With this you'll be able to access the response status and data.
If you log just the error object, it's not obvious that you can access the response within that error which is what had me stumped.

How to pass a parameter in Koa middleware?

So I have this function in Koa, that basically checks if a user can access a specific route.
exports.requireRole = async role =>
async (ctx, next) => {
const { user } = ctx.state.user;
try {
const foundUser = await User.findById(user.id);
// If the user couldn't be found, return an error
if (!foundUser) {
ctx.status = 404;
ctx.body = { errors: [{ error: ERRORS.USER_NOT_FOUND }] };
} else {
// Otherwise, continue checking role
if (getRole(user.role) >= getRole(role)) {
await next();
}
ctx.status = 403;
ctx.body = { errors: [{ error: ERRORS.NO_PERMISSION }] };
}
} catch (err) {
ctx.throw(500, err);
}
};
And I want to use it as a middleware:
router.delete('/:id', combine([jwtAuth, requireRole(ROLES.ADMIN)]), deleteUser);
But then I get an error saying:
middleware must be a function not object
This happens only when I try to pass an argument into it.
What am I doing wrong here?
The issue you are having is due to the fact that Promises are objects, and async functions return Promises. You need to change your initial function to be as follows:
exports.requireRole = role =>
instead of
exports.requireRole = async role =>
I was going over middleware myself, and ran into this issue as well.
Your middleware looks fine, what is combine?
Also, since you are using koa-router you don't need it.
router.delete('/:id', jwtAuth, requireRole(ROLES.ADMIN), deleteUser);

Karma/Jasmin Test Promise error inside of regular function

First my Setup. I try to test some of my Ionic Pages etc.
And I have a login page where I want to test the Login.
This is my Login method:
doLogin() {
let authHelper = this.injector.get(AuthHelper);
authHelper.sendSignInLink(this.email).then(()=> {
window.localStorage.setItem("userMail", this.email);
let loginToast = this.toast.create({
message: "Link to email succesfully send. In order to finish the login, it is necessary to click the send link.",
duration: 3000,
position: "bottom",
});
loginToast.present();
}).catch(() => {
throw new EmailSignInLinkError("invalid Mail");
});
}
As we can see the method sendSignInLink is returning a promise and if the promise is rejected it should throw a custom error.
For my unit test I mocked the authHelperClass to a very simple mock:
export class AuthHelperMock {
public auth(): Promise<any> {
return new Promise((resolve, reject) => {
resolve(2);
});
}
public sendSignInLink(email: String): Promise<any> {
return new Promise((resolve, reject) => {
if (email != undefined || email != "")
resolve(1);
else
reject("Invalid email");
});
}
}
Now is the Problem that I try to check on this thrown error from my promise.
My it case is:
it('should not do the login', () => {
component.email = "";
expect(() => {
component.doLogin();
}).toThrowError(EmailSignInLinkError)
I know that this will not work because the promise is async and the case will fail before it throws the error. But I don't find any suitable solution beside changing my doLogin to a promise as well.
How can I check on this Promise within a regular function?

Resources