Skip to content

Commit

Permalink
chore(firestore-genai-chatbot): lint
Browse files Browse the repository at this point in the history
  • Loading branch information
cabljac committed Nov 19, 2024
1 parent 79cff7b commit 07c6ca2
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as admin from 'firebase-admin';
import { Timestamp } from 'firebase-admin/firestore';
import { FirestoreOnWriteProcessor } from '../../src/firestore-onwrite-processor';
import { WrappedFunction } from 'firebase-functions-test/lib/v1';
import { Change, firestore } from 'firebase-functions/v1';
import { describe, test, beforeEach, afterEach, expect, vi } from 'vitest';
import {Timestamp} from 'firebase-admin/firestore';
import {FirestoreOnWriteProcessor} from '../../src/firestore-onwrite-processor';
import {WrappedFunction} from 'firebase-functions-test/lib/v1';
import {Change, firestore} from 'firebase-functions/v1';
import {describe, test, beforeEach, afterEach, expect, vi} from 'vitest';

const firebaseFunctionsTest = require('firebase-functions-test');
const fft = firebaseFunctionsTest({
Expand All @@ -13,7 +13,7 @@ const fft = firebaseFunctionsTest({
process.env.GCLOUD_PROJECT = 'demo-gcp';
process.env.FIRESTORE_EMULATOR_HOST = '127.0.0.1:8080';

type DocumentReference = admin.firestore.DocumentReference;
type DocumentReference = admin.firestore.DocumentReference;
type DocumentData = admin.firestore.DocumentData;
type DocumentSnapshot = admin.firestore.DocumentSnapshot<DocumentData>;
type WrappedFirebaseFunction = WrappedFunction<
Expand All @@ -28,10 +28,10 @@ admin.initializeApp({
const firestoreObserver = vi.fn((_x: any) => {});
let collectionName: string;

const processor = new FirestoreOnWriteProcessor<string, { output: string }>({
const processor = new FirestoreOnWriteProcessor<string, {output: string}>({
inputField: 'input',
processFn: async (input: string) => {
return { output: input };
return {output: input};
},
errorFn: JSON.stringify,
});
Expand All @@ -55,7 +55,7 @@ describe('SingleFieldProcessor', () => {

await fetch(
`http://${process.env.FIRESTORE_EMULATOR_HOST}/emulator/v1/projects/demo-gcp/databases/(default)/documents`,
{ method: 'DELETE' }
{method: 'DELETE'}
);
vi.clearAllMocks();

Expand Down Expand Up @@ -84,10 +84,10 @@ describe('SingleFieldProcessor', () => {

expect(firestoreObserver).toHaveBeenCalledTimes(3);
const firestoreCallData = firestoreObserver.mock.calls.map(
(call: { docs: { data: () => any }[] }[]) => call[0].docs[0].data()
(call: {docs: {data: () => any}[]}[]) => call[0].docs[0].data()
);

expect(firestoreCallData[0]).toEqual({ input: 'test' });
expect(firestoreCallData[0]).toEqual({input: 'test'});
expect(firestoreCallData[1]).toEqual({
input: 'test',
createTime: expect.any(Timestamp),
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('SingleFieldProcessor', () => {

expect(firestoreObserver).toHaveBeenCalledTimes(3);
const firestoreCallData = firestoreObserver.mock.calls.map(
(call: { docs: { data: () => any }[] }[]) => call[0].docs[0].data()
(call: {docs: {data: () => any}[]}[]) => call[0].docs[0].data()
);

expect(firestoreCallData[0]).toEqual({
Expand Down Expand Up @@ -171,7 +171,7 @@ describe('SingleFieldProcessor', () => {
const simulateFunctionTriggered =
(wrappedFunction: WrappedFirebaseFunction) =>
async (ref: DocumentReference, before?: DocumentSnapshot) => {
const data = (await ref.get()).data() as { [key: string]: unknown };
const data = (await ref.get()).data() as {[key: string]: unknown};
const beforeFunctionExecution = fft.firestore.makeDocumentSnapshot(
data,
`${collectionName}/${ref.id}`
Expand Down
45 changes: 23 additions & 22 deletions firestore-genai-chatbot/functions/__tests__/google_ai/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Hoisted mocks
const { mockGenerate, mockGoogleAI } = vi.hoisted(() => ({
const {mockGenerate, mockGoogleAI} = vi.hoisted(() => ({
mockGenerate: vi.fn(),
mockGoogleAI: vi.fn(() => ({}))
mockGoogleAI: vi.fn(() => ({})),
}));

// Mock setup using hoisted mocks
Expand All @@ -16,18 +16,18 @@ vi.mock('@genkit-ai/google', () => ({
}));

// Type imports
import { Change } from 'firebase-functions/v1';
import type { WrappedFunction } from 'firebase-functions-test/lib/v1';
import type { QuerySnapshot } from 'firebase-admin/firestore';
import {Change} from 'firebase-functions/v1';
import type {WrappedFunction} from 'firebase-functions-test/lib/v1';
import type {QuerySnapshot} from 'firebase-admin/firestore';

// Regular imports
import * as admin from 'firebase-admin';
const firebaseFunctionsTest = require('firebase-functions-test');

import { describe, beforeEach, afterEach, test, expect, vi } from 'vitest';
import { expectToProcessCorrectly } from '../util';
import {describe, beforeEach, afterEach, test, expect, vi} from 'vitest';
import {expectToProcessCorrectly} from '../util';

// Mock configuration
// Mock configuration
vi.mock('../../src/config', () => ({
default: {
googleAi: {
Expand All @@ -52,7 +52,7 @@ vi.mock('../../src/config', () => ({

// Import modules that depend on mocks
import config from '../../src/config';
import { generateMessage } from '../../src/index';
import {generateMessage} from '../../src/index';

process.env.GCLOUD_PROJECT = 'demo-gcp';
process.env.FIRESTORE_EMULATOR_HOST = '127.0.0.1:8080';
Expand Down Expand Up @@ -88,7 +88,7 @@ describe('generateMessage Google AI', () => {
beforeEach(async () => {
await fetch(
`http://${process.env.FIRESTORE_EMULATOR_HOST}/emulator/v1/projects/demo-gcp/databases/(default)/documents`,
{ method: 'DELETE' }
{method: 'DELETE'}
);
vi.clearAllMocks();
const randomInteger = Math.floor(Math.random() * 1000000);
Expand Down Expand Up @@ -187,7 +187,7 @@ describe('generateMessage Google AI', () => {

expect(mockGenerate).toHaveBeenCalledTimes(1);
expect(mockGenerate).toHaveBeenCalledWith({
prompt: [{ text: 'hello chat bison' }],
prompt: [{text: 'hello chat bison'}],
messages: [],
model: 'googleai/gemini-1.5-flash',
config: {
Expand Down Expand Up @@ -225,7 +225,7 @@ describe('generateMessage Google AI', () => {

expect(mockGenerate).toHaveBeenCalledTimes(1);
expect(mockGenerate).toHaveBeenCalledWith({
prompt: [{ text: 'hello world' }],
prompt: [{text: 'hello world'}],
messages: [],
model: 'googleai/gemini-1.5-flash',
config: {
Expand All @@ -239,28 +239,29 @@ describe('generateMessage Google AI', () => {

test('should handle errors from genkit', async () => {
mockGenerate.mockRejectedValueOnce(new Error('API Error'));

const message = {
prompt: 'hello world',
createTime: Timestamp.now(),
};

const ref = await admin.firestore().collection(collectionName).add(message);
await simulateFunctionTriggered(wrappedGenerateMessage)(ref);
await new Promise(resolve => setTimeout(resolve, 100));

const updatedDoc = await ref.get();
const data = updatedDoc.data();

expect(data).toMatchObject({
prompt: 'hello world',
status: {
state: 'ERROR',
error: 'An error occurred while processing the provided message, API Error',
updateTime: expect.any(Timestamp)
}
error:
'An error occurred while processing the provided message, API Error',
updateTime: expect.any(Timestamp),
},
});

expect(mockGenerate).toHaveBeenCalledTimes(1);
expect(firestoreObserver).toHaveBeenCalled();
});
Expand All @@ -269,7 +270,7 @@ describe('generateMessage Google AI', () => {
const simulateFunctionTriggered =
(wrappedFunction: WrappedFirebaseFunction) =>
async (ref: DocumentReference, before?: DocumentSnapshot) => {
const data = (await ref.get()).data() as { [key: string]: unknown };
const data = (await ref.get()).data() as {[key: string]: unknown};
const beforeFunctionExecution = fft.firestore.makeDocumentSnapshot(
data,
`${collectionName}/${ref.id}`
Expand All @@ -287,4 +288,4 @@ const expectNoOp = async () => {
await new Promise(resolve => setTimeout(resolve, 100));
expect(firestoreObserver).toHaveBeenCalledTimes(1);
expect(mockGenerate).toHaveBeenCalledTimes(0);
};
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { extractOverrides } from '../../src/overrides'; // Adjust the import as per your file structure
import { describe, beforeEach, afterEach, test, expect, vi } from 'vitest';
import {extractOverrides} from '../../src/overrides'; // Adjust the import as per your file structure
import {describe, beforeEach, afterEach, test, expect, vi} from 'vitest';

describe('extractOverrides function', () => {
let mockDocSnap: any;
Expand Down
4 changes: 2 additions & 2 deletions firestore-genai-chatbot/functions/__tests__/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from 'vitest';
import { Timestamp } from 'firebase-admin/firestore';
import {expect} from 'vitest';
import {Timestamp} from 'firebase-admin/firestore';

export const expectToProcessCorrectly = (
firestoreCallData: any[],
Expand Down
67 changes: 34 additions & 33 deletions firestore-genai-chatbot/functions/__tests__/vertex_ai/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Hoisted mocks
const { mockGenerate, mockVertexAI } = vi.hoisted(() => ({
const {mockGenerate, mockVertexAI} = vi.hoisted(() => ({
mockGenerate: vi.fn(),
mockVertexAI: vi.fn(() => ({}))
mockVertexAI: vi.fn(() => ({})),
}));

// Mock setup using hoisted mocks
Expand All @@ -16,16 +16,16 @@ vi.mock('@genkit-ai/vertexai', () => ({
}));

// Type imports
import { Change } from 'firebase-functions/v1';
import type { WrappedFunction } from 'firebase-functions-test/lib/v1';
import type { QuerySnapshot } from 'firebase-admin/firestore';
import {Change} from 'firebase-functions/v1';
import type {WrappedFunction} from 'firebase-functions-test/lib/v1';
import type {QuerySnapshot} from 'firebase-admin/firestore';

// Regular imports
import * as admin from 'firebase-admin';
const firebaseFunctionsTest = require('firebase-functions-test');

import { describe, beforeEach, afterEach, test, expect, vi } from 'vitest';
import { expectToProcessCorrectly } from '../util';
import {describe, beforeEach, afterEach, test, expect, vi} from 'vitest';
import {expectToProcessCorrectly} from '../util';

// Mock configuration
vi.mock('../../src/config', () => ({
Expand All @@ -52,7 +52,7 @@ vi.mock('../../src/config', () => ({

// Import modules that depend on mocks
import config from '../../src/config';
import { generateMessage } from '../../src/index';
import {generateMessage} from '../../src/index';

process.env.GCLOUD_PROJECT = 'demo-gcp';
process.env.FIRESTORE_EMULATOR_HOST = '127.0.0.1:8080';
Expand Down Expand Up @@ -88,7 +88,7 @@ describe('generateMessage Vertex AI', () => {
beforeEach(async () => {
await fetch(
`http://${process.env.FIRESTORE_EMULATOR_HOST}/emulator/v1/projects/demo-gcp/databases/(default)/documents`,
{ method: 'DELETE' }
{method: 'DELETE'}
);
vi.clearAllMocks();
const randomInteger = Math.floor(Math.random() * 1000000);
Expand Down Expand Up @@ -169,25 +169,25 @@ describe('generateMessage Vertex AI', () => {
createTime: Timestamp.now(),
};
const ref = await admin.firestore().collection(collectionName).add(message);

await simulateFunctionTriggered(wrappedGenerateMessage)(ref);

expect(firestoreObserver).toHaveBeenCalledTimes(3);

const firestoreCallData = firestoreObserver.mock.calls.map(call =>
call[0].docs[0].data()
);

expectToProcessCorrectly(
firestoreCallData,
message,
false,
'test response'
);

expect(mockGenerate).toHaveBeenCalledTimes(1);
expect(mockGenerate).toHaveBeenCalledWith({
prompt: [{ text: 'hello world' }],
prompt: [{text: 'hello world'}],
messages: [],
model: 'vertexai/gemini-1.5-flash',
config: {
Expand All @@ -203,29 +203,29 @@ describe('generateMessage Vertex AI', () => {
const message = {
prompt: 'hello chat bison',
};

const ref = await admin.firestore().collection(collectionName).add(message);

const beforeOrderField = await simulateFunctionTriggered(
wrappedGenerateMessage
)(ref);

await simulateFunctionTriggered(wrappedGenerateMessage)(
ref,
beforeOrderField
);

expect(firestoreObserver).toHaveBeenCalledTimes(3);

const firestoreCallData = firestoreObserver.mock.calls.map(call => {
return call[0].docs[0].data();
});

expectToProcessCorrectly(firestoreCallData, message, true, 'test response');

expect(mockGenerate).toHaveBeenCalledTimes(1);
expect(mockGenerate).toHaveBeenCalledWith({
prompt: [{ text: 'hello chat bison' }],
prompt: [{text: 'hello chat bison'}],
messages: [],
model: 'vertexai/gemini-1.5-flash',
config: {
Expand All @@ -240,28 +240,29 @@ describe('generateMessage Vertex AI', () => {
test('should handle errors from genkit', async () => {
// Setup mock to reject
mockGenerate.mockRejectedValueOnce(new Error('API Error'));

const message = {
prompt: 'hello world',
createTime: Timestamp.now(),
};

const ref = await admin.firestore().collection(collectionName).add(message);
await simulateFunctionTriggered(wrappedGenerateMessage)(ref);
await new Promise(resolve => setTimeout(resolve, 100));

const updatedDoc = await ref.get();
const data = updatedDoc.data();

expect(data).toMatchObject({
prompt: 'hello world',
status: {
state: 'ERROR',
error: 'An error occurred while processing the provided message, API Error',
updateTime: expect.any(Timestamp)
}
error:
'An error occurred while processing the provided message, API Error',
updateTime: expect.any(Timestamp),
},
});

expect(mockGenerate).toHaveBeenCalledTimes(1);
expect(firestoreObserver).toHaveBeenCalled();
});
Expand All @@ -270,7 +271,7 @@ describe('generateMessage Vertex AI', () => {
const simulateFunctionTriggered =
(wrappedFunction: WrappedFirebaseFunction) =>
async (ref: DocumentReference, before?: DocumentSnapshot) => {
const data = (await ref.get()).data() as { [key: string]: unknown };
const data = (await ref.get()).data() as {[key: string]: unknown};
const beforeFunctionExecution = fft.firestore.makeDocumentSnapshot(
data,
`${collectionName}/${ref.id}`
Expand All @@ -288,4 +289,4 @@ const expectNoOp = async () => {
await new Promise(resolve => setTimeout(resolve, 100));
expect(firestoreObserver).toHaveBeenCalledTimes(1);

Check failure on line 290 in firestore-genai-chatbot/functions/__tests__/vertex_ai/index.test.ts

View workflow job for this annotation

GitHub Actions / node.js_18_test

__tests__/vertex_ai/index.test.ts > generateMessage Vertex AI > should not run if the prompt field is empty

AssertionError: expected "spy" to be called 1 times, but got 0 times ❯ expectNoOp __tests__/vertex_ai/index.test.ts:290:29 ❯ __tests__/vertex_ai/index.test.ts:148:5
expect(mockGenerate).toHaveBeenCalledTimes(0);
};
};
2 changes: 1 addition & 1 deletion firestore-genai-chatbot/functions/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineConfig } from 'vitest/config';
import {defineConfig} from 'vitest/config';

export default defineConfig({
test: {
Expand Down

0 comments on commit 07c6ca2

Please sign in to comment.