Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add chat/workspaces with discord map #215

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1cdf0d0
feat(chat/workspaces): add profile
martinalbert Feb 24, 2022
2fab038
feat(chat/workspaces/discord): add map and provider
martinalbert Feb 24, 2022
ebdfc37
test(chat/workspaces): add tests, snaps and recs
martinalbert Feb 24, 2022
7f52830
chore: format
martinalbert Feb 24, 2022
8c1407b
feat(chat/workspaces): update profile
martinalbert Feb 24, 2022
24c1e9c
feat(chat/workspaces/mock): add map
martinalbert Feb 24, 2022
728f7ba
feat(chat/workspaces/discord): update map
martinalbert Feb 24, 2022
3fa9613
chore(chat/workspaces): add description for profile
martinalbert Mar 15, 2022
b989ec4
chore(chat/workspaces): add examples to profile
martinalbert Mar 15, 2022
598946f
fix(chat/threads): update timestamps to seconds
martinalbert Mar 15, 2022
e47fabe
chore(chat/workspaces): update timestamps description
martinalbert Mar 15, 2022
a0269d5
Apply suggestions from code review
martinalbert Mar 22, 2022
70967bc
test(chat/workspaces): update recording hash
martinalbert Mar 22, 2022
68cae02
test(chat/workspaces/discord): update snapshot
martinalbert Mar 22, 2022
554bfc3
Merge branch 'main' into feature/chat-workspaces
martinalbert Mar 22, 2022
2551810
feat(chat/workspaces/discord): update profile
martinalbert Jun 9, 2022
05150a2
feat(chat/workspaces/discord): update map
martinalbert Jun 9, 2022
bd3d4de
chore(chat/workspaces/discord): update snaps and recs
martinalbert Jun 9, 2022
301018c
feat(chat/workspaces): update profile version in map
martinalbert Jun 9, 2022
c034f32
Update grid/chat/workspaces/profile.supr
martinalbert Jun 9, 2022
ade2bd9
feat(chat/workspaces): remove unnecassary field from input
martinalbert Jun 13, 2022
c24f660
feat(chat/workspaces/discord): update map
martinalbert Jun 13, 2022
0a8dd13
test(chat/workspaces): update test cases
martinalbert Jun 13, 2022
32b9a5d
Merge branch 'main' into feature/chat-workspaces
martinalbert Jun 13, 2022
b00e525
chore(chat/workspaces): update profile
martinalbert Jun 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions grid/chat/workspaces/maps/__snapshots__/discord.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`chat/workspaces/discord GetWorkspaces performs correctly 1`] = `
Ok {
"value": Object {
"rateLimit": Object {
"bucket": "2a0617accf8bb8625c43e2ffeb5b8d5b",
"remainingRequests": 0,
"remainingRequestsPercentage": 0,
"resetAfter": 1,
"resetTimestamp": 1645700687000,
"totalRequests": 1,
},
"workspaces": Array [
Object {
"createdAt": 1643221182610,
"id": "935962220104396881",
"name": "test server",
},
],
},
}
`;
180 changes: 180 additions & 0 deletions grid/chat/workspaces/maps/discord.suma
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
profile = "chat/[email protected]"
provider = "discord"

"""
GetWorkspaces map
"""
map GetWorkspaces {
http GET "/users/@me/guilds" {
request "application/json" {
headers {
"Authorization" = `${input.asBot ? 'Bot' : 'Bearer'} ${parameters.accessToken}`
}
}

response 200 "application/json" {
workspaces = call MapWorkspaces(workspaces = body)
rateLimit = call MapRateLimitDetails(headers = headers)

map result {
workspaces = workspaces
rateLimit = rateLimit
}
}

response {
error = call MapDiscordError(
statusCode = statusCode,
error = body,
headers = headers,
)

map error error
}
}
}

operation MapWorkspaces {
workspaces = args.workspaces.map(workspace => {
/**
* Returns UNIX timestamp from specified discord snowflake id
* More about snowflakes: https://discord.com/developers/docs/reference#snowflakes
*/
const discordEpoch = 1420070400000;
const getTimestamp = (snowflake) => Number(BigInt(snowflake) >> BigInt(22)) + discordEpoch;

const resultWorkspace = {
id: workspace.id,
createdAt: getTimestamp(workspace.id),
name: workspace.name,
};

if (workspace.member_count) {
resultWorkspace.membersCount = workspace.member_count;
}

if (workspace.icon) {
resultWorkspace.icon = workspace.icon;
}

if (workspace.description) {
resultWorkspace.description = workspace.description;
}

return resultWorkspace;
});

return workspaces
}


