@@ -686,3 +686,110 @@ func TestSignerKeySet(t *testing.T) {
686686 })
687687 }
688688}
689+
690+ func TestRedirectedAuthErrHandler (t * testing.T ) {
691+ tests := []struct {
692+ name string
693+ redirectURI string
694+ state string
695+ errType string
696+ description string
697+ wantStatus int
698+ wantErr bool
699+ }{
700+ {
701+ name : "valid redirect uri with error parameters" ,
702+ redirectURI : "https://example.com/callback" ,
703+ state : "state123" ,
704+ errType : errInvalidRequest ,
705+ description : "Invalid request parameter" ,
706+ wantStatus : http .StatusSeeOther ,
707+ wantErr : false ,
708+ },
709+ {
710+ name : "valid redirect uri with query params" ,
711+ redirectURI : "https://example.com/callback?existing=param&another=value" ,
712+ state : "state456" ,
713+ errType : errAccessDenied ,
714+ description : "User denied access" ,
715+ wantStatus : http .StatusSeeOther ,
716+ wantErr : false ,
717+ },
718+ {
719+ name : "valid redirect uri without description" ,
720+ redirectURI : "https://example.com/callback" ,
721+ state : "state789" ,
722+ errType : errServerError ,
723+ description : "" ,
724+ wantStatus : http .StatusSeeOther ,
725+ wantErr : false ,
726+ },
727+ {
728+ name : "invalid redirect uri" ,
729+ redirectURI : "not a valid url ://" ,
730+ state : "state" ,
731+ errType : errInvalidRequest ,
732+ description : "Test error" ,
733+ wantStatus : http .StatusBadRequest ,
734+ wantErr : true ,
735+ },
736+ }
737+
738+ for _ , tc := range tests {
739+ tc := tc
740+ t .Run (tc .name , func (t * testing.T ) {
741+ err := & redirectedAuthErr {
742+ State : tc .state ,
743+ RedirectURI : tc .redirectURI ,
744+ Type : tc .errType ,
745+ Description : tc .description ,
746+ }
747+
748+ handler := err .Handler ()
749+ w := httptest .NewRecorder ()
750+ r := httptest .NewRequest ("GET" , "/" , nil )
751+
752+ handler .ServeHTTP (w , r )
753+
754+ if w .Code != tc .wantStatus {
755+ t .Errorf ("expected status %d, got %d" , tc .wantStatus , w .Code )
756+ }
757+
758+ if tc .wantStatus == http .StatusSeeOther {
759+ // Verify the redirect location is a valid URL
760+ location := w .Header ().Get ("Location" )
761+ if location == "" {
762+ t .Fatalf ("expected Location header, got empty string" )
763+ }
764+
765+ // Parse the redirect URL to verify it's valid
766+ redirectURL , parseErr := url .Parse (location )
767+ if parseErr != nil {
768+ t .Fatalf ("invalid redirect URL: %v" , parseErr )
769+ }
770+
771+ // Verify error parameters are present in the query string
772+ query := redirectURL .Query ()
773+ if query .Get ("state" ) != tc .state {
774+ t .Errorf ("expected state %q, got %q" , tc .state , query .Get ("state" ))
775+ }
776+ if query .Get ("error" ) != tc .errType {
777+ t .Errorf ("expected error type %q, got %q" , tc .errType , query .Get ("error" ))
778+ }
779+ if tc .description != "" && query .Get ("error_description" ) != tc .description {
780+ t .Errorf ("expected error_description %q, got %q" , tc .description , query .Get ("error_description" ))
781+ }
782+
783+ // Verify that existing query parameters are preserved
784+ if tc .name == "valid redirect uri with query params" {
785+ if query .Get ("existing" ) != "param" {
786+ t .Errorf ("expected existing parameter 'param', got %q" , query .Get ("existing" ))
787+ }
788+ if query .Get ("another" ) != "value" {
789+ t .Errorf ("expected another parameter 'value', got %q" , query .Get ("another" ))
790+ }
791+ }
792+ }
793+ })
794+ }
795+ }
0 commit comments