How to easily test redux-observable epic that emits an action after 5 minutes? - testing

I have an epic that emits SOME_OTHER_ACTION when 5 minutes have passed after SOME_ACTION (using delay operator).
I want to use jest or sinon useFakeTimers method to be able to do the following: dispatch an action, wait 5 minutes and test if another action was dispatched.
I really don't want to use marble diagrams, or inject TestSchedulers.
I also don't want to wait 5 minutes of real time.
const timeBefore = new Date().getTime() / 1000;
store.dispatch(SOME_ACTION);
// wait 5 minutes
jest.runTimersToTime(5 * 60 * 1000);
expect(store.getActions()).toEqual([ SOME_ACTION, SOME_OTHER_ACTION ]);
expect(store.getActions()[1].time).toEqual(timeBefore + 5 * 60 * 1000);

So what I ended up doing is: replaced RxJS with xstream, and used adapter for redux-observable, modified my epics accordingly.
It turns out that Jest doesn't handle Date correctly when using fakeTimers, so I used lolex for fake timers.
See my gist for full example.
(I didn't find easy way to test or replace internal RxJS delay, so I had to use different reactive library).
clock.setTimeout(() => {
expect(store.getActions()).toEqual([trainIncomingAction, reminderAction]);
done();
}, 60 * 60 * 1001);
clock.runToLast();

Related

Vesting gradually in seconds in Hardhat (Solidity)

I have been studying vesting schedules in blockchain lately. I wanted to test if the implementation of vesting works correctly. First i made a test that has duration of 24 months and cliff duration of 6 months. After testing everything worked correctly, so I decided to create another test but in seconds. Here is the implementation:
it("Should be able to vest gradually (in seconds)", async () => {
// deploy vesting contract
let tokenVesting: TokenVesting = await new TokenVesting__factory(owner).deploy();
await tokenVesting.deployed();
await tokenVesting.initialize();
// send tokens to vesting contract
await expect(saleToken.transfer(tokenVesting.address, 1000))
.to.emit(saleToken, "Transfer")
.withArgs(owner.address, tokenVesting.address, 1000)
const currentBlock = await hh.ethers.provider.getBlock(await hh.ethers.provider.getBlockNumber());
let now: number = currentBlock.timestamp;
let vestingId = "vesting id";
let initiallyReleasablePercentage = 0;
let startTime: number = now + 1; // current time
let duration: number = 10; // 10 seconds
let cliffDuration: number = 4; // 4 seconds
let slicePeriodSeconds = 1; // 1 second
await tokenVesting.createVesting(
vestingId,
saleToken.address,
startTime,
duration,
cliffDuration,
initiallyReleasablePercentage,
slicePeriodSeconds
);
await saleToken.connect(owner).approve(tokenVesting.address, hh.ethers.utils.parseUnits("10", 18));
await tokenVesting.vest(vestingId, owner.address, hh.ethers.utils.parseUnits("10", 18));
/**
* vested amount should be 0 for the next 4 seconds, because cliff duration is 4 seconds
*/
expect(await tokenVesting.getReleasableAmount(tokenVesting.address, vestingId)).to.equal(0);
/**
* go ahead by 5 seconds -> current time is 5 seconds,
* should be able to vest 5 tokens because it reached cliff start time
*/
await hh.ethers.provider.send("evm_increaseTime", [5]);
await hh.ethers.provider.send("evm_mine", []);
expect(await tokenVesting.getReleasableAmount(owner.address, vestingId)).to.be.equal(5);
}
In this code first 10 lines are for deploying vesting contract and sending tokens to it. Then get current time using block.timestamp. Then I create fields that will be used to createVesting. duration is the total duration of a vesting, cliffDuration is cliff time, so time after which we can vest tokens and slicePeriodSeconds is the time that we have to wait after the previous release. Then under the tokenVesting.createVesting I send tokens to the user that will be tested and the amount is 10 and then testing starts.
Here is the problem
First test works fine because the releasable amount is 0. But then when I jump to the future by 5 seconds and test it, the test cracks. It shows that the releasable amount is 7 tokens but it should be 5 because we jumped to the middle of the token vesting period and total amount of tokens is 10.
My thoughts
It got me thinking that in these tests, time does not stop. It is going further. So when I jump by 5 second it logs time before and after creating vesting but when i m trying to getReleasableAmount the time passed and in this function gives me wrong amount of tokens. I don not really know if this is correct it is just my assumption.
Is it possible to somehow stop the time in hardhat testing after evm_increaseTime? When I tested the code but evm_increase_time was in months everything worked and releasable amount was as expected. But trying to test it in seconds when total vesting time is 10 seconds and cliff duration is 4 seconds it is not working as expected.
Has anybody had similar problem or know the solution to that (e.g. stopping the time in hardhat or something else)?

Postman running the same request multiple times

I want to run the same request multi times with different pre-request scripts? Any idea how can I do it without using the Data Driven (CSV) test?
Eg., I have to run the below GET url multiple times (every 2 minutes) but whenever I run this, I need to have a different pre request tests!
{{url}}/legacy/COL
enter image description here
Onetime operation:
If you want to send request 10 times (including first request 11) , then create two environment variables that contains the count. you can create the variables by simply copy pasting the below two lines in pre-request or test script ( remove all other code).
pm.environment.set("repeat",10);
pm.environment.set("repeat",10);
Once the variables are added remove the above lines from script.
Now in test script:
we can sendrequest multiple time by using pm.sendrequest or pm.setNextrequest. Here the example shows calling same request 10 more times using pm.setNextRequest.
The delay of 2mins or 3 mins can be set using the setTimeout javascript function which waits the mentioned time (here 3 seconds ) before executing the code inside that. so the setNextrequest will executed only after 3 sec in this case you can change it to 2 mins.
let repeatTemp = pm.environment.get("repeatTemp");
if (repeatTemp === 0) {
pm.environment.set("repeatTemp", pm.environment.get("repeat"));
} else {
let repeatTemp = pm.environment.get("repeatTemp")
let increment = pm.environment.get("increment")===0?15:pm.environment.get("increment")+5
pm.environment.set("increment",increment)
pm.environment.set("repeatTemp", repeatTemp-1);
setTimeout(function () { postman.setNextRequest("something") }, 3000);
}
so if your request name is "yourrequestname" then it will send this request 1+10 times
Pre-request script:
in your format you mentioned yyyy-mm which is wrong mm stands for minutes not month for year-month you have to give capital YYYY-MM
let repeatTemp = pm.environment.get("repeatTemp");
let repeat = pm.environment.get("repeat");
if (repeatTemp===repeat) {
pm.environment.set("increment", 0)
}
let moment = require('moment')
pm.environment.set('estimatedTimeArrival', moment().add(30 + pm.environment.get("increment"), 'minutes').format("YYYY-MM-DDThh:mm:ss"));
pm.environment.set('estimatedTimeDeparture', moment().add(2, 'hours').format("YYYY-MM-DDThh:mm:ss"));
pm.environment.set('scheduledTimeArrival', moment().add(10, 'minutes').format("YYYY-MM-DDThh:mm:ss"));
console.log(pm.environment.get('increment'))
console.log(pm.environment.get('estimatedTimeArrival'))
output:

how to send random local notification message in react-native?

I have an app that needs to send out notification/s everyday with random messages to user depending on how many notification they want (up to 5 notifs per day) and between what time they want (for example notifications will fire only between 6:00am - 9:00am everyday).
To elaborate I'm building a functionality with an idea to send out random inspirational messages that I'm pulling from a hardcoded array variable or json file.
Currently I'm using this package: https://github.com/zo0r/react-native-push-notification to create local notification.
I tried the idea of setting a function that returns a string for the message parameter of localNotificationSchedule, but when I do this, instead of using a regular string, it's not showing the notification.
PushNotification.localNotificationSchedule({
id : '1',
userInfo : { id: userId },
message : () => {
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); //trying to return random string every time notification fires.
},
date : moment(Date.now()).add(2, 'seconds').toDate(),
repeatType : 'day',
});
I considered using other approach such as react-native headless JS but it's for android only.
Also considered using https://www.npmjs.com/package/react-native-background-fetch. But I have a complex interval for notifications. For example, the user might set the notification to run from 6:00am - 6:30am everyday and set to fire 5 notifications. In this interval, notifications will run every 6 mins.
But react-native-background-fetch' minimal interval is only 15 minutes.
I know that this can be done by using a push notification instead, but with that, user will need a connection in order for them to receive a notification, which is not ideal for this case.
Iv'e seen this from an Ios app so I know this is possible to achieve.
As per the dev, you can try calling PushNotification.localNotificationSchedule multiple times.
What I've done is this:
const messages = [{text:'',time:0}...];
messages.map(message=>{
PushNotification.localNotificationSchedule({
//... You can use all the options from localNotifications
channelId: "my-channel",
message: message.text, // (required)
date: new Date(Date.now() + (60 + message.time) * 1000), // in 60 secs
});
})
to show a message from the messages array separated by 5 seconds.

How to call function every 60 seconds in Polymer 2.x

I wish to call a function in Polymer element every 60 seconds to autosave to persist a result in database (let's assume that DB operations will happen within 60 secs). How can this be achieved in Polymer?
is setTimeout() a good option? how to use it call a function every 60 seconds which is part of polymer element?
setTimeout(async () => {...},6000); // how to make this function called every 60 seconds?
I wish to have a polymer 2x function being called every x time interval
You can use setInterval for that.

How to use assertions for multiple scenario in gatling?

Right Now I am trying to do performance testing of all my api's.I already created one feature file having different scenarios(every scenario having different tag).Now I want to do use assertions on mean ResponseTime with different scenarios different assertions.
val Performance1 = scenario("Performance1").exec(karateFeature("classpath:mock/Testing1.feature#Performance"))
val Performance2 = scenario("Performance2").exec(karateFeature("classpath:mock/Testing2.feature#v3ContentMeta"))
val v4SearchTest = scenario("SearchTest").
group("SearchTesting") { exec(karateFeature("classpath:mock/Testing1.feature#Performance"))
}
setUp(
(Performance1.inject(rampUsers(10) over (5 seconds)).protocols(protocol)),
Performance2.inject(rampUsers(10) over (5 seconds)).protocols(protocol)
).assertions(details("SearchTesting").responseTime.mean.lte(680))```
You can add Gatling assertions as Global asserts. This will perfectly work with Karate Gatling. This is a sample scenario which we tried
setUp(
firstScenario.inject(
nothingFor(5 seconds), // Pause for a given duration
atOnceUsers(10), //Inject 10 Users at once
constantUsersPerSec(10) during (20 seconds), // Induce 10 requests on every second and continues this process for 30 seconds
rampUsers(10) over (10 seconds) // Linear Ramp up of the user
).protocols(protocol),
secondScenario.inject(
nothingFor(10 seconds), // Pause for a given duration
atOnceUsers(20), // Inject 10 Users at once
constantUsersPerSec(10) during (10 seconds), // Induce 10 requests on every second and continues this process for 40 seconds
).protocols(protocol),
thirdScenario.inject(
nothingFor(15 seconds), // Pause for a given duration
rampUsers(20) over (1 minute) // Linear Ramp up of the user
).protocols(protocol),
fourthScenario.inject(
nothingFor(20 seconds), // Pause for a given duration
constantUsersPerSec(10) during (20 seconds), // Induce 10 requests on every second and continues this process for 20 seconds
).protocols(protocol)
).assertions(
global.responseTime.max.between(100, 5000),
global.failedRequests.percent.is(0),
global.successfulRequests.percent.gt(90)
).maxDuration(10 minutes) // Configuring the maximum duration of your simulation. It is useful when we need to bound the duration the simulation when we can’t predict it.
The global asserts will be displayed as a separate section in the Gatling reports. This is a useful feature of Karate Gatling. Test specific failures will also get displayed in the report of Karate Gatling. For example, if this is your scenario
Scenario: My First Sample Scenario
Given url endpointUrl
And header karate-name = 'Feature 1_Scenario3'
When method get
Then status 200
And if the status code is not responded as 200, this also gets recorded in the Karate Gatling reports.
Asserts in Gatling: https://gatling.io/docs/current/general/assertions/#scope