slacktest

package
v1.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package slacktest provides a fake Slack host for testing.

It serves both the public API that slack-go calls and the internal endpoints (client.counts, subscriptions.thread.getView) that this server reads directly. Response shapes are taken from real responses captured against a live workspace, including the fields ADR-003 depends on — `latest` on every conversation whether read or unread, and `latest_reply` on thread roots.

Typical use:

srv := slacktest.New(t)
srv.Handle("client.counts", func(*http.Request) any { ... })
p := srv.Provider(t)

When a test asserts how many requests something made — the cost of a tick, or that a read tool did not touch the read marker — quiesce before measuring, because provider bootstrap continues in background goroutines:

p := srv.Provider(t)
p.Provide()
srv.Quiesce(t)
srv.ResetCalls()
// ... exercise the tool, then assert srv.Calls(...)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Channel

func Channel(id, name string) map[string]any

Channel builds a conversations entry the caller is a member of.

func Conversation

func Conversation(id, lastRead, latest string, hasUnreads bool, mentions int) map[string]any

Conversation builds one client.counts entry. `latest` is present whether or not the conversation has unreads — the property ADR-003's watermark relies on.

func Counts

func Counts(channels, ims []any) map[string]any

Counts builds a client.counts response including the per-channel thread counts that thread_counts_by_channel=true adds.

func Message

func Message(user, text, ts string) map[string]any

Message builds a conversations.history entry.

func Thread

func Thread(channel, threadTs, latestReply string, replyCount, unread int) map[string]any

Thread builds one subscriptions.thread.getView entry.

func ThreadView

func ThreadView(threads ...any) map[string]any

ThreadView wraps threads in a getView response. Note the real endpoint caps at 10 entries per page and pages via current_ts; tests that care about paging should override the handler.

func User

func User(id, name, realName string) map[string]any

User builds a users.list member entry.

Types

type Handler

type Handler func(r *http.Request) any

Handler produces the JSON body for one endpoint. Returning nil falls through to the default fixture.

type Server

type Server struct {
	*httptest.Server
	// contains filtered or unexported fields
}

Server is a fake Slack host.

func New

func New(t *testing.T) *Server

New starts a fake Slack host serving default fixtures. It is closed when the test finishes.

func (*Server) Calls

func (s *Server) Calls(method string) int

Calls reports how many times an endpoint was requested. Use it to assert the cost of a tick, not only its output.

func (*Server) Handle

func (s *Server) Handle(method string, h Handler)

Handle overrides the response for one endpoint, named without the "/api/" prefix (e.g. "client.counts").

func (*Server) Provider

func (s *Server) Provider(t *testing.T) *provider.ApiProvider

Provider returns an ApiProvider whose public and internal clients both point at this server, started warm.

The provider loads members channels in a background goroutine (the two-phase cache from ADR-001), so a test that relied on that fetch would race it. Seeding the on-disk cache first means loadChannelsFromCache — which runs synchronously during bootstrap — has the fixtures before any tool runs.

func (*Server) Quiesce

func (s *Server) Quiesce(t *testing.T)

Quiesce blocks until the server has been idle for a short settle window, so that background bootstrap traffic cannot land in the middle of a measurement.

The provider spawns loadMemberChannels and backgroundBackfill as goroutines holding context.Background(), so nothing cancels them and nothing reports when they finish. Without this, a test asserting exact call counts races them, and a test that ends promptly tears the server down underneath one — which shows up as "EOF" or "connection refused" in bootstrap log lines.

func (*Server) ResetCalls

func (s *Server) ResetCalls()

ResetCalls zeroes the call counters, so a test can measure one phase in isolation from provider bootstrap.

Call Quiesce first. Bootstrap traffic runs partly in background goroutines, so resetting without quiescing leaves a window in which a late bootstrap request lands after the reset and inflates the counters being measured.

func (*Server) SeedChannels

func (s *Server) SeedChannels(channels ...slack.Channel)

SeedChannels replaces the channels a provider starts warm with.

func (*Server) SeedUsers

func (s *Server) SeedUsers(users ...slack.User)

SeedUsers replaces the users a provider starts warm with.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL