I am writing test cases for Javascript using mocha. My code exactly looks like this apigee
This javascript is deployed in apigee cloud. Where it has access to platform variables. This is myscript my-code.js
var responseCode = parseInt(context.getVariable(properties.source));
var log = {
org: context.getVariable(organization.name),
env: context.getVariable(environment.name),
responseCode: responseCode,
isError: (responseCode >= 400)
};
if (log.isError) {
log.errorMessage = context.getVariable(flow.error.message);
}
var logglyRequest = new Request(
'https://loggly.com/aaa',
'POST',
{'Content-Type': 'application/json'},
JSON.stringify(log)
);
httpClient.send(logglyRequest);
javascript code would have access to properties.source at run time. Apigee platform has its own internal way of how jc access those params. My question is if I am writing test case for this jc, how would I mock the values for properties.source. I am able to mock function call context.getVariable(). I am getting ReferenceError: properties is not defined. Test script in same in the apigee link given.
Try adding the following to your tests:
global.properties = {
source: 'jwt.Decode-IAM-JWT.decoded.header.kid'
};
That is what I do and it works fine.
Related
In the code presented below, I am trying to interact with a database through the use of a js function within the karate framework. The query used to get some data works as expected, likewise auxiliary information is accessible. The same function within the js file can be ran through groovy just fine but seems to explode when ran within karate.
JS Function to be ran in karate through a callSingle():
function() { let dbUser = Java.type('dev.dao.dbUser') return dbUser.getId(karate.properties['username'])
dbUser:
class dbUser {
static Integer getId(String email) {
db.sql.firstRow("select user_id from table.db_user where email = ?", [email]).userId
}
}
Karate-config.js
function fn() {
let config = {
project: karate.properties['vs.project'],
environment: karate.properties['vs.environment'],
baseUrl: karate.properties['vs.baseUrl'],
timeZoneId: karate.properties['vs.timeZoneId'],
env: karate.properties['vs.env'],
proxy: {
...
]
},
demoUserId: 1,
userId: karate.callSingle('classpath:proj/dev/js/dao/getDbUserId.js'),
createDBuid: karate.read('classpath:proj/dev/js/createDBuid.js'),
DBuid: karate.callonce('classpath:proj/dev/js/createDBuid.js')
}
}
Error returned calling the getDbUserId.js:
PolyglotError
<<<<
org.graalvm.polyglot.PolyglotException
com.intuit.karate.core.ScenarioBridge.callSingle(ScenarioBridge.java:243)
com.intuit.karate.core.ScenarioBridge.callSingle(ScenarioBridge.java:187)
.fn(Unnamed:18)
I am trying to string a few Postman requests together for testing.
In the first request I set a global variable as a test script.
tests['Status code is 200'] = (responseCode.code === 200);
if (responseCode.code === 200) {
try {
let jwt = responseBody.replace(/"/g, '');
pm.globals.set("jwt", jwt);
console.log("Variable will be set to", jwt);
}
catch(e) {
console.log(e);
}
}
In the second request I run a pre-request script as
let jwt = pm.globals.get("jwt");
Then I try to pass it into the header
Is it possible to pass a value into the header when running tests in the runner?
When running tests in the Runner the second request fails due to having an invalid jwt, and the Postman docs only show examples passing variables into the URL.
It's covered in postman auth.
Authenticate to get the JWT(oken) - Token API request
Add the test in to capture the token
var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("jwt", jsonData.token);
Authorization > Type > Bearer Token
Token: {{jwt}}
Setup your Environment
Select the Environment
Select Keep variable values from the Collection Runner dialog (if you are running it in command line)
Note: I'm using version 6.3.0.
I'm a beginner in Amazon's Lambda-API implementations.
I'm just deploying a very simple API: a very simple lambda function with Python 2.7 printing "Hello World" that I trigger with API Gateway. However, when I click on the Invoke URL link, it tells me "{"message": "Internal server error"}".
Thus, I'm trying to see what is wrong here, so I click on the API itself and I can see the following being grey in my Method Execution: "Integration Response: Proxy integrations cannot be configured to transform responses."
I have tested many different configurations but I still face the same error. I have no idea why this step is grey.
I had the same problem when trying to integrate API gateway and lambda function. Basically, after spending a couple of hours, I figure out.
So when you were creating a new resource or method the Use Lambda Proxy integration was set by default.
So you need to remove this. Follow to Integration Request and untick the Use Lambda Proxy integration
you will see the following picture
Then in you Resources, Atction tab, choose Enable CORS
Once this done Deploy your API once again and test function. Also, this topic will explain what's happening under the hood.
Good luck...
The Lambda response should be in a specific format for API gateway to process. You could find details in the post. https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/
exports.handler = (event, context, callback) => {
var responseBody = {
"key3": "value3",
"key2": "value2",
"key1": "value1"
};
var response = {
"statusCode": 200,
"headers": {
"my_header": "my_value"
},
"body": JSON.stringify(responseBody),
"isBase64Encoded": false
};
callback(null, response);
My API was working in Postman but not locally when I was developing the front end. I was getting the same errors when trying to enable CORS on my resources for GET, POST and OPTIONS and after searching all over #aditya answer got me on the right track but I had to tweak my code slightly.
I needed to add the res.statusCodeand the two headers and it started working.
// GET
// get all myModel
app.get('/models/', (req, res) => {
const query = 'SELECT * FROM MyTable'
pool.query(query, (err, results, fields) => {
//...
const models = [...results]
const response = {
data: models,
message: 'All models successfully retrieved.',
}
//****** needed to add the next 3 lines
res.statusCode = 200;
res.setHeader('content-type', 'application/json');
res.setHeader('Access-Control-Allow-Origin', '*');
res.send(response)
})
})
If you re using terraform for aws resource provision you can set the
"aws_api_gateway_integration" type = "AWS" instead of "AWS_PROXY" and that should resolve your problem.
Just finished breakfast and already hit a snag. I'm trying to call the salesforce REST api from my google sheets. I've written a working script locally in python, but converting it into JS, something went wrong:
function authenticateSF(){
var url = 'https://login.salesforce.com/services/oauth2/token';
var options = {
grant_type:'password',
client_id:'XXXXXXXXXXX',
client_secret:'111111111111',
username:'ITSME#smee.com',
password:'smee'
};
var results = UrlFetchApp.fetch(url, options);
}
Here is the error response:
Request failed for https://login.salesforce.com/services/oauth2/token
returned code 400. Truncated server response:
{"error_description":"grant type not
supported","error":"unsupported_grant_type"} (use muteHttpExceptions
option to examine full response) (line 12, file "Code")
Mind you, these exact parameters work fine in my local python script (putting the key values inside quotations).
Here are the relevant docs:
Google Script: Connecting to external API's
Salesforce: REST API guide
Thank you all!
Google's UrlFetchApp object automatically defaults to a GET request. To authenticate, you have to explicitly set in the options the method "post":
function authenticateSF(){
var url = 'https://login.salesforce.com/services/oauth2/token';
var payload = {
'grant_type':'password',
'client_id':'XXXXXXXXXXX',
'client_secret':'111111111111',
'username':'ITSME#smee.com',
'password':'smee'
};
var options = {
'method':'post',
'payload':payload
};
var results = UrlFetchApp.fetch(url, options);
}
I tried lot of examples available in the net using node module wcf.js. But could not get any appropriate result. I'm using the below url
https://webservice.kareo.com/services/soap/2.1/KareoServices.svc?wsdl
Any one who can explain me with the help of code will be really helpful. I want to know how to access the wsdl in node.js
Thanks.
Please have a look at wcf.js
In short you can follow these steps:
npm install wcf.js
Write your code like this:
code
var Proxy = require('wcf.js').Proxy;
var BasicHttpBinding = require('wcf.js').BasicHttpBinding;
var binding = new BasicHttpBinding();
//Ensure the proxy variable created below has a working wsdl link that actually loads wsdl
var proxy = new Proxy(binding, "http://YourHost/YourService.svc?wsdl");
/*Ensure your message below looks like a valid working SOAP UI request*/
var message = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:sil='http://YourNamespace'>" +
"<soapenv:Header/>" +
"<soapenv:Body>" +
"<sil:YourMethod>" +
"<sil:YourParameter1>83015348-b9dc-41e5-afe2-85e19d3703f9</sil:YourParameter1>" +
"<sil:YourParameter2>IMUT</sil:YourParameter2>" +
"</sil:YourMethod>" +
"</soapenv:Body>" +
"</soapenv:Envelope>";
/*The message that you created above, ensure it works properly in SOAP UI rather copy a working request from SOAP UI*/
/*proxy.send's second argument is the soap action; you can find the soap action in your wsdl*/
proxy.send(message, "http://YourNamespace/IYourService/YourMethod", function (response, ctx) {
console.log(response);
/*Your response is in xml and which can either be used as it is of you can parse it to JSON etc.....*/
});
You don't have that many options.
You'll probably want to use one of:
node-soap
douche
soapjs
i tried node-soap to get INR USD rate with following code.
app.get('/getcurr', function(req, res) {
var soap = require('soap');
var args = {FromCurrency: 'USD', ToCurrency: 'INR'};
var url = "http://www.webservicex.net/CurrencyConvertor.asmx?WSDL";
soap.createClient(url, function(err, client) {
client.ConversionRate(args, function(err, result) {
console.log(result);
});
});
});
Code Project has got a neat sample which uses wcf.js for which api's are wcf like so no need to learn new paradigm.
I think that an alternative would be to:
use a tool such as SoapUI to record input and output xml messages
use node request to form input xml message to send (POST) the request to the web service (note that standard javascript templating mechanisms such as ejs or mustache could help you here) and finally
use an XML parser to deserialize response data to JavaScript objects
Yes, this is a rather dirty and low level approach but it should work without problems
You'll probably want to use one of:
node-soap
douche
soapjs
Aslo, there's an existing question.
In my case, I used https://www.npmjs.com/package/soap. By default forceSoap12Headers option was set to false which prevented node-soap to generate correct soap message according to SOAP 1.2. Check for more details: I am confused about SOAP namespaces. After I set it to true, I was able to make a call to .NET WCF service. Here is a TypeScript code snipper that worked for me.
import * as soap from 'soap';
import { IOptions } from 'soap';
// ...
const url = 'https://www.your-domain.com/stock.svc?wsdl';
const opt: IOptions = {
forceSoap12Headers: true,
};
soap.createClient(url, opt, (err, client: soap.Client) => {
if (err) {
throw err;
}
const wsSecurityOptions = {
hasTimeStamp: false,
};
const wsSecurity = new soap.WSSecurity('username', 'password', wsSecurityOptions);
client.setSecurity(wsSecurity);
client.addSoapHeader({ Action: 'http://tempuri.org/API/GetStockDetail' }, undefined, 'wsa', 'http://www.w3.org/2005/08/addressing');
client.addSoapHeader({ To: 'https://www.your-domain.com/stock.svc' }, undefined, 'wsa', 'http://www.w3.org/2005/08/addressing');
const args = {
symbol: 'GOOG',
};
client.GetStockDetail(
args,
(requestErr, result) => {
if (requestErr) {
throw requestErr;
}
console.log(result);
},
);
});
Here couple links to the documentation of node-soap usage:
https://github.com/vpulim/node-soap/tree/master/test
https://github.com/vpulim/node-soap