Commit 9a86595

mo khan <mo@mokhan.ca>
2025-03-10 20:54:11
test: add e2e spec for OIDC login
1 parent ef02c04
Changed files (4)
bin/idp
@@ -234,7 +234,7 @@ class IdentityProvider
         <head><title></title></head>
         <body>
           <h2>Authorize?</h2>
-          <form action="/oauth/authorize" method="post">
+          <form id="authorize-form" action="/oauth/authorize" method="post">
             <input type="hidden" name="client_id" value="<%= request.params['client_id'] %>" />
             <input type="hidden" name="scope" value="<%= request.params['scope'] %>" />
             <input type="hidden" name="redirect_uri" value="<%= request.params['redirect_uri'] %>" />
@@ -243,7 +243,7 @@ class IdentityProvider
             <input type="hidden" name="state" value="<%= request.params['state'] %>" />
             <input type="hidden" name="code_challenge_method" value="<%= request.params['code_challenge_method'] %>" />
             <input type="hidden" name="code_challenge" value="<%= request.params['code_challenge'] %>" />
-            <input type="submit" value="Submit" />
+            <input id="submit-button" type="submit" value="Submit" />
           </form>
         </body>
       </html>
test/e2e_test.go
@@ -2,14 +2,23 @@ package main
 
 import (
 	"net/http"
+	"strings"
 	"testing"
 
 	"github.com/playwright-community/playwright-go"
 	"github.com/stretchr/testify/assert"
 	"github.com/xlgmokha/x/pkg/env"
+	"github.com/xlgmokha/x/pkg/serde"
 	"github.com/xlgmokha/x/pkg/x"
 )
 
+type OAuthTokens struct {
+	AccessToken  string `json:"access_token"`
+	TokenType    string `json:"token_type"`
+	ExpiresIn    uint64 `json:"expires_in"`
+	RefreshToken string `json:"refresh_token"`
+}
+
 func TestHelloWorld(t *testing.T) {
 	_ = playwright.Install()
 
@@ -52,4 +61,21 @@ func TestHelloWorld(t *testing.T) {
 			})
 		})
 	})
+
+	t.Run("OIDC", func(t *testing.T) {
+		t.Run("Performs an OIDC login", func(t *testing.T) {
+			x.Must(page.Goto("http://ui.example.com:8080/oidc/new"))
+			assert.Contains(t, page.URL(), "http://idp.example.com:8080/oauth/authorize")
+			assert.NoError(t, page.Locator("#submit-button").Click())
+
+			assert.Contains(t, page.URL(), "http://ui.example.com:8080/oauth/callback")
+			content := x.Must(page.Locator("pre").First().InnerText())
+			item := x.Must(serde.FromJSON[OAuthTokens](strings.NewReader(content)))
+			assert.NotEmpty(t, item.AccessToken)
+			assert.Equal(t, "Bearer", item.TokenType)
+			assert.NotEmpty(t, item.RefreshToken)
+			// header = { 'Authorization' => "Bearer #{token}" }
+			// http.Get("http://api.example.com:8080/projects.json")
+		})
+	})
 }
go.mod
@@ -19,10 +19,12 @@ require (
 	github.com/go-jose/go-jose/v3 v3.0.4 // indirect
 	github.com/go-stack/stack v1.8.1 // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/google/jsonapi v1.0.0 // indirect
 	github.com/kr/text v0.2.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
 
go.sum
@@ -24,6 +24,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/jsonapi v1.0.0 h1:qIGgO5Smu3yJmSs+QlvhQnrscdZfFhiV6S8ryJAglqU=
+github.com/google/jsonapi v1.0.0/go.mod h1:YYHiRPJT8ARXGER8In9VuLv4qvLfDmA9ULQqptbLE4s=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -94,6 +96,8 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=