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
34 changes: 34 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"project": "./tsconfig.json"
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"plugins": ["@typescript-eslint"],
"env": {
"node": true,
"es2020": true
},
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": ["warn", {
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}]
},
"ignorePatterns": [
"dist/",
"node_modules/",
"coverage/",
"**/*.js",
"**/*.cjs",
"**/*.d.ts"
]
}

119 changes: 119 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Tests

on:
push:
branches: [ main, develop, 'feat/**' ]
pull_request:
branches: [ main, develop ]

jobs:
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run unit tests
run: npm run test:unit

- name: Upload coverage
uses: codecov/codecov-action@v3
if: always()
with:
files: ./coverage/lcov.info
flags: unit

integration-tests:
name: Integration Tests
runs-on: ubuntu-latest

services:
mock-api:
image: ghcr.io/quantcdn/quant-mock-api:4.0.0
ports:
- 4010:4010
options: >-
--health-cmd "nc -z 127.0.0.1 4010"
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run integration tests
env:
MOCK_API_URL: http://localhost:4010
run: npm run test:integration

- name: Upload coverage
uses: codecov/codecov-action@v3
if: always()
with:
files: ./coverage/lcov.info
flags: integration

lint:
name: Lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run linter
run: npm run lint

build:
name: Build
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Check dist files
run: |
if [ ! -f "dist/index.js" ]; then
echo "Build failed: dist/index.js not found"
exit 1
fi

49 changes: 49 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.PHONY: help test test-unit test-integration test-all mock-api-start mock-api-stop mock-api-logs clean

help: ## Show this help message
@echo 'Usage: make [target]'
@echo ''
@echo 'Available targets:'
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-20s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

test: test-unit ## Run unit tests (default)

test-unit: ## Run unit tests only (no Docker required)
npm run test:unit

test-integration: ## Run integration tests with mock API
npm run test:integration

test-all: ## Run all tests (unit + integration)
npm run test:all

mock-api-start: ## Start mock API container
@echo "Starting mock API container..."
@docker compose -f docker-compose.test.yml up -d
@printf "Waiting for mock API to be healthy..."
@i=0; while [ $$i -lt 30 ]; do \
status=$$(docker inspect --format="{{.State.Health.Status}}" quant-mock-api-test 2>/dev/null || echo "starting"); \
if [ "$$status" = "healthy" ]; then \
printf "\n✅ Mock API is running at http://localhost:4010\n\n"; \
printf "Test it:\n curl http://localhost:4010/api/v3/organisations/test-org/applications\n"; \
exit 0; \
fi; \
printf "."; \
sleep 1; \
i=$$((i + 1)); \
done; \
printf "\n❌ Mock API failed to start\n"; \
docker logs quant-mock-api-test 2>&1 | tail -20; \
exit 1

mock-api-stop: ## Stop mock API container
docker compose -f docker-compose.test.yml down -v

mock-api-logs: ## Show mock API logs
docker compose -f docker-compose.test.yml logs -f

clean: ## Clean build artifacts and stop containers
npm run clean
docker compose -f docker-compose.test.yml down -v 2>/dev/null || true
rm -rf coverage node_modules/.cache

59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,68 @@ npm run dev
npm link
```

### Testing

The CLI includes comprehensive unit and integration tests. Integration tests use a mock API backend via Docker.

#### Running Tests

```bash
# Unit tests only (fast, no Docker required)
npm test
# or
make test

# Integration tests (requires Docker)
npm run test:integration
# or
make test-integration

# All tests
npm run test:all
# or
make test-all

# With coverage
npm run test:coverage
```

#### Manual Testing with Mock API

Test CLI commands against the mock API backend:

```bash
# Start mock API
make mock-api-start

# Configure CLI to use mock API (in another terminal)
export QUANT_HOST=http://localhost:4010
export QUANT_TOKEN=mock-token-123

# Test commands
qc app list --org=test-org
qc env list --org=test-org --app=test-app

# Stop mock API
make mock-api-stop
```

#### Mock API

The mock API is built with [Prism](https://stoplight.io/open-source/prism) and automatically generates valid responses from the OpenAPI specification.

- **Container**: `ghcr.io/quantcdn/quant-mock-api:4.0.0`
- **Endpoint**: `http://localhost:4010`
- **Auto-managed**: Integration tests start/stop Docker automatically
- **Public**: No authentication required to pull the container

See `__tests__/README.md` for detailed testing documentation.

## Environment Variables

- `LOG_LEVEL` - Set logging level (DEBUG, INFO, WARN, ERROR)
- `QUANT_HOST` - Override API host (useful for testing with mock API)
- `QUANT_TOKEN` - Override authentication token (for testing)

## License

Expand Down
Loading
Loading