Skip to content

Commit

Permalink
Merge pull request #4 from istresearch/develop
Browse files Browse the repository at this point in the history
v0.94.2-1 Release
  • Loading branch information
jeremyist authored Nov 9, 2020
2 parents 48934d7 + f4b3265 commit 8a4f4ce
Show file tree
Hide file tree
Showing 319 changed files with 25,353 additions and 2,417 deletions.
41 changes: 41 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
version: 2
jobs:
tests:
docker:
- image: circleci/golang:1.13
auth:
username: $DOCKER_USER
password: $DOCKER_PASS

parallelism: 1

environment: # environment variables for the build itself
TEST_RESULTS: /tmp/test-results # path to where test results will be saved

steps: # steps that comprise the `build` job
- checkout # check out source code to working directory
- run: mkdir -p $TEST_RESULTS # create the test results directory
- run: sudo apt -y update && sudo apt -y install pandoc gettext

- run:
name: Run unit tests

environment:
GOFLAGS: -p=2

# store the results of our tests in the $TEST_RESULTS directory
command: |
PACKAGE_NAMES=$(go list ./... | circleci tests split --split-by=timings --timings-type=classname)
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES
- store_artifacts: # upload test summary for display in Artifacts
path: /tmp/test-results
destination: raw-test-output

- store_test_results: # upload test results for display in Test Summary
path: /tmp/test-results
workflows:
version: 2
run-tests:
jobs:
- tests
125 changes: 125 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,128 @@
v0.94.2
----------
* Use jsonx.Marshal consistently

v0.94.1
----------
* Add IsQueryError util

v0.94.0
----------
* Move all location stuff from utils to envs
* Simplify resolving locations from environments
* Refactor field modifiers to take raw values and location parsing to not require a session

v0.93.1
----------
* Fix clearing all URNs

v0.93.0
----------
* Add urns modifier to replace all the URNs on a contact

v0.92.0
----------
* Move elastic functionality from mailroom

v0.91.1
----------
* Fix clearing of fields

v0.91.0
----------
* Move generic PO stuff into utils/i18n

v0.90.0
----------
* Allow querying contacts by UUID
* Move i18n package under flows to avoid confusion with locales package
* Add completion to localized documentation

v0.89.0
----------
* Tweak change language functionality to allow missing translations
* Add country to template translations and use when resolving templates

v0.88.0
----------
* Add support for localized documentation

v0.87.0
----------
* Disallow opening tickets, starting sessions and sending broadcasts when doing batch start
* Add ability to change the language of a flow
* Update our format_datetime docs to properly show range of 01-24
* Fix evaluation of legacy vars in other-contacts actions

v0.86.2
----------
* Fix spelling of Readact

v0.86.1
----------
* Do redaction of access keys from HTTP logs

v0.86.0
----------
* Add open_ticket actions and ticket_opened events

v0.85.0
----------
* Add new service_called event to be used for classifiers and ticketers etc

v0.84.0
----------
* Replace contact blocked and stopped fields with status field
* Rename blocked and stopped modifiers to contact status modifier

v0.83.1
----------
* Fix anywhere we truncate strings to do it by rune

v0.83.0
----------
* Add blocked and stopped modifiers and events
* Add blocked and stopped fields to contact

v0.82.0
----------
* Fix default to understand objects with defaults

v0.81.0
----------
* Rework httpx to replace NewTrace with NewRequest+DoTrace
* Separate out the header part of response traces from the body which won't always be valid UTF-8

v0.80.0
----------
* ivr_created events should include language of translated text

v0.79.1
----------
* Include 3-char language code as extra header in PO files

v0.79.0
----------
* Add custom Source-Flows header to exported PO files
* Make router categories inspectable
* Importing of translations into flows

v0.78.1
----------
* Add decode_html Excellent function
* Start of i18n work
* Prevent XText.Slice from panicking

v0.78.0
----------
* Add support for extracting the "base" translation of a flow
* Allow queries on URNs to check if they are set or not
* Add Language.ToISO639_2()
* Make flowrunner easier to use by defaulting to first flow in the assets
* Default to current version in flowmigrate cmd
* Rework group asset loading so that parsing is not deferred
* Override environment country if contact has preferred channel with country

v0.77.4
----------
* Fix loading flow assets that are new spec but also have metadata section
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Specification

