@freshworks/shiftleft-tools 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +351 -0
- package/bin/shiftleft.js +95 -0
- package/package.json +57 -0
- package/src/commands/doctor.js +208 -0
- package/src/commands/init-postman.js +298 -0
- package/src/commands/init-rules.js +78 -0
- package/src/commands/link.js +172 -0
- package/src/commands/protect.js +61 -0
- package/src/commands/run-tests.js +182 -0
- package/src/commands/setup-pipeline.js +209 -0
- package/src/commands/update.js +203 -0
- package/src/index.js +4 -0
- package/src/utils/copy-tree.js +98 -0
- package/src/utils/gitignore.js +26 -0
- package/src/utils/logger.js +9 -0
- package/src/utils/manifest.js +145 -0
- package/src/utils/stack.js +80 -0
- package/src/utils/template.js +135 -0
- package/templates/AGENTS.md +109 -0
- package/templates/CLAUDE.md +3 -0
- package/templates/jenkins/Jenkinsfile-java.groovy +432 -0
- package/templates/jenkins/Jenkinsfile-node.groovy +450 -0
- package/templates/postman/.husky/pre-commit +19 -0
- package/templates/postman/.prettierrc.json +5 -0
- package/templates/postman/README.md.ejs +147 -0
- package/templates/postman/collections/01-core.json.ejs +91 -0
- package/templates/postman/config/local.json.ejs +12 -0
- package/templates/postman/config/staging.json.ejs +26 -0
- package/templates/postman/environments/local.postman_environment.json.ejs +31 -0
- package/templates/postman/environments/staging.postman_environment.json.ejs +31 -0
- package/templates/postman/gitignore +16 -0
- package/templates/postman/npmrc +31 -0
- package/templates/postman/package.json.ejs +66 -0
- package/templates/postman/run-all-shim.sh +16 -0
- package/templates/postman/scripts/auth/generate-jwt.sh +113 -0
- package/templates/postman/scripts/auth/get-issuer-secret.sh +140 -0
- package/templates/postman/scripts/infra/start-mocks.sh +138 -0
- package/templates/postman/scripts/infra/stop-mocks.sh +43 -0
- package/templates/postman/scripts/lib/api_coverage.py +1122 -0
- package/templates/postman/scripts/lib/cleanup-reports.sh +101 -0
- package/templates/postman/scripts/lib/cleanup-stryker.sh +44 -0
- package/templates/postman/scripts/lib/report_combined.py +527 -0
- package/templates/postman/scripts/lib/report_consolidated.py +363 -0
- package/templates/postman/scripts/lib/report_generator.py +121 -0
- package/templates/postman/scripts/lib/report_migration.py +156 -0
- package/templates/postman/scripts/lib/report_mutation.py +110 -0
- package/templates/postman/scripts/lib/report_unit.py +353 -0
- package/templates/postman/scripts/lib/report_utils.py +973 -0
- package/templates/postman/scripts/report-generators/generate-consolidated-report.sh +445 -0
- package/templates/postman/scripts/report-generators/java-api-coverage-matrix.sh +257 -0
- package/templates/postman/scripts/report-generators/mutation-report.sh +672 -0
- package/templates/postman/scripts/report-generators/node-api-coverage-matrix.sh +167 -0
- package/templates/postman/scripts/report-generators/stage-report-artifacts.sh +27 -0
- package/templates/postman/scripts/run-all.sh +452 -0
- package/templates/postman/scripts/runners/run-mutation-tests.sh +113 -0
- package/templates/postman/scripts/runners/run-tests-local.sh +936 -0
- package/templates/postman/scripts/runners/run-tests-staging.sh +741 -0
- package/templates/postman-node/README.md.ejs +26 -0
- package/templates/postman-node/collections/crud/01-bootstrap.json.ejs +34 -0
- package/templates/postman-node/config/local.json.ejs +46 -0
- package/templates/postman-node/config/staging.json.ejs +31 -0
- package/templates/postman-node/local.test.env.ejs +3 -0
- package/templates/postman-node/mocks/external.js +14 -0
- package/templates/postman-node/package.json.ejs +39 -0
- package/templates/postman-node/requirements.txt +1 -0
- package/templates/postman-node/scripts/database/cleanup-mysql.sh +12 -0
- package/templates/postman-node/scripts/database/run-migrations.js +29 -0
- package/templates/postman-node/scripts/database/start-mysql.sh +34 -0
- package/templates/postman-node/scripts/database/wait-for-mysql.sh +36 -0
- package/templates/postman-node/scripts/lib/api_coverage_node.py +1137 -0
- package/templates/postman-node/scripts/lib/fetch-jwt.sh +86 -0
- package/templates/postman-node/scripts/lib/run-newman.sh +104 -0
- package/templates/postman-node/scripts/lib/setup-database.sh +55 -0
- package/templates/postman-node/scripts/lib/start-app.sh +48 -0
- package/templates/postman-node/scripts/lib/utils.sh +114 -0
- package/templates/postman-node/scripts/report-generators/stage-report-artifacts.sh +26 -0
- package/templates/postman-node/scripts/run-all.sh +303 -0
- package/templates/postman-node/scripts/runners/run-tests.sh +123 -0
- package/templates/postman-node/scripts/setup-mocks.js.ejs +29 -0
- package/templates/postman-node/stryker.config.js.ejs +51 -0
- package/templates/rules/local-test-setup.mdc +420 -0
- package/templates/rules/testing-node.mdc +66 -0
- package/templates/rules/testing.mdc +248 -0
- package/templates/skills/_shared/postman-standards.md +380 -0
- package/templates/skills/enhance-test-pipeline/SKILL-java.md +483 -0
- package/templates/skills/enhance-test-pipeline/SKILL-node.md +431 -0
- package/templates/skills/enhance-test-pipeline/SKILL.md +9 -0
- package/templates/skills/review-test-suite/SKILL-java.md +137 -0
- package/templates/skills/review-test-suite/SKILL-node.md +78 -0
- package/templates/skills/review-test-suite/SKILL.md +9 -0
- package/templates/skills/run-test-suite/SKILL-java.md +186 -0
- package/templates/skills/run-test-suite/SKILL-node.md +191 -0
- package/templates/skills/run-test-suite/SKILL.md +9 -0
- package/templates/skills/setup-api-tests/SKILL-java.md +1094 -0
- package/templates/skills/setup-api-tests/SKILL-node.md +141 -0
- package/templates/skills/setup-api-tests/SKILL.md +9 -0
- package/templates/skills/setup-mutation-tests/SKILL-java.md +303 -0
- package/templates/skills/setup-mutation-tests/SKILL-node.md +408 -0
- package/templates/skills/setup-mutation-tests/SKILL.md +9 -0
- package/templates/skills/setup-test-pipeline/SKILL-java.md +454 -0
- package/templates/skills/setup-test-pipeline/SKILL-node.md +318 -0
- package/templates/skills/setup-test-pipeline/SKILL.md +9 -0
- package/templates/skills/write-api-tests/SKILL-java.md +115 -0
- package/templates/skills/write-api-tests/SKILL-node.md +83 -0
- package/templates/skills/write-api-tests/SKILL.md +9 -0
- package/templates/stryker.config.js +50 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# <%= serviceDisplayName %> — Postman API Tests
|
|
2
|
+
|
|
3
|
+
Node.js/Express integration tests using Newman. Config-driven via `config/local.json` and `config/staging.json`.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd postman && npm ci --ignore-scripts
|
|
9
|
+
cd scripts && ./runners/run-tests.sh local
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Full pipeline (unit + mutation + Postman + coverage + report)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cd postman/scripts && ./run-all.sh
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Structure
|
|
19
|
+
|
|
20
|
+
- `collections/crud/` — numbered Newman collections (bootstrap first, cleanup last)
|
|
21
|
+
- `config/` — environment-specific setup (DB, app, auth)
|
|
22
|
+
- `scripts/runners/run-tests.sh` — unified local/staging runner
|
|
23
|
+
- `scripts/setup-mocks.js` — nock stubs (load when `NODE_ENV=integration-tests`)
|
|
24
|
+
- `mocks/` — per-service nock definitions
|
|
25
|
+
|
|
26
|
+
Reference implementation: `freshapps_api_node`
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"info": {
|
|
3
|
+
"name": "01-bootstrap",
|
|
4
|
+
"description": "Bootstrap collection — runs first. Sets shared env vars for later collections.",
|
|
5
|
+
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
|
6
|
+
},
|
|
7
|
+
"item": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Health - GET /health",
|
|
10
|
+
"request": {
|
|
11
|
+
"method": "GET",
|
|
12
|
+
"header": [],
|
|
13
|
+
"url": {
|
|
14
|
+
"raw": "{{base_url}}/health",
|
|
15
|
+
"host": ["{{base_url}}"],
|
|
16
|
+
"path": ["health"]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"event": [
|
|
20
|
+
{
|
|
21
|
+
"listen": "test",
|
|
22
|
+
"script": {
|
|
23
|
+
"exec": [
|
|
24
|
+
"pm.test('Status is 200', function () {",
|
|
25
|
+
" pm.response.to.have.status(200);",
|
|
26
|
+
"});"
|
|
27
|
+
],
|
|
28
|
+
"type": "text/javascript"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comment": "Local environment configuration for <%= serviceName %> Postman tests",
|
|
3
|
+
"environment": "local",
|
|
4
|
+
"api_url": "http://localhost:4013",
|
|
5
|
+
"setup": {
|
|
6
|
+
"database": {
|
|
7
|
+
"enabled": false,
|
|
8
|
+
"type": "docker",
|
|
9
|
+
"container_name": "<%= serviceNameLower %>-test-mysql",
|
|
10
|
+
"port": 3309,
|
|
11
|
+
"host": "127.0.0.1",
|
|
12
|
+
"user": "testuser",
|
|
13
|
+
"password": "testpass",
|
|
14
|
+
"database": "<%= serviceNameLower %>"
|
|
15
|
+
},
|
|
16
|
+
"app": {
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"port": 4013,
|
|
19
|
+
"node_env": "integration-tests",
|
|
20
|
+
"env_file": "postman/local.test.env",
|
|
21
|
+
"start_command": "yarn start"
|
|
22
|
+
},
|
|
23
|
+
"migrations": {
|
|
24
|
+
"enabled": false
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"auth": {
|
|
28
|
+
"type": "local",
|
|
29
|
+
"jwt": {
|
|
30
|
+
"secret": "change-me-local-jwt-secret",
|
|
31
|
+
"issuer": "<%= serviceNameLower %>_automation",
|
|
32
|
+
"account_id": "102",
|
|
33
|
+
"product": "freshdesk",
|
|
34
|
+
"expiry": "3600",
|
|
35
|
+
"users": {
|
|
36
|
+
"developer": {
|
|
37
|
+
"user_id": "1001",
|
|
38
|
+
"user_role": "developer",
|
|
39
|
+
"user_email": "developer@example.com",
|
|
40
|
+
"user_name": "Developer User"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"test_data": {}
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comment": "Staging environment configuration for <%= serviceName %> Postman tests",
|
|
3
|
+
"environment": "staging",
|
|
4
|
+
"api_url": "https://staging.example.com",
|
|
5
|
+
"setup": {
|
|
6
|
+
"database": { "enabled": false },
|
|
7
|
+
"app": { "enabled": false },
|
|
8
|
+
"migrations": { "enabled": false }
|
|
9
|
+
},
|
|
10
|
+
"auth": {
|
|
11
|
+
"type": "aws",
|
|
12
|
+
"aws": {
|
|
13
|
+
"secret_name": "staging_stack_secrets",
|
|
14
|
+
"account_id": "000000000000",
|
|
15
|
+
"region": "us-west-2"
|
|
16
|
+
},
|
|
17
|
+
"jwt": {
|
|
18
|
+
"issuer": "<%= serviceNameLower %>_automation",
|
|
19
|
+
"product": "freshdesk",
|
|
20
|
+
"expiry": "3600",
|
|
21
|
+
"users": {
|
|
22
|
+
"developer": {
|
|
23
|
+
"user_id": "1001",
|
|
24
|
+
"user_role": "developer",
|
|
25
|
+
"user_email": "developer@example.com",
|
|
26
|
+
"user_name": "Developer User"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Example external HTTP stubs. Add one file per external dependency.
|
|
5
|
+
*/
|
|
6
|
+
function setupExternalMocks(nock) {
|
|
7
|
+
// Replace with your service's external domains
|
|
8
|
+
nock('https://api.example.com')
|
|
9
|
+
.persist()
|
|
10
|
+
.get(/.*/)
|
|
11
|
+
.reply(200, { success: true });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = { setupExternalMocks };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "<%= serviceName %>-postman-tests",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Postman API tests for <%= serviceName %>",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"prepare": "cd .. && husky postman/.husky",
|
|
8
|
+
"test:local": "./scripts/runners/run-tests.sh local",<% if (includeStaging) { %>
|
|
9
|
+
"test:staging": "./scripts/runners/run-tests.sh staging",<% } %>
|
|
10
|
+
"report:consolidated": "./scripts/report-generators/generate-consolidated-report.sh",
|
|
11
|
+
"audit": "npm audit --audit-level=high",
|
|
12
|
+
"audit:signatures": "npm audit signatures",
|
|
13
|
+
"security:check": "npm run audit && npm run audit:signatures",
|
|
14
|
+
"format": "prettier --write '**/*.json' '!node_modules/**'",
|
|
15
|
+
"format:check": "prettier --check '**/*.json' '!node_modules/**'"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"jsonwebtoken": "9.0.2",
|
|
19
|
+
"newman": "6.2.2",
|
|
20
|
+
"newman-reporter-htmlextra": "1.23.1",
|
|
21
|
+
"nock": "13.5.6"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"aws-sdk-mock": "6.2.1",
|
|
25
|
+
"husky": "9.1.7",
|
|
26
|
+
"prettier": "3.4.2"
|
|
27
|
+
},
|
|
28
|
+
"overrides": {
|
|
29
|
+
"tunnel-agent": "0.6.0",
|
|
30
|
+
"tough-cookie": "4.1.3",
|
|
31
|
+
"semver": "7.5.4"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18.0.0",
|
|
35
|
+
"npm": ">=8.4.0"
|
|
36
|
+
},
|
|
37
|
+
"keywords": ["postman", "api-testing", "newman", "<%= serviceName %>"],
|
|
38
|
+
"license": "UNLICENSED"
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
defusedxml>=0.7.1
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Cleanup MySQL container
|
|
3
|
+
|
|
4
|
+
CONTAINER_NAME="${MYSQL_CONTAINER_NAME:-integration-test-mysql}"
|
|
5
|
+
|
|
6
|
+
echo "Cleaning up MySQL container..."
|
|
7
|
+
|
|
8
|
+
if podman rm -f "$CONTAINER_NAME" 2>/dev/null; then
|
|
9
|
+
echo "MySQL container '$CONTAINER_NAME' removed"
|
|
10
|
+
else
|
|
11
|
+
echo "No container to remove (already cleaned up)"
|
|
12
|
+
fi
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Database migration stub for local Postman integration tests.
|
|
5
|
+
*
|
|
6
|
+
* Customize this for your ORM (Sequelize, Knex, TypeORM, etc.) or disable
|
|
7
|
+
* migrations in postman/config/local.json: setup.migrations.enabled = false
|
|
8
|
+
*
|
|
9
|
+
* Reference implementation: freshapps_api_node/postman/scripts/database/run-migrations.js
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
// eslint-disable-next-line no-unused-vars
|
|
15
|
+
const PROJECT_ROOT = path.resolve(__dirname, '../../..');
|
|
16
|
+
|
|
17
|
+
async function runMigrations() {
|
|
18
|
+
console.log('[run-migrations] No migrations configured — customize postman/scripts/database/run-migrations.js');
|
|
19
|
+
console.log('[run-migrations] Or set setup.migrations.enabled to false in postman/config/local.json');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (require.main === module) {
|
|
23
|
+
runMigrations().catch((err) => {
|
|
24
|
+
console.error(err);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = { runMigrations };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Start ephemeral MySQL container for integration tests
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
CONTAINER_NAME="${MYSQL_CONTAINER_NAME:-integration-test-mysql}"
|
|
7
|
+
MYSQL_PORT="${MYSQL_PORT:-3309}"
|
|
8
|
+
MYSQL_ROOT_PASSWORD="${MYSQL_ROOT_PASSWORD:-testpass}"
|
|
9
|
+
MYSQL_DATABASE="${MYSQL_DATABASE:-freshapps}"
|
|
10
|
+
MYSQL_USER="${MYSQL_USER:-testuser}"
|
|
11
|
+
MYSQL_PASSWORD="${MYSQL_PASSWORD:-testpass}"
|
|
12
|
+
|
|
13
|
+
echo "Starting MySQL container..."
|
|
14
|
+
echo " Container: $CONTAINER_NAME"
|
|
15
|
+
echo " Port: $MYSQL_PORT"
|
|
16
|
+
echo " Database: $MYSQL_DATABASE"
|
|
17
|
+
|
|
18
|
+
# Remove existing container if it exists
|
|
19
|
+
podman rm -f "$CONTAINER_NAME" 2>/dev/null || true
|
|
20
|
+
|
|
21
|
+
# Start MySQL container
|
|
22
|
+
podman run -d \
|
|
23
|
+
--name "$CONTAINER_NAME" \
|
|
24
|
+
-e MYSQL_ROOT_PASSWORD="$MYSQL_ROOT_PASSWORD" \
|
|
25
|
+
-e MYSQL_DATABASE="$MYSQL_DATABASE" \
|
|
26
|
+
-e MYSQL_USER="$MYSQL_USER" \
|
|
27
|
+
-e MYSQL_PASSWORD="$MYSQL_PASSWORD" \
|
|
28
|
+
-p "$MYSQL_PORT:3306" \
|
|
29
|
+
mysql:8.0 \
|
|
30
|
+
--default-authentication-plugin=mysql_native_password \
|
|
31
|
+
--character-set-server=utf8mb4 \
|
|
32
|
+
--collation-server=utf8mb4_unicode_ci
|
|
33
|
+
|
|
34
|
+
echo "MySQL container started"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Wait for MySQL to be ready and grant permissions
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
CONTAINER_NAME="${MYSQL_CONTAINER_NAME:-integration-test-mysql}"
|
|
7
|
+
MYSQL_ROOT_PASSWORD="${MYSQL_ROOT_PASSWORD:-testpass}"
|
|
8
|
+
MYSQL_USER="${MYSQL_USER:-testuser}"
|
|
9
|
+
MAX_WAIT="${MAX_WAIT:-20}"
|
|
10
|
+
INTERVAL=2
|
|
11
|
+
|
|
12
|
+
echo "Waiting for MySQL to be ready (max ${MAX_WAIT}s)..."
|
|
13
|
+
|
|
14
|
+
elapsed=0
|
|
15
|
+
while [ $elapsed -lt $MAX_WAIT ]; do
|
|
16
|
+
if podman exec "$CONTAINER_NAME" mysqladmin ping -h localhost --silent 2>/dev/null; then
|
|
17
|
+
echo "MySQL is ready! (took ${elapsed}s)"
|
|
18
|
+
|
|
19
|
+
# Grant full privileges to testuser for creating and managing databases
|
|
20
|
+
echo "Granting privileges to ${MYSQL_USER}..."
|
|
21
|
+
podman exec "$CONTAINER_NAME" mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" -e "
|
|
22
|
+
GRANT ALL PRIVILEGES ON *.* TO '${MYSQL_USER}'@'%' WITH GRANT OPTION;
|
|
23
|
+
FLUSH PRIVILEGES;
|
|
24
|
+
" 2>/dev/null || echo "Warning: Could not grant privileges (may already be set)"
|
|
25
|
+
|
|
26
|
+
echo "Database user configured successfully"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
sleep $INTERVAL
|
|
31
|
+
elapsed=$((elapsed + INTERVAL))
|
|
32
|
+
echo " Waiting... (${elapsed}s)"
|
|
33
|
+
done
|
|
34
|
+
|
|
35
|
+
echo "ERROR: MySQL did not become ready within ${MAX_WAIT}s"
|
|
36
|
+
exit 1
|