Skip to content

Commit

Permalink
feat: implement provider state parameters in consumer tests #372
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronald Holshausen committed Mar 11, 2020
1 parent cdb72db commit af8bf32
Show file tree
Hide file tree
Showing 11 changed files with 2,619 additions and 1,561 deletions.
4,048 changes: 2,517 additions & 1,531 deletions examples/v3/e2e/package-lock.json

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions examples/v3/e2e/repository.js
Expand Up @@ -19,6 +19,14 @@ class Repository {
clear() {
this.entities = []
}

first() {
return this.entities[0]
}

count() {
return this.entities.length
}
}

module.exports = Repository
4 changes: 3 additions & 1 deletion examples/v3/e2e/test/consumer.spec.js
Expand Up @@ -167,7 +167,9 @@ describe("Pact V3", () => {

before(() =>
provider
.given("Has an animal with ID 1")
.given("Has an animal with ID", {
id: 100,
})
.uponReceiving("a request for an animal with ID 1")
.withRequest({
path: regex("/animals/[0-9]+", "/animals/1"),
Expand Down
6 changes: 6 additions & 0 deletions examples/v3/e2e/test/helper.ts
@@ -0,0 +1,6 @@
import wrapper from "@pact-foundation/pact-node"

// used to kill any left over mock server instances
process.on("SIGINT", () => {
wrapper.removeAllServers()
})
11 changes: 6 additions & 5 deletions examples/v3/e2e/test/provider.spec.js
Expand Up @@ -35,21 +35,22 @@ describe("Pact Verification", () => {
"Has no animals": () => {
animalRepository.clear()
token = "1234"
return Promise.resolve(`Animals removed to the db`)
return Promise.resolve({description: `Animals removed to the db`})
},
"Has some animals": () => {
token = "1234"
importData()
return Promise.resolve(`Animals added to the db`)
return Promise.resolve({description: `Animals added to the db`, count: animalRepository.count()})
},
"Has an animal with ID 1": () => {
"Has an animal with ID": (parameters) => {
token = "1234"
importData()
return Promise.resolve(`Animals added to the db`)
animalRepository.first().id = parameters.id
return Promise.resolve({description: `Animal with ID ${parameters.id} added to the db`, id: parameters.id})
},
"is not authenticated": () => {
token = ""
Promise.resolve(`Invalid bearer token generated`)
return Promise.resolve({description: `Invalid bearer token generated`})
},
},

Expand Down
47 changes: 33 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -160,7 +160,7 @@
"ts-node": "^3.3.0",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"typescript": "^3.3.3",
"typescript": "^3.8.3",
"webpack": "^3.5.5"
},
"binary": {
Expand Down
2 changes: 1 addition & 1 deletion src/v3/native/artifacts.json
@@ -1 +1 @@
{"active":"release","targets":{"release":{"rustc":"","env":{"npm_config_target":null,"npm_config_arch":null,"npm_config_target_arch":null,"npm_config_disturl":null,"npm_config_runtime":null,"npm_config_build_from_source":null,"npm_config_devdir":null}},"debug":{"rustc":"","env":{"npm_config_target":null,"npm_config_arch":null,"npm_config_target_arch":null,"npm_config_disturl":null,"npm_config_runtime":null,"npm_config_build_from_source":null,"npm_config_devdir":null}}}}
{"active":"debug","targets":{"release":{"rustc":"","env":{"npm_config_target":null,"npm_config_arch":null,"npm_config_target_arch":null,"npm_config_disturl":null,"npm_config_runtime":null,"npm_config_build_from_source":null,"npm_config_devdir":null}},"debug":{"rustc":"","env":{"npm_config_target":null,"npm_config_arch":null,"npm_config_target_arch":null,"npm_config_disturl":null,"npm_config_runtime":null,"npm_config_build_from_source":null,"npm_config_devdir":null}}}}
36 changes: 33 additions & 3 deletions src/v3/native/src/lib.rs
Expand Up @@ -117,7 +117,7 @@ fn process_xml(body: String, matching_rules: &mut Category, generators: &mut Gen

fn process_body(body: String, content_type: DetectedContentType, matching_rules: &mut MatchingRules, generators: &mut Generators) -> Result<OptionalBody, String> {
let category = matching_rules.add_category("body");
match dbg!(content_type) {
match content_type {
DetectedContentType::Json => Ok(OptionalBody::from(process_json(body, category, generators))),
DetectedContentType::Xml => Ok(OptionalBody::Present(process_xml(body, category, generators)?)),
_ => Ok(OptionalBody::from(body))
Expand Down Expand Up @@ -182,8 +182,38 @@ declare_types! {
let states: Handle<JsArray> = cx.argument(1)?;
let provider_states = states.to_vec(&mut cx)?.iter()
.map(|state| {
let state_desc = state.downcast::<JsString>().unwrap().value();
ProviderState::default(&state_desc.clone())
let js_state = state.downcast::<JsObject>().unwrap();
let description = js_state.get(&mut cx, "description").unwrap().downcast::<JsString>().unwrap().value();
let js_parameters = js_state.get(&mut cx, "parameters");
match js_parameters {
Ok(parameters) => match parameters.downcast::<JsObject>() {
Ok(parameters) => {
let js_props = parameters.get_own_property_names(&mut cx).unwrap();
let props = js_props.to_vec(&mut cx).unwrap().iter().map(|prop| {
let prop_name = prop.downcast::<JsString>().unwrap().value();
let prop_val = parameters.get(&mut cx, prop_name.as_str()).unwrap();
if let Ok(val) = prop_val.downcast::<JsString>() {
(prop_name, json!(val.value()))
} else if let Ok(val) = prop_val.downcast::<JsNumber>() {
(prop_name, json!(val.value()))
} else if let Ok(val) = prop_val.downcast::<JsBoolean>() {
(prop_name, json!(val.value()))
} else {
error!("Ignoring value for provider state parameter '{}'", prop_name);
(prop_name, Value::Null)
}
}).collect();
ProviderState { name: description.clone(), params: props }
},
Err(_) => {
if !parameters.is_a::<JsUndefined>() && !!parameters.is_a::<JsNull>() {
error!("Expected an Object for state change parameters '{}'", description);
}
ProviderState::default(&description.clone())
}
},
_ => ProviderState::default(&description.clone())
}
}).collect();

let mut this = cx.this();
Expand Down
5 changes: 3 additions & 2 deletions src/v3/native/src/verify.rs
Expand Up @@ -237,7 +237,7 @@ pub fn verify_provider(mut cx: FunctionContext) -> JsResult<JsUndefined> {
Ok(url) => {
provider_info.protocol = url.scheme().into();
provider_info.host = url.host_str().unwrap_or("localhost").into();
provider_info.port = url.port().unwrap_or(8080);
provider_info.port = url.port();
provider_info.path = url.path().into();
},
Err(err) => {
Expand All @@ -264,7 +264,8 @@ pub fn verify_provider(mut cx: FunctionContext) -> JsResult<JsUndefined> {
publish: false,
provider_version: None,
build_url: None,
request_filter
request_filter,
provider_tags: vec![]
};

BackgroundTask { provider_info, pacts, filter_info, consumers_filter, options }.schedule(callback);
Expand Down
11 changes: 8 additions & 3 deletions src/v3/pact.ts
Expand Up @@ -7,18 +7,23 @@ export interface PactV3Options {
provider: string
}

export interface V3ProviderState {
description: string
parameters?: any
}

export class PactV3 {
private opts: any
private states: any[] = []
private states: V3ProviderState[] = []
private pact: any

constructor(opts: PactV3Options & {}) {
this.opts = opts
this.pact = new PactNative.Pact(opts.consumer, opts.provider)
}

public given(providerState: any) {
this.states.push(providerState)
public given(providerState: any, parameters?: any) {
this.states.push({ description: providerState, parameters })
return this
}

Expand Down

0 comments on commit af8bf32

Please sign in to comment.