See https://nyaruka.github.io/goflow/ for the complete specification docs.
See [here](https://nyaruka.github.io/goflow/en_US/) for the complete specification docs.

## Basic Usage

Expand All @@ -14,11 +14,11 @@ import (
"github.com/nyaruka/goflow/utils"
)

env := envs.NewBuilder().Build()
source, _ := static.LoadSource("myassets.json")
assets, _ := engine.NewSessionAssets(source, nil)
assets, _ := engine.NewSessionAssets(env, source, nil)
contact := flows.NewContact(assets, ...)
env := envs.NewBuilder().Build()
trigger := triggers.NewManual(env, contact, flow.Reference(), nil, nil, time.Now())
trigger := triggers.NewManual(env, contact, flow.Reference(), nil, false, nil, time.Now())
eng := engine.NewBuilder().Build()
session, sprint, err := eng.NewSession(assets, trigger)
```
Expand Down
26 changes: 23 additions & 3 deletions assets/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"

"github.com/nyaruka/goflow/envs"
"github.com/nyaruka/goflow/utils"
"github.com/nyaruka/goflow/utils/uuids"
)

Expand Down Expand Up @@ -206,8 +205,8 @@ type Label interface {
//
// @asset location
type LocationHierarchy interface {
FindByPath(path utils.LocationPath) *utils.Location
FindByName(name string, level utils.LocationLevel, parent *utils.Location) []*utils.Location
FindByPath(path envs.LocationPath) *envs.Location
FindByName(name string, level envs.LocationLevel, parent *envs.Location) []*envs.Location
}

// Resthook is a set of URLs which are subscribed to the named event.
Expand All @@ -225,6 +224,7 @@ type Resthook interface {
Subscribers() []string
}

// TemplateUUID is the UUID of a template
type TemplateUUID uuids.UUID

// Template is a message template, currently only used by WhatsApp channels
Expand Down Expand Up @@ -263,10 +263,29 @@ type Template interface {
type TemplateTranslation interface {
Content() string
Language() envs.Language
Country() envs.Country
VariableCount() int
Channel() ChannelReference
}

// TicketerUUID is the UUID of a ticketer
type TicketerUUID uuids.UUID

// Ticketer is a system which can open or close tickets
//
// {
// "uuid": "37657cf7-5eab-4286-9cb0-bbf270587bad",
// "name": "Support Tickets",
// "type": "mailgun"
// }
//
// @asset ticketer
type Ticketer interface {
UUID() TicketerUUID
Name() string
Type() string
}

// Source is a source of assets
type Source interface {
Channels() ([]Channel, error)
Expand All @@ -279,4 +298,5 @@ type Source interface {
Locations() ([]LocationHierarchy, error)
Resthooks() ([]Resthook, error)
Templates() ([]Template, error)
Ticketers() ([]Ticketer, error)
}
37 changes: 37 additions & 0 deletions assets/references.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,43 @@ func (r *TemplateReference) Variable() bool {

var _ UUIDReference = (*TemplateReference)(nil)

// TicketerReference is used to reference a ticketer
type TicketerReference struct {
UUID TicketerUUID `json:"uuid" validate:"required,uuid"`
Name string `json:"name"`
}

// NewTicketerReference creates a new classifier reference with the given UUID and name
func NewTicketerReference(uuid TicketerUUID, name string) *TicketerReference {
return &TicketerReference{UUID: uuid, Name: name}
}

// Type returns the name of the asset type
func (r *TicketerReference) Type() string {
return "ticketer"
}

// GenericUUID returns the untyped UUID
func (r *TicketerReference) GenericUUID() uuids.UUID {
return uuids.UUID(r.UUID)
}

// Identity returns the unique identity of the asset
func (r *TicketerReference) Identity() string {
return string(r.UUID)
}

// Variable returns whether this a variable (vs concrete) reference
func (r *TicketerReference) Variable() bool {
return false
}

func (r *TicketerReference) String() string {
return fmt.Sprintf("%s[uuid=%s,name=%s]", r.Type(), r.Identity(), r.Name)
}

var _ UUIDReference = (*TicketerReference)(nil)

//------------------------------------------------------------------------------------------
// Callbacks for missing assets
//------------------------------------------------------------------------------------------
Expand Down
19 changes: 19 additions & 0 deletions assets/references_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "61602f3e-f603-4c70-8a8f-c477505bf4bf", channelRef.Identity())
assert.Equal(t, uuids.UUID("61602f3e-f603-4c70-8a8f-c477505bf4bf"), channelRef.GenericUUID())
assert.Equal(t, "channel[uuid=61602f3e-f603-4c70-8a8f-c477505bf4bf,name=Nexmo]", channelRef.String())
assert.False(t, channelRef.Variable())
assert.NoError(t, utils.Validate(channelRef))

// channel references must always be concrete
Expand All @@ -27,6 +28,7 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "61602f3e-f603-4c70-8a8f-c477505bf4bf", classifierRef.Identity())
assert.Equal(t, uuids.UUID("61602f3e-f603-4c70-8a8f-c477505bf4bf"), classifierRef.GenericUUID())
assert.Equal(t, "classifier[uuid=61602f3e-f603-4c70-8a8f-c477505bf4bf,name=Booking]", classifierRef.String())
assert.False(t, classifierRef.Variable())
assert.NoError(t, utils.Validate(classifierRef))

// classifier references must always be concrete
Expand All @@ -36,6 +38,7 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "field", fieldRef.Type())
assert.Equal(t, "gender", fieldRef.Identity())
assert.Equal(t, "field[key=gender,name=Gender]", fieldRef.String())
assert.False(t, fieldRef.Variable())
assert.NoError(t, utils.Validate(fieldRef))

// field references must have a key
Expand All @@ -46,6 +49,7 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "61602f3e-f603-4c70-8a8f-c477505bf4bf", flowRef.Identity())
assert.Equal(t, uuids.UUID("61602f3e-f603-4c70-8a8f-c477505bf4bf"), flowRef.GenericUUID())
assert.Equal(t, "flow[uuid=61602f3e-f603-4c70-8a8f-c477505bf4bf,name=Registration]", flowRef.String())
assert.False(t, flowRef.Variable())
assert.NoError(t, utils.Validate(flowRef))

// flow references must always be concrete
Expand All @@ -55,6 +59,7 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "global", globalRef.Type())
assert.Equal(t, "org_name", globalRef.Identity())
assert.Equal(t, "global[key=org_name,name=Org Name]", globalRef.String())
assert.False(t, globalRef.Variable())
assert.NoError(t, utils.Validate(globalRef))

// global references must have a key
Expand All @@ -65,6 +70,7 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "61602f3e-f603-4c70-8a8f-c477505bf4bf", groupRef.Identity())
assert.Equal(t, uuids.UUID("61602f3e-f603-4c70-8a8f-c477505bf4bf"), groupRef.GenericUUID())
assert.Equal(t, "group[uuid=61602f3e-f603-4c70-8a8f-c477505bf4bf,name=Testers]", groupRef.String())
assert.False(t, groupRef.Variable())
assert.NoError(t, utils.Validate(groupRef))

// group references can be concrete or a name match template
Expand All @@ -87,6 +93,7 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "61602f3e-f603-4c70-8a8f-c477505bf4bf", labelRef.Identity())
assert.Equal(t, uuids.UUID("61602f3e-f603-4c70-8a8f-c477505bf4bf"), labelRef.GenericUUID())
assert.Equal(t, "label[uuid=61602f3e-f603-4c70-8a8f-c477505bf4bf,name=Spam]", labelRef.String())
assert.False(t, labelRef.Variable())
assert.NoError(t, utils.Validate(labelRef))

// label references can be concrete or a name match template
Expand All @@ -107,7 +114,19 @@ func TestReferences(t *testing.T) {
assert.Equal(t, "61602f3e-f603-4c70-8a8f-c477505bf4bf", templateRef.Identity())
assert.Equal(t, uuids.UUID("61602f3e-f603-4c70-8a8f-c477505bf4bf"), templateRef.GenericUUID())
assert.Equal(t, "template[uuid=61602f3e-f603-4c70-8a8f-c477505bf4bf,name=Affirmation]", templateRef.String())
assert.False(t, templateRef.Variable())
assert.NoError(t, utils.Validate(templateRef))

ticketerRef := assets.NewTicketerReference("61602f3e-f603-4c70-8a8f-c477505bf4bf", "Support Tickets")
assert.Equal(t, "ticketer", ticketerRef.Type())
assert.Equal(t, "61602f3e-f603-4c70-8a8f-c477505bf4bf", ticketerRef.Identity())
assert.Equal(t, uuids.UUID("61602f3e-f603-4c70-8a8f-c477505bf4bf"), ticketerRef.GenericUUID())
assert.Equal(t, "ticketer[uuid=61602f3e-f603-4c70-8a8f-c477505bf4bf,name=Support Tickets]", ticketerRef.String())
assert.False(t, ticketerRef.Variable())
assert.NoError(t, utils.Validate(ticketerRef))

// ticketer references must always be concrete
assert.EqualError(t, utils.Validate(assets.NewTicketerReference("", "Booking")), "field 'uuid' is required")
}

func TestChannelReferenceUnmarsal(t *testing.T) {
Expand Down
Loading

0 comments on commit 8a4f4ce

Please sign in to comment.