Skip to content

Commit db35e18

Browse files
committed
Added tutorial 5 'quote'.
Added patterns for testing the current state. Improved and added other testing patterns.
1 parent 38f6db8 commit db35e18

20 files changed

+529
-31
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
yarn.lock
66

77
/lib
8+
/test.ts

.prettierrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "all",
4+
"printWidth": 120
5+
}

features/05-quote/01-request.feature

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
Feature: The customer fill out the form to request a quote
2+
3+
Background:
4+
Given the process is created from the "quote" scenario
5+
And "Alice" is the "customer" actor
6+
And "Bob" is the "sales" actor
7+
8+
Scenario: Customer fills out all fields correctly
9+
When "Alice" does "request" with:
10+
| company | Acme Inc |
11+
| contact | Alice |
12+
| email | alice@example.com |
13+
| address | 123 Main St |
14+
| requirements | The product should be able to do X, Y and Z |
15+
Then the last event is not skipped
16+
And actor "customer" has "company" is "Acme Inc"
17+
* actor "customer" has "contact" is "Alice"
18+
* actor "customer" has "email" is "[email protected]"
19+
* actor "customer" has "address" is "123 Main St"
20+
And the process is in "requested"
21+
And actor "customer" has instructions "Thank you for your request. We will get back to you shortly."
22+
And actor "sales" has instructions:
23+
"""
24+
Please create a quote based on the customer requirements:
25+
The product should be able to do X, Y and Z
26+
"""
27+
28+
Scenario: Customer does not fill out her email address
29+
When "Alice" does "request" with:
30+
| company | Acme Inc |
31+
| contact | Alice |
32+
| requirements | The product should be able to do X, Y and Z |
33+
Then the last event is skipped with "Response is invalid: data must have required property 'email'"
34+
And the process is in "initial"

