diff --git a/cli/cli.go b/cli/cli.go index 932d2ab..83be2ce 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -2,41 +2,57 @@ package cli import ( "errors" + "flag" "os" + "regexp" "strings" ) var ( readFile = os.ReadFile getEnv = os.Getenv + initArgs = flag.Args ) -func ParseArgs(args []string) (string, error) { - var url string - if len(args) <= 1 || args[1] != "fetch" { - return url, errors.New("did you want to call fetch?") +var sessionFlag = flag.String("session", "./session", "session token from advent of code") + +const SESSION_TOKEN = "AOC_SESSION" + +func Run() (url, sessionParam string, err error) { + flag.Parse() + args := initArgs() + if len(args) < 1 || args[0] != "fetch" { + return url, sessionParam, errors.New("Did you want to call \"fetch\"?") } - if len(args) < 3 { - return url, errors.New("please enter a url") + if len(args) < 2 { + return url, sessionParam, errors.New("Please enter a url") } - return args[2], nil + return args[1], *sessionFlag, nil +} + +func isPath(input string) bool { + return regexp.MustCompile("^[./]").MatchString(input) } -func GrabSessionID() (sessionID string, err error) { - fileContent, err := readFile("./session") - if err != nil { - sessionID = getEnv("SESSION") +func GrabSessionID(sessionParam string) (sessionID string, err error) { + err = errors.New("No session id found") + + if isPath(sessionParam) { + fileContent, err := readFile(sessionParam) + if err != nil { + return sessionID, err + } + + sessionID = strings.Fields(string(fileContent))[0] } else { - sessionID = string(fileContent) + sessionID = sessionParam } if len(sessionID) == 0 { - return sessionID, errors.New("No session id found") + return sessionID, err } - sessionID = strings.Fields(sessionID)[0] - return sessionID, nil } diff --git a/cli/cli_test.go b/cli/cli_test.go index ec90e78..f17b99e 100644 --- a/cli/cli_test.go +++ b/cli/cli_test.go @@ -1,41 +1,87 @@ package cli import ( - "errors" "testing" ) func TestParsingArgs(t *testing.T) { t.Run("Error if no args in inputs", func(t *testing.T) { args := []string{"command"} + initArgs = mockFlagArgs(args) - if _, err := ParseArgs(args); err == nil { + if _, _, err := Run(); err == nil { t.Error("Should return error if no args") } }) t.Run("First argument is fetch", func(t *testing.T) { - args := []string{"command", "fetch", "url"} + args := []string{"fetch", "url"} + initArgs = mockFlagArgs(args) - if _, err := ParseArgs(args); err != nil { - t.Error("First argument as fetch should be valid") + if _, _, err := Run(); err != nil { + t.Errorf("First argument as fetch should be valid. Got error: %s", err.Error()) + } + }) + + t.Run("Error if first argument not fetch", func(t *testing.T) { + var err error + args := []string{"notfetch"} + initArgs = mockFlagArgs(args) + expectedErrMsg := "Did you want to call \"fetch\"?" + + if _, _, err = Run(); err == nil { + t.Error("Expected an error") + } + + errMsg := err.Error() + if errMsg != expectedErrMsg { + t.Errorf("Expected error: %s, but got error: %s", expectedErrMsg, errMsg) } }) t.Run("Error if no url passed as second argument", func(t *testing.T) { - args := []string{"command", "fetch"} + var err error + args := []string{"fetch"} + initArgs = mockFlagArgs(args) + expectedErrMsg := "Please enter a url" + + if _, _, err = Run(); err == nil { + t.Error("Expected and error") + } - if _, err := ParseArgs(args); err == nil { - t.Error("Not passing a third argument should return an error") + errMsg := err.Error() + if errMsg != expectedErrMsg { + t.Errorf("Expected error: %s, but got error: %s", expectedErrMsg, errMsg) } }) t.Run("Should return url", func(t *testing.T) { - args := []string{"command", "fetch", "url"} + args := []string{"fetch", "url"} + initArgs = mockFlagArgs(args) - url, err := ParseArgs(args) - if err != nil || url != args[2] { - t.Errorf("Should return %s, got %s", args[2], url) + url, _, err := Run() + if err != nil { + t.Errorf("Should not have error, got error: %s", err.Error()) + } + + if url != args[1] { + t.Errorf("Should return %s, got %s", args[1], url) + } + }) + + t.Run("Should return a session field from session flag", func(t *testing.T) { + args := []string{"fetch", "url"} + initArgs = mockFlagArgs(args) + + defaultSessionFlagVal := "./session" + + _, sessionID, err := Run() + if err != nil { + t.Errorf("Should not have an error, got error: %s", err.Error()) + } + + if sessionID != defaultSessionFlagVal { + t.Errorf("Should have session: %s, but got session: %s", defaultSessionFlagVal, sessionID) } }) } @@ -43,9 +89,8 @@ func TestParsingArgs(t *testing.T) { func TestGrabbingSessionId(t *testing.T) { t.Run("Returns error if no cookie found", func(t *testing.T) { readFile = mockReadFile([]byte{}, nil) - getEnv = mockGetEnv("") - sessionID, err := GrabSessionID() + sessionID, err := GrabSessionID("") if err == nil { t.Errorf("Expected an error, got %s", sessionID) } @@ -54,11 +99,10 @@ func TestGrabbingSessionId(t *testing.T) { t.Run("Returns sessionID from file when it exists", func(t *testing.T) { mockFile := []byte{'a', 'b', 'c'} expected := "abc" - + pathToFile := "/path" readFile = mockReadFile(mockFile, nil) - getEnv = mockGetEnv("") - sessionID, err := GrabSessionID() + sessionID, err := GrabSessionID(pathToFile) if err != nil { t.Errorf("Expected no error, got %s", err) } @@ -67,67 +111,87 @@ func TestGrabbingSessionId(t *testing.T) { } }) - t.Run("Returns sessionID from environment variable if file doesn't exist", func(t *testing.T) { - mockValue := "abc" - expected := mockValue - - readFile = mockReadFile([]byte{}, errors.New("No file")) - getEnv = mockGetEnv(mockValue) + t.Run("Must return a single line string", func(t *testing.T) { + mockFile := `line1 + line2 + line3 + ` + expected := "line1" + pathToFile := "/path" + readFile = mockReadFile([]byte(mockFile), nil) - sessionID, err := GrabSessionID() + sessionID, err := GrabSessionID(pathToFile) if err != nil { - t.Errorf("Expected no error, got %s", err) + t.Errorf("Expected no error, got %s", err.Error()) } if sessionID != expected { t.Errorf("Expected %s, got %s", expected, sessionID) } }) - t.Run("Returns sessionID from file if both file and env variable exist", func(t *testing.T) { - mockFile := []byte{'a', 'b', 'c'} - mockValue := "123" - expected := "abc" + t.Run("Should return session id from params", func(t *testing.T) { + expectedID := "abc123" - readFile = mockReadFile(mockFile, nil) - getEnv = mockGetEnv(mockValue) + actualID, err := GrabSessionID(expectedID) + if err != nil { + t.Errorf("Expected no error, got error: %s", err.Error()) + } + + if actualID != expectedID { + t.Errorf("Expexted id: %s, got id: %s", expectedID, actualID) + } + }) + + t.Run("Should grab session if from file if passed a path", func(t *testing.T) { + expectedId := "abc123" + readFile = mockReadFile([]byte(expectedId), nil) + idPath := "/file/path" - sessionID, err := GrabSessionID() + sessionID, err := GrabSessionID(idPath) if err != nil { - t.Errorf("Expected no error, got %s", err) + t.Errorf("Expected no error, got error: %s", err.Error()) } - if sessionID != expected { - t.Errorf("Expected %s, got %s", expected, sessionID) + + if sessionID != expectedId { + t.Errorf("Expected sessionID: %s, got sessionID: %s", expectedId, sessionID) } }) +} - t.Run("Must return a single line string", func(t *testing.T) { - mockFile := `line1 - line2 - line3 - ` - expected := "line1" +func TestCheckingIfPath(t *testing.T) { + t.Run("Should be false for regular string", func(t *testing.T) { + input := "abc123" - readFile = mockReadFile([]byte(mockFile), nil) - getEnv = mockGetEnv("") + if isPath(input) { + t.Errorf("Expected input: %s to be false", input) + } + }) - sessionID, err := GrabSessionID() - if err != nil { - t.Errorf("Expected no error, got %s", err) + t.Run("Should be true for absolute path string", func(t *testing.T) { + input := "/path/to/file" + + if !isPath(input) { + t.Errorf("Expected input: %s to be true", input) } - if sessionID != expected { - t.Errorf("Expected %s, got %s", expected, sessionID) + }) + + t.Run("Should be true for relative path", func(t *testing.T) { + input := "./path/to/file" + + if !isPath(input) { + t.Errorf("Expected input: %s to be true", input) } }) } -func mockReadFile(file []byte, err error) func(string) ([]byte, error) { - return func(path string) ([]byte, error) { - return file, err +func mockFlagArgs(args []string) func() []string { + return func() []string { + return args } } -func mockGetEnv(value string) func(string) string { - return func(key string) string { - return value +func mockReadFile(file []byte, err error) func(string) ([]byte, error) { + return func(path string) ([]byte, error) { + return file, err } } diff --git a/main.go b/main.go index 5a13c2c..8afe044 100644 --- a/main.go +++ b/main.go @@ -16,12 +16,12 @@ var ( ) func main() { - url, err := cli.ParseArgs(os.Args) + url, sessionFlag, err := cli.Run() if err != nil { handleError(err, 2) } - sessionID, err := cli.GrabSessionID() + sessionID, err := cli.GrabSessionID(sessionFlag) if err != nil { handleError(err, 2) }