GraphQL : Auto renew is creating duplicates - mongodb

I have created a MERN employee management system where employers can assign task to employees have it able to change status(pending, overdue and submitted). And created recurring tasks which renew everyday automatically
So the idea is to create a resolver, which finds all Tasks. Once all tasks are found, it needs to check if any are over due and set the status of the task to overdue and the look for recurring Tasks
Recurring tasks are to renew automatically when the due date of the task has reached
I was Successful in achieving this but now for some reason the tasks are duplicating
i.e., if there is task
Expected
"send sales report" due on 24th mar 2022
so when it renews for the next day it should be
"send sales report" due on 25th mar 2022
But it duplicates
Current
"send sales report" due on 24th mar 2022
so when it renews for the next day it is
"send sales report" due on 25th mar 2022
"send sales report" due on 25th mar 2022
Sometimes it is creating duplicates, sometime it is creating triplets and some times quadruples
Attaching resolver below.
tasks : async () => {
const today = new Date()
const todayunix = Date.parse(today)
const allTasks = await Task.find({}).populate('user').sort({ status: 1 });
const recuurringTask = allTasks.filter((task)=> task.recurring === true)
const checkStatus = allTasks.filter((task) => task.status === 'pending')
if (today.getDay() !== 1) {
for (let i = 0; i < checkStatus.length; i++){
if(checkStatus[i].dueDate < todayunix){
const overdue = await Task.findByIdAndUpdate({_id : checkStatus[i]._id},{status:'overdue'})
}
}
for(let i = 0; i < recuurringTask.length; i++){
const fDueDate= new Date(recuurringTask[i].dueDate)
const fDueDateUnix = Date.parse(fDueDate)
if(fDueDateUnix < todayunix) {
const dueInDays = 86400000 * recuurringTask[i].renewIn
const calcDueDate = dueInDays + todayunix
const task = {
description: recuurringTask[i].description,
user: recuurringTask[i].user,
dueDate: new Date(calcDueDate),
recurring: recuurringTask[i].recurring,
renewIn:recuurringTask[i].renewIn
};
const createTask = await Task.create(task)
const setRecurringFalse = await Task.findOneAndUpdate({_id:recuurringTask[i]._id},{recurring:false})
}
}
}
return allTasks
},

Related

sendAndConfirmTransaction bug?

In my application I use the signatures returned from web3.sendAndConfirmTransaction to do some offline/async reporting relating to the fees incurred by my transactions.
i.e. i use the signature to retrieve the transaction and then use the transaction?.meta?.fee field.
I have noticed though, when my transaction contains 2 instructions (in my example below) that the signature returned only contains the fee relating to 1 of the instructions. When I check the transaction history of my phantom wallet I can clearly see 2 separate fees - one for each instruction
async createTokenMetadataForToken(
business,
token_type
) {
const mint_authority = web3.Keypair.fromSeed(
derivePath(
`m/44'/501'/0'/0'`,
Bip39.mnemonicToSeedSync(
JSON.parse(business.keys).MINTER_SEED
).toString("hex")
).key
);
const metadata = await Metadata.getPDA(token_type.token_address);
const host = (config.nodeEnv == 'prod') ? 'https://<url>' : 'https://<url>'
const createMetadataTx = new CreateMetadataV2(
{ feePayer: mint_authority.publicKey },
{
metadata,
metadataData: new DataV2({
uri: `${host}/token_type/${token_type.token_type_id}/metadata`,
name: token_type.name,
symbol: token_type.symbol,
sellerFeeBasisPoints: 100,
creators: null,
collection: null,
uses: null,
tokenStandard: TokenStandard.FungibleAsset,
}),
updateAuthority: mint_authority.publicKey,
mint: new web3.PublicKey(token_type.token_address),
mintAuthority: mint_authority.publicKey,
}
);
const connection = getConnection(token_type.cluster);
const transaction = new web3.Transaction();
console.log("creating metadata")
transaction.add(createMetadataTx)
if(token_type?.equity_total_supply > 0){
console.log("also creating equity in same trx..")
//look up token
const token = new Token(
connection,
new web3.PublicKey(token_type.token_address),
TOKEN_PROGRAM_ID,
mint_authority
);
const recipientTokenAddress = await token.getOrCreateAssociatedAccountInfo(
new web3.PublicKey(mint_authority.publicKey)
);
transaction.add(
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
new web3.PublicKey(token_type.token_address),
recipientTokenAddress.address,
mint_authority.publicKey,
[mint_authority],
token_type?.equity_total_supply
)
)
}
const sig = await web3.sendAndConfirmTransaction(connection, transaction, [mint_authority], {
skipPreflight: false
})
return sig; //This signature only contains fee of one of the parts of the transaction
}

