Skip to content

Commit

Permalink
some tests and better ui.Time logic
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Jan 22, 2023
1 parent e1d09db commit ecb595f
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 10 deletions.
91 changes: 91 additions & 0 deletions auth/context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package auth

import (
"context"
"reflect"
"testing"
)

type fakeProvider struct {
simpleProvider
}

func (fakeProvider) Type() Type {
return Type(99)
}

var fakeTestProvider = &fakeProvider{simpleProvider{Token: "test"}}

var (
emptyContext = context.Background()
contextWithProvider = WithContext(context.Background(), fakeTestProvider)
)

func TestFromContext(t *testing.T) {
type args struct {
ctx context.Context
}
tests := []struct {
name string
args args
want Provider
wantErr bool
}{
{
"empty context",
args{emptyContext},
nil,
true,
},
{
"context with provider",
args{contextWithProvider},
&fakeProvider{simpleProvider{Token: "test"}},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := FromContext(tt.args.ctx)
if (err != nil) != tt.wantErr {
t.Errorf("FromContext() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("FromContext() = %v, want %v", got, tt.want)
}
})
}
}

func TestWithContext(t *testing.T) {
type args struct {
pctx context.Context
p Provider
}
tests := []struct {
name string
args args
want context.Context
}{
{
"fake provider",
args{context.Background(), fakeTestProvider},
contextWithProvider,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := WithContext(tt.args.pctx, tt.args.p); !reflect.DeepEqual(got, tt.want) {
t.Errorf("WithContext() = %v, want %v", got, tt.want)
}
prov, err := FromContext(tt.want)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(prov, tt.args.p) {
t.Errorf("Provider from context = %v, want %v", prov, tt.args.p)
}
})
}
}
12 changes: 12 additions & 0 deletions cmd/slackdump/internal/export/wizard.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ func wizExport(ctx context.Context, cmd *base.Command, args []string) error {
} else {
options.Type = exportType
}

if wantExportToken, err := ui.Confirm("Do you want to specify an export token for attachments?", false); err != nil {
return err
} else if wantExportToken {
// ask for the export token
exportToken, err := ui.String("Export token", "Enter the export token, that will be appended to each of the attachment URLs.")
if err != nil {
return err
}
options.ExportToken = exportToken
}

// ask for the save location
baseLoc, err := ui.FileSelector("Output ZIP or Directory name", "Enter the name of the ZIP or directory to save the export to.")
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion fsadapter/fsadapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/assert"
)

func TestForFilename(t *testing.T) {
func TestNew(t *testing.T) {
tmp := t.TempDir()
type args struct {
name string
Expand Down
43 changes: 34 additions & 9 deletions internal/app/ui/time.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ui

import (
"errors"
"fmt"
"strings"
"time"
Expand All @@ -13,19 +14,29 @@ const (
timeHint = "HH:MM:SS"
)

// Time asks the user to enter a date and time.
// ErrEmptyOptionalInput is returned when an optional input is empty.
var ErrEmptyOptionalInput = errors.New("empty input in optional field")

// Time asks the user to enter a date and time. For simplicity, the date and
// time are entered in two separate prompts. The date is optional, and if
// it is not given, the function terminates returning ErrEmptyOptionalInput.
// If the date is entered and is valid (checked with validators, you don't have
// to worry), the function will ask for time, which is then required.
func Time(msg string, opt ...Option) (time.Time, error) {
var opts = defaultOpts().apply(opt...)
// q returns a survey.Question for the given entity (date or time).
q := func(msg, entity, hint, layout string) *survey.Question {
q := func(msg, entity, hint, layout string, required bool) *survey.Question {
return &survey.Question{
Name: entity,
Prompt: &survey.Input{
Message: fmt.Sprintf("%s %s (%s):", msg, strings.ToLower(entity), hint),
},
Validate: survey.ComposeValidators(
survey.Required,
func(ans interface{}) error {
s := ans.(string)
if !required && s == "" {
return nil
}
_, err := time.Parse(layout, ans.(string))
if err != nil {
return fmt.Errorf("invalid input, expected %s format: %s", strings.ToLower(entity), hint)
Expand All @@ -36,18 +47,32 @@ func Time(msg string, opt ...Option) (time.Time, error) {
}
}

qs := []*survey.Question{
q(msg, "Date", dateHint, "2006-01-02"),
q(msg, "Time", timeHint, "15:04:05"),
}

var p struct {
Date string
Time string
}
if err := survey.Ask(qs, &p, opts.surveyOpts()...); err != nil {

// First, ask for date. Date is optional. If date is not given, we
// shall not ask for time, and will return EmptyOptionalInput.
if err := survey.Ask(
[]*survey.Question{q(msg, "Date", dateHint, "2006-01-02", false)},
&p,
opts.surveyOpts()...,
); err != nil {
return time.Time{}, err
}
if p.Date == "" {
return time.Time{}, ErrEmptyOptionalInput
}
// if date is given, ask for time. Time is required.
if err := survey.Ask(
[]*survey.Question{q(msg, "Time", timeHint, "15:04:05", true)},
&p,
opts.surveyOpts()...,
); err != nil {
return time.Time{}, err
}

res, err := time.Parse("2006-01-02 15:04:05", p.Date+" "+p.Time)
if err != nil {
return time.Time{}, err
Expand Down
37 changes: 37 additions & 0 deletions internal/app/ui/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,41 @@ func TestTime(t *testing.T) {
RunTest(t, procedure, testFn)
assert.Equal(t, time.Date(2019, 9, 16, 15, 16, 17, 0, time.UTC), tm)
})
t.Run("empty date", func(t *testing.T) {
var tm time.Time
var err error
testFn := func(stdio terminal.Stdio) error {
tm, err = Time("UNIT", WithOutput(stdio))
return nil
}
procedure := func(t *testing.T, console console) {
console.ExpectString("UNIT date")
console.SendLine("")
console.ExpectEOF()
}
RunTest(t, procedure, testFn)
assert.Equal(t, time.Time{}, tm)
assert.Equal(t, ErrEmptyOptionalInput, err)
})
t.Run("empty time does not pass validation", func(t *testing.T) {
var tm time.Time
var err error
testFn := func(stdio terminal.Stdio) error {
tm, err = Time("UNIT", WithOutput(stdio))
return nil
}
procedure := func(t *testing.T, console console) {
console.ExpectString("UNIT date")
console.SendLine("2019-09-16")
console.ExpectString("UNIT time")
console.SendLine("")
// validation fails, reenter
console.ExpectString("invalid input, expected time format: HH:MM:SS")
console.SendLine("15:16:17")
console.ExpectEOF()
}
RunTest(t, procedure, testFn)
assert.Equal(t, time.Date(2019, 9, 16, 15, 16, 17, 0, time.UTC), tm)
assert.Nil(t, err)
})
}

0 comments on commit ecb595f

Please sign in to comment.