diff options
Diffstat (limited to 'app/domain')
| -rw-r--r-- | app/domain/entity.go | 7 | ||||
| -rw-r--r-- | app/domain/id.go | 7 | ||||
| -rw-r--r-- | app/domain/repository.go | 7 | ||||
| -rw-r--r-- | app/domain/sparkle.go | 60 | ||||
| -rw-r--r-- | app/domain/sparkle_test.go | 51 | ||||
| -rw-r--r-- | app/domain/user.go | 34 | ||||
| -rw-r--r-- | app/domain/user_test.go | 24 |
7 files changed, 190 insertions, 0 deletions
diff --git a/app/domain/entity.go b/app/domain/entity.go new file mode 100644 index 0000000..fb1cab8 --- /dev/null +++ b/app/domain/entity.go @@ -0,0 +1,7 @@ +package domain + +type Entity interface { + GetID() ID + SetID(id ID) error + Validate() error +} diff --git a/app/domain/id.go b/app/domain/id.go new file mode 100644 index 0000000..117a9ad --- /dev/null +++ b/app/domain/id.go @@ -0,0 +1,7 @@ +package domain + +type ID string + +func (id ID) String() string { + return string(id) +} diff --git a/app/domain/repository.go b/app/domain/repository.go new file mode 100644 index 0000000..fb7b6da --- /dev/null +++ b/app/domain/repository.go @@ -0,0 +1,7 @@ +package domain + +type Repository[T Entity] interface { + All() []T + Find(ID) T + Save(T) error +} diff --git a/app/domain/sparkle.go b/app/domain/sparkle.go new file mode 100644 index 0000000..68aed67 --- /dev/null +++ b/app/domain/sparkle.go @@ -0,0 +1,60 @@ +package domain + +import ( + "errors" + "regexp" + + "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/pls" +) + +type Sparkle struct { + ID ID `json:"id" jsonapi:"primary,sparkles"` + Sparklee string `json:"sparklee" jsonapi:"attr,sparklee"` + Author *User `json:"author" jsonapi:"attr,author"` + Reason string `json:"reason" jsonapi:"attr,reason"` +} + +var SparkleRegex = regexp.MustCompile(`\A\s*(?P<sparklee>@\w+)\s+(?P<reason>.+)\z`) +var SparkleeIndex = SparkleRegex.SubexpIndex("sparklee") +var ReasonIndex = SparkleRegex.SubexpIndex("reason") + +var ReasonIsRequired = errors.New("Reason is required") +var SparkleIsEmpty = errors.New("Sparkle is empty") +var SparkleIsInvalid = errors.New("Sparkle is invalid") +var SparkleeIsRequired = errors.New("Sparklee is required") + +func NewSparkle(text string) (*Sparkle, error) { + if len(text) == 0 { + return nil, SparkleIsEmpty + } + + matches := SparkleRegex.FindStringSubmatch(text) + if len(matches) == 0 { + return nil, SparkleIsInvalid + } + + return &Sparkle{ + ID: ID(pls.GenerateULID()), + Sparklee: matches[SparkleeIndex], + Reason: matches[ReasonIndex], + }, nil +} + +func (s *Sparkle) GetID() ID { + return s.ID +} + +func (s *Sparkle) SetID(id ID) error { + s.ID = id + return nil +} + +func (s *Sparkle) Validate() error { + if s.Sparklee == "" { + return SparkleeIsRequired + } + if s.Reason == "" { + return ReasonIsRequired + } + return nil +} diff --git a/app/domain/sparkle_test.go b/app/domain/sparkle_test.go new file mode 100644 index 0000000..8d81afd --- /dev/null +++ b/app/domain/sparkle_test.go @@ -0,0 +1,51 @@ +package domain + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSparkle(t *testing.T) { + t.Run("NewSparkle", func(t *testing.T) { + t.Run("with a valid body", func(t *testing.T) { + sparkle, err := NewSparkle("@tanuki for helping me with my homework!") + + assert.Nil(t, err) + if err != nil { + assert.Equal(t, "@tanuki", sparkle.Sparklee) + assert.Equal(t, "for helping me with my homework!", sparkle.Reason) + } + }) + + t.Run("with an empty body", func(t *testing.T) { + sparkle, err := NewSparkle("") + + assert.Nil(t, sparkle) + assert.NotNil(t, err) + if err != nil { + assert.Equal(t, "Sparkle is empty", err.Error()) + } + }) + + t.Run("without a reason", func(t *testing.T) { + sparkle, err := NewSparkle("@tanuki") + + assert.Nil(t, sparkle) + assert.NotNil(t, err) + if err != nil { + assert.Equal(t, "Sparkle is invalid", err.Error()) + } + }) + + t.Run("without a username", func(t *testing.T) { + sparkle, err := NewSparkle("for helping me with my homework") + + assert.Nil(t, sparkle) + assert.NotNil(t, err) + if err != nil { + assert.Equal(t, "Sparkle is invalid", err.Error()) + } + }) + }) +} diff --git a/app/domain/user.go b/app/domain/user.go new file mode 100644 index 0000000..aae17f6 --- /dev/null +++ b/app/domain/user.go @@ -0,0 +1,34 @@ +package domain + +type User struct { + ID ID `json:"id" jsonapi:"primary,users"` + Username string `json:"username" jsonapi:"attr,username"` + Email string `json:"email" jsonapi:"attr,email"` + ProfileURL string `json:"profile" jsonapi:"attr,profile"` + Picture string `json:"picture" jsonapi:"attr,picture"` +} + +func NewUser() *User { + return &User{} +} + +func (u *User) GetID() ID { + return u.ID +} + +func (u *User) SetID(id ID) error { + u.ID = id + return nil +} + +func (u *User) Validate() error { + return nil +} + +func (self *User) Sparkle(sparklee string, reason string) *Sparkle { + return &Sparkle{ + Sparklee: sparklee, + Author: self, + Reason: reason, + } +} diff --git a/app/domain/user_test.go b/app/domain/user_test.go new file mode 100644 index 0000000..1576d6d --- /dev/null +++ b/app/domain/user_test.go @@ -0,0 +1,24 @@ +package domain + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUser(t *testing.T) { + t.Run("Sparkle", func(t *testing.T) { + t.Run("returns a new Sparkle", func(t *testing.T) { + tanuki := &User{Username: "tanuki"} + user := &User{} + + sparkle := user.Sparkle(tanuki.Username, "for helping me with my homework") + + require.NotNil(t, sparkle) + assert.Equal(t, tanuki.Username, sparkle.Sparklee) + assert.Equal(t, "for helping me with my homework", sparkle.Reason) + assert.Equal(t, user, sparkle.Author) + }) + }) +} |
