Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored the end of round report #67

Merged
merged 1 commit into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/bot/job_create_round_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (s *CreateRoundSuite) Test_CreateRound() {
s.mock,
reportStatsParams,
models.JobTypeReportStats.String(),
models.JobPriorityStandard,
models.JobPriorityLow,
)

// Mock query to queue CREATE_ROUND job
Expand Down
10 changes: 5 additions & 5 deletions internal/bot/job_end_round.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type EndRoundParams struct {
NextRound time.Time `json:"next_round"`
}

// EndRound completes a running chat-roulette round for a Slack channel.
// EndRound concludes a running chat-roulette round for a Slack channel.
func EndRound(ctx context.Context, db *gorm.DB, client *slack.Client, p *EndRoundParams) error {

logger := hclog.FromContext(ctx).With(
Expand All @@ -28,7 +28,7 @@ func EndRound(ctx context.Context, db *gorm.DB, client *slack.Client, p *EndRoun

logger.Info("ending chat-roulette round if one is in progress")

// End the previous chat-roulette round for this Slack channel
// End the current chat-roulette round for this Slack channel
dbCtx, cancel := context.WithTimeout(ctx, 300*time.Millisecond)
defer cancel()

Expand All @@ -39,12 +39,12 @@ func EndRound(ctx context.Context, db *gorm.DB, client *slack.Client, p *EndRoun
Update("has_ended", true)

if result.Error != nil {
message := "failed to end chat-roulette round"
message := "failed to end current chat-roulette round"
logger.Error(message, "error", result.Error)
return errors.Wrap(result.Error, message)
}

logger.Info("ended the last chat-roulette round")
logger.Info("ended the current chat-roulette round")

return nil
}
Expand All @@ -55,7 +55,7 @@ func QueueEndRoundJob(ctx context.Context, db *gorm.DB, p *EndRoundParams) error
JobType: models.JobTypeEndRound,
Priority: models.JobPriorityStandard,
Params: p,
ExecAt: p.NextRound.Add(-(1 * time.Hour)),
ExecAt: p.NextRound.Add(-(4 * time.Hour)), // 4 hours before the start of the next round
}

return QueueJob(ctx, db, job)
Expand Down
2 changes: 1 addition & 1 deletion internal/bot/job_end_round_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (s *EndRoundSuite) Test_EndRound() {

err := EndRound(s.ctx, s.db, nil, p)
r.NoError(err)
r.Contains(s.buffer.String(), "ended the last chat-roulette round")
r.Contains(s.buffer.String(), "ended the current chat-roulette round")
}

func (s *EndRoundSuite) Test_QueueEndRoundJob() {
Expand Down
37 changes: 18 additions & 19 deletions internal/bot/job_report_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ const (

// reportStatsTemplate is used with reportStatsTemplateFilename
type reportStatsTemplate struct {
Matches float64
Pairs float64
Met float64
Percent float64
}

type roundStats struct {
Total int
Met int
}

// ReportStatsParams are the parameters for the REPORT_STATS job.
type ReportStatsParams struct {
ChannelID string `json:"channel_id"`
Expand All @@ -40,25 +45,20 @@ func ReportStats(ctx context.Context, db *gorm.DB, client *slack.Client, p *Repo
"round_id", p.RoundID,
)

// Retrieve the number of matches that were made and how many actually met
type Matches struct {
Total int64
Met int64
}

var matches Matches
// Retrieve the number of pairs that were made and how many actually met
var stats roundStats

dbCtx, cancel := context.WithTimeout(ctx, 300*time.Millisecond)
defer cancel()

result := db.WithContext(dbCtx).
Model(&models.Match{}).
Select(
`COUNT(*) as total`,
`SUM(CASE WHEN has_met = true then 1 else 0 end) AS met`,
).
Select(`
COUNT(*) AS total,
COUNT(*) FILTER (WHERE has_met) AS met
`).
Where("round_id = ?", p.RoundID).
Find(&matches)
Find(&stats)

if result.Error != nil {
message := "failed to retrieve match results"
Expand All @@ -67,12 +67,12 @@ func ReportStats(ctx context.Context, db *gorm.DB, client *slack.Client, p *Repo
}

// Calculate matches percent
percent := (float64(matches.Met) / float64(matches.Total)) * 100
percent := (float64(stats.Met) / float64(stats.Total)) * 100

// Render template
t := reportStatsTemplate{
Matches: float64(matches.Total),
Met: float64(matches.Met),
Pairs: float64(stats.Total),
Met: float64(stats.Met),
Percent: percent,
}

Expand Down Expand Up @@ -104,10 +104,9 @@ func ReportStats(ctx context.Context, db *gorm.DB, client *slack.Client, p *Repo
func QueueReportStatsJob(ctx context.Context, db *gorm.DB, p *ReportStatsParams) error {
job := models.GenericJob[*ReportStatsParams]{
JobType: models.JobTypeReportStats,
Priority: models.JobPriorityStandard,
Priority: models.JobPriorityLow,
Params: p,
// This should execute before the start of the next chat-roulette round.
ExecAt: p.NextRound.Add(-(1 * time.Hour)),
ExecAt: p.NextRound.Add(-(4 * time.Hour)), // 4 hours before the start of the next round
}

return QueueJob(ctx, db, job)
Expand Down
14 changes: 8 additions & 6 deletions internal/bot/job_report_stats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (s *ReportStatsSuite) Test_ReportStats() {
w.Write([]byte(`{"ok":false}`))
}

r.Len(blocks.BlockSet, 5)
r.Len(blocks.BlockSet, 9)

w.Write([]byte(`{
"ok": true,
Expand Down Expand Up @@ -102,13 +102,14 @@ func Test_reportStatsTemplate(t *testing.T) {

testCases := []struct {
name string
matches float64
pairs float64
met float64
percent float64
contains []string
}{
{"all met", 10, 10, 100, []string{}},
{"half met", 10, 5, 50, []string{
"This round had *20* participants",
"*5* groups met",
"*50%* of the *10* intros made",
}},
Expand All @@ -117,20 +118,21 @@ func Test_reportStatsTemplate(t *testing.T) {
"*25%* of the *4* intros made",
}},
{"none met", 20, 0, 0, []string{
"This round had *40* participants",
"*0* groups met",
"*0%* of the *20* intros made",
}},
{"no matches", 0, 0, 0, []string{
"No matches were made in the last round of Chat Roulette! :cry:",
"To ensure matches can be made in the next round, participants must opt-in to Chat Roulette.",
{"no pairs", 0, 0, 0, []string{
"No intros were made in the last round :sob:",
"To ensure intros can be made in the next round, you must opt-in to Chat Roulette.",
}},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {

p := reportStatsTemplate{
Matches: tc.matches,
Pairs: tc.pairs,
Met: tc.met,
Percent: tc.percent,
}
Expand Down
7 changes: 4 additions & 3 deletions internal/bot/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ var (

// funcMap is a map of custom template functions
funcMap = template.FuncMap{
"capitalize": templatex.Capitalize,
"prettyDate": templatex.PrettierDate,
"prettyURL": templatex.PrettyURL,
"capitalize": templatex.Capitalize,
"prettyDate": templatex.PrettierDate,
"prettyURL": templatex.PrettyURL,
"prettyPercent": templatex.PrettyPercent,
}

templates = template.New("custom").Funcs(funcMap).Funcs(sprig.TxtFuncMap())
Expand Down
2 changes: 1 addition & 1 deletion internal/bot/templates/report_matches.json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*{{ .Pairs }}* matches were made {{ $matchesEmoji }}"
"text": "*{{ .Pairs }}* intros were made {{ $matchesEmoji }}"
}
}
{{- if and ( gt .Pairs 0 ) ( not .IsAdmin ) }}
Expand Down
47 changes: 40 additions & 7 deletions internal/bot/templates/report_stats.json.tmpl
Original file line number Diff line number Diff line change
@@ -1,47 +1,80 @@
{{- $participants := mul .Pairs 2 }}
{{- $groupsKeyword := "groups" }}
{{- if eq .Met 1.0 }}
{{- $groupsKeyword = "group" }}
{{- end -}}
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hi all :wave:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "The current round of Chat Roulette has now come to an end :smile:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "The next round will begin soon. But before that, let's review how we did!"
}
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": ":bar_chart: Stats for Chat Roulette",
"text": ":bar_chart: Round Stats",
"emoji": true
}
},
{
"type": "divider"
},
{{- if (eq .Matches 0.0) }}
{{- if eq .Pairs 0.0 }}
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "No matches were made in the last round of Chat Roulette! :cry:"
"text": "No intros were made in the last round :sob:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "To ensure matches can be made in the next round, participants must opt-in to Chat Roulette."
"text": "To ensure intros can be made in the next round, you must opt-in to Chat Roulette."
}
}
{{- else }}
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*{{ .Met }}* group{{ if or (eq .Met 0.0) (gt .Met 1.0) }}s{{ end }} met from the last round of Chat Roulette!"
"text": "This round had *{{ $participants }}* participants :tada:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*{{ .Met }}* {{ $groupsKeyword }} met :partying_face:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "That's *{{ .Percent }}%* of the *{{ .Matches }}* intros made."
"text": "That's *{{ .Percent | prettyPercent }}* of the *{{ .Pairs }}* intros made :confetti_ball:"
}
},
{{- if (eq .Percent 100.0) }}
{{- if eq .Percent 100.0 }}
{
"type": "section",
"text": {
Expand Down
2 changes: 1 addition & 1 deletion internal/bot/testdata/report_matches_admin.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*25* matches were made :raised_hands:"
"text": "*25* intros were made :raised_hands:"
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion internal/bot/testdata/report_matches_channel.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*6* matches were made :raised_hands:"
"text": "*6* intros were made :raised_hands:"
}
}
,{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*0* matches were made :sob:"
"text": "*0* intros were made :sob:"
}
}
]
Expand Down
34 changes: 31 additions & 3 deletions internal/bot/testdata/report_stats.json.golden
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hi all :wave:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "The current round of Chat Roulette has now come to an end :smile:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "The next round will begin soon. But before that, let's review how we did!"
}
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": ":bar_chart: Stats for Chat Roulette",
"text": ":bar_chart: Round Stats",
"emoji": true
}
},
Expand All @@ -15,14 +36,21 @@
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*10* groups met from the last round of Chat Roulette!"
"text": "This round had *20* participants :tada:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*10* groups met :partying_face:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "That's *100%* of the *10* intros made."
"text": "That's *100%* of the *10* intros made :confetti_ball:"
}
},
{
Expand Down
Loading
Loading