Merge pull request #40 from pheuberger/claude/increase-code-coverage-… #28
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Security Tests | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "src/services/crypto.js" | |
| - "src/services/pairing-code.js" | |
| - "src/services/key-storage.js" | |
| - "src/components/pairing/PairingFlow.jsx" | |
| - "src/services/crypto.test.js" | |
| - "src/services/pairing-code.test.js" | |
| - "src/services/key-storage.test.js" | |
| - "src/components/pairing/PairingFlow.test.jsx" | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "src/services/crypto.js" | |
| - "src/services/pairing-code.js" | |
| - "src/services/key-storage.js" | |
| - "src/components/pairing/PairingFlow.jsx" | |
| - "src/services/crypto.test.js" | |
| - "src/services/pairing-code.test.js" | |
| - "src/services/key-storage.test.js" | |
| - "src/components/pairing/PairingFlow.test.jsx" | |
| workflow_dispatch: | |
| jobs: | |
| security-tests: | |
| name: Security-Critical Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20.x | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run security tests | |
| run: | | |
| echo "Running security-critical tests..." | |
| npm run test -- --run \ | |
| src/services/crypto.test.js \ | |
| src/services/pairing-code.test.js \ | |
| src/services/key-storage.test.js \ | |
| src/components/pairing/PairingFlow.test.jsx | |
| - name: Run security tests with coverage | |
| run: | | |
| echo "Generating coverage for security-critical files..." | |
| npm run test -- --run --coverage \ | |
| src/services/crypto.test.js \ | |
| src/services/pairing-code.test.js \ | |
| src/services/key-storage.test.js \ | |
| src/components/pairing/PairingFlow.test.jsx | |
| - name: Check security coverage requirements | |
| run: | | |
| echo "Checking security file coverage requirements (95% minimum)..." | |
| node -e " | |
| try { | |
| const fs = require('fs'); | |
| const coverage = JSON.parse(fs.readFileSync('coverage/coverage-summary.json', 'utf8')); | |
| const securityFiles = [ | |
| 'src/services/crypto.js', | |
| 'src/services/pairing-code.js', | |
| 'src/services/key-storage.js', | |
| 'src/components/pairing/PairingFlow.jsx' | |
| ]; | |
| let allPassed = true; | |
| const minSecurityCoverage = 95; | |
| console.log('Security File Coverage Report:'); | |
| console.log('====================================='); | |
| securityFiles.forEach(file => { | |
| const fileKey = file.replace(/\\\\/g, '/'); | |
| const fileCoverage = coverage[fileKey]; | |
| if (fileCoverage) { | |
| const lineCoverage = fileCoverage.lines.pct; | |
| const funcCoverage = fileCoverage.functions.pct; | |
| const branchCoverage = fileCoverage.branches.pct; | |
| const stmtCoverage = fileCoverage.statements.pct; | |
| console.log(file + ':'); | |
| console.log(' Lines: ' + lineCoverage + '%'); | |
| console.log(' Functions: ' + funcCoverage + '%'); | |
| console.log(' Branches: ' + branchCoverage + '%'); | |
| console.log(' Statements: ' + stmtCoverage + '%'); | |
| if (lineCoverage < minSecurityCoverage || funcCoverage < minSecurityCoverage || | |
| branchCoverage < minSecurityCoverage || stmtCoverage < minSecurityCoverage) { | |
| console.log(' ❌ BELOW SECURITY THRESHOLD (' + minSecurityCoverage + '%)'); | |
| allPassed = false; | |
| } else { | |
| console.log(' ✅ Meets security requirements'); | |
| } | |
| console.log(''); | |
| } else { | |
| console.log(file + ': No coverage data found'); | |
| } | |
| }); | |
| if (!allPassed) { | |
| console.log('❌ Security coverage requirements not met!'); | |
| console.log('Security-critical files must have >= ' + minSecurityCoverage + '% coverage'); | |
| process.exit(1); | |
| } else { | |
| console.log('✅ All security files meet coverage requirements'); | |
| } | |
| } catch (err) { | |
| console.log('Security coverage check failed:', err.message); | |
| process.exit(1); | |
| } | |
| " | |
| - name: Upload security coverage report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-coverage-report | |
| path: coverage/ | |
| retention-days: 30 | |
| - name: Security test summary | |
| run: | | |
| echo "## Security Tests Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Security-critical files tested:" >> $GITHUB_STEP_SUMMARY | |
| echo "- \`src/services/crypto.js\` - Cryptographic operations" >> $GITHUB_STEP_SUMMARY | |
| echo "- \`src/services/pairing-code.js\` - Pairing code generation/parsing" >> $GITHUB_STEP_SUMMARY | |
| echo "- \`src/services/key-storage.js\` - Key persistence" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "All security tests passed." >> $GITHUB_STEP_SUMMARY |