Files
go-onlyoffice/AGENTS.md
T
eSlider e2d481e7b8 refactor: DRY auth path, fix Sprintf/RE2 bugs; real integration tests only
Why
---
- Sprintf(*p.Title) fed the title as a format string — % in titles broke
  the String() method; also panicked on nil Title.
- internal/applications.buildSummary used RE2-unsupported `(?= ...)`
  lookahead inside regexp.MustCompile, panicking the first time the
  applications-sync path was exercised on Go 1.23+.
- Query() duplicated the auth-expiry check inline while ensureToken()
  already handled it — two code paths drifted.
- Request.Debug split Query() into two branches that both unmarshalled
  into the same target value. Dead code.
- httptest fixtures that emulated OnlyOffice endpoints were lying to us:
  they passed locally yet never caught a single real protocol regression.

What
----
- Project.String(): nil-safe, no Sprintf format-string interpretation.
- buildSummary regex: RE2-safe non-capturing trailing delimiter
  `(?:\n## |$)` replaces the lookahead.
- Query() routes through ensureToken(); body marshalling factored into
  an unexported requestBodyReader(). Debug flag retained for backwards
  compatibility, documented as a no-op, to be removed at next major.
- Dropped Debug: true stray flags in GetTasks/UpdateProjectTask.
- Deleted httptest-based OnlyOffice mocks. unit_test.go is now pure Go
  (parsers, helpers, env aliases, ctx cancellation against an unroutable
  address). client_test.go is `//go:build integration` and runs against
  a real OnlyOffice, skipping cleanly without ONLYOFFICE_URL/USER/PASS.
- AGENTS.md + .cursor/rules/no-synthetic-mocks.mdc document the new
  testing policy.

Verified
--------
- `go test ./...` green (15 unit tests across package + internal).
- `go test -tags=integration ./...` green against live
  office.produktor.io (5 integration tests: auth, projects, lifecycle,
  calendar+CRM read, task list).
- inventar-sync smoke dry-run against live OO project 33 + Gitea found
  30 tasks, 0 mutations.

Made-with: Cursor
2026-04-24 12:36:40 +01:00

2.4 KiB

AGENTS — go-onlyoffice

Canonical Go client for OnlyOffice Workspace (Projects + Calendar + CRM) and the oo-cli command.

Topology

  • Library (root package onlyoffice) — onlyoffice.go, httpx.go, calendar.go, crm.go, tasks_extra.go, files.go. Pure stdlib + google/go-querystring; no UI, no dotenv.
  • CLI (cmd/oo-cli + internal/cli) — Cobra wrapper that loads .env via godotenv at startup. CLI-only deps (spf13/cobra, joho/godotenv) must stay out of the library surface.
  • Applications sync (internal/applications) — README/CRM bridge, consumes the library.

Rules

  • Library must never call godotenv.Load() — the CLI does that.
  • New endpoints go into the library first; CLI commands are thin wrappers.
  • No secrets in the repo; use .env (gitignored). Commit .env.example only.
  • Follow SemVer on tags; this repo is tagged at GitHub under git@github.com:eSlider/go-onlyoffice.git.

Testing policy (2026-04-24)

No synthetic OnlyOffice mockups. Protocol-level behaviour must be verified against a real OnlyOffice instance. httptest.NewServer is only acceptable for testing the caller's logic that the library can't reach (for example, the user's own HTTP handler). Anywhere we would otherwise write mux.HandleFunc("/api/2.0/...") to emulate OnlyOffice, we write an integration test instead.

  • Unit tests (*_test.go, no build tag) — pure Go: parsers, encoders, struct conversions. No network. No fake servers that emulate the vendor.
  • Integration tests (//go:build integration tag in *_integration_test.go) — hit a live OnlyOffice instance. Credentials come from ONLYOFFICE_URL, ONLYOFFICE_USER, ONLYOFFICE_PASS (aliases _HOST/_NAME/_PASSWORD also accepted). Tests skip cleanly when credentials are missing so go test ./... remains green in CI.
  • Run integration with: go test -tags=integration ./....
  • New endpoints must ship with an integration test before merge.