Skip to content

Commit

Permalink
add cli tests and upload resume tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adwski committed May 16, 2024
1 parent dd6476b commit 9ba8aa1
Show file tree
Hide file tree
Showing 12 changed files with 378 additions and 49 deletions.
4 changes: 2 additions & 2 deletions cmd/vidictl/vidi.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package main
import (
"os"

"github.com/adwski/vidi/internal/app/vidictl"
"github.com/adwski/vidi/internal/cli"
)

func main() {
os.Exit(vidictl.Execute())
os.Exit(cli.Execute())
}
23 changes: 11 additions & 12 deletions e2e/e2e_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,22 +268,14 @@ func videoGetAll(t *testing.T, userCookie *http.Cookie) []*videohttp.VideoRespon
func videoCreate(t *testing.T, userCookie *http.Cookie) *videohttp.VideoResponse {
t.Helper()

// get size
size, err := file.GetSize(testFilePath)
require.NoError(t, err)
require.Greater(t, size, uint64(0))

// make parts with checksums
parts, err := file.MakePartsFromFile(testFilePath, partSize, size)
require.NoError(t, err)
require.Greater(t, len(parts), 0)
size, parts := getSizeAndMakeParts(t)

var (
respBody videohttp.VideoResponse
reqBody video.CreateRequest
errBody common.Response
)
reqBody.Name = "test"
reqBody.Name = "testvid"
reqBody.Size = size
for _, part := range parts {
reqBody.Parts = append(reqBody.Parts, &video.Part{
Expand Down Expand Up @@ -312,9 +304,8 @@ func videoCreate(t *testing.T, userCookie *http.Cookie) *videohttp.VideoResponse
return &respBody
}

func videoUpload(t *testing.T, url string) {
func getSizeAndMakeParts(t *testing.T) (uint64, []file.Part) {
t.Helper()

// get size
size, err := file.GetSize(testFilePath)
require.NoError(t, err)
Expand All @@ -325,6 +316,14 @@ func videoUpload(t *testing.T, url string) {
require.NoError(t, err)
require.Greater(t, len(parts), 0)

return size, parts
}

func videoUpload(t *testing.T, url string) {
t.Helper()

_, parts := getSizeAndMakeParts(t)

// upload parts
f, err := os.Open(testFilePath)
require.NoError(t, err)
Expand Down
165 changes: 161 additions & 4 deletions e2e/vidit_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//go:build e2e

package e2e

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
Expand All @@ -13,6 +16,7 @@ import (
"testing"
"time"

"github.com/adwski/vidi/internal/api/user/model"
"github.com/adwski/vidi/internal/tool"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/x/exp/teatest"
Expand Down Expand Up @@ -168,7 +172,7 @@ func TestVidit_MainFlow(t *testing.T) {

// --------------------------------------------------------------------------------------
// Copy mp4 file, so it would be easier to find it in file picker
fileName := fmt.Sprintf("testvideo%s.mp4", random.String(5, "asdzxcqwe"))
fileName := fmt.Sprintf("testvideo%s.mp4", random.String(5))
require.NoError(t, copyFile(homeDir+"/"+fileName, "../testfiles/test_seq_h264_high_uhd.mp4"),
"copy test video file to home dir")

Expand Down Expand Up @@ -212,7 +216,7 @@ func TestVidit_MainFlow(t *testing.T) {
return bytes.Contains(bts, []byte("Enter Name of the video"))
}, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3))

videoName := fmt.Sprintf("test video %s", random.String(5, "asdzxcqwe123"))
videoName := fmt.Sprintf("test video %s", random.String(5))
// enter name
tm.Send(tea.KeyMsg{
Type: tea.KeyDown,
Expand Down Expand Up @@ -241,7 +245,7 @@ func TestVidit_MainFlow(t *testing.T) {
// Here should eventually be upload success message
teatest.WaitFor(t, tm.Output(), func(bts []byte) bool {
return bytes.Contains(bts, []byte("Upload completed successfully! Press any key to continue..."))
}, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3))
}, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*5))

tm.Send(tea.KeyMsg{
Type: tea.KeyEnter,
Expand All @@ -255,7 +259,7 @@ func TestVidit_MainFlow(t *testing.T) {
}, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3))
t.Log("main menu screen showed")

time.Sleep(time.Second * 15)
time.Sleep(time.Second * 10)
tm.Send(tea.KeyMsg{
Type: tea.KeyEnter,
})
Expand Down Expand Up @@ -637,6 +641,159 @@ func TestVidit_LoginExistingUser(t *testing.T) {
t.Log(string(b))
}

func TestVidit_ResumeUpload(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()

// --------------------------------------------------------------------------------------
// Prepare created but not uploaded video
cookie := userLogin(t, &model.UserRequest{
Username: VIDITe2eUser,
Password: VIDITe2ePassword,
})

video := videoCreate(t, cookie)
_, parts := getSizeAndMakeParts(t)

state := &tool.State{
Endpoint: srv.URL,
CurrentUser: 0,
Users: []tool.User{
{
Name: VIDITe2eUser,
Token: cookie.Value,
CurrentUpload: &tool.Upload{
ID: video.ID,
Name: video.Name,
Filename: testFilePath,
Parts: parts,
},
},
},
}

// --------------------------------------------------------------------------------------
// Init tool
homeDir := t.TempDir()
stateB, err := json.Marshal(state)
require.NoError(t, err)
err = os.WriteFile(homeDir+"/state.json", stateB, 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 main screen
teatest.WaitFor(t, tm.Output(), func(bts []byte) bool {
return bytes.Contains(bts, []byte("Welcome to Vidi terminal tool")) &&
bytes.Contains(bts, []byte("Resume Current Upload"))
}, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3))
t.Log("main menu screen with resume option showed")

// select resume
tm.Send(tea.KeyMsg{
Type: tea.KeyDown,
})
time.Sleep(time.Millisecond * 200)
tm.Send(tea.KeyMsg{
Type: tea.KeyDown,
})
time.Sleep(time.Millisecond * 200)
tm.Send(tea.KeyMsg{
Type: tea.KeyDown,
})
time.Sleep(time.Millisecond * 200)
tm.Send(tea.KeyMsg{
Type: tea.KeyDown,
})
time.Sleep(time.Millisecond * 200)
tm.Send(tea.KeyMsg{
Type: tea.KeyEnter,
})
time.Sleep(time.Millisecond * 200)

// --------------------------------------------------------------------------------------
// Here should eventually be upload success message
teatest.WaitFor(t, tm.Output(), func(bts []byte) bool {
return bytes.Contains(bts, []byte("Upload completed successfully! Press any key to continue..."))
}, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*5))

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")

time.Sleep(time.Second * 10)
tm.Send(tea.KeyMsg{
Type: tea.KeyEnter,
})
time.Sleep(time.Millisecond * 200)

// --------------------------------------------------------------------------------------
// Here should be videos screen
teatest.WaitFor(t, tm.Output(), func(bts []byte) bool {
return bytes.Contains(bts, []byte(video.Name)) && bytes.Contains(bts, []byte("ready"))
}, teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*1))
t.Log("videos screen showed and uploaded video is ready")

// --------------------------------------------------------------------------------------
// 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 {
Expand Down
14 changes: 8 additions & 6 deletions internal/app/vidictl/api.go → internal/cli/api.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package vidictl
package cli

import (
"fmt"
"io"
"time"

"github.com/adwski/vidi/internal/api/user/auth"
Expand All @@ -23,12 +23,12 @@ var createSvcTokenCmd = &cobra.Command{
name := cmd.Flag("svcname").Value.String()
secret := cmd.Flag("jwtsecret").Value.String()
expiration := cast.ToDuration(cmd.Flag("expiration").Value.String())
createServiceToken(name, secret, expiration)
createServiceToken(cmd.OutOrStdout(), name, secret, expiration)
},
}

func createServiceToken(name, secret string, expiration time.Duration) {
logger := logging.GetZapLoggerConsole()
func createServiceToken(w io.Writer, name, secret string, expiration time.Duration) {
logger := logging.GetZapLoggerWriter(w)

au, err := auth.NewAuth(&auth.Config{
Secret: secret,
Expand All @@ -44,5 +44,7 @@ func createServiceToken(name, secret string, expiration time.Duration) {
logger.Error("cannot create token", zap.Error(errT))
return
}
fmt.Println(token)
if _, err = w.Write([]byte(token)); err != nil {
logger.Error("cannot write token", zap.Error(err))
}
}
2 changes: 1 addition & 1 deletion internal/app/vidictl/cli.go → internal/cli/cli.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package vidictl
package cli

import (
"fmt"
Expand Down
Loading

0 comments on commit 9ba8aa1

Please sign in to comment.