Node red crashing when use http request to call a webservice - javascript

I'm having a problem developing a node that makes web service calls.
I'm using:
Node-RED version: v0.17.5
Node.js version: v8.4.0
It is throwing that exception
node-red_1 | 30 Aug 21:21:50 - [red] Uncaught Exception:
node-red_1 | 30 Aug 21:21:50 - TypeError: Cannot set property listening of #<Server> which has only a getter
node-red_1 | at _clone (/usr/src/node-red/node_modules/clone/clone.js:156:16)
node-red_1 | at _clone (/usr/src/node-red/node_modules/clone/clone.js:156:18)
node-red_1 | at _clone (/usr/src/node-red/node_modules/clone/clone.js:156:18)
node-red_1 | at _clone (/usr/src/node-red/node_modules/clone/clone.js:156:18)
node-red_1 | at _clone (/usr/src/node-red/node_modules/clone/clone.js:156:18)
node-red_1 | at clone (/usr/src/node-red/node_modules/clone/clone.js:196:10)
node-red_1 | at Object.cloneMessage (/usr/src/node-red/node_modules/node-red/red/runtime/util.js:53:13)
node-red_1 | at /usr/src/node-red/node_modules/node-red/red/runtime/nodes/flows/Flow.js:262:48
node-red_1 | at Array.forEach (<anonymous>)
node-red_1 | at Flow.handleError (/usr/src/node-red/node_modules/node-red/red/runtime/nodes/flows/Flow.js:256:34)
I have a list of data that I need to POST to a webservice.
Everything works fine until I fire my HTTP post.
Basically, I have this snippet of code
const objects = msg.payload || []
const hpptCalls = objects.map(obj => (callback) => {
processObject(obj, callback)
})
async.parallelLimit(hpptCalls, 5, (err, results) => {
node.send(msg)
})
Inside my processObject function, I have almost the same code that exists in core node 21-httprequest.js
const req = http.request(options, res => {
let data = ''
res.on('data', chunk => {
data += chunk
})
res.on('end', () => {
callback(null)
})
})
req.setTimeout(120000, () => {
node.error('Error', msg)
req.abort()
callback('Error')
})
req.on('error', err => {
node.error(err, msg)
callback(err)
})
if (content) {
req.write(JSON.stringify(content))
}
req.end()
But, it seems that when the first HTTP post is called, my node-red crash entirely with that exception. I can figure what is the problem. I put a lot o try catches thinking that my code is breaking something, but it is a straightforward code.

Apparently found the problem, as mentioned in project's github. At a random point in the flow, someone put a function node with the following code
return {
"_msg": msg
[other properties]
}
Thanks! (It was hard to find the problem lol, we have a big flow).

Related

Why java script fs.readFileSync is not getting mocked?

i have a fs.readFileSync function that i need to mock using jest.
i have tried the below code.
my original file which i want to test.
const fs = require('fs');
const read_file = (path) => {
try {
const data = fs.readFileSync(path, 'utf8');
return data;
} catch (err) {
console.error('Error in read_file', err);
throw err;
}
};
const getSecret = secretName => {
try {
return read_file(`/etc/secrets/${secretName}.txt`);
} catch (err){
throw err;
}
};
const secretConfig = {
kafka_keystore_password: getSecret('kafka_keystore_password')
};
module.exports = secretConfig;
here is my test case
const secret = require('./secret');
let fs = require('fs')
jest.mock('fs');
describe('secret read files', () => {
afterEach(jest.restoreAllMocks);
it('should read secret from file', () => {
//fs.readFileSync.mockReturnValue("randomPrivateKey");
fs.readFileSync.mockResolvedValue("randomPrivateKey")
const secretMessage = secret.kafka_keystore_password;
//expect(fs.readFileSync).toHaveBeenCalled();
expect(secretMessage).toEqual('randomPrivateKey');
})
})
describe('getSecretsFromFile', () => {
const secret = 'secret';
const secrets = { mySecret: secret };
afterEach(jest.restoreAllMocks);
it('returns secrets if file is present', () => {
fs.existsSync.mockReturnValue(true);
fs.readFileSync.mockReturnValue('randomPrivateKey');
const secretMessage = secret.kafka_keystore_password;
expect(secretMessage).toEqual('randomPrivateKey');
});
});
and i get the following error.
FAIL src/config/secret.test.js ● secret read files › should read
secret from file
expect(received).toEqual(expected) // deep equality
Expected: "randomPrivateKey"
Received: undefined
15 | const secretMessage = secret.kafka_keystore_password;
16 | //expect(fs.readFileSync).toHaveBeenCalled();
> 17 | expect(secretMessage).toEqual('randomPrivateKey');
| ^
18 |
19 | })
20 |
at Object.<anonymous> (src/config/secret.test.js:17:27)
● getSecretsFromFile › returns secrets if file is present
expect(received).toEqual(expected) // deep equality
Expected: "randomPrivateKey"
Received: undefined
32 |
33 | const secretMessage = secret.kafka_keystore_password;
> 34 | expect(secretMessage).toEqual('randomPrivateKey');
| ^
35 | });
36 | });
37 |
at Object.<anonymous> (src/config/secret.test.js:34:29)
help me fix this .
try:
const fs = {
readFileSync: jest.fn(() => ({ message: 'Test'}))
}
to mock the fs readFileSync message.
But I don't see how this test is ever going to pass because you're returning value "Test"
but checking for randomPrivateKey
expect(secretMessage).toEqual('randomPrivateKey');
Without seeing what's going on inside the code it's difficult to say but I am assuming you might want to change that line to:
expect(secretMessage).toEqual('test');
As test is the value your mocking alternatively return randomPrivateKey from the mock.
I'm having to make a load of assumptions here because I don't know-how
secret.kafka_keystore_password is calculated. I'm assuming it just returns the whatever the fs.readFileSync returns.7

