/// <reference types="node" />
import { UpdatePolicy, HttpHeaders, HttpRequestMethod } from '../../../utils';
import { Page, Request } from 'playwright';
export declare type ResponseData = Record<string, unknown> | Record<string, never> | string | undefined | unknown;
export declare type PostData = Record<string, unknown> | string | undefined | null | unknown;
export declare type QueryString = Record<string, string>;
export interface RequestInfos {
    request: Request;
    queryString: QueryString;
    postData: PostData;
    sharedContext: unknown;
}
/**
 * Be able to intercept a given http request url and provide a mocked response.
 * The mock will be selected only if all provided matchers return true.
 * When a matcher is not provided, it always default to true.
 * When multiple mocks are selected, the last one is taken (like in CSS):
 *  this enables you to override existing mocks on specific conditions.
 * @export
 * @interface FluentMock
 */
export interface FluentMock {
    /**
     * Mock friendly name. Useful when you are debugging your mocks.
     * By default it will be set to 'not set' if you forgot to give your mock a name.
     * @type {string}
     * @memberof FluentMock
     */
    displayName: string;
    /**
     * Predicate acting on the http request url.
     * If you return true for the input url, then the request will be mocked accordingly to the responseType.
     * If you return false, the the request will never be mocked and other matchers will never be called.
     * @memberof FluentMock
     */
    urlMatcher: (url: string) => boolean;
    /**
     * Optional predicate acting on the http request method.
     * This predicate will be called only if the predicate urlMatcher returns true.
     * If you do not set a methodMatcher, a default one that always returns true is provided.
     * @memberof FluentMock
     */
    methodMatcher: (method: HttpRequestMethod) => boolean;
    /**
     * Optional predicate acting on the query string.
     * This predicate will be called only if the predicate urlMatcher returns true.
     * If you do not set a queryStringMatcher, a default one that always returns true is provided.
     *
     * @memberof FluentMock
     */
    queryStringMatcher: (queryString: QueryString) => boolean;
    /**
     * Optional predicate acting on the post data sent by the http request.
     * This predicate will be called only if the predicate urlMatcher returns true.
     * If you do not set a postDataMatcher, a default one that always returns true is provided.
     *
     * @memberof FluentMock
     */
    postDataMatcher: (postData: PostData) => boolean;
    /**
     * Optional predicate acting on the shared context.
     * This predicate will be called only if all predicates {@link urlMatcher}, {@link queryStringMatcher}, {@link postDataMatcher}, returns true.
     * If you do not set a contextMatcher, a default one that always returns true is provided.
     * A mock can update the shared context on any method passing a {@link RequestInfos} object.
     * A context matcher should be used when the mock response depends on the requests history,
     * for example when the mock must respond only to the nth request given by the urlMatcher.
     *
     * @memberof FluentMock
     */
    contextMatcher: (context: unknown) => boolean;
    /**
     * Optional predicate acting on custom conditions from the request and/or the query string and/or the post data and/or the shared context.
     * This predicate will be called only if the predicate urlMatcher returns true.
     * If you do not set a customMatcher, a default one that always returns true is provided.
     *
     * @memberof FluentMock
     */
    customMatcher: (requestInfos: RequestInfos) => boolean;
    /**
     * Add or modify the headers that will be sent with the mocked response.
     *
     * @memberof FluentMock
     */
    enrichResponseHeaders: (headers: HttpHeaders) => HttpHeaders;
    /**
     * Define the response type of the mocked request.
     * If you do not set a responseType, a default one will be infered from the provided jsonResponse or rawResponse.
     *
     * @type {('json' | 'string' | 'javascript' | 'empty' | 'continue')}
     * @memberof FluentMock
     */
    responseType: 'json' | 'string' | 'javascript' | 'empty' | 'continue';
    /**
     * Http response status. Can be a function that returns a number.
     * defaults to 200.
     *
     * @memberof FluentMock
     */
    status: number | ((requestInfos: RequestInfos) => number);
    /**
     * Build your own json response.
     * This method will be called only if responseType is 'json'.
     * @memberof FluentMock
     */
    jsonResponse: (requestInfos: RequestInfos) => ResponseData;
    /**
     * Build your own string response.
     * This method will be called only if responseType is 'string' or 'javascript'.
     *
     * @memberof FluentMock
     */
    rawResponse: (requestInfos: RequestInfos) => string;
    /**
     * Delay the response by the given number of milliseconds.
     * Defaults to 0.
     *
     * @type {number}
     * @memberof FluentMock
     */
    delayInMilliseconds: number;
    /**
     * Optional callback to update the data source of the mocked response.
     * When provided, this method will be called automatically when
     *  1°) the mock is found to be outdated by the helper {@link getOutdatedMocks})
     *  2°) and the call to {@link lastUpdated} gives a date that is older than the {@link updatePolicy}
     * @memberof FluentMock
     */
    updateData: (requestInfos: RequestInfos, response: ResponseData) => void;
    /**
     * Optional callback to get the last update of the data source used to mock the response.
     * This method will be called automatically when the mock is found to be outdated by the helper {@link getOutdatedMocks})
     * Defaults to the current date.
     *
     * @type {Date}
     * @memberof FluentMock
     */
    lastUpdated: () => Date;
    /**
     * Update policy for the data source of the mocked response.
     * Defaults to 'always'.
     *
     * @type {UpdatePolicy}
     * @memberof FluentMock
     */
    updatePolicy: UpdatePolicy;
}
export declare function noopVoidFunc(): void;
export declare function getPostDataOf(request: Request): PostData;
export declare const passthroughMock: FluentMock;
export interface WithMocksOptions {
    onMockFound: (mock: Partial<FluentMock>, requestInfos: RequestInfos) => void;
    onMockNotFound: (requestInfos: RequestInfos) => void;
    onInternalError: (error: Error, mock: Partial<FluentMock>, requestInfos: RequestInfos) => void;
}
export declare const defaultMocksOptions: WithMocksOptions;
export declare function getMockStatus(mock: Partial<FluentMock>, requestInfos: RequestInfos): number;
export declare function inferMockResponseTypeIfNeeded(mock: Partial<FluentMock>): Partial<FluentMock>;
export declare function spreadMissingProperties(mock: Partial<FluentMock>): FluentMock;
export interface RouteOptions {
    /**
     * Response body.
     */
    body: string | Buffer;
    /**
     * If set, equals to setting `Content-Type` response header.
     */
    contentType: string;
    /**
     * Response headers. Header values will be converted to a string.
     */
    headers: {
        [key: string]: string;
    };
    /**
     * File path to respond with. The content type will be inferred from file extension. If `path` is a relative path, then it
     * is resolved relative to the current working directory.
     */
    path: string;
    /**
     * Response status code, defaults to `200`.
     */
    status: number;
}
export declare function withMocks(mocks: () => Partial<FluentMock>[], context: () => unknown, options: Partial<WithMocksOptions>, page: Page | undefined): Promise<void>;
