feat(organizations): Complete Organization Management UI #22
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: SSO Platform Tests | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| - feat/** | |
| paths: | |
| - 'sso-platform/**' | |
| - '.github/workflows/test-auth.yml' | |
| pull_request: | |
| branches: | |
| - main | |
| paths: | |
| - 'sso-platform/**' | |
| - '.github/workflows/test-auth.yml' | |
| defaults: | |
| run: | |
| working-directory: sso-platform | |
| jobs: | |
| test: | |
| name: Run SSO Platform Tests | |
| runs-on: ubuntu-latest | |
| # PostgreSQL service for database tests | |
| services: | |
| postgres: | |
| image: postgres:16 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: auth_test | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 9 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "pnpm" | |
| cache-dependency-path: "sso-platform/pnpm-lock.yaml" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Setup environment variables | |
| run: | | |
| cat > .env.local << EOF | |
| # Database | |
| DATABASE_URL=postgresql://postgres:postgres@localhost:5432/auth_test | |
| # Better Auth | |
| BETTER_AUTH_SECRET=${{ secrets.BETTER_AUTH_SECRET || 'test-secret-key-for-ci-do-not-use-in-production-min-32-chars' }} | |
| BETTER_AUTH_URL=http://localhost:3001 | |
| # CORS Configuration | |
| ALLOWED_ORIGINS=http://localhost:3000,http://localhost:3001 | |
| # Client-side configuration | |
| NEXT_PUBLIC_BETTER_AUTH_URL=http://localhost:3001 | |
| NEXT_PUBLIC_APP_NAME=Auth Server CI | |
| NEXT_PUBLIC_ORG_NAME=RoboLearn | |
| # Email (test mode - no actual emails sent) | |
| EMAIL_FROM=test@example.com | |
| EMAIL_PROVIDER=console | |
| # Node environment | |
| NODE_ENV=test | |
| # Disable email verification for automated testing | |
| DISABLE_EMAIL_VERIFICATION=true | |
| EOF | |
| - name: Run database migrations | |
| run: pnpm db:push | |
| - name: Seed test data | |
| run: pnpm seed:setup | |
| - name: Start auth server in background | |
| run: | | |
| pnpm dev > server.log 2>&1 & | |
| echo $! > .server.pid | |
| # Wait for server to be ready (max 120 seconds for first compilation) | |
| echo "Waiting for Next.js to compile and server to be ready..." | |
| for i in {1..120}; do | |
| # Check health endpoint (verifies server AND database connection) | |
| if curl -sf http://localhost:3001/api/health > /dev/null 2>&1; then | |
| echo "✅ Server is healthy and ready!" | |
| curl -s http://localhost:3001/api/health | |
| break | |
| fi | |
| if [ $i -eq 120 ]; then | |
| echo "❌ Server failed to start within 120 seconds" | |
| echo "Last 50 lines of server logs:" | |
| tail -50 .next/trace || echo "No trace file found" | |
| exit 1 | |
| fi | |
| # Show progress every 10 seconds | |
| if [ $((i % 10)) -eq 0 ]; then | |
| echo "Still waiting... ($i/120 seconds)" | |
| fi | |
| sleep 1 | |
| done | |
| - name: Create admin user via Better Auth API | |
| run: | | |
| set -euo pipefail | |
| echo "Creating admin user through Better Auth signup..." | |
| RESPONSE_FILE=$(mktemp) | |
| STATUS=$(curl -s -o "$RESPONSE_FILE" -w "%{http_code}" -X POST http://localhost:3001/api/auth/sign-up/email \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"email":"admin@robolearn.io","password":"admin@robolearn.io","name":"Admin User"}') | |
| if [ "$STATUS" = "200" ] || [ "$STATUS" = "201" ]; then | |
| echo "✅ Admin user created via API" | |
| elif [ "$STATUS" = "409" ] || [ "$STATUS" = "422" ]; then | |
| echo "ℹ️ Admin user already exists (status $STATUS)" | |
| else | |
| echo "❌ Admin signup failed with status $STATUS" | |
| echo "=== Response body ===" | |
| cat "$RESPONSE_FILE" | |
| echo "" | |
| echo "=== Server logs (last 100 lines) ===" | |
| tail -100 server.log || echo "No server.log found" | |
| exit 1 | |
| fi | |
| rm -f "$RESPONSE_FILE" | |
| - name: Set admin role and verify email | |
| run: | | |
| echo "Setting admin role and email verification..." | |
| psql postgresql://postgres:postgres@localhost:5432/auth_test -c \ | |
| "UPDATE \"user\" SET role = 'admin', email_verified = true WHERE email = 'admin@robolearn.io';" | |
| echo "Admin user updated!" | |
| - name: Verify admin test user exists | |
| run: | | |
| echo "Verifying admin@robolearn.io exists with correct role and verification..." | |
| RESULT=$(psql -t -A postgresql://postgres:postgres@localhost:5432/auth_test -c \ | |
| "SELECT COUNT(*) FROM \"user\" WHERE email = 'admin@robolearn.io' AND email_verified = true AND role = 'admin';" | tr -d '[:space:]') | |
| if [ "$RESULT" != "1" ]; then | |
| echo "❌ Admin user verification failed (expected 1, got $RESULT)" | |
| echo "Dumping user row for debugging:" | |
| psql postgresql://postgres:postgres@localhost:5432/auth_test -c \ | |
| "SELECT email, role, email_verified, created_at FROM \"user\" WHERE email = 'admin@robolearn.io';" | |
| exit 1 | |
| fi | |
| echo "✅ Admin user verified" | |
| - name: Validate admin credentials | |
| run: | | |
| set -euo pipefail | |
| echo "Validating admin password via sign-in endpoint..." | |
| RESPONSE_FILE=$(mktemp) | |
| STATUS=$(curl -s -o "$RESPONSE_FILE" -w "%{http_code}" -X POST http://localhost:3001/api/auth/sign-in/email \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"email":"admin@robolearn.io","password":"admin@robolearn.io"}') | |
| if [ "$STATUS" != "200" ]; then | |
| echo "❌ Admin sign-in failed (status $STATUS)" | |
| cat "$RESPONSE_FILE" | |
| exit 1 | |
| fi | |
| echo "✅ Admin password confirmed" | |
| rm -f "$RESPONSE_FILE" | |
| - name: Run API tests | |
| run: pnpm test-api | |
| timeout-minutes: 5 | |
| - name: Run E2E tests | |
| run: pnpm test-e2e | |
| timeout-minutes: 5 | |
| - name: Stop auth server | |
| if: always() | |
| run: | | |
| if [ -f .server.pid ]; then | |
| kill $(cat .server.pid) || true | |
| rm .server.pid | |
| fi | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results | |
| path: | | |
| sso-platform/test-results.json | |
| sso-platform/tests/**/*.log | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| security-audit: | |
| name: Security Audit | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: sso-platform | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 9 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "pnpm" | |
| cache-dependency-path: "sso-platform/pnpm-lock.yaml" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run security audit | |
| run: pnpm audit --audit-level=moderate | |
| continue-on-error: true | |
| - name: Check for outdated dependencies | |
| run: pnpm outdated | |
| continue-on-error: true |