1
- import { HttpServer } from "@effect/platform"
1
+ import { HttpClient , HttpServer } from "@effect/platform"
2
+ import { Schema } from "@effect/schema"
2
3
import * as it from "@effect/vitest"
3
- import { Context , Effect , Either , Layer , Option , pipe , ReadonlyArray } from "effect"
4
- import { Api , ApiResponse , ClientError , RouterBuilder , ServerError } from "effect-http"
4
+ import { Context , Effect , Either , Encoding , Layer , Option , pipe , ReadonlyArray } from "effect"
5
+ import { Api , ApiResponse , ClientError , RouterBuilder , Security , ServerError } from "effect-http"
5
6
import { NodeTesting } from "effect-http-node"
6
7
import { createHash } from "node:crypto"
7
8
import { describe , expect , test } from "vitest"
@@ -286,7 +287,7 @@ it.scoped(
286
287
287
288
const result = yield * _ (
288
289
NodeTesting . make ( app , exampleApiOptional ) ,
289
- Effect . flatMap ( ( client ) => Effect . all ( ReadonlyArray . map ( params , client . hello ) ) )
290
+ Effect . flatMap ( ( client ) => Effect . all ( ReadonlyArray . map ( params , ( params ) => client . hello ( params ) ) ) )
290
291
)
291
292
292
293
expect ( result ) . toStrictEqual ( params )
@@ -309,7 +310,7 @@ it.scoped(
309
310
310
311
const result = yield * _ (
311
312
NodeTesting . make ( app , exampleApiOptionalParams ) ,
312
- Effect . flatMap ( ( client ) => Effect . all ( ReadonlyArray . map ( params , client . hello ) ) )
313
+ Effect . flatMap ( ( client ) => Effect . all ( ReadonlyArray . map ( params , ( params ) => client . hello ( params ) ) ) )
313
314
)
314
315
315
316
expect ( result ) . toStrictEqual ( params )
@@ -364,3 +365,113 @@ it.scoped(
364
365
expect ( result ) . toBe ( undefined )
365
366
} )
366
367
)
368
+
369
+ it . scoped (
370
+ "optional parameters" ,
371
+ Effect . gen ( function * ( _ ) {
372
+ const app = pipe (
373
+ RouterBuilder . make ( exampleApiOptionalParams ) ,
374
+ RouterBuilder . handle ( "hello" , ( { path } ) => Effect . succeed ( { path } ) ) ,
375
+ RouterBuilder . build
376
+ )
377
+
378
+ const params = [
379
+ { path : { value : 12 } } ,
380
+ { path : { value : 12 , another : "another" } }
381
+ ] as const
382
+
383
+ const result = yield * _ (
384
+ NodeTesting . make ( app , exampleApiOptionalParams ) ,
385
+ Effect . flatMap ( ( client ) => Effect . all ( ReadonlyArray . map ( params , ( params ) => client . hello ( params ) ) ) )
386
+ )
387
+
388
+ expect ( result ) . toStrictEqual ( params )
389
+ } )
390
+ )
391
+
392
+ it . scoped (
393
+ "single full response" ,
394
+ Effect . gen ( function * ( _ ) {
395
+ const app = pipe (
396
+ RouterBuilder . make ( exampleApiFullResponse ) ,
397
+ RouterBuilder . handle ( "hello" , ( ) =>
398
+ Effect . succeed ( {
399
+ body : 12 ,
400
+ headers : { "my-header" : "test" } ,
401
+ status : 200 as const
402
+ } ) ) ,
403
+ RouterBuilder . handle ( "another" , ( ) => Effect . succeed ( 12 ) ) ,
404
+ RouterBuilder . build
405
+ )
406
+
407
+ const result = yield * _ (
408
+ NodeTesting . make ( app , exampleApiFullResponse ) ,
409
+ Effect . flatMap ( ( client ) => Effect . all ( [ client . hello ( { } ) , client . another ( { } ) ] ) )
410
+ )
411
+
412
+ expect ( result ) . toMatchObject ( [
413
+ {
414
+ status : 200 ,
415
+ body : 12 ,
416
+ headers : { "my-header" : "test" }
417
+ } ,
418
+ 12
419
+ ] )
420
+ } )
421
+ )
422
+
423
+ it . scoped (
424
+ "empty response" ,
425
+ Effect . gen ( function * ( _ ) {
426
+ const app = pipe (
427
+ RouterBuilder . make ( exampleApiEmptyResponse ) ,
428
+ RouterBuilder . handle ( "test" , ( ) => Effect . unit ) ,
429
+ RouterBuilder . build
430
+ )
431
+
432
+ const result = yield * _ (
433
+ NodeTesting . make ( app , exampleApiEmptyResponse ) ,
434
+ Effect . flatMap ( ( client ) => client . test ( { body : "test" } ) )
435
+ )
436
+
437
+ expect ( result ) . toBe ( undefined )
438
+ } )
439
+ )
440
+
441
+ it . scoped (
442
+ "complex security example" ,
443
+ Effect . gen ( function * ( _ ) {
444
+ class MyService extends Effect . Tag ( "MyService" ) < MyService , { value : string } > ( ) {
445
+ static live = Layer . succeed ( MyService , { value : "hello" } )
446
+ }
447
+
448
+ const security = pipe (
449
+ Security . basic ( ) ,
450
+ Security . mapEffect ( ( creds ) => MyService . value . pipe ( Effect . map ( ( value ) => `${ value } -${ creds . user } -${ creds . pass } ` ) ) )
451
+ )
452
+
453
+ const api = Api . make ( ) . pipe (
454
+ Api . addEndpoint (
455
+ Api . post ( "test" , "/test" ) . pipe ( Api . setResponseBody ( Schema . string ) , Api . setSecurity ( security ) )
456
+ )
457
+ )
458
+
459
+ const app = pipe (
460
+ RouterBuilder . make ( api ) ,
461
+ RouterBuilder . handle ( "test" , ( _ , security ) => Effect . succeed ( security ) ) ,
462
+ RouterBuilder . build
463
+ )
464
+
465
+ const credentials = Encoding . encodeBase64 ( "user:pass" )
466
+
467
+ const result = yield * _ (
468
+ NodeTesting . make ( app , api ) ,
469
+ Effect . flatMap ( ( client ) =>
470
+ client . test ( { } , HttpClient . request . setHeader ( "authorization" , `basic ${ credentials } ` ) )
471
+ ) ,
472
+ Effect . provide ( MyService . live )
473
+ )
474
+
475
+ expect ( result ) . toBe ( "hello-user-pass" )
476
+ } )
477
+ )
0 commit comments