How can I mock an http error response in dart? - testing

So I'm doing some unit tests for my http provider.
In one of my tests I want to verify that when I do a POST call and I get an error response with status 409 I do then a call to PATCH and everything works.
This is my code
Future<IdentityResponse> _createUser(dynamic body) {
return http
.post(api, body: json.encode(body))
.catchError((err) {
return _isStatusCode(err, 409) ? _patchUser(body) : throw (err);
});
}
I'm using mockito, and tried first returning a Response like this:
when(http.post(argThat(startsWith(api)), body: anyNamed('body')))
.thenAnswer((_) async => Response("user exists", 409);
And it works... kind of. I catch the error, but then I can't get the status code, I get only the message 'user exists'
If I change to the structure that the backend returns, which is {"error": { "code": 409 }} and I do this:
when(http.post(argThat(startsWith(api)), body: anyNamed('body')))
.thenAnswer((_) async => Response(json.encode(fakeErrorResponse), 409);
Then my catch does not work anymore (??)
I tried then to return an error instead of a response, like this:
when(http.post(argThat(startsWith(api)), body: anyNamed('body')))
.thenAnswer((_) => Future.error(fakeErrorResponse));
Now my catch works again, but the error I get is an _ImmutableMap and I see no easy way to retrieve my data from there.
How can I mock an http error that returns the body that I want and not a simple String?
Thanks

Related

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)

VueJS POST http://127.0.0.1:8000/login 404 (Not Found)

so i post this qs yesterday enter link description here
i was getting this **Uncaught (in promise) Error: Request failed with status code 405 VUEJS
**
now i did fix the part of axios from this :
axios.post('http://127.0.0.1:8000/?#/login/',{
email: this.email, password: this.password
}, headers)
.then((response)=>{
const data=response.data;
console.log(data);
})
to this
axios({
method: "post",
url: "/api/login/",
data: {
email: "",
password: ""
}
}).then(
response => {
console.log(response);
},
error => {
console.log(error);
}
);
now i'm getting this error
as u can see the problem and the api.php and the root
405 error code means your api endpoint not allow the current method you requesting to so 405 errorbis aboutbendpoint problems, and about 404 response status in axios if server's response have a 4XX status it'll go directlly on catch it should be somthing like this:
axios.post("http://127.0.0.1:8000/api/login/",{data: value,data1: value1})
.then((res)=>console.log(res))
.catch((err)=>{
// 404 will be loged below
console.log(err.response.status)
console.log(err.response)
}
i have never saw somting like this but i think you should ckeck your api server and make sure you entered the currect url and currect port and make sure in your server logic response part you have'nt a type error or somithing im really sorry if it was'nt helpful
p.s. i wrote the code above with my phone im really sorry its may be a little ugly
and if you have some problems with your api server and your not a backend i can fix it(if its django) or i can make a simple one for you to use

How to read the contents of a Post request on Postman?

In the systems I am testing, there are cases that the response informs 200 (ok), but the content may indicate an error in the internal validations of the backend service. How can I read the contents of the response with Postman and schedule a successful validation if this service error code comes as expected?
You can use the tests tab in Postman to run checks on the body (JSON and XML). There are snippets which show you the syntax. You can adapt them to check for the element of the response body which indicates the error.
Postman has a tab called "Tests" where you can provide you test script for execution.
If you want to validate your request responded with 200 OK, following is the script
pm.test("Status test", function () {
pm.response.to.have.status(200);
});
If you want to validate the response contains any specified string,
pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});
In your case am assuming the above script can be used. In case the response body is JSON,
pm.test("JSON Body match", function () {
var respBody = pm.response.json();
pm.expect(respBody.<json node>).is.to.equal("Error_name");
});
Example JSON response body
{
"id" : 100,
"status" : "Bad Request"
}
pm.test("JSON Body matches string", function () {
var respBody = pm.response.json();
pm.expect(respBody.status).is.to.equal("Bad Request");
});

How to get the data associated with the error response back?

I am making a request from the front-end to a route in my backend that is validating the token associated with a user, which would send an error response back to the front-end if the token has expired. I am sending some json with it but upon doing console.log of the error message in the catch block, the json sent along the error response is not shown.
Sending the error response like this
res.status(401).json({
message: 'User session has expired'
})
But the response that I am getting in the catch block in the front-end has no sign of the json sent with the error.
POST http://localhost:3001/check-validation 401 (Unauthorized)
Error: Request failed with status code 401
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:78)
I don't understand why the json sent along the error response is not shown and how to get it?
Upon doing console.log of the error only the stacktrace of the error is shown and not the data associated with it. The data sent with it can be procured and depends on how the request has been made or by what library it has been made. If the request is made by axios then the following can be done:
axios.post('/formulas/create', {
name: "",
parts: ""
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error.response.data.message)
});
Here, in axios the details of the error would be wrapped up in error.response. Whereas, if the request was made by the fetch API then something following can resolve the problem:
fetch('/401').then(function(response) {
if (response.status === 401) {
return response.json()
}
}).then(function(object) {
console.log(object.message)
})
P.S I was searching a lot regarding this problem but didn't get an answer on SO, neither got any article or docs regarding it, even the official Express docs on error handling were not helpful. At last, I understood that the problem lies with the library that is being used to make the request. That's why answering my own question to mark the presence of this question on SO. A detailed discussion can be found here related to axios and here related to fetch api

How do I handle an express route json error (without "Can't set headers after they are sent.")

I've got an Express route which uses response.json to return the response. However, I can't figure out how to catch error cases with it. If I do:
try {
response.json();
} catch (e){
response.send('it went wrong!'
}
or if I do:
.then(() => response.json())
.catch(() => response.send('it went wrong!')
I get a Can't set headers after they are sent error.
That makes sense, since json calls end, and you can't set headers after end is called. However, if I can't edit the response after an error occurs in json, how can I possibly return an error response in such a case?
... Or you could always check:
if (!res.headerSent) {
// do your stuff end with res.json(), res.end(), res.render() or whatever you need
}