mattermost/server/channels/api4/content_flagging_test.go
Jesse Hallam e3fbf8711f
MM-68149: Upgrade to Go 1.26.2 (#36418)
* MM-68149: upgrade to Go 1.26.2

Update go directive in go.mod and .go-version.

* MM-68149: replace pointer helpers with Go 1.26 new()

Go 1.26 extends the built-in new() to accept an initial value expression,
making typed-pointer helpers like model.NewPointer(x), bToP(x), and boolPtr(x)
redundant. Replace every call site with new(x) and remove the now-unused
helper functions and their //go:fix inline directives.

* MM-68149: apply go fix for reflect API and format-string changes

- reflect.Ptr → reflect.Pointer (renamed in Go 1.18, deprecated alias removed in 1.26)
- reflect range-over-struct: for i := 0; i < t.NumField(); i++ → for field := range t.Fields()
  and the equivalent for Methods() and interface types
- Fix format-string concatenation and variadic-arg mismatches flagged by go vet

* MM-68149: update JPEG fixtures and test infrastructure for Go 1.26 encoder

Go 1.26 ships a new image/jpeg encoder that produces slightly different output.
Regenerate all JPEG fixture files and switch the comparison helpers from
byte-equality to pixel-level comparison with a small per-channel tolerance,
so minor encoder drift across patch versions is handled automatically.

Add -update-fixtures flag to make it easy to regenerate fixtures after future
major Go upgrades. Document the update procedure in tests/README.md.

* MM-68149: CI check that go fix ./... produces no changes

* Fix real bugs flagged by CodeRabbit review

- group.go: set newGroup.MemberCount not group.MemberCount (member count
  was populated on the wrong variable and lost before publish/return)
- file_test.go: guard compareImage(GetFilePreview) on the preview slice
  length, not the thumbnail slice length (copy-paste error)
- config_test.go: remove duplicate MinimumLength assignment

* fixup! Fix real bugs flagged by CodeRabbit review
2026-05-12 15:59:12 +00:00

1245 lines
43 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package api4
import (
"context"
"net/http"
"testing"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/v8/channels/utils/testutils"
"github.com/stretchr/testify/require"
)
func setBasicCommonReviewerConfig(th *TestHelper) *model.AppError {
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{th.BasicUser.Id},
},
},
}
config.SetDefaults()
return th.App.SaveContentFlaggingConfig(config)
}
func setNonReviewerConfig(th *TestHelper) *model.AppError {
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(false),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
TeamReviewersSetting: map[string]*model.TeamReviewerSetting{
th.BasicTeam.Id: {
Enabled: new(true),
ReviewerIds: []string{},
},
},
},
},
}
config.SetDefaults()
return th.App.SaveContentFlaggingConfig(config)
}
func setBasicTeamReviewerConfig(th *TestHelper, extraReviewerIds ...string) *model.AppError {
ids := []string{th.BasicUser.Id}
ids = append(ids, extraReviewerIds...)
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(false),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
TeamReviewersSetting: map[string]*model.TeamReviewerSetting{
th.BasicTeam.Id: {
Enabled: new(true),
ReviewerIds: ids,
},
},
},
},
}
config.SetDefaults()
return th.App.SaveContentFlaggingConfig(config)
}
func setCommonReviewerWithRequiredCommentConfig(th *TestHelper) *model.AppError {
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
AdditionalSettings: &model.AdditionalContentFlaggingSettings{
ReviewerCommentRequired: new(true),
},
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{th.BasicUser.Id},
},
},
}
config.SetDefaults()
return th.App.SaveContentFlaggingConfig(config)
}
func flagPostViaAPI(t *testing.T, client *model.Client4, postId string) {
t.Helper()
flagRequest := &model.FlagContentRequest{
Reason: "Classification mismatch",
Comment: "This is sensitive content",
}
resp, err := client.FlagPostForContentReview(context.Background(), postId, flagRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
}
func uploadFileAndCreatePost(t *testing.T, th *TestHelper, client *model.Client4) (*model.Post, *model.FileInfo) {
t.Helper()
data, err := testutils.ReadTestFile("test.png")
require.NoError(t, err)
fileResponse, _, err := client.UploadFile(context.Background(), data, th.BasicChannel.Id, "test.png")
require.NoError(t, err)
require.Equal(t, 1, len(fileResponse.FileInfos))
fileInfo := fileResponse.FileInfos[0]
post := th.CreatePostInChannelWithFiles(t, th.BasicChannel, fileInfo)
return post, fileInfo
}
func TestRequireContentFlaggingEnabled(t *testing.T) {
th := Setup(t).InitBasic(t)
t.Run("Should set error when license is not valid", func(t *testing.T) {
th.RemoveLicense(t)
c := &Context{
App: th.App,
Logger: th.App.Log(),
}
requireContentFlaggingEnabled(c)
require.NotNil(t, c.Err)
require.Equal(t, "api.data_spillage.error.license", c.Err.Id)
require.Equal(t, http.StatusNotImplemented, c.Err.StatusCode)
})
t.Run("Should set error when feature is disabled in config", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
c := &Context{
App: th.App,
Logger: th.App.Log(),
}
requireContentFlaggingEnabled(c)
require.NotNil(t, c.Err)
require.Equal(t, "api.data_spillage.error.disabled", c.Err.Id)
require.Equal(t, http.StatusNotImplemented, c.Err.StatusCode)
})
t.Run("Should not set error when license is valid and feature is enabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(true)
config.ContentFlaggingSettings.SetDefaults()
})
c := &Context{
App: th.App,
Logger: th.App.Log(),
}
requireContentFlaggingEnabled(c)
require.Nil(t, c.Err)
})
}
func TestGetFlaggingConfiguration(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
status, resp, err := client.GetFlaggingConfiguration(context.Background())
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
require.Nil(t, status)
})
t.Run("Should successfully return configuration without team_id for any authenticated user", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(true)
config.ContentFlaggingSettings.SetDefaults()
})
config, resp, err := client.GetFlaggingConfiguration(context.Background())
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, config)
require.NotEmpty(t, config.Reasons)
require.NotNil(t, config.ReporterCommentRequired)
require.NotNil(t, config.ReviewerCommentRequired)
// Reviewer-only fields should be nil when not requesting as a reviewer
require.Nil(t, config.NotifyReporterOnRemoval)
require.Nil(t, config.NotifyReporterOnDismissal)
})
t.Run("Should return 403 when team_id is provided but user is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setNonReviewerConfig(th)
require.Nil(t, appErr)
flagConfig, resp, err := client.GetFlaggingConfigurationForTeam(context.Background(), th.BasicTeam.Id)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
require.Nil(t, flagConfig)
})
t.Run("Should successfully return configuration with reviewer fields when user is a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
config, resp, err := client.GetFlaggingConfigurationForTeam(context.Background(), th.BasicTeam.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, config)
require.NotEmpty(t, config.Reasons)
require.NotNil(t, config.ReporterCommentRequired)
require.NotNil(t, config.ReviewerCommentRequired)
// Reviewer-only fields should be present when requesting as a reviewer
require.NotNil(t, config.NotifyReporterOnRemoval)
require.NotNil(t, config.NotifyReporterOnDismissal)
})
t.Run("Should successfully return configuration with reviewer fields when user is a team reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicTeamReviewerConfig(th)
require.Nil(t, appErr)
flagConfig, resp, err := client.GetFlaggingConfigurationForTeam(context.Background(), th.BasicTeam.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, flagConfig)
require.NotEmpty(t, flagConfig.Reasons)
require.NotNil(t, flagConfig.ReporterCommentRequired)
require.NotNil(t, flagConfig.ReviewerCommentRequired)
// Reviewer-only fields should be present when requesting as a team reviewer
require.NotNil(t, flagConfig.NotifyReporterOnRemoval)
require.NotNil(t, flagConfig.NotifyReporterOnDismissal)
})
}
func TestSaveContentFlaggingSettings(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 403 when user does not have manage system permission", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{th.BasicUser.Id},
},
},
}
// Use basic user who doesn't have manage system permission
th.LoginBasic(t)
resp, err := client.SaveContentFlaggingSettings(context.Background(), &config)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("Should return 400 when config is invalid", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
// Invalid config - missing required fields
config := model.ContentFlaggingSettingsRequest{
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
TeamAdminsAsReviewers: new(false),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{},
},
},
}
config.SetDefaults()
th.LoginSystemAdmin(t)
resp, err := th.SystemAdminClient.SaveContentFlaggingSettings(context.Background(), &config)
require.Error(t, err)
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
})
t.Run("Should successfully save content flagging settings when user has manage system permission", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{th.BasicUser.Id},
},
},
}
// Use system admin who has manage system permission
resp, err := th.SystemAdminClient.SaveContentFlaggingSettings(context.Background(), &config)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
}
func TestGetContentFlaggingSettings(t *testing.T) {
th := Setup(t).InitBasic(t)
t.Run("Should return 403 when user does not have manage system permission", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
// Use basic user who doesn't have manage system permission
th.LoginBasic(t)
settings, resp, err := th.Client.GetContentFlaggingSettings(context.Background())
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
require.Nil(t, settings)
})
t.Run("Should successfully get content flagging settings when user has manage system permission", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
// First save some settings
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
// Use system admin who has manage system permission
settings, resp, err := th.SystemAdminClient.GetContentFlaggingSettings(context.Background())
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, settings)
require.NotNil(t, settings.EnableContentFlagging)
require.True(t, *settings.EnableContentFlagging)
require.NotNil(t, settings.ReviewerSettings)
require.NotNil(t, settings.ReviewerSettings.CommonReviewers)
require.True(t, *settings.ReviewerSettings.CommonReviewers)
require.NotNil(t, settings.ReviewerSettings.CommonReviewerIds)
require.Contains(t, settings.ReviewerSettings.CommonReviewerIds, th.BasicUser.Id)
})
}
func TestGetPostPropertyValues(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
post := th.CreatePost(t)
propertyValues, resp, err := client.GetPostPropertyValues(context.Background(), post.Id)
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
require.Nil(t, propertyValues)
})
t.Run("Should return 403 when user is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(true)
config.ContentFlaggingSettings.SetDefaults()
})
post := th.CreatePost(t)
propertyValues, resp, err := client.GetPostPropertyValues(context.Background(), post.Id)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
require.Nil(t, propertyValues)
})
t.Run("Should successfully get property values when user is a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now get the property values
propertyValues, resp, err := client.GetPostPropertyValues(context.Background(), post.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, propertyValues)
require.Len(t, propertyValues, 6)
})
}
func TestGetFlaggedPost(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
post := th.CreatePost(t)
flaggedPost, resp, err := client.GetContentFlaggedPost(context.Background(), post.Id)
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
require.Nil(t, flaggedPost)
})
t.Run("Should return 403 when user is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
appErr := setNonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flaggedPost, resp, err := client.GetContentFlaggedPost(context.Background(), post.Id)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
require.Nil(t, flaggedPost)
})
t.Run("Should return 404 when post is not flagged", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flaggedPost, resp, err := client.GetContentFlaggedPost(context.Background(), post.Id)
require.Error(t, err)
require.Equal(t, http.StatusNotFound, resp.StatusCode)
require.Nil(t, flaggedPost)
})
t.Run("Should successfully get flagged post when user is a reviewer and post is flagged", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now get the flagged post
flaggedPost, resp, err := client.GetContentFlaggedPost(context.Background(), post.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, flaggedPost)
require.Equal(t, post.Id, flaggedPost.Id)
})
t.Run("Should return flagged post's file info", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post, fileInfo := uploadFileAndCreatePost(t, th, client)
flagPostViaAPI(t, client, post.Id)
flaggedPost, resp, err := client.GetContentFlaggedPost(context.Background(), post.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.Equal(t, 1, len(flaggedPost.Metadata.Files))
require.Equal(t, fileInfo.Id, flaggedPost.Metadata.Files[0].Id)
})
}
func TestFlagPost(t *testing.T) {
th := Setup(t).InitBasic(t)
// Enable BurnOnRead feature flag
th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.BurnOnRead = true })
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
post := th.CreatePost(t)
flagRequest := &model.FlagContentRequest{
Reason: "spam",
Comment: "This is spam content",
}
resp, err := client.FlagPostForContentReview(context.Background(), post.Id, flagRequest)
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
})
t.Run("Should return 403 when user does not have permission to view post", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(true)
config.ContentFlaggingSettings.SetDefaults()
})
// Create a private channel and post
privateChannel := th.CreatePrivateChannel(t)
post := th.CreatePostWithClient(t, th.Client, privateChannel)
th.RemoveUserFromChannel(t, th.BasicUser, privateChannel)
flagRequest := &model.FlagContentRequest{
Reason: "spam",
Comment: "This is spam content",
}
resp, err := client.FlagPostForContentReview(context.Background(), post.Id, flagRequest)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("Should return 400 when content flagging is not enabled for the team", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(false),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
TeamReviewersSetting: map[string]*model.TeamReviewerSetting{
th.BasicTeam.Id: {Enabled: new(false)},
},
},
},
}
config.SetDefaults()
appErr := th.App.SaveContentFlaggingConfig(config)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagRequest := &model.FlagContentRequest{
Reason: "spam",
Comment: "This is spam content",
}
resp, err := client.FlagPostForContentReview(context.Background(), post.Id, flagRequest)
require.Error(t, err)
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
})
t.Run("Should successfully flag a post when all conditions are met", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagRequest := &model.FlagContentRequest{
Reason: "Classification mismatch",
Comment: "This is sensitive data",
}
resp, err := client.FlagPostForContentReview(context.Background(), post.Id, flagRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("Should not allow flagging a burn on read post", func(t *testing.T) {
enableBurnOnReadFeature(th)
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(true)
config.ContentFlaggingSettings.SetDefaults()
})
post := &model.Post{
UserId: th.BasicUser.Id,
ChannelId: th.BasicChannel.Id,
Message: "This is a burn on read post",
Type: model.PostTypeBurnOnRead,
}
createdPost, response, err := client.CreatePost(context.Background(), post)
require.NoError(t, err)
CheckCreatedStatus(t, response)
flagRequest := &model.FlagContentRequest{
Reason: "spam",
Comment: "This is spam content",
}
response, err = client.FlagPostForContentReview(context.Background(), createdPost.Id, flagRequest)
require.Error(t, err)
CheckBadRequestStatus(t, response)
})
}
func TestGetTeamPostReportingFeatureStatus(t *testing.T) {
th := Setup(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
status, resp, err := client.GetTeamPostFlaggingFeatureStatus(context.Background(), model.NewId())
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
require.Nil(t, status)
})
t.Run("Should return Forbidden error when calling for a team without the team membership", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{"reviewer_user_id_1", "reviewer_user_id_2"},
},
},
}
config.SetDefaults()
appErr := th.App.SaveContentFlaggingConfig(config)
require.Nil(t, appErr)
// using basic user because the default user is a system admin, and they have
// access to all teams even without being an explicit team member
th.LoginBasic(t)
team := th.CreateTeam(t)
// unlinking from the created team as by default the team's creator is
// a team member, so we need to leave the team explicitly
th.UnlinkUserFromTeam(t, th.BasicUser, team)
status, resp, err := client.GetTeamPostFlaggingFeatureStatus(context.Background(), team.Id)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
require.Nil(t, status)
// now we will join the team and that will allow us to call the endpoint without error
th.LinkUserToTeam(t, th.BasicUser, team)
status, resp, err = client.GetTeamPostFlaggingFeatureStatus(context.Background(), team.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.True(t, status["enabled"])
})
}
func TestSearchReviewers(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
reviewers, resp, err := client.SearchContentFlaggingReviewers(context.Background(), th.BasicTeam.Id, "test")
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
require.Nil(t, reviewers)
})
t.Run("Should return 403 when user is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setNonReviewerConfig(th)
require.Nil(t, appErr)
reviewers, resp, err := client.SearchContentFlaggingReviewers(context.Background(), th.BasicTeam.Id, "test")
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
require.Nil(t, reviewers)
})
t.Run("Should successfully search reviewers when user is a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
reviewers, resp, err := client.SearchContentFlaggingReviewers(context.Background(), th.BasicTeam.Id, "basic")
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, reviewers)
})
t.Run("Should successfully search reviewers when user is a team reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicTeamReviewerConfig(th)
require.Nil(t, appErr)
reviewers, resp, err := client.SearchContentFlaggingReviewers(context.Background(), th.BasicTeam.Id, "basic")
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, reviewers)
})
}
func TestAssignContentFlaggingReviewer(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
post := th.CreatePost(t)
resp, err := client.AssignContentFlaggingReviewer(context.Background(), post.Id, th.BasicUser.Id)
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
})
t.Run("Should return 400 when user ID is invalid", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
resp, err := client.AssignContentFlaggingReviewer(context.Background(), post.Id, "invalidUserId")
require.Error(t, err)
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
})
t.Run("Should return 403 when assigning user is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setNonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
resp, err := client.AssignContentFlaggingReviewer(context.Background(), post.Id, th.BasicUser.Id)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("Should return 400 when assignee is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
// Create another user who will not be a reviewer
nonReviewerUser := th.CreateUser(t)
th.LinkUserToTeam(t, nonReviewerUser, th.BasicTeam)
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{th.BasicUser.Id}, // Only BasicUser is a reviewer
},
},
}
config.SetDefaults()
appErr := th.App.SaveContentFlaggingConfig(config)
require.Nil(t, appErr)
post := th.CreatePost(t)
// Try to assign non-reviewer user
resp, err := client.AssignContentFlaggingReviewer(context.Background(), post.Id, nonReviewerUser.Id)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("Should successfully assign reviewer when all conditions are met", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
// Create another reviewer user
reviewerUser := th.CreateUser(t)
th.LinkUserToTeam(t, reviewerUser, th.BasicTeam)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
// Also add reviewerUser as a common reviewer
config := model.ContentFlaggingSettingsRequest{
ContentFlaggingSettingsBase: model.ContentFlaggingSettingsBase{
EnableContentFlagging: new(true),
},
ReviewerSettings: &model.ReviewSettingsRequest{
ReviewerSettings: model.ReviewerSettings{
CommonReviewers: new(true),
},
ReviewerIDsSettings: model.ReviewerIDsSettings{
CommonReviewerIds: []string{th.BasicUser.Id, reviewerUser.Id},
},
},
}
config.SetDefaults()
appErr = th.App.SaveContentFlaggingConfig(config)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now assign the reviewer
resp, err := client.AssignContentFlaggingReviewer(context.Background(), post.Id, reviewerUser.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("Should successfully assign reviewer when user is team reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
// Create another reviewer user
reviewerUser := th.CreateUser(t)
th.LinkUserToTeam(t, reviewerUser, th.BasicTeam)
appErr := setBasicTeamReviewerConfig(th, reviewerUser.Id)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now assign the reviewer
resp, err := client.AssignContentFlaggingReviewer(context.Background(), post.Id, reviewerUser.Id)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
}
func TestRemoveFlaggedPost(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
post := th.CreatePost(t)
actionRequest := &model.FlagContentActionRequest{
Comment: "Removing this post",
}
resp, err := client.RemoveFlaggedPost(context.Background(), post.Id, actionRequest)
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
})
t.Run("Should return 403 when user is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setNonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
actionRequest := &model.FlagContentActionRequest{
Comment: "Removing this post",
}
resp, err := client.RemoveFlaggedPost(context.Background(), post.Id, actionRequest)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("Should return 400 when comment is required but not provided", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setCommonReviewerWithRequiredCommentConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Try to remove without comment
actionRequest := &model.FlagContentActionRequest{
Comment: "", // Empty comment when required
}
resp, err := client.RemoveFlaggedPost(context.Background(), post.Id, actionRequest)
require.Error(t, err)
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
})
t.Run("Should successfully remove flagged post when all conditions are met", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now remove the flagged post
actionRequest := &model.FlagContentActionRequest{
Comment: "Removing this post due to policy violation",
}
resp, err := client.RemoveFlaggedPost(context.Background(), post.Id, actionRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Verify the post was deleted
_, resp, err = client.GetPost(context.Background(), post.Id, "")
require.Error(t, err)
require.Equal(t, http.StatusNotFound, resp.StatusCode)
})
t.Run("Should successfully remove flagged post when user is team reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicTeamReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now remove the flagged post
actionRequest := &model.FlagContentActionRequest{
Comment: "Removing this post due to policy violation",
}
resp, err := client.RemoveFlaggedPost(context.Background(), post.Id, actionRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("Should remove file attachments and edit history when removing flagged post", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post, fileInfo := uploadFileAndCreatePost(t, th, client)
// Verify file info exists for the post
fileInfos, err2 := th.App.Srv().Store().FileInfo().GetForPost(post.Id, true, false, false)
require.NoError(t, err2)
require.Len(t, fileInfos, 1)
require.Equal(t, fileInfo.Id, fileInfos[0].Id)
// Update the post to create edit history
post.Message = "Updated message to create edit history"
updatedPost, _, err := client.UpdatePost(context.Background(), post.Id, post)
require.NoError(t, err)
require.NotNil(t, updatedPost)
require.Equal(t, "Updated message to create edit history", updatedPost.Message)
// Verify edit history exists
editHistory, appErr := th.App.GetEditHistoryForPost(post.Id)
require.Nil(t, appErr)
require.NotEmpty(t, editHistory)
editHistoryPostId := editHistory[0].Id
flagPostViaAPI(t, client, post.Id)
// Remove the flagged post
actionRequest := &model.FlagContentActionRequest{
Comment: "Removing this post due to policy violation",
}
resp, err := client.RemoveFlaggedPost(context.Background(), post.Id, actionRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Verify file attachments are removed from database
fileInfosAfter, err2 := th.App.Srv().Store().FileInfo().GetForPost(post.Id, true, true, false)
require.NoError(t, err2)
require.Empty(t, fileInfosAfter, "File attachments should be removed from database after removing flagged post")
// Verify edit history posts are removed from database
editHistoryAfter, appErr := th.App.GetEditHistoryForPost(post.Id)
require.NotNil(t, appErr)
require.Equal(t, http.StatusNotFound, appErr.StatusCode, "Edit history should be removed from database after removing flagged post")
require.Empty(t, editHistoryAfter)
// Verify the edit history post is also permanently deleted
_, err2 = th.App.Srv().Store().Post().GetSingle(th.Context, editHistoryPostId, true)
require.Error(t, err2, "Edit history post should be permanently deleted")
})
}
func TestKeepFlaggedPost(t *testing.T) {
th := Setup(t).InitBasic(t)
client := th.Client
t.Run("Should return 501 when feature is disabled", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
th.App.UpdateConfig(func(config *model.Config) {
config.ContentFlaggingSettings.EnableContentFlagging = new(false)
config.ContentFlaggingSettings.SetDefaults()
})
post := th.CreatePost(t)
actionRequest := &model.FlagContentActionRequest{
Comment: "Keeping this post",
}
resp, err := client.KeepFlaggedPost(context.Background(), post.Id, actionRequest)
require.Error(t, err)
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
})
t.Run("Should return 403 when user is not a reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setNonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
actionRequest := &model.FlagContentActionRequest{
Comment: "Keeping this post",
}
resp, err := client.KeepFlaggedPost(context.Background(), post.Id, actionRequest)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("Should return 400 when comment is required but not provided", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setCommonReviewerWithRequiredCommentConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Try to keep without comment
actionRequest := &model.FlagContentActionRequest{
Comment: "", // Empty comment when required
}
resp, err := client.KeepFlaggedPost(context.Background(), post.Id, actionRequest)
require.Error(t, err)
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
})
t.Run("Should successfully keep flagged post when all conditions are met", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now keep the flagged post
actionRequest := &model.FlagContentActionRequest{
Comment: "Keeping this post after review",
}
resp, err := client.KeepFlaggedPost(context.Background(), post.Id, actionRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Verify the post still exists
fetchedPost, resp, err := client.GetPost(context.Background(), post.Id, "")
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, fetchedPost)
require.Equal(t, post.Id, fetchedPost.Id)
})
t.Run("Should successfully keep flagged post when user is team reviewer", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicTeamReviewerConfig(th)
require.Nil(t, appErr)
post := th.CreatePost(t)
flagPostViaAPI(t, client, post.Id)
// Now keep the flagged post
actionRequest := &model.FlagContentActionRequest{
Comment: "Keeping this post after review",
}
resp, err := client.KeepFlaggedPost(context.Background(), post.Id, actionRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("Should preserve file attachments and edit history when keeping flagged post", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
defer th.RemoveLicense(t)
appErr := setBasicCommonReviewerConfig(th)
require.Nil(t, appErr)
post, fileInfo := uploadFileAndCreatePost(t, th, client)
// Verify file info exists for the post
fileInfos, err2 := th.App.Srv().Store().FileInfo().GetForPost(post.Id, true, false, false)
require.NoError(t, err2)
require.Len(t, fileInfos, 1)
require.Equal(t, fileInfo.Id, fileInfos[0].Id)
// Update the post to create edit history
post.Message = "Updated message to create edit history"
updatedPost, _, err := client.UpdatePost(context.Background(), post.Id, post)
require.NoError(t, err)
require.NotNil(t, updatedPost)
require.Equal(t, "Updated message to create edit history", updatedPost.Message)
// Verify edit history exists
editHistory, appErr := th.App.GetEditHistoryForPost(post.Id)
require.Nil(t, appErr)
require.NotEmpty(t, editHistory)
editHistoryPostId := editHistory[0].Id
flagPostViaAPI(t, client, post.Id)
// Keep the flagged post
actionRequest := &model.FlagContentActionRequest{
Comment: "Keeping this post after review - content is acceptable",
}
resp, err := client.KeepFlaggedPost(context.Background(), post.Id, actionRequest)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Verify file attachments are still present in database
fileInfosAfter, err2 := th.App.Srv().Store().FileInfo().GetForPost(post.Id, true, false, false)
require.NoError(t, err2)
require.Len(t, fileInfosAfter, 1, "File attachments should be preserved after keeping flagged post")
require.Equal(t, fileInfo.Id, fileInfosAfter[0].Id)
// Verify edit history is still present in database
editHistoryAfter, appErr := th.App.GetEditHistoryForPost(post.Id)
require.Nil(t, appErr, "Edit history should be preserved after keeping flagged post")
require.NotEmpty(t, editHistoryAfter)
require.Equal(t, editHistoryPostId, editHistoryAfter[0].Id)
// Verify the post still exists and is accessible
fetchedPost, resp, err := client.GetPost(context.Background(), post.Id, "")
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NotNil(t, fetchedPost)
require.Equal(t, post.Id, fetchedPost.Id)
})
}