open-code-review/cmd/opencodereview/provider_config_apply_test.go
kite 840f85f9bc
test: raise statement coverage to 90% and enforce it in CI (#747)
* test: raise statement coverage to 90% and enforce it in CI

Add unit tests across the cmd and internal packages to bring total
statement coverage above 90%, and gate future regressions.

- Cover CLI helpers, provider TUI handlers, resume/manifest paths, and
  error branches in config, llm, llmloop, scan, session, agent, viewer,
  mcp, pathutil, and telemetry.
- Raise the coverage threshold from 80% to 90% in the Makefile
  (COVERAGE_THRESHOLD) and in the CI "Check coverage threshold" step.
- Ignore generated coverage.out and coverage.html artifacts.

Total statement coverage is now 90.5%, measured consistently by both
`make coverage` and the CI `go test ./...` scope.

* test: widen statement coverage margin with environment-independent unit tests

Add table-driven unit tests for pure, environment-independent functions to
raise the statement-coverage safety margin above the 90% threshold:

- session.ResumeState.ValidateScanOptions (70% -> 100%)
- rules.SystemRule.UnmarshalJSON error branches (71% -> 82%)
- llmloop.stripMarkdownFences no-newline branch (82% -> 100%)
- diff.firstLine empty/blank-input branch
- diff.extractCodeBlock missing-newline and no-closing-fence branches
- main.truncate n<=1 and normalization branches
- agent.Agent nil-receiver accessor guards
2026-08-06 12:55:44 +08:00

61 lines
2.1 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 alibaba/open-code-review Contributors
package main
import (
"path/filepath"
"strings"
"testing"
)
// TestApplyOfficialProviderConfig_Validation covers the pre-save validation
// branches (empty provider, empty model, missing API key) that reject the
// request before any network connection test runs.
func TestApplyOfficialProviderConfig_Validation(t *testing.T) {
configPath := filepath.Join(t.TempDir(), "config.json")
t.Run("empty provider rejected", func(t *testing.T) {
err := applyOfficialProviderConfig(configPath, &Config{}, providerTUIResult{})
if err == nil || !strings.Contains(err.Error(), "required") {
t.Fatalf("got %v, want provider/model required error", err)
}
})
t.Run("empty model rejected", func(t *testing.T) {
err := applyOfficialProviderConfig(configPath, &Config{}, providerTUIResult{provider: "openai"})
if err == nil || !strings.Contains(err.Error(), "required") {
t.Fatalf("got %v, want provider/model required error", err)
}
})
t.Run("missing API key for non-preset provider rejected", func(t *testing.T) {
err := applyOfficialProviderConfig(configPath, &Config{}, providerTUIResult{
provider: "not-a-preset-provider",
model: "m",
})
if err == nil || !strings.Contains(err.Error(), "API key is required") {
t.Fatalf("got %v, want API-key-required error", err)
}
})
}
// TestSetCustomProviderValue covers the malformed-key rejection and the
// success path that materializes a custom provider entry.
func TestSetCustomProviderValue(t *testing.T) {
t.Run("malformed key rejected", func(t *testing.T) {
if err := setCustomProviderValue(&Config{}, "custom_providers.onlyname", "v"); err == nil {
t.Error("expected error for key missing a field segment")
}
})
t.Run("success sets a custom provider field", func(t *testing.T) {
cfg := &Config{}
if err := setCustomProviderValue(cfg, "custom_providers.cp.url", "https://x.example"); err != nil {
t.Fatalf("setCustomProviderValue: %v", err)
}
if cfg.CustomProviders["cp"].URL != "https://x.example" {
t.Errorf("custom provider url not set: %+v", cfg.CustomProviders)
}
})
}