Suite of AT Protocol TypeScript libraries built on web standards
21
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 241 lines 5.5 kB view raw
1import type { LexiconDoc } from "@atp/lexicon"; 2import { Client } from "./_xrpc-client.ts"; 3import * as xrpcServer from "../mod.ts"; 4import { closeServer, createServer } from "./_util.ts"; 5import { assertEquals, assertRejects } from "@std/assert"; 6 7const LEXICONS: LexiconDoc[] = [ 8 { 9 lexicon: 1, 10 id: "io.example.paramTest", 11 defs: { 12 main: { 13 type: "query", 14 parameters: { 15 type: "params", 16 required: ["str", "int", "bool", "arr"], 17 properties: { 18 str: { type: "string", minLength: 2, maxLength: 10 }, 19 int: { type: "integer", minimum: 2, maximum: 10 }, 20 bool: { type: "boolean" }, 21 arr: { type: "array", items: { type: "integer" }, maxLength: 2 }, 22 def: { type: "integer", default: 0 }, 23 }, 24 }, 25 output: { 26 encoding: "application/json", 27 }, 28 }, 29 }, 30 }, 31]; 32 33let server: ReturnType<typeof xrpcServer.createServer>; 34let s: Deno.HttpServer; 35let client: Client; 36 37Deno.test.beforeAll(async () => { 38 server = xrpcServer.createServer(LEXICONS); 39 server.method( 40 "io.example.paramTest", 41 (ctx: { params: xrpcServer.Params }) => ({ 42 encoding: "application/json", 43 body: ctx.params, 44 }), 45 ); 46 47 s = await createServer(server); 48 const port = (s as Deno.HttpServer & { port: number }).port; 49 client = new Client(`http://localhost:${port}`, LEXICONS); 50}); 51 52Deno.test.afterAll(async () => { 53 await closeServer(s); 54}); 55 56Deno.test("validates query params with valid data", { 57 sanitizeOps: false, 58 sanitizeResources: false, 59}, async () => { 60 const res1 = await client.call("io.example.paramTest", { 61 str: "valid", 62 int: 5, 63 bool: true, 64 arr: [1, 2], 65 def: 5, 66 }); 67 assertEquals(res1.success, true); 68 assertEquals(res1.data.str, "valid"); 69 assertEquals(res1.data.int, 5); 70 assertEquals(res1.data.bool, true); 71 assertEquals(res1.data.arr, [1, 2]); 72 assertEquals(res1.data.def, 5); 73}); 74 75Deno.test("coerces query params to correct types", { 76 sanitizeOps: false, 77 sanitizeResources: false, 78}, async () => { 79 const res2 = await client.call("io.example.paramTest", { 80 str: 10, 81 int: "5", 82 bool: "foo", 83 arr: "3", 84 }); 85 assertEquals(res2.success, true); 86 assertEquals(res2.data.str, "10"); 87 assertEquals(res2.data.int, 5); 88 assertEquals(res2.data.bool, false); 89 assertEquals(res2.data.arr, [3]); 90 assertEquals(res2.data.def, 0); 91}); 92 93Deno.test("rejects string that is too short", { 94 sanitizeOps: false, 95 sanitizeResources: false, 96}, async () => { 97 await assertRejects( 98 () => 99 client.call("io.example.paramTest", { 100 str: "n", 101 int: 5, 102 bool: true, 103 arr: [1], 104 }), 105 Error, 106 "str must not be shorter than 2 characters", 107 ); 108}); 109 110Deno.test("rejects string that is too long", { 111 sanitizeOps: false, 112 sanitizeResources: false, 113}, async () => { 114 await assertRejects( 115 () => 116 client.call("io.example.paramTest", { 117 str: "loooooooooooooong", 118 int: 5, 119 bool: true, 120 arr: [1], 121 }), 122 Error, 123 "str must not be longer than 10 characters", 124 ); 125}); 126 127Deno.test("rejects when required str param is missing", { 128 sanitizeOps: false, 129 sanitizeResources: false, 130}, async () => { 131 await assertRejects( 132 () => 133 client.call("io.example.paramTest", { 134 int: 5, 135 bool: true, 136 arr: [1], 137 }), 138 Error, 139 'Params must have the property "str"', 140 ); 141}); 142 143Deno.test("rejects integer that is too small", { 144 sanitizeOps: false, 145 sanitizeResources: false, 146}, async () => { 147 await assertRejects( 148 () => 149 client.call("io.example.paramTest", { 150 str: "valid", 151 int: -1, 152 bool: true, 153 arr: [1], 154 }), 155 Error, 156 "int can not be less than 2", 157 ); 158}); 159 160Deno.test("rejects integer that is too large", { 161 sanitizeOps: false, 162 sanitizeResources: false, 163}, async () => { 164 await assertRejects( 165 () => 166 client.call("io.example.paramTest", { 167 str: "valid", 168 int: 11, 169 bool: true, 170 arr: [1], 171 }), 172 Error, 173 "int can not be greater than 10", 174 ); 175}); 176 177Deno.test("rejects when required int param is missing", { 178 sanitizeOps: false, 179 sanitizeResources: false, 180}, async () => { 181 await assertRejects( 182 () => 183 client.call("io.example.paramTest", { 184 str: "valid", 185 bool: true, 186 arr: [1], 187 }), 188 Error, 189 'Params must have the property "int"', 190 ); 191}); 192 193Deno.test("rejects when required bool param is missing", { 194 sanitizeOps: false, 195 sanitizeResources: false, 196}, async () => { 197 await assertRejects( 198 () => 199 client.call("io.example.paramTest", { 200 str: "valid", 201 int: 5, 202 arr: [1], 203 }), 204 Error, 205 'Params must have the property "bool"', 206 ); 207}); 208 209Deno.test("rejects when required array param is empty", { 210 sanitizeOps: false, 211 sanitizeResources: false, 212}, async () => { 213 await assertRejects( 214 () => 215 client.call("io.example.paramTest", { 216 str: "valid", 217 int: 5, 218 bool: true, 219 arr: [], 220 }), 221 Error, 222 'Error: Params must have the property "arr"', 223 ); 224}); 225 226Deno.test("rejects array that exceeds max length", { 227 sanitizeOps: false, 228 sanitizeResources: false, 229}, async () => { 230 await assertRejects( 231 () => 232 client.call("io.example.paramTest", { 233 str: "valid", 234 int: 5, 235 bool: true, 236 arr: [1, 2, 3], 237 }), 238 Error, 239 "Error: arr must not have more than 2 elements", 240 ); 241});