Documentation
¶
Overview ¶
Package fakegithub is a Coach-owned, fixture-driven fake GitHub HTTP service for offline acceptance testing.
It implements only the contracts Coach consumes: OAuth identity (authorize/token exchange, /user and /api/v3/user), GitHub App installation (token mint, repo→installation, effective permissions), and repository content reads (Contents API file fetch plus directory listing for pkg/githubingest symlink detection). Fixture.RejectedTokens is the seam for non-GitHub credentials (Coach JWT stand-ins) that must record as acceptanceharness.AuthModeRejected on every route.
It is not a general-purpose GitHub emulator. Pull-request listing and changed-file reads are deferred to the PR History Scan epic.
The package consumes internal/acceptanceharness's shared fixture and request-recording contract rather than inventing a competing one. See docs/architecture/acceptance-harness.md section 6.
Index ¶
- Constants
- func Handler(fixture *Fixture) (http.Handler, *acceptanceharness.Recorder)
- type CommitEntry
- type ContentsFixture
- type DirEntry
- type FileEntry
- type Fixture
- type Identity
- type InstallationEntry
- type InstallationFixture
- type OAuthCodeEntry
- type OAuthFixture
- type OAuthTokenEntry
- type PermissionEntry
- type RepoInstallationEntry
- type RepoMetaEntry
- type RepoMetaFixture
- type Scenario
- type Server
- type TokenKind
Constants ¶
const DefaultFixtureID = "coach-fakegithub-default"
DefaultFixtureID is a FixtureID for tests that do not need multiple datasets.
Variables ¶
This section is empty.
Functions ¶
func Handler ¶
func Handler(fixture *Fixture) (http.Handler, *acceptanceharness.Recorder)
Handler builds the http.Handler and Recorder that answer fixture's OAuth, installation, and contents routes -- the same route table NewServer wraps in an httptest.Server. Callers that need the fake embedded in their own server topology (e.g. a standalone process serving real HTTP, rather than an in-process httptest.Server) can use Handler directly. fixture must outlive the returned handler (it is not copied). Panics if fixture is nil.
Types ¶
type CommitEntry ¶ added in v0.2.0
CommitEntry is a resolved commit object for GET /repos/{owner}/{repo}/commits/{ref}.
type ContentsFixture ¶
type ContentsFixture struct {
Files map[string]FileEntry // "owner/repo/ref/path" -> file
Dirs map[string][]DirEntry // "owner/repo/ref/dirpath" (root path segment omitted) -> listing
}
ContentsFixture holds file contents and directory listings, both keyed by repo/ref/path so one fixture can answer the file read and the parent-dir listing githubingest ReadFile uses for symlink detection.
A successful ReadFile needs both: Files[fileKey] and Dirs[parentKey]. Omitting the parent Dirs entry yields 404 on the symlink-check listing and surfaces as githubingest.ErrNotFound even when the file Scenario is OK.
type DirEntry ¶
type DirEntry struct {
Name string
Type string // "file" | "dir" | "symlink" | "submodule"
SHA string
Size int
}
DirEntry is one entry in a fixture directory listing.
type FileEntry ¶
FileEntry is file content keyed in ContentsFixture.Files by "owner/repo/ref/path". For ScenarioOversized, Content may be nil — the wire size is forced above the Contents API 1 MiB limit.
type Fixture ¶
type Fixture struct {
Header acceptanceharness.FixtureHeader
OAuth OAuthFixture
Installation InstallationFixture
Contents ContentsFixture
Repos RepoMetaFixture
// RejectedTokens are bearer credentials that must never be accepted on
// any route (AuthModeRejected). Use for non-GitHub credentials (notably a
// Coach JWT stand-in) without inventing coach-api or weakening the
// "unknown bearer ≈ unverifiable App JWT" simplification on installation
// mint/resolution. Empty string is never a rejected token.
RejectedTokens map[string]struct{}
// contains filtered or unexported fields
}
Fixture is the versioned dataset a Server answers from, stamped with the shared acceptanceharness fixture envelope.
func NewFixture ¶
NewFixture returns an empty Fixture with SchemaVersion set and every map non-nil so callers can assign without a nil-map panic.
func (*Fixture) ClassifyToken ¶
ClassifyToken reports which credential registry token belongs to. Empty token is always TokenUnknown, even if an InstallationEntry has an empty Token (auth-fail/transient entries never mint). RejectedTokens is checked before OAuth/installation so a rejected stand-in cannot collide with a minted credential and be reclassified.
type InstallationEntry ¶
InstallationEntry is a fixture-registered GitHub App installation.
type InstallationFixture ¶
type InstallationFixture struct {
Installations map[int64]InstallationEntry // installation ID -> entry
RepoMappings map[string]RepoInstallationEntry // "owner/repo" -> entry
Permissions map[string]PermissionEntry // "owner/repo/username" -> entry
}
InstallationFixture is the GitHub App installation slice of a Fixture.
type OAuthCodeEntry ¶
OAuthCodeEntry is a fixture-registered authorization code awaiting exchange.
type OAuthFixture ¶
type OAuthFixture struct {
ClientID string
ClientSecret string
Identities map[string]Identity // login -> Identity
// Codes maps authorization code -> entry. A successful exchange deletes
// the code (single-use, like real GitHub); the handler registers the
// minted token into Tokens. No separate "already used" flag.
Codes map[string]OAuthCodeEntry
Tokens map[string]OAuthTokenEntry // access token -> entry
}
OAuthFixture is the OAuth slice of a Fixture.
type OAuthTokenEntry ¶
OAuthTokenEntry is a fixture-registered OAuth access token for GET /user.
type PermissionEntry ¶
type PermissionEntry struct {
Level string // "admin" | "write" | "read" | "none"
Scenario Scenario
}
PermissionEntry is the effective permission for a (repo, username) pair.
type RepoInstallationEntry ¶
RepoInstallationEntry maps owner/repo to the governing installation ID.
type RepoMetaEntry ¶ added in v0.2.0
RepoMetaEntry is repository metadata for GET /repos/{owner}/{repo} (default-branch resolution for empty refs).
type RepoMetaFixture ¶ added in v0.2.0
type RepoMetaFixture struct {
Repos map[string]RepoMetaEntry // "owner/repo" -> meta
Commits map[string]CommitEntry // "owner/repo/ref" -> commit
}
RepoMetaFixture holds repository metadata and commit resolutions used by githubingest.ResolveCommitSHA.
type Scenario ¶
type Scenario string
Scenario names a deterministic non-success (or success) outcome for a fixture entry, so not-found/auth-failure/transient/oversized behavior is independent of real GitHub state or timing.
const ( ScenarioOK Scenario = "ok" // successful response ScenarioNotFound Scenario = "not-found" // HTTP 404 ScenarioAuthFail Scenario = "auth-failure" // HTTP 401 ScenarioTransient Scenario = "transient" // HTTP 503 ScenarioOversized Scenario = "oversized" // Contents API oversize (encoding "none") )
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is an in-process httptest.Server for the OAuth, installation, and contents routes this package implements. It is driven by a caller-supplied Fixture and records every handled request via acceptanceharness.Recorder.
Route paths live in routes.go; handler bodies live in the file named for their API (oauth.go, oauth_user.go, installation.go, permission.go, contents.go, repo_meta.go).
func NewServer ¶
NewServer starts a Server backed by fixture. fixture must outlive the Server (it is not copied). Callers must Close when done. Panics if fixture is nil.
func (*Server) Recorder ¶
func (s *Server) Recorder() *acceptanceharness.Recorder
Recorder returns the request recorder for sequence/auth assertions.