diff --git a/e2e/vidit_test.go b/e2e/vidit_test.go index e98b276..45fa49a 100644 --- a/e2e/vidit_test.go +++ b/e2e/vidit_test.go @@ -389,6 +389,254 @@ func TestVidit_MainFlow(t *testing.T) { t.Log(string(b)) } +func TestVidit_Login(t *testing.T) { + // -------------------------------------------------------------------------------------- + // Prepare remote config and serve it + b, err := os.ReadFile("cert.pem") + require.NoError(t, err) + + remoteConfig := fmt.Sprintf(testRCFG, base64.StdEncoding.EncodeToString(b)) + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, errW := w.Write([]byte(remoteConfig)) + require.NoError(t, errW) + })) + defer srv.Close() + + // -------------------------------------------------------------------------------------- + // Init tool + homeDir := t.TempDir() + vidit, err := tool.NewWithConfig(tool.Config{ + EnforceHomeDir: homeDir, + FilePickerDir: homeDir, + EarlyInit: true, + }) + require.NoError(t, err) + require.NotNil(t, vidit) + + // -------------------------------------------------------------------------------------- + // Create teatest program + tm := teatest.NewTestModel(t, vidit, teatest.WithInitialTermSize(300, 100)) + + // -------------------------------------------------------------------------------------- + // Run tool + errc := make(chan error) + wg := &sync.WaitGroup{} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + wg.Add(1) + go vidit.RunWithProgram(ctx, wg, errc, tm.GetProgram()) + go func() { + for { + select { + case errR := <-errc: + require.NoError(t, errR) + case <-ctx.Done(): + return + } + } + }() + + // -------------------------------------------------------------------------------------- + // Here should be config screen + teatest.WaitFor(t, tm.Output(), func(bts []byte) bool { + return bytes.Contains(bts, []byte("Configure ViDi endpoint URL")) + }, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3)) + t.Log("config screen showed") + + // enter endpoint + tm.Send(tea.KeyMsg{ + Type: tea.KeyRunes, + Runes: []rune(srv.URL), + }) + time.Sleep(time.Millisecond * 200) + // press enter + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + + // -------------------------------------------------------------------------------------- + // Here should be new user screen + teatest.WaitFor(t, tm.Output(), func(bts []byte) bool { + // t.Log(string(bts)) + return bytes.Contains(bts, []byte("No locally stored users have found")) + }, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3)) + t.Log("new user screen showed") + + // choose login + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + + // -------------------------------------------------------------------------------------- + // Here should be new user screen, second stage + teatest.WaitFor(t, tm.Output(), func(bts []byte) bool { + return bytes.Contains(bts, []byte("Provide user credentials")) + }, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3)) + t.Log("new user second screen showed") + + // enter creds + tm.Send(tea.KeyMsg{ + Type: tea.KeyRunes, + Runes: []rune(VIDITe2eUser), + }) + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyRunes, + Runes: []rune(VIDITe2ePassword), + }) + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + time.Sleep(time.Millisecond * 200) + // confirm + tm.Send(tea.KeyMsg{ + Type: tea.KeyLeft, + }) + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + + // -------------------------------------------------------------------------------------- + // Here should be main screen + teatest.WaitFor(t, tm.Output(), func(bts []byte) bool { + return bytes.Contains(bts, []byte("Welcome to Vidi terminal tool")) + }, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3)) + t.Log("main menu screen showed") + + // -------------------------------------------------------------------------------------- + // Cleanup + cancel() + wg.Wait() + + b, err = os.ReadFile(homeDir + "/log.json") + require.NoError(t, err) + t.Log(string(b)) +} + +func TestVidit_LoginExistingUser(t *testing.T) { + // -------------------------------------------------------------------------------------- + // Prepare remote config and serve it + b, err := os.ReadFile("cert.pem") + require.NoError(t, err) + + remoteConfig := fmt.Sprintf(testRCFG, base64.StdEncoding.EncodeToString(b)) + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, errW := w.Write([]byte(remoteConfig)) + require.NoError(t, errW) + })) + defer srv.Close() + + // -------------------------------------------------------------------------------------- + // Init tool + homeDir := t.TempDir() + savedState := fmt.Sprintf(`{"endpoint": "%s", "current_user": 0, "users": [{"name": "%s"}]}`, srv.URL, VIDITe2eUser) + err = os.WriteFile(homeDir+"/state.json", []byte(savedState), 0600) + require.NoError(t, err) + + vidit, err := tool.NewWithConfig(tool.Config{ + EnforceHomeDir: homeDir, + FilePickerDir: homeDir, + EarlyInit: true, + }) + require.NoError(t, err) + require.NotNil(t, vidit) + + // -------------------------------------------------------------------------------------- + // Create teatest program + tm := teatest.NewTestModel(t, vidit, teatest.WithInitialTermSize(300, 100)) + + // -------------------------------------------------------------------------------------- + // Run tool + errc := make(chan error) + wg := &sync.WaitGroup{} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + wg.Add(1) + go vidit.RunWithProgram(ctx, wg, errc, tm.GetProgram()) + go func() { + for { + select { + case errR := <-errc: + require.NoError(t, errR) + case <-ctx.Done(): + return + } + } + }() + + // -------------------------------------------------------------------------------------- + // Here should be user select screen + teatest.WaitFor(t, tm.Output(), func(bts []byte) bool { + return bytes.Contains(bts, []byte("Enter your password again or select another user")) && + bytes.Contains(bts, []byte(fmt.Sprintf("Enter password for '%s'", VIDITe2eUser))) + }, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3)) + t.Log("user select screen showed") + + // confirm re-enter password + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + time.Sleep(time.Millisecond * 200) + + // -------------------------------------------------------------------------------------- + // Here should be re-log screen + teatest.WaitFor(t, tm.Output(), func(bts []byte) bool { + return bytes.Contains(bts, []byte(fmt.Sprintf("Enter password for '%s'", VIDITe2eUser))) && + !bytes.Contains(bts, []byte("Enter your password again or select another user")) + }, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3)) + t.Log("re-log screen showed") + + // enter password + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyRunes, + Runes: []rune(VIDITe2ePassword), + }) + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + time.Sleep(time.Millisecond * 200) + // confirm + tm.Send(tea.KeyMsg{ + Type: tea.KeyLeft, + }) + time.Sleep(time.Millisecond * 200) + tm.Send(tea.KeyMsg{ + Type: tea.KeyEnter, + }) + time.Sleep(time.Millisecond * 200) + + // -------------------------------------------------------------------------------------- + // Here should be main screen + teatest.WaitFor(t, tm.Output(), func(bts []byte) bool { + return bytes.Contains(bts, []byte("Welcome to Vidi terminal tool")) + }, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3)) + t.Log("main menu screen showed") + + // -------------------------------------------------------------------------------------- + // Cleanup + cancel() + wg.Wait() + + b, err = os.ReadFile(homeDir + "/log.json") + require.NoError(t, err) + t.Log(string(b)) +} + func copyFile(dst string, src string) error { fSrc, err := os.Open(src) if err != nil {