Cypress crashes when test that uses gmail-tester library finished it work

I'm was trying to use "gmail-tester" library to verify the account creation message.
https://www.npmjs.com/package/gmail-tester
It seems that I settled up everything as it was supposed to be done. When my test is finished I supposed to get an assertion in cypress such as this
Instead, cypress is awaiting for a message for 30seconds
, then browser crashes and I got this
Does anyone know what would cause the problem?
I have managed to complete all steps mentioned in this tutorial:
https://levz0r.medium.com/how-to-poll-a-gmail-inbox-in-cypress-io-a4286cfdb888
../cypress/plugins.index.js
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* #type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
const path = require("path");
const gmail = require("gmail-tester");
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
// ...
on("task", {
"gmail:check": async args => {
const { from, to, subject } = args;
const email = await gmail.check_inbox(
path.resolve(__dirname, "credentials.json"), // credentials.json is inside plugins/ directory.
path.resolve(__dirname, "gmail_token.json"), // gmail_token.json is inside plugins/ directory.
subject,
from,
to,
10, // Poll interval (in seconds)
12 // Maximum poll interval (in seconds). If reached, return null, indicating the completion of the task().
);
return email;
}
});
};
testCase.spec.js
import Navigation from '../../../utils/navigation.spec'
import LoginPage from '../../../pageobject/login/login-page'
describe("New user registration", async function() {
beforeEach(() => {
cy.visit(Navigation.Login)
})
it.only("Reset Form: Email is delievered", function() {
const test_id = new Date().getTime();
const incoming_mailbox = `userautomatedtest+${test_id}#gmail.com`;
// const password = uuidv1().split("-")[0];
const login = new LoginPage();
const username = "Cypress" + test_id;
const password = "111#wZOO";
login.registerButton()
.usernameInput(username)
.emailInput(incoming_mailbox)
.firstNameInput("Name")
.lastNameInput("Surname")
.passwordInput(password)
.repeatPasswordInput(password)
.registerButton()
//assert
cy.contains('Registration succeeded').should('be.visible')
cy.task("gmail:check", {
from: "dev.mailer.no.reply#gmail.com",
to: incoming_mailbox,
subject: "Registration confirmation"
})
.then(email => {
assert.isNotNull(email, `Email was not found`);
});
});
});
btw: in documentation is mentioned that by changing this number we can manipulate awaiting time for checking email. In my case, I'm changing this value and nothing is happening.
This is some problem with the OAuth consent screen, probably access given is not correct, or the GMail API isn't enabled.
Using the most recent version of this package, I had the same issue with the plugins/index.js crashing.
I solved this by adjusting the options-parameter to match the gmail task package function check_inbox.
module.exports = (on, config) => {
on("task", {
"gmail:check": async (args) => {
const { from, to, subject } = args;
const email = await gmail.check_inbox(
path.resolve(__dirname, "credentials.json"),
path.resolve(__dirname, "gmail_token.json"),
{
subject: subject,
from: from,
to: to,
wait_time_sec: 10,
max_wait_time_sec: 30,
}
);
return email;
},
});
};

Facebook photo upload date timestamp

I've downloaded all my Facebook data and wish to upload some of the images that I've sent via Messenger to Google Photos. I wish to have them to have the correct metadata so they are uploaded under the correct day, not under today. Unfortunately, they have the date of download for Date created.
I tried parsing the title, but it doesn't seem to be a timestamp.
My question is: is there a way to create a script that adds the correct metadata to a photo downloaded from Facebook (via Download your information archive)? An example title is: 142666616_209126620919024_535058535265435125_n.jpg. This photo should have the date Jan 27, 2021, 10:53 AM.
After some digging I found a solution.
The archive that Facebook gives you has folders for each friend with the following structure:
\friend_name_a1b2c3
\photos
12345678_123456788996_123124421.jpg
\gifs
\audio
messages_1.json
messages_1.json has all your messages with that friend and here is an example how a message looks like:
{
"sender_name": "Your Name",
"timestamp_ms": 1562647443588,
"photos": [
{
"uri": "messages/inbox/friend_name_a1b2c3/photos/12345678_123456788996_123124421.jpg",
"creation_timestamp": 1562647443
}
],
"type": "Generic",
"is_unsent": false
},
So, using glob and utimes I came up with the following script:
var glob = require("glob")
var Promise = require('bluebird');
var fs = Promise.promisifyAll(require("fs"));
var { utimes } = require("utimes");
const readJSONFiles = async () => {
const messagesFiles = glob.sync(`**/message_*.json`)
const promises = [];
messagesFiles.forEach(mFile => {
promises.push(fs.readFileAsync(mFile, 'utf8'));
})
return Promise.all(promises);
}
readJSONFiles().then(result => {
const map = {};
result.forEach(data => {
const messagesContents = JSON.parse(data);
messagesContents.messages
.filter(m => m.photos)
.forEach(m => {
m.photos.filter(p => {
const splitted = p.uri.split("/")
const messagePhotoFileName = splitted[splitted.length - 1];
map[messagePhotoFileName] = m.timestamp_ms;
})
})
})
fs.writeFileSync("./map.json", JSON.stringify(map))
}).then(() => {
fs.readFileAsync("./map.json", 'utf8').then(data => {
const map = JSON.parse(data);
glob("**/*.jpg", function (er, files) {
files.forEach(file => {
const [, , photo] = file.split("/");
utimes(file, {
btime: map[photo],
atime: map[photo],
mtime: map[photo]
});
})
})
})
});
It creates a map of file-name:date-taken then loops over all .jpg files and changes its metadata. It definitely is a little rough around the edges but gets the job done, after all.

