LetsFlow
Search
⌃K

A proper introduction

Use response data and data instructions.
In the previous tutorial two actors greeted each other and could have a small conversation. In this tutorial we have a similar premise. The initiator is now at a conference, where he strikes a conversation introducing himself.
Create a new subdirectory named introduction.
To keep it simple we're not modeling all kind of different responses in this tutorial. For that take a look at the "A handshake" tutorial.

Introduce yourself

Joe, the initiator, will introduce himself stating his name and organization. Jane will respond by introducing herself also stating her name and organization.
Feature: Two actors meet at a conference and exchange information.
Background:
Given a chain is created by "Joe"
Given "Joe" creates the "main" process using the "introduction" scenario
And "Joe" is the "initiator" actor of the "main" process
And "Jane" is the "recipient" actor of the "main" process
Scenario:
When "Joe" runs the "introduce_initiator" action of the "main" process with:
| name | Joe Smith |
| organization | LTO Network |
Then the "main" process is in the "wait_on_recipient" state
When "Jane" runs the "introduce_recipient" action of the "main" process with:
| name | Jane Wong |
| organization | Acme Inc |
Then the "main" process is completed

The basic scenario

YAML
JSON
$schema: "https://specs.letsflow.io/v0.2.0/scenario/schema.json#"
title: A proper introduction
actors:
initiator:
title: Initiator
recipient:
title: Recipient
actions:
introduce_initiator:
title: Greet the person you're meeting
actor: initiator
introduce_recipient:
title: Reply to the initiator
actor: recipient
states:
initial:
action: introduce_initiator
transition: wait_on_recipient
wait_on_recipient:
action: introduce_recipient
transition: :success
{
"$schema": "https://specs.letsflow.io/v0.2.0/scenario/schema.json#",
"title": "A proper introduction",
"actors": {
"initiator": {
"title": "Initiator"
},
"recipient": {
"title": "Recipient"
}
},
"actions": {
"introduce_initiator": {
"actor": "initiator"
},
"introduce_recipient": {
"actor": "recipient"
}
},
"states": {
"initial": {
"action": "introduce_initiator",
"transition": "wait_on_recipient"
},
"wait_on_recipient": {
"action": "introduce_recipient",
"transition": ":success"
}
}
}

Using response data

Defining the actors

The process is gathering information about both actors. We need to define the properties that the actors will have.
We define the actors in the scenario using JSON schema. In the instantiated process these will become objects with the specified properties.
YAML
JSON
$schema: "https://specs.letsflow.io/v0.2.0/scenario/schema.json#"
title: A proper introduction
actors:
initiator:
$schema: "http://json-schema.org/schema#"
title: Initiator
type: object
properties:
name:
type: string
organization:
type: string
recipient:
$schema: "http://json-schema.org/schema#"
title: Recipient
type: object
properties:
name:
type: string
organization:
type: string
{
"actors": {
"initiator": {
"$schema": "http://json-schema.org/schema#",
"title": "Initiator",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"organization": {
"type": "string"
}
}
},
"recipient": {
"$schema": "http://json-schema.org/schema#",
"title": "Recipient",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"organization": {
"type": "string"
}
}
}
}
}
The JSON schema for actors can become quite big. It that case, it's recommended to store it in a separate JSON file and use $ref with a URL to the file.

Testing the actor properties

In the test, we want to see that the actors are assigned the correct properties after introducing themselves.
Feature: Two actors meet at a conference and exchange information.
Background:
Given a chain is created by "Joe"
Given "Joe" creates the "main" process using the "introduction" scenario
And "Joe" is the "initiator" actor of the "main" process
And "Jane" is the "recipient" actor of the "main" process
Scenario:
When "Joe" runs the "introduce_initiator" action of the "main" process with:
| name | Joe Smith |
| organization | LTO Network |
Then the "initiator" actor of the "main" process has:
| name | Joe Smith |
| organization | LTO Network |
And the "main" process is in the "wait_on_recipient" state
When "Jane" runs the "introduce_recipient" action of the "main" process with:
| name | Jane Wong |
| organization | Acme Inc |
Then the "recipient" actor of the "main" process has:
| name | Jane Wong |
| organization | Acme Inc |
And the "main" process is completed

Update instructions

The process doesn't automatically update the actor information. We need to supply update instructions for each action.
Adding an update property to an action or response will update the selected object with the data that's send by the client.
YAML
JSON
$schema: "https://specs.letsflow.io/v0.2.0/scenario/schema.json#"
title: A proper introduction
actors:
initiator:
$schema: "http://json-schema.org/schema#"
title: Initiator
type: object
properties:
name:
type: string
organization:
type: string
recipient:
$schema: "http://json-schema.org/schema#"
title: Recipient
type: object
properties:
name:
type: string
organization:
type: string
actions:
introduce_initiator:
title: Greet the person you're meeting
actor: initiator
update: actors.initiator
introduce_recipient:
title: Reply to the initiator
actor: recipient
update: actors.recipient
states:
initial:
action: introduce_initiator
transition: wait_on_recipient
wait_on_recipient:
action: introduce_recipient
transition: :success
{
"$schema": "https://specs.letsflow.io/v0.2.0/scenario/schema.json#",
"title": "A proper introduction",
"actors": {
"initiator": {
"$schema": "http://json-schema.org/schema#",
"title": "Initiator",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"organization": {
"type": "string"
}
}
},
"recipient": {
"$schema": "http://json-schema.org/schema#",
"title": "Recipient",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"organization": {
"type": "string"
}
}
}
},
"actions": {
"introduce_initiator": {
"title": "Greet the person you're meeting",
"actor": "initiator",
"update": "actors.initiator"
},
"introduce_recipient": {
"title": "Reply to the initiator",
"actor": "recipient",
"update": "actors.recipient"
}
},
"states": {
"initial": {
"action": "introduce_initiator",
"transition": "wait_on_recipient"
},
"wait_on_recipient": {
"action": "introduce_recipient",
"transition": ":success"
}
}
}

Using the actor's name

Once we know the name of the actor, we can use it in the process. Rather than saying "Reply to the initiator", we could say "Reply to Joe Smith".
The <tpl> data instruction parses a mustache template, injecting process data.
YAML
JSON
introduce_recipient:
title: !tpl Reply to {{ actors.initiator }}
actor: recipient
update: actors.recipient
"introduce_recipient": {
"title": {
"<tpl>": "Reply to {{ actors.initiator }}"
},
"actor": "initiator",
"update": "actors.initiator"
}

Now you!

We only get the name and organization of the recipient. To contact her, we'd also like to know her e-mail address.
In the process, she won't give it while introducing herself. Instead the initiator may ask the information after the introduction. If he doesn't ask, the conversation is over.
To keep it simple, we'll assume she's always willing to give her e-mail address.
  1. 1.
    EditScenario section of the main.feature test file. The process isn't completed after the introduction. Instead it's in the wait on initiator state. The initiator will give run the complete action to finish the process.
  2. 2.
    Add a second Scenario section. The first steps are the same as the original Scenario. On wait on initiator, the initiator will ask for email.
  3. 3.
    The recipient will reply on email the request with her e-mail address. Her address is added to the actor information. This will complete the process.
  4. 4.
    Modify the scenario so the new test succeeds.

More data next

Process data can be utilized for much more than just being displayed in titles and instructions. In the upcoming tutorials we'll see how data can alter the flow using conditions and how it can be used when communicating with externals system.