7f26b17652
* Improve error message when using invalid client_id during code exchange * Extract SPA example OAuth client in own package * wip * remove dependency on get-port * Properly configure jest to only transpile "get-port" from node_modules https://jestjs.io/docs/configuration#transformignorepatterns-arraystring * Use dynamically assigned port number during tests * use puppeteer to run tests * remove login input "id" attribute * code style * add missing declaration * tidy * headless * remove get-port dependency * fix tests/proxied/admin.test.ts * fix tests * Allow unsecure oauth providers through configuration * transpile "lande" during ozone tests * Cache Puppeteer browser binaries * Use puppeteer cache during all workflow steps * remove use of set-output * use get-port in xrpc-server tests * Renamed to allowHttp * tidy * tidy
170 lines
4.3 KiB
TypeScript
170 lines
4.3 KiB
TypeScript
import * as http from 'node:http'
|
|
import { Readable } from 'node:stream'
|
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
import { XrpcClient } from '@atproto/xrpc'
|
|
import { createServer, closeServer } from './_util'
|
|
import * as xrpcServer from '../src'
|
|
import { AddressInfo } from 'node:net'
|
|
|
|
const LEXICONS: LexiconDoc[] = [
|
|
{
|
|
lexicon: 1,
|
|
id: 'io.example.pingOne',
|
|
defs: {
|
|
main: {
|
|
type: 'procedure',
|
|
parameters: {
|
|
type: 'params',
|
|
properties: {
|
|
message: { type: 'string' },
|
|
},
|
|
},
|
|
output: {
|
|
encoding: 'text/plain',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
lexicon: 1,
|
|
id: 'io.example.pingTwo',
|
|
defs: {
|
|
main: {
|
|
type: 'procedure',
|
|
input: {
|
|
encoding: 'text/plain',
|
|
},
|
|
output: {
|
|
encoding: 'text/plain',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
lexicon: 1,
|
|
id: 'io.example.pingThree',
|
|
defs: {
|
|
main: {
|
|
type: 'procedure',
|
|
input: {
|
|
encoding: 'application/octet-stream',
|
|
},
|
|
output: {
|
|
encoding: 'application/octet-stream',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
lexicon: 1,
|
|
id: 'io.example.pingFour',
|
|
defs: {
|
|
main: {
|
|
type: 'procedure',
|
|
input: {
|
|
encoding: 'application/json',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['message'],
|
|
properties: { message: { type: 'string' } },
|
|
},
|
|
},
|
|
output: {
|
|
encoding: 'application/json',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['message'],
|
|
properties: { message: { type: 'string' } },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
]
|
|
|
|
describe('Procedures', () => {
|
|
let s: http.Server
|
|
const server = xrpcServer.createServer(LEXICONS)
|
|
server.method('io.example.pingOne', (ctx: { params: xrpcServer.Params }) => {
|
|
return { encoding: 'text/plain', body: ctx.params.message }
|
|
})
|
|
server.method(
|
|
'io.example.pingTwo',
|
|
(ctx: { params: xrpcServer.Params; input?: xrpcServer.HandlerInput }) => {
|
|
return { encoding: 'text/plain', body: ctx.input?.body }
|
|
},
|
|
)
|
|
server.method(
|
|
'io.example.pingThree',
|
|
async (ctx: {
|
|
params: xrpcServer.Params
|
|
input?: xrpcServer.HandlerInput
|
|
}) => {
|
|
if (!(ctx.input?.body instanceof Readable))
|
|
throw new Error('Input not readable')
|
|
const buffers: Buffer[] = []
|
|
for await (const data of ctx.input.body) {
|
|
buffers.push(data)
|
|
}
|
|
return {
|
|
encoding: 'application/octet-stream',
|
|
body: Buffer.concat(buffers),
|
|
}
|
|
},
|
|
)
|
|
server.method(
|
|
'io.example.pingFour',
|
|
(ctx: { params: xrpcServer.Params; input?: xrpcServer.HandlerInput }) => {
|
|
return {
|
|
encoding: 'application/json',
|
|
body: { message: ctx.input?.body?.message },
|
|
}
|
|
},
|
|
)
|
|
|
|
let client: XrpcClient
|
|
beforeAll(async () => {
|
|
s = await createServer(server)
|
|
const { port } = s.address() as AddressInfo
|
|
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
})
|
|
afterAll(async () => {
|
|
await closeServer(s)
|
|
})
|
|
|
|
it('serves requests', async () => {
|
|
const res1 = await client.call('io.example.pingOne', {
|
|
message: 'hello world',
|
|
})
|
|
expect(res1.success).toBeTruthy()
|
|
expect(res1.headers['content-type']).toBe('text/plain; charset=utf-8')
|
|
expect(res1.data).toBe('hello world')
|
|
|
|
const res2 = await client.call('io.example.pingTwo', {}, 'hello world', {
|
|
encoding: 'text/plain',
|
|
})
|
|
expect(res2.success).toBeTruthy()
|
|
expect(res2.headers['content-type']).toBe('text/plain; charset=utf-8')
|
|
expect(res2.data).toBe('hello world')
|
|
|
|
const res3 = await client.call(
|
|
'io.example.pingThree',
|
|
{},
|
|
new TextEncoder().encode('hello world'),
|
|
{ encoding: 'application/octet-stream' },
|
|
)
|
|
expect(res3.success).toBeTruthy()
|
|
expect(res3.headers['content-type']).toBe('application/octet-stream')
|
|
expect(new TextDecoder().decode(res3.data)).toBe('hello world')
|
|
|
|
const res4 = await client.call(
|
|
'io.example.pingFour',
|
|
{},
|
|
{ message: 'hello world' },
|
|
)
|
|
expect(res4.success).toBeTruthy()
|
|
expect(res4.headers['content-type']).toBe('application/json; charset=utf-8')
|
|
expect(res4.data?.message).toBe('hello world')
|
|
})
|
|
})
|