SyntaxError: Unexpected token { in JSON at position 101033 at JSON.parse (<anonymous>) fix?

So I am trying to complete the open source mission in TwilioQuest but I can't becuase the terminal gives me an error when I run this command:
git commit -m "feat(pixels): add my new pixel"
It tells me there is an error in one of the scripts which is this one and its written in Javascript:
const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const { sortPixels, pixelsToString } = require('../utils/pixels-helper');
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
const pixelFilePath = path.join('_data', 'pixels.json');
readFile(pixelFilePath, { encoding: 'utf8' })
.then(pixelFileData => {
const pixels = JSON.parse(pixelFileData);
const sortedPixelString = pixelsToString(sortPixels(pixels));
writeFile(pixelFilePath, sortedPixelString);
})
.catch(console.log);
The error it gives me for this script is this:
SyntaxError: Unexpected token { in JSON at position 101033
at JSON.parse (<anonymous>)
8 | const filePath = path.resolve(__dirname, '../_data/', dataJsonFile);
9 | const pixelJsonString = await readFile(filePath, 'utf8');
> 10 | return JSON.parse(pixelJsonString);
| ^
11 | }
12 |
13 | describe('pixels', () => {
What is this error about and how can I fix it?
Regarding git features in this matter : this error is triggered by a custom script, most probably .git/hooks/pre-commit.
You may open .git/hooks/pre-commit in an editor to view how your code is tested, and execute in your terminal .git/hooks/pre-commit to see if the test passes or fails.
Regarding javascript debugging : use your regular tools and methods to debug.
For example :
you may add console.log(filePath) before calling JSON.parse, to see which file was opened, or console.log(pixelJsonString) to see what is returned from your function,
you may use a node debugger to follow you program's execution
...

Jest - Testing for AWS Lambda

I'm trying to use Jest with my NodeJS based AWS Lambda function to test that the Lambda handler function is returning specific status codes. It seems like using lambda-tester is the easiest way to achieve this.
handler.test.js
const handler = require('../src/handler.js');
const LambdaTester = require('lambda-tester');
test('should return a StatusCode of 400 due to requirement not being met', function (done) {
return LambdaTester(handler.run)
.event({})
.expectResult(result => {
expect(result.statusCode).toBe(400);
});
});
I thought that would be pretty straightforward however I get this as a result:
expect(received).toBe(expected) // Object.is equality
Expected: 400
Received: 500
7 | .event({})
8 | .expectResult(result => {
> 9 | expect(result.statusCode).toBe(400);
| ^
10 | });
11 | });
12 |
at tests/handler.test.js:9:33
at runVerifier (node_modules/lambda-tester/lib/runner.js:121:16)
at LambdaRunner.run (node_modules/lambda-tester/lib/runner.js:277:23)
If I change the expect line to check for a statuscode of 500 I get an Async timeout:
Timeout - Async callback was not invoked within the 5000 ms timeout
specified by jest.setTimeout.Timeout
Any ideas as to why this isn't working?
The lambda should fail instantly because the event being passed in doesnt have a required attribute and it indeed does when tested via Postman.
Edit:
This lambda is part of a serverless application and could be tested locally, how could I use Jest to do that?
I was over thinking it, the below is working well:
test('should return a StatusCode of 400 due to requirement not being met', async () => {
const event = {};
const context = {};
const result = await handler.run(event, context);
expect(result.statusCode).toBe(400)
expect(result.headers)
});

Error: Protocol JSON API error running Lighthouse with TestCafe Server

I am trying to write code that will spin up a TestCafe Server, log into an authenticated page, navigate to the page I want, and then execute Lighthouse against that page.
Here is my testcafeServer.js file:
const createTestCafe = require('testcafe');
let testcafe = null;
createTestCafe('localhost', 1337, 1338)
.then((tc) => {
testcafe = tc;
const runner = testcafe.createRunner();
return runner.src(['test_lightHouse.js']).browsers(['chrome']).run();
})
.then((failedCount) => {
console.log('Tests failed: ' + failedCount);
testcafe.close();
});
Here is my test_lighthouse.js file:
import { Selector } from 'testcafe';
var fs = require('fs');
const lighthouse = require('lighthouse');
fixture`LightHouse Test`.page(
'MY-SPECIFIC-URL'
);
test(`Generate Light House Result `, async (t) => {
//Specific code to navigate to a certain page
const auditResult = await lighthouse(
'MY-CURRENT-URL-I-WANT-TO-TEST',
{
logLevel: 'info',
output: 'html',
port: 1337, //I am getting this port # from the TestCafe server I am standing up locally - might be wrong
}
);
// Write data in 'Output.txt' .
fs.writeFile('mynewfile3.html', auditResult, function (err) {
if (err) throw err;
console.log('Saved!');
});
console.log(auditResult);
});
When executing this code, I get the following error:
✖ Generate Light House Result
1) Error: Protocol JSON API error (list), status: 404
Browser: Chrome 80.0.3987.163 / macOS 10.15.4
102 | return resolve({message: data});
103 | }
104 | return reject(e);
105 | }
106 | }
> 107 | reject(new Error(`Protocol JSON API error (${command}), status: ${response.statusCode}`));
108 | });
109 | });
110 |
111 | // This error handler is critical to ensuring Lighthouse exits cleanly even when Chrome crashes.
112 | // See https://github.com/GoogleChrome/lighthouse/pull/8583.
What is going wrong? Why does this constantly happen? Is Lighthouse just not meant to work with TestCafe?
Currently, there is no simple way to integrate lighthouse with TestCafe. Please track the following issue in the TestCafe repository to be notified of our results: https://github.com/DevExpress/testcafe/issues/3493.
Also, you can try the approach shown here: https://stackoverflow.com/a/55447097/10684943, but it may work incorrectly with authentication pages.

