Auto-indexing service and GraphQL API for AT Protocol Records quickslice.slices.network/
atproto gleam graphql
at main 478 lines 12 kB view raw
1/// Tests for Mutation Builder - uploadBlob mutation 2/// 3/// Tests the uploadBlob mutation and BlobUploadResponse type with flat structure 4import gleam/dict 5import gleam/list 6import gleam/option.{None, Some} 7import gleeunit/should 8import lexicon_graphql/mutation/builder as mutation_builder 9import swell/schema 10import swell/value 11 12/// Test that uploadBlob mutation is added when factory is provided 13pub fn build_mutation_type_includes_upload_blob_test() { 14 // Create a simple upload blob resolver factory 15 let upload_factory = fn() { 16 fn(_ctx) { 17 Ok( 18 value.Object([ 19 #("ref", value.String("bafkreiabc123")), 20 #("mime_type", value.String("image/jpeg")), 21 #("size", value.Int(12_345)), 22 ]), 23 ) 24 } 25 } 26 27 // Build mutation type with uploadBlob factory 28 let mutation_build_result = 29 mutation_builder.build_mutation_type( 30 [], 31 dict.new(), 32 None, 33 None, 34 None, 35 Some(upload_factory), 36 None, 37 None, 38 ) 39 40 // Verify the mutation type has uploadBlob field 41 let fields = schema.get_fields(mutation_build_result.mutation_type) 42 let has_upload_blob = 43 list.any(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 44 45 has_upload_blob 46 |> should.be_true() 47} 48 49/// Test that uploadBlob mutation is NOT added when factory is None 50pub fn build_mutation_type_without_upload_blob_test() { 51 // Build mutation type without uploadBlob factory 52 let mutation_build_result = 53 mutation_builder.build_mutation_type( 54 [], 55 dict.new(), 56 None, 57 None, 58 None, 59 None, 60 None, 61 None, 62 ) 63 64 // Verify the mutation type does NOT have uploadBlob field 65 let fields = schema.get_fields(mutation_build_result.mutation_type) 66 let has_upload_blob = 67 list.any(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 68 69 has_upload_blob 70 |> should.be_false() 71} 72 73/// Test that uploadBlob mutation has correct arguments 74pub fn upload_blob_has_correct_arguments_test() { 75 // Create a simple factory 76 let upload_factory = fn() { 77 fn(_ctx) { 78 Ok( 79 value.Object([ 80 #("ref", value.String("test")), 81 #("mime_type", value.String("test")), 82 #("size", value.Int(0)), 83 ]), 84 ) 85 } 86 } 87 88 // Build mutation type 89 let mutation_build_result = 90 mutation_builder.build_mutation_type( 91 [], 92 dict.new(), 93 None, 94 None, 95 None, 96 Some(upload_factory), 97 None, 98 None, 99 ) 100 101 // Get uploadBlob field 102 let fields = schema.get_fields(mutation_build_result.mutation_type) 103 let upload_blob_field = 104 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 105 106 case upload_blob_field { 107 Ok(field) -> { 108 let args = schema.field_arguments(field) 109 // Should have 2 arguments: data and mimeType 110 let has_data = 111 list.any(args, fn(arg) { schema.argument_name(arg) == "data" }) 112 let has_mime_type = 113 list.any(args, fn(arg) { schema.argument_name(arg) == "mimeType" }) 114 115 has_data |> should.be_true() 116 has_mime_type |> should.be_true() 117 list.length(args) |> should.equal(2) 118 } 119 Error(_) -> should.be_true(False) 120 } 121} 122 123/// Test that data argument is non-null String 124pub fn upload_blob_data_argument_is_non_null_string_test() { 125 let upload_factory = fn() { 126 fn(_ctx) { 127 Ok( 128 value.Object([ 129 #("ref", value.String("test")), 130 #("mime_type", value.String("test")), 131 #("size", value.Int(0)), 132 ]), 133 ) 134 } 135 } 136 137 let mutation_build_result = 138 mutation_builder.build_mutation_type( 139 [], 140 dict.new(), 141 None, 142 None, 143 None, 144 Some(upload_factory), 145 None, 146 None, 147 ) 148 149 // Get uploadBlob field 150 let fields = schema.get_fields(mutation_build_result.mutation_type) 151 let upload_blob_field = 152 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 153 154 case upload_blob_field { 155 Ok(field) -> { 156 let args = schema.field_arguments(field) 157 let data_arg = 158 list.find(args, fn(arg) { schema.argument_name(arg) == "data" }) 159 160 case data_arg { 161 Ok(arg) -> { 162 let arg_type = schema.argument_type(arg) 163 // Check if it's non-null 164 schema.is_non_null(arg_type) |> should.be_true() 165 166 // Check if inner type is string 167 case schema.inner_type(arg_type) { 168 Some(inner) -> { 169 schema.type_name(inner) |> should.equal("String") 170 } 171 None -> should.be_true(False) 172 } 173 } 174 Error(_) -> should.be_true(False) 175 } 176 } 177 Error(_) -> should.be_true(False) 178 } 179} 180 181/// Test that mimeType argument is non-null String 182pub fn upload_blob_mime_type_argument_is_non_null_string_test() { 183 let upload_factory = fn() { 184 fn(_ctx) { 185 Ok( 186 value.Object([ 187 #("ref", value.String("test")), 188 #("mime_type", value.String("test")), 189 #("size", value.Int(0)), 190 ]), 191 ) 192 } 193 } 194 195 let mutation_build_result = 196 mutation_builder.build_mutation_type( 197 [], 198 dict.new(), 199 None, 200 None, 201 None, 202 Some(upload_factory), 203 None, 204 None, 205 ) 206 207 // Get uploadBlob field 208 let fields = schema.get_fields(mutation_build_result.mutation_type) 209 let upload_blob_field = 210 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 211 212 case upload_blob_field { 213 Ok(field) -> { 214 let args = schema.field_arguments(field) 215 let mime_type_arg = 216 list.find(args, fn(arg) { schema.argument_name(arg) == "mimeType" }) 217 218 case mime_type_arg { 219 Ok(arg) -> { 220 let arg_type = schema.argument_type(arg) 221 // Check if it's non-null 222 schema.is_non_null(arg_type) |> should.be_true() 223 224 // Check if inner type is string 225 case schema.inner_type(arg_type) { 226 Some(inner) -> { 227 schema.type_name(inner) |> should.equal("String") 228 } 229 None -> should.be_true(False) 230 } 231 } 232 Error(_) -> should.be_true(False) 233 } 234 } 235 Error(_) -> should.be_true(False) 236 } 237} 238 239/// Test that uploadBlob returns non-null BlobUploadResponse 240pub fn upload_blob_return_type_is_non_null_blob_upload_response_test() { 241 let upload_factory = fn() { 242 fn(_ctx) { 243 Ok( 244 value.Object([ 245 #("ref", value.String("test")), 246 #("mime_type", value.String("test")), 247 #("size", value.Int(0)), 248 ]), 249 ) 250 } 251 } 252 253 let mutation_build_result = 254 mutation_builder.build_mutation_type( 255 [], 256 dict.new(), 257 None, 258 None, 259 None, 260 Some(upload_factory), 261 None, 262 None, 263 ) 264 265 // Get uploadBlob field 266 let fields = schema.get_fields(mutation_build_result.mutation_type) 267 let upload_blob_field = 268 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 269 270 case upload_blob_field { 271 Ok(field) -> { 272 let return_type = schema.field_type(field) 273 // Check if it's non-null 274 schema.is_non_null(return_type) |> should.be_true() 275 276 // Check if inner type is BlobUploadResponse 277 case schema.inner_type(return_type) { 278 Some(inner) -> { 279 schema.type_name(inner) |> should.equal("BlobUploadResponse") 280 } 281 None -> should.be_true(False) 282 } 283 } 284 Error(_) -> should.be_true(False) 285 } 286} 287 288/// Test BlobUploadResponse type has ref field 289pub fn blob_upload_response_has_ref_field_test() { 290 let upload_factory = fn() { 291 fn(_ctx) { 292 Ok( 293 value.Object([ 294 #("ref", value.String("test")), 295 #("mime_type", value.String("test")), 296 #("size", value.Int(0)), 297 ]), 298 ) 299 } 300 } 301 302 let mutation_build_result = 303 mutation_builder.build_mutation_type( 304 [], 305 dict.new(), 306 None, 307 None, 308 None, 309 Some(upload_factory), 310 None, 311 None, 312 ) 313 314 // Get uploadBlob field 315 let fields = schema.get_fields(mutation_build_result.mutation_type) 316 let upload_blob_field = 317 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 318 319 case upload_blob_field { 320 Ok(field) -> { 321 let return_type = schema.field_type(field) 322 case schema.inner_type(return_type) { 323 Some(blob_response_type) -> { 324 let response_fields = schema.get_fields(blob_response_type) 325 let has_ref = 326 list.any(response_fields, fn(f) { schema.field_name(f) == "ref" }) 327 has_ref |> should.be_true() 328 } 329 None -> should.be_true(False) 330 } 331 } 332 Error(_) -> should.be_true(False) 333 } 334} 335 336/// Test BlobUploadResponse type has mimeType field 337pub fn blob_upload_response_has_mime_type_field_test() { 338 let upload_factory = fn() { 339 fn(_ctx) { 340 Ok( 341 value.Object([ 342 #("ref", value.String("test")), 343 #("mime_type", value.String("test")), 344 #("size", value.Int(0)), 345 ]), 346 ) 347 } 348 } 349 350 let mutation_build_result = 351 mutation_builder.build_mutation_type( 352 [], 353 dict.new(), 354 None, 355 None, 356 None, 357 Some(upload_factory), 358 None, 359 None, 360 ) 361 362 // Get uploadBlob field 363 let fields = schema.get_fields(mutation_build_result.mutation_type) 364 let upload_blob_field = 365 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 366 367 case upload_blob_field { 368 Ok(field) -> { 369 let return_type = schema.field_type(field) 370 case schema.inner_type(return_type) { 371 Some(blob_response_type) -> { 372 let response_fields = schema.get_fields(blob_response_type) 373 let has_mime_type = 374 list.any(response_fields, fn(f) { 375 schema.field_name(f) == "mimeType" 376 }) 377 has_mime_type |> should.be_true() 378 } 379 None -> should.be_true(False) 380 } 381 } 382 Error(_) -> should.be_true(False) 383 } 384} 385 386/// Test BlobUploadResponse type has size field 387pub fn blob_upload_response_has_size_field_test() { 388 let upload_factory = fn() { 389 fn(_ctx) { 390 Ok( 391 value.Object([ 392 #("ref", value.String("test")), 393 #("mime_type", value.String("test")), 394 #("size", value.Int(0)), 395 ]), 396 ) 397 } 398 } 399 400 let mutation_build_result = 401 mutation_builder.build_mutation_type( 402 [], 403 dict.new(), 404 None, 405 None, 406 None, 407 Some(upload_factory), 408 None, 409 None, 410 ) 411 412 // Get uploadBlob field 413 let fields = schema.get_fields(mutation_build_result.mutation_type) 414 let upload_blob_field = 415 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 416 417 case upload_blob_field { 418 Ok(field) -> { 419 let return_type = schema.field_type(field) 420 case schema.inner_type(return_type) { 421 Some(blob_response_type) -> { 422 let response_fields = schema.get_fields(blob_response_type) 423 let has_size = 424 list.any(response_fields, fn(f) { schema.field_name(f) == "size" }) 425 has_size |> should.be_true() 426 } 427 None -> should.be_true(False) 428 } 429 } 430 Error(_) -> should.be_true(False) 431 } 432} 433 434/// Test BlobUploadResponse has exactly 3 fields (no nested blob wrapper) 435pub fn blob_upload_response_has_three_fields_test() { 436 let upload_factory = fn() { 437 fn(_ctx) { 438 Ok( 439 value.Object([ 440 #("ref", value.String("test")), 441 #("mime_type", value.String("test")), 442 #("size", value.Int(0)), 443 ]), 444 ) 445 } 446 } 447 448 let mutation_build_result = 449 mutation_builder.build_mutation_type( 450 [], 451 dict.new(), 452 None, 453 None, 454 None, 455 Some(upload_factory), 456 None, 457 None, 458 ) 459 460 // Get uploadBlob field 461 let fields = schema.get_fields(mutation_build_result.mutation_type) 462 let upload_blob_field = 463 list.find(fields, fn(field) { schema.field_name(field) == "uploadBlob" }) 464 465 case upload_blob_field { 466 Ok(field) -> { 467 let return_type = schema.field_type(field) 468 case schema.inner_type(return_type) { 469 Some(blob_response_type) -> { 470 let response_fields = schema.get_fields(blob_response_type) 471 list.length(response_fields) |> should.equal(3) 472 } 473 None -> should.be_true(False) 474 } 475 } 476 Error(_) -> should.be_true(False) 477 } 478}