-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update base-client.ts --------- Co-authored-by: Fil Maj <[email protected]>
- Loading branch information
1 parent
d857639
commit 368e406
Showing
5 changed files
with
200 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
const API_VERSION_REGEX = /\/deno_slack_api@(.*)\//; | ||
|
||
export function getUserAgent() { | ||
const userAgents = []; | ||
userAgents.push(`Deno/${Deno.version.deno}`); | ||
userAgents.push(`OS/${Deno.build.os}`); | ||
userAgents.push( | ||
`deno-slack-api/${_internals.getModuleVersion()}`, | ||
); | ||
return userAgents.join(" "); | ||
} | ||
|
||
function getModuleVersion(): string | undefined { | ||
const url = _internals.getModuleUrl(); | ||
// Insure this module is sourced from https://deno.land/x/deno_slack_api | ||
if (url.host === "deno.land") { | ||
return url.pathname.match(API_VERSION_REGEX)?.at(1); | ||
} | ||
return undefined; | ||
} | ||
|
||
function getModuleUrl(): URL { | ||
return new URL(import.meta.url); | ||
} | ||
|
||
// Serialize an object into a string so as to be compatible with x-www-form-urlencoded payloads | ||
export function serializeData(data: Record<string, unknown>): URLSearchParams { | ||
const encodedData: Record<string, string> = {}; | ||
Object.entries(data).forEach(([key, value]) => { | ||
// Objects/arrays, numbers and booleans get stringified | ||
// Slack API accepts JSON-stringified-and-url-encoded payloads for objects/arrays | ||
// Inspired by https://github.com/slackapi/node-slack-sdk/blob/%40slack/web-api%406.7.2/packages/web-api/src/WebClient.ts#L452-L528 | ||
|
||
// Skip properties with undefined values. | ||
if (value === undefined) return; | ||
|
||
const serializedValue: string = typeof value !== "string" | ||
? JSON.stringify(value) | ||
: value; | ||
encodedData[key] = serializedValue; | ||
}); | ||
|
||
return new URLSearchParams(encodedData); | ||
} | ||
|
||
export const _internals = { getModuleVersion, getModuleUrl }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts"; | ||
import { | ||
_internals, | ||
getUserAgent, | ||
serializeData, | ||
} from "./base-client-helpers.ts"; | ||
import { assertSpyCalls, stub } from "./dev_deps.ts"; | ||
|
||
Deno.test(`base-client-helpers.${_internals.getModuleVersion.name}`, async (t) => { | ||
await t.step( | ||
"should return the version if the module is sourced from deno.land", | ||
() => { | ||
const getModuleUrlStub = stub(_internals, "getModuleUrl", () => { | ||
return new URL("https://deno.land/x/[email protected]/mod.ts)"); | ||
}); | ||
|
||
try { | ||
const moduleVersion = _internals.getModuleVersion(); | ||
|
||
assertSpyCalls(getModuleUrlStub, 1); | ||
assertEquals(moduleVersion, "2.1.0"); | ||
} finally { | ||
getModuleUrlStub.restore(); | ||
} | ||
}, | ||
); | ||
|
||
await t.step( | ||
"should return undefined if the module is not sourced from deno.land", | ||
() => { | ||
const getModuleUrlStub = stub(_internals, "getModuleUrl", () => { | ||
return new URL("file:///hello/world.ts)"); | ||
}); | ||
try { | ||
const moduleVersion = _internals.getModuleVersion(); | ||
|
||
assertSpyCalls(getModuleUrlStub, 1); | ||
assertEquals(moduleVersion, undefined); | ||
} finally { | ||
getModuleUrlStub.restore(); | ||
} | ||
}, | ||
); | ||
|
||
await t.step( | ||
"should return undefined if the regex used to parse [email protected] fails", | ||
() => { | ||
const getModuleUrlStub = stub(_internals, "getModuleUrl", () => { | ||
return new URL("https://deno.land/x/[email protected]/mod.ts)"); | ||
}); | ||
try { | ||
const moduleVersion = _internals.getModuleVersion(); | ||
|
||
assertSpyCalls(getModuleUrlStub, 1); | ||
assertEquals(moduleVersion, undefined); | ||
} finally { | ||
getModuleUrlStub.restore(); | ||
} | ||
}, | ||
); | ||
}); | ||
|
||
Deno.test(`base-client-helpers.${getUserAgent.name}`, async (t) => { | ||
await t.step( | ||
"should return the user agent with deno version, OS name and undefined deno-slack-api version", | ||
() => { | ||
const expectedVersion = undefined; | ||
const getModuleUrlStub = stub(_internals, "getModuleVersion", () => { | ||
return expectedVersion; | ||
}); | ||
|
||
try { | ||
const userAgent = getUserAgent(); | ||
|
||
assertSpyCalls(getModuleUrlStub, 1); | ||
assertEquals( | ||
userAgent, | ||
`Deno/${Deno.version.deno} OS/${Deno.build.os} deno-slack-api/undefined`, | ||
); | ||
} finally { | ||
getModuleUrlStub.restore(); | ||
} | ||
}, | ||
); | ||
|
||
await t.step( | ||
"should return the user agent with deno version, OS name and deno-slack-api version", | ||
() => { | ||
const expectedVersion = "2.1.0"; | ||
const getModuleUrlStub = stub(_internals, "getModuleUrl", () => { | ||
return new URL( | ||
`https://deno.land/x/deno_slack_api@${expectedVersion}/mod.ts)`, | ||
); | ||
}); | ||
|
||
try { | ||
const userAgent = getUserAgent(); | ||
|
||
assertSpyCalls(getModuleUrlStub, 1); | ||
assertEquals( | ||
userAgent, | ||
`Deno/${Deno.version.deno} OS/${Deno.build.os} deno-slack-api/${expectedVersion}`, | ||
); | ||
} finally { | ||
getModuleUrlStub.restore(); | ||
} | ||
}, | ||
); | ||
}); | ||
|
||
Deno.test(`${serializeData.name} helper function`, async (t) => { | ||
await t.step( | ||
"should serialize string values as strings and return a URLSearchParams object", | ||
() => { | ||
assertEquals( | ||
serializeData({ "batman": "robin" }).toString(), | ||
"batman=robin", | ||
); | ||
}, | ||
); | ||
await t.step( | ||
"should serialize non-string values as JSON-encoded strings and return a URLSearchParams object", | ||
() => { | ||
assertEquals( | ||
serializeData({ "hockey": { "good": true, "awesome": "yes" } }) | ||
.toString(), | ||
"hockey=%7B%22good%22%3Atrue%2C%22awesome%22%3A%22yes%22%7D", | ||
); | ||
}, | ||
); | ||
await t.step( | ||
"should not serialize undefined values", | ||
() => { | ||
assertEquals( | ||
serializeData({ | ||
"hockey": { "good": true, "awesome": "yes" }, | ||
"baseball": undefined, | ||
}) | ||
.toString(), | ||
"hockey=%7B%22good%22%3Atrue%2C%22awesome%22%3A%22yes%22%7D", | ||
); | ||
}, | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,7 @@ export { | |
afterEach, | ||
beforeAll, | ||
} from "https://deno.land/[email protected]/testing/bdd.ts"; | ||
export { | ||
assertSpyCalls, | ||
stub, | ||
} from "https://deno.land/[email protected]/testing/mock.ts"; |