Nock - how to log the status of each request? - nock

I would like to be able to see each request that an interceptor has intercepted and see whether it has responded or is pending. I am using scope.persist(true) for each interceptor. How can this be done?

Scopes emit events when an Interceptor is matched to a request and when that Interceptor replies with a payload.
https://github.com/nock/nock#events
The callback for each of those events gets passed the Interceptor as an arg.
I'm not entirely sure what the ask is around "see whether it has responded or is pending", but something like this should get you going:
const scope = nock('http://example.test')
.get('/')
.reply(200)
scope.on('request', (req, interceptor) => {
console.log('interceptor matched request', interceptor.uri)
});
scope.on('replied', (req, interceptor) => {
console.log('response replied with nocked payload', interceptor.uri)
});

Related

Axios onUploadProgress jumps at 100% even before the request is done

I have a controller that calls multiple external api from Gmail API concurrently, and then saves the retrieved data into the database, all of this in ONE post request.
To start, I pooled the external api requests, map the results and save it to db.
In my Controller:
$resp = Http::pool(fn (Pool $pool) [
$pool->as('pool-1')->withToken($user->token)->get('https://....call-1');
$pool->as('pool-2')->withToken($user->token)->get('https://....call-2');
$pool->as('pool-3')->withToken($user->token)->get('https://....call-3');
]);
collect($resp)->map(function ($req) {
Email::firstOrCreate(...);
})
In my vue component:
const config = {
onUploadProgress: progressEvent => {
console.log(`sent: ${Math.floor((progressEvent.loaded * 100) / progressEvent.total)}`)
}
}
axios.post(url, param, config).then(response => {}).catch(err => {})
Now, when I check in console.
It should be logging:
sent:0
sent:1
sent:2
...
sent:100
But instead, it automatically logs sent:100 even though the post request is still pending.
Is this a bug in chrome? or axios?, or perhaps it has something to do with external api calls?
Or if it isn't, can someone point out where I went wrong?

Post Confirmation ConfirmForgotPassword lambda execution returns InvalidLambdaResponseException - Unrecognizable lambda output

I have spent a bunch of hours to solve this issue, all related SO answers seem to be outdated or irrelevant.
State:
Amplify.js "^4.3.10" with code
Auth.forgotPasswordSubmit(email, confirmationCode, password)
.then(_ => this.notification.success("Confirmation OK"))
.catch(err => console.log(err));
Lambda on Node.js 14
Cognito trigger "Post confirmation"
Lambda function code:
'use strict';
exports.handler = async (event, context, callback) => {
if (event.triggerSource === "PostConfirmation_ConfirmForgotPassword") {
const postConfirmEmail = () => `<html><body>HERE IS MY TEMPLATE</body></html>`;
event.response = {
emailSubject: "Reset Password Notification",
emailMessage: postConfirmEmail()
};
callback(null, event);
}
};
As result, I am getting
InvalidLambdaResponseException: Unrecognizable lambda output (Error 400)
The thing is that password is really updating as expected, but e-mail confirmation is NOT sent and error remains.
TIP: User is CONFIRMED. Tried also with "context.done(null, event);" / "return event;" but response is always with the same error.
You shouldn't be using an async handler with the callback. It's either one or the other.
Simply return event without calling the callback or don't make your function async.
Additionally, Cognito will not send confirmation emails, you will have to implement this functionality yourself.

How can I fix an Axios interceptor causing property 'status' of undefined error

I have a selection to set permissions for elements to global or private. I'm using the Axios interceptor request to handle looking for the permissions field to have data and, if it does, stringify it. The problem is, it causes me to get a "TypeError: Cannot read property 'status' of undefined" when I attempt to reload the program at all. The only "fix" right now is to log out, remove the interceptor, log in, read it, and then run the check again.
Because of this, I can't even get to the home dashboard of the software. If I clear my cookies, I can go back to the login screen, but no further than that after attempting to log in.
Is there something I'm missing for it? below is the interceptor code. If more information or context is needed, please let me know.
export default {
install: (Vue) => {
Vue.$eventBus = new Vue();
Vue.axios.interceptors.response.use(response => {
return response.data;
}, async error => {
if (error.response.status === 401 && error.config.url != '/api/authentication/login') {
var config = await Vue.$configService.find();
window.location = config.accountPortalUrl;
return
}
console.log(error);
Vue.$eventBus.$emit('notifyUser', 'Uh oh, something went wrong!');
return Promise.reject(error);
});
Vue.axios.interceptors.request.use(
config => {
// check request method -> use post if many params
if (config.data.permissions) {
config.data.permissions = JSON.stringify(config.data.permissions);
}
console.log(config);
return config;
}
);
}
};
Looks like your service API is not responding, this might happen if the user is not authenticated . Your error is at line where you check (error.response.status). Its only possible to get an undefined response when the request was interrupted before response. Most probably if you check your browser network pannel you will see that the preflight check for this request causes a 401 network error. Hence because the preflight failed your actual response comes as undefined. You should sanity check first if your server responded with a response or not and then access the response status.
Something like this might help
if (error.response) {
// Request was made and the server responded successfully
// You can now de-structure the response object to get the status
console.log(error.response.status);
} else if (error.request) {
// request was made but not responded by server
console.log(error.request);
}
So, the answer ultimately was something extremely simple.
if (config.data.permissions)
needed to be
if (config.data && config.data.permissions)

