An ATProto Lexicon validator for Gleam.
at v1.2.0 5.9 kB view raw
1import gleam/json 2import gleeunit 3import gleeunit/should 4import honk/validation/context 5import honk/validation/primary/query 6 7pub fn main() { 8 gleeunit.main() 9} 10 11// Test valid query parameters 12pub fn valid_query_parameters_test() { 13 let schema = 14 json.object([ 15 #("type", json.string("query")), 16 #( 17 "parameters", 18 json.object([ 19 #("type", json.string("params")), 20 #( 21 "properties", 22 json.object([ 23 #( 24 "limit", 25 json.object([ 26 #("type", json.string("integer")), 27 #("minimum", json.int(1)), 28 #("maximum", json.int(100)), 29 ]), 30 ), 31 #("cursor", json.object([#("type", json.string("string"))])), 32 ]), 33 ), 34 ]), 35 ), 36 ]) 37 38 let data = 39 json.object([#("limit", json.int(50)), #("cursor", json.string("abc123"))]) 40 41 let assert Ok(ctx) = context.builder() |> context.build() 42 query.validate_data(data, schema, ctx) |> should.be_ok 43} 44 45// Test query with required parameter 46pub fn valid_query_with_required_test() { 47 let schema = 48 json.object([ 49 #("type", json.string("query")), 50 #( 51 "parameters", 52 json.object([ 53 #("type", json.string("params")), 54 #( 55 "properties", 56 json.object([ 57 #("repo", json.object([#("type", json.string("string"))])), 58 ]), 59 ), 60 #("required", json.array([json.string("repo")], fn(x) { x })), 61 ]), 62 ), 63 ]) 64 65 let data = json.object([#("repo", json.string("did:plc:abc123"))]) 66 67 let assert Ok(ctx) = context.builder() |> context.build() 68 query.validate_data(data, schema, ctx) |> should.be_ok 69} 70 71// Test invalid: missing required parameter 72pub fn invalid_query_missing_required_test() { 73 let schema = 74 json.object([ 75 #("type", json.string("query")), 76 #( 77 "parameters", 78 json.object([ 79 #("type", json.string("params")), 80 #( 81 "properties", 82 json.object([ 83 #("repo", json.object([#("type", json.string("string"))])), 84 #("collection", json.object([#("type", json.string("string"))])), 85 ]), 86 ), 87 #("required", json.array([json.string("repo")], fn(x) { x })), 88 ]), 89 ), 90 ]) 91 92 let data = json.object([#("collection", json.string("app.bsky.feed.post"))]) 93 94 let assert Ok(ctx) = context.builder() |> context.build() 95 query.validate_data(data, schema, ctx) |> should.be_error 96} 97 98// Test invalid: wrong parameter type 99pub fn invalid_query_wrong_type_test() { 100 let schema = 101 json.object([ 102 #("type", json.string("query")), 103 #( 104 "parameters", 105 json.object([ 106 #("type", json.string("params")), 107 #( 108 "properties", 109 json.object([ 110 #( 111 "limit", 112 json.object([ 113 #("type", json.string("integer")), 114 #("minimum", json.int(1)), 115 ]), 116 ), 117 ]), 118 ), 119 ]), 120 ), 121 ]) 122 123 let data = json.object([#("limit", json.string("not-a-number"))]) 124 125 let assert Ok(ctx) = context.builder() |> context.build() 126 query.validate_data(data, schema, ctx) |> should.be_error 127} 128 129// Test invalid: data not an object 130pub fn invalid_query_not_object_test() { 131 let schema = 132 json.object([ 133 #("type", json.string("query")), 134 #( 135 "parameters", 136 json.object([ 137 #("type", json.string("params")), 138 #("properties", json.object([])), 139 ]), 140 ), 141 ]) 142 143 let data = json.array([], fn(x) { x }) 144 145 let assert Ok(ctx) = context.builder() |> context.build() 146 query.validate_data(data, schema, ctx) |> should.be_error 147} 148 149// Test parameter constraint violation 150pub fn invalid_query_constraint_violation_test() { 151 let schema = 152 json.object([ 153 #("type", json.string("query")), 154 #( 155 "parameters", 156 json.object([ 157 #("type", json.string("params")), 158 #( 159 "properties", 160 json.object([ 161 #( 162 "limit", 163 json.object([ 164 #("type", json.string("integer")), 165 #("maximum", json.int(100)), 166 ]), 167 ), 168 ]), 169 ), 170 ]), 171 ), 172 ]) 173 174 let data = json.object([#("limit", json.int(200))]) 175 176 let assert Ok(ctx) = context.builder() |> context.build() 177 query.validate_data(data, schema, ctx) |> should.be_error 178} 179 180// Test array parameter 181pub fn valid_query_array_parameter_test() { 182 let schema = 183 json.object([ 184 #("type", json.string("query")), 185 #( 186 "parameters", 187 json.object([ 188 #("type", json.string("params")), 189 #( 190 "properties", 191 json.object([ 192 #( 193 "tags", 194 json.object([ 195 #("type", json.string("array")), 196 #( 197 "items", 198 json.object([ 199 #("type", json.string("string")), 200 #("maxLength", json.int(50)), 201 ]), 202 ), 203 ]), 204 ), 205 ]), 206 ), 207 ]), 208 ), 209 ]) 210 211 let data = 212 json.object([ 213 #( 214 "tags", 215 json.array([json.string("tag1"), json.string("tag2")], fn(x) { x }), 216 ), 217 ]) 218 219 let assert Ok(ctx) = context.builder() |> context.build() 220 query.validate_data(data, schema, ctx) |> should.be_ok 221} 222 223// Test query with no parameters 224pub fn valid_query_no_parameters_test() { 225 let schema = json.object([#("type", json.string("query"))]) 226 227 let data = json.object([]) 228 229 let assert Ok(ctx) = context.builder() |> context.build() 230 query.validate_data(data, schema, ctx) |> should.be_ok 231}