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