Documentation
¶
Overview ¶
Package supporttest is the support module's behaviour-test harness: the module's real repositories (tickets, announcements, ads and documents) and the platform's task bookkeeping the marketing tasks write, over a private in-memory SQLite database with miniredis as their cache, together with recording fakes of the module's ports onto the other domains, seeding and reading helpers, a way to make the database refuse statements, the API views of stored rows and a client for the Hertz handlers. Tests check what a flow stored and what a caller sees, not which repository call was made.
The harness builds no service: the subdomain packages, the facade and the handler tests build theirs from Env, so any of them may import it. It also gives the handler tests, which may import no other module, what they need of the identity and platform modules (a signed-in user, the task statuses). Only tests import it.
Index ¶
- Constants
- func AdView(ad ads.Ads) dto.Ads
- func AnnouncementView(a announcement.Announcement) dto.Announcement
- func Context() context.Context
- func DocumentView(d document.Document, tags ...string) dto.Document
- func EmailScope(t testing.TB, row task.Task) task.EmailScope
- func QuotaScope(t testing.TB, row task.Task) task.QuotaScope
- func TicketView(t ticket.Ticket, follows ...ticket.Follow) dto.Ticket
- func WithMetadata(ctx context.Context) context.Context
- func WithUser(ctx context.Context, id int64) context.Context
- type AuditLog
- type EmailCampaign
- type Env
- func (e *Env) Ad(t testing.TB, row ads.Ads) *ads.Ads
- func (e *Env) AllTasks(t testing.TB) []task.Task
- func (e *Env) Announcement(t testing.TB, row announcement.Announcement) *announcement.Announcement
- func (e *Env) Count(t testing.TB, model any) int64
- func (e *Env) Document(t testing.TB, row document.Document) *document.Document
- func (e *Env) EmailTask(t testing.TB, c EmailCampaign) int64
- func (e *Env) Follow(t testing.TB, row ticket.Follow) *ticket.Follow
- func (e *Env) Follows(t testing.TB, ticketID int64) []ticket.Follow
- func (e *Env) QuotaTask(t testing.TB, q QuotaCampaign) int64
- func (e *Env) Refuse(t testing.TB, op, table string, skip int, err error) (lift func())
- func (e *Env) ReloadAd(t testing.TB, id int64) ads.Ads
- func (e *Env) ReloadAnnouncement(t testing.TB, id int64) announcement.Announcement
- func (e *Env) ReloadDocument(t testing.TB, id int64) document.Document
- func (e *Env) ReloadTask(t testing.TB, id int64) task.Task
- func (e *Env) ReloadTicket(t testing.TB, id int64) ticket.Ticket
- func (e *Env) Task(t testing.TB, row task.Task) *task.Task
- func (e *Env) TaskError(t testing.TB, row task.TaskError)
- func (e *Env) TaskFailure(t testing.TB, taskID int64, position uint64, target, reason string, at int64)
- func (e *Env) Ticket(t testing.TB, row ticket.Ticket) *ticket.Ticket
- type MirroredReply
- type MirroredStatus
- type Notifier
- type Queue
- type QueuedEmail
- type QuotaCampaign
- type QuotaTargets
- type Recipients
- type Reply
- type Stopper
- type Subscriptions
Constants ¶
const ( ClientIP = "203.0.113.9" UserAgent = "support-test/1.0" ActorID = 1 )
ClientIP, UserAgent and ActorID are the request metadata Context carries.
const ( TaskPending = task.StatusPending TaskInProgress = task.StatusInProgress TaskCancelled = task.StatusCancelled TaskEnqueueFailed = task.StatusEnqueueFailed )
The task statuses the marketing tasks move through, re-exported for the handler tests, which may not import the platform module.
Variables ¶
This section is empty.
Functions ¶
func AnnouncementView ¶
func AnnouncementView(a announcement.Announcement) dto.Announcement
AnnouncementView shows a stored announcement.
func Context ¶
Context is a request context carrying ClientIP, UserAgent and ActorID, as the access-log and auth middlewares set them for an administrator's request.
func DocumentView ¶
DocumentView shows a stored document with its content as written and the tags given, which a test states rather than splitting the stored column the way the code under test does.
func EmailScope ¶
EmailScope decodes the scope a stored email task records.
func QuotaScope ¶
QuotaScope decodes the scope a stored quota task records.
func TicketView ¶
TicketView shows a stored ticket with the follows given, in their order.
func WithMetadata ¶
WithMetadata returns ctx carrying the request metadata Context carries.
Types ¶
type AuditLog ¶
AuditLog is the platform log port the administrators' mutations are recorded in: every row written, and Err failing every write.
type EmailCampaign ¶
type EmailCampaign struct {
Subject, Content string
Scope int8
Recipients, Additional []string
RegisterStartTime int64
RegisterEndTime int64
Scheduled int64
Interval uint8
Limit uint64
Status int8
Total, Current uint64
Errors string
}
EmailCampaign is a batch email task as the marketing service records it.
type Env ¶
type Env struct {
DB *gorm.DB
Redis *redis.Client
Mini *miniredis.Miniredis
Tickets repository.TicketRepo
Announcements repository.AnnouncementRepo
Ads repository.AdsRepo
Documents repository.DocumentRepo
// Tasks is the platform's task repository, which records the marketing
// tasks.
Tasks repository.TaskRepo
}
Env is one test's database, cache and repositories.
func (*Env) Announcement ¶
func (e *Env) Announcement(t testing.TB, row announcement.Announcement) *announcement.Announcement
Announcement stores an announcement; its unset flags are stored false.
func (*Env) EmailTask ¶
func (e *Env) EmailTask(t testing.TB, c EmailCampaign) int64
EmailTask stores the campaign and returns its task id.
func (*Env) QuotaTask ¶
func (e *Env) QuotaTask(t testing.TB, q QuotaCampaign) int64
QuotaTask stores the quota task and returns its task id; its total is the number of its objects.
func (*Env) Refuse ¶
Refuse makes the database refuse the statements of kind op on table with err once the first skip of them succeeded, until the test ends or the returned function lifts the refusal, so a flow's failure paths run against the real repositories. op is the GORM callback kind: "create", "query", "update", "delete" or "row" (a scanned select). A refused statement is not sent to the database.
func (*Env) ReloadAnnouncement ¶
func (e *Env) ReloadAnnouncement(t testing.TB, id int64) announcement.Announcement
ReloadAnnouncement reads an announcement as stored.
func (*Env) ReloadDocument ¶
ReloadDocument reads a document as stored.
func (*Env) ReloadTask ¶
ReloadTask reads a task as stored.
func (*Env) ReloadTicket ¶
ReloadTicket reads a ticket as stored.
type MirroredReply ¶
MirroredReply is a ticket reply mirrored to the admin group.
type MirroredStatus ¶
MirroredStatus is a ticket status change mirrored to the admin group.
type Notifier ¶
type Notifier struct {
Created []int64
Replies []MirroredReply
Statuses []MirroredStatus
}
Notifier records the ticket lifecycle the module mirrors to the Telegram admin group.
func (*Notifier) TicketCreated ¶
TicketCreated records the new ticket's id.
func (*Notifier) TicketReplied ¶
TicketReplied records the reply.
type Queue ¶
type Queue struct {
Emails []QueuedEmail
Quotas []int64
Err error
Received func(taskID int64)
}
Queue is the marketing task queue. It records every task handed to it; Err refuses them all, and Received, when set, runs as a task arrives, before the queue answers (a worker picking the task up at once).
type QueuedEmail ¶
QueuedEmail is a campaign handed to the queue and the time it is to run.
type QuotaCampaign ¶
type QuotaCampaign struct {
Subscribers []int64
IsActive *bool
StartTime, EndTime int64
// Objects are the user subscriptions the task applies to.
Objects []int64
ResetTraffic bool
Days uint64
GiftType uint8
GiftValue uint64
Status int8
Current uint64
Errors string
}
QuotaCampaign is a quota gift task as the marketing service records it.
type QuotaTargets ¶
type QuotaTargets struct {
IDs []int64
Err error
// Queried and Counted record the filters of the queries and counts.
Queried []usersub.SubscribeFilter
Counted []usersub.SubscribeFilter
}
QuotaTargets is the subscription port selecting the user subscriptions a quota task applies to: every query answers IDs, and every count their number.
func (*QuotaTargets) CountSubscribesByFilter ¶
func (q *QuotaTargets) CountSubscribesByFilter(_ context.Context, filter *usersub.SubscribeFilter) (int64, error)
CountSubscribesByFilter answers the number of IDs.
func (*QuotaTargets) QuerySubscribeIdsByFilter ¶
func (q *QuotaTargets) QuerySubscribeIdsByFilter(_ context.Context, filter *usersub.SubscribeFilter) ([]int64, error)
QuerySubscribeIdsByFilter answers IDs.
type Recipients ¶
type Recipients struct {
Emails []string
Err error
// Queried and Counted record the filters of the queries and counts.
Queried []user.EmailRecipientFilter
Counted []user.EmailRecipientFilter
}
Recipients is the identity port selecting the recipients of an email campaign: every query answers Emails, and every count their number.
func (*Recipients) CountEmailRecipients ¶
func (r *Recipients) CountEmailRecipients(_ context.Context, filter *user.EmailRecipientFilter) (int64, error)
CountEmailRecipients answers the number of Emails.
func (*Recipients) QueryEmailRecipients ¶
func (r *Recipients) QueryEmailRecipients(_ context.Context, filter *user.EmailRecipientFilter) ([]string, error)
QueryEmailRecipients answers Emails.
type Reply ¶
type Reply struct {
Status int `json:"-"`
Body string `json:"-"`
Code uint32 `json:"code"`
Msg string `json:"msg"`
Data json.RawMessage `json:"data"`
}
Reply is a handler's answer: the HTTP status, the raw body and the envelope decoded from it.
func Serve ¶
Serve performs method target on h, with body as a JSON document or, when body is empty, with no body, and decodes the JSON envelope of the answer.
func (Reply) Decode ¶
Decode fails the test unless the reply is the success envelope, and decodes its data into v.
type Stopper ¶
type Stopper struct {
Stopped []int64
}
Stopper records the campaigns whose running worker it was asked to stop.
func (*Stopper) StopBatchEmail ¶
StopBatchEmail records the campaign.
type Subscriptions ¶
type Subscriptions struct {
Active map[int64]bool
Err error
// Asked records the users asked about.
Asked []int64
}
Subscriptions is the subscription port the document rendering asks: the users in Active hold an active subscription, and Err fails every question.
func Subscribed ¶
func Subscribed(ids ...int64) *Subscriptions
Subscribed returns the port answering that exactly ids hold an active subscription.
func (*Subscriptions) HasActiveSubscription ¶
HasActiveSubscription reports whether userID is in Active.