github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/api4/system_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"os"
    12  	"strconv"
    13  	"strings"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  
    20  	"github.com/masterhung0112/hk_server/v5/model"
    21  	"github.com/masterhung0112/hk_server/v5/shared/mlog"
    22  )
    23  
    24  func TestGetPing(t *testing.T) {
    25  	th := Setup(t)
    26  	defer th.TearDown()
    27  
    28  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
    29  		t.Run("healthy", func(t *testing.T) {
    30  			status, resp := client.GetPing()
    31  			CheckNoError(t, resp)
    32  			assert.Equal(t, model.STATUS_OK, status)
    33  		})
    34  
    35  		t.Run("unhealthy", func(t *testing.T) {
    36  			goRoutineHealthThreshold := *th.App.Config().ServiceSettings.GoroutineHealthThreshold
    37  			defer func() {
    38  				th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.GoroutineHealthThreshold = goRoutineHealthThreshold })
    39  			}()
    40  
    41  			th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.GoroutineHealthThreshold = 10 })
    42  			status, resp := client.GetPing()
    43  			CheckInternalErrorStatus(t, resp)
    44  			assert.Equal(t, model.STATUS_UNHEALTHY, status)
    45  		})
    46  	}, "basic ping")
    47  
    48  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
    49  		t.Run("healthy", func(t *testing.T) {
    50  			status, resp := client.GetPingWithServerStatus()
    51  
    52  			CheckNoError(t, resp)
    53  			assert.Equal(t, model.STATUS_OK, status)
    54  		})
    55  
    56  		t.Run("unhealthy", func(t *testing.T) {
    57  			oldDriver := th.App.Config().FileSettings.DriverName
    58  			badDriver := "badDriverName"
    59  			th.App.Config().FileSettings.DriverName = &badDriver
    60  			defer func() {
    61  				th.App.Config().FileSettings.DriverName = oldDriver
    62  			}()
    63  
    64  			status, resp := client.GetPingWithServerStatus()
    65  			CheckInternalErrorStatus(t, resp)
    66  			assert.Equal(t, model.STATUS_UNHEALTHY, status)
    67  		})
    68  	}, "with server status")
    69  
    70  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
    71  		th.App.ReloadConfig()
    72  		resp, appErr := client.DoApiGet(client.GetSystemRoute()+"/ping", "")
    73  		require.Nil(t, appErr)
    74  		require.Equal(t, http.StatusOK, resp.StatusCode)
    75  		respBytes, err := ioutil.ReadAll(resp.Body)
    76  		require.NoError(t, err)
    77  		respString := string(respBytes)
    78  		require.NotContains(t, respString, "TestFeatureFlag")
    79  
    80  		// Run the environment variable override code to test
    81  		os.Setenv("MM_FEATUREFLAGS_TESTFEATURE", "testvalueunique")
    82  		defer os.Unsetenv("MM_FEATUREFLAGS_TESTFEATURE")
    83  		th.App.ReloadConfig()
    84  
    85  		resp, appErr = client.DoApiGet(client.GetSystemRoute()+"/ping", "")
    86  		require.Nil(t, appErr)
    87  		require.Equal(t, http.StatusOK, resp.StatusCode)
    88  		respBytes, err = ioutil.ReadAll(resp.Body)
    89  		require.NoError(t, err)
    90  		respString = string(respBytes)
    91  		require.Contains(t, respString, "testvalue")
    92  	}, "ping feature flag test")
    93  }
    94  
    95  func TestGetAudits(t *testing.T) {
    96  	th := Setup(t)
    97  	defer th.TearDown()
    98  	Client := th.Client
    99  
   100  	audits, resp := th.SystemAdminClient.GetAudits(0, 100, "")
   101  	CheckNoError(t, resp)
   102  	require.NotEmpty(t, audits, "should not be empty")
   103  
   104  	audits, resp = th.SystemAdminClient.GetAudits(0, 1, "")
   105  	CheckNoError(t, resp)
   106  	require.Len(t, audits, 1, "should only be 1")
   107  
   108  	audits, resp = th.SystemAdminClient.GetAudits(1, 1, "")
   109  	CheckNoError(t, resp)
   110  	require.Len(t, audits, 1, "should only be 1")
   111  
   112  	_, resp = th.SystemAdminClient.GetAudits(-1, -1, "")
   113  	CheckNoError(t, resp)
   114  
   115  	_, resp = Client.GetAudits(0, 100, "")
   116  	CheckForbiddenStatus(t, resp)
   117  
   118  	Client.Logout()
   119  	_, resp = Client.GetAudits(0, 100, "")
   120  	CheckUnauthorizedStatus(t, resp)
   121  }
   122  
   123  func TestEmailTest(t *testing.T) {
   124  	th := Setup(t)
   125  	defer th.TearDown()
   126  	Client := th.Client
   127  
   128  	dir, err := ioutil.TempDir("", "")
   129  	require.NoError(t, err)
   130  	defer os.RemoveAll(dir)
   131  
   132  	config := model.Config{
   133  		ServiceSettings: model.ServiceSettings{
   134  			SiteURL: model.NewString(""),
   135  		},
   136  		EmailSettings: model.EmailSettings{
   137  			SMTPServer:                        model.NewString(""),
   138  			SMTPPort:                          model.NewString(""),
   139  			SMTPPassword:                      model.NewString(""),
   140  			FeedbackName:                      model.NewString(""),
   141  			FeedbackEmail:                     model.NewString("some-addr@test.com"),
   142  			ReplyToAddress:                    model.NewString("some-addr@test.com"),
   143  			ConnectionSecurity:                model.NewString(""),
   144  			SMTPUsername:                      model.NewString(""),
   145  			EnableSMTPAuth:                    model.NewBool(false),
   146  			SkipServerCertificateVerification: model.NewBool(true),
   147  			SendEmailNotifications:            model.NewBool(false),
   148  			SMTPServerTimeout:                 model.NewInt(15),
   149  		},
   150  		FileSettings: model.FileSettings{
   151  			DriverName: model.NewString(model.IMAGE_DRIVER_LOCAL),
   152  			Directory:  model.NewString(dir),
   153  		},
   154  	}
   155  
   156  	t.Run("as system user", func(t *testing.T) {
   157  		_, resp := Client.TestEmail(&config)
   158  		CheckForbiddenStatus(t, resp)
   159  	})
   160  
   161  	t.Run("as system admin", func(t *testing.T) {
   162  		_, resp := th.SystemAdminClient.TestEmail(&config)
   163  		CheckErrorMessage(t, resp, "api.admin.test_email.missing_server")
   164  		CheckBadRequestStatus(t, resp)
   165  
   166  		inbucket_host := os.Getenv("CI_INBUCKET_HOST")
   167  		if inbucket_host == "" {
   168  			inbucket_host = "localhost"
   169  		}
   170  
   171  		inbucket_port := os.Getenv("CI_INBUCKET_SMTP_PORT")
   172  		if inbucket_port == "" {
   173  			inbucket_port = "10025"
   174  		}
   175  
   176  		*config.EmailSettings.SMTPServer = inbucket_host
   177  		*config.EmailSettings.SMTPPort = inbucket_port
   178  		_, resp = th.SystemAdminClient.TestEmail(&config)
   179  		CheckOKStatus(t, resp)
   180  	})
   181  
   182  	t.Run("as restricted system admin", func(t *testing.T) {
   183  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
   184  
   185  		_, resp := th.SystemAdminClient.TestEmail(&config)
   186  		CheckForbiddenStatus(t, resp)
   187  	})
   188  }
   189  
   190  func TestGenerateSupportPacket(t *testing.T) {
   191  	th := Setup(t)
   192  	defer th.TearDown()
   193  
   194  	t.Run("As a System Administrator", func(t *testing.T) {
   195  		l := model.NewTestLicense()
   196  		th.App.Srv().SetLicense(l)
   197  
   198  		file, resp := th.SystemAdminClient.GenerateSupportPacket()
   199  		require.Nil(t, resp.Error)
   200  		require.NotZero(t, len(file))
   201  	})
   202  
   203  	t.Run("As a Regular User", func(t *testing.T) {
   204  		_, resp := th.Client.GenerateSupportPacket()
   205  		CheckForbiddenStatus(t, resp)
   206  	})
   207  
   208  	t.Run("Server with no License", func(t *testing.T) {
   209  		ok, resp := th.SystemAdminClient.RemoveLicenseFile()
   210  		CheckNoError(t, resp)
   211  		require.True(t, ok)
   212  
   213  		_, resp = th.SystemAdminClient.GenerateSupportPacket()
   214  		CheckForbiddenStatus(t, resp)
   215  	})
   216  }
   217  
   218  func TestSiteURLTest(t *testing.T) {
   219  	th := Setup(t)
   220  	defer th.TearDown()
   221  	Client := th.Client
   222  
   223  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   224  		if strings.HasSuffix(r.URL.Path, "/valid/api/v4/system/ping") {
   225  			w.WriteHeader(200)
   226  		} else {
   227  			w.WriteHeader(400)
   228  		}
   229  	}))
   230  	defer ts.Close()
   231  
   232  	validSiteURL := ts.URL + "/valid"
   233  	invalidSiteURL := ts.URL + "/invalid"
   234  
   235  	t.Run("as system admin", func(t *testing.T) {
   236  		_, resp := th.SystemAdminClient.TestSiteURL("")
   237  		CheckBadRequestStatus(t, resp)
   238  
   239  		_, resp = th.SystemAdminClient.TestSiteURL(invalidSiteURL)
   240  		CheckBadRequestStatus(t, resp)
   241  
   242  		_, resp = th.SystemAdminClient.TestSiteURL(validSiteURL)
   243  		CheckOKStatus(t, resp)
   244  	})
   245  
   246  	t.Run("as system user", func(t *testing.T) {
   247  		_, resp := Client.TestSiteURL(validSiteURL)
   248  		CheckForbiddenStatus(t, resp)
   249  	})
   250  
   251  	t.Run("as restricted system admin", func(t *testing.T) {
   252  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
   253  
   254  		_, resp := Client.TestSiteURL(validSiteURL)
   255  		CheckForbiddenStatus(t, resp)
   256  	})
   257  }
   258  
   259  func TestDatabaseRecycle(t *testing.T) {
   260  	th := Setup(t)
   261  	defer th.TearDown()
   262  	Client := th.Client
   263  
   264  	t.Run("as system user", func(t *testing.T) {
   265  		_, resp := Client.DatabaseRecycle()
   266  		CheckForbiddenStatus(t, resp)
   267  	})
   268  
   269  	t.Run("as system admin", func(t *testing.T) {
   270  		_, resp := th.SystemAdminClient.DatabaseRecycle()
   271  		CheckNoError(t, resp)
   272  	})
   273  
   274  	t.Run("as restricted system admin", func(t *testing.T) {
   275  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
   276  
   277  		_, resp := th.SystemAdminClient.DatabaseRecycle()
   278  		CheckForbiddenStatus(t, resp)
   279  	})
   280  }
   281  
   282  func TestInvalidateCaches(t *testing.T) {
   283  	th := Setup(t)
   284  	defer th.TearDown()
   285  	Client := th.Client
   286  
   287  	t.Run("as system user", func(t *testing.T) {
   288  		ok, resp := Client.InvalidateCaches()
   289  		CheckForbiddenStatus(t, resp)
   290  		require.False(t, ok, "should not clean the cache due to no permission.")
   291  	})
   292  
   293  	t.Run("as system admin", func(t *testing.T) {
   294  		ok, resp := th.SystemAdminClient.InvalidateCaches()
   295  		CheckNoError(t, resp)
   296  		require.True(t, ok, "should clean the cache")
   297  	})
   298  
   299  	t.Run("as restricted system admin", func(t *testing.T) {
   300  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
   301  
   302  		ok, resp := th.SystemAdminClient.InvalidateCaches()
   303  		CheckForbiddenStatus(t, resp)
   304  		require.False(t, ok, "should not clean the cache due to no permission.")
   305  	})
   306  }
   307  
   308  func TestGetLogs(t *testing.T) {
   309  	th := Setup(t)
   310  	defer th.TearDown()
   311  
   312  	for i := 0; i < 20; i++ {
   313  		mlog.Info(strconv.Itoa(i))
   314  	}
   315  
   316  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   317  		logs, resp := c.GetLogs(0, 10)
   318  		CheckNoError(t, resp)
   319  		require.Len(t, logs, 10)
   320  
   321  		for i := 10; i < 20; i++ {
   322  			assert.Containsf(t, logs[i-10], fmt.Sprintf(`"msg":"%d"`, i), "Log line doesn't contain correct message")
   323  		}
   324  
   325  		logs, resp = c.GetLogs(1, 10)
   326  		CheckNoError(t, resp)
   327  		require.Len(t, logs, 10)
   328  
   329  		logs, resp = c.GetLogs(-1, -1)
   330  		CheckNoError(t, resp)
   331  		require.NotEmpty(t, logs, "should not be empty")
   332  	})
   333  
   334  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   335  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
   336  		_, resp := th.Client.GetLogs(0, 10)
   337  		CheckForbiddenStatus(t, resp)
   338  	})
   339  
   340  	_, resp := th.Client.GetLogs(0, 10)
   341  	CheckForbiddenStatus(t, resp)
   342  
   343  	th.Client.Logout()
   344  	_, resp = th.Client.GetLogs(0, 10)
   345  	CheckUnauthorizedStatus(t, resp)
   346  }
   347  
   348  func TestPostLog(t *testing.T) {
   349  	th := Setup(t)
   350  	defer th.TearDown()
   351  	Client := th.Client
   352  
   353  	enableDev := *th.App.Config().ServiceSettings.EnableDeveloper
   354  	defer func() {
   355  		*th.App.Config().ServiceSettings.EnableDeveloper = enableDev
   356  	}()
   357  	*th.App.Config().ServiceSettings.EnableDeveloper = true
   358  
   359  	message := make(map[string]string)
   360  	message["level"] = "ERROR"
   361  	message["message"] = "this is a test"
   362  
   363  	_, resp := Client.PostLog(message)
   364  	CheckNoError(t, resp)
   365  
   366  	*th.App.Config().ServiceSettings.EnableDeveloper = false
   367  
   368  	_, resp = Client.PostLog(message)
   369  	CheckNoError(t, resp)
   370  
   371  	*th.App.Config().ServiceSettings.EnableDeveloper = true
   372  
   373  	Client.Logout()
   374  
   375  	_, resp = Client.PostLog(message)
   376  	CheckNoError(t, resp)
   377  
   378  	*th.App.Config().ServiceSettings.EnableDeveloper = false
   379  
   380  	_, resp = Client.PostLog(message)
   381  	CheckForbiddenStatus(t, resp)
   382  
   383  	logMessage, resp := th.SystemAdminClient.PostLog(message)
   384  	CheckNoError(t, resp)
   385  	require.NotEmpty(t, logMessage, "should return the log message")
   386  
   387  }
   388  
   389  func TestGetAnalyticsOld(t *testing.T) {
   390  	th := Setup(t).InitBasic()
   391  	defer th.TearDown()
   392  	Client := th.Client
   393  
   394  	rows, resp := Client.GetAnalyticsOld("", "")
   395  	CheckForbiddenStatus(t, resp)
   396  	require.Nil(t, rows, "should be nil")
   397  	rows, resp = th.SystemAdminClient.GetAnalyticsOld("", "")
   398  	CheckNoError(t, resp)
   399  
   400  	found := false
   401  	found2 := false
   402  	for _, row := range rows {
   403  		if row.Name == "unique_user_count" {
   404  			found = true
   405  		} else if row.Name == "inactive_user_count" {
   406  			found2 = true
   407  			assert.True(t, row.Value >= 0)
   408  		}
   409  	}
   410  
   411  	assert.True(t, found, "should return unique user count")
   412  	assert.True(t, found2, "should return inactive user count")
   413  
   414  	_, resp = th.SystemAdminClient.GetAnalyticsOld("post_counts_day", "")
   415  	CheckNoError(t, resp)
   416  
   417  	_, resp = th.SystemAdminClient.GetAnalyticsOld("user_counts_with_posts_day", "")
   418  	CheckNoError(t, resp)
   419  
   420  	_, resp = th.SystemAdminClient.GetAnalyticsOld("extra_counts", "")
   421  	CheckNoError(t, resp)
   422  
   423  	rows, resp = th.SystemAdminClient.GetAnalyticsOld("", th.BasicTeam.Id)
   424  	CheckNoError(t, resp)
   425  
   426  	for _, row := range rows {
   427  		if row.Name == "inactive_user_count" {
   428  			assert.Equal(t, float64(-1), row.Value, "inactive user count should be -1 when team specified")
   429  		}
   430  	}
   431  
   432  	rows2, resp2 := th.SystemAdminClient.GetAnalyticsOld("standard", "")
   433  	CheckNoError(t, resp2)
   434  	assert.Equal(t, "total_websocket_connections", rows2[5].Name)
   435  	assert.Equal(t, float64(0), rows2[5].Value)
   436  
   437  	WebSocketClient, err := th.CreateWebSocketClient()
   438  	require.Nil(t, err)
   439  	time.Sleep(100 * time.Millisecond)
   440  	rows2, resp2 = th.SystemAdminClient.GetAnalyticsOld("standard", "")
   441  	CheckNoError(t, resp2)
   442  	assert.Equal(t, "total_websocket_connections", rows2[5].Name)
   443  	assert.Equal(t, float64(1), rows2[5].Value)
   444  
   445  	WebSocketClient.Close()
   446  
   447  	rows2, resp2 = th.SystemAdminClient.GetAnalyticsOld("standard", "")
   448  	CheckNoError(t, resp2)
   449  	assert.Equal(t, "total_websocket_connections", rows2[5].Name)
   450  	assert.Equal(t, float64(0), rows2[5].Value)
   451  
   452  	Client.Logout()
   453  	_, resp = Client.GetAnalyticsOld("", th.BasicTeam.Id)
   454  	CheckUnauthorizedStatus(t, resp)
   455  }
   456  
   457  func TestS3TestConnection(t *testing.T) {
   458  	th := Setup(t)
   459  	defer th.TearDown()
   460  	Client := th.Client
   461  
   462  	s3Host := os.Getenv("CI_MINIO_HOST")
   463  	if s3Host == "" {
   464  		s3Host = "localhost"
   465  	}
   466  
   467  	s3Port := os.Getenv("CI_MINIO_PORT")
   468  	if s3Port == "" {
   469  		s3Port = "9000"
   470  	}
   471  
   472  	s3Endpoint := fmt.Sprintf("%s:%s", s3Host, s3Port)
   473  	config := model.Config{
   474  		FileSettings: model.FileSettings{
   475  			DriverName:              model.NewString(model.IMAGE_DRIVER_S3),
   476  			AmazonS3AccessKeyId:     model.NewString(model.MINIO_ACCESS_KEY),
   477  			AmazonS3SecretAccessKey: model.NewString(model.MINIO_SECRET_KEY),
   478  			AmazonS3Bucket:          model.NewString(""),
   479  			AmazonS3Endpoint:        model.NewString(s3Endpoint),
   480  			AmazonS3Region:          model.NewString(""),
   481  			AmazonS3PathPrefix:      model.NewString(""),
   482  			AmazonS3SSL:             model.NewBool(false),
   483  		},
   484  	}
   485  
   486  	t.Run("as system user", func(t *testing.T) {
   487  		_, resp := Client.TestS3Connection(&config)
   488  		CheckForbiddenStatus(t, resp)
   489  	})
   490  
   491  	t.Run("as system admin", func(t *testing.T) {
   492  		_, resp := th.SystemAdminClient.TestS3Connection(&config)
   493  		CheckBadRequestStatus(t, resp)
   494  		require.Equal(t, resp.Error.Message, "S3 Bucket is required", "should return error - missing s3 bucket")
   495  		// If this fails, check the test configuration to ensure minio is setup with the
   496  		// `mattermost-test` bucket defined by model.MINIO_BUCKET.
   497  		*config.FileSettings.AmazonS3Bucket = model.MINIO_BUCKET
   498  		config.FileSettings.AmazonS3PathPrefix = model.NewString("")
   499  		*config.FileSettings.AmazonS3Region = "us-east-1"
   500  		_, resp = th.SystemAdminClient.TestS3Connection(&config)
   501  		CheckOKStatus(t, resp)
   502  
   503  		config.FileSettings.AmazonS3Region = model.NewString("")
   504  		_, resp = th.SystemAdminClient.TestS3Connection(&config)
   505  		CheckOKStatus(t, resp)
   506  
   507  		config.FileSettings.AmazonS3Bucket = model.NewString("Wrong_bucket")
   508  		_, resp = th.SystemAdminClient.TestS3Connection(&config)
   509  		CheckInternalErrorStatus(t, resp)
   510  		assert.Equal(t, "api.file.test_connection_s3_bucket_does_not_exist.app_error", resp.Error.Id)
   511  
   512  		*config.FileSettings.AmazonS3Bucket = "shouldnotcreatenewbucket"
   513  		_, resp = th.SystemAdminClient.TestS3Connection(&config)
   514  		CheckInternalErrorStatus(t, resp)
   515  		assert.Equal(t, "api.file.test_connection_s3_bucket_does_not_exist.app_error", resp.Error.Id)
   516  	})
   517  
   518  	t.Run("with incorrect credentials", func(t *testing.T) {
   519  		configCopy := config
   520  		*configCopy.FileSettings.AmazonS3AccessKeyId = "invalidaccesskey"
   521  		_, resp := th.SystemAdminClient.TestS3Connection(&configCopy)
   522  		CheckInternalErrorStatus(t, resp)
   523  		assert.Equal(t, "api.file.test_connection_s3_auth.app_error", resp.Error.Id)
   524  	})
   525  
   526  	t.Run("as restricted system admin", func(t *testing.T) {
   527  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
   528  
   529  		_, resp := th.SystemAdminClient.TestS3Connection(&config)
   530  		CheckForbiddenStatus(t, resp)
   531  	})
   532  }
   533  
   534  func TestSupportedTimezones(t *testing.T) {
   535  	th := Setup(t)
   536  	defer th.TearDown()
   537  	Client := th.Client
   538  
   539  	supportedTimezonesFromConfig := th.App.Timezones().GetSupported()
   540  	supportedTimezones, resp := Client.GetSupportedTimezone()
   541  
   542  	CheckNoError(t, resp)
   543  	assert.Equal(t, supportedTimezonesFromConfig, supportedTimezones)
   544  }
   545  
   546  func TestRedirectLocation(t *testing.T) {
   547  	expected := "https://mattermost.com/wp-content/themes/mattermostv2/img/logo-light.svg"
   548  
   549  	testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
   550  		res.Header().Set("Location", expected)
   551  		res.WriteHeader(http.StatusFound)
   552  		res.Write([]byte("body"))
   553  	}))
   554  	defer func() { testServer.Close() }()
   555  
   556  	mockBitlyLink := testServer.URL
   557  
   558  	th := Setup(t)
   559  	defer th.TearDown()
   560  	Client := th.Client
   561  	enableLinkPreviews := *th.App.Config().ServiceSettings.EnableLinkPreviews
   562  	defer func() {
   563  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableLinkPreviews = enableLinkPreviews })
   564  	}()
   565  
   566  	*th.App.Config().ServiceSettings.EnableLinkPreviews = true
   567  	*th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections = "127.0.0.1"
   568  
   569  	_, resp := th.SystemAdminClient.GetRedirectLocation("https://mattermost.com/", "")
   570  	CheckNoError(t, resp)
   571  
   572  	_, resp = th.SystemAdminClient.GetRedirectLocation("", "")
   573  	CheckBadRequestStatus(t, resp)
   574  
   575  	actual, resp := th.SystemAdminClient.GetRedirectLocation(mockBitlyLink, "")
   576  	CheckNoError(t, resp)
   577  	assert.Equal(t, expected, actual)
   578  
   579  	// Check cached value
   580  	actual, resp = th.SystemAdminClient.GetRedirectLocation(mockBitlyLink, "")
   581  	CheckNoError(t, resp)
   582  	assert.Equal(t, expected, actual)
   583  
   584  	*th.App.Config().ServiceSettings.EnableLinkPreviews = false
   585  	actual, resp = th.SystemAdminClient.GetRedirectLocation("https://mattermost.com/", "")
   586  	CheckNoError(t, resp)
   587  	assert.Equal(t, actual, "")
   588  
   589  	actual, resp = th.SystemAdminClient.GetRedirectLocation("", "")
   590  	CheckNoError(t, resp)
   591  	assert.Equal(t, actual, "")
   592  
   593  	actual, resp = th.SystemAdminClient.GetRedirectLocation(mockBitlyLink, "")
   594  	CheckNoError(t, resp)
   595  	assert.Equal(t, actual, "")
   596  
   597  	Client.Logout()
   598  	_, resp = Client.GetRedirectLocation("", "")
   599  	CheckUnauthorizedStatus(t, resp)
   600  }
   601  
   602  func TestSetServerBusy(t *testing.T) {
   603  	th := Setup(t)
   604  	defer th.TearDown()
   605  
   606  	const secs = 30
   607  
   608  	t.Run("as system user", func(t *testing.T) {
   609  		ok, resp := th.Client.SetServerBusy(secs)
   610  		CheckForbiddenStatus(t, resp)
   611  		require.False(t, ok, "should not set server busy due to no permission")
   612  		require.False(t, th.App.Srv().Busy.IsBusy(), "server should not be marked busy")
   613  	})
   614  
   615  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   616  		ok, resp := c.SetServerBusy(secs)
   617  		CheckNoError(t, resp)
   618  		require.True(t, ok, "should set server busy successfully")
   619  		require.True(t, th.App.Srv().Busy.IsBusy(), "server should be marked busy")
   620  	}, "as system admin")
   621  }
   622  
   623  func TestSetServerBusyInvalidParam(t *testing.T) {
   624  	th := Setup(t)
   625  	defer th.TearDown()
   626  
   627  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   628  		params := []int{-1, 0, MaxServerBusySeconds + 1}
   629  		for _, p := range params {
   630  			ok, resp := c.SetServerBusy(p)
   631  			CheckBadRequestStatus(t, resp)
   632  			require.False(t, ok, "should not set server busy due to invalid param ", p)
   633  			require.False(t, th.App.Srv().Busy.IsBusy(), "server should not be marked busy due to invalid param ", p)
   634  		}
   635  	}, "as system admin, invalid param")
   636  }
   637  
   638  func TestClearServerBusy(t *testing.T) {
   639  	th := Setup(t)
   640  	defer th.TearDown()
   641  
   642  	th.App.Srv().Busy.Set(time.Second * 30)
   643  	t.Run("as system user", func(t *testing.T) {
   644  		ok, resp := th.Client.ClearServerBusy()
   645  		CheckForbiddenStatus(t, resp)
   646  		require.False(t, ok, "should not clear server busy flag due to no permission.")
   647  		require.True(t, th.App.Srv().Busy.IsBusy(), "server should be marked busy")
   648  	})
   649  
   650  	th.App.Srv().Busy.Set(time.Second * 30)
   651  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   652  		ok, resp := c.ClearServerBusy()
   653  		CheckNoError(t, resp)
   654  		require.True(t, ok, "should clear server busy flag successfully")
   655  		require.False(t, th.App.Srv().Busy.IsBusy(), "server should not be marked busy")
   656  	}, "as system admin")
   657  }
   658  
   659  func TestGetServerBusy(t *testing.T) {
   660  	th := Setup(t)
   661  	defer th.TearDown()
   662  
   663  	th.App.Srv().Busy.Set(time.Second * 30)
   664  
   665  	t.Run("as system user", func(t *testing.T) {
   666  		_, resp := th.Client.GetServerBusy()
   667  		CheckForbiddenStatus(t, resp)
   668  	})
   669  
   670  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   671  		sbs, resp := c.GetServerBusy()
   672  		expires := time.Unix(sbs.Expires, 0)
   673  		CheckNoError(t, resp)
   674  		require.Greater(t, expires.Unix(), time.Now().Unix())
   675  	}, "as system admin")
   676  }
   677  
   678  func TestGetServerBusyExpires(t *testing.T) {
   679  	th := Setup(t)
   680  	defer th.TearDown()
   681  
   682  	th.App.Srv().Busy.Set(time.Second * 30)
   683  
   684  	t.Run("as system user", func(t *testing.T) {
   685  		_, resp := th.Client.GetServerBusyExpires()
   686  		CheckForbiddenStatus(t, resp)
   687  	})
   688  
   689  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   690  		expires, resp := c.GetServerBusyExpires()
   691  		CheckNoError(t, resp)
   692  		require.Greater(t, expires.Unix(), time.Now().Unix())
   693  	}, "as system admin")
   694  }
   695  
   696  func TestServerBusy503(t *testing.T) {
   697  	th := Setup(t)
   698  	defer th.TearDown()
   699  
   700  	th.App.Srv().Busy.Set(time.Second * 30)
   701  
   702  	t.Run("search users while busy", func(t *testing.T) {
   703  		us := &model.UserSearch{Term: "test"}
   704  		_, resp := th.SystemAdminClient.SearchUsers(us)
   705  		CheckServiceUnavailableStatus(t, resp)
   706  	})
   707  
   708  	t.Run("search teams while busy", func(t *testing.T) {
   709  		ts := &model.TeamSearch{}
   710  		_, resp := th.SystemAdminClient.SearchTeams(ts)
   711  		CheckServiceUnavailableStatus(t, resp)
   712  	})
   713  
   714  	t.Run("search channels while busy", func(t *testing.T) {
   715  		cs := &model.ChannelSearch{}
   716  		_, resp := th.SystemAdminClient.SearchChannels("foo", cs)
   717  		CheckServiceUnavailableStatus(t, resp)
   718  	})
   719  
   720  	t.Run("search archived channels while busy", func(t *testing.T) {
   721  		cs := &model.ChannelSearch{}
   722  		_, resp := th.SystemAdminClient.SearchArchivedChannels("foo", cs)
   723  		CheckServiceUnavailableStatus(t, resp)
   724  	})
   725  
   726  	th.App.Srv().Busy.Clear()
   727  
   728  	t.Run("search users while not busy", func(t *testing.T) {
   729  		us := &model.UserSearch{Term: "test"}
   730  		_, resp := th.SystemAdminClient.SearchUsers(us)
   731  		CheckNoError(t, resp)
   732  	})
   733  }
   734  
   735  func TestPushNotificationAck(t *testing.T) {
   736  	th := Setup(t)
   737  	api := Init(th.App, th.Server.Router)
   738  	session, _ := th.App.GetSession(th.Client.AuthToken)
   739  	defer th.TearDown()
   740  	t.Run("should return error when the ack body is not passed", func(t *testing.T) {
   741  		handler := api.ApiHandler(pushNotificationAck)
   742  		resp := httptest.NewRecorder()
   743  		req := httptest.NewRequest("POST", "/api/v4/notifications/ack", nil)
   744  		req.Header.Set(model.HEADER_AUTH, "Bearer "+session.Token)
   745  
   746  		handler.ServeHTTP(resp, req)
   747  		assert.Equal(t, http.StatusBadRequest, resp.Code)
   748  		assert.NotNil(t, resp.Body)
   749  	})
   750  }