Skip to content

Commit

Permalink
feat: auth context support (#227)
Browse files Browse the repository at this point in the history
* feat: add .idea to .gitignore

* feat: Initial implementation

* chore: run prettier

* feat: types from new interfaces

* feat: update firebase-functions to latest version (4.9.0)

* feat: fix types from latest functions SDK
  • Loading branch information
exaby73 authored Apr 8, 2024
1 parent 5410568 commit 2e7c3db
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ lib
.vscode
*.tgz
.tmp
*.log
*.log
.idea
18 changes: 8 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@types/mocha": "^5.2.7",
"chai": "^4.2.0",
"firebase-admin": "^12.0.0",
"firebase-functions": "^4.6.0",
"firebase-functions": "^4.9.0",
"firebase-tools": "^8.9.2",
"mocha": "^6.2.2",
"prettier": "^1.19.1",
Expand All @@ -57,7 +57,7 @@
},
"peerDependencies": {
"firebase-admin": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0",
"firebase-functions": ">=4.3.0",
"firebase-functions": ">=4.9.0",
"jest": ">=28.0.0"
},
"engines": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MockCloudEventAbstractFactory } from '../../types';
import { CloudEvent, CloudFunction, firestore } from 'firebase-functions/v2';
import { getEventType } from '../helpers';
import { QueryDocumentSnapshot } from 'firebase-admin/firestore';
import { getDocumentSnapshotCloudEventWithAuthContext } from './helpers';

