Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore/upgrade firebase #34

Merged
merged 3 commits into from
Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
steps:
- name: 'node:13-alpine'
- name: 'node:14-alpine'
entrypoint: "npm"
args: ['ci']
- name: 'node:13-alpine'
- name: 'node:14-alpine'
entrypoint: "npm"
args: ['run', 'build']
- name: 'gcr.io/$PROJECT_ID/firebase'
entrypoint: "npm"
args: ['run', 'test:emulator:coverage']
env:
- 'CI=true'
- 'FIRESTORE_EMULATOR_HOST=localhost:8080'
- name: 'node:13-alpine'
- name: 'node:14-alpine'
entrypoint: 'npm'
args: ['run', 'coveralls']
env:
Expand Down
856 changes: 665 additions & 191 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,20 @@
"homepage": "https://github.com/thdk/firestorable#readme",
"peerDependencies": {
"mobx": ">= 6",
"firebase": ">= 8",
"@firebase/rules-unit-testing": "^1.1.4",
"firebase-admin": "^9.2.0"
"firebase": ">= 9",
"@firebase/rules-unit-testing": "^2",
"firebase-admin": "^9"
},
"dependencies": {},
"devDependencies": {
"@firebase/rules-unit-testing": "^1.1.4",
"@firebase/rules-unit-testing": "^2.0.1",
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-typescript": "^6.1.0",
"@rollup/plugin-typescript": "^8.2.5",
"@testing-library/dom": "^7.28.1",
"@types/jest": "^24.0.23",
"coveralls": "^3.1.0",
"firebase": "^8.10.0",
"firebase": "^9.1.1",
"firebase-admin": "^9.11.1",
"jest": "^26.6.3",
"mobx": "^6.3.3",
Expand Down
46 changes: 26 additions & 20 deletions src/__test-utils__/firestore.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
import type firebase from "firebase";
import {
addDoc,
doc,
PartialWithFieldValue,
setDoc,
WithFieldValue,
SetOptions,
getDoc,
CollectionReference,
WriteBatch,
} from "firebase/firestore";

export const addAsync = <T>(
collectionRef: firebase.firestore.CollectionReference,
data: Partial<T>,
export function addAsync<T>(
collectionRef: CollectionReference<T>,
data: WithFieldValue<T> | PartialWithFieldValue<T>,
id?: string,
setOptions?: firebase.firestore.SetOptions,
) => {
setOptions?: SetOptions,
) {
if (id || setOptions) {
const docRef = id ? collectionRef.doc(id) : collectionRef.doc();
return docRef
.set(data, { ...setOptions })
const docRef = id ? doc(collectionRef, id) : doc(collectionRef);
return setDoc(docRef, data, { ...setOptions })
.then(() => docRef.id);
}

return collectionRef
.add(data)
.then(docRef => docRef.id);
return addDoc(collectionRef, data as WithFieldValue<T>).then((ref) => ref.id);
};

/**
* Returns a promise that resolves with T if document with id exists
* or rejects if document with id does not exist.
*/
export function getAsync<T>(collectionRef: firebase.firestore.CollectionReference, id: string) {
return collectionRef.doc(id)
.get()
export function getAsync<T>(collectionRef: CollectionReference<T>, id: string) {
return getDoc(doc(collectionRef, id))
.then(d => {
if (!d.exists) {
if (!d.exists()) {
throw new Error(`Collection '${collectionRef.id}' contains no document with id '${id}'`);
}

Expand All @@ -35,11 +41,11 @@ export function getAsync<T>(collectionRef: firebase.firestore.CollectionReferenc
};

export const addItemInBatch = (
batch: firebase.firestore.WriteBatch,
batch: WriteBatch,
data: any,
collectionRef: firebase.firestore.CollectionReference,
collectionRef: CollectionReference,
id?: string,
) => {
const doc = id === undefined ? collectionRef.doc() : collectionRef.doc(id);
batch.set(doc, data);
const docRef = id === undefined ? doc(collectionRef) : doc(collectionRef, id);
batch.set(docRef, data);
};
90 changes: 47 additions & 43 deletions src/collection/__tests__/add-document.test.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,57 @@
import { firestore as firestoreNamespace } from "firebase-admin";
import { initializeTestEnvironment, RulesTestEnvironment } from "@firebase/rules-unit-testing";
import { ICollectionOptions, Collection } from "../..";
import { initTestFirestore } from "../../../utils/test-firestore";
import { logger } from "../../__test-utils__";

const firebase = require("firebase-admin");

const {
firestore,
refs: [collectionRef],
clearFirestoreData,
deleteFirebaseApp,
} = initTestFirestore(
"test-add-documents",
["books"],
);

import { FirebaseFirestore } from "@firebase/firestore-types";
import { collection, CollectionReference, deleteField, doc, getDoc } from "firebase/firestore";
interface IBook {
name: string;
total: number;
award?: string;
isDeleted?: boolean;
}

export function createCollection<T, K = T>(options?: ICollectionOptions<T, K>) {
return new Collection<T, K>(
firestore,
collectionRef,
options,
{
logger
}
);
}
describe("Collection.addAsync", () => {
let testEnv: RulesTestEnvironment;
let bookCollection: Collection<IBook>;
let collectionRef: CollectionReference<any>;
let firestore: FirebaseFirestore;

let collection: Collection<IBook>;
function createCollection<T, K = T>(options?: ICollectionOptions<T, K>) {
return new Collection<T, K>(
firestore,
collectionRef,
options,
{
logger
}
);
}

beforeEach(() => clearFirestoreData());
beforeEach(() => testEnv.clearFirestore());

afterAll(deleteFirebaseApp);
afterAll(() => testEnv.cleanup());
beforeAll(async () => {
testEnv = await initializeTestEnvironment({
projectId: "test-add-documents",
firestore: {
host: "localhost",
port: 8080,
}
});

firestore = testEnv.unauthenticatedContext().firestore();
collectionRef = collection(firestore, "books");
});

describe("Collection.addAsync", () => {
beforeEach(() => {
collection = createCollection<IBook>({
bookCollection = createCollection<IBook>({
serialize: data => {
if (!data) {
throw new Error("Deleting not supported");
}
const firestoreData: any = {
award: firebase.firestore.FieldValue.delete(),
award: deleteField(),
...data
};
return firestoreData;
Expand All @@ -63,14 +67,14 @@ describe("Collection.addAsync", () => {
describe("when no forced id is provided", () => {
test("it should add the document with a generated id", () => {

return collection.addAsync({
return bookCollection.addAsync({
total: 11,
name: "Book"
})
.then(id => {
return collectionRef.doc(id).get()
.then((snapshot: firestoreNamespace.DocumentSnapshot) => {
expect(snapshot.exists).toBe(true);
return getDoc(doc(collectionRef, id))
.then(snapshot => {
expect(snapshot.exists()).toBe(true);
});
});
});
Expand All @@ -79,17 +83,17 @@ describe("Collection.addAsync", () => {
describe("when a forced id is provided", () => {
test("it should add the document with the given id", () => {

return collection.addAsync(
return bookCollection.addAsync(
{
name: "Book",
total: 11,
},
"given-id"
)
.then(() => {
return collectionRef.doc("given-id").get()
.then((snapshot: firestoreNamespace.DocumentSnapshot) => {
expect(snapshot.exists).toBe(true);
return getDoc(doc(collectionRef, "given-id"))
.then(snapshot => {
expect(snapshot.exists()).toBe(true);
});
});
});
Expand All @@ -98,19 +102,19 @@ describe("Collection.addAsync", () => {

describe("Adding multiple documents", () => {
test("it should add the documents with generated ids", () => {
return collection.addAsync([
return bookCollection.addAsync([
{ total: 11, name: "Book" },
{ total: 22, name: "Book 2" }
])
.then(ids => {
return Promise.all(
[
collectionRef.doc(ids[0]).get(),
collectionRef.doc(ids[1]).get(),
getDoc(doc(collectionRef, ids[0])),
getDoc(doc(collectionRef, ids[1]))
]
).then(([snapshot1, snapshot2]) => {
expect(snapshot1.exists).toBe(true);
expect(snapshot2.exists).toBe(true);
expect(snapshot1.exists()).toBe(true);
expect(snapshot2.exists()).toBe(true);
});
});
});
Expand Down
36 changes: 24 additions & 12 deletions src/collection/__tests__/constructor.test.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import { initializeTestEnvironment, RulesTestEnvironment } from "@firebase/rules-unit-testing";
import { Collection } from "../..";

import { initTestFirestore } from "../../../utils/test-firestore";

const {
firestore,
} = initTestFirestore(
"test-constructor-collection",
["books"],
);
import { FirebaseFirestore } from "@firebase/firestore-types";
import { collection } from "firebase/firestore";

const projectId = "test-constructor-collection";
describe("Collection.constructor", () => {
let firestore: FirebaseFirestore;
let testEnv: RulesTestEnvironment;

beforeAll(async () => {
testEnv = await initializeTestEnvironment({
projectId,
firestore: {
host: "localhost",
port: 8080,
}
});

firestore = testEnv.unauthenticatedContext().firestore();
});

afterAll(() => testEnv.cleanup());
test("it should create a Collection instance with a string as collectionRef", () => {
const collection = new Collection(firestore, "books");

expect(collection).toBeInstanceOf(Collection);
});

test("it should create a Collection instance with a function as collectionRef", () => {
const collection = new Collection(firestore, () => firestore.collection("books"));
const booksCollection = new Collection(firestore, () => collection(firestore, "books"));

expect(collection).toBeInstanceOf(Collection);
expect(booksCollection).toBeInstanceOf(Collection);
});

test("it should create a Collection instance with a CollectionReference as collectionRef", () => {
const collection = new Collection(firestore, firestore.collection("books"));
const booksCollection = new Collection(firestore, collection(firestore, "books"));

expect(collection).toBeInstanceOf(Collection);
expect(booksCollection).toBeInstanceOf(Collection);
});
});
Loading