273 lines
7.1 KiB
Go
273 lines
7.1 KiB
Go
package unit
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"omega-server/local/graphql/handler"
|
|
"testing"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
func TestGraphQLHandler(t *testing.T) {
|
|
// Create a basic GraphQL handler without dependencies
|
|
graphqlHandler := handler.NewGraphQLHandler(nil)
|
|
|
|
// Create a Fiber app for testing
|
|
app := fiber.New(fiber.Config{
|
|
DisableStartupMessage: true,
|
|
})
|
|
|
|
// Set up routes
|
|
app.Post("/graphql", graphqlHandler.Handle)
|
|
app.Get("/graphql", func(c *fiber.Ctx) error {
|
|
return c.SendString(graphqlHandler.GetSchema())
|
|
})
|
|
|
|
t.Run("GetSchema", func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/graphql", nil)
|
|
resp, err := app.Test(req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to execute request: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
// Read response body
|
|
buf := new(bytes.Buffer)
|
|
buf.ReadFrom(resp.Body)
|
|
schema := buf.String()
|
|
|
|
if schema == "" {
|
|
t.Fatal("Expected non-empty schema")
|
|
}
|
|
|
|
// Check for basic GraphQL types
|
|
expectedTypes := []string{"type User", "type Project", "type Task", "type Query", "type Mutation"}
|
|
for _, expectedType := range expectedTypes {
|
|
if !contains(schema, expectedType) {
|
|
t.Errorf("Schema should contain '%s'", expectedType)
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("InvalidRequestBody", func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodPost, "/graphql", bytes.NewBufferString("invalid json"))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := app.Test(req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to execute request: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusBadRequest {
|
|
t.Errorf("Expected status 400, got %d", resp.StatusCode)
|
|
}
|
|
|
|
// Parse response
|
|
var response map[string]interface{}
|
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
|
t.Fatalf("Failed to decode response: %v", err)
|
|
}
|
|
|
|
// Should have errors
|
|
if errors, exists := response["errors"]; !exists {
|
|
t.Error("Expected errors in response")
|
|
} else {
|
|
errorList, ok := errors.([]interface{})
|
|
if !ok || len(errorList) == 0 {
|
|
t.Error("Expected non-empty error list")
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("MeQuery", func(t *testing.T) {
|
|
requestBody := map[string]interface{}{
|
|
"query": `
|
|
query Me {
|
|
me {
|
|
id
|
|
email
|
|
fullName
|
|
}
|
|
}
|
|
`,
|
|
}
|
|
|
|
body, _ := json.Marshal(requestBody)
|
|
req := httptest.NewRequest(http.MethodPost, "/graphql", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := app.Test(req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to execute request: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
// Parse response
|
|
var response map[string]interface{}
|
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
|
t.Fatalf("Failed to decode response: %v", err)
|
|
}
|
|
|
|
// Should have data
|
|
if data, exists := response["data"]; !exists {
|
|
t.Error("Expected data in response")
|
|
} else {
|
|
dataMap, ok := data.(map[string]interface{})
|
|
if !ok {
|
|
t.Error("Expected data to be an object")
|
|
} else {
|
|
if me, exists := dataMap["me"]; !exists {
|
|
t.Error("Expected 'me' field in data")
|
|
} else {
|
|
meMap, ok := me.(map[string]interface{})
|
|
if !ok {
|
|
t.Error("Expected 'me' to be an object")
|
|
} else {
|
|
// Check for required fields
|
|
if id, exists := meMap["id"]; !exists || id == "" {
|
|
t.Error("Expected non-empty 'id' field")
|
|
}
|
|
if email, exists := meMap["email"]; !exists || email == "" {
|
|
t.Error("Expected non-empty 'email' field")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("UnsupportedQuery", func(t *testing.T) {
|
|
requestBody := map[string]interface{}{
|
|
"query": `
|
|
query UnsupportedQuery {
|
|
unsupportedField {
|
|
id
|
|
name
|
|
}
|
|
}
|
|
`,
|
|
}
|
|
|
|
body, _ := json.Marshal(requestBody)
|
|
req := httptest.NewRequest(http.MethodPost, "/graphql", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := app.Test(req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to execute request: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusBadRequest {
|
|
t.Errorf("Expected status 400, got %d", resp.StatusCode)
|
|
}
|
|
|
|
// Parse response
|
|
var response map[string]interface{}
|
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
|
t.Fatalf("Failed to decode response: %v", err)
|
|
}
|
|
|
|
// Should have errors
|
|
if errors, exists := response["errors"]; !exists {
|
|
t.Error("Expected errors in response")
|
|
} else {
|
|
errorList, ok := errors.([]interface{})
|
|
if !ok || len(errorList) == 0 {
|
|
t.Error("Expected non-empty error list")
|
|
} else {
|
|
// Check error message
|
|
if errorMap, ok := errorList[0].(map[string]interface{}); ok {
|
|
if message, ok := errorMap["message"].(string); ok {
|
|
if message != "Query not supported" {
|
|
t.Errorf("Expected 'Query not supported', got '%s'", message)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("CreateProjectMutation", func(t *testing.T) {
|
|
requestBody := map[string]interface{}{
|
|
"query": `
|
|
mutation CreateProject($name: String!, $description: String, $ownerId: String!) {
|
|
createProject(input: {name: $name, description: $description, ownerId: $ownerId}) {
|
|
id
|
|
name
|
|
description
|
|
ownerId
|
|
}
|
|
}
|
|
`,
|
|
"variables": map[string]interface{}{
|
|
"name": "Test Project",
|
|
"description": "A test project",
|
|
"ownerId": "test-owner-id",
|
|
},
|
|
}
|
|
|
|
body, _ := json.Marshal(requestBody)
|
|
req := httptest.NewRequest(http.MethodPost, "/graphql", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := app.Test(req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to execute request: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
// Parse response
|
|
var response map[string]interface{}
|
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
|
t.Fatalf("Failed to decode response: %v", err)
|
|
}
|
|
|
|
// Should have data
|
|
if data, exists := response["data"]; !exists {
|
|
t.Error("Expected data in response")
|
|
} else {
|
|
dataMap, ok := data.(map[string]interface{})
|
|
if !ok {
|
|
t.Error("Expected data to be an object")
|
|
} else {
|
|
if createProject, exists := dataMap["createProject"]; !exists {
|
|
t.Error("Expected 'createProject' field in data")
|
|
} else {
|
|
projectMap, ok := createProject.(map[string]interface{})
|
|
if !ok {
|
|
t.Error("Expected 'createProject' to be an object")
|
|
} else {
|
|
// Check for required fields
|
|
if id, exists := projectMap["id"]; !exists || id == "" {
|
|
t.Error("Expected non-empty 'id' field")
|
|
}
|
|
if name, exists := projectMap["name"]; !exists || name != "Test Project" {
|
|
t.Errorf("Expected name 'Test Project', got '%v'", name)
|
|
}
|
|
if ownerId, exists := projectMap["ownerId"]; !exists || ownerId != "test-owner-id" {
|
|
t.Errorf("Expected ownerId 'test-owner-id', got '%v'", ownerId)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|