jest tobeCalled is not working as expected - javascript

i have mokced a response object like
export const mockResponse = () => {
let res = {};
res["status"] = jest.fn().mockReturnValue(res);
res["json"] = jest.fn().mockReturnValue(res);
res["redirect"] = jest.fn().mockReturnValue(res);
return res;
};
and called it like res = mockResponse();
the mocking works fine i get all the function in it
i have calling the redirect function in the actual function
return res.redirect(url);
and i am expecting it toBeCalled
i have tried debuging the redirect function is itself calling but jest won't getting it
expect(jest.fn()).toBeCalled()
Expected number of calls: >= 1
Received number of calls: 0
> 159 | expect(res.redirect).toBeCalled();
| ^
160 | });
161 | });
162 |
does anybody know why is this happening

Related

Requesting and reading JSON from Yahoo Finance with a generic function

My knowledge of javascript is limited. However, with much reading I was able to hack together the functions below. The goal is to define a generic function with which I can extract certain data from Yahoo finance.
In the example below, I'm pulling in A LOT of JSON data for any ticker (example link at the bottom). From the returned JSON, I select which values I'm interested in (here only dividendRate and paypoutRatio. If you call this function in a cell (I use Google Sheets), it will return 2 cells with the requested information:
=yFinance("KO")
+------+
| 1.76 |
+------+
| 0.75 |
+------+
Link used: Yahoo Finance JSON for Coca Cola
What I need, however, is to have the data formatted not in 2 cells BELOW each other, but NEXT TO each other:
=yFinance("KO")
+------+------+
| 1.76 | 0.75 |
+------+------+
I have two questions:
How can the code (probably in getMatchingValues()?) be updated to make this happen?
Is there any way to simplify these functions?
Any help is greatly appreciated, also because I feel that a generic function like this would benefit many people in the future. I have seen many posts about extracting a single value from Yahoo Finance, mostly by parsing the HTML (tables) using Google Sheets INDEX() function, but I believe via the JSON is faster and more resistent to future front-end changes at Yahoo.
function yFinance(symbol) {
const url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(symbol)
+ '?modules=price,assetProfile,summaryDetail,incomeStatementHistory,'
+ 'balanceSheetHistory,defaultKeyStatistics,financialData,calendarEvents,'
+ 'recommendationTrend,upgradeDowngradeHistory,majorHoldersBreakdown'
;
const response = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
const responseCode = response.getResponseCode();
if (responseCode === 200) {
const quote = JSON.parse(response.getContentText());
const paths = [
'summaryDetail/dividendRate/raw',
'summaryDetail/payoutRatio/raw'
];
return getMatchingValues(getPath(quote, 'quoteSummary/result/0'), paths);
}
else
{
return -1;
}
}
function getPath( obj, path ) {
if (!path || !obj) {
return null;
}
const parts = path.split('/');
const currentPath = parts[0];
const nextPath = parts.slice(1).join('/');
const currentObj = obj[currentPath];
// final path, exit here
if (nextPath.length === 0) {
return currentObj;
}
if (Array.isArray( currentObj )) {
// does an element exit at the next level
if ( currentObj[parts[1]] ) {
// will continue reading for 1 element
return getPath( currentObj, nextPath );
}
// return all the subpaths, skip the ones that are falsy
return currentObj.map( item => getPath( item, nextPath ) ).filter( v => v );
}
// get the next part of the object
return getPath( currentObj, nextPath );
}
function getMatchingValues( obj, paths ) {
return paths.flatMap( path => getPath( obj, path ));
}
If you want to get side by side values, modify by adding brackets as follows
return [getMatchingValues(getPath(quote, 'quoteSummary/result/0'), paths)];
You can simplify the code as follows
function yFinance_new(symbol) {
const url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(symbol)
+ '?modules=price,assetProfile,summaryDetail,incomeStatementHistory,'
+ 'balanceSheetHistory,defaultKeyStatistics,financialData,calendarEvents,'
+ 'recommendationTrend,upgradeDowngradeHistory,majorHoldersBreakdown'
;
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const responseCode = response.getResponseCode();
if (responseCode === 200) {
const quote = JSON.parse(response.getContentText());
return [[
quote.quoteSummary.result[0].summaryDetail.dividendRate.raw,
quote.quoteSummary.result[0].summaryDetail.payoutRatio.raw
]];
}
else {
return -1;
}
}

Getting a 'Cannot read property 'on' of undefined' when calling a function in a class in a node module

Here's my code:
From the module's index.js:
class TSL5 extends EventEmitter {
constructor () {
super()
//Message Format
this._PBC = 0 //offset
this._VER = 2
this._FLAGS = 3
this._SCREEN = 4
this._INDEX = 6
this._CONTROL = 8
this._LENGTH = 10
}
listenUDP(port) {
this.server = dgram.createSocket('udp4')
this.server.bind(port)
this.server.on('message',(msg, rinfo) => {
this.processTally(msg,rinfo)
debug('Message recieved: ', msg)
})
this.server.on('listening', () => {
var address = this.server.address();
debug(`server listening ${address.address}:${address.port}`);
});
this.server.on('error', (err) => {
debug('server error: ', err);
throw err;
});
return this.server;
}
processTally(data,rinfo) {
let buf = Buffer.from(data)
let tally = { display: {} }
tally.sender = rinfo.address
tally.pbc = buf.readInt16LE(this._PBC)
tally.ver = buf.readInt8(this._VER)
tally.flags = buf.readInt8(this._VER)
tally.screen = buf.readInt16LE(this._SCREEN)
tally.index = buf.readInt16LE(this._INDEX)
tally.control = buf.readInt16LE(this._CONTROL)
tally.length = buf.readInt16LE(this._LENGTH)
tally.display.text = buf.toString('ascii', this._LENGTH+2)
tally.display.rh_tally = (tally.control >> 0 & 0b11);
tally.display.text_tally = (tally.control >> 2 & 0b11);
tally.display.lh_tally = (tally.control >> 4 & 0b11);
tally.display.brightness = (tally.control >> 6 & 0b11);
tally.display.reserved = (tally.control >> 8 & 0b1111111);
tally.display.control_data = (tally.control >> 15 & 0b1);
this.emit('message',tally)
}
and then the server side index.js:
let umd = new TSL5;
for (let i = 0; i < source_connections.length; i++) {
if (source_connections[i].sourceId === sourceId) {
AddPort(port, sourceId);
logger(`Source: ${source.name} Creating TSL 5.0 UDP Connection.`, 'info-quiet');
//source_connections[i].server = dgram.createSocket('udp4');
//source_connections[i].server.bind(port);
source_connections[i].server = umd.listenUDP(port);
source_connections[i].server.on('message', function (message) {
processTSL5Tally(sourceId, message);
});
logger(`Source: ${source.name} TSL 5.0 Server started. Listening for data on UDP Port: ${port}`, 'info');
for (let j = 0; j < sources.length; j++) {
if (sources[j].id === sourceId) {
sources[j].connected = true;
break;
}
}
UpdateSockets('sources');
UpdateCloud('sources');
break;
}
}
Whenever I try to call the function that the lower block of code is in, then I get the Cannot read property 'on' of undefined error. The only way to get the error to go away is add a return this.server to the listenUDP function. If I do this however, then all of the data that function is supposed to emit through the processTally function is lost.
Your current issue is caused by those lines:
source_connections[i].server = umd.listenUDP(port);
source_connections[i].server.on('message', function (message) {
processTSL5Tally(sourceId, message);
});
source_connections[i].server is the result of calling listenUDP. Therefore if you do not return the server (through return this.server), then there's nothing to call .on upon.
And returning the server is causing another issue that you have:
// in processTally
this.emit('message',tally)
But inside your loop, you're calling
source_connections[i].server.on('message', function (message) {
The event emitter itself is emitting this new "message", but you are still listening on the "event emitter's server". The emitter (TSL5 class) is a wrapper over the server. So instead of listening on the server's message, you should listen on the event emitter, that emits "message" as well, that is the result of working on the internal server's message:
// just the emitter, not the server
source_connections[i].on('message', function (message) {
processTSL5Tally(sourceId, message);
});
As a side note - just remember you're having a single instance for the emitter. Therefore if that loops runs multiple times (for different connections), things will get scrambled. Therefore you'd probably need to create new emitter for each iteration, but not sure if that's your case.

How to generate new random value for each scenario in protractor node js

Am able to generate a random string in protractor node js BDD framework.But the problem is, the same value is being hold for all the scenarios when batch execution is triggered and the tests are getting failing because of the same value used in all the scenarios.Can someone please suggest how to generate new random value everytime a scenario is invoked during batch execution and the same value should be passed for all the methods for that scenario.
Note : I have declared it as global variable to be used across the methods for a particular scenario.
this
// 1.spec.js
let generateString = (length) => {
let letters = 'abcdefghijklmnopqrstuvwxyz',
str = '';
for (let i = 0; i < length; i++) {
str += letters[Math.floor(Math.random() * letters.length)];
}
return str;
}
let randomString = generateString(7);
describe(`Scenario`, () => {
it('1', async () => {
console.log(randomString);
});
it('2', async () => {
console.log(randomString);
});
it('3', async () => {
console.log(randomString);
});
});
will produce this
Jasmine started
saxijqt
Scenario
✓ 1 (0.014 sec)
saxijqt
✓ 2 (0.035 sec)
saxijqt
✓ 3 (0.01 sec)

React-Native Child of object returns undefined despite it exists

I am having a very basic but mind blowing issue that i cant figure out. Here is this:
Short summary of problem
I got receipt object coming from IAP, but cant get productId child. It returns undefined ? How can it happen ? receipt.productID returns undefined despite receipt object its ok and has a productId child which is not undefined. It should perfectly return me 'lite_plan' but it returns undefined?
initIAP = () => {
RNIap.initConnection().then(() => {
RNIap.flushFailedPurchasesCachedAsPendingAndroid().catch(() => {
}).then(() => {
console.log('open listener')
this.purchaseUpdateSubscription = purchaseUpdatedListener((purchase: InAppPurchase | SubscriptionPurchase | ProductPurchase ) => {
console.log('purchaseUpdatedListener', purchase);
var receipt = purchase.transactionReceipt;
if (receipt) {
console.log('receipt >> ' + receipt)
console.log('product id >> ' + receipt.productId)
AsyncStorage.setItem('activeplan_local', receipt.productId).then(() => {
.....
console output:
receipt >> {"orderId":"****","packageName":"com.****","productId":"lite_plan","purchaseTime":1617193622753,"purchaseState":0,"purchaseToken":"*****","autoRenewing":true,"acknowledged":false}
product id >> undefined
Can you show me the issue ?
Thanks for your support
You could try this -
this.purchaseUpdateSubscription = purchaseUpdatedListener(async (purchase: InAppPurchase | SubscriptionPurchase | ProductPurchase ) => {
console.log('purchaseUpdatedListener', purchase);
// use const instead of var
const receipt = await purchase.transactionReceipt;
if (receipt) {
console.log('receipt >> ' + receipt)
console.log('product id >> ' + receipt.productId)
AsyncStorage.setItem('activeplan_local', receipt.productId).then(() => {
Found the solution like this:
var receiptObject = JSON.parse(receipt)
var productId = JSON.parse(receipt).productId
Still could not figure out why i needed to parse receipt object. It was already an object. Strange but working this way.

Unit testing: Input/output

I am trying to run a unit test for the following code: This code below only checks if the function is true.
Here is the Unit testing code:
import {encodeLengthHex, toHex } from './utils';
// testing new function
describe('EncodeLengthHex', () => { //mocking the method
test('Testing Function toHex ', () => { // declaring the method
const str = 128 // initial value
const actual = encodeLengthHex(str) // calculate the value
expect(actual).toMatchSnapshot(); // checking whether is true
})
});
Here is the main code:
export function encodeLengthHex(n) {
if (n <= 127) {
return toHex(n);
}
const nHex = toHex(n);
const lengthOfLengthByte = 128 + nHex.length / 2;
return toHex(lengthOfLengthByte) + nHex;
Function is passing. But how could I add a few inputs to test and compare when this function pass or fail. Thanks

Categories

Resources