Skip to content

Commit 26ced95

Browse files
authored
Adding demo for extension functionality (#49)
- adding sample Vue frontend - adding WireMock docker configuration for demo - udpate README.md <!-- 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 5cc141a commit 26ced95

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+8856
-43
lines changed

.run/WireMock Docker Demo.run.xml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="WireMock Docker Demo" type="docker-deploy" factoryName="docker-image" server-name="Docker">
3+
<deployment type="docker-image">
4+
<settings>
5+
<option name="imageTag" value="wiremock/wiremock:3x" />
6+
<option name="command" value="--global-response-templating --jetty-header-request-size 32768 --jetty-header-response-size 32768 --verbose" />
7+
<option name="containerName" value="wiremock-extension-state-test" />
8+
<option name="portBindings">
9+
<list>
10+
<DockerPortBindingImpl>
11+
<option name="containerPort" value="8080" />
12+
<option name="hostPort" value="8080" />
13+
</DockerPortBindingImpl>
14+
</list>
15+
</option>
16+
<option name="volumeBindings">
17+
<list>
18+
<DockerVolumeBindingImpl>
19+
<option name="containerPath" value="/var/wiremock/extensions" />
20+
<option name="hostPath" value="$PROJECT_DIR$/build/libs" />
21+
<option name="readOnly" value="true" />
22+
</DockerVolumeBindingImpl>
23+
<DockerVolumeBindingImpl>
24+
<option name="containerPath" value="/home/wiremock" />
25+
<option name="hostPath" value="$PROJECT_DIR$/demo/stubs" />
26+
</DockerVolumeBindingImpl>
27+
</list>
28+
</option>
29+
</settings>
30+
</deployment>
31+
<method v="2" />
32+
</configuration>
33+
</component>

README.md

Lines changed: 84 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,16 @@ the `GET` won't have any knowledge of the previous post.
113113
```
114114

115115
2`POST` add another new item (`POST /queue`)
116+
116117
- Request:
117118

118119
```json
119120
{
120121
"firstName": "Jane",
121122
"lastName": "Doe"
123+
122124
}
125+
123126
```
124127

125128
- Response:
@@ -144,7 +147,9 @@ the `GET` won't have any knowledge of the previous post.
144147
"id": "kn0ixsaswzrzcfzriytrdupnjnxor1is",
145148
"firstName": "John",
146149
"lastName": "Doe"
150+
147151
}
152+
148153
```
149154

150155
4. `GET` to retrieve the second value (`GET /queue`)
@@ -251,12 +256,11 @@ java -cp "wiremock-state-extension-standalone-0.0.5.jar:wiremock-standalone-3.0.
251256

252257
### Docker
253258

254-
Using the extension with docker is similar to its usage with usage [standalone](#standalone): it just has to be available on
259+
Using the extension with docker is similar to its usage with usage [standalone](#standalone): it just has to be available on
255260
the classpath to be loaded automatically - it does not have to be added via `--extensions` .
256261

257262
**Note:** This extension depends on the current WireMock beta development, thus the tag `3x` has to be used:
258263

259-
260264
```bash
261265
docker run -it --rm \
262266
-p 8080:8080 \
@@ -441,16 +445,18 @@ To append a state to a list:
441445

442446
### Accessing the previous state
443447

444-
You can use the `state` helper to temporarily access the previous state. Use the `state` helper in the same way as you would use it when you [retrieve a state](#retrieve-a-state).
448+
You can use the `state` helper to temporarily access the previous state. Use the `state` helper in the same way as you would use it when
449+
you [retrieve a state](#retrieve-a-state).
445450

446451
**Note:** This extension does not keep a history in itself but it's an effect of the evaluation order.
447452
As templates are evaluated before the state is written, the state you access in `recordState` is the one before you store the new one
448-
(so there might be none - you might want to use `default` for these cases). In case you have multiple `recordState` `serveEventListeners`, you will have new states
453+
(so there might be none - you might want to use `default` for these cases). In case you have multiple `recordState` `serveEventListeners`, you will have new
454+
states
449455
being created in between, thus the previous state is the last stored one (so: not the one before the request).
450456

451457
1. listener 1 is executed
452-
1. accesses state n
453-
2. stores state n+1
458+
1. accesses state n
459+
2. stores state n+1
454460
2. listener 2 is executed
455461
1. accesses state n+1
456462
2. stores state n+2
@@ -478,7 +484,6 @@ The evaluation order of listeners within a stub as well as across stubs is not g
478484
}
479485
```
480486

481-
482487
## Deleting a state
483488

484489
Similar to recording a state, its deletion can be initiated in `serveEventListeners` of a stub.
@@ -528,50 +533,62 @@ Dictionary - only one option is interpreted (top to bottom as listed here)
528533
- ```json
529534
{
530535
"name": "deleteState",
531-
"list": {
532-
"deleteFirst": true
536+
"parameters": {
537+
"list": {
538+
"deleteFirst": true
539+
}
533540
}
534541
}
535542
```
536543
- ```json
537544
{
538545
"name": "deleteState",
539-
"list": {
540-
"deleteLast": true
546+
"parameters": {
547+
"list": {
548+
"deleteLast": true
549+
}
541550
}
542551
}
543552
```
544553
- ```json
545554
{
546555
"name": "deleteState",
547-
"list": {
548-
"deleteIndex": "1"
556+
"parameters": {
557+
"list": {
558+
"deleteIndex": "1"
559+
}
549560
}
550561
}
551562
```
552563
- ```json
553564
{
554565
"name": "deleteState",
555-
"list": {
556-
"deleteIndex": "-1"
566+
"parameters": {
567+
"list": {
568+
"deleteIndex": "-1"
569+
}
557570
}
558571
}
559572
```
560573
- ```json
561574
{
562575
"name": "deleteState",
563-
"list": {
564-
"deleteIndex": "{{request.pathSegments.[1]}}"
576+
"parameters": {
577+
"list": {
578+
"deleteIndex": "{{request.pathSegments.[1]}}"
579+
}
565580
}
566581
}
567582
```
568583
- ```json
569584
{
570585
"name": "deleteState",
571-
"list": {
572-
"deleteWhere": {
573-
"property": "myProperty",
574-
"value": "{{request.pathSegments.[2]}}"
586+
"parameters": {
587+
"list": {
588+
"deleteWhere": {
589+
"property": "myProperty",
590+
"value": "{{request.pathSegments.[2]}}"
591+
}
575592
}
576593
}
577594
}
@@ -763,7 +780,7 @@ The handler has the following parameters:
763780
The number matches the one described in [Context update count match](#context-update-count-match)
764781
- `property='listSize` retrieves the number of entries of `list`
765782
- `property='list` get the whole list as array, e.g. to use it with [handlebars #each](https://handlebarsjs.com/guide/builtin-helpers.html#each)
766-
- this property always has a default value (empty list), which can be overwritten with a JSON list
783+
- this property always has a default value (empty list), which can be overwritten with a JSON list
767784
- `list`: Getting an entry of the context's `list`, identified via a JSON path. Examples:
768785
- getting the first state in the list: `list='[0].myProperty`
769786
- getting the last state in the list: `list='[-1].myProperty`
@@ -774,7 +791,7 @@ You have to choose either `property` or `list` (otherwise, you will get a config
774791

775792
To retrieve a full body, use tripple braces: `{{{state context=request.pathSegments.[1] property='fullBody'}}}` .
776793

777-
When registering this extension, this helper is available via WireMock's [response templating](https://wiremock.org/3.x/docs/response-templating/) as well as
794+
When registering this extension, this helper is available via WireMock's [response templating](https://wiremock.org/3.x/docs/response-templating/) as well as
778795
in all configuration options of this extension.
779796

780797
### List operations
@@ -784,30 +801,60 @@ You can use [handlebars #each](https://handlebarsjs.com/guide/builtin-helpers.ht
784801
Things to consider:
785802

786803
- this syntax only works with `body`. It DOES NOT work with `jsonBody`
787-
- as this might get ugly, consider using `bodyFileName` / `withBodyFile()` have proper indentation
804+
- as this might get ugly, consider using `bodyFileName` / `withBodyFile()` have proper indentation
788805
- the default response for non-existant context as well as non-existant list in a context is an empty list. These states cannot be differentiated here
789-
- if you still want a different response, consider using a [StateRequestMatcher](#negative-context-exists-match)
806+
- if you still want a different response, consider using a [StateRequestMatcher](#negative-context-exists-match)
790807
- the default value for this property has to be a valid JSON list - otherwise you will get an error log and the empty list response
791808
- JSON does not allow trailing commas, so in order to create a valid JSON list, use `{{#unless @last}},{{/unless}` before `{{/each}}`
792809

810+
Example with inline body:
811+
812+
```json
813+
{
814+
"request": {
815+
"urlPathPattern": "/listing",
816+
"method": "GET"
817+
},
818+
"response": {
819+
"status": 200,
820+
"body": "[\n{{# each (state context='list' property='list' default='[]') }} {\n \"id\": \"{{id}}\",\n \"firstName\": \"{{firstName}}\",\n \"lastName\": \"{{lastName}}\" }{{#unless @last}},{{/unless}}\n{{/each}}]",
821+
"headers": {
822+
"content-type": "application/json"
823+
}
824+
}
825+
}
826+
```
827+
828+
Example with bodyFileName:
793829

794-
Example:
795830
```json
796831
{
797-
"request" : {
798-
"urlPathPattern" : "/listing",
799-
"method" : "GET"
832+
"request": {
833+
"urlPathPattern": "/listing",
834+
"method": "GET"
800835
},
801-
"response" : {
802-
"status" : 200,
803-
"body" : "[\n{{# each (state context=list property='list' default='[]') }} {\n \"id\": \"{{id}}\",\n \"firstName\": \"{{firstName}}\",\n \"firstName\": \"{{firstName}}\" }{{#unless @last}},{{/unless}}\n{{/each}}]",
804-
"headers" : {
805-
"content-type" : "application/json"
836+
"response": {
837+
"status": 200,
838+
"bodyFileName": "body.json",
839+
"headers": {
840+
"content-type": "application/json"
806841
}
807842
}
808843
}
809844
```
810845

846+
```json
847+
[
848+
{{# each (state context='list' property='list' default='[]') }}
849+
{
850+
"id": {{id}},
851+
"firstName": "{{firstName}}",
852+
"lastName": "{{lastName}}"
853+
}{{#unless @last}},{{/unless}}
854+
{{/each}}
855+
]
856+
```
857+
811858
### Error handling
812859

813860
Missing Helper properties as well as unknown context properties are reported as error. WireMock renders them in the field, itself, so there won't be an
@@ -818,12 +865,13 @@ Example response with error:
818865
```json
819866
{
820867
"id": "kn0ixsaswzrzcfzriytrdupnjnxor1is",
821-
"firstName": "[ERROR: No state for context kn0ixsaswzrzcfzriytrdupnjnxor1is, property firstName found]",
868+
"firstName": "[ERROR: No state for context 'kn0ixsaswzrzcfzriytrdupnjnxor1is', property 'firstName' found]",
822869
"lastName": "Doe"
823870
}
824871
```
825872

826-
To avoid errors, you can specify a `default` for the state helper: `"clientId": "{{state context=request.pathSegments.[1] property='firstname' default='John'}}",`
873+
To avoid errors, you can specify a `default` for the state
874+
helper: `"clientId": "{{state context=request.pathSegments.[1] property='firstname' default='John'}}",`
827875

828876
# Debugging
829877

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": {{randomInt lower=1 upper=10000}},
3+
"title": "{{jsonPath request.body '$.title'}}",
4+
"description": "{{jsonPath request.body '$.description'}}"
5+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[
2+
{{# each (state context='todolist' property='list' default='[]') }}
3+
{
4+
"id": {{id}},
5+
"title": "{{title}}",
6+
"description": "{{description}}"
7+
}{{#unless @last}},{{/unless}}
8+
{{/each}}
9+
]

0 commit comments

Comments
 (0)