Я использую firebase-tools
эмулятор для локального тестирования сохранения записи в Cloud Firestore.
$ firebase serve --only functions,firestore
i firestore: Serving ALL traffic (including WebChannel) on http://localhost:8080
⚠ firestore: Support for WebChannel on a separate port (8081) is DEPRECATED and will go away soon. Please use port above instead.
i firestore: Emulator logging to firestore-debug.log
⚠ Your requested "node" version "8" doesn't match your global version "12"
✔ functions: Emulator started at http://localhost:5000
✔ firestore: Emulator started at http://localhost:8080
Мой код:
// FirestoreConnection.ts
import {firestore} from "firebase-admin";
export default class FirestoreConnection {
protected shopDomain: string;
protected database: firestore.Firestore;
constructor(shopDomain: string, database: firestore.Firestore) {
this.shopDomain = shopDomain;
this.database = database;
}
// --------------- Public Methods
public async createNew(type: RecordTypes, documentData: object): Promise<firestore.DocumentSnapshot|null> {
try {
return await this.addDocument(collectionName, documentData);
}
catch (e) {
console.log(e, `=====error createNew()=====`);
return null;
}
}
// --------------- Protected/Private Methods
protected async addDocument(collectionName: string, documentData: object): Promise<firestore.DocumentSnapshot|null> {
try {
const newlyAddedDocument = await this.database
.collection(collectionName)
.add(documentData);
return await newlyAddedDocument.get();
}
catch (e) {
console.log(e, `=====error addDocument()=====`);
return null;
}
}
// FirestoreConnection.test.ts
import * as firebaseTesting from "@firebase/testing";
import {Logger} from "@firebase/logger";
import {RecordTypes} from "../../../../shared";
import FirestoreConnection from "../FirestoreConnection";
/* * * * * * * * * * * * * * * * * * * * *
Setup
* * * * * * * * * * * * * * * * * * * * */
// setup firebase logging
const logClient = new Logger("@firebase/testing");
logClient.log("FirestoreConnection.test.ts");
// --------------- Helpers
const createTestDatabase = (credentials): any => {
return firebaseTesting
.initializeTestApp({
projectId: 'testproject',
auth: credentials
})
.firestore();
};
const nullAllApps = firebaseTesting
.apps().map(app => app.delete());
const db = new FirestoreConnection('testshopdomain', createTestDatabase(null));
// --------------- Before / After
beforeEach(() => {
});
afterEach(async () => {
try {
await Promise.all(nullAllApps);
await firebaseTesting.clearFirestoreData({
projectId : "testproject"
})
}
catch (e) {
console.log(e, `=====error=====`);
}
});
/* * * * * * * * * * * * * * * * * * * * *
Tests
* * * * * * * * * * * * * * * * * * * * */
test("creates new record", async () => {
try {
const addedDocument = await db
.createNew(RecordTypes.globalRule, {
storeId : "dummystoreid"
, globalPercent : 40
});
expect(addedDocument).toEqual({
storeId : "dummystoreid"
, globalPercent : 40
, badProp : 0
});
}
catch (e) {
console.log(e, `=====error test("creates new record"=====`);
}
}, 100000);
Я получаю длинную ошибку при запуске jest
. Тысячи строк показывают + 118,
или подобное число вместе со свойствами объекта, весь красный текст. Затем трассировка стека в белом тексте.
// terminal
+ 116,
+ 111,
+ 51,
// continues for thousands of lines...
+ ],
+ "type": "Buffer",
+ },
+ ],
+ "format": "Protocol Buffer 3 DescriptorProto",
+ "type": Object {
+ "enumType": Array [],
+ "extension": Array [],
+ "extensionRange": Array [],
+ "field": Array [
+ Object {
+ "defaultValue": "",
+ "extendee": "",
+ "jsonName": "",
+ "label": "LABEL_OPTIONAL",
+ "name": "updateTime",
+ "number": 1,
+ "oneofIndex": 0,
+ "options": null,
+ "type": "TYPE_MESSAGE",
+ "typeName": "protobuf.Timestamp",
+ },
+ Object {
+ "defaultValue": "",
+ "extendee": "",
+ "jsonName": "",
+ "label": "LABEL_REPEATED",
+ "name": "transformResults",
+ "number": 2,
+ "oneofIndex": 0,
+ "options": null,
+ "type": "TYPE_MESSAGE",
+ "typeName": "Value",
+ },
+ ],
+ "name": "WriteResult",
+ "nestedType": Array [],
+ "oneofDecl": Array [],
+ "options": null,
+ "reservedName": Array [],
+ "reservedRange": Array [],
+ },
+ },
+ },
+ },
+ "credentialsProvider": FirebaseCredentialsProvider {
+ "auth": null,
+ "changeListener": [Function anonymous],
+ "currentUser": User {
+ "uid": null,
+ },
+ "forceRefresh": false,
+ "receivedInitialUser": true,
+ "tokenCounter": 1,
+ "tokenListener": [Function anonymous],
+ },
+ "handshakeComplete_": true,
+ "idleTimer": DelayedOperation {
+ "asyncQueue": AsyncQueue {
+ "_isShuttingDown": false,
+ "delayedOperations": Array [
+ [Circular],
+ ],
+ "failure": null,
+ "operationInProgress": true,
+ "tail": Promise {},
+ "timerIdsToSkip": Array [],
+ },
+ "catch": [Function bound catch],
+ "deferred": Deferred {
+ "promise": Promise {},
+ "reject": [Function anonymous],
+ "resolve": [Function anonymous],
+ },
+ "op": [Function anonymous],
+ "removalCallback": [Function anonymous],
+ "targetTimeMs": 1579867383588,
+ "then": [Function bound then],
+ "timerHandle": Timeout {
+ "_destroyed": false,
+ "_idleNext": TimersList {
+ "_idleNext": [Circular],
+ "_idlePrev": [Circular],
+ "expiry": 79350,
+ "id": -9007199254740987,
+ "msecs": 60000,
+ "priorityQueuePosition": 1,
+ },
+ "_idlePrev": TimersList {
+ "_idleNext": [Circular],
+ "_idlePrev": [Circular],
+ "expiry": 79350,
+ "id": -9007199254740987,
+ "msecs": 60000,
+ "priorityQueuePosition": 1,
+ },
+ "_idleStart": 19350,
+ "_idleTimeout": 60000,
+ "_onTimeout": [Function anonymous],
+ "_repeat": null,
+ "_timerArgs": undefined,
+ Symbol(refed): true,
+ Symbol(asyncId): 152,
+ Symbol(triggerId): 0,
+ },
+ "timerId": "write_stream_idle",
+ },
+ "idleTimerId": "write_stream_idle",
+ "lastStreamToken": Object {
+ "data": Array [
+ 49,
+ ],
+ "type": "Buffer",
+ },
+ "listener": Object {
+ "onClose": [Function bound ],
+ "onHandshakeComplete": [Function bound ],
+ "onMutationResult": [Function bound ],
+ "onOpen": [Function bound ],
+ },
+ "queue": AsyncQueue {
+ "_isShuttingDown": false,
+ "delayedOperations": Array [
+ DelayedOperation {
+ "asyncQueue": [Circular],
+ "catch": [Function bound catch],
+ "deferred": Deferred {
+ "promise": Promise {},
+ "reject": [Function anonymous],
+ "resolve": [Function anonymous],
+ },
+ "op": [Function anonymous],
+ "removalCallback": [Function anonymous],
+ "targetTimeMs": 1579867383588,
+ "then": [Function bound then],
+ "timerHandle": Timeout {
+ "_destroyed": false,
+ "_idleNext": TimersList {
+ "_idleNext": [Circular],
+ "_idlePrev": [Circular],
+ "expiry": 79350,
+ "id": -9007199254740987,
+ "msecs": 60000,
+ "priorityQueuePosition": 1,
+ },
+ "_idlePrev": TimersList {
+ "_idleNext": [Circular],
+ "_idlePrev": [Circular],
+ "expiry": 79350,
+ "id": -9007199254740987,
+ "msecs": 60000,
+ "priorityQueuePosition": 1,
+ },
+ "_idleStart": 19350,
+ "_idleTimeout": 60000,
+ "_onTimeout": [Function anonymous],
+ "_repeat": null,
+ "_timerArgs": undefined,
+ Symbol(refed): true,
+ Symbol(asyncId): 152,
+ Symbol(triggerId): 0,
+ },
+ "timerId": "write_stream_idle",
+ },
+ ],
+ "failure": null,
+ "operationInProgress": true,
+ "tail": Promise {},
+ "timerIdsToSkip": Array [],
+ },
+ "serializer": JsonProtoSerializer {
+ "databaseId": DatabaseId {
+ "database": "(default)",
+ "projectId": "testproject",
+ },
+ "options": Object {
+ "useProto3Json": false,
+ },
+ },
+ "state": 2,
+ "stream": StreamBridge {
+ "closeFn": [Function closeFn],
+ "sendFn": [Function sendFn],
+ "wrappedOnClose": [Function anonymous],
+ "wrappedOnMessage": [Function anonymous],
+ "wrappedOnOpen": [Function anonymous],
+ },
+ },
+ },
+ "sharedClientState": MemorySharedClientState {
+ "localState": LocalClientState {
+ "activeTargetIds": SortedSet {
+ "comparator": [Function primitiveComparator],
+ "data": SortedMap {
+ "comparator": [Function primitiveComparator],
+ "root": LLRBEmptyNode {
+ "size": 0,
+ },
+ },
+ },
+ },
+ "onlineStateHandler": [Function sharedClientStateOnlineStateChangedHandler],
+ "queryState": Object {
+ "2": "current",
+ },
+ "sequenceNumberHandler": null,
+ "syncEngine": [Circular],
+ },
+ "syncEngineListener": EventManager {
+ "onlineState": 1,
+ "queries": ObjectMap {
+ "inner": Object {},
+ "mapKeyFn": [Function anonymous],
+ },
+ "snapshotsInSyncListeners": Set {},
+ "syncEngine": [Circular],
+ },
+ },
+ },
+ "_persistenceKey": "app-1579867322226-0.11944467708511985",
+ "_queue": AsyncQueue {
+ "_isShuttingDown": false,
+ "delayedOperations": Array [
+ DelayedOperation {
+ "asyncQueue": [Circular],
+ "catch": [Function bound catch],
+ "deferred": Deferred {
+ "promise": Promise {},
+ "reject": [Function anonymous],
+ "resolve": [Function anonymous],
+ },
+ "op": [Function anonymous],
+ "removalCallback": [Function anonymous],
+ "targetTimeMs": 1579867383588,
+ "then": [Function bound then],
+ "timerHandle": Timeout {
+ "_destroyed": false,
+ "_idleNext": TimersList {
+ "_idleNext": [Circular],
+ "_idlePrev": [Circular],
+ "expiry": 79350,
+ "id": -9007199254740987,
+ "msecs": 60000,
+ "priorityQueuePosition": 1,
+ },
+ "_idlePrev": TimersList {
+ "_idleNext": [Circular],
+ "_idlePrev": [Circular],
+ "expiry": 79350,
+ "id": -9007199254740987,
+ "msecs": 60000,
+ "priorityQueuePosition": 1,
+ },
+ "_idleStart": 19350,
+ "_idleTimeout": 60000,
+ "_onTimeout": [Function anonymous],
+ "_repeat": null,
+ "_timerArgs": undefined,
+ Symbol(refed): true,
+ Symbol(asyncId): 152,
+ Symbol(triggerId): 0,
+ },
+ "timerId": "write_stream_idle",
+ },
+ ],
+ "failure": null,
+ "operationInProgress": true,
+ "tail": Promise {},
+ "timerIdsToSkip": Array [],
+ },
+ "_settings": FirestoreSettings {
+ "cacheSizeBytes": 41943040,
+ "credentials": undefined,
+ "forceLongPolling": false,
+ "host": "localhost:8080",
+ "ssl": false,
+ "timestampsInSnapshots": true,
+ },
+ },
+ "_fromCache": false,
+ "_hasPendingWrites": false,
+ "_key": DocumentKey {
+ "path": ResourcePath {
+ "len": 2,
+ "offset": 0,
+ "segments": Array [
+ "globalRule",
+ "YaGhEFEv3kFI0uUWWsSQ",
+ ],
+ },
+ },
// text turns from red to white exactly here (including } )
}
at /home/owner/PhpstormProjects/shopify/buyUsedServer/functions/src/classes/__tests__/FirestoreConnection.test.ts:73:27
at step (/home/owner/PhpstormProjects/shopify/buyUsedServer/functions/src/classes/__tests__/FirestoreConnection.test.ts:33:23)
at Object.next (/home/owner/PhpstormProjects/shopify/buyUsedServer/functions/src/classes/__tests__/FirestoreConnection.test.ts:14:53)
at fulfilled (/home/owner/PhpstormProjects/shopify/buyUsedServer/functions/src/classes/__tests__/FirestoreConnection.test.ts:5:58) {
matcherResult: {
actual: DocumentSnapshot {
_firestore: [Firestore],
_key: [DocumentKey],
_document: [Document],
_fromCache: false,
_hasPendingWrites: false,
_converter: undefined
},
expected: { storeId: 'dummystoreid', globalPercent: 40, badProp: 0 },
message: [Function],
name: 'toEqual',
pass: false
}
} =====error test("creates new record"=====
Может кто-нибудь сказать, что является причиной того, что catch возвращает здесь ошибку? Отсутствие сообщения об ошибке затрудняет отладку для меня.