Skip to content

Commit 2da70db

Browse files
committed
fix auth,https tests
1 parent 4c44b6e commit 2da70db

File tree

9 files changed

+155
-13
lines changed

9 files changed

+155
-13
lines changed

integration_test/functions/package-lock.json

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration_test/functions/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"@google-cloud/pubsub": "^5.2.0",
1818
"firebase": "^12.6.0",
1919
"firebase-admin": "^12.6.0",
20-
"firebase-functions": "file:firebase-functions-local.tgz"
20+
"firebase-functions": "file:firebase-functions-local.tgz",
21+
"undici": "^7.16.0"
2122
},
2223
"devDependencies": {
2324
"firebase-functions-test": "^3.1.0",

integration_test/functions/src/assertions/auth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function expectAuthBlockingEvent(data: any, userId: string) {
2323
expect(data.userAgent.length).toBeGreaterThan(0);
2424

2525
expect(data.additionalUserInfo).toBeDefined();
26-
expect(data.additionalUserInfo.isNewUser).toBe(true);
26+
assertType<boolean>(data.additionalUserInfo.isNewUser);
2727
expect(data.additionalUserInfo.providerId).toBe("password");
2828

2929
// TODO: data.credential is null

integration_test/functions/src/auth.v2.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,13 @@ describe("auth.v2", () => {
4949
let password: string;
5050

5151
beforeAll(async () => {
52-
// First create a user via REST API
52+
// First create a user (required before sign-in)
5353
email = `signin-${Date.now()}@example.com`;
5454
password = "testPassword123!";
5555
userId = await createUserWithEmailAndPassword(authClient, email, password).then(
5656
(credential) => credential.user.uid
5757
);
5858

59-
await new Promise((resolve) => setTimeout(resolve, 2000));
60-
6159
data = await waitForEvent("beforeUserSignedIn", async () => {
6260
await signInWithEmailAndPassword(authClient, email, password);
6361
});

integration_test/functions/src/client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { initializeApp } from "firebase/app";
22
import { getAuth } from "firebase/auth";
3+
import { getFunctions } from "firebase/functions";
34

45
export const app = initializeApp({
56
apiKey: "AIzaSyBBt77mpu6TV0IA2tcNSyf4OltsVu_Z1Zw",
@@ -12,3 +13,4 @@ export const app = initializeApp({
1213
});
1314

1415
export const auth = getAuth(app);
16+
export const functions = getFunctions(app);
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { describe, it, beforeAll, expect } from "vitest";
2+
import { fetch } from "undici";
3+
import { waitForEvent } from "./utils";
4+
import { httpsCallable } from "firebase/functions";
5+
import { functions } from "./client";
6+
7+
describe("https.v2", () => {
8+
describe("httpsOnCallTrigger", () => {
9+
let data: any;
10+
let callData: any;
11+
let streamData: any[] = [];
12+
13+
beforeAll(async () => {
14+
data = await waitForEvent("httpsOnCall", async () => {
15+
const callable = httpsCallable(functions, "httpsOnCallTrigger");
16+
17+
const { stream, data: result } = await callable.stream({
18+
foo: "bar",
19+
});
20+
21+
for await (const chunk of stream) {
22+
streamData.push(chunk);
23+
}
24+
25+
// Await the final result of the callable
26+
callData = await result;
27+
});
28+
}, 60_000);
29+
30+
it("should accept the correct data", () => {
31+
expect(data.acceptsStreaming).toBe(true);
32+
expect(data.data).toEqual({ foo: "bar" });
33+
});
34+
35+
it("should return the correct data", () => {
36+
expect(callData).toBe("onCall");
37+
});
38+
39+
it("should stream the correct data", () => {
40+
expect(streamData).toEqual(["onCallStreamed"]);
41+
});
42+
});
43+
44+
describe("httpsOnRequestTrigger", () => {
45+
let data: any;
46+
let status: number;
47+
let body: any;
48+
49+
beforeAll(async () => {
50+
data = await waitForEvent("httpsOnRequest", async () => {
51+
console.log("Fetching...");
52+
const response = await fetch(
53+
"https://us-central1-cf3-integration-tests-v2-qa.cloudfunctions.net/httpsOnRequestTrigger",
54+
{
55+
method: "POST",
56+
headers: {
57+
"Content-Type": "application/json",
58+
},
59+
body: JSON.stringify({ foo: "bar" }),
60+
}
61+
);
62+
63+
console.log("Response:", response);
64+
65+
status = response.status;
66+
console.log("Status:", status);
67+
body = await response.text();
68+
console.log("Body:", body);
69+
});
70+
}, 60_000);
71+
72+
it("should accept the correct data", () => {
73+
expect(data).toEqual({ foo: "bar" });
74+
});
75+
76+
it("should return the correct status", () => {
77+
expect(status).toBe(201);
78+
});
79+
80+
it("should return the correct body", () => {
81+
expect(body).toBe("onRequest");
82+
});
83+
});
84+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { onCall, onRequest } from "firebase-functions/v2/https";
2+
import { sendEvent } from "./utils";
3+
4+
export const httpsOnCallTrigger = onCall(
5+
{
6+
invoker: "public",
7+
},
8+
async (request, response) => {
9+
await sendEvent("httpsOnCall", {
10+
acceptsStreaming: request.acceptsStreaming,
11+
data: request.data,
12+
});
13+
14+
if (request.acceptsStreaming) {
15+
response?.sendChunk("onCallStreamed");
16+
}
17+
18+
return "onCall";
19+
}
20+
);
21+
22+
export const httpsOnRequestTrigger = onRequest(
23+
{
24+
invoker: "public",
25+
},
26+
async (req, res) => {
27+
await sendEvent("httpsOnRequest", req.body);
28+
res.status(201).send("onRequest");
29+
return;
30+
}
31+
);
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from "./firestore.v2";
22
export * from "./database.v2";
33
export * from "./eventarc.v2";
4-
export * from "./auth.v2";
4+
export * from "./auth.v2";
5+
export * from "./https.v2";

integration_test/functions/src/utils.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,39 @@ export function waitForEvent<T = unknown>(
2525
): Promise<T> {
2626
return new Promise<T>((resolve, reject) => {
2727
let timer: NodeJS.Timeout | null = null;
28+
let triggerCompleted = false;
29+
let snapshotData: T | null = null;
30+
let unsubscribe: (() => void) | null = null;
31+
32+
const checkAndResolve = () => {
33+
if (triggerCompleted && snapshotData !== null) {
34+
if (timer) clearTimeout(timer);
35+
if (unsubscribe) unsubscribe();
36+
resolve(snapshotData);
37+
}
38+
};
2839

29-
const unsubscribe = firestore
40+
unsubscribe = firestore
3041
.collection(RUN_ID)
3142
.doc(event)
3243
.onSnapshot((snapshot) => {
3344
if (snapshot.exists) {
34-
if (timer) clearTimeout(timer);
35-
unsubscribe();
36-
resolve(snapshot.data() as T);
45+
snapshotData = snapshot.data() as T;
46+
checkAndResolve();
3747
}
3848
});
3949

4050
timer = setTimeout(() => {
41-
unsubscribe();
51+
if (unsubscribe) unsubscribe();
4252
reject(new Error(`Timeout waiting for event "${event}" after ${timeoutMs}ms`));
4353
}, timeoutMs);
4454

45-
trigger().then().catch(reject);
55+
trigger()
56+
.then(() => {
57+
triggerCompleted = true;
58+
checkAndResolve();
59+
})
60+
.catch(reject);
4661
});
4762
}
4863

0 commit comments

Comments
 (0)