How do I set timeout for LocalNotification

How do I set timeout like example I want the notification to be
Trigger start from (27 Nov 2020, 12pm)
Subsequently every one hour until 28 Nov 2020, 12pm.
Without reopening the app, heres my codes.
var mySchedule: LocalNotificationSchedule = {
on:"27 Nov 2020, 12pm",
repeats: true,
every: 'hour',
count:1,
#until : "28 Nov 2020, 12pm"
};
var notification={};
notification["title"]="Local Notification Test";
notification["body"]="Example body";
notification["id"]="2";
notification["schedule"]=mySchedule;
notification["sound"]="default";
this.localNoti.push(notification);
const notifs = await LocalNotifications.schedule({
notifications: this.localNoti
});

Why subsequent tests for ngmocke2e failed to call mock backend. Only the first test would pass. Second test would call the real backend

Why subsequent tests for ngmocke2e failed to call mock backend? Only the first test would pass. Second test would call the real backend.
Here is my sample code: The first test would call the mock. The second will call the real backend.
var LoginPage = require( './login_page' );
describe('As a user, when using valid credentials', function() {
var login = new LoginPage();
beforeEach(
function () {
browser.addMockModule('myService', function() {
angular
.module('myService', ['myApp', 'ngMockE2E'])
.run(function($httpBackend) {
var access={"access_token":"a", "token_type":"bearer", "expires_in":299, "refresh_token":"a", "userName":"any", "clientId":"blah", ".issued":"Mon, 08 Jun 2015 20:47:40 GMT", ".expires":"Mon, 08 Jun 2015 20:52:40 GMT"};
$httpBackend.whenPOST("https://blah.com/OAuth2Server/1.0/OAuth/Token").respond(200, access);
$httpBackend.whenGET(/\/*/).passThrough();
$httpBackend.whenPOST().passThrough();
});
});
});
it('logins successfully', function() {
login
.navigate()
.login("anything", "password");
browser.sleep(5000);
browser.ignoreSynchronization=true;
var currentUrl=browser.getCurrentUrl();
expect(currentUrl).toBe("http://localhost:55555/#/my-jobs");
});
});
describe('As a user, when using valid credentials', function() {
var login = new LoginPage();
beforeEach(
function () {
browser.addMockModule('myService', function() {
angular
.module('myService', ['myApp', 'ngMockE2E'])
.run(function($httpBackend) {
var access={"access_token":"a", "token_type":"bearer", "expires_in":299, "refresh_token":"a", "userName":"any", "clientId":"blah", ".issued":"Mon, 08 Jun 2015 20:47:40 GMT", ".expires":"Mon, 08 Jun 2015 20:52:40 GMT"};
$httpBackend.whenPOST("https://blah.com/OAuth2Server/1.0/OAuth/Token").respond(200, access);
$httpBackend.whenGET(/\/*/).passThrough();
$httpBackend.whenPOST().passThrough();
});
});
});
it('logins successfully', function() {
login
.navigate()
.login("anything2", "password2");
browser.sleep(5000);
browser.ignoreSynchronization=true;
var currentUrl=browser.getCurrentUrl();
expect(currentUrl).toBe("http://localhost:55555/#/my-jobs");
});
});
I don't exactly know why this issue occurs (happened to me as well), but I was able to 'fix' it by restarting the browser at the end each describe. Just reloading it didn't work for me.
Add the following inside each describe:
afterAll(function() {
// need this to avoid problems with ngmocke2e
browser.restart();
});
I know it's not an ideal solution, and it adds some extra time to the tests, but this does the trick for now.