Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
branches:
- main

permissions:
contents: read
actions: read
checks: write

jobs:
test:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -49,5 +54,56 @@ jobs:
- name: Build packages
run: pnpm -r run build

- name: Run tests and lint
run: pnpm -r run test
- name: Run SDK tests
id: sdk-test
working-directory: packages/b2c-tooling-sdk
run: pnpm run test:ci && pnpm run lint

- name: Run CLI tests
id: cli-test
if: always() && steps.sdk-test.conclusion != 'cancelled'
working-directory: packages/b2c-cli
run: pnpm run test:ci && pnpm run lint

- name: Test Report
uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0
if: always() && steps.sdk-test.conclusion != 'cancelled'
with:
name: Test Results (Node ${{ matrix.node-version }})
path: 'packages/*/test-results.json'
reporter: mocha-json

- name: Generate coverage summary
if: always() && steps.sdk-test.conclusion != 'cancelled'
run: |
echo "## Coverage (Node ${{ matrix.node-version }})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

# SDK Coverage
if [ -f "packages/b2c-tooling-sdk/coverage/lcov.info" ]; then
echo "### @salesforce/b2c-tooling-sdk" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cd packages/b2c-tooling-sdk && pnpm c8 report --reporter=text-summary 2>/dev/null | tail -n 6 >> $GITHUB_STEP_SUMMARY
cd ../..
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
fi

# CLI Coverage
if [ -f "packages/b2c-cli/coverage/lcov.info" ]; then
echo "### @salesforce/b2c-cli" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cd packages/b2c-cli && pnpm c8 report --reporter=text-summary 2>/dev/null | tail -n 6 >> $GITHUB_STEP_SUMMARY
cd ../..
echo '```' >> $GITHUB_STEP_SUMMARY
fi

- name: Upload coverage reports
if: always() && steps.sdk-test.conclusion != 'cancelled'
uses: actions/upload-artifact@v4
with:
name: coverage-reports-node-${{ matrix.node-version }}
path: |
packages/b2c-tooling-sdk/coverage/
packages/b2c-cli/coverage/
retention-days: 30
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/dist
/tmp
/node_modules
/coverage
oclif.manifest.json


Expand Down
72 changes: 72 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,75 @@ Features:
- Dynamic column widths based on content
- Supports `extended` flag on columns for optional fields
- Use `TableRenderer` class directly for column validation helpers (e.g., `--columns` flag support)

## Testing

Tests use Mocha + Chai with c8 for coverage. HTTP mocking uses MSW (Mock Service Worker).

### Running Tests

```bash
# Run all tests with coverage
pnpm run test

# Run tests for specific package
pnpm --filter @salesforce/b2c-tooling-sdk run test

# Run single test file (no coverage, faster)
cd packages/b2c-tooling-sdk
pnpm mocha "test/clients/webdav.test.ts"

# Run tests matching pattern
pnpm mocha --grep "mkcol" "test/**/*.test.ts"

# Watch mode for TDD
pnpm --filter @salesforce/b2c-tooling-sdk run test:watch
```

### Writing Tests

- Place tests in `packages/<package>/test/` mirroring the src structure
- Use `.test.ts` suffix for test files
- Import from package names, not relative paths:
```typescript
// Good - uses package exports
import { WebDavClient } from '@salesforce/b2c-tooling-sdk/clients';

// Avoid - relative paths
import { WebDavClient } from '../../src/clients/webdav.js';
```

### HTTP Mocking with MSW

For testing HTTP clients, use MSW to mock at the network level:

```typescript
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';

const server = setupServer();

before(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
after(() => server.close());

it('makes HTTP request', async () => {
server.use(
http.get('https://example.com/api/*', () => {
return HttpResponse.json({ data: 'test' });
}),
);

// Test code that makes HTTP requests...
});
```

### Test Helpers

- `test/helpers/mock-auth.ts` - Mock AuthStrategy for testing HTTP clients

### Coverage

- Coverage reports generated in `coverage/` directory
- SDK package has 5% minimum threshold (will increase as tests are added)
- CI publishes coverage summary to GitHub Actions job summary
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,42 @@ pnpm --filter @salesforce/b2c-cli run build
pnpm --filter @salesforce/b2c-tooling-sdk run build
```

### Testing and Linting
### Testing

Tests use [Mocha](https://mochajs.org/) + [Chai](https://www.chaijs.com/) with [c8](https://github.com/bcoe/c8) for coverage. HTTP mocking uses [MSW](https://mswjs.io/).

```bash
# Run all tests (also runs linter after tests)
# Run all tests with coverage (also runs linter after tests)
pnpm test

# Run tests for a specific package
pnpm --filter @salesforce/b2c-tooling-sdk run test

# Run tests without coverage (faster)
pnpm --filter @salesforce/b2c-tooling-sdk run test:unit

# Watch mode for TDD
pnpm --filter @salesforce/b2c-tooling-sdk run test:watch

# Run a specific test file
cd packages/b2c-tooling-sdk
pnpm mocha "test/clients/webdav.test.ts"

