firebase / firebase/firebase-functions-test
Gen2 / TypeScript: Snapshot from 'makeDocumentSnapshot' Doesn't Work for 'onDocumentCreated'
- Dominant language
- TypeScript
- Stars
- 248
- Forks
- 63
- PR merge metrics
- No merged PRs in 30d
Description
### Version info
**firebase-functions-test:** 3.1.0
**firebase-functions:** 4.4.1
**firebase-admin:** 11.9.0
### Test case
**Firebase Cloud Function**
```tsx
import { onDocumentCreated } from 'firebase-functions/v2/firestore';
import * as logger from 'firebase-functions/logger';
import { initializeApp } from 'firebase-admin/app';
initializeApp();
export const docCreateTest = onDocumentCreated(
'messages/{documentId}',
(event) => {
const original = event.data?.data().original;
logger.log('Uppercasing: ', original);
const uppercase = original.toUpperCase();
return event.data.ref.set({ uppercase }, { merge: true });
}
);
```
**Unit Test**
_**Note**: Using Vitest but I believe it would be the same result with Jest, etc._
```tsx
import { describe, test, expect } from 'vitest';
import firebaseFunctionsTest from 'firebase-functions-test';
import * as admin from 'firebase-admin';
import { docCreateTest } from '../functions/index';
// NOTE: Don't need the service account file when using
// GOOGLE_APPLICATION_CREDENTIALS environment variable
const { wrap, firestore } = firebaseFunctionsTest({
databaseURL: 'http://127.0.0.1:8080',
projectId: 'project-id-test',
});
describe('Running tests...', () => {
test('should return uppercase message', async () => {
// create mock doc snapshot
const snap = firestore.makeDocumentSnapshot(
{ original: 'hello' },
'messages/abc'
);
// TODO: Workaround for https://github.com/firebase/firebase-functions-test/issues/163
// @ts-ignore
const wrapped = wrap(docCreateTest);
await wrapped(snap);
const result = await admin.firestore().doc('messages/abc').get();
expect(result.data()?.uppercase).toBe('HELLO');
});
});
```
### Steps to reproduce
Run the unit test against the Firebase function and it will result in a _Cannot read properties of undefined (reading 'original')_ when trying to create the 'original' variable in the function (`const original = event.data?.data().original;`).
This is because `event.data.data()` is undefined.
### Expected behavior
The document snapshot created in the unit test with `makeDocumentSnapshot` is in the correct format to be passed into `onDocumentCreated` so that its data can be read.
### Actual behavior
The 'original' variable cannot be created in the Firebase function because it can't read the `data` object in the passed in `event` resulting in the following error...
```
Cannot read properties of undefined (reading 'original')
```
I guess this is due to `makeDocumentSnapshot` creating a `DocumentSnapshot` and the `event` in `onDocumentCreated` expected to have a type of `FirestoreEvent`.
I can't find any alternative to `makeDocumentSnapshot` that should be used in this scenario for gen2 functions though so I'm guessing this isn't supported yet?
If I create an object that contains the document snapshot as the value of a `data` parameter, it will work
```tsx
test('should return uppercase message', async () => {
// create mock doc snap
const snap = firestore.makeDocumentSnapshot(
{ original: 'hello' },
'messages/abc'
);
// TODO: My workaround for missing 'data' property when passing event
const event = { data: snap }; // <-- CREATING THE NEW OBJECT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const wrapped = wrap(docCreateTest);
await wrapped(event); // <-- PASSING THE OBJECT I CREATED INSTEAD OF 'snap'
const result = await admin.firestore().doc('messages/abc').get();
expect(result.data()?.uppercase).toBe('HELLO');
});
```
___
I'm not sure how much of this library is currently expected to work with the gen2 Firebase functions, but I couldn't find this issue already logged and the [gen2 samples](https://github.com/firebase/functions-samples/tree/main/Node/test-functions-jest-ts) don't cover `onDocumentCreated` functions.
Cheers
Jess
Contributor guide
Assessment
This issue has not been assessed yet.