Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3 tests #338

Merged
merged 21 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ CMD=./cmd/slackdump
OUTPUT=slackdump
EXECUTABLE=slackdump
BUILD=$(shell git describe --tags)
BUILD_YEAR=$(shell date +%Y)
BUILD_DATE=$(shell TZ=UTC date +%Y-%m-%d\ %H:%M:%SZ)
COMMIT=$(shell git rev-parse --short HEAD)

PKG=github.com/rusq/slackdump/v3

LDFLAGS="-s -w -X 'main.build=$(BUILD)' -X 'main.buildYear=$(BUILD_YEAR)'"
LDFLAGS="-s -w -X 'main.commit=$(COMMIT)' -X 'main.version=$(BUILD)' -X 'main.date=$(BUILD_DATE)'"
OSES=linux darwin windows
DISTFILES=README.rst LICENSE
ZIPFILES=$(foreach s,$(OSES),$(OUTPUT)-$s.zip)
Expand Down
3 changes: 2 additions & 1 deletion cmd/slackdump/internal/archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/rusq/fsadapter"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/bootstrap"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/cfg"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/golang/base"
"github.com/rusq/slackdump/v3/internal/chunk"
Expand Down Expand Up @@ -63,7 +64,7 @@ func RunArchive(ctx context.Context, cmd *base.Command, args []string) error {
return err
}

sess, err := cfg.SlackdumpSession(ctx)
sess, err := bootstrap.SlackdumpSession(ctx)
if err != nil {
base.SetExitStatus(base.SInitializationError)
return err
Expand Down
20 changes: 18 additions & 2 deletions cmd/slackdump/internal/archive/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"strings"

"github.com/rusq/fsadapter"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/bootstrap"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/cfg"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/golang/base"
"github.com/rusq/slackdump/v3/internal/chunk"
"github.com/rusq/slackdump/v3/internal/chunk/control"
"github.com/rusq/slackdump/v3/internal/chunk/transform/fileproc"
"github.com/rusq/slackdump/v3/logger"
"github.com/rusq/slackdump/v3/stream"
)

