import { FluentMock , QueryString , RequestInfos , ResponseData } from './with-mocks' ; import { MissingMock } from './get-missing-mocks' ; import { ensureDirectoryExists , hasNoQueryString , UpdatePolicy , urlToShortPath , } from '../../../utils' ; import path from 'path' ; import { writeFileSync } from 'fs' ; export interface UpdatePolicyOptions { /**
     * 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  getOutdatedMocks )
     *  2°) and the call to  lastUpdated gives a date that is older than the  updatePolicy memberof 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  getOutdatedMocks )
     * Defaults to the current date.
     *
     *  type { Date } memberof lastUpdated ? : ( ) => Date ; type { UpdatePolicy } memberof updatePolicy ? : UpdatePolicy ; } export template T param { string } relativeUrl param { T } response param { UpdatePolicyOptions } updatePolicy returns { Partial < FluentMock > } example export function mockGetWithJsonResponse < T > ( relativeUrl , response , updatePolicy ? ) { return { displayName : `GET ${ relativeUrl }` , urlMatcher : ( url ) => url . includes ( relativeUrl ) , methodMatcher : ( m ) => m === 'GET' , jsonResponse : ( ) => response , ... updatePolicy , } ; } export param { string } relativeUrl param { string } response param { UpdatePolicyOptions } updatePolicy returns { Partial < FluentMock > } example export function mockGetWithJavascriptResponse ( relativeUrl , response , updatePolicy ? ) { return { displayName : `GET ${ relativeUrl }` , urlMatcher : ( url ) => url . includes ( relativeUrl ) , methodMatcher : ( m ) => m === 'GET' , responseType : 'javascript' , rawResponse : ( ) => response , ... updatePolicy , } ; } export function mockGetWithEmptyResponseAndStatus ( relativeUrl , status = 200 ) { return { displayName : `GET ${ relativeUrl }` , urlMatcher : ( url ) => url . includes ( relativeUrl ) , methodMatcher : ( m ) => m === 'GET' , responseType : 'empty' , status , } ; } export param { string } relativeUrl returns { Partial < FluentMock > } example export function mockGetWithUnauthorizedResponse ( relativeUrl ) { return { displayName : `GET ${ relativeUrl }` , urlMatcher : ( url ) => url . includes ( relativeUrl ) , methodMatcher : ( m ) => m === 'GET' , responseType : 'empty' , status : 401 , } ; } export param { string } relativeUrl returns { Partial < FluentMock > } example export function mockGetWithForbiddenResponse ( relativeUrl ) { return { displayName : `GET ${ relativeUrl }` , urlMatcher : ( url ) => url . includes ( relativeUrl ) , methodMatcher : ( m ) => m === 'GET' , responseType : 'empty' , status : 403 , } ; } export function mockPostWithEmptyResponseAndStatus ( relativeUrl , status = 200 ) { return { displayName : `POST ${ relativeUrl }` , urlMatcher : ( url ) => url . includes ( relativeUrl ) , methodMatcher : ( m ) => m === 'POST' , responseType : 'empty' , status , } ; } export template T param { string } relativeUrl param { QueryString } queryString param { T } response param { UpdatePolicyOptions } updatePolicy returns { Partial < FluentMock > } example export function mockGetWithJsonResponseDependingOnQueryString < T > ( relativeUrl , queryString , response , updatePolicy ? ) { const searchParams = new URLSearchParams ( queryString ) ; return { displayName : `GET ${ relativeUrl }?${ searchParams . toString ( ) }` , methodMatcher : ( m ) => m === 'GET' , urlMatcher : ( url ) => url . includes ( relativeUrl ) , queryStringMatcher : ( qs ) => { let match = true ; for ( const key in queryString ) { if ( qs && qs [ key ] === undefined ) { match = false ; break ; } if ( qs && qs [ key ] && qs [ key ] !== queryString [ key ] ) { match = false ; break ; } } return match ; } , jsonResponse : ( ) => response , ... updatePolicy , } ; } export function generateCodeForMissingMock ( missingMock , targetDirectory ) { ensureDirectoryExists ( targetDirectory ) ; const targetFolderName = urlToShortPath ( missingMock . url ) . replace ( /\//g , '_' ) . replace ( /\?/g , '#' ) ; const targetSubDirectory = path . join ( targetDirectory , targetFolderName ) ; ensureDirectoryExists ( targetSubDirectory ) ; switch ( missingMock . mimeType ) { case 'application/json' : { const dataFileName = `${ targetFolderName }.json` ; const dataFilePath = path . join ( targetSubDirectory , dataFileName ) ; writeFileSync ( dataFilePath , JSON . stringify ( missingMock . response , null , 2 ) ) ; const mockSourceCode = generateMockCodeOf ( missingMock , dataFileName ) ; writeFileSync ( path . join ( targetSubDirectory , `${ targetFolderName }.ts` ) , mockSourceCode ) ; } break ; default : console . log ( `Unsupported mime type: ${ missingMock . mimeType }` ) ; break ; } } export function generateMockCodeOf ( missingMock , dataFileName ) { if ( missingMock . mimeType === 'application/json' && missingMock . method === 'GET' && hasNoQueryString ( missingMock . url ) ) { return `
    import response from './${ dataFileName }';
    export const mock = mockGetWithJsonResponse('${ missingMock . url }', response)
    ` ; } return `Unsupported mime type: ${ missingMock . mimeType }` ; }