diff --git a/server/api/bot.go b/server/api/bot.go index f65891b8a6..22179bf2aa 100644 --- a/server/api/bot.go +++ b/server/api/bot.go @@ -199,8 +199,6 @@ func (h *BotHandler) connect(c *Context, w http.ResponseWriter, r *http.Request) } else if app.ShouldSendDailyDigestMessage(info, timezone, currentTime) { sendRegularDigest(DigestSenderParams{isWeekly: false}) } - - w.WriteHeader(http.StatusOK) } func (h *BotHandler) createDigestSender(c *Context, w http.ResponseWriter, userID string, userInfo *app.UserInfo) func(DigestSenderParams) { diff --git a/server/api_bot_test.go b/server/api_bot_test.go index fe7afd26af..8b0f4c2c48 100644 --- a/server/api_bot_test.go +++ b/server/api_bot_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/mattermost/mattermost/server/public/model" ) @@ -53,3 +54,54 @@ func TestTrialLicences(t *testing.T) { assert.Equal(t, http.StatusOK, resp.StatusCode) }) } + +// TestBotConnect exercises the real GET /bot/connect endpoint end-to-end (real server, real +// UserInfoStore and PlaybookRunService — no mocks), confirming it returns 200 in the conditions +// it handles. The weekly/daily digest-timing decision itself is unit-tested in +// app/regular_digest_service_test.go; this only confirms the handler reaches a 200 either way. +func TestBotConnect(t *testing.T) { + e := Setup(t) + e.CreateBasic() + + // e.RegularUser already owns BasicRun from e.CreateBasic() (via CreateBasicRun()), so + // there's something to digest here without any extra setup. + botUser, _, err := e.ServerAdminClient.GetUserByUsername(context.Background(), "playbooks", "") + require.NoError(t, err) + + dmChannel, _, err := e.ServerClient.CreateDirectChannel(context.Background(), botUser.Id, e.RegularUser.Id) + require.NoError(t, err) + + var digestPost *model.Post + + t.Run("digest due for a user connecting for the first time", func(t *testing.T) { + resp, err := e.DoPluginAPIRequestWithHeaders(context.Background(), e.ServerClient, http.MethodGet, "/api/v0/bot/connect", "", nil) + require.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + + // The bot posts the digest DM synchronously within connect() (Bot.DM -> + // pluginAPI.Post.CreatePost, no goroutine/queue), so it's already there by the + // time the HTTP response comes back — no need to poll or wait for it. + posts, _, err := e.ServerClient.GetPostsForChannel(context.Background(), dmChannel.Id, 0, 10, "", false, false) + require.NoError(t, err) + require.NotEmpty(t, posts.Order, "expected the bot to have DMed a digest") + digestPost = posts.Posts[posts.Order[0]] + assert.Equal(t, botUser.Id, digestPost.UserId) + assert.NotEmpty(t, digestPost.Message) + }) + + t.Run("no digest due immediately after the first connect", func(t *testing.T) { + // The first subtest's connect() call already persisted LastDailyTodoDMAt = now, + // so calling connect() again moments later deterministically finds both + // ShouldSendWeeklyDigestMessage (same ISO week) and ShouldSendDailyDigestMessage + // (well under an hour elapsed) false — no need for a second user or settings. + resp, err := e.DoPluginAPIRequestWithHeaders(context.Background(), e.ServerClient, http.MethodGet, "/api/v0/bot/connect", "", nil) + require.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + + // GetPostsSince is exclusive (server queries UpdateAt > since), so digestPost + // itself won't reappear here. + sincePosts, _, err := e.ServerClient.GetPostsSince(context.Background(), dmChannel.Id, digestPost.CreateAt, false) + require.NoError(t, err) + assert.Empty(t, sincePosts.Order, "expected no digest on the second immediate connect") + }) +}