Skip to content

Add unit tests and add makefile #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,12 @@ go.sum
# OS generated files
.DS_Store

# builds
openmcpauthproxy

# test out files
coverage.out
coverage.html

# IDE files
.vscode
73 changes: 73 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Makefile for open-mcp-auth-proxy

# Variables
BINARY_NAME := openmcpauthproxy
GO := go
GOFMT := gofmt
GOVET := go vet
GOTEST := go test
GOLINT := golangci-lint
GOCOV := go tool cover
BUILD_DIR := build

# Source files
SRC := $(shell find . -name "*.go" -not -path "./vendor/*")
PKGS := $(shell go list ./... | grep -v /vendor/)

# Set build options
BUILD_OPTS := -v

# Set test options
TEST_OPTS := -v -race

.PHONY: all build clean test fmt lint vet coverage help

# Default target
all: lint test build

# Build the application
build:
@echo "Building $(BINARY_NAME)..."
@mkdir -p $(BUILD_DIR)
$(GO) build $(BUILD_OPTS) -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/proxy

# Clean build artifacts
clean:
@echo "Cleaning build artifacts..."
@rm -rf $(BUILD_DIR)
@rm -f coverage.out

# Run tests
test:
@echo "Running tests..."
$(GOTEST) $(TEST_OPTS) ./...

# Run tests with coverage report
coverage:
@echo "Running tests with coverage..."
@$(GOTEST) -coverprofile=coverage.out ./...
@$(GOCOV) -func=coverage.out
@$(GOCOV) -html=coverage.out -o coverage.html
@echo "Coverage report generated in coverage.html"

# Run gofmt
fmt:
@echo "Running gofmt..."
@$(GOFMT) -w -s $(SRC)

# Run go vet
vet:
@echo "Running go vet..."
@$(GOVET) ./...

# Show help
help:
@echo "Available targets:"
@echo " all : Run lint, test, and build"
@echo " build : Build the application"
@echo " clean : Clean build artifacts"
@echo " test : Run tests"
@echo " coverage : Run tests with coverage report"
@echo " fmt : Run gofmt"
@echo " vet : Run go vet"
@echo " help : Show this help message"
125 changes: 125 additions & 0 deletions internal/authz/default_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package authz

import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/wso2/open-mcp-auth-proxy/internal/config"
)

func TestNewDefaultProvider(t *testing.T) {
cfg := &config.Config{}
provider := NewDefaultProvider(cfg)

if provider == nil {
t.Fatal("Expected non-nil provider")
}

// Ensure it implements the Provider interface
var _ Provider = provider
}

func TestDefaultProviderWellKnownHandler(t *testing.T) {
// Create a config with a custom well-known response
cfg := &config.Config{
Default: config.DefaultConfig{
Path: map[string]config.PathConfig{
"/.well-known/oauth-authorization-server": {
Response: &config.ResponseConfig{
Issuer: "https://test-issuer.com",
JwksURI: "https://test-issuer.com/jwks",
ResponseTypesSupported: []string{"code"},
GrantTypesSupported: []string{"authorization_code"},
CodeChallengeMethodsSupported: []string{"S256"},
},
},
},
},
}

provider := NewDefaultProvider(cfg)
handler := provider.WellKnownHandler()

// Create a test request
req := httptest.NewRequest("GET", "/.well-known/oauth-authorization-server", nil)
req.Host = "test-host.com"
req.Header.Set("X-Forwarded-Proto", "https")

// Create a response recorder
w := httptest.NewRecorder()

// Call the handler
handler(w, req)

// Check response status
if w.Code != http.StatusOK {
t.Errorf("Expected status OK, got %v", w.Code)
}

// Verify content type
contentType := w.Header().Get("Content-Type")
if contentType != "application/json" {
t.Errorf("Expected Content-Type: application/json, got %s", contentType)
}

// Decode and check the response body
var response map[string]interface{}
if err := json.NewDecoder(w.Body).Decode(&response); err != nil {
t.Fatalf("Failed to decode response JSON: %v", err)
}

// Check expected values
if response["issuer"] != "https://test-issuer.com" {
t.Errorf("Expected issuer=https://test-issuer.com, got %v", response["issuer"])
}
if response["jwks_uri"] != "https://test-issuer.com/jwks" {
t.Errorf("Expected jwks_uri=https://test-issuer.com/jwks, got %v", response["jwks_uri"])
}
if response["authorization_endpoint"] != "https://test-host.com/authorize" {
t.Errorf("Expected authorization_endpoint=https://test-host.com/authorize, got %v", response["authorization_endpoint"])
}
}

func TestDefaultProviderHandleOPTIONS(t *testing.T) {
provider := NewDefaultProvider(&config.Config{})
handler := provider.WellKnownHandler()

// Create OPTIONS request
req := httptest.NewRequest("OPTIONS", "/.well-known/oauth-authorization-server", nil)
w := httptest.NewRecorder()

// Call the handler
handler(w, req)

// Check response
if w.Code != http.StatusNoContent {
t.Errorf("Expected status NoContent for OPTIONS request, got %v", w.Code)
}

// Check CORS headers
if w.Header().Get("Access-Control-Allow-Origin") != "*" {
t.Errorf("Expected Access-Control-Allow-Origin: *, got %s", w.Header().Get("Access-Control-Allow-Origin"))
}
if w.Header().Get("Access-Control-Allow-Methods") != "GET, OPTIONS" {
t.Errorf("Expected Access-Control-Allow-Methods: GET, OPTIONS, got %s", w.Header().Get("Access-Control-Allow-Methods"))
}
}

func TestDefaultProviderInvalidMethod(t *testing.T) {
provider := NewDefaultProvider(&config.Config{})
handler := provider.WellKnownHandler()

// Create POST request (which should be rejected)
req := httptest.NewRequest("POST", "/.well-known/oauth-authorization-server", nil)
w := httptest.NewRecorder()

// Call the handler
handler(w, req)

// Check response
if w.Code != http.StatusMethodNotAllowed {
t.Errorf("Expected status MethodNotAllowed for POST request, got %v", w.Code)
}
}
Loading
Loading