Firestore SDK cannot mock DocumentSnapshot - javascript

So I am trying to create a unit test for a firestore trigger, triggered by an onCreate event. The firebase documentation said to do this as so: Firebase Unit Testing Background Functions
I copy the documentation pretty closely:
const snapshot = test.firestore.makeDocumentSnapshot(
{owner: 'testUserA', text: 'response from test user a'},
'users/testUserA/questions/testQuestion/responses/testResponse'
);
This line gives the error:
UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token u in JSON at position 0
At first I thought it might have to do with the refPath because it starts with u, but after changing it, the error is identical, so I assume it has to do with the first parameter, which seems like correct json, but apparently not. I'm kind of stumped.
Any ideas? Thanks!

Do you have test.cleanup() in any other testing cases before you use test.firestore.makeDocumentSnapshot()? If any, remove them and run the test again

Related

Visual Studio Code local run throws error - undefined variable is defined

So I went through a Microsoft online demo on how to do an httpTrigger in Visual Studio Code (language: JavaScript) to upload it to Azure Functions and it was successful. I then started to customize the code so it can do a certain calculation. I got the calculation to be done and I was able to print to console.
Now I'm trying to run it locally so I can pass TWO values to it, but testing it with one. I noticed that in their demo, they were able to use the line:
const name = (req.query.name || (req.body && req.body.name));
where in the body response up top, a default {"name": "Azure"} would present and I sent that value, which came up in their response. Basically, they were able to assign const name with what value was passed in the curly braces with the key value pair {"name": "whateverIputhere"}.
So I decided to try in when running locally, below is the condensed code I am having trouble with:
module.exports = async function (req) {
const var1 = req.query.var1
}
and I've tried passing a parameter in multiple ways. I thought I had to do it as {"var1": "1"} but it would tell me var1 is undefined during the running of the function locally.
Why am I not able to assign it as they did?
Possible clue: There is a sample.dat file that I thought I had to modify to just replace the default entries and it still brings up {"name": "Azure"} as the default entries not sure why.
I am at a loss and would love some help.
I was having an issue only because I was NOT including .query as an option to assign the variable. All other "issues" during the description were quickly gone. Thank you all for looking at this.

PouchDB has documents that are 'undefined' instead of just {} or {_id}. How do I delete them?

