Skip to content

Commit 8945b3c

Browse files
authored
allow to delete a selective property (#45)
<!-- Please describe your pull request here. --> ## References - TODO <!-- References to relevant GitHub issues and pull requests, esp. upstream and downstream changes --> ## Submitter checklist - [ ] Recommended: Join [WireMock Slack](https://slack.wiremock.org/) to get any help in `#help-contributing` or a project-specific channel like `#wiremock-java` - [ ] The PR request is well described and justified, including the body and the references - [ ] The PR title represents the desired changelog entry - [ ] The repository's code style is followed (see the contributing guide) - [ ] Test coverage that demonstrates that the change works as expected - [ ] For new features, there's necessary documentation in this pull request or in a subsequent PR to [wiremock.org](https://github.com/wiremock/wiremock.org) <!-- Put an `x` into the [ ] to show you have filled the information. The template comes from https://github.com/wiremock/.github/blob/main/.github/pull_request_template.md You can override it by creating .github/pull_request_template.md in your own repository -->
1 parent 2b36cdb commit 8945b3c

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ wiremock/wiremock:3x \
271271
The state is recorded in `serveEventListeners` of a stub. The following functionalities are provided:
272272

273273
- `state` : stores a state in a context. Storing the state multiple times can be used to selectively overwrite existing properties.
274+
- to delete a selective property, set it to `null` (as string).
274275
- `list` : stores a state in a list. Can be used to prepend/append new states to an existing list. List elements cannot be modified (only read/deleted).
275276

276277
`state` and `list` can be used in the same `ServeEventListener` (would count as two updates). Adding multiple `recordState` `ServeEventListener` is supported.
@@ -392,6 +393,28 @@ To record a complete response body, use:
392393
}
393394
```
394395

396+
To delete a selective property, ensure that the field has the value `null` as string, e.g. by specifying `default='null` for `jsonpath`:
397+
398+
```json
399+
{
400+
"request": {},
401+
"response": {},
402+
"serveEventListeners": [
403+
{
404+
"name": "recordState",
405+
"parameters": {
406+
"context": "{{jsonPath response.body '$.id'}}",
407+
"state": {
408+
"id": "{{jsonPath response.body '$.id'}}",
409+
"firstName": "{{jsonPath request.body '$.firstName' default='null'}}",
410+
"lastName": "{{jsonPath request.body '$.lastName' default='null'}}"
411+
}
412+
}
413+
}
414+
]
415+
}
416+
```
417+
395418
To append a state to a list:
396419

397420
```json

src/main/java/org/wiremock/extensions/state/internal/ContextManager.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,13 @@ public Long createOrUpdateContextState(String contextName, Map<String, String> p
6262
it.incUpdateCount();
6363
return it;
6464
}).orElseGet(() -> new Context(contextName));
65-
context.getProperties().putAll(properties);
65+
properties.forEach((k, v) -> {
66+
if(v.equals("null")) {
67+
context.getProperties().remove(k);
68+
} else {
69+
context.getProperties().put(k, v);
70+
}
71+
});
6672
store.put(contextName, context);
6773
return context.getUpdateCount();
6874
}

src/test/java/org/wiremock/extensions/state/functionality/StateRequestMatcherTest.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.junit.jupiter.api.Test;
2929

3030
import java.net.URI;
31+
import java.util.HashMap;
3132
import java.util.Map;
3233

3334
import static com.github.tomakehurst.wiremock.client.WireMock.delete;
@@ -173,7 +174,7 @@ private void createPostStub() throws JsonProcessingException {
173174
Map.of(
174175
"context", "{{jsonPath response.body '$.id'}}",
175176
"state", Map.of(
176-
"stateValue", "{{jsonPath request.body '$.contextValue'}}"
177+
"stateValue", "{{jsonPath request.body '$.contextValue' default='null'}}"
177178
),
178179
"list", Map.of(
179180
"addLast", Map.of(
@@ -228,7 +229,10 @@ private String postAndAssertContextValue(String contextValue) {
228229
private String postAndAssertContextValue(String contextName, String contextValue) {
229230
var context = given()
230231
.accept(ContentType.JSON)
231-
.body(Map.of("contextValue", contextValue, "id", contextName))
232+
.body(new HashMap<String, String>() {{
233+
put("contextValue", contextValue);
234+
put("id", contextName);
235+
}})
232236
.post(assertDoesNotThrow(() -> new URI(wm.getRuntimeInfo().getHttpBaseUrl() + TEST_URL + "/" + contextName)))
233237
.then()
234238
.statusCode(HttpStatus.SC_OK)
@@ -303,6 +307,16 @@ void test_hasProperty_propertyExists_ok() {
303307
getAndAssertContextMatcher(context, "hasProperty/stateValue", HttpStatus.SC_OK, "context found", "2", "1");
304308
}
305309

310+
@Test
311+
void test_hasProperty_propertyGotDeleted_fail() {
312+
var contextValue = RandomStringUtils.randomAlphabetic(5);
313+
314+
var context = postAndAssertContextValue(contextValue);
315+
postAndAssertContextValue(contextValue);
316+
postAndAssertContextValue(context, null);
317+
getAndAssertContextMatcher(context, "hasProperty/stateValue", HttpStatus.SC_NOT_FOUND);
318+
}
319+
306320
@Test
307321
void test_hasNotProperty_propertyExists_fail() {
308322
var contextValue = RandomStringUtils.randomAlphabetic(5);

0 commit comments

Comments
 (0)