Skip to content

Commit

Permalink
Split flows.Environment into AssetsEnvironment and SessionEnvironment
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Aug 15, 2023
1 parent 65d919c commit 5660eb8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 57 deletions.
2 changes: 1 addition & 1 deletion flows/engine/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (s *session) SetType(type_ flows.FlowType) { s.type_ = type_ }

func (s *session) Environment() envs.Environment { return s.env }
func (s *session) SetEnvironment(env envs.Environment) { s.env = env }
func (s *session) MergedEnvironment() envs.Environment { return flows.NewEnvironment(s) }
func (s *session) MergedEnvironment() envs.Environment { return flows.NewSessionEnvironment(s) }

func (s *session) Contact() *flows.Contact { return s.contact }
func (s *session) SetContact(contact *flows.Contact) { s.contact = contact }
Expand Down
108 changes: 59 additions & 49 deletions flows/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,68 +10,26 @@ import (
"golang.org/x/exp/slices"
)

type environment struct {
type assetsEnvironment struct {
envs.Environment

session Session
locationResolver envs.LocationResolver
}

// NewEnvironment creates a new environment from a session's base environment that merges some properties with
// those from the contact, and adds support for location resolving using the session's locations assets.
func NewEnvironment(s Session) envs.Environment {
// NewAssetsEnvironment creates a new environment from a base environment and adds support for location resolving using
// location assets.
func NewAssetsEnvironment(e envs.Environment, la *LocationAssets) envs.Environment {
var locationResolver envs.LocationResolver

hierarchies := s.Assets().Locations().Hierarchies()
hierarchies := la.Hierarchies()
if len(hierarchies) > 0 {
locationResolver = &assetLocationResolver{hierarchies[0]}
}

return &environment{
Environment: s.Environment(),
session: s,
locationResolver: locationResolver,
}
}

func (e *environment) Timezone() *time.Location {
contact := e.session.Contact()

// if we have a contact and they have a timezone that overrides the base enviroment's timezone
if contact != nil && contact.Timezone() != nil {
return contact.Timezone()
}
return e.Environment.Timezone()
}

func (e *environment) DefaultLanguage() envs.Language {
contact := e.session.Contact()

// if we have a contact and they have a language and it's an allowed language that overrides the base environment's languuage
if contact != nil && contact.Language() != envs.NilLanguage && slices.Contains(e.AllowedLanguages(), contact.Language()) {
return contact.Language()
}
return e.Environment.DefaultLanguage()
return &assetsEnvironment{Environment: e, locationResolver: locationResolver}
}

func (e *environment) DefaultCountry() envs.Country {
contact := e.session.Contact()

// if we have a contact and they have a preferred channel with a country that overrides the base environment's country
if contact != nil {
cc := contact.Country()
if cc != envs.NilCountry {
return cc
}
}
return e.Environment.DefaultCountry()
}

func (e *environment) DefaultLocale() envs.Locale {
return envs.NewLocale(e.DefaultLanguage(), e.DefaultCountry())
}

func (e *environment) LocationResolver() envs.LocationResolver {
func (e *assetsEnvironment) LocationResolver() envs.LocationResolver {
return e.locationResolver
}

Expand Down Expand Up @@ -125,3 +83,55 @@ func (r *assetLocationResolver) FindLocationsFuzzy(text string, level envs.Locat
func (r *assetLocationResolver) LookupLocation(path envs.LocationPath) *envs.Location {
return r.locations.FindByPath(path)
}

type sessionEnvironment struct {
envs.Environment

session Session
}

// NewSessionEnvironment creates a new environment from a session's base environment that merges some properties with
// those from the contact.
func NewSessionEnvironment(s Session) envs.Environment {
return &sessionEnvironment{
Environment: NewAssetsEnvironment(s.Environment(), s.Assets().Locations()),
session: s,
}
}

func (e *sessionEnvironment) Timezone() *time.Location {
contact := e.session.Contact()

// if we have a contact and they have a timezone that overrides the base enviroment's timezone
if contact != nil && contact.Timezone() != nil {
return contact.Timezone()
}
return e.Environment.Timezone()
}

func (e *sessionEnvironment) DefaultLanguage() envs.Language {
contact := e.session.Contact()

// if we have a contact and they have a language and it's an allowed language that overrides the base environment's languuage
if contact != nil && contact.Language() != envs.NilLanguage && slices.Contains(e.AllowedLanguages(), contact.Language()) {
return contact.Language()
}
return e.Environment.DefaultLanguage()
}

func (e *sessionEnvironment) DefaultCountry() envs.Country {
contact := e.session.Contact()

// if we have a contact and they have a preferred channel with a country that overrides the base environment's country
if contact != nil {
cc := contact.Country()
if cc != envs.NilCountry {
return cc
}
}
return e.Environment.DefaultCountry()

Check warning on line 132 in flows/environment.go

View check run for this annotation

Codecov / codecov/patch

flows/environment.go#L132

Added line #L132 was not covered by tests
}

func (e *sessionEnvironment) DefaultLocale() envs.Locale {
return envs.NewLocale(e.DefaultLanguage(), e.DefaultCountry())
}
14 changes: 7 additions & 7 deletions flows/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var assetsJSON = `{
]
}`

func TestEnvironmentLocationResolving(t *testing.T) {
func TestAssetsEnvironment(t *testing.T) {
env := envs.NewBuilder().WithDefaultCountry("RW").Build()
source, err := static.NewSource([]byte(assetsJSON))
require.NoError(t, err)
Expand All @@ -82,14 +82,14 @@ func TestEnvironmentLocationResolving(t *testing.T) {
session, _, err := eng.NewSession(sa, trigger)
require.NoError(t, err)

senv := session.MergedEnvironment()
assert.Equal(t, envs.Country("RW"), senv.DefaultCountry())
require.NotNil(t, senv.LocationResolver())
aenv := flows.NewAssetsEnvironment(env, session.Assets().Locations())
assert.Equal(t, envs.Country("RW"), aenv.DefaultCountry())
require.NotNil(t, aenv.LocationResolver())

kigali := senv.LocationResolver().LookupLocation("Rwanda > Kigali City")
kigali := aenv.LocationResolver().LookupLocation("Rwanda > Kigali City")
assert.Equal(t, "Kigali City", kigali.Name())

matches := senv.LocationResolver().FindLocationsFuzzy("gisozi town", flows.LocationLevelWard, nil)
matches := aenv.LocationResolver().FindLocationsFuzzy("gisozi town", flows.LocationLevelWard, nil)
assert.Equal(t, 1, len(matches))
assert.Equal(t, "Gisozi", matches[0].Name())
}
Expand All @@ -107,7 +107,7 @@ const contactJSON = `{
]
}`

func TestEnvironmentMerging(t *testing.T) {
func TestSessionEnvironment(t *testing.T) {
tzRW, _ := time.LoadLocation("Africa/Kigali")
tzEC, _ := time.LoadLocation("America/Guayaquil")
tzUK, _ := time.LoadLocation("Europe/London")
Expand Down

0 comments on commit 5660eb8

Please sign in to comment.