export const firestoreOnDocumentCreatedWithAuthContext: MockCloudEventAbstractFactory<firestore.FirestoreAuthEvent<
QueryDocumentSnapshot
>> = {
generateMock: getDocumentSnapshotCloudEventWithAuthContext,
match(cloudFunction: CloudFunction<CloudEvent<unknown>>): boolean {
return (
getEventType(cloudFunction) ===
'google.cloud.firestore.document.v1.created.withAuthContext'
);
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MockCloudEventAbstractFactory } from '../../types';
import { CloudEvent, CloudFunction, firestore } from 'firebase-functions/v2';
import { getEventType } from '../helpers';
import { QueryDocumentSnapshot } from 'firebase-admin/firestore';
import { getDocumentSnapshotCloudEventWithAuthContext } from './helpers';

export const firestoreOnDocumentDeletedWithAuthContext: MockCloudEventAbstractFactory<firestore.FirestoreAuthEvent<
QueryDocumentSnapshot
>> = {
generateMock: getDocumentSnapshotCloudEventWithAuthContext,
match(cloudFunction: CloudFunction<CloudEvent<unknown>>): boolean {
return (
getEventType(cloudFunction) ===
'google.cloud.firestore.document.v1.deleted.withAuthContext'
);
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { MockCloudEventAbstractFactory } from '../../types';
import {
Change,
CloudEvent,
CloudFunction,
firestore,
} from 'firebase-functions/v2';
import { getEventType } from '../helpers';
import { QueryDocumentSnapshot } from 'firebase-admin/firestore';
import { getDocumentSnapshotChangeCloudEventWithAuthContext } from './helpers';

export const firestoreOnDocumentUpdatedWithAuthContext: MockCloudEventAbstractFactory<firestore.FirestoreAuthEvent<
Change<QueryDocumentSnapshot>
>> = {
generateMock: getDocumentSnapshotChangeCloudEventWithAuthContext,
match(cloudFunction: CloudFunction<CloudEvent<unknown>>): boolean {
return (
getEventType(cloudFunction) ===
'google.cloud.firestore.document.v1.updated.withAuthContext'
);
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { MockCloudEventAbstractFactory } from '../../types';
import {
Change,
CloudEvent,
CloudFunction,
firestore,
} from 'firebase-functions/v2';
import { getEventType } from '../helpers';
import { DocumentSnapshot } from 'firebase-admin/firestore';
import { getDocumentSnapshotChangeCloudEventWithAuthContext } from './helpers';

export const firestoreOnDocumentWrittenWithAuthContext: MockCloudEventAbstractFactory<firestore.FirestoreAuthEvent<
Change<DocumentSnapshot>
>> = {
generateMock: getDocumentSnapshotChangeCloudEventWithAuthContext,
match(cloudFunction: CloudFunction<CloudEvent<unknown>>): boolean {
return (
getEventType(cloudFunction) ===
'google.cloud.firestore.document.v1.written.withAuthContext'
);
},
};
53 changes: 53 additions & 0 deletions src/cloudevent/mocks/firestore/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,31 @@ export function getDocumentSnapshotCloudEvent(
};
}

export function getDocumentSnapshotCloudEventWithAuthContext(
cloudFunction: CloudFunction<firestore.FirestoreAuthEvent<DocumentSnapshot>>,
cloudEventPartial?: DeepPartial<
firestore.FirestoreAuthEvent<DocumentSnapshot | object>
>
) {
const eventWithoutAuthContext = getDocumentSnapshotCloudEvent(
cloudFunction,
cloudEventPartial
);
const authContext: { authId?: string; authType: firestore.AuthType } = {
authType: 'unknown',
};
if (cloudEventPartial?.authId) {
authContext.authId = cloudEventPartial.authId;
}
if (cloudEventPartial?.authType) {
authContext.authType = cloudEventPartial.authType;
}
return {
...eventWithoutAuthContext,
...authContext,
};
}

/** Creates a mock CloudEvent that contains a Change<DocumentSnapshot> as its data. */
export function getDocumentSnapshotChangeCloudEvent(
cloudFunction: CloudFunction<
Expand Down Expand Up @@ -82,6 +107,34 @@ export function getDocumentSnapshotChangeCloudEvent(
};
}

export function getDocumentSnapshotChangeCloudEventWithAuthContext(
cloudFunction: CloudFunction<
firestore.FirestoreAuthEvent<Change<DocumentSnapshot>>
>,
cloudEventPartial?: DeepPartial<
firestore.FirestoreAuthEvent<Change<DocumentSnapshot> | ChangeLike>
>
) {
const eventWithoutAuthContext = getDocumentSnapshotChangeCloudEvent(
cloudFunction,
cloudEventPartial
);
const authContext: { authId?: string; authType: firestore.AuthType } = {
authType: 'unknown',
};
if (cloudEventPartial?.authId) {
authContext.authId = cloudEventPartial.authId;
}
if (cloudEventPartial?.authType) {
authContext.authType = cloudEventPartial.authType;
}

return {
...eventWithoutAuthContext,
...authContext,
};
}

/** Finds or provides reasonable defaults for mock FirestoreEvent data. */
function getFirestoreEventFields(
cloudFunction: CloudFunction<
Expand Down
8 changes: 8 additions & 0 deletions src/cloudevent/mocks/partials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import {
import { storageV1 } from './storage';
import { remoteConfigOnConfigUpdated } from './remoteconfig/remote-config-on-config-updated';
import { testLabOnTestMatrixCompleted } from './testlab/test-lab-on-test-matrix-completed';
import { firestoreOnDocumentCreatedWithAuthContext } from './firestore/firestore-on-document-created-with-auth-context';
import { firestoreOnDocumentDeletedWithAuthContext } from './firestore/firestore-on-document-deleted-with-auth-context';
import { firestoreOnDocumentUpdatedWithAuthContext } from './firestore/firestore-on-document-updated-with-auth-context';
import { firestoreOnDocumentWrittenWithAuthContext } from './firestore/firestore-on-document-written-with-auth-context';

/**
* Note: Ordering matters. Some MockEventPartials will match more generally
Expand Down Expand Up @@ -59,6 +63,10 @@ export const LIST_OF_MOCK_CLOUD_EVENT_PARTIALS: Array<MockCloudEventAbstractFact
firestoreOnDocumentDeleted,
firestoreOnDocumentUpdated,
firestoreOnDocumentWritten,
firestoreOnDocumentCreatedWithAuthContext,
firestoreOnDocumentDeletedWithAuthContext,
firestoreOnDocumentUpdatedWithAuthContext,
firestoreOnDocumentWrittenWithAuthContext,

// CustomEventPublished must be called last
eventarcOnCustomEventPublished,
Expand Down

0 comments on commit 2e7c3db

Please sign in to comment.