From aba6454364920789f57be3f819890cba31cb7146 Mon Sep 17 00:00:00 2001 From: Eric Wollesen Date: Mon, 22 Jan 2024 15:53:31 -0700 Subject: [PATCH] set ExpiresAt in confirmations that support expiration This field will help the care partner mobile app. BACK-2807 --- models/confirmation.go | 11 +++++---- models/confirmation_test.go | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/models/confirmation.go b/models/confirmation.go index b3426e43f..1377cf543 100644 --- a/models/confirmation.go +++ b/models/confirmation.go @@ -23,6 +23,7 @@ type ( Created time.Time `json:"created" bson:"created"` Modified time.Time `json:"modified" bson:"modified"` Status Status `json:"status" bson:"status"` + ExpiresAt *time.Time `json:"expiresAt,omitempty" bson:"expiresAt,omitempty"` Restrictions *Restrictions `json:"restrictions" bson:"-"` TemplateName TemplateName `json:"-" bson:"templateName"` @@ -110,6 +111,10 @@ func NewConfirmation(theType Type, templateName TemplateName, creatorId string) Created: time.Now(), } + if timeout, ok := Timeouts[theType]; ok { + expiresAt := conf.Created.Add(timeout) + conf.ExpiresAt = &expiresAt + } return conf, nil } } @@ -232,12 +237,10 @@ func (c *Confirmation) ValidateType(expectedType Type, validationErrors *[]error } func (c *Confirmation) IsExpired() bool { - timeout, ok := Timeouts[c.Type] - if !ok { + if c.ExpiresAt == nil || c.ExpiresAt.IsZero() { return false } - - return time.Now().After(c.Created.Add(timeout)) + return time.Now().After(*c.ExpiresAt) } func (c *Confirmation) ResetKey() error { diff --git a/models/confirmation_test.go b/models/confirmation_test.go index e6629ba78..afa08bc6c 100644 --- a/models/confirmation_test.go +++ b/models/confirmation_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "testing" + "time" ) const ( @@ -67,6 +68,10 @@ func Test_NewConfirmation(t *testing.T) { t.Fail() } + if confirmation.ExpiresAt.IsZero() { + t.Errorf("expected expiresAt to be non-Zero") + } + confirmation.UpdateStatus(StatusCompleted) if confirmation.Status != StatusCompleted { @@ -229,6 +234,47 @@ func TestConfirmationContextCustomUnmarshaler(s *testing.T) { }) } +func TestConfirmationCalculatesExpiresAt(t *testing.T) { + for cType := range Timeouts { + invite, err := NewConfirmation(cType, TemplateNamePasswordReset, USERID) + if err != nil { + t.Fatalf("expected nil, got %+v", err) + } + if invite.ExpiresAt == nil || invite.ExpiresAt.IsZero() { + t.Errorf("expected non-Zero ExiresAt") + } + } +} + +func TestConfirmationIsExpired(t *testing.T) { + for cType := range Timeouts { + invite, err := NewConfirmation(cType, TemplateNameCareteamInvite, USERID) + if err != nil { + t.Fatalf("expected nil error, got %s", err) + } + if invite.IsExpired() { + t.Errorf("expected false, got true") + } + *invite.ExpiresAt = time.Unix(0, 0) + if !invite.IsExpired() { + t.Errorf("expected true, got false") + } + } + + // These types don't have timeouts, so don't get an expires at. They're + // never expired. + for _, cType := range []Type{TypeClinicianInvite, TypeNoAccount} { + nonExpiringInviting, err := NewConfirmation(cType, TemplateNameCareteamInvite, USERID) + if err != nil { + t.Fatalf("expected nil error, got %s", err) + } + if nonExpiringInviting.IsExpired() { + t.Errorf("expected invitation type %q to never expire", cType) + } + } + +} + // buff is a helper for generating a JSON []byte representation. func buff(format string, args ...interface{}) *bytes.Buffer { return bytes.NewBufferString(fmt.Sprintf(format, args...))