



























@@ -138,6 +138,33 @@ function createFakeFetch(handlers: Array<(url: string, init?: unknown) => unknow
138138return { fetchImpl, calls };
139139}
140140141+function expectInvokeResponse(sendActivity: ReturnType<typeof vi.fn>, status?: number): void {
142+const activity = sendActivity.mock.calls.find(([arg]) => {
143+return (
144+typeof arg === "object" &&
145+arg !== null &&
146+(arg as { type?: unknown }).type === "invokeResponse"
147+);
148+})?.[0] as { value?: { status?: unknown } } | undefined;
149+150+expect(activity).toBeDefined();
151+if (status !== undefined) {
152+expect(activity?.value?.status).toBe(status);
153+}
154+}
155+156+function expectLogFields(logFn: unknown, message: string, fields: Record<string, unknown>): void {
157+const calls = (logFn as { mock?: { calls?: Array<[unknown, unknown?]> } }).mock?.calls;
158+expect(calls).toBeDefined();
159+const call = calls?.find(([text]) => text === message);
160+expect(call).toBeDefined();
161+const meta = call?.[1] as Record<string, unknown> | undefined;
162+expect(meta).toBeDefined();
163+for (const [key, value] of Object.entries(fields)) {
164+expect(meta?.[key]).toEqual(value);
165+}
166+}
167+141168function createBlockedSigninScenarios() {
142169return [
143170{
@@ -398,17 +425,11 @@ describe("msteams signin invoke handler registration", () => {
398425399426await registered.run(ctx);
400427401-expect(ctx.sendActivity).toHaveBeenCalledWith(
402-expect.objectContaining({
403-type: "invokeResponse",
404-value: expect.objectContaining({ status: 200 }),
405-}),
406-);
428+expectInvokeResponse(ctx.sendActivity, 200);
407429expect(run).not.toHaveBeenCalled();
408-expect(deps.log.debug).toHaveBeenCalledWith(
409-"signin invoke received but msteams.sso is not configured",
410-expect.objectContaining({ name: "signin/tokenExchange" }),
411-);
430+expectLogFields(deps.log.debug, "signin invoke received but msteams.sso is not configured", {
431+name: "signin/tokenExchange",
432+});
412433});
413434414435for (const invoke of invokeVariants) {
@@ -441,22 +462,14 @@ describe("msteams signin invoke handler registration", () => {
441462442463await registered.run(ctx);
443464444-expect(ctx.sendActivity).toHaveBeenCalledWith(
445-expect.objectContaining({
446-type: "invokeResponse",
447-value: expect.objectContaining({ status: 200 }),
448-}),
449-);
465+expectInvokeResponse(ctx.sendActivity, 200);
450466expect(calls).toHaveLength(0);
451467const stored = await tokenStore.get({
452468connectionName: "GraphConnection",
453469userId: scenario.context.userAadId ?? "aad-user-guid",
454470});
455471expect(stored).toBeNull();
456-expect(deps.log.debug).toHaveBeenCalledWith(
457-scenario.expectedDropLog,
458-expect.objectContaining({ name: invoke.name }),
459-);
472+expectLogFields(deps.log.debug, scenario.expectedDropLog, { name: invoke.name });
460473});
461474}
462475}
@@ -484,16 +497,11 @@ describe("msteams signin invoke handler registration", () => {
484497485498await registered.run(ctx);
486499487-expect(ctx.sendActivity).toHaveBeenCalledWith(
488-expect.objectContaining({
489-type: "invokeResponse",
490-value: expect.objectContaining({ status: 200 }),
491-}),
492-);
493-expect(deps.log.info).toHaveBeenCalledWith(
494-"msteams sso token exchanged",
495-expect.objectContaining({ userId: "aad-user-guid", hasExpiry: true }),
496-);
500+expectInvokeResponse(ctx.sendActivity, 200);
501+expectLogFields(deps.log.info, "msteams sso token exchanged", {
502+userId: "aad-user-guid",
503+hasExpiry: true,
504+});
497505const stored = await tokenStore.get({
498506connectionName: "GraphConnection",
499507userId: "aad-user-guid",
@@ -515,13 +523,11 @@ describe("msteams signin invoke handler registration", () => {
515523516524await registered.run(ctx);
517525518-expect(ctx.sendActivity).toHaveBeenCalledWith(
519-expect.objectContaining({ type: "invokeResponse" }),
520-);
521-expect(deps.log.error).toHaveBeenCalledWith(
522-"msteams sso token exchange failed",
523-expect.objectContaining({ code: "unexpected_response", status: 400 }),
524-);
526+expectInvokeResponse(ctx.sendActivity);
527+expectLogFields(deps.log.error, "msteams sso token exchange failed", {
528+code: "unexpected_response",
529+status: 400,
530+});
525531});
526532527533it("handles signin/verifyState via the magic-code flow", async () => {
@@ -550,10 +556,9 @@ describe("msteams signin invoke handler registration", () => {
550556551557await registered.run(ctx);
552558553-expect(deps.log.info).toHaveBeenCalledWith(
554-"msteams sso verifyState succeeded",
555-expect.objectContaining({ userId: "aad-user-guid" }),
556-);
559+expectLogFields(deps.log.info, "msteams sso verifyState succeeded", {
560+userId: "aad-user-guid",
561+});
557562const stored = await tokenStore.get({
558563connectionName: "GraphConnection",
559564userId: "aad-user-guid",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。