jest test emitting events for eventemitter objects (http)

assume the following nodejs code
const server = http.listen(8080,'127.0.0.1')
.on("error", err => {
// ...
})
module.exports = server;
how to write a test using jest to emit the http "error" event (to cover the error event handler)?
Since you create a server in module scope, the code will execute immediately when you require or import server.js. You need to stub the http.createServer before you require this module.
For testing .on(error, callback) method, you should use mockImplementation or mockImplementationOnce, so when the mocked server calls the mocked .on('error', callback), you will get the original callback in your test case. Which means handler is equivalent to callback. When you call handler(mError), the mocked error object will be passed into the original callback. Then you can use this mError test your code logic.
Here is the unit test solution:
server.js:
const http = require('http');
const server = http.createServer();
server.listen(8080, '127.0.0.1').on('error', (err) => {
console.log(err);
});
module.exports = server;
server.test.js:
const http = require('http');
describe('60435647', () => {
it('should handle error', () => {
const mError = new Error('network');
const mServer = {
listen: jest.fn().mockReturnThis(),
on: jest.fn().mockImplementationOnce((event, handler) => {
// handler is the original callback, the mError variable will be passed into the original callback.
handler(mError);
}),
};
const createServerSpy = jest.spyOn(http, 'createServer').mockImplementationOnce(() => mServer);
const logSpy = jest.spyOn(console, 'log');
require('./server');
expect(createServerSpy).toBeCalledTimes(1);
expect(mServer.listen).toBeCalledWith(8080, '127.0.0.1');
expect(mServer.on).toBeCalledWith('error', expect.any(Function));
expect(logSpy).toBeCalledWith(mError);
});
});
Unit test results with 100% coverage:
PASS stackoverflow/60435647/server.test.js
60435647
✓ should handle error (459ms)
console.log node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866
Error: network
at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/stackoverflow/60435647/server.test.js:5:20)
at Object.asyncJestTest (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
at resolve (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
at new Promise (<anonymous>)
at mapper (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
at promise.then (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
at process._tickCallback (internal/process/next_tick.js:68:7)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
server.js | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.772s, estimated 6s

Categories

Resources