My pouchdb-find queries are failing because there are some bad data objects: they are undefined, actually stored undefineds in the database. They are not {} or {_id: 'something'}, they are actually undefineds.
Details
I discovered it while trying to query for a field being not-null. When I query for {$eq: null} to find those records, I found something strange.
Query:
await db.find({ selector: {text: {$gt: null}} });
// or
await db.find({ selector: {text: {$exists: true}} });
Results:
{
docs: [
undefined,
undefined,
undefined,
undefined,
{
_id: 'test-id-1618443059797',
_rev: '3-251568304e939d8d5b688af8c09eaa13'
},
{
_id: 'test-id-1618443082960',
_rev: '3-a60c1dde0e11e14d0a14cd86d2478140'
}
]
}
This seems to explain why I'm getting errors like the following. (The slightly different formatting is from tslog).
TypeError Cannot read property 'text' of undefined
error stack:
• index.js:14 getFieldFromDoc
node_modules/.pnpm/pouchdb-selector-core#7.2.2/node_modules/pouchdb-selector-core/lib/index.js:14:18
• index.js:345 <anonymous>
node_modules/.pnpm/pouchdb-selector-core#7.2.2/node_modules/pouchdb-selector-core/lib/index.js:345:25
• index.js:342 rowFilter
node_modules/.pnpm/pouchdb-selector-core#7.2.2/node_modules/pouchdb-selector-core/lib/index.js:342:25
• index.js:319 <anonymous>
node_modules/.pnpm/pouchdb-selector-core#7.2.2/node_modules/pouchdb-selector-core/lib/index.js:319:12
• index.js:318 filterInMemoryFields
node_modules/.pnpm/pouchdb-selector-core#7.2.2/node_modules/pouchdb-selector-core/lib/index.js:318:15
• index.js:1307 <anonymous>
node_modules/.pnpm/pouchdb-find#7.2.2/node_modules/pouchdb-find/lib/index.js:1307:40
The same kind of error happens for other queries involving fields, since null.<anything> will keep causing errors like that.
What I think is going on
I figure these are corrupted writes, and I'm trying to figure out how to clean those up without doing a destroy(). The state seems corrupt overall because there are multiple of these undefined records.
What I've tried
Thoroughly debugging, through the library code. Helped me clarify the issue but I don't have a fix yet.
For good measure, I tried each way to delete a record detailed in the PouchDB docs. They hit the same error (which makes sense to me)
Because they are undefined, I cannot set _deleted property. And even if I could change properties, there's no _id to pass to remove etc.
Working around with .destroy(), i.e. loading data from allDocs, calling destroy, and putting it all back. This seems hacky because more data corruption could happen in the process.
Environment
My current usage is in a nodejs environment. Executing via ts-node but I doubt that matters.
Dependency versions
pouchdb 7.2.2
pouchdb-find 7.2.2
How do I remove these undefined documents?
Is there any way to handle this besides destroying? (Meaning, I would copy the data out, destroy, then put all the non-corrupt data back; but that could cause new issues

Mixpanel returning a response object instead of undefined even when opted out in AVA Unit Test

I'm trying to implement an AVA Unit Test for my mixpanel implementation. To do this, I'm comparing the result of mixpanel.track() where if it returns anything, the track was successful, otherwise, it should be undefined.
I thought maybe it was that it was using a different mixpanel instance so I tried creating a named instance and ensuring that but it was to no avail. I'm also trying the same process but with Amplitude and it seems to be working fine (when I am opted out, the response fails as expected)
I have done this in my components where if
const test = mixpanel.track('event_name', {}) is successful, !!test === true but if I do mixpanel.opt_out.tracking() prior to const test = mixpanel.track('event_name', {}), then !!test === undefined.
Expected behaviour (and the observed behaviour when I use it in my components):
trackResponse === undefined
Observed behaviour:
trackResponse === { event: 'asdf',
properties:
{ '$browser': 'Safari',
'$current_url': 'about:blank',
'$browser_version': null,
'$screen_height': 0,
'$screen_width': 0,
mp_lib: 'web',
'$lib_version': '2.30.1',
time: 1572898982.142,
distinct_id: '[some_id]',
'$device_id': '[some_id]',
'$initial_referrer': '$direct',
'$initial_referring_domain': '$direct',
token: '[token]' } }
where [some_id] and [token] are some distinct values I've deleted.
I don't understand why in the AVA test, I'm receiving a response when normally a failed track() results in an undefined response. Could someone shine some light on this?
Let me know if I need to provide any additional information. Thanks.
I figured it out in case anyone else runs into this issue.
I used a debugger to step into the mixpanel.track() calls and figured out that to see if the user had opted out, mixpanel checks for a property in the localStorage and compares it to see if it's === to '0'. If this fails, it assumes the user has not opted out and carries out the track call as normal.
I guess during the AVA test, it was unable to access this property and assumed the user had not opted out. To fix it, in my call to mixpanel.init(), I added opt_out_tracking_persistence_type: 'cookie' as an option so that my opt_out call was being saved somewhere that the property could be accessed during the test.

`waitForEnabled()` says "selector needs to be typeof `string`" even though string was passed

I was originally using the mocha command line tool to run my tests and they were working fine. I switched to using the wdio command to run my tests. My tests now throw an error with this line of code:
browser.waitForEnabled('#div_id');
With this error:
Promise was rejected with the following reason: Error: selector needs to be typeof `string`
running chrome
Error: Promise was rejected with the following reason: Error: selector needs to be typeof `string`
at elements() - isEnabled.js:18:17
at isEnabled() - waitForEnabled.js:37:22
This was working fine until I started using wdio (specifically I run wdio --spec path/to/file.js). I've run the typeof function on the selector in question and verified that it is, in fact, a string.
The div in question looks like this:
<div class="highlight" id="div_id">
A fair bit of content goes here.
</div>
Why am I seeing this error? How do I fix it?
waitForEnabled() documentation => http://webdriver.io/api/utility/waitForEnabled.html
wdio documentation => http://webdriver.io/guide/testrunner/gettingstarted.html
Update:
I've tried adding a timeout to the waitForEnabled() function. Since I've done so, it sometimes fails, and sometimes does not. More often it fails though.
I'm not marking this as the answer because I have no idea why it works. But passing in all of the optional params to waitForEnabled() makes it work just fine.
As in:
waitForEnabled('#div_id'); Fails. Wheras:
waitForEnabled('#div_id', 99999, false); works without errors.
The fact that you're passing milliseconds & the false option should not make the test pass.
I'd suggest using some of the other waitFor commands, like waitForVisible() or waitForExist(), because I'm assuming this is what you really want from the code example you gave above. The waitForEnabled() command waits for a field that had a disabled html attribute, to not have it anymore. You can read more on that here: https://www.w3schools.com/tags/att_disabled.asp.

Is there someway to disable all firebase logging to console?

I have created some unit tests for my firebase security rules. Part of this testing is trying to do illegal operations and asserting that they fail.
My problem has to do with noise; when I run the tests using nodeunit, the firebase client spits out several logs similar to this:
FIREBASE WARNING: set at /user failed: permission_denied
I do not want this output when intentionally doing illegal operations as it just results in noise and confusion.
These days there is an option to set the log level on the global firebase object:
import firebase from 'firebase/app';
firebase.setLogLevel('silent')
In our testing suite, we rewrite process.stderr.write to only ignore firebase warnings like so:
Javascript
process.stderr.write = (function(write) {
return function() {
if (!arguments[0].includes("FIREBASE WARNING"))
write.apply(process.stderr, arguments);
};
}(process.stderr.write));
Typescript (including tslint fix)
process.stderr.write = (() => {
// tslint:disable-next-line:no-unbound-method
const write = process.stderr.write;
return function () {
if (!(arguments[0] as string).includes("FIREBASE WARNING")) {
return write.apply(process.stderr, arguments);
}
};
})();
There is no way to disable the security warnings as they are emitted asynchronously by the Firebase SDK. I worked around this by adding a message before the errors:
>>> An intentional security error should be printed after this line...
As Kato said, there doesn't appear to be an official way to disable it. That said, if you really want to, it takes 2 seconds to go into the source, Ctrl+F for "WARNING", and comment out this line:
"undefined"!==typeof console.warn?console.warn(b):console.log(b)

Categories

Resources