Jest not generating values correctly using crypto - reactjs

I made a function to generate a complex password using window.crypto lib, this work perfectly and return values like jQzPN%c#tr71ie6Dt^C8.
Here is my function :
const genPwd = (length: number): string => {
const regex = /^(?=.*[A-Z])(?=.*[!##$%^&*])(?=.*[0-9]).{8,}$/;
const charset =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!##$%^&*()_-+={[}]|:;<,>.?/';
let result = '';
let values = new Uint32Array(length);
window.crypto.getRandomValues(values);
for (let i = 0; i < length; i++) {
result += charset[values[i] % charset.length];
}
if (!regex.test(result)) {
console.log('result', result);
return genPwd(length);
} else {
return result;
}
};
But when I try to test this function using Jest, it falls everytime in the last condition because it doesn't match the regex, the console.log shows "AAAAAAAAAAAAAAAAAAAA", like nothing is generating correctly, so it doesn't match the regex and looping.
Here is my test :
it('should generate a x length password', () => {
const mGetRandomValues = jest.fn().mockReturnValueOnce(new Uint32Array(20));
Object.defineProperty(globalThis, 'crypto', {
value: { getRandomValues: mGetRandomValues },
});
const valueToConvert = utils.genPwd(20);
const valueToFind = 20;
expect(valueToConvert).toHaveLength(valueToFind);
expect(mGetRandomValues).toBeCalledWith(new Uint32Array(valueToFind));
});
Does anyone have a solution ?
I have no idea about this issue

Related

How to Write a 'removeZeros' function that accepts an integer n and returns this integer without zeros in javascript?

This is the code i have so far but the mate academy platform rejects it
function removeZeros(n) {
let nStr = n.toString();
let nStrArr = nStr.split('');
let nStrArrNoZeros = [];
for (var i = 0; i < nStrArr.length; i++) {
if (nStrArr[i] !== '0') {
nStrArrNoZeros.push(nStrArr[i]);
}
}
return parseInt(nStrArrNoZeros.join(''));
}
You can simply use below code.
Hope it would be help to you.
const removeZeros = (str) => {
return parseInt(str.replace(/0/g, ''));
}

Display the name of the subjects and their marks after pushing to new array

HERE IS MY CODE,
let subjects: string[] = ['Mathemetics-70', 'Science-67', 'English-88', 'Geography-62', 'ComputerSc-55'];
function uppercase(subject: string) {
return subject.toUpperCase();
}
let subjects_upppercase = subjects
.map(uppercase)
.toString()
.match(/\d+/g)
.map(function (numbers) {
return parseInt(numbers);
})
.filter(function (number) {
if (number > 65) {
return true;
}
})
.map(function (newarray) {
return newarray;
});
console.log(subjects_upppercase);
I have an array of numbers [70,67,88]
now I want to print names of subjects corresponding to the numbers inside an array.
can someone help with this, please?
here is a solution (I didnt quite get what your requirements where but here you go)
const subjects: string[] = ["Mathemetics-70","Science-67","English-88","Geography-62","ComputerSc-55"];
const pairs = subjects.map(subject => {
const subjectNumber = subject.match( /\d+/);
if (!subjectNumber) return undefined;
return [parseInt(subjectNumber[0]), subject.toUpperCase()]
}).filter(Boolean)
const obj = Object.fromEntries(pairs);
console.log(obj); // this will be { number: subject }
// and if you want to print only your numbers use
const toPrint = [70,67,88];
for (let numberToPrint of toPrint){
console.log(obj[numberToPrint]);
}
It is my solution, the code is:
let subjects: string[] = ['Mathemetics-70', 'Science-67', 'English-88', 'Geography-62', 'ComputerSc-55'];
const str = subjects.join("\n");
const arr = [70, 67, 88].map((num) => {
return str.match(new RegExp("(\\w+\-)" + num))[0];
});
console.log(arr);
// ['Mathemetics-70', 'Science-67', 'English-88']

Combining a loop function and IF condition in google app scirpt

New to google app script and trying to create a function which combines loop (can be map, for or forEach) and IF condition.
See public spreadsheet for data: https://docs.google.com/spreadsheets/d/1V7CpCxBH0lg6wi1TAhfZJP5gXE8hj7ivQ8_ULxLSLgs/edit?usp=sharing
I wish to create an array inside a variable. In this array I want all quantity of column "D" but only if column "C" is "Buy".
This is the code I have tried but it comes back empty:
const ss = SpreadsheetApp.getActiveSpreadsheet();
const historySheet = ss.getSheetByName('Blad1');
function quantBuy () {
const searchRange = historySheet.getRange(3,2,historySheet.getLastRow()-1, 2)
let rangeValues = searchRange.getValues();
for (i = 0; i < historySheet.getLastRow()-1; i++) {
if (rangeValues[i] === 'Buy') {
console.log(i);
}}}
Any help is appreciated.
getValues is 2 demiensional
function quantBuy () {
const searchRange = historySheet.getRange(3,3,historySheet.getLastRow()-1, 2)
let rangeValues = searchRange.getValues();
for (let i = 0; i < rangeValues.length; i++) {
if (rangeValues[i][0] === 'Buy') {
console.log(rangeValues[i][1]);
}
}
}

Execute methods sequence - React

I have written following code to get current user group Ids and later from that Ids I wanted to filter data from SharePoint list. First I want to execute
ServiceManager.getRemoteService().getCurrentUserGroups()
method. Once I get group Ids, I want to execute the next method. But unfortunately filter part of the REST query is blank because
this.groupIdString
is blank. This may be because both methods are executed same time. I'm new to React and I want to know is there any best approach to manage this scenario. Basically I want to execute the methods in the order I write.
public componentDidMount() {
this.groupIdString= "";
ServiceManager.getRemoteService().getCurrentUserGroups(this.props.siteUrl, "/_api/web/currentuser/groups").then((value) => {
if (value[0]) {
for (let i: number = 0; i < value.length; i++) {
if(value[i].Id != undefined){
this.groupIdString += "(UserGroupsId eq " + value[i].Id.toString()+")";
}
}
}
});
const restQuery = "/_api/Web/Lists/GetByTitle('Weather')/Items?$select=Title,NewsBody,UserGroupsId&$filter=("+this.groupIdString+")";
ServiceManager.getRemoteService().getWeatherListItems(this.props.siteUrl, restQuery).then((value) => {
if (value[0]) {
//code
}
});
}
#Sivakumar Piratheeban,
You can put the second request in the callback of the first call.
public componentDidMount() {
this.groupIdString = "";
ServiceManager.getRemoteService().getCurrentUserGroups(this.props.siteUrl, "/_api/web/currentuser/groups").then((value) => {
if (value[0]) {
for (let i: number = 0; i < value.length; i++) {
if (value[i].Id != undefined) {
this.groupIdString += "(UserGroupsId eq " + value[i].Id.toString() + ")";
}
}
// Second
const restQuery = "/_api/Web/Lists/GetByTitle('Weather')/Items?$select=Title,NewsBody,UserGroupsId&$filter=(" + this.groupIdString + ")";
ServiceManager.getRemoteService().getWeatherListItems(this.props.siteUrl, restQuery).then((value) => {
if (value[0]) {
//code
}
});
//
}
});
}
BR

How to convert JSON to URL params string as per my expected value?

I am working on an angular project. For a method getting a response JSON to convert stringify and POST a body to an API is done. Now the problem is for another one function I should send this value as a URL parameter I tried some ways but didn't get expected result. Please find the below codes and help me out. Thanks
Here is my JSON format value
const bodyJSON = [{FullPackageIDs:[11,7],
PartialPkg:[
{PackageID:4,
FormsList:[
{Form_Name:"Form name One"},
{Form_Name:"Form name Two"}]},
{PackageID:6,
FormsList:[
{Form_Name:"Form name Three"},
{Form_Name:"Form name Four"},
{Form_Name:"Form name Five"}
]
}
]
}]
My expected URL string value like below
http://localhost:4200/DownloadPackage?FullPackageIDs[0]=11&FullPackageIDs[1]=7&PartialPkg[0].PackageID=4&PartialPkg[0].FormsList[0].Form_Name=Form name One&PartialPkg[0].FormsList[1].Form_Name=Form name Two&PartialPkg[1].PackageID=6&PartialPkg[0].FormsList[0].Form_Name=Form name Three&PartialPkg[1].FormsList[1].Form_Name=Form name Four&PartialPkg[2].FormsList[2].Form_Name=Form name Five
I tried via forloop but didnt get expected result. Here is the code for what I tried.
for (let i = 0; i < getSelectedId.length; i++) {
fullPackageParams = `${fullPackageParams}FullPackageIDs[${i}]=${getSelectedId[i]}&`;
for (let j = 0; j < getPartialId.length; j++) {
// const getPartialName = this.partialPackage.map(res => res[i].FormsList);
const getPartialName = getPartialId[j].FormsList;
partialPackageIDParams = `${partialPackageIDParams}PartialPkg[${j}].PackageID=${getPartialId[j].PackageID}&`;
for (let index = 0; index < getPartialName.length; index++) {
partialPackageNameParams = `PartialPkg[${index}].FormsList[${index}].Form_Name=${getPartialName[index].Form_Name}&`;
}
}
}
console.log('params for full packages', fullPackageParams + partialPackageIDParams + partialPackageNameParams);
even if it seems kinda strange to me that you need to pass all of those params using query, you can try this
it just uses ES6 map, reduce functions to create your query string
let URLQuery = bodyJSON.map(value => {
const packageIDs = value.FullPackageIDs.map((v, i) => `FullPackageIDs[${i}]=${encodeURIComponent(v)}`);
const partialPkgs = value.PartialPkg.map((v, i) => {
const startKey = `PartialPkg[${i}]`;
return [
`${startKey}.PackageID=${v.PackageID}`
].concat(
v.FormsList.map((v, i) => `${startKey}.FormsList[${i}].Form_Name=${encodeURIComponent(v.Form_Name)}`)
);
}).reduce((arr, v) => {
return arr.concat(v)
}, []);
return packageIDs.concat(partialPkgs);
}).reduce((arr, v) => {
return arr.concat(v);
}, []).join("&");
const fullURL = `https://example.com?${URLQuery}`;

Resources