features/05-quote/02-response.feature

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
Feature: The sales department creates a quote
2+
3+
Background:
4+
Given the process is created from the "quote" scenario
5+
And "Alice" is the "customer" actor
6+
And "Bob" is the "sales" actor
7+
8+
When "Alice" does "request" with:
9+
| company | Acme Inc |
10+
| contact | Alice |
11+
| email | alice@example.com |
12+
| address | 123 Main St |
13+
| requirements | The product should be able to do X, Y and Z |
14+
Then the process is in "requested"
15+
16+
Scenario: Sales creates a quote
17+
When "Bob" does "create_quote" with "cms:quotes/test.pdf"
18+
Then the last event is not skipped
19+
And the process is in "quoted"
20+
And the result is "cms:quotes/test.pdf"
21+
And service "email" is notified with:
22+
"""yaml
23+
$schema: schema:messages/email-v1
24+
to:
25+
name: Alice
26+
27+
template: quote
28+
data:
29+
customer:
30+
title: Customer
31+
id: !ref actors.customer.id
32+
company: Acme Inc
33+
contact: Alice
34+
35+
address: 123 Main St
36+
generate_token: !ref actors.customer.id
37+
attachments:
38+
-
39+
filename: quote.pdf
40+
file: cms:quotes/test.pdf
41+
"""
42+
43+
Scenario: Sales cancels the process
44+
When "Bob" does "cancel" with:
45+
| reason | Unable to deliver on requirements |
46+
Then the last event is not skipped
47+
And the process ended in "cancelled"
48+
And the state description is:
49+
"""
50+
The quote request has been cancelled.
51+
Reason: Unable to deliver on requirements
52+
"""
53+
And service "email" is notified with:
54+
"""yaml
55+
$schema: schema:messages/email-v1
56+
to:
57+
name: Alice
58+
59+
template: no-quote
60+
data:
61+
customer:
62+
title: Customer
63+
id: !ref actors.customer.id
64+
company: Acme Inc
65+
contact: Alice
66+
67+
address: 123 Main St
68+
reason: Unable to deliver on requirements
69+
"""
70+
71+
Scenario: Customer cancels the process
72+
When "Alice" does "cancel" with:
73+
| reason | No longer interested |
74+
Then the last event is not skipped
75+
And the process ended in "cancelled"
76+
And the state description is:
77+
"""
78+
The quote request has been cancelled.
79+
Reason: No longer interested
80+
"""
81+
And service "email" is not notified
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Feature: The customer accepts or rejects the quote
2+
3+
Background:
4+
Given the process is created from the "quote" scenario
5+
And "Alice" is the "customer" actor
6+
And "Bob" is the "sales" actor
7+
8+
When "Alice" does "request" with:
9+
| company | Acme Inc |
10+
| contact | Alice |
11+
| email | alice@example.com |
12+
| address | 123 Main St |
13+
| requirements | The product should be able to do X, Y and Z |
14+
Then the process is in "requested"
15+
16+
When "Bob" does "create_quote" with "cms:quotes/test.pdf"
17+
Then the process is in "quoted"
18+
19+
Scenario: Customer accepts the quote
20+
When "Alice" does "accept"
21+
Then the last event is not skipped
22+
And the process ended in "accepted"
23+
24+
Scenario: Customer rejects the quote
25+
When "Alice" does "reject"
26+
Then the last event is not skipped
27+
And the process ended in "rejected"

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
},
1010
"dependencies": {
1111
"@cucumber/cucumber": "^11.2.0",
12-
"@letsflow/core": "^1.2.3",
12+
"@letsflow/core": "^1.3.3",
13+
"better-ajv-errors": "^1.2.0",
1314
"chai": "^4.3.7",
1415
"get-value": "^3.0.1",
1516
"ts-node": "^10.9.2"

scenarios/quote.yaml

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: quote
2+
version: '1.0'
3+
title: Quote
4+
description: Send a quote based on customer requirements
5+
6+
actors:
7+
sales:
8+
title: Organisation
9+
role: sales
10+
properties:
11+
name: !default 'Acme Inc.'
12+
customer:
13+
title: Customer
14+
properties:
15+
id: !format uuid
16+
company: string
17+
address: string
18+
contact: string
19+
email: string
20+
21+
actions:
22+
request:
23+
$schema: schema:actions/form-v1
24+
actor: customer
25+
response:
26+
properties:
27+
company: !required string
28+
contact: string
29+
email: !required
30+
type: string
31+
format: email
32+
address: string
33+
requirements: !required string
34+
ui:
35+
company:
36+
ui:description: Company name
37+
contact:
38+
ui:description: First and last name
39+
address:
40+
ui:widget: textarea
41+
ui:rows: 3
42+
requirements:
43+
ui:widget: textarea
44+
ui:rows: 5
45+
update:
46+
- set: actors.customer
47+
value: !ref "current.response | { id: uuid('customer', $.id), company: company, address: address, contact: contact, email: email }"
48+
mode: merge
49+
- set: vars.requirements
50+
value: !ref current.response.requirements
51+
create_quote:
52+
$schema: schema:actions/draft-v1
53+
actor: sales
54+
title: Create a quote
55+
description: Create a quote based on customer requirements
56+
template: quote
57+
data:
58+
customer: !ref actors.customer
59+
update: result
60+
cancel:
61+
$schema: schema:actions/form-v1
62+
title: Cancel
63+
description: Cancel the quote request
64+
response:
65+
properties:
66+
reason: !required string
67+
ui:
68+
reason:
69+
ui:widget: textarea
70+
ui:rows: 3
71+
update:
72+
- set: vars.cancel_reason
73+
value: !ref current.response.reason
74+
75+
states:
76+
initial:
77+
on: request
78+
goto: requested
79+
requested:
80+
instructions:
81+
customer: !tpl |
82+
Thank you for your request. We will get back to you shortly.
83+
sales: !tpl |
84+
Please create a quote based on the customer requirements:
85+
{{ vars.requirements }}
86+
transitions:
87+
- on: create_quote
88+
goto: quoted
89+
- on: cancel
90+
goto: (cancelled)
91+
quoted:
92+
notify:
93+
service: email
94+
message:
95+
$schema: schema:messages/email-v1
96+
to: !ref 'actors.customer | { name: contact, email: email }'
97+
template: quote
98+
generate_token: !ref actors.customer.id
99+
data:
100+
customer: !ref actors.customer
101+
attachments:
102+
- filename: quote.pdf
103+
file: !ref result
104+
transitions:
105+
- on: accept
106+
goto: (accepted)
107+
- on: reject
108+
goto: (rejected)
109+
- after: 10 days
110+
goto: (rejected)
111+
(cancelled):
112+
description: !tpl |
113+
The quote request has been cancelled.
114+
Reason: {{ vars.cancel_reason }}
115+
notify:
116+
service: email
117+
if: !ref previous[-1].actor.key == 'sales'
118+
message:
119+
$schema: schema:messages/email-v1
120+
to: !ref 'actors.customer | { name: contact, email: email }'
121+
template: no-quote
122+
data:
123+
customer: !ref actors.customer
124+
reason: !ref vars.cancel_reason
125+
126+
vars:
127+
requirements: string
128+
cancel_reason: string
129+
130+
result: !format uri

schemas/actions/draft-v1.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
$id: schema:actions/draft-v1
2+
description: |
3+
Create a document based on a template.
4+
This action can be automated through a document generation service or performed manually by an actor
5+
allOf:
6+
- $ref: https://schemas.letsflow.io/v1.0/action
7+
properties:
8+
template: !required string
9+
filetype: !default pdf
10+
data:
11+
description: |
12+
Data to be used to populate the template.
13+
When the action is performed by an actor, this is the default data.
14+
type: object
15+
additionalProperties: true

schemas/actions/form-v1.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
$id: schema:actions/form-v1
2+
description: Show a form using react-jsonschema-form for the user to fill out
3+
allOf:
4+
- $ref: https://schemas.letsflow.io/v1.0/action
5+
properties:
6+
ui:
7+
additionalProperties: object
8+
required:
9+
- response

schemas/messages/email-v1.yaml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
$id: schema:messages/email-v1
2+
description: Send an email based on a template using the email service
3+
allOf:
4+
- $ref: https://schemas.letsflow.io/v1.0/action
5+
properties:
6+
to: !required
7+
properties:
8+
name: string
9+
email: !required
10+
type: string
11+
format: email
12+
template: !required string
13+
generate_token: string
14+
data:
15+
type: object
16+
additionalProperties: true
17+
attachments:
18+
items:
19+
properties:
20+
filename: string
21+
source: !required string

0 commit comments

Comments
 (0)