How to send an additional request to endpoint after each test case

I’m currently looking at Botium Box, and I’m wondering if it is possible to send an additional request to our endpoint after each test case? Let me give you some background information about how we set up the HTTP(S)/JSON connector in Botium Box and how we are sending information to our bot:
HTTP(S) endpoint:
https://MyChatBotsEndpoint.com/?userinput={{msg.messageText}}
HTTP method: POST
We also send cookies through the header template in the request builder. Like this:
{
"Cookie": "JSESSIONID={{context.sessionId}}"
}
The response is given back in JSON.
When a test ends (when it is successful but also when it fails), we need to send an additional request to our endpoint. The endpoint URL of that request should look like this:
https://MyChatBotsEndpoint.com/endsession
The header should include the cookie as described before.
Is there a way to achieve this in Botium?
Botium has many extension points to plug in your custom functionality. In this case, I guess the SIMPLEREST_STOP_HOOK is the best choice.
Write a small javascript file calling your endpoint, and register is with the SIMPLEREST_STOP_HOOK capability in botium.json. The context (session context from the HTTP/JSON connector) is part of the hook arguments.
in botium.json:
...
"SIMPLEREST_STOP_HOOK": "my-stop-hook.js"
...
my-stop-hook.js:
const request = require('request')
module.exports = ({ context }) => {
return new Promise((resolve, reject) => {
request({
method: 'GET',
uri: 'https://MyChatBotsEndpoint.com/endsession',
headers: {
Cookie: "JSESSIONID=" + context.sessionId
}
}, (err) => {
if (err) reject(err)
else resolve()
})
})
}

Express.io can not emit events when routed from http request

Here i use those codes:
// Initial web request.
app.get('/hello', function(req, res) {
// Forward to an io route.
req.io.route('hello')
})
app.io.route('hello', function(req) {
//Here use emit
req.io.emit("world","world");
})
it report an error as follow:
TypeError: Object #<Object> has no method 'emit'
at Object.hello (/Users/wensonsmith/ProjectX/Server/app.js:44:12)
at Manager.io.route (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/lib/index.coffee:65:29)
at Object.request.io.route (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/lib/index.coffee:143:29)
at /Users/wensonsmith/ProjectX/Server/app.js:39:12
at callbacks (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/node_modules/express/lib/router/index.js:160:37)
at param (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/node_modules/express/lib/router/index.js:134:11)
at pass (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/node_modules/express/lib/router/index.js:141:5)
at Router._dispatch (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/node_modules/express/lib/router/index.js:169:5)
at Object.router (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/node_modules/express/lib/router/index.js:32:10)
at next (/Users/wensonsmith/ProjectX/Server/node_modules/express.io/node_modules/connect/lib/proto.js:190:15)
req.io.respond is OK .
Broadcast is also have some problem.It can broadcast ,but it doesn't stop after broadcast.
it run for a long while ,then return nothing ,and no error messages.
My code is
// Initial web request.
app.get('/hello', function(req, res) {
// Forward to an io route.
req.io.route('hello')
})
// Forward io route to another io route.
app.io.route('hello', function(req) {
req.io.broadcast("world","world");
})
It doesn't look like the code you're posting is the actual code, judging by the stack trace.
But apart from that: as far as I understand express.io, when you're forwarding an HTTP request to an io route, the io route should always send back a response with respond; otherwise, the HTTP request will stall.
So try this:
app.get('/hello', function(req, res) {
req.io.route('hello');
});
app.io.route('hello', function(req) {
// broadcast first...
req.io.broadcast("world","world");
// ...then send back an empty response
req.io.respond();
});
Just to make sure: req.io.broadcast will not send the message back to the client that initiated the request. If you want that, use app.io.broadcast instead (see docs).
Its only 50% answered ;) ::
.respond takes your arguments "directly" to emit them,
e.g.:
req.io.respond({hello: 'world'})