Skip to content

Commit

Permalink
Merge pull request #6 from StreakInTheSky/improve-session-handling
Browse files Browse the repository at this point in the history
Improve session handling
  • Loading branch information
StreakInTheSky authored Dec 8, 2022
2 parents d081a85 + 13caec8 commit 8cd2d5d
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 71 deletions.
46 changes: 31 additions & 15 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
172 changes: 118 additions & 54 deletions cli/cli_test.go
Original file line number Diff line number Diff line change
@@ -1,51 +1,96 @@
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)
}
})
}

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)
}
Expand All @@ -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)
}
Expand All @@ -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
}
}
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 8cd2d5d

Please sign in to comment.