var CmdSearch = &base.Command{
Expand Down Expand Up @@ -55,6 +57,14 @@ var cmdSearchAll = &base.Command{
PrintFlags: true,
}

var fastSearch bool

func init() {
for _, cmd := range []*base.Command{cmdSearchMessages, cmdSearchFiles, cmdSearchAll} {
cmd.Flag.BoolVar(&fastSearch, "no-channel-users", false, "skip channel users (approx ~2.5x faster)")
}
}

func runSearchMsg(ctx context.Context, cmd *base.Command, args []string) error {
ctrl, stop, err := initController(ctx, args)
if err != nil {
Expand Down Expand Up @@ -109,7 +119,7 @@ func initController(ctx context.Context, args []string) (*control.Controller, fu
return nil, nil, errNoOutput
}

sess, err := cfg.SlackdumpSession(ctx)
sess, err := bootstrap.SlackdumpSession(ctx)
if err != nil {
base.SetExitStatus(base.SInitializationError)
return nil, nil, err
Expand All @@ -130,9 +140,15 @@ func initController(ctx context.Context, args []string) (*control.Controller, fu
fsadapter.NewDirectory(cd.Name()),
lg,
)

var sopts []stream.Option
if fastSearch {
sopts = append(sopts, stream.OptFastSearch())
}

var (
subproc = fileproc.NewExport(fileproc.STmattermost, dl)
stream = sess.Stream()
stream = sess.Stream(sopts...)
ctrl = control.New(cd, stream, control.WithLogger(lg), control.WithFiler(subproc))
)
return ctrl, stop, nil
Expand Down
17 changes: 0 additions & 17 deletions cmd/slackdump/internal/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
// Package bootstrap contains some initialisation functions that are shared
// between main some other top level commands, i.e. wizard.
package bootstrap

import (
"context"

"github.com/rusq/slackdump/v3/auth"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/cfg"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/workspace"
)

// CurrentProviderCtx returns the context with the current provider.
func CurrentProviderCtx(ctx context.Context) (context.Context, error) {
prov, err := workspace.AuthCurrent(ctx, cfg.CacheDir(), cfg.Workspace, cfg.LegacyBrowser)
if err != nil {
return ctx, err
}
return auth.WithContext(ctx, prov), nil
}
18 changes: 18 additions & 0 deletions cmd/slackdump/internal/bootstrap/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package bootstrap

import (
"context"

"github.com/rusq/slackdump/v3/auth"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/cfg"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/workspace"
)

// CurrentProviderCtx returns the context with the current provider.
func CurrentProviderCtx(ctx context.Context) (context.Context, error) {
prov, err := workspace.AuthCurrent(ctx, cfg.CacheDir(), cfg.Workspace, cfg.LegacyBrowser)
if err != nil {
return ctx, err
}
return auth.WithContext(ctx, prov), nil
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
package cfg
package bootstrap

import (
"context"

"github.com/rusq/slackdump/v3"
"github.com/rusq/slackdump/v3/auth"
"github.com/rusq/slackdump/v3/logger"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/cfg"
)

// SlackdumpSession returns the Slackdump Session initialised with the provider
// from context and a standard set of options initialised from the
// configuration. One can provide additional options to override the
// defaults.
func SlackdumpSession(ctx context.Context, opts ...slackdump.Option) (*slackdump.Session, error) {
lg := logger.FromContext(ctx)
prov, err := auth.FromContext(ctx)
if err != nil {
return nil, err
}

var stdOpts = []slackdump.Option{
slackdump.WithLogger(lg),
slackdump.WithForceEnterprise(ForceEnterprise),
slackdump.WithLimits(Limits),
slackdump.WithLogger(cfg.Log),
slackdump.WithForceEnterprise(cfg.ForceEnterprise),
slackdump.WithLimits(cfg.Limits),
}

stdOpts = append(stdOpts, opts...)
Expand Down
38 changes: 38 additions & 0 deletions cmd/slackdump/internal/bootstrap/slackdump_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package bootstrap

import (
"context"
"strings"
"testing"

"github.com/rusq/slack"
"github.com/rusq/slackdump/v3"
"github.com/rusq/slackdump/v3/auth"
"github.com/rusq/slackdump/v3/internal/fixtures"
)

func TestSlackdumpSession(t *testing.T) {
t.Run("no auth in context", func(t *testing.T) {
_, err := SlackdumpSession(context.Background())
if err == nil {
t.Error("expected error")
}
})
t.Run("auth in context", func(t *testing.T) {
var authJSON = `{"token":"` + strings.Replace(fixtures.TestClientToken, `xoxc`, `xoxb`, -1) + `"}`
prov, err := auth.Load(strings.NewReader(authJSON))
if err != nil {
t.Fatal(err)
}

// start fake Slack server
srv := fixtures.TestAuthServer(t)
defer srv.Close()
s := slack.New("", slack.OptionAPIURL(srv.URL+"/"))

ctx := auth.WithContext(context.Background(), prov)
if _, err := SlackdumpSession(ctx, slackdump.WithSlackClient(s)); err != nil {
t.Error(err)
}
})
}
17 changes: 14 additions & 3 deletions cmd/slackdump/internal/cfg/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,27 @@ func TestCacheDir(t *testing.T) {
t.Fatal(err)
}
tests := []struct {
name string
want string
name string
localDirCache string // set the LocalDirCache to this value
want string
}{
{
"returns the UserCacheDir value",
"returns the UserCacheDir value if global LocalDirCache is empty",
"",
filepath.Join(ucd, cacheDirName),
},
{
"returns the LocalDirCache value if it's set",
"local",
"local",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
old := LocalCacheDir
LocalCacheDir = tt.localDirCache
t.Cleanup(func() { LocalCacheDir = old })

if got := CacheDir(); got != tt.want {
t.Errorf("CacheDir() = %v, want %v", got, tt.want)
}
Expand Down
12 changes: 12 additions & 0 deletions cmd/slackdump/internal/cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,20 @@ var (
NoUserCache bool

Log logger.Interface

Version BuildInfo // version propagated by main package.
)

type BuildInfo struct {
Version string `json:"version"`
Commit string `json:"commit"`
Date string `json:"date"`
}

func (b BuildInfo) String() string {
return fmt.Sprintf("Slackdump %s (commit: %s) built on: %s", b.Version, b.Commit, b.Date)
}

type FlagMask uint16

const (
Expand Down
119 changes: 119 additions & 0 deletions cmd/slackdump/internal/cfg/cfg_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Package cfg contains common configuration variables.
package cfg

import (
"flag"
"testing"
"time"

"github.com/rusq/slackdump/v3/auth/browser"
"github.com/stretchr/testify/assert"
)

func TestSetBaseFlags(t *testing.T) {
t.Run("all flags are set", func(t *testing.T) {
fs := flag.NewFlagSet("test", flag.ExitOnError)
mask := DefaultFlags

SetBaseFlags(fs, mask)

// Test flag parsing and assignment
fs.Parse([]string{
"-trace", "trace.log",
"-log", "log.txt",
"-v",
"-token", "slack_token",
"-cookie", "slack_cookie",
"-browser", "firefox",
"-browser-timeout", "5s",
"-autologin-timeout", "10s",
"-legacy-browser",
"-enterprise",
"-user-agent", "Mozilla/5.0",
"-files=false",
"-api-config", "config.json",
"-o", "output.zip",
"-cache-dir", "/tmp/cache",
"-workspace", "my_workspace",
"-no-user-cache",
"-user-cache-retention", "30m",
"-no-chunk-cache",
"-time-from", "2022-01-01T00:00:00",
"-time-to", "2022-01-31T23:59:59",
})

// Test flag values
if TraceFile != "trace.log" {
t.Errorf("Expected TraceFile to be 'trace.log', got '%s'", TraceFile)
}
if LogFile != "log.txt" {
t.Errorf("Expected LogFile to be 'log.txt', got '%s'", LogFile)
}
if !Verbose {
t.Error("Expected Verbose to be true, got false")
}
if SlackToken != "slack_token" {
t.Errorf("Expected SlackToken to be 'slack_token', got '%s'", SlackToken)
}
if SlackCookie != "slack_cookie" {
t.Errorf("Expected SlackCookie to be 'slack_cookie', got '%s'", SlackCookie)
}
if Browser != browser.Bfirefox {
t.Errorf("Expected Browser to be 'chrome', got '%s'", Browser)
}
if LoginTimeout != 5*time.Second {
t.Errorf("Expected LoginTimeout to be 5 seconds, got %s", LoginTimeout)
}
if HeadlessTimeout != 10*time.Second {
t.Errorf("Expected HeadlessTimeout to be 10 seconds, got %s", HeadlessTimeout)
}
if !LegacyBrowser {
t.Error("Expected LegacyBrowser to be true, got false")
}
if !ForceEnterprise {
t.Error("Expected ForceEnterprise to be true, got false")
}
if RODUserAgent != "Mozilla/5.0" {
t.Errorf("Expected RODUserAgent to be 'Mozilla/5.0', got '%s'", RODUserAgent)
}
if DownloadFiles {
t.Error("Expected DownloadFiles to be false, got true")
}
if ConfigFile != "config.json" {
t.Errorf("Expected ConfigFile to be 'config.json', got '%s'", ConfigFile)
}
if Output != "output.zip" {
t.Errorf("Expected Output to be 'output.zip', got '%s'", Output)
}
if LocalCacheDir != "/tmp/cache" {
t.Errorf("Expected LocalCacheDir to be '/tmp/cache', got '%s'", LocalCacheDir)
}
if Workspace != "my_workspace" {
t.Errorf("Expected Workspace to be 'my_workspace', got '%s'", Workspace)
}
if !NoUserCache {
t.Error("Expected NoUserCache to be true, got false")
}
if UserCacheRetention != 30*time.Minute {
t.Errorf("Expected UserCacheRetention to be 30 minutes, got %s", UserCacheRetention)
}
if !NoChunkCache {
t.Error("Expected NoChunkCache to be true, got false")
}
if Oldest.String() != "2022-01-01T00:00:00" {
t.Errorf("Expected Oldest to be '2022-01-01T00:00:00Z', got '%s'", Oldest.String())
}
if Latest.String() != "2022-01-31T23:59:59" {
t.Errorf("Expected Latest to be '2022-01-31T23:59:59Z', got '%s'", Latest.String())
}
})
t.Run("omit cache dir set", func(t *testing.T) {
fs := flag.NewFlagSet("test", flag.ExitOnError)
mask := OmitCacheDir

SetBaseFlags(fs, mask)
fs.Parse([]string{})

assert.Equal(t, LocalCacheDir, CacheDir())
})
}
Loading
Loading