Cypress get the text of an API response parameter - api

I want to get the number from the URL located in an API response.
For that I get the URL, but I don't know how to convert that in to text to extract the number.
cy.intercept('GET', 'http://viasphere.localhost/documents/page_elements/client/**',).as('response')
goTo.plusClientsButton()
cy.wait('#response', {timeout: 10000})
cy.get('#response').then( xhr => {
const link = xhr.request.headers.referer
cy.log(link)
link has the value: http://viasphere.localhost/documents/page_elements/client/19537
Obviosly const link = xhr.request.headers.referer.text() is not working...

You have to add .replace(/^\D+/g, '') to extract the number from the url.
cy.intercept(
'GET',
'http://viasphere.localhost/documents/page_elements/client/**'
).as('response')
goTo.plusClientsButton()
cy.wait('#response', {timeout: 10000})
cy.get('#response').then((xhr) => {
const client_id = xhr.request.headers.referer.replace(/^\D+/g, '')
cy.log(client_id) //prints 19537
})

Alternatively to the .then() Alapan Das provided, you can use cypress commands to perform the same actions.
cy.intercept('GET', 'http://viasphere.localhost/documents/page_elements/client/**',).as('response')
goTo.plusClientsButton()
cy.wait('#response', {timeout: 10000})
// can access request.headers.referer from .wait()
.its('request.headers.referer')
// returns 'http://viasphere.localhost/documents/page_elements/client/'
.invoke('replace', /^D+/g, '')
// now you have the link and can print it
.then(cy.log)

Related

req.query returns nothing

Trying to get variable from http://localhost:3000/categories/subcategories?category_id=13 but req.query returns empty result.
app.get('/subcategories', (req, res) => {
let category_id = req.query.category_id
console.log(req.query)
db.query('SELECT subcategory_name FROM subcategories WHERE category_id=(?)',
[category_id],
(err, result) =>{
res.send({category_id})
});
})
Is this possibly a problem with the way I've set up my server?
See how you are passing the data , directly entering the data or from another URL you are passing the data.
Ensuring you are not sending data via req.body. Ref :
Empty req.query on ExpressJS
or check res.send({category_id}) . Try printing res.send({"category_id": category_id}) . or see console.log(JSON.stringify(req.query))
Or Extract Query Parameters Without Express
const url = require('url');
const querystring = require('querystring');
let rawUrl = 'https://stackabuse.com/?page=2&limit=3';
let parsedUrl = url.parse(rawUrl);
let parsedQs = querystring.parse(parsedUrl.query);
https://stackabuse.com/get-query-strings-and-parameters-in-express-js/

How "equals" in express-validator works?

I have to validate two fields are equals. In this case both passwords are the same. The problem it is that the "equals" from express-validator is not working.
This is the code:
app.post('/register', [
isNotLogged,
check('email', 'The email must be a valid one').isEmail(),
check('nickname', 'The nickname must be filled').notEmpty(),
check('password', 'The password must contain minimum eight characters, at least one letter and one number')
.matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"),
//This is not working
check('passwordConfirm', 'The passwords must match').equals('password'),
validateResults
], register)
Unfortunately Express-Validator doesn't work with Validator.js's equals(), you'll have to use one of Express-Validator's middlewares and not its Validator.js affility.
Here is an example straight from Express-Validator's website which seems fit your use case:
body('oldPassword')
// if the new password is provided...
.if((value, { req }) => req.body.newPassword)
// OR
.if(body('newPassword').exists())
// ...then the old password must be too...
.notEmpty()
// ...and they must not be equal.
.custom((value, { req }) => value !== req.body.newPassword);
You do not need to use Express-Validator's check middleware as you are throwing away your ability to utilise Validator.js's validators. Instead of check you could use isEmail() and exists() (an Express-Validator validator). Also, you don't need to have your middlewares as part of an array (although you can):
app.post('/register',
isNotLogged,
body('email').isEmail().withMessage('The email must be a valid one').bail().trim(),
body('nickname').exists({ checkNull: true }).withMessage('The nickname must be filled').bail().trim(),
body('password').trim().if((value, { req }) => (typeof req.body.passwordConfirm !== 'undefined')).bail().custom((value, { req }) => value !== req.body.passwordConfirm).withMessage('The email must be a valid one').bail().trim().matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"),
validateResults,
register
);
Here the body() function would come from const { body } = require('express-validator') theres a few others similar for query paramaters, header parameters ect, all are documented here.
I also used some trim()s and bails()s just to be safe. You can read up on those here and here.
I solve this problem like this:
code before:
const registrar = async (req, res) => {
await check('password').isLength({ min:6}).withMessage('password short ').run(req);
await check('repetir_password').equals('password').withMessage('password diferente?').run(req);
let resultado = validationResult(req);
res.json(resultado.array());
};
after:
correct code: change
'password'
by
req.body.password
const registrar = async (req, res) => {
await check('password').isLength({ min: 6 }).withMessage('password corta ').run(req);
await check('repetir_password').equals(req.body.password).withMessage('password diferente?').run(req);
let resultado = validationResult(req);
res.json(resultado.array());
};

Vue.js Nuxt - cannot access Array (value evaluated upon first expanding error)

I have the following function which gives me an array called URLs
const storageRef = this.$fire.storage.ref().child(fileName)
try {
const snapshot = storageRef.put(element).then((snapshot) => {
snapshot.ref.getDownloadURL().then((url) => {
urls.push(url)
})
})
console.log('File uploaded.')
} catch (e) {
console.log(e.message)
}
});
console.log(urls)
console.log("about to run enter time with imageurls length " + urls.length)
When I run console.log(URLs) initially I do see the array like the following
[]
0: "testvalue"
length: 1
__proto__: Array(0)
However, there is a small information icon stating
This value was evaluated upon first expanding. The value may have changed since.
Because of this, when I try to get the length of URLs, I get zero, meaning the value is being updated.
Does anyone know what's happening? I am using Vue.JS/Nuxt.

