github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/cmd/mattermost/commands/command_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package commands
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/mattermost/mattermost-server/v5/model"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestCreateCommand(t *testing.T) {
    15  	th := Setup(t).InitBasic()
    16  	defer th.TearDown()
    17  
    18  	config := th.Config()
    19  	*config.ServiceSettings.EnableCommands = true
    20  	th.SetConfig(config)
    21  
    22  	team := th.BasicTeam
    23  	adminUser := th.TeamAdminUser
    24  	user := th.BasicUser
    25  
    26  	testCases := []struct {
    27  		Description string
    28  		Args        []string
    29  		ExpectedErr string
    30  	}{
    31  		{
    32  			"nil error",
    33  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    34  			"",
    35  		},
    36  		{
    37  			"Team not specified",
    38  			[]string{"command", "create", "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    39  			"Error: requires at least 1 arg(s), only received 0",
    40  		},
    41  		{
    42  			"Team not found",
    43  			[]string{"command", "create", "fakeTeam", "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    44  			"Error: unable to find team",
    45  		},
    46  		{
    47  			"Creator not specified",
    48  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler"},
    49  			`Error: required flag(s) "creator" not set`,
    50  		},
    51  		{
    52  			"Creator not found",
    53  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", "fakeuser"},
    54  			"unable to find user",
    55  		},
    56  		{
    57  			"Creator not team admin",
    58  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", user.Username},
    59  			"the creator must be a user who has permissions to manage slash commands",
    60  		},
    61  		{
    62  			"Command not specified",
    63  			[]string{"command", "", team.Name, "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    64  			"Error: unknown flag: --trigger-word",
    65  		},
    66  		{
    67  			"Trigger not specified",
    68  			[]string{"command", "create", team.Name, "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    69  			`Error: required flag(s) "trigger-word" not set`,
    70  		},
    71  		{
    72  			"Blank trigger",
    73  			[]string{"command", "create", team.Name, "--trigger-word", "", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    74  			"Invalid trigger",
    75  		},
    76  		{
    77  			"Trigger with space",
    78  			[]string{"command", "create", team.Name, "--trigger-word", "test cmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    79  			"Error: a trigger word must not contain spaces",
    80  		},
    81  		{
    82  			"Trigger starting with /",
    83  			[]string{"command", "create", team.Name, "--trigger-word", "/testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    84  			"Error: a trigger word cannot begin with a /",
    85  		},
    86  		{
    87  			"URL not specified",
    88  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd", "--creator", adminUser.Username},
    89  			`Error: required flag(s) "url" not set`,
    90  		},
    91  		{
    92  			"Blank URL",
    93  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd2", "--url", "", "--creator", adminUser.Username},
    94  			"Invalid URL",
    95  		},
    96  		{
    97  			"Invalid URL",
    98  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd2", "--url", "localhost:8000/my-slash-handler", "--creator", adminUser.Username},
    99  			"Invalid URL",
   100  		},
   101  		{
   102  			"Duplicate Command",
   103  			[]string{"command", "create", team.Name, "--trigger-word", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
   104  			"This trigger word is already in use",
   105  		},
   106  		{
   107  			"Misspelled flag",
   108  			[]string{"command", "create", team.Name, "--trigger-wor", "testcmd", "--url", "http://localhost:8000/my-slash-handler", "--creator", adminUser.Username},
   109  			"Error: unknown flag:",
   110  		},
   111  	}
   112  
   113  	for _, testCase := range testCases {
   114  		t.Run(testCase.Description, func(t *testing.T) {
   115  			actual, _ := th.RunCommandWithOutput(t, testCase.Args...)
   116  
   117  			cmds, response := th.SystemAdminClient.ListCommands(team.Id, true)
   118  
   119  			require.Nil(t, response.Error, "Failed to list commands")
   120  
   121  			if testCase.ExpectedErr == "" {
   122  				assert.NotZero(t, len(cmds), "Failed to create command")
   123  				assert.Equal(t, cmds[0].Trigger, "testcmd", "Failed to create command")
   124  				assert.Contains(t, actual, "PASS")
   125  			} else {
   126  				assert.LessOrEqual(t, len(cmds), 1, "Created command that shouldn't have been created")
   127  				assert.Contains(t, actual, testCase.ExpectedErr)
   128  			}
   129  		})
   130  	}
   131  }
   132  
   133  func TestShowCommand(t *testing.T) {
   134  	th := Setup(t).InitBasic()
   135  	defer th.TearDown()
   136  
   137  	url := "http://localhost:8000/test-command"
   138  	team := th.BasicTeam
   139  	user := th.BasicUser
   140  	th.LinkUserToTeam(user, team)
   141  	trigger := "trigger_" + model.NewId()
   142  	displayName := "dn_" + model.NewId()
   143  
   144  	c := &model.Command{
   145  		DisplayName: displayName,
   146  		Method:      "G",
   147  		TeamId:      team.Id,
   148  		Username:    user.Username,
   149  		CreatorId:   user.Id,
   150  		URL:         url,
   151  		Trigger:     trigger,
   152  	}
   153  
   154  	t.Run("existing command", func(t *testing.T) {
   155  		command, err := th.App.CreateCommand(c)
   156  		require.Nil(t, err)
   157  		commands, err := th.App.ListTeamCommands(team.Id)
   158  		require.Nil(t, err)
   159  		assert.Equal(t, len(commands), 1)
   160  
   161  		output := th.CheckCommand(t, "command", "show", command.Id)
   162  		assert.Contains(t, output, command.Id)
   163  		assert.Contains(t, output, command.TeamId)
   164  		assert.Contains(t, output, trigger)
   165  		assert.Contains(t, output, displayName)
   166  		assert.Contains(t, output, user.Username)
   167  	})
   168  
   169  	t.Run("not existing command", func(t *testing.T) {
   170  		assert.Error(t, th.RunCommand(t, "command", "show", "invalid"))
   171  	})
   172  
   173  	t.Run("no commandID", func(t *testing.T) {
   174  		assert.Error(t, th.RunCommand(t, "command", "show"))
   175  	})
   176  }
   177  
   178  func TestDeleteCommand(t *testing.T) {
   179  	// Skipped due to v5.6 RC build issues.
   180  	t.Skip()
   181  
   182  	th := Setup(t).InitBasic()
   183  	defer th.TearDown()
   184  	url := "http://localhost:8000/test-command"
   185  	team := th.BasicTeam
   186  	user := th.BasicUser
   187  	th.LinkUserToTeam(user, team)
   188  
   189  	c := &model.Command{
   190  		DisplayName: "dn_" + model.NewId(),
   191  		Method:      "G",
   192  		TeamId:      team.Id,
   193  		Username:    user.Username,
   194  		CreatorId:   user.Id,
   195  		URL:         url,
   196  		Trigger:     "trigger_" + model.NewId(),
   197  	}
   198  
   199  	t.Run("existing command", func(t *testing.T) {
   200  		command, err := th.App.CreateCommand(c)
   201  		require.Nil(t, err)
   202  		commands, err := th.App.ListTeamCommands(team.Id)
   203  		require.Nil(t, err)
   204  		assert.Equal(t, len(commands), 1)
   205  
   206  		th.CheckCommand(t, "command", "delete", command.Id)
   207  		commands, err = th.App.ListTeamCommands(team.Id)
   208  		require.Nil(t, err)
   209  		assert.Equal(t, len(commands), 0)
   210  	})
   211  
   212  	t.Run("not existing command", func(t *testing.T) {
   213  		assert.Error(t, th.RunCommand(t, "command", "delete", "invalid"))
   214  	})
   215  }
   216  
   217  func TestModifyCommand(t *testing.T) {
   218  	th := Setup(t).InitBasic()
   219  	defer th.TearDown()
   220  
   221  	// set config
   222  	config := th.Config()
   223  	*config.ServiceSettings.EnableCommands = true
   224  	th.SetConfig(config)
   225  
   226  	// set team and users
   227  	team := th.BasicTeam
   228  	adminUser := th.TeamAdminUser
   229  	user := th.BasicUser
   230  
   231  	// create test command to modify
   232  	url := "http://localhost:8000/test-command"
   233  	th.LinkUserToTeam(user, team)
   234  	trigger := "trigger_" + model.NewId()
   235  	displayName := "dn_" + model.NewId()
   236  
   237  	c := &model.Command{
   238  		DisplayName: displayName,
   239  		Method:      "G",
   240  		TeamId:      team.Id,
   241  		Username:    user.Username,
   242  		CreatorId:   user.Id,
   243  		URL:         url,
   244  		Trigger:     trigger,
   245  	}
   246  
   247  	command, err := th.App.CreateCommand(c)
   248  	require.Nil(t, err)
   249  	commands, err := th.App.ListTeamCommands(team.Id)
   250  	require.Nil(t, err)
   251  	assert.Equal(t, len(commands), 1)
   252  
   253  	t.Run("command not specified", func(t *testing.T) {
   254  		args := []string{"command", "", command.Id, "--trigger-word", "sometrigger"}
   255  		output, _ := th.RunCommandWithOutput(t, args...)
   256  		assert.Contains(t, output, "Error: unknown flag: --trigger-word")
   257  	})
   258  
   259  	t.Run("modify command unchanged", func(t *testing.T) {
   260  		args := []string{"command", "modify", command.Id}
   261  		output, _ := th.RunCommandWithOutput(t, args...)
   262  		cmd, _ := th.App.GetCommand(command.Id)
   263  		assert.Contains(t, output, "PASS")
   264  		assert.Equal(t, cmd.DisplayName, command.DisplayName)
   265  		assert.Equal(t, cmd.Method, command.Method)
   266  		assert.Equal(t, cmd.TeamId, command.TeamId)
   267  		assert.Equal(t, cmd.Username, command.Username)
   268  		assert.Equal(t, cmd.CreatorId, command.CreatorId)
   269  		assert.Equal(t, cmd.URL, command.URL)
   270  		assert.Equal(t, cmd.Trigger, command.Trigger)
   271  		assert.Equal(t, cmd.AutoComplete, command.AutoComplete)
   272  		assert.Equal(t, cmd.AutoCompleteDesc, command.AutoCompleteDesc)
   273  		assert.Equal(t, cmd.AutoCompleteHint, command.AutoCompleteHint)
   274  		assert.Equal(t, cmd.IconURL, command.IconURL)
   275  	})
   276  
   277  	t.Run("misspelled flag", func(t *testing.T) {
   278  		args := []string{"command", "", command.Id, "--trigger-wor", "sometrigger"}
   279  		output, _ := th.RunCommandWithOutput(t, args...)
   280  		assert.Contains(t, output, "Error: unknown flag:")
   281  	})
   282  
   283  	t.Run("multiple flags nil error", func(t *testing.T) {
   284  		testName := "multitrigger"
   285  		testURL := "http://localhost:8000/test-modify"
   286  		testDescription := "multiple field test"
   287  		args := []string{"command", "modify", command.Id, "--trigger-word", testName, "--url", testURL, "--description", testDescription}
   288  		output, _ := th.RunCommandWithOutput(t, args...)
   289  		cmd, _ := th.App.GetCommand(command.Id)
   290  		assert.Contains(t, output, "PASS")
   291  		assert.Equal(t, cmd.Trigger, testName)
   292  		assert.Equal(t, cmd.URL, testURL)
   293  		assert.Equal(t, cmd.Description, testDescription)
   294  	})
   295  
   296  	t.Run("displayname nil error", func(t *testing.T) {
   297  		testVal := "newName"
   298  		args := []string{"command", "modify", command.Id, "--title", testVal}
   299  		output, _ := th.RunCommandWithOutput(t, args...)
   300  		cmd, _ := th.App.GetCommand(command.Id)
   301  		assert.Contains(t, output, "PASS")
   302  		assert.Equal(t, cmd.DisplayName, testVal)
   303  	})
   304  
   305  	t.Run("description nil error", func(t *testing.T) {
   306  		testVal := "test description"
   307  		args := []string{"command", "modify", command.Id, "--description", testVal}
   308  		output, _ := th.RunCommandWithOutput(t, args...)
   309  		cmd, _ := th.App.GetCommand(command.Id)
   310  		assert.Contains(t, output, "PASS")
   311  		assert.Equal(t, cmd.Description, testVal)
   312  	})
   313  
   314  	t.Run("trigger nil error", func(t *testing.T) {
   315  		testVal := "testtrigger"
   316  		args := []string{"command", "modify", command.Id, "--trigger-word", testVal}
   317  		output, _ := th.RunCommandWithOutput(t, args...)
   318  		cmd, _ := th.App.GetCommand(command.Id)
   319  		assert.Contains(t, output, "PASS")
   320  		assert.Equal(t, cmd.Trigger, testVal)
   321  	})
   322  
   323  	t.Run("trigger with space", func(t *testing.T) {
   324  		testVal := "bad trigger"
   325  		args := []string{"command", "modify", command.Id, "--trigger-word", testVal}
   326  		output, _ := th.RunCommandWithOutput(t, args...)
   327  		assert.Contains(t, output, "Error: a trigger word must not contain spaces")
   328  	})
   329  
   330  	t.Run("trigger with leading /", func(t *testing.T) {
   331  		testVal := "/bad-trigger"
   332  		args := []string{"command", "modify", command.Id, "--trigger-word", testVal}
   333  		output, _ := th.RunCommandWithOutput(t, args...)
   334  		assert.Contains(t, output, "Error: a trigger word cannot begin with a /")
   335  	})
   336  
   337  	t.Run("blank trigger", func(t *testing.T) {
   338  		cmd_unmodified, _ := th.App.GetCommand(command.Id)
   339  		args := []string{"command", "modify", command.Id, "--trigger-word", ""}
   340  		output, _ := th.RunCommandWithOutput(t, args...)
   341  		cmd_modified, _ := th.App.GetCommand(command.Id)
   342  
   343  		// assert trigger remains unchanged
   344  		assert.Contains(t, output, "PASS")
   345  		assert.Equal(t, cmd_unmodified.Trigger, cmd_modified.Trigger)
   346  	})
   347  
   348  	//url case
   349  	t.Run("url nil error", func(t *testing.T) {
   350  		testVal := "http://localhost:8000/modify-command"
   351  		args := []string{"command", "modify", command.Id, "--url", testVal}
   352  		output, _ := th.RunCommandWithOutput(t, args...)
   353  		cmd, _ := th.App.GetCommand(command.Id)
   354  		assert.Contains(t, output, "PASS")
   355  		assert.Equal(t, cmd.URL, testVal)
   356  	})
   357  
   358  	t.Run("blank url", func(t *testing.T) {
   359  		cmd_unmodified, _ := th.App.GetCommand(command.Id)
   360  		args := []string{"command", "modify", command.Id, "--url", ""}
   361  		output, _ := th.RunCommandWithOutput(t, args...)
   362  		cmd_modified, _ := th.App.GetCommand(command.Id)
   363  
   364  		//assert URL remains unchanged
   365  		assert.Contains(t, output, "PASS")
   366  		assert.Equal(t, cmd_unmodified.URL, cmd_modified.URL)
   367  	})
   368  
   369  	t.Run("icon url nil error", func(t *testing.T) {
   370  		testVal := "http://localhost:8000/testicon.png"
   371  		args := []string{"command", "modify", command.Id, "--icon", testVal}
   372  		output, _ := th.RunCommandWithOutput(t, args...)
   373  		cmd, _ := th.App.GetCommand(command.Id)
   374  		assert.Contains(t, output, "PASS")
   375  		assert.Equal(t, cmd.IconURL, testVal)
   376  	})
   377  
   378  	t.Run("creator nil error", func(t *testing.T) {
   379  		testVal := adminUser
   380  		args := []string{"command", "modify", command.Id, "--creator", testVal.Username}
   381  		output, _ := th.RunCommandWithOutput(t, args...)
   382  		cmd, _ := th.App.GetCommand(command.Id)
   383  		assert.Contains(t, output, "PASS")
   384  		assert.Equal(t, cmd.CreatorId, testVal.Id)
   385  	})
   386  
   387  	t.Run("creator not found", func(t *testing.T) {
   388  		testVal := "fakeuser"
   389  		args := []string{"command", "modify", command.Id, "--creator", testVal}
   390  		output, _ := th.RunCommandWithOutput(t, args...)
   391  		assert.Contains(t, output, "unable to find user")
   392  	})
   393  
   394  	t.Run("creator not admin user", func(t *testing.T) {
   395  		testVal := user.Username
   396  		args := []string{"command", "modify", command.Id, "--creator", testVal}
   397  		output, _ := th.RunCommandWithOutput(t, args...)
   398  		assert.Contains(t, output, "the creator must be a user who has permissions to manage slash commands")
   399  	})
   400  
   401  	t.Run("response username nil error", func(t *testing.T) {
   402  		testVal := "response-test"
   403  		args := []string{"command", "modify", command.Id, "--response-username", testVal}
   404  		output, _ := th.RunCommandWithOutput(t, args...)
   405  		cmd, _ := th.App.GetCommand(command.Id)
   406  		assert.Contains(t, output, "PASS")
   407  		assert.Equal(t, cmd.Username, testVal)
   408  	})
   409  
   410  	t.Run("post set and unset", func(t *testing.T) {
   411  		args_set := []string{"command", "modify", command.Id, "--post", ""}
   412  		args_unset := []string{"command", "modify", command.Id, "", ""}
   413  
   414  		// set post and check
   415  		output_set, _ := th.RunCommandWithOutput(t, args_set...)
   416  		cmd_set, _ := th.App.GetCommand(command.Id)
   417  		assert.Contains(t, output_set, "PASS")
   418  		assert.Equal(t, cmd_set.Method, "P")
   419  
   420  		// unset post and check
   421  		output_unset, _ := th.RunCommandWithOutput(t, args_unset...)
   422  		cmd_unset, _ := th.App.GetCommand(command.Id)
   423  		assert.Contains(t, output_unset, "PASS")
   424  		assert.Equal(t, cmd_unset.Method, "G")
   425  	})
   426  
   427  	t.Run("autocomplete set and unset", func(t *testing.T) {
   428  		args_set := []string{"command", "modify", command.Id, "--autocomplete", ""}
   429  		args_unset := []string{"command", "modify", command.Id, "", ""}
   430  
   431  		// set autocomplete and check
   432  		output_set, _ := th.RunCommandWithOutput(t, args_set...)
   433  		cmd_set, _ := th.App.GetCommand(command.Id)
   434  		assert.Contains(t, output_set, "PASS")
   435  		assert.Equal(t, cmd_set.AutoComplete, true)
   436  
   437  		// unset autocomplete and check
   438  		output_unset, _ := th.RunCommandWithOutput(t, args_unset...)
   439  		cmd_unset, _ := th.App.GetCommand(command.Id)
   440  		assert.Contains(t, output_unset, "PASS")
   441  		assert.Equal(t, cmd_unset.AutoComplete, false)
   442  	})
   443  }