From c0171fc9f8554547331eaa236b7ef68dd5892b2e Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Tue, 4 Jun 2024 09:29:46 -0600 Subject: [PATCH] feat: Add ability to exclude keys from HyperRequest and HyperResponse mementos --- models/HyperRequest.cfc | 91 +++++++++++++++++--------- models/HyperResponse.cfc | 33 ++++++---- tests/specs/unit/HyperRequestSpec.cfc | 5 ++ tests/specs/unit/HyperResponseSpec.cfc | 12 ++++ 4 files changed, 96 insertions(+), 45 deletions(-) diff --git a/models/HyperRequest.cfc b/models/HyperRequest.cfc index 4ccfa1d..48bc61c 100644 --- a/models/HyperRequest.cfc +++ b/models/HyperRequest.cfc @@ -1397,35 +1397,40 @@ component accessors="true" { * * @return struct */ - public struct function getMemento() { - return { - "requestID" : getRequestID(), - "baseUrl" : getBaseUrl(), - "url" : getUrl(), - "fullUrl" : getFullUrl(), - "method" : getMethod(), - "queryParams" : getQueryParams(), - "headers" : getHeaders(), - "cookies" : getCookies(), - "files" : getFiles(), - "bodyFormat" : getBodyFormat(), - "body" : getBody(), - "referrerId" : isNull( variables.referrer ) ? "" : variables.referrer.getResponseID(), - "throwOnError" : getThrowOnError(), - "timeout" : getTimeout(), - "maximumRedirects" : getMaximumRedirects(), - "authType" : getAuthType(), - "username" : getUsername(), - "password" : getPassword(), - "clientCert" : isNull( variables.clientCert ) ? "" : variables.clientCert, - "clientCertPassword" : isNull( variables.clientCertPassword ) ? "" : variables.clientCertPassword, - "domain" : getDomain(), - "workstation" : getWorkstation(), - "resolveUrls" : getResolveUrls(), - "encodeUrl" : getEncodeUrl(), - "retries" : getRetries(), - "currentRequestCount" : getCurrentRequestCount() - }; + public struct function getMemento( array excludes = [] ) { + return structFilter( + { + "requestID" : getRequestID(), + "baseUrl" : getBaseUrl(), + "url" : getUrl(), + "fullUrl" : getFullUrl(), + "method" : getMethod(), + "queryParams" : getQueryParams(), + "headers" : getHeaders(), + "cookies" : getCookies(), + "files" : getFiles(), + "bodyFormat" : getBodyFormat(), + "body" : getBody(), + "referrerId" : isNull( variables.referrer ) ? "" : variables.referrer.getResponseID(), + "throwOnError" : getThrowOnError(), + "timeout" : getTimeout(), + "maximumRedirects" : getMaximumRedirects(), + "authType" : getAuthType(), + "username" : getUsername(), + "password" : getPassword(), + "clientCert" : isNull( variables.clientCert ) ? "" : variables.clientCert, + "clientCertPassword" : isNull( variables.clientCertPassword ) ? "" : variables.clientCertPassword, + "domain" : getDomain(), + "workstation" : getWorkstation(), + "resolveUrls" : getResolveUrls(), + "encodeUrl" : getEncodeUrl(), + "retries" : getRetries(), + "currentRequestCount" : getCurrentRequestCount() + }, + function( key ) { + return !arrayContainsNoCase( excludes, key ); + } + ); } /** @@ -1463,7 +1468,19 @@ component accessors="true" { for ( var pattern in variables.fakeConfiguration ) { if ( getPathPatternMatcher().matchPattern( pattern, getFullUrl() ) ) { if ( variables.builder.hasSequenceForPattern( pattern ) ) { - return variables.builder.record( this, variables.builder.popResponseForSequence( pattern ) ); + var fakeRes = variables.builder.record( this, variables.builder.popResponseForSequence( pattern ) ); + if ( fakeRes.getRequest().getThrowOnError() && fakeRes.isError() ) { + throw( + type = "HyperRequestError", + message = "Received a [#fakeRes.getStatus()#] response when requesting [#fakeRes.getRequest().getFullUrl()#]", + detail = fakeRes.getData(), + extendedinfo = serializeJSON( { + "request" : fakeRes.getRequest().getMemento(), + "response" : fakeRes.getMemento() + } ) + ); + } + return fakeRes; } var callback = variables.fakeConfiguration[ pattern ]; @@ -1485,7 +1502,19 @@ component accessors="true" { } variables.builder.registerSequence( pattern, res ); - return variables.builder.record( this, variables.builder.popResponseForSequence( pattern ) ); + var fakeRes = variables.builder.record( this, variables.builder.popResponseForSequence( pattern ) ); + if ( fakeRes.getRequest().getThrowOnError() && fakeRes.isError() ) { + throw( + type = "HyperRequestError", + message = "Received a [#fakeRes.getStatus()#] response when requesting [#fakeRes.getRequest().getFullUrl()#]", + detail = fakeRes.getData(), + extendedinfo = serializeJSON( { + "request" : fakeRes.getRequest().getMemento(), + "response" : fakeRes.getMemento() + } ) + ); + } + return fakeRes; } } diff --git a/models/HyperResponse.cfc b/models/HyperResponse.cfc index 92179dc..e187655 100644 --- a/models/HyperResponse.cfc +++ b/models/HyperResponse.cfc @@ -322,20 +322,25 @@ component accessors="true" { * * @returns struct */ - public struct function getMemento() { - return { - "responseID" : getResponseID(), - "requestID" : getRequestID(), - "statusCode" : getStatusCode(), - "statusText" : getStatusText(), - "status" : getStatus(), - "data" : getData(), - "charset" : getCharset(), - "headers" : getHeaders(), - "timestamp" : getTimestamp(), - "executionTime" : getExecutionTime(), - "cookies" : getCookies() - }; + public struct function getMemento( array excludes = [] ) { + return structFilter( + { + "responseID" : getResponseID(), + "requestID" : getRequestID(), + "statusCode" : getStatusCode(), + "statusText" : getStatusText(), + "status" : getStatus(), + "data" : getData(), + "charset" : getCharset(), + "headers" : getHeaders(), + "timestamp" : getTimestamp(), + "executionTime" : getExecutionTime(), + "cookies" : getCookies() + }, + function( key ) { + return !arrayContainsNoCase( excludes, key ); + } + ); } /** diff --git a/tests/specs/unit/HyperRequestSpec.cfc b/tests/specs/unit/HyperRequestSpec.cfc index 9842bd0..98a777b 100644 --- a/tests/specs/unit/HyperRequestSpec.cfc +++ b/tests/specs/unit/HyperRequestSpec.cfc @@ -43,6 +43,11 @@ component extends="testbox.system.BaseSpec" { } ); } ); + it( "can exclude keys from the memento", () => { + var memento = variables.req.getMemento( excludes = [ "cookies" ] ); + expect( memento ).notToHaveKey( "cookies" ); + } ); + it( "can set multiple values at once from a struct", function() { expect( req.getUrl() ).toBe( "" ); expect( req.getMethod() ).toBe( "GET" ); diff --git a/tests/specs/unit/HyperResponseSpec.cfc b/tests/specs/unit/HyperResponseSpec.cfc index 81162d6..dad5b7a 100644 --- a/tests/specs/unit/HyperResponseSpec.cfc +++ b/tests/specs/unit/HyperResponseSpec.cfc @@ -25,6 +25,18 @@ component extends="testbox.system.BaseSpec" { } ); } ); + it( "can exclude keys from the memento", function() { + var res = new Hyper.models.HyperResponse( + originalRequest = createStub( extends = "models.HyperRequest" ).$( "getRequestID", createUUID() ), + statusCode = 200, + executionTime = 100, + headers = { "Content-Type" : "text/html; charset=utf-8" } + ); + + var memento = res.getMemento( excludes = [ "cookies" ] ); + expect( memento ).notToHaveKey( "cookies" ); + } ); + it( "throws an exception when requesting json data but the data is not json", function() { var res = new Hyper.models.HyperResponse( originalRequest = createStub( extends = "models.HyperRequest" ),