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 }