package main import ( "sync" "testing" "github.com/mattermost/mattermost/server/public/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestParseLanguageFlag(t *testing.T) { tests := []struct { name string input string wantLanguage string wantQuery string }{ { name: "no flag", input: "The Great Gatsby", wantLanguage: "", wantQuery: "The Great Gatsby", }, { name: "flag with space", input: "--language en The Great Gatsby", wantLanguage: "en", wantQuery: "The Great Gatsby", }, { name: "flag with equals", input: "--language=en The Great Gatsby", wantLanguage: "en", wantQuery: "The Great Gatsby", }, { name: "flag in middle", input: "The Great --language en Gatsby", wantLanguage: "en", wantQuery: "The Great Gatsby", // Double space from flag removal, trimmed only at edges }, { name: "flag only no query", input: "--language en", wantLanguage: "en", wantQuery: "", }, { name: "extra whitespace", input: " --language es Don Quixote ", wantLanguage: "es", wantQuery: "Don Quixote", }, { name: "empty input", input: "", wantLanguage: "", wantQuery: "", }, { name: "flag at end", input: "Don Quixote --language es", wantLanguage: "es", wantQuery: "Don Quixote", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { lang, query := parseLanguageFlag(tt.input) assert.Equal(t, tt.wantLanguage, lang) assert.Equal(t, tt.wantQuery, query) }) } } func TestEphemeralResponse(t *testing.T) { resp := ephemeralResponse("test message") assert.Equal(t, model.CommandResponseTypeEphemeral, resp.ResponseType) assert.Equal(t, "test message", resp.Text) } func TestRenderPostMessage(t *testing.T) { makePlugin := func(template string) *Plugin { return &Plugin{ configurationLock: sync.RWMutex{}, configuration: &configuration{ PostTemplate: template, }, } } t.Run("default template", func(t *testing.T) { p := makePlugin("") task := &DownloadTask{BookTitle: "My Book"} msg, err := p.renderPostMessage(task) require.NoError(t, err) assert.Equal(t, "### My Book", msg) }) t.Run("custom template", func(t *testing.T) { p := makePlugin("**{{.Title}}** by {{.AuthorsList}}") task := &DownloadTask{ BookTitle: "My Book", BookAuthors: []string{"Author A", "Author B"}, } msg, err := p.renderPostMessage(task) require.NoError(t, err) assert.Equal(t, "**My Book** by Author A, Author B", msg) }) t.Run("localized title takes precedence", func(t *testing.T) { p := makePlugin("") task := &DownloadTask{ BookTitle: "Original Title", LocalizedTitle: "Titulo Localizado", } msg, err := p.renderPostMessage(task) require.NoError(t, err) assert.Equal(t, "### Titulo Localizado", msg) }) t.Run("invalid template returns error", func(t *testing.T) { p := makePlugin("{{.Invalid") task := &DownloadTask{BookTitle: "Test"} _, err := p.renderPostMessage(task) require.Error(t, err) }) } func TestHandleRequestBook_EmptyQuery(t *testing.T) { p := &Plugin{ configurationLock: sync.RWMutex{}, configuration: &configuration{ ShelfmarkHost: "http://localhost:8084", ChannelID: "ch1", }, } resp, err := p.handleRequestBook(&model.CommandArgs{ Command: "/requestbook", }, "en") require.NoError(t, err) require.NotNil(t, resp) assert.Contains(t, resp.Text, "Usage:") } func TestHandleRequestBook_InvalidConfig(t *testing.T) { p := &Plugin{ configurationLock: sync.RWMutex{}, configuration: &configuration{}, } resp, err := p.handleRequestBook(&model.CommandArgs{ Command: "/requestbook some book", }, "en") require.NoError(t, err) require.NotNil(t, resp) assert.Contains(t, resp.Text, "not configured") }