How can a Firestore Timestamp object be correctly created within a rules test data set?

I am in the process of writing tests for Firestore rules, focusing on testing rules that control when actions can be executed based on a timestamp stored in the document.

It is important to note that the rules will utilize rules.Timestamp rather than JavaScript Date objects. Therefore, I need to generate Timestamp objects within my test data.

However, upon importing @google-cloud/firestore to access the Timestamp data type, I encounter a severe error during test compilation:

functions/node_modules/@google-cloud/firestore/types/firestore.d.ts:23:1 - error TS6200: Definitions of the following identifiers conflict with those in another file: DocumentData, UpdateData, Firestore, GeoPoint, Transaction, WriteBatch, WriteResult, DocumentReference, DocumentSnapshot, QueryDocumentSnapshot, OrderByDirection, WhereFilterOp, Query, QuerySnapshot, DocumentChangeType, CollectionReference, FieldValue, FieldPath, Timestamp, v1beta1, v1, OK, CANCELLED, UNKNOWN, INVALID_ARGUMENT, DEADLINE_EXCEEDED, NOT_FOUND, ALREADY_EXISTS, PERMISSION_DENIED, RESOURCE_EXHAUSTED, FAILED_PRECONDITION, ABORTED, OUT_OF_RANGE, UNIMPLEMENTED, INTERNAL, UNAVAILABLE, DATA_LOSS, UNAUTHENTICATED, FirebaseFirestore

