scriptable-testlab
Version:
A lightweight, efficient tool designed to manage and update scripts for Scriptable.
199 lines (171 loc) • 4.67 kB
text/typescript
import {AbsRequest} from 'scriptable-abstract';
import {MockData} from '../data';
interface RequestState {
url: string;
method: string;
headers: Record<string, string>;
body: string;
timeoutInterval: number;
allowInsecureRequest: boolean;
onRedirect: (request: Request) => Request;
response: {[key: string]: any};
}
const DEFAULT_STATE: RequestState = {
url: '',
method: 'GET',
headers: {},
body: '',
timeoutInterval: 60,
allowInsecureRequest: false,
onRedirect: (request: Request) => request,
response: {},
};
export class MockRequest extends AbsRequest<RequestState> {
constructor() {
super(DEFAULT_STATE);
}
get url(): string {
return this.state.url;
}
set url(value: string) {
if (value === null) {
throw new Error('URL cannot be null');
}
if (typeof value !== 'string') {
throw new Error('URL must be a string');
}
this.setState({url: value});
}
get method(): string {
return this.state.method;
}
set method(value: string) {
if (value === null) {
throw new Error('Method cannot be null');
}
const validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'PATCH'];
if (!validMethods.includes(value)) {
throw new Error('Invalid HTTP method');
}
this.setState({method: value});
}
get headers(): Record<string, string> {
return {...this.state.headers};
}
set headers(value: Record<string, string>) {
if (value === null) {
throw new Error('Headers cannot be null');
}
if (typeof value !== 'object') {
throw new Error('Headers must be an object');
}
this.setState({headers: {...value}});
}
get body(): string {
return this.state.body;
}
set body(value: string) {
if (value === null) {
throw new Error('Body cannot be null');
}
this.setState({body: value});
}
get timeoutInterval(): number {
return this.state.timeoutInterval;
}
set timeoutInterval(value: number) {
if (value < 0) {
throw new Error('Timeout must be non-negative');
}
if (Number.isNaN(value)) {
throw new Error('Timeout must be a valid number');
}
this.setState({timeoutInterval: value});
}
get allowInsecureRequest(): boolean {
return this.state.allowInsecureRequest;
}
set allowInsecureRequest(value: boolean) {
if (value === null) {
throw new Error('allowInsecureRequest must be a boolean');
}
this.setState({allowInsecureRequest: value});
}
get onRedirect(): (request: Request) => Request {
return this.state.onRedirect;
}
set onRedirect(value: (request: Request) => Request) {
this.setState({onRedirect: value});
}
get response(): {[key: string]: any} {
return this.state.response;
}
addHeaderField(name: string, value: string): void {
if (name === null) {
throw new Error('Header name cannot be null');
}
if (name === '') {
throw new Error('Header name cannot be empty');
}
if (value === null) {
throw new Error('Header value cannot be null');
}
const headers = new Map(Object.entries(this.state.headers));
headers.set(name, value);
this.setState({
headers: Object.fromEntries(headers),
});
}
async load(): Promise<Data> {
if (!this.url || this.url === 'invalid-url') {
throw new Error('Invalid URL');
}
// Mock implementation for redirect
if (this.url.includes('redirect.example.com')) {
const redirectRequest = new MockRequest();
redirectRequest.url = 'https://example.com/redirected';
return this.onRedirect(redirectRequest as unknown as Request) as unknown as Data;
}
// Mock implementation for error
if (this.url.includes('/error')) {
throw new Error('Server error');
}
// Default mock implementation
this.setState({
response: {
statusCode: 200,
headers: {
'Content-Type': 'text/plain',
},
},
});
return MockData.fromString('') as unknown as Data;
}
async loadString(): Promise<string> {
// Mock implementation - returns empty string
this.setState({
response: {
statusCode: 200,
headers: {
'Content-Type': 'text/plain',
},
},
});
return '';
}
async loadJSON(): Promise<any> {
// Mock implementation - returns empty object
this.setState({
response: {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
},
},
});
return {};
}
async loadImage(): Promise<Image> {
throw new Error('Not implemented');
}
}