Add tests for CLI
continuous-integration/woodpecker the build was successful Details

Signed-off-by: jolheiser <john.olheiser@gmail.com>
main
jolheiser 2021-11-23 22:08:40 -06:00
parent 5871595462
commit 2514b79913
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
4 changed files with 116 additions and 9 deletions

View File

@ -10,6 +10,15 @@ import (
) )
func main() { func main() {
pw, err := doMain(os.Args[1:])
if err != nil {
fmt.Println(err)
return
}
fmt.Println(pw)
}
func doMain(args []string) (string, error) {
fs := flag.NewFlagSet("spectre", flag.ExitOnError) fs := flag.NewFlagSet("spectre", flag.ExitOnError)
fs.Usage = func() { fs.Usage = func() {
fmt.Fprintln(fs.Output(), "spectre [FLAGS] [site]") fmt.Fprintln(fs.Output(), "spectre [FLAGS] [site]")
@ -30,11 +39,11 @@ func main() {
return return
}) })
if err := fs.Parse(os.Args[1:]); err != nil { if err := fs.Parse(args); err != nil {
panic(err) return "", err
} }
if err := checkEnv(fs); err != nil { if err := checkEnv(fs); err != nil {
panic(err) return "", err
} }
if templateFlag == "" { if templateFlag == "" {
@ -42,23 +51,45 @@ func main() {
} }
if *usernameFlag == "" || *secretFlag == "" || fs.NArg() < 1 { if *usernameFlag == "" || *secretFlag == "" || fs.NArg() < 1 {
panic("username, secret, and site are required") return "", requiredArgs{
missingUsername: *usernameFlag == "",
missingSecret: *secretFlag == "",
missingSite: fs.NArg() < 1,
}
} }
s, err := spectre.New(*usernameFlag, *secretFlag, spectre.WithScoper(spectre.SimpleScoper{ s, err := spectre.New(*usernameFlag, *secretFlag, spectre.WithScoper(spectre.SimpleScoper{
Key: *scoperFlag, Key: *scoperFlag,
})) }))
if err != nil { if err != nil {
panic(err) return "", err
} }
pw := s.Site(fs.Arg(0), return s.Site(fs.Arg(0),
spectre.WithScope(scopeFlag), spectre.WithScope(scopeFlag),
spectre.WithTemplate(templateFlag), spectre.WithTemplate(templateFlag),
spectre.WithCounter(*counterFlag), spectre.WithCounter(*counterFlag),
) ), nil
}
fmt.Println(pw) type requiredArgs struct {
missingUsername bool
missingSecret bool
missingSite bool
}
func (r requiredArgs) Error() string {
s := "--username, --secret, and <site-name> are required, missing: "
if r.missingUsername {
s += "\n- username"
}
if r.missingSecret {
s += "\n- secret"
}
if r.missingSite {
s += "\n- site name"
}
return s
} }
func checkEnv(fs *flag.FlagSet) error { func checkEnv(fs *flag.FlagSet) error {

View File

@ -0,0 +1,76 @@
package main
import (
_ "embed"
"encoding/xml"
"fmt"
"testing"
)
// These are the exact same tests as spectre_test.go
// These are here just to make sure the CLI is giving the same outputs
func TestCLI(t *testing.T) {
var tests TestCases
if err := xml.Unmarshal(testsXML, &tests); err != nil {
t.Log("could not load test data")
t.FailNow()
}
dc := tests.Cases[0]
for _, tc := range tests.Cases[1:] {
t.Run(tc.ID, func(t *testing.T) {
user := def(dc.UserName, tc.UserName)
secret := def(dc.UserSecret, tc.UserSecret)
siteName := def(dc.SiteName, tc.SiteName)
template := def(dc.ResultType, tc.ResultType)
counter := def(dc.KeyCounter, tc.KeyCounter)
scope := def(dc.KeyPurpose, tc.KeyPurpose)
args := []string{
"--username", user,
"--secret", secret,
"--template", template,
"--counter", counter,
"--scope", scope,
siteName,
}
fmt.Println(args)
pw, err := doMain(args)
if err != nil {
t.Log(err)
t.FailNow()
}
if pw != tc.Result {
t.Log("passwords did not match")
t.Fail()
}
})
}
}
//go:embed spectre_tests.xml
var testsXML []byte
type TestCases struct {
Cases []TestCase `xml:"case"`
}
type TestCase struct {
ID string `xml:"id,attr"`
UserName string `xml:"userName"`
UserSecret string `xml:"userSecret"`
SiteName string `xml:"siteName"`
ResultType string `xml:"resultType"`
KeyCounter string `xml:"keyCounter"`
KeyPurpose string `xml:"keyPurpose"`
Result string `xml:"result"`
}
func def(def, alt string) string {
if alt != "" {
return alt
}
return def
}

View File

@ -84,7 +84,7 @@ func Example_second() {
// Output: Ig^JIcxD!*)TbefJBi6- // Output: Ig^JIcxD!*)TbefJBi6-
} }
//go:embed spectre_tests.xml //go:embed cmd/spectre/spectre_tests.xml
var testsXML []byte var testsXML []byte
type TestCases struct { type TestCases struct {