From 2fada2a82be4718855f8d28cdbc4e65096658c7c Mon Sep 17 00:00:00 2001 From: Matt Fellows <53900+mefellows@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:30:02 +1100 Subject: [PATCH] feat: add pactffi_given_with_params for params Will eventually replace pactffi_given_with_param with pactffi_given_with_params. See https://github.com/pact-foundation/pact-js/issues/848 for background --- native/addon.cc | 2 +- native/consumer.cc | 46 ++++++++++++++++++++++++++----------------- native/consumer.h | 2 +- src/consumer/index.ts | 6 +++--- src/ffi/types.ts | 5 ++--- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/native/addon.cc b/native/addon.cc index 8701cba0..8a112aea 100644 --- a/native/addon.cc +++ b/native/addon.cc @@ -21,7 +21,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) { exports.Set(Napi::String::New(env, "pactffiNewInteraction"), Napi::Function::New(env, PactffiNewInteraction)); exports.Set(Napi::String::New(env, "pactffiUponReceiving"), Napi::Function::New(env, PactffiUponReceiving)); exports.Set(Napi::String::New(env, "pactffiGiven"), Napi::Function::New(env, PactffiGiven)); - exports.Set(Napi::String::New(env, "pactffiGivenWithParam"), Napi::Function::New(env, PactffiGivenWithParam)); + exports.Set(Napi::String::New(env, "PactffiGivenWithParams"), Napi::Function::New(env, PactffiGivenWithParams)); exports.Set(Napi::String::New(env, "pactffiWithRequest"), Napi::Function::New(env, PactffiWithRequest)); exports.Set(Napi::String::New(env, "pactffiWithQueryParameter"), Napi::Function::New(env, PactffiWithQueryParameter)); exports.Set(Napi::String::New(env, "pactffiWithSpecification"), Napi::Function::New(env, PactffiWithSpecification)); diff --git a/native/consumer.cc b/native/consumer.cc index 9548c101..a89ea093 100644 --- a/native/consumer.cc +++ b/native/consumer.cc @@ -631,51 +631,61 @@ Napi::Value PactffiGiven(const Napi::CallbackInfo& info) { // } /** - * Adds a provider state to the Interaction with a parameter key and value. Returns false if the interaction or Pact can't be - * modified (i.e. the mock server for it has already started) + * Adds a provider state to the Interaction with a set of parameter key and value pairs in JSON + * form. If the params is not an JSON object, it will add it as a single parameter with a `value` + * key. + * + * # Parameters + * * `description` - The provider state description. + * * `params` - Parameter values as a JSON fragment. + * + * # Errors + * Returns EXIT_FAILURE (1) if the interaction or Pact can't be modified (i.e. the mock server + * for it has already started). + * Returns 2 and sets the error message (which can be retrieved with `pactffi_get_error_message`) + * if the parameter values con't be parsed as JSON. + * Returns 3 if any of the C strings are not valid. * - * * `description` - The provider state description. It needs to be unique. - * * `name` - Parameter name. - * * `value` - Parameter value. * * C interface: * - * bool pactffi_given_with_param(InteractionHandle interaction, + * int pactffi_given_with_params(InteractionHandle interaction, * const char *description, - * const char *name, - * const char *value); + * const char *params); */ -Napi::Value PactffiGivenWithParam(const Napi::CallbackInfo& info) { +Napi::Value PactffiGivenWithParams(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); if (info.Length() < 4) { - throw Napi::Error::New(env, "PactffiGivenWithParam received < 4 arguments"); + throw Napi::Error::New(env, "PactffiGivenWithParams received < 4 arguments"); } if (!info[0].IsNumber()) { - throw Napi::Error::New(env, "PactffiGivenWithParam(arg 0) expected a InteractionHandle (uint32_t)"); + throw Napi::Error::New(env, "PactffiGivenWithParams(arg 0) expected a InteractionHandle (uint32_t)"); } if (!info[1].IsString()) { - throw Napi::Error::New(env, "PactffiGivenWithParam(arg 1) expected a string"); + throw Napi::Error::New(env, "PactffiGivenWithParams(arg 1) expected a string"); } if (!info[2].IsString()) { - throw Napi::Error::New(env, "PactffiGivenWithParam(arg 2) expected a string"); + throw Napi::Error::New(env, "PactffiGivenWithParams(arg 2) expected a string"); } if (!info[3].IsString()) { - throw Napi::Error::New(env, "PactffiGivenWithParam(arg 3) expected a string"); + throw Napi::Error::New(env, "PactffiGivenWithParams(arg 3) expected a string"); } InteractionHandle interaction = info[0].As().Uint32Value(); std::string description = info[1].As().Utf8Value(); - std::string name = info[2].As().Utf8Value(); - std::string value = info[3].As().Utf8Value(); + std::string params = info[2].As().Utf8Value(); - bool res = pactffi_given_with_param(interaction, description.c_str(), name.c_str(), value.c_str()); + int res = pactffi_given_with_params(interaction, description.c_str(), params.c_str()); - return Napi::Boolean::New(env, res); + if (res > 0) { + return Napi::Boolean::New(env, false); + } + return Napi::Boolean::New(env, true); } /** diff --git a/native/consumer.h b/native/consumer.h index bd5d7c93..47bca46c 100644 --- a/native/consumer.h +++ b/native/consumer.h @@ -16,7 +16,7 @@ Napi::Value PactffiCleanupMockServer(const Napi::CallbackInfo& info); Napi::Value PactffiCreateMockServerForPact(const Napi::CallbackInfo& info); Napi::Value PactffiCreateMockServer(const Napi::CallbackInfo& info); Napi::Value PactffiGiven(const Napi::CallbackInfo& info); -Napi::Value PactffiGivenWithParam(const Napi::CallbackInfo& info); +Napi::Value PactffiGivenWithParams(const Napi::CallbackInfo& info); Napi::Value PactffiMockServerLogs(const Napi::CallbackInfo& info); Napi::Value PactffiMockServerMatched(const Napi::CallbackInfo& info); Napi::Value PactffiMockServerMismatches(const Napi::CallbackInfo& info); diff --git a/src/consumer/index.ts b/src/consumer/index.ts index 9011e281..38f794c2 100644 --- a/src/consumer/index.ts +++ b/src/consumer/index.ts @@ -180,7 +180,7 @@ export const makeConsumerPact = ( }, given: (state: string) => ffi.pactffiGiven(interactionPtr, state), givenWithParam: (state: string, name: string, value: string) => - ffi.pactffiGivenWithParam(interactionPtr, state, name, value), + ffi.pactffiGivenWithParams(interactionPtr, state, name, value), withRequestContents: (body: string, contentType: string) => ffi.pactffiWithBody( interactionPtr, @@ -240,7 +240,7 @@ export const makeConsumerPact = ( ffi.pactffiUponReceiving(interactionPtr, recieveDescription), given: (state: string) => ffi.pactffiGiven(interactionPtr, state), givenWithParam: (state: string, name: string, value: string) => - ffi.pactffiGivenWithParam(interactionPtr, state, name, value), + ffi.pactffiGivenWithParams(interactionPtr, state, JSON.stringify({[name]: value})), withRequest: (method: string, path: string) => ffi.pactffiWithRequest(interactionPtr, method, path), withQuery: (name: string, index: number, value: string) => @@ -450,7 +450,7 @@ export const makeConsumerMessagePact = ( }, given: (state: string) => ffi.pactffiGiven(interactionPtr, state), givenWithParam: (state: string, name: string, value: string) => - ffi.pactffiGivenWithParam(interactionPtr, state, name, value), + ffi.pactffiGivenWithParams(interactionPtr, state, JSON.stringify({[name]: value})), withRequestContents: (body: string, contentType: string) => ffi.pactffiWithBody( interactionPtr, diff --git a/src/ffi/types.ts b/src/ffi/types.ts index 85a94451..8c044c32 100644 --- a/src/ffi/types.ts +++ b/src/ffi/types.ts @@ -157,11 +157,10 @@ export type FfiConsumerFunctions = { description: string ): boolean; pactffiGiven(handle: FfiInteractionHandle, providerState: string): boolean; - pactffiGivenWithParam( + pactffiGivenWithParams( handle: FfiInteractionHandle, description: string, - name: string, - value: string + params: string ): boolean; pactffiWithRequest( handle: FfiInteractionHandle,