# Web Support

Mock web server for testing BoxLang web applications in CLI runtime. Simulates HTTP requests/responses without needing an actual web server.

## 📋 Table of Contents

* [📋 Table of Contents](#-table-of-contents)
* [⚠️ Warning](#️-warning)
* [📦 Installation](#-installation)
* [⚙️ Configuration](#️-configuration)
* [🚀 Quick Start](#-quick-start)
* [🔧 BIF Reference](#-bif-reference)
  * [mockServerGet()](#mockserverget)
  * [mockRequestNew()](#mockrequestnew)
  * [mockRequestRun()](#mockrequestrun)
* [💡 Examples](#-examples)
  * [Basic GET Request](#basic-get-request)
  * [POST with JSON](#post-with-json)
  * [Request with Authentication](#request-with-authentication)
  * [Form Submission](#form-submission)
* [🔗 Fluent API](#-fluent-api)
* [🧪 Testing Patterns](#-testing-patterns)
  * [Test Isolation](#test-isolation)
  * [Multiple Requests](#multiple-requests)
  * [Response Inspection](#response-inspection)
* [📚 Resources](#-resources)

## ⚠️ Warning

**DO NOT install this module into a BoxLang web-runtime!** This module is for CLI runtime testing or mocking only and will cause JAR conflicts in web server environments. Not needed for CommandBox or MiniServer.

## 📦 Installation

```bash
# OS Quick Installer
install-bx-module bx-web-support

# CommandBox
box install bx-web-support
```

## ⚙️ Configuration

Configure in your `ModuleConfig.bx`:

```js
settings = {
    port       : 8080,                          // Mock server port
    host       : "localhost",                   // Mock server host
    webRoot    : server.java.executionPath,    // Web root path
    secure     : false,                         // Enable HTTPS
    requestKey : "bxMockServer"                 // Request scope key
};
```

## 🚀 Quick Start

```js
// Get mock server
mockServer = mockServerGet()
    .setRequestMethod( "POST" )
    .setRequestPath( "/api/users" )
    .addRequestHeader( "Content-Type", "application/json" )
    .setRequestBody( '{"name": "John"}' );

// Use web-aware BIFs
httpData = getHTTPRequestData();
println( httpData.method ); // POST
```

## 🔧 BIF Reference

### mockServerGet()

Creates or retrieves cached mock server exchange.

**Arguments:**

* `webroot` (string) - Web root path
* `host` (string) - Server host (default: localhost)
* `port` (numeric) - Server port (default: 8080)
* `secure` (boolean) - Enable HTTPS (default: false)
* `force` (boolean) - Force new instance (default: false)

**Returns:** `MockHTTPExchange`

```js
// Get or create server
server = mockServerGet();

// Force new instance
server = mockServerGet( force: true );

// Custom configuration
server = mockServerGet( host: "example.com", port: 9090, secure: true );
```

### mockRequestNew()

Creates mock request builder for fluent configuration.

**Arguments:**

* `method` (string) - HTTP method (default: GET)
* `path` (string) - Request path (default: /)
* `body` (string) - Request body
* `contentType` (string) - Content type (default: text/html)
* `headers` (struct) - Request headers
* `urlScope` (struct) - URL parameters
* `formScope` (struct) - Form fields
* `cookieScope` (struct) - Cookies
* Plus: `webroot`, `host`, `port`, `secure`

**Returns:** `MockHTTPExchange` (builder pattern)

```js
// Builder pattern
mockRequestNew()
    .setRequestMethod( "POST" )
    .setRequestBodyJSON( { name: "John" } )
    .addRequestHeader( "Authorization", "Bearer token" )
    .execute();

// Inline configuration
mockRequestNew(
    method: "PUT",
    path: "/api/users/123",
    body: '{"name": "Jane"}',
    headers: { "Authorization": "Bearer token" }
).execute();
```

### mockRequestRun()

Executes full mock request with all-in-one configuration.

**Arguments:**

* **Request:** `path`, `method`, `pathInfo`, `queryString`, `contentType`, `body`, `urlScope`, `formScope`, `cookieScope`, `headers`
* **Response:** `responseStatus`, `responseContentType`, `responseBody`, `responseHeaders`
* **Server:** `webroot`, `host`, `port`, `secure`, `force`

**Returns:** `MockHTTPExchange` (executed)

```js
// Simple request
mockRequestRun( path: "/api/users", method: "GET" );

// Complex request
mockRequestRun(
    path: "/api/data",
    method: "POST",
    body: '{"key": "value"}',
    contentType: "application/json",
    headers: { "Authorization": "Bearer token" },
    responseStatus: 201,
    responseBody: '{"success": true}'
);
```

## 💡 Examples

### Basic GET Request

```js
mockRequestRun( path: "/api/users" );
httpData = getHTTPRequestData();
println( httpData.method ); // GET
```

### POST with JSON

```js
mockRequestNew(
    method: "POST",
    path: "/api/users",
    contentType: "application/json",
    body: '{"name": "John", "email": "john@example.com"}'
).execute();
```

### Request with Authentication

```js
mockServer = mockServerGet()
    .setRequestMethod( "GET" )
    .setRequestPath( "/api/protected" )
    .addRequestHeader( "Authorization", "Bearer xyz789" )
    .addRequestCookie( "sessionId", "sess-123" );
```

### Form Submission

```js
mockRequestRun(
    path: "/contact",
    method: "POST",
    formScope: {
        name: "Jane Doe",
        email: "jane@example.com",
        message: "Hello!"
    }
);
```

## 🔗 Fluent API

`MockHTTPExchange` provides fluent methods for request configuration:

**Request Configuration:**

* `setRequestMethod(method)` - Set HTTP method
* `setRequestPath(path)` - Set request path
* `setRequestBody(body)` - Set request body
* `setRequestBodyJSON(struct)` - Set JSON body (auto content-type)
* `setRequestBodyXML(string)` - Set XML body (auto content-type)
* `setRequestContentType(type)` - Set content type

**Headers & Parameters:**

* `addRequestHeader(name, value)` - Add single header
* `addRequestHeaders(struct)` - Add multiple headers
* `addURLParam(name, value)` - Add URL parameter
* `addURLParams(struct)` - Add multiple URL parameters
* `addFormField(name, value)` - Add form field
* `addFormFields(struct)` - Add multiple form fields
* `addRequestCookie(name, value)` - Add cookie

**Execution & Inspection:**

* `execute()` - Execute the request
* `getResponseBody()` - Get response body
* `getResponseStatus()` - Get status code
* `getMockRequestHeaders()` - Get request headers
* `getMockResponseHeaders()` - Get response headers
* `getMockForm()` - Get form scope
* `getMockURL()` - Get URL scope

**Test Utilities:**

* `clearRequestData()` - Reset request data
* `clearResponseData()` - Reset response data
* `clearAll()` - Reset everything

## 🧪 Testing Patterns

### Test Isolation

```js
// Reset between tests
mockServer = mockServerGet();
mockServer.clearAll();

// Or force new instance
mockServer = mockServerGet( force: true );
```

### Multiple Requests

```js
// Test different methods
mockRequestNew( method: "GET", path: "/api/users" ).execute();
mockRequestNew( method: "POST", path: "/api/users", body: "{}" ).execute();
mockRequestNew( method: "DELETE", path: "/api/users/123" ).execute();
```

### Response Inspection

```js
mockServer = mockRequestRun(
    path: "/api/test",
    method: "POST",
    body: '{"test": true}'
);

// Inspect
status = mockServer.getResponseStatus();
body = mockServer.getResponseBody();
headers = mockServer.getMockResponseHeaders();
```

## 📚 Resources

* [GitHub Repository](https://github.com/ortus-boxlang/bx-web-support)
* [Issue Tracker](https://ortussolutions.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=13359\&components=27030\&issuetype=1)
* [BoxLang Documentation](https://boxlang.io)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://boxlang.ortusbooks.com/boxlang-framework/modularity/web-support.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
