@@ -19,12 +19,13 @@ package ffapi
19
19
import (
20
20
"context"
21
21
"fmt"
22
- "github.com/getkin/kin-openapi/openapi3"
23
22
"io"
24
23
"net/http"
25
24
"strings"
26
25
"testing"
27
26
27
+ "github.com/getkin/kin-openapi/openapi3"
28
+
28
29
"github.com/go-resty/resty/v2"
29
30
"github.com/hyperledger/firefly-common/pkg/config"
30
31
"github.com/hyperledger/firefly-common/pkg/httpserver"
@@ -428,3 +429,208 @@ func TestBadMetrics(t *testing.T) {
428
429
as .MetricsRegistry = metric .NewPrometheusMetricsRegistry ("wrong" )
429
430
assert .Panics (t , func () { as .createMonitoringMuxRouter (context .Background ()) })
430
431
}
432
+
433
+ func newTestVersionedAPIServer (t * testing.T , versionedAPIs * VersionedAPIs ) (* utManager , * apiServer [* utManager ], func ()) {
434
+ ctx , cancelCtx := context .WithCancel (context .Background ())
435
+ apiConfig , monitoringConfig , corsConfig := initUTConfig ()
436
+ um := & utManager {t : t }
437
+ as := NewAPIServer (ctx , APIServerOptions [* utManager ]{
438
+ MetricsRegistry : metric .NewPrometheusMetricsRegistry ("ut" ),
439
+ VersionedAPIs : versionedAPIs ,
440
+ EnrichRequest : func (r * APIRequest ) (* utManager , error ) {
441
+ // This could be some dynamic object based on extra processing in the request,
442
+ // but the most common case is you just have a "manager" that you inject into each
443
+ // request and that's the "T" on the APIServer
444
+ return um , um .mockEnrichErr
445
+ },
446
+ Description : "unit testing" ,
447
+ APIConfig : apiConfig ,
448
+ MonitoringConfig : monitoringConfig ,
449
+ CORSConfig : corsConfig ,
450
+ MetricsSubsystemName : "apiserver_ut" ,
451
+ })
452
+ done := make (chan struct {})
453
+
454
+ go func () {
455
+ err := as .Serve (ctx )
456
+ assert .NoError (t , err )
457
+ close (done )
458
+ }()
459
+ return um , as .(* apiServer [* utManager ]), func () {
460
+ cancelCtx ()
461
+ <- done
462
+ }
463
+ }
464
+
465
+ func TestVersionedAPIsWithASingleVersion (t * testing.T ) {
466
+ um , as , done := newTestVersionedAPIServer (t , & VersionedAPIs {
467
+ APIVersions : map [string ]* APIVersion {
468
+ "v2" : {
469
+ Routes : []* Route {utAPIRoute2 },
470
+ },
471
+ },
472
+ })
473
+ defer done ()
474
+
475
+ <- as .Started ()
476
+
477
+ var o sampleOutput
478
+
479
+ // check v2 API only supports the getit route
480
+ res , err := resty .New ().R ().
481
+ SetBody (nil ).
482
+ SetResult (& o ).
483
+ Get (fmt .Sprintf ("%s/api/v2/ut/utresource/id12345/getit" , as .APIPublicURL ()))
484
+ assert .NoError (t , err )
485
+ assert .Equal (t , 200 , res .StatusCode ())
486
+ assert .Equal (t , "application/octet-stream" , res .Header ().Get ("Content-Type" ))
487
+ assert .Equal (t , "id12345" , um .calledStreamHandler )
488
+ assert .Equal (t , "a stream!" , string (res .Body ()))
489
+ }
490
+
491
+ func TestAPIsWithMultipleVersions (t * testing.T ) {
492
+ um , as , done := newTestVersionedAPIServer (t , & VersionedAPIs {
493
+ DefaultVersion : "v2" ,
494
+ APIVersions : map [string ]* APIVersion {
495
+ "v1" : {
496
+ Routes : []* Route {utAPIRoute1 , utAPIRoute2 },
497
+ },
498
+ "v2" : {
499
+ Routes : []* Route {utAPIRoute2 }, // v2 only supports the getit route
500
+ },
501
+ },
502
+ })
503
+ defer done ()
504
+
505
+ <- as .Started ()
506
+
507
+ var o sampleOutput
508
+
509
+ // check v1 API supports both routes
510
+ res , err := resty .New ().R ().
511
+ SetBody (nil ).
512
+ SetResult (& o ).
513
+ Get (fmt .Sprintf ("%s/api/v1/ut/utresource/id12345/getit" , as .APIPublicURL ()))
514
+ assert .NoError (t , err )
515
+ assert .Equal (t , 200 , res .StatusCode ())
516
+ assert .Equal (t , "application/octet-stream" , res .Header ().Get ("Content-Type" ))
517
+ assert .Equal (t , "id12345" , um .calledStreamHandler )
518
+ assert .Equal (t , "a stream!" , string (res .Body ()))
519
+
520
+ res , err = resty .New ().R ().
521
+ SetBody (& sampleInput {
522
+ Input1 : "test_json_input" ,
523
+ }).
524
+ SetResult (& o ).
525
+ Post (fmt .Sprintf ("%s/api/v1/ut/utresource/id12345/postit" , as .APIPublicURL ()))
526
+ assert .NoError (t , err )
527
+ assert .Equal (t , 200 , res .StatusCode ())
528
+ assert .Equal (t , "id12345" , um .calledJSONHandler )
529
+ assert .Equal (t , "test_json_output" , o .Output1 )
530
+
531
+ // check v2 API only supports the getit route
532
+ res , err = resty .New ().R ().
533
+ SetBody (nil ).
534
+ SetResult (& o ).
535
+ Get (fmt .Sprintf ("%s/api/v2/ut/utresource/id12345/getit" , as .APIPublicURL ()))
536
+ assert .NoError (t , err )
537
+ assert .Equal (t , 200 , res .StatusCode ())
538
+ assert .Equal (t , "application/octet-stream" , res .Header ().Get ("Content-Type" ))
539
+ assert .Equal (t , "id12345" , um .calledStreamHandler )
540
+ assert .Equal (t , "a stream!" , string (res .Body ()))
541
+
542
+ res , err = resty .New ().R ().
543
+ SetBody (& sampleInput {
544
+ Input1 : "test_json_input" ,
545
+ }).
546
+ SetResult (& o ).
547
+ Post (fmt .Sprintf ("%s/api/v2/ut/utresource/id12345/postit" , as .APIPublicURL ()))
548
+ assert .NoError (t , err )
549
+ assert .Equal (t , 404 , res .StatusCode ())
550
+ }
551
+
552
+ func TestVersionedAPIInitErrors (t * testing.T ) {
553
+ ctx := context .Background ()
554
+ apiConfig , monitoringConfig , _ := initUTConfig ()
555
+ as := NewAPIServer (ctx , APIServerOptions [* utManager ]{
556
+ MetricsRegistry : metric .NewPrometheusMetricsRegistry ("ut" ),
557
+ Routes : []* Route {utAPIRoute1 , utAPIRoute2 },
558
+ VersionedAPIs : & VersionedAPIs {
559
+ DefaultVersion : "v2" ,
560
+ APIVersions : map [string ]* APIVersion {
561
+ "v1" : {
562
+ Routes : []* Route {utAPIRoute1 , utAPIRoute2 },
563
+ },
564
+ "v2" : {
565
+ Routes : []* Route {utAPIRoute2 }, // v2 only supports the getit route
566
+ },
567
+ },
568
+ },
569
+ Description : "unit testing" ,
570
+ APIConfig : apiConfig ,
571
+ MonitoringConfig : monitoringConfig ,
572
+ })
573
+
574
+ err := as .Serve (ctx )
575
+ assert .Error (t , err )
576
+ assert .Regexp (t , "FF00251" , err )
577
+
578
+ as = NewAPIServer (ctx , APIServerOptions [* utManager ]{
579
+ MetricsRegistry : metric .NewPrometheusMetricsRegistry ("ut" ),
580
+ VersionedAPIs : & VersionedAPIs {
581
+ DefaultVersion : "" ,
582
+ APIVersions : map [string ]* APIVersion {},
583
+ },
584
+ Description : "unit testing" ,
585
+ APIConfig : apiConfig ,
586
+ MonitoringConfig : monitoringConfig ,
587
+ })
588
+
589
+ err = as .Serve (ctx )
590
+ assert .Error (t , err )
591
+ assert .Regexp (t , "FF00252" , err )
592
+
593
+ as = NewAPIServer (ctx , APIServerOptions [* utManager ]{
594
+ MetricsRegistry : metric .NewPrometheusMetricsRegistry ("ut" ),
595
+ VersionedAPIs : & VersionedAPIs {
596
+ DefaultVersion : "" ,
597
+ APIVersions : map [string ]* APIVersion {
598
+ "v1" : {
599
+ Routes : []* Route {utAPIRoute1 , utAPIRoute2 },
600
+ },
601
+ "v2" : {
602
+ Routes : []* Route {utAPIRoute2 }, // v2 only supports the getit route
603
+ },
604
+ },
605
+ },
606
+ Description : "unit testing" ,
607
+ APIConfig : apiConfig ,
608
+ MonitoringConfig : monitoringConfig ,
609
+ })
610
+
611
+ err = as .Serve (ctx )
612
+ assert .Error (t , err )
613
+ assert .Regexp (t , "FF00253" , err )
614
+ as = NewAPIServer (ctx , APIServerOptions [* utManager ]{
615
+ MetricsRegistry : metric .NewPrometheusMetricsRegistry ("ut" ),
616
+ VersionedAPIs : & VersionedAPIs {
617
+ DefaultVersion : "unknown" ,
618
+ APIVersions : map [string ]* APIVersion {
619
+ "v1" : {
620
+ Routes : []* Route {utAPIRoute1 , utAPIRoute2 },
621
+ },
622
+ "v2" : {
623
+ Routes : []* Route {utAPIRoute2 }, // v2 only supports the getit route
624
+ },
625
+ },
626
+ },
627
+ Description : "unit testing" ,
628
+ APIConfig : apiConfig ,
629
+ MonitoringConfig : monitoringConfig ,
630
+ })
631
+
632
+ err = as .Serve (ctx )
633
+ assert .Error (t , err )
634
+ assert .Regexp (t , "FF00254" , err )
635
+
636
+ }
0 commit comments