corteq-onepassword 0.1.5

Secure 1Password SDK wrapper with FFI bindings for Rust applications
Documentation
# Testing Guide

## Overview

This crate includes unit and integration tests.
Unit tests run without external dependencies, test parsing, error handling, and FFI layer.
The integration tests require a valid 1Password service account token to test actual SDK operations

## Prerequisites

### Unit Tests

No setup required. Unit tests run automatically with:

```bash
cargo test --lib
```

### Integration Tests

1. **Create a 1Password service account**

   - Go to your 1Password account settings
   - Create a new service account
   - Note: Personal account tokens are NOT supported

2. **Set up a test vault**

   - Create or use an existing vault (e.g., "Development")
   - Grant the service account access to this vault

3. **Create a test item**
   - Create an item in the vault with a known field value
   - Example: Create a "test-secret" item with a "password" field

## Environment Variables

| Variable                   | Required | Description                                        |
| -------------------------- | -------- | -------------------------------------------------- |
| `OP_SERVICE_ACCOUNT_TOKEN` | Yes\*    | Service account token (starts with `ops_`)         |
| `TEST_SECRET_REF`          | Yes\*    | Secret reference in format `op://vault/item/field` |
| `TEST_SECRET_VALUE`        | No       | Expected value for verification                    |

\*Required for integration tests only

### Example Setup

```bash
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
export TEST_SECRET_REF="op://Development/test-secret/password"
export TEST_SECRET_VALUE="expected-value"  # Optional
```

## Running Tests

### Unit Tests (No credentials needed)

```bash
# Run all unit tests
cargo test --lib

# Run specific module tests
cargo test --lib client::tests
cargo test --lib error::tests
cargo test --lib secret::tests
cargo test --lib ffi::loader::tests
cargo test --lib ffi::bindings::tests
cargo test --lib ffi::protocol::tests
cargo test --lib ffi::uniffi_types::tests

# Run with verbose output
cargo test --lib -- --nocapture
```

### Integration Tests (credentials required)

```bash
# Set environment variables first
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
export TEST_SECRET_REF="op://Vault/Item/field"

# Run integration tests only (ignored by default)
cargo test --lib -- --ignored

# Run ALL tests (unit + integration)
cargo test --lib -- --include-ignored

# Run external integration tests (tests/ directory)
cargo test --test integration -- --ignored
```

### Feature-specific tests

```bash
# Test with blocking feature
cargo test --lib --features blocking

# Test with tracing feature
cargo test --lib --features tracing

# Test with all features
cargo test --lib --all-features

# All features + integration tests
cargo test --lib --all-features -- --include-ignored
```

## Code Coverage

### Setup

```bash
# Install cargo-llvm-cov
cargo install cargo-llvm-cov
```

### Running Coverage

**Important:** Use `--ignore-filename-regex` to exclude test code from coverage metrics.
Without this flag, `#[ignore]` integration tests count as "missed lines" and artificially lower coverage.

```bash
# Run coverage on unit tests (recommended)
cargo llvm-cov --lib --ignore-filename-regex='mod tests'

# Run coverage including integration tests (credentials required)
# Note: Use --include-ignored to run BOTH unit AND integration tests
# Using just --ignored runs ONLY integration tests (skips unit tests!)
cargo llvm-cov --lib --ignore-filename-regex='mod tests' -- --include-ignored

# Generate HTML report
cargo llvm-cov --lib --ignore-filename-regex='mod tests' --html
# View at: target/llvm-cov/html/index.html

# Show text summary with line details
cargo llvm-cov --lib --ignore-filename-regex='mod tests' --text
```

### Understanding the Coverage Report

When you run `cargo llvm-cov`, you'll see a table like this:

```
Filename        Regions  Missed Regions  Cover  Functions  Missed Functions  Executed  Lines  Missed Lines  Cover  Branches  Missed Branches  Cover
client.rs           258             102  60.5%         29                11    62.1%    151            55  63.6%         0                0      -
```

#### What Each Column Means

| Column               | Description                                                                        |
| -------------------- | ---------------------------------------------------------------------------------- |
| **Regions**          | Smallest trackable code units (blocks without branches). More granular than lines. |
| **Missed Regions**   | Regions never executed during tests.                                               |
| **Functions**        | Total functions/methods in the file.                                               |
| **Missed Functions** | Functions never called during tests.                                               |
| **Lines**            | Source code lines (most intuitive metric).                                         |
| **Missed Lines**     | Lines never executed during tests.                                                 |
| **Branches**         | Decision points (if/else, match arms). Shows "-" when unavailable.                 |

#### Which Metric to Focus On

- **Lines**: Start here - "did this code run?"
- **Functions**: High-level view - "did we call this at all?"
- **Regions**: Fine-grained - useful when one line has multiple statements
- **Branches**: Decision coverage - "did we test both if and else?"

### What To Do With Missed Code

#### Is it dead code?

If a function shows 0% coverage:

| Possibility    | Action                                 |
| -------------- | -------------------------------------- |
| Dead code      | Safe to remove                         |
| Future feature | Document why it exists                 |
| Feature-gated  | Run tests with `--all-features`        |
| Error handler  | Keep it, hard to trigger but important |

#### Is it error handling?

Error paths often have low coverage. Options:

- Write tests that deliberately trigger errors
- Use mocks to simulate failure conditions
- Accept lower coverage for truly exceptional cases

#### Is it integration-only code?

Code requiring external dependencies (APIs, databases):

- Write integration tests with `#[ignore]` attribute
- Run `cargo llvm-cov --lib -- --ignored` with credentials
- Accept lower unit test coverage if integration tests verify it

#### Common patterns

| Pattern                     | Recommendation                                      |
| --------------------------- | --------------------------------------------------- |
| Unused `pub` function       | Consider making private or removing                 |
| `impl Debug/Display`        | Usually fine to leave untested                      |
| Match arm never hit         | Verify it's reachable; if not, use `unreachable!()` |
| `From` impl never triggered | Write test that triggers the conversion             |

### Coverage Targets

| Target         | Use Case                               |
| -------------- | -------------------------------------- |
| **80%+ lines** | Good baseline for most projects        |
| **90%+ lines** | High confidence                        |
| **100%**       | Often impractical; diminishing returns |

### When Low Coverage Is Acceptable

- Generated code (FFI bindings, macros)
- Panic handlers and `unreachable!()` branches
- Platform-specific code (tested on other platforms)
- Debug-only code (`#[cfg(debug_assertions)]`)

## Need help?

### "Skipping: OP_SERVICE_ACCOUNT_TOKEN not set"

Integration tests are skipped when no token is available. This is expected behavior for unit test runs.

### "Authentication failed" errors

- Verify your token is valid and not expired
- Ensure the token starts with `ops_`
- Check that the service account has access to the vault

### "Secret not found" errors

- Verify the secret reference format: `op://vault/item/field`
- Check that the vault, item, and field names are correct
- Ensure the service account has read access to the item

### "Library not found" errors

The native 1Password SDK library is downloaded during build. If you see library errors:

```bash
# Clean and rebuild
cargo clean
cargo build
```

Or set a custom library path:

```bash
export ONEPASSWORD_LIB_PATH="/path/to/libop_uniffi_core.so"
```

**Security Note**: Never commit tokens to source control. Use CI secrets management.