mailtest

package
v0.1.0-preview.4 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package mailtest provides an instance-owned, bounded mail sender for tests and local reference applications.

Index

Examples

Constants

View Source
const (
	// MaxCapacity bounds one sender's retained attempt and observation history.
	MaxCapacity = 10_000
)

Variables

View Source
var (
	// ErrCapacityExceeded reports a send that could not be retained because
	// the configured attempt history is full.
	ErrCapacityExceeded = errors.New("mail test sender capacity exceeded")
	// ErrInvalidMessage reports a Message value that does not contain the
	// valid MIME produced by mail.NewMessage.
	ErrInvalidMessage = errors.New("mail test sender received invalid message")
)

Functions

This section is empty.

Types

type Attachment

type Attachment struct {
	// contains filtered or unexported fields
}

Attachment is one immutable delivered MIME attachment.

func (Attachment) Bytes

func (attachment Attachment) Bytes() []byte

Bytes returns a defensive attachment-content copy.

func (Attachment) ContentType

func (attachment Attachment) ContentType() string

ContentType returns the normalized delivered media type.

func (Attachment) Filename

func (attachment Attachment) Filename() string

Filename returns the delivered attachment filename.

type Attempt

type Attempt struct {
	// contains filtered or unexported fields
}

Attempt is one accepted delivery attempt.

func (Attempt) Error

func (attempt Attempt) Error() error

Error returns the configured failure or cancellation result.

func (Attempt) Message

func (attempt Attempt) Message() Snapshot

Message returns a defensive immutable delivered snapshot.

func (Attempt) Number

func (attempt Attempt) Number() uint64

Number returns the one-based sender attempt number.

func (Attempt) Outcome

func (attempt Attempt) Outcome() Outcome

Outcome returns the delivery result class.

type CapacityError

type CapacityError struct {
	Capacity int
	Attempt  uint64
}

CapacityError describes an explicitly rejected send.

func (*CapacityError) Error

func (err *CapacityError) Error() string

Error implements error.

func (*CapacityError) Unwrap

func (err *CapacityError) Unwrap() error

Unwrap supports errors.Is with ErrCapacityExceeded.

type Config

type Config struct {
	Capacity int
	Failures []error
	Observer Observer
}

Config defines one immutable test sender policy. Failures are indexed by one-based accepted attempt number; a nil entry succeeds.

type Observation

type Observation struct {
	Attempt   uint64
	MessageID string
	Outcome   Outcome
}

Observation is bounded delivery metadata. It deliberately excludes recipients, subjects, bodies, attachments, and error text.

type Observer

type Observer func(context.Context, Observation)

Observer receives one synchronous observation after sender state is unlocked.

type Outcome

type Outcome string

Outcome classifies one test delivery attempt without retaining message content in observations.

const (
	// OutcomeDelivered reports a successfully recorded delivery.
	OutcomeDelivered Outcome = "delivered"
	// OutcomeFailed reports a configured deterministic transport failure.
	OutcomeFailed Outcome = "failed"
	// OutcomeCanceled reports cancellation observed after snapshot creation.
	OutcomeCanceled Outcome = "canceled"
	// OutcomeRejected reports an attempt rejected by the capacity bound.
	OutcomeRejected Outcome = "rejected"
)

type Sender

type Sender struct {
	// contains filtered or unexported fields
}

Sender records bounded immutable delivery attempts.

Example
package main

import (
	"context"
	"fmt"
	"time"

	spicemail "github.com/spice-framework/spice/mail"
	"github.com/spice-framework/spice/mail/mailtest"
)

func main() {
	message, err := spicemail.NewMessage(spicemail.MessageSpec{
		ID:       "welcome-7@example.com",
		Date:     time.Date(2026, time.July, 26, 12, 0, 0, 0, time.UTC),
		From:     "team@example.com",
		To:       []string{"developer@example.com"},
		Subject:  "Welcome",
		TextBody: "Spice is ready.",
	})
	if err != nil {
		panic(err)
	}
	sender, err := mailtest.New(mailtest.Config{Capacity: 10})
	if err != nil {
		panic(err)
	}
	if err := sender.Send(context.Background(), message); err != nil {
		panic(err)
	}
	delivered := sender.Messages()
	fmt.Println(delivered[0].Subject())
	fmt.Println(delivered[0].TextBody())
}
Output:
Welcome
Spice is ready.

func New

func New(config Config) (*Sender, error)

New validates and creates one isolated sender.

func (*Sender) AttemptCount

func (sender *Sender) AttemptCount() uint64

AttemptCount returns all numbered valid-message attempts, including capacity rejections.

func (*Sender) Attempts

func (sender *Sender) Attempts() []Attempt

Attempts returns deep defensive accepted-attempt copies in attempt order.

func (*Sender) Messages

func (sender *Sender) Messages() []Snapshot

Messages returns only successfully delivered snapshots in attempt order.

func (*Sender) Observations

func (sender *Sender) Observations() []Observation

Observations returns bounded payload-free accepted-attempt observations. Capacity rejections reach the configured Observer but are not retained after the history is full.

func (*Sender) Send

func (sender *Sender) Send(
	ctx context.Context,
	message spicemail.Message,
) error

Send records one immutable snapshot or returns an explicit failure. A context already canceled on entry is returned immediately and consumes no attempt capacity.

type Snapshot

type Snapshot struct {
	// contains filtered or unexported fields
}

Snapshot is one immutable view of the exact delivered envelope and MIME.

func (Snapshot) Attachments

func (snapshot Snapshot) Attachments() []Attachment

Attachments returns deep defensive attachment copies in MIME order.

func (Snapshot) Bytes

func (snapshot Snapshot) Bytes() []byte

Bytes returns a defensive copy of the complete delivered MIME.

func (Snapshot) EnvelopeFrom

func (snapshot Snapshot) EnvelopeFrom() string

EnvelopeFrom returns the SMTP envelope sender.

func (Snapshot) HTMLBody

func (snapshot Snapshot) HTMLBody() string

HTMLBody returns the decoded, CRLF-normalized HTML body.

func (Snapshot) ID

func (snapshot Snapshot) ID() string

ID returns the delivered Message-ID without angle brackets.

func (Snapshot) Recipients

func (snapshot Snapshot) Recipients() []string

Recipients returns the stable de-duplicated SMTP recipient envelope.

func (Snapshot) Subject

func (snapshot Snapshot) Subject() string

Subject returns the decoded Subject header.

func (Snapshot) TextBody

func (snapshot Snapshot) TextBody() string

TextBody returns the decoded, CRLF-normalized plain-text body.

Jump to

Keyboard shortcuts

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