github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/msg_int_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/ActiveState/cli/internal/constants"
     9  	"github.com/ActiveState/cli/internal/fileutils"
    10  	"github.com/ActiveState/cli/internal/graph"
    11  	"github.com/ActiveState/cli/internal/testhelpers/e2e"
    12  	"github.com/ActiveState/cli/internal/testhelpers/suite"
    13  	"github.com/ActiveState/cli/internal/testhelpers/tagsuite"
    14  )
    15  
    16  type MsgIntegrationTestSuite struct {
    17  	tagsuite.Suite
    18  }
    19  
    20  func (suite *MsgIntegrationTestSuite) TestMessage_None() {
    21  	suite.OnlyRunForTags(tagsuite.Messaging, tagsuite.Critical)
    22  	ts := e2e.New(suite.T(), false)
    23  	defer ts.Close()
    24  
    25  	// We test on config as it just dumps help and has minimal output
    26  	// The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long
    27  	cp := ts.SpawnWithOpts(e2e.OptArgs("config"))
    28  	cp.Expect("Usage:")
    29  	cp.ExpectExitCode(0)
    30  
    31  	// Note: since message failures should fail silently without impacting the user we need to check
    32  	// the logs for any potential issues. This is done automatically by ts.Close().
    33  }
    34  
    35  func (suite *MsgIntegrationTestSuite) TestMessage_Basic() {
    36  	suite.OnlyRunForTags(tagsuite.Messaging, tagsuite.Critical)
    37  	tests := []struct {
    38  		Name         string
    39  		MessageJson  string
    40  		ExpectRepeat bool
    41  	}{
    42  		{
    43  			"Defaults",
    44  			`[{
    45  				"ID": "simple",
    46  				"Message": "This is a [NOTICE]simple[/RESET] message"
    47  			}]`,
    48  			false,
    49  		},
    50  		{
    51  			"Repeat Hourly",
    52  			`[{
    53  				"ID": "simple",
    54  				"Message": "This is a [NOTICE]simple[/RESET] message",
    55  				"Repeat": "Hourly"
    56  			}]`,
    57  			false,
    58  		},
    59  		{
    60  			"Repeat Constantly",
    61  			`[{
    62  				"ID": "simple",
    63  				"Message": "This is a [NOTICE]simple[/RESET] message",
    64  				"Repeat": "Constantly"
    65  			}]`,
    66  			true,
    67  		},
    68  	}
    69  	for _, tt := range tests {
    70  		suite.Run(tt.Name, func() {
    71  			ts := e2e.New(suite.T(), false)
    72  			defer ts.Close()
    73  
    74  			msgFile, err := fileutils.WriteTempFileToDir(ts.Dirs.Work, "messages.json", []byte(tt.MessageJson), 0755)
    75  			suite.Require().NoError(err)
    76  
    77  			// We test on config as it just dumps help and has minimal output
    78  			// The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long
    79  			cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile))
    80  			cp.Expect(`This is a simple message`)
    81  			cp.Expect("Usage:")
    82  			cp.ExpectExitCode(0)
    83  
    84  			// Ensure message doesn't stick around when we run another command
    85  			cp = ts.Spawn("--version")
    86  			if tt.ExpectRepeat {
    87  				cp.Expect(`This is a simple message`)
    88  			}
    89  			cp.ExpectExitCode(0)
    90  			if !tt.ExpectRepeat {
    91  				suite.Require().NotContains(cp.Output(), "This is a simple message", "Should not repeat as that's the default behavior")
    92  			}
    93  		})
    94  	}
    95  }
    96  
    97  func (suite *MsgIntegrationTestSuite) TestMessage_Basic_PlacementAfter() {
    98  	suite.OnlyRunForTags(tagsuite.Messaging)
    99  	ts := e2e.New(suite.T(), false)
   100  	defer ts.Close()
   101  
   102  	msgFile, err := fileutils.WriteTempFileToDir(ts.Dirs.Work, "messages.json", []byte(fmt.Sprintf(`[
   103  	{
   104  		"ID": "simple",
   105  		"Message": "This is a [NOTICE]simple[/RESET] message",
   106  		"Placement": "%s"
   107  	}
   108  ]`, graph.MessagePlacementTypeAfterCmd)), 0755)
   109  	suite.Require().NoError(err)
   110  
   111  	// We test on config as it just dumps help and has minimal output
   112  	// The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long
   113  	cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile))
   114  	cp.Expect("Usage:")
   115  	cp.Expect(`This is a simple message`)
   116  	cp.ExpectExitCode(0)
   117  }
   118  
   119  func (suite *MsgIntegrationTestSuite) TestMessage_Basic_InterruptPrompt() {
   120  	suite.OnlyRunForTags(tagsuite.Messaging)
   121  	ts := e2e.New(suite.T(), false)
   122  	defer ts.Close()
   123  
   124  	msgFile, err := fileutils.WriteTempFileToDir(ts.Dirs.Work, "messages.json", []byte(fmt.Sprintf(`[
   125  	{
   126  		"ID": "simple",
   127  		"Message": "This is a [NOTICE]simple[/RESET] message",
   128  		"Repeat": "Constantly",
   129  		"Interrupt": "%s"
   130  	}
   131  ]`, graph.MessageInterruptTypePrompt)), 0755)
   132  	suite.Require().NoError(err)
   133  
   134  	cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile))
   135  	cp.Expect(`This is a simple message`)
   136  	cp.Expect("Press ENTER to continue")
   137  	time.Sleep(time.Millisecond * 100)
   138  	suite.Require().NotContains(cp.Output(), "Usage:")
   139  	cp.SendEnter()
   140  	cp.Expect("Usage:")
   141  	cp.ExpectExitCode(0)
   142  
   143  	// Test that non-interactive does not prompt
   144  	cp = ts.SpawnWithOpts(e2e.OptArgs("config", "-n"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile))
   145  	cp.Expect(`This is a simple message`)
   146  	cp.Expect("Usage:")
   147  	cp.ExpectExitCode(0)
   148  	suite.Require().NotContains(cp.Output(), "Press ENTER to continue")
   149  }
   150  
   151  func (suite *MsgIntegrationTestSuite) TestMessage_Basic_InterruptExit() {
   152  	suite.OnlyRunForTags(tagsuite.Messaging)
   153  	ts := e2e.New(suite.T(), false)
   154  	defer ts.Close()
   155  
   156  	msgFile, err := fileutils.WriteTempFileToDir(ts.Dirs.Work, "messages.json", []byte(fmt.Sprintf(`[
   157  	{
   158  		"ID": "simple",
   159  		"Message": "This is a [NOTICE]simple[/RESET] message",
   160  		"Interrupt": "%s"
   161  	}
   162  ]`, graph.MessageInterruptTypeExit)), 0755)
   163  	suite.Require().NoError(err)
   164  
   165  	cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile))
   166  	cp.ExpectExitCode(1)
   167  	suite.Require().Contains(cp.Snapshot(), "This is a simple message")
   168  	suite.Require().NotContains(cp.Output(), "Usage:")
   169  	ts.IgnoreLogErrors()
   170  }
   171  
   172  func TestMsgIntegrationTestSuite(t *testing.T) {
   173  	suite.Run(t, new(MsgIntegrationTestSuite))
   174  }