# Run tests matching a pattern
pnpm mocha --grep "uploads a file" "test/**/*.test.ts"
```

#### Coverage

Coverage reports are generated in each package's `coverage/` directory:
- `coverage/index.html` - HTML report
- `coverage/lcov.info` - LCOV format for CI integration

The SDK package has a 5% coverage threshold that will fail the build if not met.

### Linting

```bash
# Run linter only
pnpm --filter @salesforce/b2c-cli run lint
pnpm --filter @salesforce/b2c-tooling-sdk run lint
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"scripts": {
"start": "pnpm --filter @salesforce/b2c-cli run dev",
"test": "pnpm -r test",
"test:unit": "pnpm -r run test:unit",
"coverage": "pnpm -r run coverage",
"format": "pnpm -r run format",
"lint": "pnpm -r run lint",
"build": "pnpm -r run build",
Expand All @@ -16,7 +18,7 @@
},
"keywords": [],
"author": "",
"license": "ISC",
"license": "MIT",
"packageManager": "pnpm@10.17.1",
"devDependencies": {
"typedoc": "^0.28.14",
Expand Down
10 changes: 10 additions & 0 deletions packages/b2c-cli/.c8rc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"all": true,
"src": ["src"],
"exclude": [
"test/**",
"**/*.d.ts"
],
"reporter": ["text", "text-summary", "html", "lcov"],
"report-dir": "coverage"
}
2 changes: 2 additions & 0 deletions packages/b2c-cli/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
/build
/tmp
/node_modules
/coverage
test-results.json
oclif.manifest.json


Expand Down
6 changes: 5 additions & 1 deletion packages/b2c-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@types/chai": "^4",
"@types/mocha": "^10",
"@types/node": "^18",
"c8": "^10.1.3",
"chai": "^4",
"eslint": "^9",
"eslint-config-oclif": "^6",
Expand Down Expand Up @@ -116,7 +117,10 @@
"posttest": "pnpm run lint",
"prepack": "oclif manifest && oclif readme",
"pretest": "tsc --noEmit -p test",
"test": "OCLIF_TEST_ROOT=. mocha --forbid-only \"test/**/*.test.ts\"",
"test": "c8 env OCLIF_TEST_ROOT=. mocha --forbid-only \"test/**/*.test.ts\"",
"test:ci": "c8 env OCLIF_TEST_ROOT=. mocha --forbid-only --reporter json --reporter-option output=test-results.json \"test/**/*.test.ts\"",
"test:unit": "env OCLIF_TEST_ROOT=. mocha --forbid-only \"test/**/*.test.ts\"",
"coverage": "c8 report",
"version": "oclif readme && git add README.md",
"dev": "node ./bin/dev.js"
},
Expand Down
16 changes: 16 additions & 0 deletions packages/b2c-tooling-sdk/.c8rc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"all": true,
"src": ["src"],
"exclude": [
"src/clients/*.generated.ts",
"test/**",
"**/*.d.ts"
],
"reporter": ["text", "text-summary", "html", "lcov"],
"report-dir": "coverage",
"check-coverage": true,
"lines": 5,
"functions": 5,
"branches": 5,
"statements": 5
}
2 changes: 2 additions & 0 deletions packages/b2c-tooling-sdk/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
/dist
/tmp
/node_modules
/coverage
test-results.json


yarn.lock
Expand Down
6 changes: 6 additions & 0 deletions packages/b2c-tooling-sdk/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"node-option": ["import=tsx", "conditions=development"],
"timeout": 10000,
"recursive": true,
"extension": ["ts"]
}
7 changes: 7 additions & 0 deletions packages/b2c-tooling-sdk/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,11 @@ export default [
'new-cap': 'off',
},
},
{
// Allow Chai property-based assertions in test files (e.g., expect(x).to.be.true)
files: ['test/**/*.ts'],
rules: {
'@typescript-eslint/no-unused-expressions': 'off',
},
},
];
14 changes: 13 additions & 1 deletion packages/b2c-tooling-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,12 @@
"lint": "eslint",
"format": "prettier --write src",
"format:check": "prettier --check src",
"test": "echo \"Error: no test specified\" && exit 0",
"pretest": "tsc --noEmit -p test",
"test": "c8 mocha --forbid-only \"test/**/*.test.ts\"",
"test:ci": "c8 mocha --forbid-only --reporter json --reporter-option output=test-results.json \"test/**/*.test.ts\"",
"test:unit": "mocha --forbid-only \"test/**/*.test.ts\"",
"test:watch": "mocha --watch \"test/**/*.test.ts\"",
"coverage": "c8 report",
"posttest": "pnpm run lint"
},
"devDependencies": {
Expand All @@ -172,14 +177,21 @@
"@salesforce/dev-config": "^4.3.2",
"@tony.ganchev/eslint-plugin-header": "^3.1.11",
"@types/archiver": "^7.0.0",
"@types/chai": "^4.3.20",
"@types/mocha": "^10.0.10",
"@types/node": "^18.19.130",
"@types/xml2js": "^0.4.14",
"c8": "^10.1.3",
"chai": "^4.5.0",
"eslint": "^9",
"eslint-config-prettier": "^10",
"eslint-plugin-prettier": "^5.5.4",
"mocha": "^10.8.2",
"msw": "^2.12.4",
"openapi-typescript": "^7.10.1",
"prettier": "^3.6.2",
"shx": "^0.3.3",
"tsx": "^4.20.6",
"typescript": "^5",
"typescript-eslint": "^8"
},
Expand Down
Loading
Loading