From 320ed3d6deb78a572243e43f581cd99d72234ce7 Mon Sep 17 00:00:00 2001 From: Joe Wolf Date: Tue, 13 Jun 2023 10:28:52 -0700 Subject: [PATCH] broken testing --- internal/authentication/authenticator.go | 2 +- internal/authentication/mock_authenticator.go | 40 +++ tests/api_test.go | 277 ++++++++++++------ tests/authentication_test.go | 220 +++++++++++--- 4 files changed, 421 insertions(+), 118 deletions(-) create mode 100644 internal/authentication/mock_authenticator.go diff --git a/internal/authentication/authenticator.go b/internal/authentication/authenticator.go index 45cbe98..fc9343f 100644 --- a/internal/authentication/authenticator.go +++ b/internal/authentication/authenticator.go @@ -12,7 +12,7 @@ import ( olError "github.com/onelogin/onelogin-go-sdk/internal/error" ) -const ( +var ( TokenPath string = "/auth/oauth2/v2/token" RevokePath string = "/auth/oauth2/revoke" ) diff --git a/internal/authentication/mock_authenticator.go b/internal/authentication/mock_authenticator.go new file mode 100644 index 0000000..0cd8afe --- /dev/null +++ b/internal/authentication/mock_authenticator.go @@ -0,0 +1,40 @@ +package authentication + +import ( + "errors" +) + +type MockAuthenticator struct { + GetTokenFunc func() (string, error) + NewAuthenticatorFunc func() Authenticator + GenerateTokenFunc func() error + RevokeTokenFunc func(token, domain *string) error +} + +func (a *MockAuthenticator) GetToken() (string, error) { + if a.GetTokenFunc != nil { + return a.GetTokenFunc() + } + return "", errors.New("GetTokenFunc is not implemented") +} + +func (a *MockAuthenticator) NewAuthenticatorF() Authenticator { + if a.NewAuthenticatorFunc != nil { + return a.NewAuthenticatorFunc() + } + return *NewAuthenticator() +} + +func (a *MockAuthenticator) GenerateToken() error { + if a.GenerateTokenFunc != nil { + return a.GenerateTokenFunc() + } + return errors.New("GenerateTokenFunc is not implemented") +} + +func (a *MockAuthenticator) RevokeToken(token, domain *string) error { + if a.RevokeTokenFunc != nil { + return a.RevokeTokenFunc(token, domain) + } + return errors.New("RevokeTokenFunc is not implemented") +} diff --git a/tests/api_test.go b/tests/api_test.go index e438d24..76f1e8f 100644 --- a/tests/api_test.go +++ b/tests/api_test.go @@ -1,116 +1,229 @@ package tests import ( - "bytes" "io/ioutil" "net/http" + "net/http/httptest" + "os" "testing" "github.com/onelogin/onelogin-go-sdk/internal/api" "github.com/onelogin/onelogin-go-sdk/internal/authentication" + "github.com/onelogin/onelogin-go-sdk/internal/models" ) -type MockDoType func(req *http.Request) (*http.Response, error) +// TestNewClient tests the NewClient function. +func TestNewClient(t *testing.T) { + // Set up environment variables + os.Setenv("ONELOGIN_SUBDOMAIN", "test") -type MockClient struct { - MockDo MockDoType + // Create a new client + client, err := api.NewClient() + if err != nil { + t.Errorf("Error creating client: %v", err) + return + } + + // Check that the client was created successfully + if client == nil { + t.Error("Client was not created") + return + } + + // Check that the client's Authenticator was created successfully + if client.Auth == nil { + t.Error("Authenticator was not created") + } } -func (m *MockClient) Do(req *http.Request) (*http.Response, error) { - return m.MockDo(req) +// TestGet tests the Get method. +func TestGet(t *testing.T) { + // Create a new client + client := &api.Client{ + HttpClient: http.DefaultClient, + Auth: authentication.NewAuthenticator(), + OLdomain: "https://test.onelogin.com", + } + + // Create a test server + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Write a response + w.WriteHeader(http.StatusOK) + w.Write([]byte("test")) + })) + defer ts.Close() + + // Send a test request + path := "/test" + queryParams := models.UserQuery{} + resp, err := client.Get(&path, &queryParams) + if err != nil { + t.Errorf("Error sending request: %v", err) + } + + // Check that the response was received successfully + if resp == nil { + t.Error("Response was not received") + } + + // Check that the response's body was read successfully + if resp == nil || resp.Body == nil { + t.Error("Response body is nil") + return + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Errorf("Error reading response body: %v", err) + } + if err != nil { + t.Errorf("Error reading response body: %v", err) + } + if string(body) != "test" { + t.Errorf("Response body was %s, expected test", string(body)) + } } -func TestNewRequest(t *testing.T) { - httpmock := MockClient{ - MockDo: func(req *http.Request) (*http.Response, error) { - resp := http.Response{ - StatusCode: 200, - Body: ioutil.NopCloser(bytes.NewBufferString(`OK`)), - } - return &resp, nil - }, +// TestDelete tests the Delete method. +func TestDelete(t *testing.T) { + // Create a new client + client := &api.Client{ + HttpClient: http.DefaultClient, + Auth: authentication.NewAuthenticator(), + OLdomain: "https://test.onelogin.com", } - authenticator := authentication.NewAuthenticator() + // Create a test server + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Write a response + w.WriteHeader(http.StatusOK) + w.Write([]byte("test")) + })) + defer ts.Close() + + // Send a test request + path := "/test" + resp, err := client.Delete(&path) + if err != nil { + t.Errorf("Error sending request: %v", err) + } - client := api.Client{ - HttpClient: &httpmock, - Auth: authenticator, - OLdomain: "http://localhost", + // Check that the response was received successfully + if resp == nil || resp.Body == nil { + t.Error("Response was not received") } - test := "/test" - resp, err := client.Get(&test, nil) + + // Check that the response's body was read successfully + body, err := ioutil.ReadAll(resp.Body) if err != nil { - t.Errorf("Expected no error, but got %v", err) + t.Errorf("Error reading response body: %v", err) } - if resp != nil && resp.StatusCode != http.StatusOK { - t.Errorf("Expected status code %d, but got %d", http.StatusOK, resp.StatusCode) + if string(body) != "test" { + t.Errorf("Response body was %s, expected test", string(body)) } } -func TestGet(t *testing.T) { - // Create a mock HTTP client - httpmock := MockClient{ - MockDo: func(req *http.Request) (*http.Response, error) { - // Modify the response based on the test case - if req.URL.Path == "/test" && req.Method == "GET" { - // Successful case - resp := http.Response{ - StatusCode: http.StatusOK, - Body: ioutil.NopCloser(bytes.NewBufferString(`OK`)), - } - return &resp, nil - } else if req.URL.Path == "/test" && req.Method == "POST" { - // Unsuccessful case - incorrect method - resp := http.Response{ - StatusCode: http.StatusMethodNotAllowed, - Body: ioutil.NopCloser(bytes.NewBufferString(`Method not allowed`)), - } - return &resp, nil - } else { - // Unsuccessful case - unexpected request - resp := http.Response{ - StatusCode: http.StatusNotFound, - Body: ioutil.NopCloser(bytes.NewBufferString(`Not found`)), - } - return &resp, nil - } - }, - } - - // Create an API client with the mock HTTP client - authenticator := authentication.NewAuthenticator() - client := api.Client{ - HttpClient: &httpmock, - Auth: authenticator, - OLdomain: "http://localhost", - } - - // Test successful GET request - test := "/test" - resp, err := client.Get(&test, nil) +// TestPost tests the Post method. +func TestPost(t *testing.T) { + // Create a new client + client := &api.Client{ + HttpClient: http.DefaultClient, + Auth: authentication.NewAuthenticator(), + OLdomain: "https://test.onelogin.com", + } + + // Create a test server + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Check that the request's body was read correctly + body, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("Error reading request body: %v", err) + } + if string(body) != "test" { + t.Errorf("Request body was %s, expected test", string(body)) + } + + // Write a response + w.WriteHeader(http.StatusOK) + w.Write([]byte("test")) + })) + defer ts.Close() + + // Send a test request + path := "/test" + body := "test" + resp, err := client.Post(&path, &body) + if err != nil { + t.Errorf("Error sending request: %v", err) + } + + // Check that the response was received successfully + if resp == nil || resp.Body == nil { + t.Error("Response was not received") + } + + // Check that the response's body was read successfully + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Errorf("Error reading response body: %v", err) + } + respBody := string(bodyBytes) if err != nil { - t.Errorf("Expected no error, but got %v", err) + t.Errorf("Error reading response body: %v", err) + } + if string(body) != "test" { + t.Errorf("Response body was %s, expected test", string(respBody)) + } +} + +// TestPut tests the Put method. +func TestPut(t *testing.T) { + // Create a new client + client := &api.Client{ + HttpClient: http.DefaultClient, + Auth: authentication.NewAuthenticator(), + OLdomain: "https://test.onelogin.com", } - if resp != nil && resp.StatusCode != http.StatusOK { - t.Errorf("Expected status code %d, but got %d", http.StatusOK, resp.StatusCode) + + // Create a test server + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Check that the request's body was read correctly + body, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("Error reading request body: %v", err) + } + if string(body) != "test" { + t.Errorf("Request body was %s, expected test", string(body)) + } + + // Write a response + w.WriteHeader(http.StatusOK) + w.Write([]byte("test")) + })) + defer ts.Close() + + // Send a test request + path := "/test" + body := "test" + resp, err := client.Put(&path, &body) + if err != nil { + t.Errorf("Error sending request: %v", err) } - // Test unsuccessful POST request - resp, err = client.Post(&test, nil) - if err == nil { - t.Error("Expected error, but got no error") + // Check that the response was received successfully + if resp == nil || resp.Body == nil { + t.Error("Response was not received") } - if resp != nil && resp.StatusCode != http.StatusMethodNotAllowed { - t.Errorf("Expected status code %d, but got %d", http.StatusMethodNotAllowed, resp.StatusCode) + + // Check that the response's body was read successfully + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Errorf("Error reading response body: %v", err) } - uhoh := "/unexpected" - // Test unsuccessful GET request with unexpected path - resp, err = client.Get(&uhoh, nil) - if err == nil { - t.Error("Expected error, but got no error") + respBody := string(bodyBytes) + if err != nil { + t.Errorf("Error reading response body: %v", err) } - if resp != nil && resp.StatusCode != http.StatusNotFound { - t.Errorf("Expected status code %d, but got %d", http.StatusNotFound, resp.StatusCode) + if string(body) != "test" { + t.Errorf("Response body was %s, expected test", string(respBody)) } } diff --git a/tests/authentication_test.go b/tests/authentication_test.go index 9a1ee39..0c108f7 100644 --- a/tests/authentication_test.go +++ b/tests/authentication_test.go @@ -1,63 +1,213 @@ package tests import ( - "encoding/json" + "errors" "net/http" "net/http/httptest" "os" "testing" "github.com/onelogin/onelogin-go-sdk/internal/authentication" + olError "github.com/onelogin/onelogin-go-sdk/internal/error" ) +func TestNewAuthenticator(t *testing.T) { + auth := authentication.NewAuthenticator() + if auth == nil { + t.Error("NewAuthenticator should not return nil") + } +} + func TestGenerateToken(t *testing.T) { - // Setup environment variables - os.Setenv("ONELOGIN_CLIENT_ID", "test-id") - os.Setenv("ONELOGIN_CLIENT_SECRET", "test-secret") - - // Create an HTTP test server - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - response := map[string]interface{}{ - "access_token": "test-token", - } + // Save the current environment variables + clientID := os.Getenv("ONELOGIN_CLIENT_ID") + clientSecret := os.Getenv("ONELOGIN_CLIENT_SECRET") + defer func() { + os.Setenv("ONELOGIN_CLIENT_ID", clientID) + os.Setenv("ONELOGIN_CLIENT_SECRET", clientSecret) + }() + + // Set the required environment variables + os.Setenv("ONELOGIN_CLIENT_ID", "test_client_id") + os.Setenv("ONELOGIN_CLIENT_SECRET", "test_client_secret") - json.NewEncoder(w).Encode(response) + // Create a test server to mock the authentication endpoint + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + t.Errorf("Expected POST request, got %s", r.Method) + } + if r.URL.Path != authentication.TokenPath { + t.Errorf("Expected path %s, got %s", authentication.TokenPath, r.URL.Path) + } + if r.Header.Get("Authorization") == "" { + t.Error("Authorization header is missing") + } + if r.Header.Get("Content-Type") != "application/json" { + t.Errorf("Expected Content-Type application/json, got %s", r.Header.Get("Content-Type")) + } + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"access_token": "test_access_token"}`)) })) - defer server.Close() + defer testServer.Close() - // Update the domain in the Authenticator - authenticator := authentication.NewAuthenticator() + // Set the authentication URL to the test server URL + authentication.TokenPath = testServer.URL + authentication.TokenPath - // Generate a token - token, err := authenticator.GetToken() + // Create a new authenticator and generate a token + auth := authentication.NewAuthenticator() + err := auth.GenerateToken() if err != nil { - t.Errorf("Expected no error, but got %v", err) + t.Errorf("Unexpected error: %s", err) } - if token != "test-token" { - t.Errorf("Expected token 'test-token', but got '%v'", token) + tk, err := auth.GetToken() + // Check that the access token was stored + if tk != "test_access_token" { + t.Errorf("Expected access token test_access_token, got %s", tk) } } -func TestRevokeToken(t *testing.T) { - // Setup environment variables - os.Setenv("ONELOGIN_CLIENT_ID", "test-id") - os.Setenv("ONELOGIN_CLIENT_SECRET", "test-secret") +func TestGenerateTokenMissingEnvVars(t *testing.T) { + // Save the current environment variables + clientID := os.Getenv("ONELOGIN_CLIENT_ID") + clientSecret := os.Getenv("ONELOGIN_CLIENT_SECRET") + defer func() { + os.Setenv("ONELOGIN_CLIENT_ID", clientID) + os.Setenv("ONELOGIN_CLIENT_SECRET", clientSecret) + }() - // Create an HTTP test server - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) + // Unset the required environment variables + os.Unsetenv("ONELOGIN_CLIENT_ID") + os.Unsetenv("ONELOGIN_CLIENT_SECRET") + + // Create a new authenticator and generate a token + auth := authentication.NewAuthenticator() + err := auth.GenerateToken() + + // Check that the error is of the correct type + var authErr *olError.AuthenticationError + if !errors.As(err, &authErr) { + t.Errorf("Expected error of type AuthenticationError, got %T", err) + } +} + +func TestGenerateTokenAuthenticationError(t *testing.T) { + // Save the current environment variables + clientID := os.Getenv("ONELOGIN_CLIENT_ID") + clientSecret := os.Getenv("ONELOGIN_CLIENT_SECRET") + defer func() { + os.Setenv("ONELOGIN_CLIENT_ID", clientID) + os.Setenv("ONELOGIN_CLIENT_SECRET", clientSecret) + }() + + // Set the required environment variables + os.Setenv("ONELOGIN_CLIENT_ID", "test_client_id") + os.Setenv("ONELOGIN_CLIENT_SECRET", "test_client_secret") + + // Create a test server to mock the authentication endpoint + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusUnauthorized) })) - defer server.Close() + defer testServer.Close() - // Update the domain in the Authenticator - authenticator := authentication.NewAuthenticator() + // Set the authentication URL to the test server URL + authentication.TokenPath = testServer.URL + authentication.TokenPath - // Revoke a token - domain := server.URL - token := "test-token" - err := authenticator.RevokeToken(&token, &domain) - if err != nil { - t.Errorf("Expected no error, but got %v", err) + // Create a new authenticator and generate a token + auth := authentication.NewAuthenticator() + err := auth.GenerateToken() + + // Check that the error is of the correct type + var authErr *olError.AuthenticationError + if !errors.As(err, &authErr) { + t.Errorf("Expected error of type AuthenticationError, got %T", err) + } +} + +func TestRevokeTokenMissingEnvVars(t *testing.T) { + // Save the current environment variables + clientID := os.Getenv("ONELOGIN_CLIENT_ID") + clientSecret := os.Getenv("ONELOGIN_CLIENT_SECRET") + defer func() { + os.Setenv("ONELOGIN_CLIENT_ID", clientID) + os.Setenv("ONELOGIN_CLIENT_SECRET", clientSecret) + }() + + // Unset the required environment variables + os.Unsetenv("ONELOGIN_CLIENT_ID") + os.Unsetenv("ONELOGIN_CLIENT_SECRET") + + // Create a new authenticator and try to revoke a token + auth := authentication.NewAuthenticator() + err := auth.RevokeToken(nil, nil) + + // Check that the error is of the correct type + if err == nil { + t.Error("Expected an error, got nil") + } +} + +func TestRevokeTokenRequestError(t *testing.T) { + // Save the current environment variables + clientID := os.Getenv("ONELOGIN_CLIENT_ID") + clientSecret := os.Getenv("ONELOGIN_CLIENT_SECRET") + defer func() { + os.Setenv("ONELOGIN_CLIENT_ID", clientID) + os.Setenv("ONELOGIN_CLIENT_SECRET", clientSecret) + }() + + // Set the required environment variables + os.Setenv("ONELOGIN_CLIENT_ID", "test_client_id") + os.Setenv("ONELOGIN_CLIENT_SECRET", "test_client_secret") + + // Create a test server that always returns an error + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + defer testServer.Close() + + // Set the revocation URL to the test server URL + authentication.RevokePath = testServer.URL + authentication.RevokePath + + // Create a new authenticator and try to revoke a token + auth := authentication.NewAuthenticator() + err := auth.RevokeToken(nil, nil) + + // Check that the error is of the correct type + if err == nil { + t.Error("Expected an error, got nil") + } +} + +func TestRevokeTokenAuthenticationError(t *testing.T) { + // Save the current environment variables + clientID := os.Getenv("ONELOGIN_CLIENT_ID") + clientSecret := os.Getenv("ONELOGIN_CLIENT_SECRET") + defer func() { + os.Setenv("ONELOGIN_CLIENT_ID", clientID) + os.Setenv("ONELOGIN_CLIENT_SECRET", clientSecret) + }() + + // Set the required environment variables + os.Setenv("ONELOGIN_CLIENT_ID", "test_client_id") + os.Setenv("ONELOGIN_CLIENT_SECRET", "test_client_secret") + + // Create a test server to mock the revocation endpoint + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusUnauthorized) + })) + defer testServer.Close() + + // Set the revocation URL to the test server URL + authentication.RevokePath = testServer.URL + authentication.RevokePath + + // Create a new authenticator and try to revoke a token + auth := authentication.NewAuthenticator() + err := auth.RevokeToken(nil, nil) + + // Check that the error is of the correct type + var authErr *olError.AuthenticationError + if !errors.As(err, &authErr) { + t.Errorf("Expected error of type AuthenticationError, got %T", err) } }