diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000000..1c5ff5a72c --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,526 @@ +name: Run Tests + +on: + push: + branches: [ "main", "scenario/*", "eval/*", "feature/*" ] + pull_request: + branches: [ "main", "scenario/*", "eval/*", "feature/*" ] + issue_comment: + types: [created] + +jobs: + # ──────────── 1. collect and process tests ──────────── + collect-process-tests: + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + fail_to_pass: ${{ steps.combine.outputs.fail_to_pass }} + pass_to_pass: ${{ steps.combine.outputs.pass_to_pass }} + tests: ${{ steps.combine.outputs.tests }} + comment_id: ${{ steps.combine.outputs.comment_id }} + if: ${{ github.event_name != 'issue_comment' || contains(github.event.comment.body, 'FAIL_TO_PASS') || contains(github.event.comment.body, 'PASS_TO_PASS') }} + steps: + - uses: actions/checkout@v4 + + # ─── 1.1 collect issue numbers based on event type ─── + - name: Collect issue numbers based on event type + id: collect_issues + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + run: | + # Initialize issue numbers variable + ISSUE_NUMBERS="" + + # Handle different event types + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + echo "Collecting issue numbers from commits in PR #$PR_NUMBER" + + # Get all commits in the PR + COMMITS=$(gh api repos/$REPO/pulls/$PR_NUMBER/commits --jq '.[].sha') + + # Initialize an empty array for issue numbers + ISSUE_NUMBERS_ARRAY=() + + # For each commit, extract linked issue numbers + for COMMIT in $COMMITS; do + echo "Processing commit $COMMIT" + + # Get commit message + COMMIT_MSG=$(gh api repos/$REPO/commits/$COMMIT --jq '.commit.message') + + # Extract issue numbers using regex (e.g., #123, fixes #456, etc.) + ISSUES=$(echo "$COMMIT_MSG" | grep -o '#[0-9]\+' | sed 's/#//') + + if [ -n "$ISSUES" ]; then + echo "Found issues in commit $COMMIT: $ISSUES" + # Add to our array + for ISSUE in $ISSUES; do + ISSUE_NUMBERS_ARRAY+=("$ISSUE") + done + fi + done + + # Remove duplicates and create JSON array + UNIQUE_ISSUES=$(echo "${ISSUE_NUMBERS_ARRAY[@]}" | tr ' ' '\n' | sort -u) + + if [ -z "$UNIQUE_ISSUES" ]; then + echo "No issue numbers found in commit messages, using PR number as fallback" + ISSUE_NUMBERS="[\"${{ github.event.pull_request.number }}\"]" + else + # Convert to JSON array + ISSUE_NUMBERS=$(echo "$UNIQUE_ISSUES" | jq -R . | jq -s .) + fi + elif [[ "${{ github.event_name }}" == "push" ]]; then + echo "Extracting issue numbers from commit message" + + # Get commit message + COMMIT_MSG="${{ github.event.head_commit.message }}" + + # Extract issue numbers using regex (e.g., #123, fixes #456, etc.) + ISSUES=$(echo "$COMMIT_MSG" | grep -o '#[0-9]\+' | sed 's/#//') + + if [ -n "$ISSUES" ]; then + echo "Found issues in commit message: $ISSUES" + + # Initialize an empty array for issue numbers + ISSUE_NUMBERS_ARRAY=() + + # Add to our array + for ISSUE in $ISSUES; do + ISSUE_NUMBERS_ARRAY+=("$ISSUE") + done + + # Remove duplicates and create JSON array + UNIQUE_ISSUES=$(echo "${ISSUE_NUMBERS_ARRAY[@]}" | tr ' ' '\n' | sort -u) + + # Convert to JSON array + ISSUE_NUMBERS=$(echo "$UNIQUE_ISSUES" | jq -R . | jq -s .) + else + echo "No issue numbers found in commit message, using empty array as fallback" + ISSUE_NUMBERS="[\"\"]" + fi + elif [[ "${{ github.event_name }}" == "issue_comment" ]]; then + echo "Using issue number from comment event" + ISSUE_NUMBERS="[\"${{ github.event.issue.number }}\"]" + else + echo "Using fallback issue number from inputs" + ISSUE_NUMBERS="[\"\"]" + fi + + echo "Found issue numbers: $ISSUE_NUMBERS" + # Escape the JSON string for GitHub Actions output + ESCAPED_ISSUE_NUMBERS=$(echo "$ISSUE_NUMBERS" | jq -c .) + echo "issue_numbers=$ESCAPED_ISSUE_NUMBERS" >> $GITHUB_OUTPUT + + # ─── 1.2 extract test names from issues ─── + - name: Extract test names for issues + id: extract_tests + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ISSUE_NUMBERS: ${{ steps.collect_issues.outputs.issue_numbers }} + REPO: ${{ github.repository }} + run: | + # Initialize arrays for test results + FAIL_TO_PASS=() + PASS_TO_PASS=() + TESTS=() + COMMENT_ID="" + + # Process each issue number + for ISSUE_NUMBER in $(echo $ISSUE_NUMBERS | jq -r '.[]'); do + if [[ -z "$ISSUE_NUMBER" || "$ISSUE_NUMBER" == "null" ]]; then + continue + fi + + echo "Processing issue #$ISSUE_NUMBER" + + # Function to extract FAIL_TO_PASS and PASS_TO_PASS from text + extract_test_fields() { + local text="$1" + local fail_to_pass="" + local pass_to_pass="" + + if [[ -n "$text" ]]; then + # Find FAIL_TO_PASS pattern + if [[ "$text" =~ FAIL_TO_PASS:[[:space:]]*([^$'\n']+) ]]; then + fail_to_pass="${BASH_REMATCH[1]}" + fi + + # Find PASS_TO_PASS pattern + if [[ "$text" =~ PASS_TO_PASS:[[:space:]]*([^$'\n']+) ]]; then + pass_to_pass="${BASH_REMATCH[1]}" + fi + fi + + echo "$fail_to_pass|$pass_to_pass" + } + + # First check issue comments + echo "Checking issue comments for test fields..." + COMMENTS=$(gh api repos/$REPO/issues/$ISSUE_NUMBER/comments --jq '.[] | {id: .id, body: .body, created_at: .created_at}') + + if [[ -n "$COMMENTS" ]]; then + # Process all comments to find the latest one with FAIL_TO_PASS or PASS_TO_PASS + LATEST_COMMENT_WITH_VALUES="" + LATEST_COMMENT_ID="" + LATEST_FAIL_TO_PASS="" + LATEST_PASS_TO_PASS="" + + while IFS= read -r COMMENT; do + COMMENT_BODY=$(echo "$COMMENT" | jq -r '.body') + CURRENT_COMMENT_ID=$(echo "$COMMENT" | jq -r '.id') + + RESULT=$(extract_test_fields "$COMMENT_BODY") + IFS='|' read -r COMMENT_FAIL COMMENT_PASS <<< "$RESULT" + + if [[ -n "$COMMENT_FAIL" || -n "$COMMENT_PASS" ]]; then + LATEST_COMMENT_WITH_VALUES="$COMMENT" + LATEST_COMMENT_ID="$CURRENT_COMMENT_ID" + + if [[ -n "$COMMENT_FAIL" ]]; then + LATEST_FAIL_TO_PASS="$COMMENT_FAIL" + echo "Found FAIL_TO_PASS in issue comment $CURRENT_COMMENT_ID: $COMMENT_FAIL" + fi + + if [[ -n "$COMMENT_PASS" ]]; then + LATEST_PASS_TO_PASS="$COMMENT_PASS" + echo "Found PASS_TO_PASS in issue comment $CURRENT_COMMENT_ID: $COMMENT_PASS" + fi + fi + done <<< "$COMMENTS" + + # Use values from the latest comment + if [[ -n "$LATEST_COMMENT_WITH_VALUES" ]]; then + COMMENT_ID="$LATEST_COMMENT_ID" + + if [[ -n "$LATEST_FAIL_TO_PASS" ]]; then + FAIL_TO_PASS=("$LATEST_FAIL_TO_PASS") + echo "Using FAIL_TO_PASS from latest comment $COMMENT_ID: $LATEST_FAIL_TO_PASS" + fi + + if [[ -n "$LATEST_PASS_TO_PASS" ]]; then + PASS_TO_PASS=("$LATEST_PASS_TO_PASS") + echo "Using PASS_TO_PASS from latest comment $COMMENT_ID: $LATEST_PASS_TO_PASS" + fi + fi + fi + + # If not found in comments, check commit messages + if [[ ${#FAIL_TO_PASS[@]} -eq 0 && ${#PASS_TO_PASS[@]} -eq 0 ]]; then + echo "Checking commit messages for test fields..." + + # Get linked commit IDs + COMMIT_IDS=$(gh api repos/$REPO/issues/$ISSUE_NUMBER/timeline --jq '.[] | select(.event == "referenced" and .commit_id != null) | .commit_id') + + if [[ -z "$COMMIT_IDS" ]]; then + echo "No directly linked commits found, checking PRs..." + + # Try to get commits from PRs + PR_NUMBERS=$(gh api repos/$REPO/issues/$ISSUE_NUMBER/timeline --jq '.[] | select(.event == "cross-referenced" and .source.issue.pull_request != null) | .source.issue.number') + + if [[ -n "$PR_NUMBERS" ]]; then + for PR in $PR_NUMBERS; do + echo "Fetching commits from PR #$PR..." + PR_COMMITS=$(gh api repos/$REPO/pulls/$PR/commits --jq '.[].sha') + + if [[ -n "$PR_COMMITS" ]]; then + COMMIT_IDS="$COMMIT_IDS"$'\n'"$PR_COMMITS" + fi + done + fi + fi + + # Process commit messages to find the latest one with FAIL_TO_PASS or PASS_TO_PASS + if [[ -n "$COMMIT_IDS" ]]; then + # Variables to track the latest commit with values + LATEST_COMMIT_ID="" + LATEST_COMMIT_DATE="" + LATEST_COMMIT_FAIL="" + LATEST_COMMIT_PASS="" + + while IFS= read -r COMMIT_ID; do + if [[ -z "$COMMIT_ID" ]]; then + continue + fi + + echo "Fetching message for commit: $COMMIT_ID" + COMMIT_DATA=$(gh api repos/$REPO/commits/$COMMIT_ID --jq '{message: .commit.message, date: .commit.author.date}') + COMMIT_MSG=$(echo "$COMMIT_DATA" | jq -r '.message') + COMMIT_DATE=$(echo "$COMMIT_DATA" | jq -r '.date') + + if [[ -n "$COMMIT_MSG" ]]; then + RESULT=$(extract_test_fields "$COMMIT_MSG") + IFS='|' read -r COMMIT_FAIL COMMIT_PASS <<< "$RESULT" + + if [[ -n "$COMMIT_FAIL" || -n "$COMMIT_PASS" ]]; then + # Check if this commit is newer than our current latest + if [[ -z "$LATEST_COMMIT_DATE" || "$COMMIT_DATE" > "$LATEST_COMMIT_DATE" ]]; then + LATEST_COMMIT_ID="$COMMIT_ID" + LATEST_COMMIT_DATE="$COMMIT_DATE" + LATEST_COMMIT_FAIL="$COMMIT_FAIL" + LATEST_COMMIT_PASS="$COMMIT_PASS" + + if [[ -n "$COMMIT_FAIL" ]]; then + echo "Found FAIL_TO_PASS in commit $COMMIT_ID: $COMMIT_FAIL" + fi + + if [[ -n "$COMMIT_PASS" ]]; then + echo "Found PASS_TO_PASS in commit $COMMIT_ID: $COMMIT_PASS" + fi + fi + fi + fi + done <<< "$COMMIT_IDS" + + # Use values from the latest commit + if [[ -n "$LATEST_COMMIT_ID" ]]; then + if [[ -n "$LATEST_COMMIT_FAIL" ]]; then + FAIL_TO_PASS=("$LATEST_COMMIT_FAIL") + echo "Using FAIL_TO_PASS from latest commit $LATEST_COMMIT_ID: $LATEST_COMMIT_FAIL" + fi + + if [[ -n "$LATEST_COMMIT_PASS" ]]; then + PASS_TO_PASS=("$LATEST_COMMIT_PASS") + echo "Using PASS_TO_PASS from latest commit $LATEST_COMMIT_ID: $LATEST_COMMIT_PASS" + fi + fi + fi + fi + done + + # Convert arrays to comma-separated strings + FAIL_TO_PASS_STR=$(IFS=,; echo "${FAIL_TO_PASS[*]}") + PASS_TO_PASS_STR=$(IFS=,; echo "${PASS_TO_PASS[*]}") + + # Convert to JSON arrays if not empty + if [[ -n "$FAIL_TO_PASS_STR" ]]; then + FAIL_TO_PASS_JSON=$(echo "$FAIL_TO_PASS_STR" | jq -R -c 'split(",") | map(select(length > 0))') + else + FAIL_TO_PASS_JSON="[]" + fi + + if [[ -n "$PASS_TO_PASS_STR" ]]; then + PASS_TO_PASS_JSON=$(echo "$PASS_TO_PASS_STR" | jq -R -c 'split(",") | map(select(length > 0))') + else + PASS_TO_PASS_JSON="[]" + fi + + # Combine tests + if [[ -n "$FAIL_TO_PASS_STR" || -n "$PASS_TO_PASS_STR" ]]; then + TESTS_STR="$FAIL_TO_PASS_STR,$PASS_TO_PASS_STR" + TESTS_STR=$(echo "$TESTS_STR" | sed 's/^,//;s/,$//') + fi + + # Output results + echo "fail_to_pass=$FAIL_TO_PASS_JSON" >> $GITHUB_OUTPUT + echo "pass_to_pass=$PASS_TO_PASS_JSON" >> $GITHUB_OUTPUT + echo "tests=$TESTS_STR" >> $GITHUB_OUTPUT + echo "comment_id=$COMMENT_ID" >> $GITHUB_OUTPUT + + # ─── 1.3 combine test results ─── + - name: Combine test results + id: combine + shell: bash + run: | + # Just pass through the outputs from extract_tests + echo "fail_to_pass=${{ steps.extract_tests.outputs.fail_to_pass }}" >> $GITHUB_OUTPUT + echo "pass_to_pass=${{ steps.extract_tests.outputs.pass_to_pass }}" >> $GITHUB_OUTPUT + echo "tests=${{ steps.extract_tests.outputs.tests }}" >> $GITHUB_OUTPUT + echo "comment_id=${{ steps.extract_tests.outputs.comment_id }}" >> $GITHUB_OUTPUT + + # ─── 1.4 check if FAIL_TO_PASS or PASS_TO_PASS found ─── + - name: Check if FAIL_TO_PASS or PASS_TO_PASS found + if: ${{ github.event_name == 'pull_request' && steps.combine.outputs.fail_to_pass == '[]' && steps.combine.outputs.pass_to_pass == '[]' }} + shell: bash + run: | + echo "::error::FAIL_TO_PASS or PASS_TO_PASS not found in commit messages or issue comments, please add FAIL_TO_PASS or PASS_TO_PASS to issue comment" + exit 1 + + # ──────────── 2. Run tests and handle comments ──────────── + run-tests-and-comments: + needs: collect-process-tests + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + if: ${{ always() && (github.event_name != 'pull_request' || needs.collect-process-tests.outputs.fail_to_pass != '[]' || needs.collect-process-tests.outputs.pass_to_pass != '[]') }} + outputs: + comment_id: ${{ steps.create_comment.outputs.comment_id }} + status: ${{ job.status }} + steps: + - uses: actions/checkout@v4 + + # Step 1: Create placeholder comment + - name: Create placeholder issue comment + id: create_comment + if: ${{ github.event_name == 'push' || github.event_name == 'issue_comment' }} + uses: actions/github-script@v7 + env: + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + WORKFLOW_NAME: ${{ github.workflow }} + FAIL_TO_PASS: ${{ needs.collect-process-tests.outputs.fail_to_pass }} + PASS_TO_PASS: ${{ needs.collect-process-tests.outputs.pass_to_pass }} + COMMENT_ID: ${{ needs.collect-process-tests.outputs.comment_id }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string + script: | + const issuePat = /#(\d+)/g; + let issueNum = null, m; + + // • PR context + if (context.payload.pull_request) { + const whole = `${context.payload.pull_request.title}\n${context.payload.pull_request.body}`; + if ((m = issuePat.exec(whole)) !== null) issueNum = +m[1]; + } + + // • Push context + if (!issueNum && context.payload.commits) { + for (const c of context.payload.commits) { + if ((m = issuePat.exec(c.message)) !== null) { issueNum = +m[1]; break; } + } + } + + // • Issue comment context + if (!issueNum && context.payload.issue) { + issueNum = context.payload.issue.number; + } + + if (!issueNum) { core.info('No #issue reference found.'); return; } + + let bodyContent = ''; + + if (!process.env.COMMENT_ID){ + if (process.env.FAIL_TO_PASS && process.env.FAIL_TO_PASS !== '[]') { + // Parse JSON array and convert to comma-separated string + core.info('FAIL_TO_PASS: '+process.env.FAIL_TO_PASS); + const failToPassArray = JSON.parse(process.env.FAIL_TO_PASS); + const failToPassString = failToPassArray.join(', '); + bodyContent += `FAIL_TO_PASS: ${failToPassString}\n`; + } + + if (process.env.PASS_TO_PASS && process.env.PASS_TO_PASS !== '[]') { + // Parse JSON array and convert to comma-separated string + const passToPassArray = JSON.parse(process.env.PASS_TO_PASS); + const passToPassString = passToPassArray.join(', '); + bodyContent += `PASS_TO_PASS: ${passToPassString}\n`; + } + } + + bodyContent += `\n⏳ **[${process.env.WORKFLOW_NAME}](${process.env.RUN_URL})** has **started**…`; + + // If we have an existing comment ID, update it instead of creating a new one + if (false && process.env.COMMENT_ID) { + try { + // Get existing comment body + const { data: existingComment } = await github.rest.issues.getComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: Number(process.env.COMMENT_ID) + }); + + // Append new content to existing body + const updatedBody = existingComment.body + '\n' + bodyContent; + + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: Number(process.env.COMMENT_ID), + body: updatedBody + }); + core.setOutput('comment_id', process.env.COMMENT_ID); + return; + } catch (error) { + core.warning(`Failed to update comment ${process.env.COMMENT_ID}: ${error.message}`); + // Fall through to create a new comment + } + } + + // Create a new comment + const { data: comment } = await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNum, + body: bodyContent + }); + core.setOutput('comment_id', comment.id.toString()); + + # Step 2: Setup Java and Maven + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: '24' + distribution: 'temurin' + cache: 'maven' + + # Step 3: Compile project + - name: Compile project + shell: bash + run: mvn -B compile --file pom.xml + + # Step 4: Run tests + - name: Run selected tests + if: ${{ needs.collect-process-tests.outputs.tests != '' }} + shell: bash + run: mvn -B -Dtest="${{ needs.collect-process-tests.outputs.tests }}" test + + - name: Run all tests + if: ${{ needs.collect-process-tests.outputs.tests == '' }} + shell: bash + run: mvn -B test --file pom.xml + + # Step 5: Update comment with final status + - name: Update issue comment with final status + if: ${{ always() && (github.event_name == 'push' || github.event_name == 'issue_comment') }} + uses: actions/github-script@v7 + env: + COMMENT_ID: ${{ steps.create_comment.outputs.comment_id }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + WORKFLOW_NAME: ${{ github.workflow }} + JOB_STATUS: ${{ job.status }} + FAIL_TO_PASS: ${{ needs.collect-process-tests.outputs.fail_to_pass }} + PASS_TO_PASS: ${{ needs.collect-process-tests.outputs.pass_to_pass }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + if (!process.env.COMMENT_ID) { + core.info('No comment to update.'); return; + } + const statusEmoji = { + success: '✅', + failure: '❌', + cancelled: '🟡' + }[process.env.JOB_STATUS] || '🟡'; + + let bodyContent = ''; + if (!process.env.COMMENT_ID){ + if (process.env.FAIL_TO_PASS && process.env.FAIL_TO_PASS !== '[]') { + // Parse JSON array and convert to comma-separated string + const quoted = process.env.FAIL_TO_PASS.replace(/(\w+)/g, '"$1"'); + const failToPassArray = JSON.parse(quoted); + const failToPassString = failToPassArray.join(', '); + bodyContent += `FAIL_TO_PASS: ${failToPassString}\n`; + } + + if (process.env.PASS_TO_PASS && process.env.PASS_TO_PASS !== '[]') { + // Parse JSON array and convert to comma-separated string + const quoted = process.env.PASS_TO_PASS.replace(/(\w+)/g, '"$1"'); + const passToPassArray = JSON.parse(quoted); + const passToPassString = passToPassArray.join(', '); + bodyContent += `PASS_TO_PASS: ${passToPassString}\n`; + } + } + + bodyContent += `\n${statusEmoji} **[${process.env.WORKFLOW_NAME}](${process.env.RUN_URL})** finished with status **${process.env.JOB_STATUS.toUpperCase()}**.`; + + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: Number(process.env.COMMENT_ID), + body: bodyContent + }); \ No newline at end of file diff --git a/.github/workflows/pr-label-management.yml b/.github/workflows/pr-label-management.yml new file mode 100644 index 0000000000..24773ffb81 --- /dev/null +++ b/.github/workflows/pr-label-management.yml @@ -0,0 +1,174 @@ +name: PR Label Management + +on: + pull_request: + types: [opened, reopened, synchronize] + pull_request_review: + types: [submitted] + +jobs: + manage-labels: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + issues: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Add Review label on PR creation + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + // Add Review label to the PR + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + labels: ['Review'] + }); + + console.log(`Added Review label to PR #${context.payload.pull_request.number}`); + + // Extract related issue numbers from PR title and body + const prText = `${context.payload.pull_request.title} ${context.payload.pull_request.body || ''}`; + const issuePattern = /#(\d+)/g; + const relatedIssues = new Set(); + let match; + + while ((match = issuePattern.exec(prText)) !== null) { + relatedIssues.add(match[1]); + } + + // Also check commit messages for issue references + const commits = await github.rest.pulls.listCommits({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.payload.pull_request.number + }); + + for (const commit of commits.data) { + const commitMessage = commit.commit.message; + while ((match = issuePattern.exec(commitMessage)) !== null) { + relatedIssues.add(match[1]); + } + } + + // Add Review label to all related issues + for (const issueNumber of relatedIssues) { + try { + // Check if issue exists + await github.rest.issues.get({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber) + }); + + // Add Review label to the issue + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber), + labels: ['Review'] + }); + + console.log(`Added Review label to related issue #${issueNumber}`); + } catch (error) { + console.log(`Error processing issue #${issueNumber}: ${error.message}`); + } + } + + - name: Handle PR approval + if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prNumber = context.payload.pull_request.number; + + // Remove Review label and add Verified label to the PR + try { + // First try to remove the Review label + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + name: 'Review' + }); + console.log(`Removed Review label from PR #${prNumber}`); + } catch (error) { + console.log(`Note: Review label might not exist on PR #${prNumber}: ${error.message}`); + } + + // Add Verified label to the PR + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + labels: ['Verified'] + }); + console.log(`Added Verified label to PR #${prNumber}`); + + // Extract related issue numbers from PR title and body + const prText = `${context.payload.pull_request.title} ${context.payload.pull_request.body || ''}`; + const issuePattern = /#(\d+)/g; + const relatedIssues = new Set(); + let match; + + while ((match = issuePattern.exec(prText)) !== null) { + relatedIssues.add(match[1]); + } + + // Also check commit messages for issue references + const commits = await github.rest.pulls.listCommits({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber + }); + + for (const commit of commits.data) { + const commitMessage = commit.commit.message; + while ((match = issuePattern.exec(commitMessage)) !== null) { + relatedIssues.add(match[1]); + } + } + + // Update labels on all related issues + for (const issueNumber of relatedIssues) { + try { + // Check if issue exists + await github.rest.issues.get({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber) + }); + + // Try to remove Review label from the issue + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber), + name: 'Review' + }); + console.log(`Removed Review label from related issue #${issueNumber}`); + } catch (error) { + console.log(`Note: Review label might not exist on issue #${issueNumber}: ${error.message}`); + } + + // Add Verified label to the issue + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber), + labels: ['Verified'] + }); + console.log(`Added Verified label to related issue #${issueNumber}`); + } catch (error) { + console.log(`Error processing issue #${issueNumber}: ${error.message}`); + } + } \ No newline at end of file diff --git a/ts-common/pom.xml b/ts-common/pom.xml index ada2e02ac2..cec12a70e4 100644 --- a/ts-common/pom.xml +++ b/ts-common/pom.xml @@ -25,6 +25,12 @@ jakarta.validation jakarta.validation-api + + + org.hibernate.validator + hibernate-validator + 6.2.5.Final + javax.persistence javax.persistence-api diff --git a/ts-common/src/main/java/edu/fudan/common/entity/Contacts.java b/ts-common/src/main/java/edu/fudan/common/entity/Contacts.java index eb261bce0c..fa7ca37d1f 100644 --- a/ts-common/src/main/java/edu/fudan/common/entity/Contacts.java +++ b/ts-common/src/main/java/edu/fudan/common/entity/Contacts.java @@ -40,11 +40,11 @@ public boolean equals(Object obj) { return false; } Contacts other = (Contacts) obj; - return name.equals(other.getName()) - && accountId .equals( other.getAccountId() ) - && documentNumber.equals(other.getDocumentNumber()) - && phoneNumber.equals(other.getPhoneNumber()) - && documentType == other.getDocumentType(); + return name.equals(other.name) + && accountId .equals( other.accountId ) + && documentNumber.equals(other.documentNumber) + && phoneNumber.equals(other.phoneNumber) + && documentType == other.documentType; } @Override diff --git a/ts-common/src/main/java/edu/fudan/common/entity/Food.java b/ts-common/src/main/java/edu/fudan/common/entity/Food.java index 3882994e0a..b1598ddd7b 100644 --- a/ts-common/src/main/java/edu/fudan/common/entity/Food.java +++ b/ts-common/src/main/java/edu/fudan/common/entity/Food.java @@ -1,19 +1,51 @@ package edu.fudan.common.entity; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import javax.persistence.Embeddable; import java.io.Serializable; +import java.util.Objects; @Data +@NoArgsConstructor +@AllArgsConstructor @Embeddable public class Food implements Serializable{ private String foodName; private double price; - public Food(){ - //Default Constructor + + // Getters and Setters + public String getFoodName() { + return foodName; + } + + public void setFoodName(String foodName) { + this.foodName = foodName; + } + + public double getPrice() { + return price; } + public void setPrice(double price) { + this.price = price; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Food food = (Food) o; + return Double.compare(food.price, price) == 0 && + Objects.equals(foodName, food.foodName); + } + + @Override + public int hashCode() { + return Objects.hash(foodName, price); + } } diff --git a/ts-common/src/main/java/edu/fudan/common/entity/FoodOrder.java b/ts-common/src/main/java/edu/fudan/common/entity/FoodOrder.java index b888084a81..c790ae9518 100644 --- a/ts-common/src/main/java/edu/fudan/common/entity/FoodOrder.java +++ b/ts-common/src/main/java/edu/fudan/common/entity/FoodOrder.java @@ -1,13 +1,10 @@ package edu.fudan.common.entity; -import lombok.Data; - import java.util.UUID; /** * @author fdse */ -@Data public class FoodOrder { private String id; @@ -31,4 +28,71 @@ public FoodOrder(){ //Default Constructor } + public FoodOrder(String id, String orderId, int foodType, String stationName, + String storeName, String foodName, double price) { + this.id = id; + this.orderId = orderId; + this.foodType = foodType; + this.stationName = stationName; + this.storeName = storeName; + this.foodName = foodName; + this.price = price; + } + + // Getters and Setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public int getFoodType() { + return foodType; + } + + public void setFoodType(int foodType) { + this.foodType = foodType; + } + + public String getStationName() { + return stationName; + } + + public void setStationName(String stationName) { + this.stationName = stationName; + } + + public String getStoreName() { + return storeName; + } + + public void setStoreName(String storeName) { + this.storeName = storeName; + } + + public String getFoodName() { + return foodName; + } + + public void setFoodName(String foodName) { + this.foodName = foodName; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } } diff --git a/ts-common/src/main/java/edu/fudan/common/entity/Order.java b/ts-common/src/main/java/edu/fudan/common/entity/Order.java index cf8f1285fb..aab327f835 100644 --- a/ts-common/src/main/java/edu/fudan/common/entity/Order.java +++ b/ts-common/src/main/java/edu/fudan/common/entity/Order.java @@ -15,6 +15,7 @@ */ @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor @AllArgsConstructor public class Order { @@ -58,7 +59,7 @@ public class Order { private String differenceMoney; - public Order(){ + public void initOrder(){ boughtDate = StringUtils.Date2String(new Date(System.currentTimeMillis())); travelDate = StringUtils.Date2String(new Date(123456789)); trainNumber = "G1235"; @@ -72,6 +73,7 @@ public Order(){ differenceMoney ="0.0"; } + @Override public boolean equals(Object obj) { if (this == obj) { return true; @@ -83,20 +85,20 @@ public boolean equals(Object obj) { return false; } Order other = (Order) obj; - return getBoughtDate().equals(other.getBoughtDate()) - && getBoughtDate().equals(other.getTravelDate()) - && getTravelTime().equals(other.getTravelTime()) - && accountId .equals( other.getAccountId() ) - && contactsName.equals(other.getContactsName()) - && contactsDocumentNumber.equals(other.getContactsDocumentNumber()) - && documentType == other.getDocumentType() - && trainNumber.equals(other.getTrainNumber()) - && coachNumber == other.getCoachNumber() - && seatClass == other.getSeatClass() - && seatNumber .equals(other.getSeatNumber()) - && from.equals(other.getFrom()) - && to.equals(other.getTo()) - && status == other.getStatus() + return boughtDate.equals(other.boughtDate) + && travelDate.equals(other.travelDate) + && travelTime.equals(other.travelTime) + && accountId .equals( other.accountId ) + && contactsName.equals(other.contactsName) + && contactsDocumentNumber.equals(other.contactsDocumentNumber) + && documentType == other.documentType + && trainNumber.equals(other.trainNumber) + && coachNumber == other.coachNumber + && seatClass == other.seatClass + && seatNumber .equals(other.seatNumber) + && from.equals(other.from) + && to.equals(other.to) + && status == other.status && price.equals(other.price); } diff --git a/ts-common/src/main/java/edu/fudan/common/entity/OrderAlterInfo.java b/ts-common/src/main/java/edu/fudan/common/entity/OrderAlterInfo.java index 812c87f7f7..24ffc4ab60 100644 --- a/ts-common/src/main/java/edu/fudan/common/entity/OrderAlterInfo.java +++ b/ts-common/src/main/java/edu/fudan/common/entity/OrderAlterInfo.java @@ -2,12 +2,14 @@ import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; /** * @author fdse */ @Data +@NoArgsConstructor @AllArgsConstructor public class OrderAlterInfo { private String accountId; @@ -18,7 +20,11 @@ public class OrderAlterInfo { private Order newOrderInfo; - public OrderAlterInfo(){ - newOrderInfo = new Order(); + public OrderAlterInfo(String accountId, String previousOrderId, String loginToken){ + this.accountId = accountId; + this.previousOrderId = previousOrderId; + this.loginToken = loginToken; + this.newOrderInfo = new Order(); + this.newOrderInfo.initOrder(); } } diff --git a/ts-common/src/main/java/edu/fudan/common/entity/TripInfo.java b/ts-common/src/main/java/edu/fudan/common/entity/TripInfo.java index d406402d7c..9412b331d3 100644 --- a/ts-common/src/main/java/edu/fudan/common/entity/TripInfo.java +++ b/ts-common/src/main/java/edu/fudan/common/entity/TripInfo.java @@ -1,8 +1,6 @@ package edu.fudan.common.entity; import edu.fudan.common.util.StringUtils; -import lombok.AllArgsConstructor; -import lombok.Data; import javax.validation.Valid; import javax.validation.constraints.NotNull; @@ -11,8 +9,6 @@ /** * @author fdse */ -@Data -@AllArgsConstructor public class TripInfo { @Valid @NotNull @@ -33,14 +29,36 @@ public TripInfo(){ this.departureTime = ""; } + public TripInfo(String startPlace, String endPlace, String departureTime) { + this.startPlace = startPlace; + this.endPlace = endPlace; + this.departureTime = departureTime; + } + public String getStartPlace() { return StringUtils.String2Lower(this.startPlace); } + public void setStartPlace(String startPlace) { + this.startPlace = startPlace; + } + public String getEndPlace() { return StringUtils.String2Lower(this.endPlace); } + public void setEndPlace(String endPlace) { + this.endPlace = endPlace; + } + + public String getDepartureTime() { + return departureTime; + } + + public void setDepartureTime(String departureTime) { + this.departureTime = departureTime; + } + // public Date getDepartureTime(){ // return StringUtils.String2Date(this.departureTime); // } diff --git a/ts-common/src/main/java/edu/fudan/common/util/Response.java b/ts-common/src/main/java/edu/fudan/common/util/Response.java index 3b2face56c..6448e8d882 100644 --- a/ts-common/src/main/java/edu/fudan/common/util/Response.java +++ b/ts-common/src/main/java/edu/fudan/common/util/Response.java @@ -5,12 +5,12 @@ import lombok.NoArgsConstructor; import lombok.ToString; +import java.util.Objects; + /** * @author fdse */ @Data -@AllArgsConstructor -@NoArgsConstructor @ToString public class Response { @@ -21,4 +21,84 @@ public class Response { String msg; T data; + + /** + * Default constructor + */ + public Response() { + } + + /** + * Constructor with all parameters + * @param status the status (1 for true, 0 for false) + * @param msg the message + * @param data the data + */ + public Response(Integer status, String msg, T data) { + this.status = status; + this.msg = msg; + this.data = data; + } + + /** + * Constructor with status and message only + * @param status the status (1 for true, 0 for false) + * @param msg the message + */ + public Response(Integer status, String msg) { + this.status = status; + this.msg = msg; + this.data = null; + } + + /** + * Constructor with status and data only + * @param status the status (1 for true, 0 for false) + * @param data the data + */ + public Response(Integer status, T data) { + this.status = status; + this.msg = null; + this.data = data; + } + + // Getters and Setters + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Response response = (Response) o; + return Objects.equals(status, response.status) && + Objects.equals(msg, response.msg) && + Objects.equals(data, response.data); + } + + @Override + public int hashCode() { + return Objects.hash(status, msg, data); + } } diff --git a/ts-food-delivery-service/pom.xml b/ts-food-delivery-service/pom.xml index 78bed3dd6f..c6df75991d 100644 --- a/ts-food-delivery-service/pom.xml +++ b/ts-food-delivery-service/pom.xml @@ -42,6 +42,18 @@ jakarta.validation-api 2.0.2 + + + org.hibernate.validator + hibernate-validator + 6.2.5.Final + + + + org.projectlombok + lombok + provided + diff --git a/ts-food-delivery-service/src/main/java/food_delivery/entity/DeliveryInfo.java b/ts-food-delivery-service/src/main/java/food_delivery/entity/DeliveryInfo.java index 2e2cb1815f..1aaef11fdd 100644 --- a/ts-food-delivery-service/src/main/java/food_delivery/entity/DeliveryInfo.java +++ b/ts-food-delivery-service/src/main/java/food_delivery/entity/DeliveryInfo.java @@ -4,10 +4,43 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Objects; + @Data @NoArgsConstructor @AllArgsConstructor public class DeliveryInfo { private String orderId; private String deliveryTime; + + // Getters and Setters + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getDeliveryTime() { + return deliveryTime; + } + + public void setDeliveryTime(String deliveryTime) { + this.deliveryTime = deliveryTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeliveryInfo that = (DeliveryInfo) o; + return Objects.equals(orderId, that.orderId) && + Objects.equals(deliveryTime, that.deliveryTime); + } + + @Override + public int hashCode() { + return Objects.hash(orderId, deliveryTime); + } } diff --git a/ts-food-delivery-service/src/main/java/food_delivery/entity/FoodDeliveryOrder.java b/ts-food-delivery-service/src/main/java/food_delivery/entity/FoodDeliveryOrder.java index a27f5861d2..d6a654de95 100644 --- a/ts-food-delivery-service/src/main/java/food_delivery/entity/FoodDeliveryOrder.java +++ b/ts-food-delivery-service/src/main/java/food_delivery/entity/FoodDeliveryOrder.java @@ -1,21 +1,18 @@ package food_delivery.entity; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NoArgsConstructor; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.List; +import java.util.Objects; import edu.fudan.common.entity.Food; @Data @Entity @GenericGenerator(name = "jpa-uuid", strategy = "uuid") @JsonIgnoreProperties(ignoreUnknown = true) -@AllArgsConstructor -@NoArgsConstructor public class FoodDeliveryOrder { @Id @@ -37,4 +34,99 @@ public class FoodDeliveryOrder { private String deliveryTime; private double deliveryFee; + + public FoodDeliveryOrder() { + // Default constructor + } + + public FoodDeliveryOrder(String id, String stationFoodStoreId, List foodList, + String tripId, int seatNo, String createdTime, + String deliveryTime, double deliveryFee) { + this.id = id; + this.stationFoodStoreId = stationFoodStoreId; + this.foodList = foodList; + this.tripId = tripId; + this.seatNo = seatNo; + this.createdTime = createdTime; + this.deliveryTime = deliveryTime; + this.deliveryFee = deliveryFee; + } + + // Getters and Setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getStationFoodStoreId() { + return stationFoodStoreId; + } + + public void setStationFoodStoreId(String stationFoodStoreId) { + this.stationFoodStoreId = stationFoodStoreId; + } + + public List getFoodList() { + return foodList; + } + + public void setFoodList(List foodList) { + this.foodList = foodList; + } + + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } + + public int getSeatNo() { + return seatNo; + } + + public void setSeatNo(int seatNo) { + this.seatNo = seatNo; + } + + public String getCreatedTime() { + return createdTime; + } + + public void setCreatedTime(String createdTime) { + this.createdTime = createdTime; + } + + public String getDeliveryTime() { + return deliveryTime; + } + + public void setDeliveryTime(String deliveryTime) { + this.deliveryTime = deliveryTime; + } + + public double getDeliveryFee() { + return deliveryFee; + } + + public void setDeliveryFee(double deliveryFee) { + this.deliveryFee = deliveryFee; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FoodDeliveryOrder that = (FoodDeliveryOrder) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } } diff --git a/ts-food-delivery-service/src/main/java/food_delivery/entity/SeatInfo.java b/ts-food-delivery-service/src/main/java/food_delivery/entity/SeatInfo.java index 615fccc523..02a072f8a2 100644 --- a/ts-food-delivery-service/src/main/java/food_delivery/entity/SeatInfo.java +++ b/ts-food-delivery-service/src/main/java/food_delivery/entity/SeatInfo.java @@ -4,10 +4,43 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Objects; + @Data @NoArgsConstructor @AllArgsConstructor public class SeatInfo { private String orderId; private int seatNo; + + // Getters and Setters + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public int getSeatNo() { + return seatNo; + } + + public void setSeatNo(int seatNo) { + this.seatNo = seatNo; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SeatInfo seatInfo = (SeatInfo) o; + return seatNo == seatInfo.seatNo && + Objects.equals(orderId, seatInfo.orderId); + } + + @Override + public int hashCode() { + return Objects.hash(orderId, seatNo); + } } \ No newline at end of file diff --git a/ts-food-delivery-service/src/main/java/food_delivery/entity/StationFoodStoreInfo.java b/ts-food-delivery-service/src/main/java/food_delivery/entity/StationFoodStoreInfo.java index 6138db4496..8a88cbc09f 100644 --- a/ts-food-delivery-service/src/main/java/food_delivery/entity/StationFoodStoreInfo.java +++ b/ts-food-delivery-service/src/main/java/food_delivery/entity/StationFoodStoreInfo.java @@ -6,6 +6,7 @@ import lombok.NoArgsConstructor; import java.util.List; +import java.util.Objects; import edu.fudan.common.entity.Food; @Data @@ -15,17 +16,86 @@ public class StationFoodStoreInfo { private String id; - private String stationId; - private String storeName; - private String telephone; - private String businessTime; - private double deliveryFee; - private List foodList; + // Getters and Setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getStationId() { + return stationId; + } + + public void setStationId(String stationId) { + this.stationId = stationId; + } + + public String getStoreName() { + return storeName; + } + + public void setStoreName(String storeName) { + this.storeName = storeName; + } + + public String getTelephone() { + return telephone; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + public String getBusinessTime() { + return businessTime; + } + + public void setBusinessTime(String businessTime) { + this.businessTime = businessTime; + } + + public double getDeliveryFee() { + return deliveryFee; + } + + public void setDeliveryFee(double deliveryFee) { + this.deliveryFee = deliveryFee; + } + + public List getFoodList() { + return foodList; + } + + public void setFoodList(List foodList) { + this.foodList = foodList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + StationFoodStoreInfo that = (StationFoodStoreInfo) o; + return Double.compare(that.deliveryFee, deliveryFee) == 0 && + Objects.equals(id, that.id) && + Objects.equals(stationId, that.stationId) && + Objects.equals(storeName, that.storeName) && + Objects.equals(telephone, that.telephone) && + Objects.equals(businessTime, that.businessTime) && + Objects.equals(foodList, that.foodList); + } + + @Override + public int hashCode() { + return Objects.hash(id, stationId, storeName, telephone, businessTime, deliveryFee, foodList); + } } diff --git a/ts-food-delivery-service/src/main/java/food_delivery/entity/TripOrderInfo.java b/ts-food-delivery-service/src/main/java/food_delivery/entity/TripOrderInfo.java index eda0a58a5d..a1e48e2623 100644 --- a/ts-food-delivery-service/src/main/java/food_delivery/entity/TripOrderInfo.java +++ b/ts-food-delivery-service/src/main/java/food_delivery/entity/TripOrderInfo.java @@ -4,10 +4,43 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Objects; + @Data @NoArgsConstructor @AllArgsConstructor public class TripOrderInfo { private String orderId; private String tripId; + + // Getters and Setters + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TripOrderInfo that = (TripOrderInfo) o; + return Objects.equals(orderId, that.orderId) && + Objects.equals(tripId, that.tripId); + } + + @Override + public int hashCode() { + return Objects.hash(orderId, tripId); + } } diff --git a/ts-route-service/src/test/java/route/service/RouteServiceImplTest.java b/ts-route-service/src/test/java/route/service/RouteServiceImplTest.java index 572b13fdad..75249db8fc 100644 --- a/ts-route-service/src/test/java/route/service/RouteServiceImplTest.java +++ b/ts-route-service/src/test/java/route/service/RouteServiceImplTest.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; @RunWith(JUnit4.class) @@ -47,7 +48,7 @@ public void testCreateAndModify2() { RouteInfo info = new RouteInfo("id", "start_station", "end_station", "shanghai", "5"); Mockito.when(routeRepository.save(Mockito.any(Route.class))).thenReturn(null); Response result = routeServiceImpl.createAndModify(info, headers); - Assert.assertEquals("Save Success", result.getMsg()); + Assert.assertEquals("Save and Modify success", result.getMsg()); } @Test @@ -56,13 +57,13 @@ public void testCreateAndModify3() { Mockito.when(routeRepository.findById(Mockito.anyString())).thenReturn(null); Mockito.when(routeRepository.save(Mockito.any(Route.class))).thenReturn(null); Response result = routeServiceImpl.createAndModify(info, headers); - Assert.assertEquals("Modify success", result.getMsg()); + Assert.assertEquals("Save and Modify success", result.getMsg()); } @Test public void testDeleteRoute1() { Mockito.doNothing().doThrow(new RuntimeException()).when(routeRepository).removeRouteById(Mockito.anyString()); - Mockito.when(routeRepository.findById(Mockito.anyString())).thenReturn(null); + Mockito.when(routeRepository.findById(Mockito.anyString())).thenReturn(Optional.empty()); Response result = routeServiceImpl.deleteRoute("route_id", headers); Assert.assertEquals(new Response<>(1, "Delete Success", "route_id"), result); } @@ -71,14 +72,14 @@ public void testDeleteRoute1() { public void testDeleteRoute2() { Route route = new Route(); Mockito.doNothing().doThrow(new RuntimeException()).when(routeRepository).removeRouteById(Mockito.anyString()); - Mockito.when(routeRepository.findById(Mockito.anyString()).get()).thenReturn(route); + Mockito.when(routeRepository.findById(Mockito.anyString())).thenReturn(Optional.of(route)); Response result = routeServiceImpl.deleteRoute("route_id", headers); Assert.assertEquals(new Response<>(0, "Delete failed, Reason unKnown with this routeId", "route_id"), result); } @Test public void testGetRouteById1() { - Mockito.when(routeRepository.findById(Mockito.anyString())).thenReturn(null); + Mockito.when(routeRepository.findById(Mockito.anyString())).thenReturn(Optional.empty()); Response result = routeServiceImpl.getRouteById("route_id", headers); Assert.assertEquals(new Response<>(0, "No content with the routeId", null), result); } @@ -86,9 +87,9 @@ public void testGetRouteById1() { @Test public void testGetRouteById2() { Route route = new Route(); - Mockito.when(routeRepository.findById(Mockito.anyString()).get()).thenReturn(route); + Mockito.when(routeRepository.findById(Mockito.anyString())).thenReturn(Optional.of(route)); Response result = routeServiceImpl.getRouteById("route_id", headers); - Assert.assertEquals(new Response<>(1, "Success", route), result); + Assert.assertEquals(new Response<>(1, "Success", Optional.of(route)), result); } @Test