diff --git a/.github/scripts/generate-test-summary-jest.sh b/.github/scripts/generate-test-summary-jest.sh new file mode 100644 index 0000000..6bbdf35 --- /dev/null +++ b/.github/scripts/generate-test-summary-jest.sh @@ -0,0 +1,83 @@ +#!/bin/bash +set -e + +# Generate Test Summary from Jest JSON Output +# Usage: ./generate-test-summary-jest.sh + +JSON_FILE="${1:-test-results.json}" + +echo "## Test Results" >> $GITHUB_STEP_SUMMARY +echo "" >> $GITHUB_STEP_SUMMARY + +# Parse test results from Jest JSON output +if [ -f "$JSON_FILE" ]; then + # Extract test counts using jq or grep/sed + # Jest JSON structure: { "numTotalTests": N, "numPassedTests": N, "numFailedTests": N, "numPendingTests": N, ... } + + if command -v jq &> /dev/null; then + # Use jq if available (preferred) + total_tests=$(jq -r '.numTotalTests // 0' "$JSON_FILE") + passed=$(jq -r '.numPassedTests // 0' "$JSON_FILE") + failed=$(jq -r '.numFailedTests // 0' "$JSON_FILE") + skipped=$(jq -r '.numPendingTests // 0' "$JSON_FILE") + + # Extract failed test details + failed_tests_file=$(mktemp) + jq -r '.testResults[]? | select(.status == "failed") | .assertionResults[]? | select(.status == "failed") | "\(.ancestorTitles | join(" > ")) > \(.title)"' "$JSON_FILE" > "$failed_tests_file" 2>/dev/null || true + else + # Fallback to grep/sed if jq is not available + total_tests=$(grep -oP '"numTotalTests":\s*\K[0-9]+' "$JSON_FILE" | head -1) + passed=$(grep -oP '"numPassedTests":\s*\K[0-9]+' "$JSON_FILE" | head -1) + failed=$(grep -oP '"numFailedTests":\s*\K[0-9]+' "$JSON_FILE" | head -1) + skipped=$(grep -oP '"numPendingTests":\s*\K[0-9]+' "$JSON_FILE" | head -1) + + # Extract failed test names (basic extraction without jq) + failed_tests_file=$(mktemp) + grep -oP '"fullName":\s*"\K[^"]*' "$JSON_FILE" | while read -r line; do + if echo "$line" | grep -q "failed"; then + echo "$line" >> "$failed_tests_file" + fi + done 2>/dev/null || true + fi + + # Default to 0 if values are empty + total_tests=${total_tests:-0} + passed=${passed:-0} + failed=${failed:-0} + skipped=${skipped:-0} + + echo "| Status | Count |" >> $GITHUB_STEP_SUMMARY + echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY + echo "| ✅ Passed | $passed |" >> $GITHUB_STEP_SUMMARY + echo "| ❌ Failed | $failed |" >> $GITHUB_STEP_SUMMARY + echo "| ⏭️ Skipped | $skipped |" >> $GITHUB_STEP_SUMMARY + echo "| **Total** | **$total_tests** |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + # List failed tests if any + if [ "$failed" -gt 0 ]; then + echo "### ❌ Failed Tests" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [ -s "$failed_tests_file" ]; then + while IFS= read -r test; do + echo "- \`$test\`" >> $GITHUB_STEP_SUMMARY + done < "$failed_tests_file" + else + echo "_Unable to parse individual test names_" >> $GITHUB_STEP_SUMMARY + fi + + echo "" >> $GITHUB_STEP_SUMMARY + echo "❌ **Tests failed!**" >> $GITHUB_STEP_SUMMARY + rm -f "$failed_tests_file" + exit 1 + else + echo "✅ **All tests passed!**" >> $GITHUB_STEP_SUMMARY + fi + + rm -f "$failed_tests_file" +else + echo "⚠️ No test results found at: $JSON_FILE" >> $GITHUB_STEP_SUMMARY + exit 1 +fi + diff --git a/.github/scripts/generate-test-summary-surefire.sh b/.github/scripts/generate-test-summary-surefire.sh new file mode 100644 index 0000000..fee0e56 --- /dev/null +++ b/.github/scripts/generate-test-summary-surefire.sh @@ -0,0 +1,82 @@ +#!/bin/bash +set -e + +# Generate Test Summary from Maven Surefire Reports +# Usage: ./generate-test-summary-surefire.sh + +REPORTS_DIR="${1:-target/surefire-reports}" + +echo "## Test Results" >> $GITHUB_STEP_SUMMARY +echo "" >> $GITHUB_STEP_SUMMARY + +# Parse test results from Surefire reports +if [ -d "$REPORTS_DIR" ]; then + total_tests=0 + failures=0 + errors=0 + skipped=0 + failed_tests_file=$(mktemp) + + for file in "$REPORTS_DIR"/TEST-*.xml; do + if [ -f "$file" ]; then + # Extract test counts from XML + tests=$(grep -oP 'tests="\K[0-9]+' "$file" | head -1) + fails=$(grep -oP 'failures="\K[0-9]+' "$file" | head -1) + errs=$(grep -oP 'errors="\K[0-9]+' "$file" | head -1) + skip=$(grep -oP 'skipped="\K[0-9]+' "$file" | head -1) + + total_tests=$((total_tests + ${tests:-0})) + failures=$((failures + ${fails:-0})) + errors=$((errors + ${errs:-0})) + skipped=$((skipped + ${skip:-0})) + + # Extract failed test cases + if [ "${fails:-0}" -gt 0 ] || [ "${errs:-0}" -gt 0 ]; then + classname=$(basename "$file" .xml | sed 's/^TEST-//') + + # Find failed testcases (with failure or error elements) + grep -oP ']*name="[^"]*"[^>]*>.*?<(failure|error)' "$file" | \ + grep -oP 'name="\K[^"]*' | while read -r testname; do + echo "$classname.$testname" >> "$failed_tests_file" + done + fi + fi + done + + passed=$((total_tests - failures - errors - skipped)) + + echo "| Status | Count |" >> $GITHUB_STEP_SUMMARY + echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY + echo "| ✅ Passed | $passed |" >> $GITHUB_STEP_SUMMARY + echo "| ❌ Failed | $((failures + errors)) |" >> $GITHUB_STEP_SUMMARY + echo "| ⏭️ Skipped | $skipped |" >> $GITHUB_STEP_SUMMARY + echo "| **Total** | **$total_tests** |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + # List failed tests if any + if [ $((failures + errors)) -gt 0 ]; then + echo "### ❌ Failed Tests" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [ -s "$failed_tests_file" ]; then + while IFS= read -r test; do + echo "- \`$test\`" >> $GITHUB_STEP_SUMMARY + done < "$failed_tests_file" + else + echo "_Unable to parse individual test names_" >> $GITHUB_STEP_SUMMARY + fi + + echo "" >> $GITHUB_STEP_SUMMARY + echo "❌ **Tests failed!**" >> $GITHUB_STEP_SUMMARY + rm -f "$failed_tests_file" + exit 1 + else + echo "✅ **All tests passed!**" >> $GITHUB_STEP_SUMMARY + fi + + rm -f "$failed_tests_file" +else + echo "⚠️ No test results found at: $REPORTS_DIR" >> $GITHUB_STEP_SUMMARY + exit 1 +fi + diff --git a/.github/workflows/run-express-tests.yml b/.github/workflows/run-express-tests.yml new file mode 100644 index 0000000..e13673e --- /dev/null +++ b/.github/workflows/run-express-tests.yml @@ -0,0 +1,56 @@ +name: Run Express Tests + +on: + pull_request_target: + branches: + - development + push: + branches: + - development + +jobs: + test: + name: Run Express Tests + runs-on: ubuntu-latest + # Require manual approval for fork PRs + environment: testing + + defaults: + run: + working-directory: server/express + + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm test -- --json --outputFile=test-results.json || true + env: + MONGODB_URI: ${{ secrets.MFLIX_URI }} + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: | + server/express/coverage/ + server/express/test-results.json + retention-days: 30 + + - name: Generate Test Summary + if: always() + working-directory: . + run: | + chmod +x .github/scripts/generate-test-summary-jest.sh + .github/scripts/generate-test-summary-jest.sh server/express/test-results.json diff --git a/.github/workflows/run-java-spring-boot-tests.yml b/.github/workflows/run-java-spring-boot-tests.yml new file mode 100644 index 0000000..8108f69 --- /dev/null +++ b/.github/workflows/run-java-spring-boot-tests.yml @@ -0,0 +1,69 @@ +name: Run Java Spring Boot Tests + +on: + pull_request_target: + branches: + - development + push: + branches: + - development + +jobs: + test: + name: Run Java Spring Boot Tests + runs-on: ubuntu-latest + # Require manual approval for fork PRs + environment: testing + + defaults: + run: + working-directory: server/java-spring + + env: + MONGODB_URI: ${{ secrets.MFLIX_URI }} + ENABLE_SEARCH_TESTS: true + + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Make mvnw executable + run: chmod +x mvnw + + - name: Debug environment variables + run: | + echo "Checking environment variables..." + echo "MONGODB_URI is set: $(if [ -n "$MONGODB_URI" ]; then echo 'YES'; else echo 'NO'; fi)" + echo "ENABLE_SEARCH_TESTS is set: $(if [ -n "$ENABLE_SEARCH_TESTS" ]; then echo 'YES'; else echo 'NO'; fi)" + echo "MONGODB_URI length: ${#MONGODB_URI}" + + - name: Run unit tests + run: ./mvnw test + + - name: Run integration tests + run: ./mvnw test -Dtest=MongoDBSearchIntegrationTest + continue-on-error: true + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: server/java-spring/target/surefire-reports/ + retention-days: 30 + + - name: Generate Test Summary + if: always() + working-directory: . + run: | + chmod +x .github/scripts/generate-test-summary-surefire.sh + .github/scripts/generate-test-summary-surefire.sh server/java-spring/target/surefire-reports diff --git a/server/express/.gitignore b/server/express/.gitignore index f9e1d4c..cdf5c6d 100644 --- a/server/express/.gitignore +++ b/server/express/.gitignore @@ -19,6 +19,9 @@ logs # Test coverage coverage/ +# Test results +test-results.json + # Optional npm cache directory .npm diff --git a/server/java-spring/pom.xml b/server/java-spring/pom.xml index d1a45d3..baff5c0 100644 --- a/server/java-spring/pom.xml +++ b/server/java-spring/pom.xml @@ -1,23 +1,23 @@ 4.0.0 - + org.springframework.boot spring-boot-starter-parent 3.5.7 - + com.mongodb sample-app-java-mflix 1.0.0 sample-app-java-mflix Java Spring Boot backend for MongoDB sample_mflix application demonstrating CRUD operations using Spring Data MongoDB - + 21 2.8.13 @@ -80,7 +80,7 @@ - + org.springframework.boot @@ -101,7 +101,7 @@ ${langchain4j.version} - +