summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-04-10 17:35:46 -0600
committermo khan <mo@mokhan.ca>2025-04-10 17:35:46 -0600
commitd8fd76b1c0c0bd86b2114dcf6af0b6e34d4783f3 (patch)
tree32d71c0e6a9a0c25789ab90a29ef742001898afc /pkg/domain
parenta722bd0ef4f69547229921eb0fe2eefce3ed6397 (diff)
feat: add a single API endpoint to return a list of sparkles
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/sparkle.go50
-rw-r--r--pkg/domain/sparkle_test.go51
2 files changed, 101 insertions, 0 deletions
diff --git a/pkg/domain/sparkle.go b/pkg/domain/sparkle.go
new file mode 100644
index 0000000..54ccb13
--- /dev/null
+++ b/pkg/domain/sparkle.go
@@ -0,0 +1,50 @@
+package domain
+
+import (
+ "errors"
+ "regexp"
+
+ "gitlab.com/mokhax/sparkled/pkg/pls"
+)
+
+type Sparkle struct {
+ ID string `json:"id" jsonapi:"primary,sparkles"`
+ Sparklee string `json:"sparklee" jsonapi:"attr,sparklee"`
+ 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: pls.GenerateULID(),
+ Sparklee: matches[SparkleeIndex],
+ Reason: matches[ReasonIndex],
+ }, nil
+}
+
+func (s *Sparkle) Validate() error {
+ if s.Sparklee == "" {
+ return SparkleeIsRequired
+ }
+ if s.Reason == "" {
+ return ReasonIsRequired
+ }
+ return nil
+}
diff --git a/pkg/domain/sparkle_test.go b/pkg/domain/sparkle_test.go
new file mode 100644
index 0000000..8d81afd
--- /dev/null
+++ b/pkg/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())
+ }
+ })
+ })
+}