import chai from 'chai' ; import chaiHttp from 'chai-http' ; import _ from 'lodash' ; import { Server } from '@libstack/server' ; import { Response , SuperAgentRequest } from 'superagent' ; chai . use ( chaiHttp ) ; chai . should ( ) ; /**
 * This is the options every request will use
 */ export interface RequestOptions { query ? : any ; headers ? : any ; } /**
 * This function will be used to decorate requests. Please take a look at RequestOptions,
 * Before the execution of every request, this function will be invoked to change the requests,
 * for example by creating a new `Authorization` Header param on your requests.
 */ export interface RequestDecorator { param request decorateRequest ( request ) : Promise < RequestOptions > ; } /**
 * This class represents HTTP access to your API
 */ export class Http { server : Server ; requestDecorator : RequestDecorator ; constructor ( httpServer , optionsDecorator ? ) { this . server = httpServer ; this . requestDecorator = optionsDecorator ; } private request ( ) { return chai . request ( this . server . server ) ; } private async handleOptions ( result , request = { } ) { if ( ! request . headers ) request . headers = { } ; if ( ! request . query ) request . query = { } ; const resultOptions = await this . decorateRequest ( request ) ; if ( resultOptions . headers ) { _ . forEach ( resultOptions . headers , ( value , key ) => result . set ( key , value ) ) ; } if ( resultOptions . query ) { result . query ( resultOptions . query ) ; } } private async handleRequest ( result , options ) { await this . handleOptions ( result , options ) ; return new Promise ( resolve => result . end ( ( err , res ) => resolve ( res ) ) ) ; } param path param options get = ( path , options ? ) : Promise < Response > => { return this . handleRequest ( this . request ( ) . get ( path ) , options ) ; } ; param path param options delete = ( path , options ? ) : Promise < Response > => { return this . handleRequest ( this . request ( ) . delete ( path ) , options ) ; } ; param path param body param options post = ( path , body ? , options ? ) : Promise < Response > => { const result = this . request ( ) . post ( path ) ; if ( body ) { result . send ( body ) ; } return this . handleRequest ( result , options ) ; } ; param path param body param options put = ( path , body ? , options ? ) : Promise < Response > => { const result = this . request ( ) . put ( path ) ; if ( body ) { result . send ( body ) ; } return this . handleRequest ( result , options ) ; } ; param decorator as ( decorator ) { return new Http ( this . server , decorator ) ; } private decorateRequest ( request ) { return this . requestDecorator ? this . requestDecorator . decorateRequest ( request ) : Promise . resolve ( request ) ; } } /**
 * This class will help testing your API.
 * All you need to do is create an instance of TestHelper
 * by passing your Server to it.
 *
 * Then you can create requests `POST`, `PUT`, `GET` and `DELETE`.
 * You can decorate requests using the `as` function.
 */ export class TestHelper { http : Http ; expect : Chai . ExpectStatic ; constructor ( server ) { this . http = new Http ( server ) ; this . expect = chai . expect ; } }