"""
Operation MapRateLimitDetails
Returns object mapping rate limit details specified in received headers
"""
operation MapRateLimitDetails {
headers = args.headers
details = {}

bucket = headers['x-ratelimit-bucket']
totalRequests = parseInt(headers['x-ratelimit-limit'])
remainingRequests = parseInt(headers['x-ratelimit-remaining'])
resetTimestamp = parseFloat(headers['x-ratelimit-reset'])
resetAfter = parseInt(headers['x-ratelimit-reset-after'])
retryAfter = parseInt(headers['Retry-After'])

set if (bucket) {
details.bucket = bucket
}

set if (!isNaN(totalRequests)) {
details.totalRequests = totalRequests
}

set if (!isNaN(remainingRequests)) {
details.remainingRequests = remainingRequests
}

set if (!isNaN(resetAfter)) {
details.resetAfter = resetAfter
}

set if (!isNaN(resetTimestamp)) {
details.resetTimestamp = resetTimestamp * 1000
}

set if (!isNaN(retryAfter)) {
details.retryAfter = retryAfter
}

set if (details.remainingRequests !== undefined && details.totalRequests) {
details.remainingRequestsPercentage = (details.remainingRequests / details.totalRequests) * 100
}

set if (Object.keys(details).length === 0) {
details = undefined
}

return details
}

"""
Operation Map Discord Error
Returns error object based on error body, statusCode and headers.
"""
operation MapDiscordError {
statusCode = args.statusCode
discordError = args.error
headers = args.headers

rateLimit = call MapRateLimitDetails(headers = headers)
detail = discordError.message

return if (statusCode === 400) {
title = 'Bad request'
detail = discordError
rateLimit = rateLimit
}

return if (statusCode === 401) {
title = 'Unauthorized'
detail = detail
rateLimit = rateLimit
}

return if (statusCode === 403) {
title = 'Forbidden'
detail = detail
rateLimit = rateLimit
}

return if (statusCode === 404) {
title = 'Not found'
detail = detail
rateLimit = rateLimit
}

return if (statusCode === 405) {
title = 'Method not allowed'
detail = detail
rateLimit = rateLimit
}

return if (statusCode === 429) {
title = 'Too Many Requests'
detail = `${detail} Retry after ${discordError.retry_after} seconds`
rateLimit = rateLimit
}

return if (statusCode === 502) {
title = 'Bad gateway'
detail = detail
rateLimit = rateLimit
}

return {
title = 'Unknown error'
detail = `Unknown error occurred. Status: ${statusCode}. Message: ${detail}.`
rateLimit = rateLimit
}
}
3 changes: 3 additions & 0 deletions grid/chat/workspaces/maps/discord.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { getWorkspacesTest } from './workspaces';

getWorkspacesTest('discord');
25 changes: 25 additions & 0 deletions grid/chat/workspaces/maps/mock.suma
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
profile = "chat/[email protected]"
provider = "mock"

"""
GetWorkspaces map
"""
map GetWorkspaces {
map result {
workspaces = [
{
id: '1',
createdAt: 1643798532134.069,
name: 'workspace',
membersCount: 100,
},
{
id: '2',
createdAt: 1643216443234.079,
name: 'workspace 2',
membersCount: 4,
description: 'Test workspace',
}
]
}
}
21 changes: 21 additions & 0 deletions grid/chat/workspaces/maps/mock.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { SuperfaceClient } from '@superfaceai/one-sdk';

describe('chat/workspaces/mock', () => {
describe('GetWorkspaces', () => {
it('performs correctly', async () => {
const client = new SuperfaceClient();
const profile = await client.getProfile('chat/workspaces');
const provider = await client.getProvider('mock');
const usecase = profile.getUseCase('GetWorkspaces');

expect(provider).not.toBeUndefined();
expect(usecase).not.toBeUndefined();

const result = await usecase.perform({}, { provider });

expect(result.isOk() && (result.value as any).workspaces.length).toEqual(
2
);
});
});
});
36 changes: 36 additions & 0 deletions grid/chat/workspaces/maps/workspaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable jest/no-export */

import { RecordingProcessOptions, SuperfaceTest } from '@superfaceai/testing';

export const getWorkspacesTest = (
provider: string,
options?: RecordingProcessOptions
): void => {
describe(`chat/workspaces/${provider}`, () => {
let superface: SuperfaceTest;

describe('GetWorkspaces', () => {
beforeAll(() => {
superface = new SuperfaceTest({
profile: 'chat/workspaces',
provider,
useCase: 'GetWorkspaces',
testInstance: expect,
});
});

it('performs correctly', async () => {
await expect(
superface.run(
{
input: {
asBot: true,
},
},
options
)
).resolves.toMatchSnapshot();
});
});
});
};
Loading