Skip to content

Commit

Permalink
feat(view): added announcement api support
Browse files Browse the repository at this point in the history
* added api support to dynamically show announcements
* fallbacks to a survey link
* unit tests for the same
  • Loading branch information
ashishkhuraishy committed Sep 10, 2024
1 parent d4b9382 commit 28c27fd
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 8 deletions.
5 changes: 2 additions & 3 deletions ignite/cmd/model/chain_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

tea "github.com/charmbracelet/bubbletea"

"github.com/ignite/cli/v29/ignite/pkg/announcements"
"github.com/ignite/cli/v29/ignite/pkg/cliui/colors"
"github.com/ignite/cli/v29/ignite/pkg/cliui/icons"
cliuimodel "github.com/ignite/cli/v29/ignite/pkg/cliui/model"
Expand Down Expand Up @@ -260,9 +261,7 @@ func (m ChainServe) renderQuitView() string {
}

fmt.Fprintf(&view, "%s %s\n", icons.Info, colors.Info("Stopped"))

// Survey Link
fmt.Fprintf(&view, "%s %s\n", icons.Survey, colors.Info("Survey: https://bit.ly/3WZS2uS"))
view.WriteString(announcements.GetAnnouncements())

return view.String()
}
Expand Down
50 changes: 50 additions & 0 deletions ignite/pkg/announcements/announcement.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package announcements

import (
"encoding/json"
"fmt"
"net/http"
"strings"

"github.com/ignite/cli/v29/ignite/pkg/cliui/icons"
)

var (
SurveyLink = "https://bit.ly/3WZS2uS"
AnnouncementAPI = "http://api.ignite.com/announcements"
)

type announcement struct {
Announcements []string `json:"announcements"`
}

func GetAnnouncements() string {
resp, err := http.Get(AnnouncementAPI)

Check failure on line 22 in ignite/pkg/announcements/announcement.go

View workflow job for this annotation

GitHub Actions / Lint Go code

G107: Potential HTTP request made with variable url (gosec)

Check failure on line 22 in ignite/pkg/announcements/announcement.go

View workflow job for this annotation

GitHub Actions / Lint Go code

G107: Potential HTTP request made with variable url (gosec)
if err != nil || resp.StatusCode != 200 {
return fallbackData()
}
defer resp.Body.Close()

var data announcement
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return fallbackData()
}

// is this needed? or if its empty we don't want to show anything?
if len(data.Announcements) == 0 {
return fallbackData()
}

var out strings.Builder
fmt.Fprintf(&out, "\n%s %s\n", icons.Announcement, "Announcements")

for _, announcement := range data.Announcements {
fmt.Fprintf(&out, "%s %s\n", icons.Bullet, announcement)
}

return out.String()
}

func fallbackData() string {
return fmt.Sprintf("\n%s Survey: %s\n", icons.Survey, SurveyLink)
}
65 changes: 65 additions & 0 deletions ignite/pkg/announcements/announcement_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package announcements_test

import (
"fmt"
"net/http"
"net/http/httptest"
"testing"

"github.com/ignite/cli/v29/ignite/pkg/announcements"
)

func TestGetAnnouncements(t *testing.T) {
fallbackData := fmt.Sprintf("\n💬 Survey: %s\n", announcements.SurveyLink)

tests := []struct {
name string
mockResponse string
statusCode int
expected string
}{
{
name: "successful retrieval",
mockResponse: `{"announcements":["Announcement 1","Announcement 2"]}`,
statusCode: http.StatusOK,
expected: "\n🗣️ Announcements\n⋆ Announcement 1\n⋆ Announcement 2\n",
},
{
name: "empty announcements",
mockResponse: `{"announcements":[]}`,
statusCode: http.StatusOK,
expected: fallbackData,
},
{
name: "invalid JSON response",
mockResponse: `invalid json`,
statusCode: http.StatusOK,
expected: fallbackData,
},
{
name: "non-200 HTTP response",
mockResponse: ``,
statusCode: http.StatusInternalServerError,
expected: fallbackData,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(tt.statusCode)
w.Write([]byte(tt.mockResponse))
}))
defer server.Close()

originalAPI := announcements.AnnouncementAPI
announcements.AnnouncementAPI = server.URL
defer func() { announcements.AnnouncementAPI = originalAPI }()

result := announcements.GetAnnouncements()
if result != tt.expected {
t.Errorf("expected %q, got %q", tt.expected, result)
}
})
}
}
11 changes: 6 additions & 5 deletions ignite/pkg/cliui/icons/icon.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
)

var (
Earth = "🌍"
CD = "💿"
User = "👤"
Tada = "🎉"
Survey = "💬"
Earth = "🌍"
CD = "💿"
User = "👤"
Tada = "🎉"
Survey = "💬"
Announcement = "🗣️"

// OK is an OK mark.
OK = colors.SprintFunc(colors.Green)("✔")
Expand Down

0 comments on commit 28c27fd

Please sign in to comment.