slackapi / deno-slack-sdk

SDK for building Run on Slack apps using Deno
https://api.slack.com/automation
151 stars 27 forks source link

[QUERY] Running a test with the recommended setup results in 405 status code error #287

Closed hgg closed 4 months ago

hgg commented 4 months ago

Question

Why do I get a 405 error when running a test for a function that calls

const userGroups = await client.usergroups.list();

when the function is mocked like so

mf.mock("GET@/api/usergroups.list", (_args) => {
  return new Response(
    `{"ok": true, "userGroups": [{ handle: "admin", id: "S0321TZR7" }]}`,
  );
});

Test output

image

Context

I need to create a workflow that sends a message and tags a slack group on that message. Since tagging groups is not supported out-of-the-box, I thought about creating a custom function that would get the name of the group to be tagged as an input and, using the usergroups.list API, get the proper group ID and tag it on the message.

Full code Function definition ```javascript import { DefineFunction, Schema, SlackFunction } from "deno-slack-sdk/mod.ts"; export const AddTagFunction = DefineFunction({ callback_id: "add_tag_function", title: "Adds Group Tag to Message", description: "Replaces the text-version group tag with a proper slack tag for the same group", source_file: "functions/add_tag_function.ts", input_parameters: { properties: { message: { type: Schema.types.string, description: "Message to be posted. Must contain `@group` so that it can be replaced in the final message.", }, group_display_name: { type: Schema.types.string, description: "Display name of the group to be tagged. A tag for this group will replace `@group` in the message.", }, }, required: ["message", "group_display_name"], }, output_parameters: { properties: { updatedMsg: { type: Schema.types.string, description: "Updated message to be posted", }, }, required: ["updatedMsg"], }, }); export default SlackFunction( AddTagFunction, async ({ inputs, client }) => { // Retrieve the list of user groups const userGroups = await client.usergroups.list(); if (!userGroups.ok) { // If there was an error retrieving user groups, log an error and return the original message console.error("Error retrieving user groups:", userGroups.error); return { outputs: { updatedMsg: inputs.message } }; } // Find the user group with the specified display name const userGroup = userGroups.userGroups.find(( group: { handle: string; id: string }, ) => group.handle === inputs.group_display_name); if (!userGroup) { // If the user group is not found, log an error and return the original message console.error("User group not found:", inputs.group_display_name); return { outputs: { updatedMsg: inputs.message } }; } // Generate the user group tag const userGroupTag = ``; // Replace "@group" with the user group tag in the message // I know this doesn't likely tag the group. This is just an intermediary version before I actually send the message through the API. const updatedMsg = inputs.message.replace("@group", userGroupTag); // Return the updated message return { outputs: { updatedMsg } }; }, ); ``` Test ```javascript import { SlackFunctionTester } from "deno-slack-sdk/mod.ts"; import { assertEquals } from "std/assert/assert_equals.ts"; import AddTagFunction from "./add_tag_function.ts"; import * as mf from "mock-fetch/mod.ts"; const { createContext } = SlackFunctionTester("add_tag_function"); // Replaces globalThis.fetch with the mocked copy mf.install(); // Shared mocks can be defined at the top level of tests mf.mock("GET@/api/usergroups.list", (_args) => { return new Response( `{"ok": true, "userGroups": [{ handle: "admins", id: "S0321TZR7" }]}`, ); }); Deno.test("AddGroupTag returns the original message with the proper group tag", async () => { const inputs = { message: "Testing message where @group is tagged.", group_display_name: "admins", }; const { outputs, error } = await AddTagFunction(createContext({ inputs })); assertEquals(error, undefined); assertEquals( outputs?.updatedMsg, "Testing message where is tagged.", ); }); ```

Environment

# Slack SDK & API
"deno-slack-sdk/": "https://deno.land/x/deno_slack_sdk@2.6.0/",
"deno-slack-api/": "https://deno.land/x/deno_slack_api@2.2.0/",

# Deno Version
deno 1.41.0 (release, aarch64-apple-darwin)
v8 12.1.285.27
typescript 5.3.3

# Machine
ProductName:            macOS
ProductVersion:         14.3.1
BuildVersion:           23D60
WilliamBergamin commented 4 months ago

Hi @hgg thanks for writing in 💯

The following works on my end

Deno.test("Test mocking behavior", async () => {
  mf.install();
  mf.mock("POST@/api/usergroups.list", () => {
    return new Response(
      `{"ok": true, "userGroups": [{ "handle": "admin", "id": "S0321TZR7" }]}`,
      {
        status: 200,
      },
    );
  });
  const client = SlackAPI("test");
  const userGroups = await client.usergroups.list();

  assert(userGroups.ok);
});

Let me know if this helps

hgg commented 4 months ago

Yes! That worked @WilliamBergamin. Thank you very much for this 🙏🏼