23 declare namespace FirebaseFirestore {
   ~~~~~~~

  node_modules/@google-cloud/firestore/types/firestore.d.ts:23:1
    23 declare namespace FirebaseFirestore {
       ~~~~~~~
    Conflicts are in this file.

node_modules/@google-cloud/firestore/types/firestore.d.ts:23:1 - error TS6200: Definitions of the following identifiers conflict with those in another file: DocumentData, UpdateData, Firestore, GeoPoint, Transaction, WriteBatch, WriteResult, DocumentReference, DocumentSnapshot, QueryDocumentSnapshot, OrderByDirection, WhereFilterOp, Query, QuerySnapshot, DocumentChangeType, CollectionReference, FieldValue, FieldPath, Timestamp, v1beta1, v1, OK, CANCELLED, UNKNOWN, INVALID_ARGUMENT, DEADLINE_EXCEEDED, NOT_FOUND, ALREADY_EXISTS, PERMISSION_DENIED, RESOURCE_EXHAUSTED, FAILED_PRECONDITION, ABORTED, OUT_OF_RANGE, UNIMPLEMENTED, INTERNAL, UNAVAILABLE, DATA_LOSS, UNAUTHENTICATED, FirebaseFirestore

23 declare namespace FirebaseFirestore {
   ~~~~~~~

  functions/node_modules/@google-cloud/firestore/types/firestore.d.ts:23:1
    23 declare namespace FirebaseFirestore {
       ~~~~~~~
    Conflicts are in this file.

node_modules/@google-cloud/firestore/types/firestore.d.ts:147:5 - error TS2374: Duplicate string index signature.

147     [key: string]: any; // Accept other properties, such as GRPC settings.
        ~~~~~~~~~~~~~~~~~~~

Below is a complete test file highlighting this issue:

import * as firebase from '@firebase/testing';
import * as fs from "fs";
import {suite, test} from "mocha-typescript";
import * as chai from 'chai';
import {Timestamp} from "@google-cloud/firestore";

const projectId = 'stackoverflow-timestamp';
const coverageUrl = `http://localhost:8080/emulator/v1/projects/${projectId}:ruleCoverage.html`;
const rules = fs.readFileSync('firestore.rules', 'utf8');

const nowMillis = Date.now();
const yesterday = Timestamp.fromMillis(nowMillis - 86400000);
const tomorrow = Timestamp.fromMillis(nowMillis + 86400000);

const test_data = {
    'timesamples/ts1': {
        'createTime': yesterday,
        'closeTime': tomorrow
    }
};

/**
 * Sets up a new app with authentication data based on the input.
 *
 * @param {object} auth the authentication object to use (usually {uid: some-uid})
 * @return {object} the initialized app
 */
function authedApp(auth) {
    return firebase.initializeTestApp({'projectId': projectId, 'auth': auth}).firestore();
}

/*
 * ============
 *  Test Cases
 * ============
 */
before(async () => {
    await firebase.loadFirestoreRules({projectId, rules});
});

beforeEach(async () => {
    // Clear the database between each test
    await firebase.clearFirestoreData({projectId});
    const db = firebase.initializeAdminApp({'projectId': projectId}).firestore();
    // Load the test data
    for (const key in test_data) {
        const ref = db.doc(key);
        await ref.set(test_data[key]);
    }
});

after(async () => {
    await Promise.all(firebase.apps().map(app => app.delete()));
    console.log(`Visit rule coverage information at ${coverageUrl}\n`);
});

@suite
class TimestampRuleChecks {
    @test
    async 'modify when close is in future'() {
        const unauthenticated = authedApp(null);
        const record = unauthenticated.collection('timesamples').doc('ts1');
        await firebase.assertSucceeds(
            record.set({'data': 'modifiedData'}, {merge: true})
                .catch(
                    (reason => {
                            chai.assert.fail("Problem in Firebase: " + reason);
                        }
                    )
                )
        );
    }
}

Answer №1

While this response may not directly solve the import issue at hand, it does provide valuable insights for testing purposes. I have personally noticed that utilizing regular Date objects when defining mock data has led to successful test results, particularly when comparing against request.time.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to maintain the correct 'this' context for a function that is outside of the Vue

I'm struggling with my Vue component and encountering some errors. <script lang="ts"> import Vue from 'vue'; import { ElForm } from 'element-ui/types/form'; type Validator = ( this: typeof PasswordReset, rule: any, va ...

Encountering an Issue with Typings Installation in Angular 2 and Algolia Search

Struggling to integrate Algolia Search with my Angular 2 app, I've been following the installation guide at https://github.com/algolia/algoliasearch-client-javascript#install. However, when I run typings install algoliasearch-client-javascript --save ...

What is the best way to recycle a variable in TypeScript?

I am trying to utilize my variable children for various scenarios: var children = []; if (folderPath == '/') { var children = rootFolder; } else { var children = folder.childs; } However, I keep receiving the following error message ...

Exploring ways to retrieve checkbox values instead of boolean values upon submission in Angular

I am currently working with a template-driven form and facing an issue. Despite receiving true or false values, I actually need to retrieve the value of checkboxes. <form #f = "ngForm" (ngSubmit) = "onClickSubmit(f.value)"> ...

What is the best way to retrieve the current complete URL in a Next.js/Typescript component?

I'm working on a component and I need to retrieve the current full URL. Here's a simplified version of what I have: /** * Share dropdown component */ export const ShareDropdown: React.FC<{ className: string }> = ({ className, }) => { ...

Is it normal for TypeScript to not throw an error when different data types are used for function parameters?

function add(a:number, b:number):number { return a+b; } let mynumber:any = "50"; let result:number = add(mynumber, 5); console.log(result); Why does the console print "505" without throwing an error in the "add" function? If I had declared mynumber ...

Distribute a TypeScript Project on NPM without exposing the source code

Issue: My library consists of numerous .ts files organized in structured folders. As I prepare to publish this library, I wish to withhold the source (typescript) files. Process: Executing the tsc command results in the creation of a corresponding .js fil ...

Angular HttpClient request fails to initiate

Overview: A button click on a form triggers the methodForm within the component. methodForm then calls methodService in the service layer. methodService is supposed to make an HTTP POST request. Problem: The HTTP POST request is not being made. However, me ...

Dividing the text by its position value and adding it to a fresh object

I needed to divide the paragraph into sections based on its entityRanges. Here is what the original paragraph looks like: { type: 'paragraph', depth: 1, text: 'Do you have questions or comments and do you wish to contact ABC? P ...

Component in Angular with an empty variable in TypeScript

I'm encountering an issue on my web page where I have a loop calling a component multiple times. I successfully pass data to the component, but the problem arises when I try to display the value of an object in the component. In the component's H ...

Fixing a wrong path in the problem matcher of vscode while compiling using $tsc-watch: A step-by-step

My project workspace directory can be found at C:\salix\fantasy. The TypeScript configuration file is located at C:\salix\fantasy\tsconfig.json Despite my efforts, I'm struggling to have the problem matcher for my project dir ...

Is it possible to send requests to multiple APIs using a TypeScript event handler?

I'm facing a challenge in pinging multiple APIs within a single function. It seems like it should be possible, especially since each API shares the same headers and observable. I attempted to write a function for this purpose, but unfortunately, it do ...

Firestore version 9 - Retrieve nested collection depending on a string being present in an array

Working on a new chat application here. It has been a while since I last used Firestore. I am currently using v9 and facing an issue with retrieving the nested "messages" collection when the "users" array in the document contains a specific ID. I have man ...

Produce new lines of code using the vscode.window.activeTextEditor.edit method in Visual Studio Code

Hey everyone, I'm currently working on a vscode extension that can automatically generate template code based on the language you are using when you click a button. However, there seems to be an issue with the formatting of the generated code as it do ...

Is there a way for me to retrieve the value that has been set within the cy.get() function in Cypress using Typescript?

Is there a way to retrieve the value of the getLength function without it returning undefined? How can I access the value in this case? Here is my code snippet: const verifyValue = () => { const selector = 'nz-option-container nz-option-item&apo ...

Angular Pipe: Working with Data Structures in Angular With Nested Arrays and Objects

After struggling to customize answers for similar questions, I find myself in need of some assistance. My current challenge involves using an angular pipe to filter the following data structure: subjects = [ { name: "subject1", keywords:[& ...

What is the process for linking read-only methods to Redux object instances?

Let's say I have a "user" object stored in redux, with fields for first name and last name (interface User { firstName : string, lastName : string} if using typescript). After retrieving a user from redux, I want to obtain the full name of the user by ...

NextJS API routes consistently provide a status code of 200 upon execution

I am new to the concepts of Next.js, and I recently encountered an issue while attempting to fetch data from an API. The API is designed to check if a user session exists (i.e., if the user is logged in) and then returns a JSON response through a GET reque ...

Utilizing Typescript for Axios Response

Incorporating Typescript into my project, I encountered a tedious issue while making an API call using axios. The problem lies within handling nested data properly. Despite my belief that I have correctly typed everything, I persistently face a Typescript ...

Exploring the power of utilizing multiple classes with conditions in Angular 2+

Can you help me figure out how to use a condition for selecting multiple classes with [ngClass] in Angular? <td> <span [ngClass]="{ 'badge badge-success': server.type === 'PRODUCTION', 'ba ...