I am trying to unit test http client on flutter. After mocked http and my repository class :
void main() {
MockHttpCLient mockHttpCLient;
FoursquareRepositoryImpl foursquareRepositoryImpl;
setUp(() {
mockHttpCLient = MockHttpCLient();
foursquareRepositoryImpl = FoursquareRepositoryImpl(client: mockHttpCLient);
});
I am running this test:
test(
'should perform a get request on a url with application/json header',
() async {
//arrange
when(mockHttpCLient.get(any, headers: anyNamed('headers'))).thenAnswer(
(_) async => http.Response(fixture('venues_details.json'), 200));
//act
foursquareRepositoryImpl.getVenuesDetails(venueId);
//assert
verify(mockHttpCLient.get(
'https://api.foursquare.com/v2/venues/$venueId?client_id={{client_id}}&client_secret={{client_secret}}&v={{v}}',
headers: {'Content-Type': 'application/json; charset=utf-8'},
));
},
);
This is foursquareRepositoryImpl.getVenuesDetails implementation :
#override
Future<VenuesDetails> getVenuesDetails(String venueId) async {
await client.get(
'https://api.foursquare.com/v2/venues/$venueId?client_id={{client_id}}&client_secret={{client_secret}}&v={{v}}',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}).timeout(Duration(seconds: 10));
}
But test is failded and i got this error: https://paste.ubuntu.com/p/Ppy3ZhnyHB/
This error is most probably caused due to non-English characters. Dart's json.decode method uses Latin encoder by default (https://stackoverflow.com/a/52993623).
Where you are returning response from venues_details.json, add the following header to that response.
(_) async => http.Response(
fixture('venues_details.json'),
200,
headers: {
HttpHeaders.contentTypeHeader: 'application/json; charset=utf-8',
}
)
Related
I am using Flutter and Django and have this error when try to call the backend
Back end error :
{detail: Unsupported media type "text/plain; charset=utf-8" in request.}
Flutter code :
Future<void> addAlbum(Album album) async {
print('5');
final url = Uri.parse('http://127.0.0.1:8000/list-create/');
try {
print('6');
final response = await http.post(url,
headers: {
'Authorization': 'Token dc7e96ed776bc44d013b44fdfe560a616c64646f',
},
body: json.encode({
'title': album.title,
'cover': album.cover, // => this is an int
'photos_number': album.photos_number, // => this is an int
}));
print('6 ed');
final responseData = json.decode(response.body);
print(responseData.toString());
final newAlbum = Album(
title: album.title,
cover: album.cover,
photos_number: album.photos_number,
);
print('6 edddgg');
_items.add(newAlbum);
print('6 f');
notifyListeners();
} catch (error) {
print('7');
print(error);
throw error;
}
}
}
Add json content type header.
headers: {
'Authorization': 'Token dc7e96ed776bc44d013b44fdfe560a616c64646f',
'Content-Type': 'application/json; charset=UTF-8',
},
This is my JS code for the API
export const getUser = async (user) => {
//Working
const json = await fetch( "*****/username/getUser", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
user:user
}),
})
.then((res) => {
return res.json();
})
.catch((err) => {
console.log("Error in getUser: " + err);
});
return json;
};
Here is an attempt to make the request, which unfortunately return the authentication error.
fetchUser.request("kirolosM")
.then((result)=>{
console.log(result);
}).catch((err)=>{console.log("Error ",err);})
The error
{
"message": "Missing Authentication Token"
}
I have tested the API using postman and it is working as expexted.
Probably useful to compare the request sent from your json code to the one you're sending from postman. It looks like you need to include you auth token in your headers in your request.
Something like
export const getUser = async (user) => {
//Working
const json = await fetch( "*****/username/getUser", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authentication": `Bearer ${token}`
},
...
I am facing an issue of receiving NULL response for the axios POST request I made. How do I correct this error?
I've tried to changing multipart/form-data into x-www-form-urlencoded and multipart/x-www-form-urlencoded
async submitUser() {
this.memberObj = {
id: this.memberObjLocal.id,
name: this.memberObjLocal.name,
password: this.memberObjLocal.password,
email: this.memberObjLocal.email,
password: this.memberObjLocal.password,
gender: this.memberObjLocal.gender,
experience: this.memberObjLocal.experience,
birth: this.memberObjLocal.birth,
phoneNum: this.memberObjLocal.phoneNum,
address: this.address,
introduce: this.introduce,
pic: this.pic
};
const config = {
headers: { "Content-Type": "multipart/form-data" }
};
var formData = new FormData();
for (let data in this.memberObj) {
console.log(data);
formData.append(data, this.memberObj[data]);
console.log(this.memberObj[data]);
}
for (var key of formData.entries()) {
console.log(key[0] + ", " + key[1]);
}
try {
let response = await this.$axios.$post("/users/", formData, config);
this.$router.push("/");
console.log(response) // null
} catch (e) {
console.log(e.response);
}
}
Please try to use like this
import axios from "axios";
//... your codes here
axios({
url: "/users/",
method: "post",
data: formData,
headers: config.headers
})
.then(response => {
this.$router.push("/");
console.log(response);
})
.catch(error => console.error(error));
//... and other codes here
and you can see more examples!
I'm trying to implement post webservice in angular2.
I have tried to hit the URL through postman and its working. But when i'm trying to implement it in angular, I'm not getting any response.
The following is my code sample:
load(username, password) {
console.log(username," ", password);
let postData = {"username":username, "password" : password,
"userdeviceInfo": [{
"deviceId": "APA91bGUZuKVbqur7Qq2gy2eyomWgXkIU5Jcmmtmgl4IGuzVzwiJVMZgAHj3Bx6yrnW0oEZlEtB9XdcR6AOpKyEMVSWwQ_UIfNX6T0iwq28hnufOhauVdTYZQSWWPAdDrdg58cjnL5T-",
"platform":"Android"
}]};
//let body= JSON.stringify(postData);
//console.log("body---"+body)
this.headers = new Headers();
this.headers.append("Content-Type", 'application/json');
this.requestoptions = new RequestOptions({
method: RequestMethod.Post,
url: this.url,
headers: this.headers,
body: JSON.stringify(postData)
})
console.log("body---"+this.requestoptions)
return this.http.request(new Request(this.requestoptions))
.map((res: Response) => {
if (res) {
console.log(res.json());
return [{ status: res.status, json: res.json() }];
}})
.subscribe(res => this.data = res);
the error i'm recieving is:
XMLHttpRequest cannot load "MY_URL". Response for preflight has invalid HTTP status code 500
I'm kind of stuck here. Can anyone help me find where am i going wrong?
here is a POST example:
rate(url: string, body: { value: number}) {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options).toPromise().then(
response => response.json(),
err => err
);
}
Of course you can delete toPromise() to use observables, this is for an example app :)
hope this can help you.
You can use this way to make a http post :
let headers = new Headers();
let body = {"username":username, "password" : password,
"userdeviceInfo": [{
"deviceId": "APA91bGUZuKVbqur7Qq2gy2eyomWgXkIU5Jcmmtmgl4IGuzVzwiJVMZgAHj3Bx6yrnW0oEZlEtB9XdcR6AOpKyEMVSWwQ_UIfNX6T0iwq28hnufOhauVdTYZQSWWPAdDrdg58cjnL5T-",
"platform":"Android"
}]};
headers.append('content-type', 'application/json');
return this.http.post("theurl", '', {
body : JSON.stringify(body),
headers : headers
})
.map(res => res.json())
.subscribe(data=>{
},
err=>{
},
()=>{
})
I've been trying to implement some authentication component in my app for a few hours now, and I still don't understand some of the things that are happening.
Basically, I'd like to send a POST request containing some credentials to my API, which sends me a cookie back with a token if the credentials worked. Then, the cookie should be included in the headers of all future requests to my API (which I believed was automatic).
server.js (my API is a mockup for now, with JSON files)
...
app.post('/api/login', jsonParser, (req, res) => {
fs.readFile(ACCOUNTS_FILE, (err, data) => {
if (err) {
console.error(err);
process.exit(1);
}
const accounts = JSON.parse(data);
const credentials = {
email: req.body.email,
password: req.body.password,
};
var token = null;
for (var i = 0; i < accounts.length; ++i) {
const account = accounts[i];
if (account.email === credentials.email
&& account.password === credentials.password) {
token = account.token;
break;
}
}
if (token) {
res.setHeader('Set-Cookie', `access_token=${token}; Secure; HttpOnly;`);
res.json({ token });
} else {
res.json({ token: null });
}
});
});
...
app.js
...
handleConnection(e) {
e.preventDefault();
const email = this.state.email.trim();
const password = this.state.password.trim();
if (!email && !password) {
return (false);
}
fetch(loginUrl, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
credentials: 'include',
},
body: JSON.stringify(this.state),
})
.then((response) => response.json())
.then((data) => {
console.log(data);
})
.catch((error) => {
console.warn(error);
});
return (true);
}
...
Now the console.log(data) always displays my token (or null if my credentials are wrong), but the cookie thing doesn't work...
See, I receive the Set-Cookie header, but I still have no cookie on my page.
And even if I managed to get the cookie, when I try to create a cookie using document.cookie = "access_token=123"; and then send the request again, my cookie doesn't go in my header like it would with a jQuery Ajaxcall :
I read here that adding credentials: 'include' would save the day, but unfortunately it didn't.
What am I missing here?
Thanks in advance!
I had the same problem and I found the answer in Peter Bengtsson's comment here: https://davidwalsh.name/fetch
If I understood, in your case the fetch should be:
fetch(loginUrl, {
credentials: 'same-origin',
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(this.state),
})