expressjs: How to catch all route parameters even if unknown?

Lets say I have this route.
this.app.use('/app/fileasset/ui.html/:view*?', function(req,res) {});
If I have this url: /app/fileasset/ui.html /test/view
Then I can catch them in req.params ==> req.params[0] (root url, 'test') and req.params.view ('view')
The question is: how can I catch an unknown numbers of parameters ?
For example: /app/fileasset/ui.html /test/view/subview/wtv
How to get 'subview' and 'wtv' in req.params ? and having the same route to catch longer url with unknown number of params ?
thanks in advance
ExpressJS routing does allow to use wildcards, if you do something like this:
this.app.use('/app/fileasset/ui.html/*', function(req,res) {});
Then going to a url like /app/fileasset/ui.html/test/view/subview/wtv should populate req.params with "['test/view/subview/wtv']" which you can easily split on the forward slash.
Do you tryed foreach over req.params?
req.params.forEach(function (item) {
someFn(item);
})
or just for
for (var i = 0, len = req.params.length; i < len; i++) {
someFn(req.params[i]);
}

Issue with BTC-e API in App Script, method parameter

I am trying to incorporate the BTC-e.com API in to a google docs spreadsheet.
The API documentation is here: https://btc-e.com/api/documentation
The method name is sent via POST parameter method.
As the URLFetchApp requires me to set the type of request as POST by a parameter method and I then have another parameter called method to be set as getInfo.
How can I go about setting the fetch method as POST and have the API parameter method as getInfo.
Below is the function this relates too. Also I am sure there a more issues in my work I am yet to find.
function inventory() {
var nonce=Number(SpreadsheetApp.getActiveSheet().getRange('K2').getValue());
var token=SpreadsheetApp.getActiveSheet().getRange('K1').getValue();
var tokenEndpoint = "https://btc-e.com/tapi";
var sign= 'TEMP'
var head = {
'Content-Type': 'application/x-www-form-urlencoded',
'Key': token,
'Sign': sign
}
var params = {
method : "POST",
method : "getInfo",
headers: head,
contentType: 'application/x-www-form-urlencoded',
method : "getInfo",
nonce: nonce
}
var request = UrlFetchApp.getRequest(tokenEndpoint, params);
var response = UrlFetchApp.fetch(tokenEndpoint, params);
var response2=String(response);
SpreadsheetApp.getActiveSheet().getRange('K2').setValue(nonce+1);
SpreadsheetApp.getActiveSheet().getRange('I16').setValue(response2);
SpreadsheetApp.getActiveSheet().getRange('I17').setValue(nonce);
}
This just yields the error
Attribute provided with invalid value: method
Thanks,
Steve
PS: First time posting, I tried to get the format correct.
I made the following Google JavaScript function to do POST access to BTC-e. You can find this function in action in the example spreadsheet I made to demonstrate the BTC-e API functions.
function btceHttpPost(keyPair, method, params, nonce) {
if (keyPair === undefined) {
return "{'error':'missing key pair'}"
}
if (params === undefined) {
params = '';
}
// Cleanup keypair, remove all \s (any whitespace)
var keyPair = keyPair.replace(/[\s]/g, '');
// Keypair example: "AFE730YV-S9A4FXBJ-NQ12HXS9-CA3S3MPM-CKQLU0PG,96a00f086824ddfddd9085a5c32b8a7b225657ae2fe9c4483b4c109fab6bf1a7"
keyPair = keyPair.split(',');
var pubKey = keyPair[0];
var privKey = keyPair[1];
// As specified on the BTC-e api (https://btc-e.com/api/documentation) the
// nonce POST parameter must be an incrementing integer (>0). The easiest
// implementation is the use of a timestamp (TS), so there is no need
// for persistant storage. Preferable, the resolution of the TS should be
// small enough the handle the desired call-frequency (a sleep of the TS
// resolution can fix this but I don't like such a waste). Another
// consideration is the sizeof the nonce supported by BTC-e. Experiments
// revealed this is a 32 bit unsigned number. The native JavaScript TS,
// stored in a float, can be 53 bits and has a resolution of 1 ms.
if (nonce === undefined)
// This time stamp counts amount of 200ms ticks starting from Jan 1st, 2014 UTC
// On 22 Mar 2041 01:17:39 UTC, it will overflow the 32 bits and will fail
// the nonce key for BTC-e
var nonce = Math.floor((Date.now() - Date.UTC(2014,0)) / 200);
// Construct payload message
var msg = 'nonce=' + nonce + '&method=' + method + params;
var msgSign = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, msg, privKey);
// Convert encoded message from byte[] to hex string
for (var msgSignHex = [], i = 0; i < msgSign.length; i++) {
// Doing it nibble by nibble makes sure we keep leading zero's
msgSignHex.push(((msgSign[i] >>> 4) & 0xF).toString(16));
msgSignHex.push((msgSign[i] & 0xF).toString(16));
}
msgSignHex = msgSignHex.join('');
var httpHeaders = {'Key': pubKey, 'Sign': msgSignHex};
var fetchOptions = {'method': 'post', 'headers': httpHeaders, 'payload': msg};
var reponse = UrlFetchApp.fetch('https://btc-e.com/tapi', fetchOptions);
return reponse.getContentText();
};
The problem looks to be with your params object . You have method set thrice in the same object, which is a source of confusion.
Next, take a look at the documentation for UrlFetchApp.fetch() ( https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object) ) . The method can take a value of post, get, delete, put.
The getInfo should probably be appended to your URL to make it
var tokenEndpoint = "https://btc-e.com/tapi/getInfo"
Per the docs, you also have to put in more parameters to the request, nonce, api key etc. Use this as a starting point, revisit the documentation and get back to SO if you still have trouble