I have this one file that calls a login function
testing.js
var res = accounts.createSession(config.email_prod,config.password_prod,user_id)
on another file, I have this:
accounts.js
export function createSession(email,password,user_id){
cy.request({
method:'POST',
url:config.accounts_prod + '/token',
headers:{
'authorization': 'Basic testestestestest'
},
qs:{
'grant_type':'password',
'username':email,
'password':password
}
}).then((response)=>{
var X = response.body.access_token
cy.log("create session " + x)
login(response.body.access_token, user_id)
})
}
export function login(token,user_id){
var result = cy.request({
method:'POST',
url:config.ws_prod + '/login.pl',
headers:{
'authorization': token,
'Content-Type' : 'application/x-www-form-urlencoded'
},
body:'user_id='+user_id+'&device_id='+device_id+'&os_type='+os_type
})
return token
}
so I want to store token value and return it to res variable on testing.js file
but everytime I store token (in this example I store it inside X) and I try to print it, it always says undefined
but I can do cy.log(token) and it was fine on login() function, but that's all it can do, it cannot be store into a variable
is there another way for me to store token ?
Maybe if i use a callback like parameter, then the second function will wait for the asynchronous task is over
export function createSession(email,password,user_id,callback){
cy.request({
method:'POST',
url:config.accounts_prod + '/token',
headers:{
'authorization': 'Basic testestestestest'
},
qs:{
'grant_type':'password',
'username':email,
'password':password
}
}).then((response)=>{
var X = response.body.access_token
cy.log("create session " + x)
callback(response.body.access_token, user_id);
})
}
var login = function (token,user_id) {
var result = cy.request({
method:'POST',
url:config.ws_prod + '/login.pl',
headers:{
'authorization': token,
'Content-Type' : 'application/x-www-form-urlencoded'
},
body:'user_id='+user_id+'&device_id='+device_id+'&os_type='+os_type
})
return token
}
// then call first fn
createSession(email,password,user_id,login);
I had almost the same issue. Comment on this answer helped me
// testing.js
let res = null;
before(() => {
accounts.createSession(config.email_prod, config.password_prod, user_id).then((responseToken) => {
res = responseToken;
console.log('response token', responseToken);
});
});
it('My tests ...', () => {
console.log('...where I can use my session token', res);
});
// accounts.js
export function createSession(email, password, user_id) {
cy.request({
method: 'POST',
url: config.accounts_prod + '/token',
headers: {
'authorization': 'Basic testestestestest'
},
qs: {
'grant_type': 'password',
'username': email,
'password': password
}
}).then((response) => {
var x = response.body.access_token
cy.log("create session " + x)
login(response.body.access_token, user_id)
return response.body.access_token; // needs return statement
})
}
Related
I'm currently trying to incorporate Spotify's API into my project but I'm having problems fetching the data.
My token is returned in the console which is great but my call to return some data doesn't work.
I'm getting an error :
error:
message: "Only valid bearer authentication supported"
status: 400
[[Prototype]]: Object
[[Prototype]]: Object
Here's what I have so far. Maybe its a simple fix.
// Token
const CLIENT_ID = 'HIDDEN';
const CLIENT_SECRET = 'HIDDEN';
let authParameters = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials&client_id=' + CLIENT_ID + '&client_secret=' + CLIENT_SECRET
}
async function getToken() {
let myToken = await fetch('https://accounts.spotify.com/api/token', authParameters)
let tokenReturn = await myToken.json()
console.log(tokenReturn.access_token)
}
// Request
async function searchData() {
const baseUrl = 'https://api.spotify.com/v1/browse/new-releases';
let ArtistParameters = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + tokenReturn
},
}
let artistID = await fetch(baseUrl, ArtistParameters)
let artistList = await artistID.json()
console.log(artistList);
}
useEffect(() => {
getToken()
searchData()
}, [])
I don't want to repeat headers for all request.
async function fetchA() {
return await axios({
method: 'GET',
url: API_URL + `/api/a`,
headers: {'Authorization': 'Bearer ' + localStorage.getItem(ACCESS_TOKEN)}
});
}
async function fetchAById(id) {
return await axios({
method: 'GET',
url: API_URL + `/api/a/${id}`,
headers: {'Authorization': 'Bearer ' + localStorage.getItem(ACCESS_TOKEN)}
});
}
I assigned headers to const but in this case accessToken was null.
What is best way to create function which adds accessToken itself?
function getHeaders() {
const serviceInstance = axios.create({
url: API_URL + `/api/a`,
headers: {'Authorization': 'Bearer ' + localStorage.getItem(ACCESS_TOKEN)}
});
return serviceInstance;
}
async function fetchA() {
return await getHeaders().get(url)
});
}
I hope this may help.
I can't seem to figure out how to get my 2nd http post to work "queuecallback". It looks like the problem is specific to how i set the headers. Headers = my_headers. It works when i hard code it but not when i try to call it dynamically. Any help would be greatly appreciated. Thanks!
const axios = require('axios');
const queuecallback = require('axios');
var my_token;
var my_formated_token;
var my_headers;
var myJSON;
function connectToAgentHandler(agent) {
axios({
method: 'post',
url: 'https://myapi.com/AuthorizationServer/Token',
data: {
username: 'myusername',
password: 'mypassword',
grant_type: 'password'
},
headers: {'Authorization': 'basic 123456789Aghtiaqq111kkksksksk111'}
}
)
.then((result) => {
my_token = result.data.access_token;
console.log("Token:", my_token);
my_formated_token = 'bearer ' + my_token;
console.log("Formated Token:", my_formated_token);
var my_headers = "{'Authorization': '" + my_formated_token + "'}";
console.log("My Headers:", my_headers);
});
//lets execute the callback from an agent
queuecallback({
method: 'post',
url: 'https://myapi.com/go',
data: {
phoneNumber: '1111111111',
skill: '12345'
},
headers: my_headers
}
)
.then((result) => {
console.log("your contactId is:", result.data.contactId);
});
}
});
It's not necesseray to require two axios :
const axios = require('axios');
const queuecallback = require('axios');
Your problem is that you set the headers in the first call
var my_headers = "{'Authorization': '" + my_formated_token + "'}";
axios is a asynchronous function so the queuecallback is called directly after the first axios call (which is not finished). You can use async function to "wait" the end of the first call :
const axios = require('axios');
async function connectToAgentHandler(agent) {
try {
let result = await axios({
method: 'post',
url: 'https://myapi.com/AuthorizationServer/Token',
data: {
username: 'myusername',
password: 'mypassword',
grant_type: 'password'
},
headers: {
'Authorization': 'basic 123456789Aghtiaqq111kkksksksk111'
}
});
const token = `bearer ${result.data.access_token}`;
const headers = {
'Authorization': token
};
result = axios({
method: 'post',
url: 'https://myapi.com/go',
data: {
phoneNumber: '1111111111',
skill: '12345'
},
headers
});
console.log("your contactId is:", result.data.contactId);
} catch (err) {
// process error
}
};
I'm trying to make an HTTP request on my server and check the result after.
Currently, I well have a result in the response object of the postCar method. But the result is null on the test on the then() method.
Where is the problem ?
postCar($access_token, $body) {
return new Cypress.Promise((resolve) => {
let bodyString = '';
cy.request({
method: 'POST',
url: '/applications',
form: true,
failOnStatusCode: false,
body: $body,
headers: {
Content: 'application/json',
Authorization: 'Bearer ' + $access_token
}
})
.then((response) => {
cy.log('Response = ' + JSON.stringify(response));
resolve(response);
});
});
}
My test:
it('Car Spec : create a car', function () {
let accessToken = Cypress.env('ACCESS_TOKEN')
var correct_body = getValidBody();
cy.postCar(accessToken, correct_body).then(function(res) {
cy.log('Application Spec : postCar response :' + JSON.stringify(res));
});
});
You shouldn't wrap the command in a Promise. Cypress Custom commands are not meant to return promises. Try just this:
function postCar ($access_token, $body) {
let bodyString = ''
cy.request({
method: 'POST',
url: '/applications',
form: true,
failOnStatusCode: false,
body: $body,
headers: {
Content: 'application/json',
Authorization: `Bearer ${$access_token}`,
},
})
.then((response) => {
cy.log(`Response = ${JSON.stringify(response)}`)
return response
})
}
I want to retrieve the JSON response from the api call I am doing. Example, I want to retrieve something like this:
{"error":{},"success":true,"data":{"user":"tom","password":"123","skill":"beginner","year":2019,"month":"Mar","day":31,"playmorning":0,"playafternoon":1,"playevening":1}}
This is my API call using fetch in react. (yes I know sending password in URL is bad, it's for a school project)
fetch('/api/user/'+ user + '?password=' + password, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then((res) => {
console.log(res); //I want to get the JSON stuff here
})
This is the API call I am calling.
app.get('/api/user/:user', function (req, res) {
// console.log(JSON.stringify(req));
// var user = req.body.user;
// var password = req.body.password;
var user = req.params.user;
var password = req.query.password;
console.log(user, password);
var result = { error: {} , success:false};
if(user==""){
result["error"]["user"]="user not supplied";
}
if(password==""){
result["error"]["password"]="password not supplied";
}
if(isEmptyObject(result["error"])){
let sql = 'SELECT * FROM user WHERE user=? and password=?;';
db.get(sql, [user, password], function (err, row){
if (err) {
res.status(500);
result["error"]["db"] = err.message;
} else if (row) {
res.status(200);
result.data = row;
result.success = true;
} else {
res.status(401);
result.success = false;
result["error"]["login"] = "login failed";
}
res.json(result);
});
} else {
res.status(400);
res.json(result);
}
});
When I do console.log(res) in the fetch call, this is what is printed:
Response {type: "basic", url: "http://localhost:3000/api/user/tim?password=123", redirected: false, status: 200, ok: true, …}body: (...)bodyUsed: falseheaders: Headers {}ok: trueredirected: falsestatus: 200statusText: "OK"type: "basic"url: "http://localhost:3000/api/user/tim?password=123"proto: Response
When I visit the website, the output is:
{"error":{},"success":true,"data":{"user":"tom","password":"123","skill":"beginner","year":2019,"month":"Mar","day":31,"playmorning":0,"playafternoon":1,"playevening":1}}
This is what I want.
In general, this is how you return the response body from the Promise.
fetch(`${baseUrl}/api/user/${user}?password=${password}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}})
.then(response => response.json())
.then(data=> {
console.log(data);
})
Try this way to parse the response:
fetch('/api/user/'+ user + '?password=' + password, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then(async (res) => {
const raw = await res.text();
const parsed = raw ? JSON.parse(raw) : { success: res.ok };
console.log(parsed);
})
In this case you can also add some checks for response statuses (if you want, of course) along with parsing the result JSON.
for you to get the JSON body content from the response, you need to use json()
fetch('/api/user/'+ user + '?password=' + password, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then((res) => {
const jsonData = res.json();
console.log(jsonData);
})
try this
fetch(${baseUrl}/api/user/${user}?password=${password},{
method:'GET',
headers: {
'Accept': 'application/json',
'Content-Type':
'application/json',
}}) .then(async(response ) => {
await response.json()
})