From 389e1d3a5b5b58f146d3801177b8c4e6b4138016 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Singh Date: Sat, 23 May 2026 18:46:09 +0530 Subject: [PATCH 1/2] chore(repo): rework github pipelines --- .github/workflows/auto-label-pr.yml | 74 ++++++++-------- .github/workflows/ci-app.yml | 57 ++++++------ .github/workflows/ci-backend.yml | 45 ++++++---- .github/workflows/ci-ml-worker.yml | 64 +++++++------- .github/workflows/ml-worker.yml | 46 ---------- .github/workflows/pr-validator.yml | 129 ++++++++++------------------ .github/workflows/setup-labels.yml | 46 +++++----- app/package.json | 4 +- 8 files changed, 207 insertions(+), 258 deletions(-) delete mode 100644 .github/workflows/ml-worker.yml diff --git a/.github/workflows/auto-label-pr.yml b/.github/workflows/auto-label-pr.yml index 3ab1815..8af1def 100644 --- a/.github/workflows/auto-label-pr.yml +++ b/.github/workflows/auto-label-pr.yml @@ -1,65 +1,71 @@ -name: Auto-label PR +name: Auto Label PR on: pull_request: - types: [opened, edited, synchronize] + types: [opened, edited, synchronize, reopened] permissions: - pull-requests: write + contents: read + pull-requests: read issues: write jobs: auto-label: - name: Apply area and type labels + name: auto-label runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - name: Parse title and apply labels + - name: Apply labels uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const pr = context.payload.pull_request; - const title = pr.title; + const owner = context.repo.owner; + const repo = context.repo.repo; const prNumber = pr.number; - const owner = context.repo.owner; - const repo = context.repo.repo; + const title = pr.title || ""; - const titleRegex = /^(feat|fix|docs|chore|refactor|test|style|perf)\((app|backend|ml-worker|repo)\): .{10,}$/; - const match = titleRegex.exec(title); + const typeMatch = /^(feat|fix|docs|chore|refactor|test|style|perf)\((app|backend|ml-worker|repo|shared)\):\s+.{10,}$/i.exec(title); + const labels = new Set(); - // If the title doesn't match the convention, skip labeling silently. - // The pr-validator workflow handles invalid PRs. - if (!match) { - console.log("Title does not match convention — skipping auto-label."); - return; + if (typeMatch) { + labels.add(`type:${typeMatch[1].toLowerCase()}`); + const scope = typeMatch[2].toLowerCase(); + labels.add(scope === "shared" ? "area:repo" : `area:${scope}`); } - const type = match[1]; // e.g. "feat" - const scope = match[2]; // e.g. "app" + const files = await github.paginate(github.rest.pulls.listFiles, { + owner, + repo, + pull_number: prNumber, + per_page: 100, + }); - const scopeToArea = { - "app": "area:app", - "backend": "area:backend", - "ml-worker": "area:ml-worker", - "repo": "area:repo", - }; - - const labelsToApply = [ - `type:${type}`, - scopeToArea[scope], - ].filter(Boolean); + for (const file of files) { + if (file.filename.startsWith("app/")) labels.add("area:app"); + if (file.filename.startsWith("backend/")) labels.add("area:backend"); + if (file.filename.startsWith("ml-worker/")) labels.add("area:ml-worker"); + if ( + file.filename.startsWith(".github/") || + file.filename === "README.md" || + file.filename.startsWith("docs/") + ) { + labels.add("area:repo"); + } + } - for (const name of labelsToApply) { + for (const name of labels) { try { await github.rest.issues.addLabels({ - owner, repo, + owner, + repo, issue_number: prNumber, labels: [name], }); - console.log(`✅ Applied label: ${name}`); - } catch (e) { - // Label may not exist in the repo yet (e.g., setup-labels not run) - core.warning(`Could not apply label "${name}": ${e.message}`); + console.log(`Applied label: ${name}`); + } catch (error) { + core.warning(`Could not apply label "${name}": ${error.message}`); } } diff --git a/.github/workflows/ci-app.yml b/.github/workflows/ci-app.yml index fb91d45..e4add60 100644 --- a/.github/workflows/ci-app.yml +++ b/.github/workflows/ci-app.yml @@ -1,16 +1,36 @@ -name: CI — App +name: CI App on: pull_request: branches: - main paths: + - ".github/workflows/ci-app.yml" - "app/**" + push: + branches: + - main + paths: + - ".github/workflows/ci-app.yml" + - "app/**" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-app-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - app-lint: - name: app-lint + app: + name: app runs-on: ubuntu-latest + timeout-minutes: 15 + + defaults: + run: + working-directory: app steps: - name: Check out repository @@ -20,36 +40,17 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" - cache: "npm" + cache: npm cache-dependency-path: app/package-lock.json - name: Install dependencies - working-directory: app run: npm ci - - name: Run ESLint - working-directory: app + - name: Check JavaScript syntax run: npm run lint - app-type-check: - name: app-type-check - runs-on: ubuntu-latest - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - cache-dependency-path: app/package-lock.json - - - name: Install dependencies - working-directory: app - run: npm ci + - name: Run TypeScript compiler + run: npm run typecheck - - name: TypeScript type check - working-directory: app - run: npx tsc --noEmit + - name: Build web bundle + run: npm run build:web diff --git a/.github/workflows/ci-backend.yml b/.github/workflows/ci-backend.yml index ade1909..0260dff 100644 --- a/.github/workflows/ci-backend.yml +++ b/.github/workflows/ci-backend.yml @@ -1,35 +1,48 @@ -name: CI — Backend +name: CI Backend on: pull_request: branches: - main paths: + - ".github/workflows/ci-backend.yml" - "backend/**" + push: + branches: + - main + paths: + - ".github/workflows/ci-backend.yml" + - "backend/**" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-backend-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - backend-build-test: - name: backend-build-test + backend: + name: backend runs-on: ubuntu-latest + timeout-minutes: 20 + + defaults: + run: + working-directory: backend steps: - name: Check out repository uses: actions/checkout@v4 - - name: Set up Java 17 + - name: Set up Java uses: actions/setup-java@v4 with: java-version: "17" - distribution: "temurin" + distribution: temurin + cache: maven + cache-dependency-path: backend/pom.xml - - name: Cache Maven dependencies - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('backend/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - - name: Build and test with Maven - working-directory: backend - run: mvn verify + - name: Verify backend + run: mvn -B verify diff --git a/.github/workflows/ci-ml-worker.yml b/.github/workflows/ci-ml-worker.yml index 0a7bf91..1f41154 100644 --- a/.github/workflows/ci-ml-worker.yml +++ b/.github/workflows/ci-ml-worker.yml @@ -1,41 +1,43 @@ -name: CI — ML Worker +name: CI ML Worker on: pull_request: branches: - main paths: + - ".github/workflows/ci-ml-worker.yml" - "ml-worker/**" + push: + branches: + - main + paths: + - ".github/workflows/ci-ml-worker.yml" + - "ml-worker/**" + workflow_dispatch: -jobs: - ml-lint: - name: ml-lint - runs-on: ubuntu-latest +permissions: + contents: read - steps: - - name: Check out repository - uses: actions/checkout@v4 +concurrency: + group: ci-ml-worker-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" +jobs: + ml-worker: + name: python-${{ matrix.python-version }} + runs-on: ubuntu-latest + timeout-minutes: 20 - - name: Install dependencies - working-directory: ml-worker - run: python -m pip install -e ".[dev]" + strategy: + fail-fast: false + matrix: + python-version: + - "3.11" + - "3.12" - - name: Run flake8 + defaults: + run: working-directory: ml-worker - run: flake8 . - - - name: Run black (check mode) - working-directory: ml-worker - run: black --check . - - ml-test: - name: ml-test - runs-on: ubuntu-latest steps: - name: Check out repository @@ -44,12 +46,14 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: | + ml-worker/pyproject.toml + ml-worker/requirements*.txt - name: Install dependencies - working-directory: ml-worker run: python -m pip install -e ".[dev]" - - name: Run pytest with coverage - working-directory: ml-worker - run: pytest --cov=ml_worker --cov-report=xml + - name: Run tests + run: pytest diff --git a/.github/workflows/ml-worker.yml b/.github/workflows/ml-worker.yml deleted file mode 100644 index 12e1021..0000000 --- a/.github/workflows/ml-worker.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: ML Worker - -on: - pull_request: - paths: - - ".github/workflows/ml-worker.yml" - - "ml-worker/**" - push: - branches: - - main - paths: - - ".github/workflows/ml-worker.yml" - - "ml-worker/**" - workflow_dispatch: - -jobs: - test: - name: Python ${{ matrix.python-version }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: - - "3.11" - - "3.12" - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: pip - cache-dependency-path: | - ml-worker/pyproject.toml - ml-worker/requirements*.txt - - - name: Install worker - working-directory: ml-worker - run: python -m pip install -e ".[dev]" - - - name: Run tests - working-directory: ml-worker - run: pytest diff --git a/.github/workflows/pr-validator.yml b/.github/workflows/pr-validator.yml index a82b008..f424ac9 100644 --- a/.github/workflows/pr-validator.yml +++ b/.github/workflows/pr-validator.yml @@ -5,141 +5,104 @@ on: types: [opened, edited, reopened, synchronize] permissions: - pull-requests: write - issues: write contents: read + pull-requests: read + issues: write jobs: validate-pr: name: validate-pr runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - name: Validate PR and enforce contribution rules + - name: Validate pull request uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const pr = context.payload.pull_request; - const title = pr.title; - const body = pr.body || ""; - const headRef = pr.head.ref; - const baseRef = pr.base.ref; - const author = pr.user.login; + const title = pr.title || ""; + const body = pr.body || ""; + const headRef = pr.head.ref || ""; + const baseRef = pr.base.ref || ""; const prNumber = pr.number; - const owner = context.repo.owner; - const repo = context.repo.repo; + const owner = context.repo.owner; + const repo = context.repo.repo; const failures = []; + const titleRegex = /^(feat|fix|docs|chore|refactor|test|style|perf)\((app|backend|ml-worker|repo|shared)\):\s+.{10,}$/i; + const branchRegex = /^(codex\/[a-z0-9-]+|(feat|fix|docs|chore|refactor|test|style|perf)\/(app|backend|ml-worker|repo|shared)\/[a-z0-9-]+)$/; - // ── Check 1: PR title format ───────────────────────────────────────── - const titleRegex = /^(feat|fix|docs|chore|refactor|test|style|perf)\((app|backend|ml-worker|repo)\): .{10,}$/; if (!titleRegex.test(title)) { - failures.push( - `**Invalid PR title:** \`${title}\` — must follow \`type(scope): description\` format where type is one of \`feat|fix|docs|chore|refactor|test|style|perf\`, scope is one of \`app|backend|ml-worker|repo\`, and description is at least 10 characters.` - ); - } - - // ── Check 2: PR body sections ──────────────────────────────────────── - const hasWhatChanged = /##\s*what changed/i.test(body); - const hasWhy = /##\s*why/i.test(body); - const hasHowToTest = /##\s*how to test/i.test(body); - if (!body.trim() || !hasWhatChanged || !hasWhy || !hasHowToTest) { - failures.push( - `**Missing PR description sections:** Your PR body must include all three headings: \`## What changed\`, \`## Why\`, and \`## How to test\`. Add them and fill them in.` - ); - } - - // ── Check 3: Linked issue ──────────────────────────────────────────── - const issueRegex = /(?:closes|fixes|resolves|relates to|ref)\s+#\d+/i; - if (!issueRegex.test(body)) { - failures.push( - `**No linked issue:** Reference the issue this PR addresses using \`closes #N\`, \`fixes #N\`, or \`relates to #N\`. Open an issue first if one doesn't exist.` - ); + failures.push("Use a title like `fix(app): handle empty room names`."); } - // ── Check 4: Target branch ─────────────────────────────────────────── if (baseRef !== "main") { - failures.push( - `**Wrong target branch:** This PR targets \`${baseRef}\` but all PRs must target \`main\`.` - ); + failures.push(`Target branch must be \`main\`, not \`${baseRef}\`.`); } - // ── Check 5: Branch name ───────────────────────────────────────────── - const branchRegex = /^(feat|fix|docs|chore|refactor|test|style|perf)\/(app|backend|ml-worker|repo|shared)\/[a-z0-9-]+$/; if (!branchRegex.test(headRef)) { - failures.push( - `**Invalid branch name:** \`${headRef}\` — must follow \`type/scope/short-description\` e.g. \`feat/app/timetable-progress\`.` - ); + failures.push("Use a branch like `codex/short-description` or `fix/app/short-description`."); + } + + const bodyHasSummary = /##\s*(summary|what changed)/i.test(body); + const bodyHasTesting = /##\s*(verification|how to test|testing)/i.test(body); + if (!body.trim() || !bodyHasSummary || !bodyHasTesting) { + failures.push("PR body must include summary and verification sections."); } - // ── Helper: safe label operations ─────────────────────────────────── async function addLabel(name) { try { await github.rest.issues.addLabels({ - owner, repo, issue_number: prNumber, + owner, + repo, + issue_number: prNumber, labels: [name], }); - } catch (e) { - // Label may not exist in the repo yet — skip silently - core.warning(`Could not add label "${name}": ${e.message}`); + } catch (error) { + core.warning(`Could not add label "${name}": ${error.message}`); } } async function removeLabel(name) { try { await github.rest.issues.removeLabel({ - owner, repo, issue_number: prNumber, + owner, + repo, + issue_number: prNumber, name, }); - } catch (e) { - // Label not present — ignore 404 + } catch (error) { + if (error.status !== 404) { + core.warning(`Could not remove label "${name}": ${error.message}`); + } } } - // ── All checks passed ──────────────────────────────────────────────── if (failures.length === 0) { await addLabel("ready-for-review"); await removeLabel("invalid-pr"); - console.log("✅ PR passed all validation checks."); + console.log("PR validation passed."); return; } - // ── Checks failed — build comment ──────────────────────────────────── - const bulletList = failures.map(f => `- ${f}`).join("\n"); - const comment = `## ❌ PR Validation Failed - -Hi @${author}, this PR was automatically closed because it does not follow Sentri's contribution guidelines. Please read [CONTRIBUTING.md](../blob/main/CONTRIBUTING.md) before re-submitting. - -### Issues found: - -${bulletList} - -### How to fix and reopen -1. Fix all issues listed above -2. Push your changes or edit the PR title/description -3. Reopen the PR — validation will run again automatically + await addLabel("invalid-pr"); + await removeLabel("ready-for-review"); ---- -_This check is automated. If you believe this is a mistake, ping a maintainer._`; + const message = [ + "## PR Validation Failed", + "", + "Please update this pull request before merge:", + "", + ...failures.map((failure) => `- ${failure}`), + ].join("\n"); - // Post comment await github.rest.issues.createComment({ - owner, repo, + owner, + repo, issue_number: prNumber, - body: comment, - }); - - // Apply / remove labels - await addLabel("invalid-pr"); - await removeLabel("ready-for-review"); - - // Close the PR - await github.rest.pulls.update({ - owner, repo, - pull_number: prNumber, - state: "closed", + body: message, }); - // Fail the job so the status check is red core.setFailed(`PR validation failed with ${failures.length} issue(s).`); diff --git a/.github/workflows/setup-labels.yml b/.github/workflows/setup-labels.yml index 2dfdd3a..7513dba 100644 --- a/.github/workflows/setup-labels.yml +++ b/.github/workflows/setup-labels.yml @@ -8,40 +8,46 @@ permissions: jobs: setup-labels: - name: Create repo labels + name: setup-labels runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - name: Create all Sentri labels + - name: Create labels uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const labels = [ - { name: "invalid-pr", color: "d73a4a", description: "PR does not follow contribution guidelines" }, - { name: "ready-for-review", color: "0075ca", description: "PR has passed all automated checks and is ready for human review" }, - { name: "area:app", color: "e4e669", description: "Changes to the Expo React Native frontend" }, - { name: "area:backend", color: "1d76db", description: "Changes to the Spring Boot backend" }, - { name: "area:ml-worker", color: "5319e7", description: "Changes to the Python OCR/ML worker" }, - { name: "area:repo", color: "0e8a16", description: "Repo-level changes: docs, CI, config" }, - { name: "type:feat", color: "a2eeef", description: "New feature" }, - { name: "type:fix", color: "d93f0b", description: "Bug fix" }, - { name: "type:docs", color: "c5def5", description: "Documentation only" }, - { name: "type:chore", color: "e4e4e4", description: "Maintenance, dependency updates, config" }, + { name: "invalid-pr", color: "d73a4a", description: "PR needs contribution fixes" }, + { name: "ready-for-review", color: "0075ca", description: "PR has passed repository validation" }, + { name: "area:app", color: "e4e669", description: "Expo React Native app changes" }, + { name: "area:backend", color: "1d76db", description: "Spring Boot backend changes" }, + { name: "area:ml-worker", color: "5319e7", description: "Python worker changes" }, + { name: "area:repo", color: "0e8a16", description: "Repository, docs, or CI changes" }, + { name: "type:feat", color: "a2eeef", description: "Feature change" }, + { name: "type:fix", color: "d93f0b", description: "Bug fix" }, + { name: "type:docs", color: "c5def5", description: "Documentation change" }, + { name: "type:chore", color: "e4e4e4", description: "Maintenance change" }, + { name: "type:refactor", color: "fbca04", description: "Refactor change" }, + { name: "type:test", color: "0e8a16", description: "Test change" }, + { name: "type:style", color: "bfd4f2", description: "Style change" }, + { name: "type:perf", color: "5319e7", description: "Performance change" }, ]; const owner = context.repo.owner; - const repo = context.repo.repo; + const repo = context.repo.repo; for (const label of labels) { try { - await github.rest.issues.createLabel({ owner, repo, ...label }); - console.log(`✅ Created: ${label.name}`); - } catch (e) { - if (e.status === 422) { - console.log(`⏭️ Already exists, skipping: ${label.name}`); - } else { - core.warning(`⚠️ Failed to create "${label.name}": ${e.message}`); + await github.rest.issues.getLabel({ owner, repo, name: label.name }); + await github.rest.issues.updateLabel({ owner, repo, name: label.name, ...label }); + console.log(`Updated label: ${label.name}`); + } catch (error) { + if (error.status !== 404) { + throw error; } + await github.rest.issues.createLabel({ owner, repo, ...label }); + console.log(`Created label: ${label.name}`); } } diff --git a/app/package.json b/app/package.json index 5c7522c..a3e69be 100644 --- a/app/package.json +++ b/app/package.json @@ -7,7 +7,9 @@ "android": "expo run:android", "ios": "expo run:ios", "web": "expo start --web", - "lint": "node scripts/check-jsx.mjs" + "lint": "node scripts/check-jsx.mjs", + "typecheck": "tsc --noEmit", + "build:web": "expo export --platform web --output-dir dist-web" }, "dependencies": { "@react-native-async-storage/async-storage": "2.2.0", From c6637d583be562326030d9e055f7ade6b4ba1e93 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Singh Date: Sat, 23 May 2026 18:52:31 +0530 Subject: [PATCH 2/2] fix(backend): restore verification build --- .../backend/service/TimetableBatchServiceImpl.java | 10 ++++++++++ .../backend/controller/IntelligenceControllerTest.java | 6 ++++++ .../backend/controller/MyspaceGraphControllerTest.java | 6 ++++++ .../backend/controller/MyspaceItemControllerTest.java | 6 ++++++ .../com/sentri/backend/service/AuthServiceTest.java | 10 ++++++++-- .../sentri/backend/service/HangoutRoomServiceTest.java | 5 ++++- .../backend/service/TimetableBatchServiceTest.java | 9 +++++++++ 7 files changed, 49 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/com/sentri/backend/service/TimetableBatchServiceImpl.java b/backend/src/main/java/com/sentri/backend/service/TimetableBatchServiceImpl.java index 06b4804..77c1110 100644 --- a/backend/src/main/java/com/sentri/backend/service/TimetableBatchServiceImpl.java +++ b/backend/src/main/java/com/sentri/backend/service/TimetableBatchServiceImpl.java @@ -116,6 +116,16 @@ public TimetableBatchDetailResponse saveParsedTimetable(Long batchId, ParsedTime return toDetailResponse(saved); } + @Override + @Transactional + @CacheEvict(cacheNames = {"timetableBatchSummaries", "timetableBatchDetails"}, allEntries = true) + public void deleteBatch(Long batchId) { + if (!timetableBatchRepository.existsById(batchId)) { + throw new ResourceNotFoundException("Timetable batch " + batchId + " was not found"); + } + timetableBatchRepository.deleteById(batchId); + } + private void applyMetadata(TimetableBatch batch, TimetableBatchMetadataRequest metadata) { if (metadata == null) { return; diff --git a/backend/src/test/java/com/sentri/backend/controller/IntelligenceControllerTest.java b/backend/src/test/java/com/sentri/backend/controller/IntelligenceControllerTest.java index a8d1e1f..1a2f0b9 100644 --- a/backend/src/test/java/com/sentri/backend/controller/IntelligenceControllerTest.java +++ b/backend/src/test/java/com/sentri/backend/controller/IntelligenceControllerTest.java @@ -3,10 +3,12 @@ import com.sentri.backend.dto.response.MyspaceSearchResponse; import com.sentri.backend.dto.response.MyspaceVectorMatchResponse; import com.sentri.backend.dto.response.MyspaceVectorSearchResponse; +import com.sentri.backend.repository.AuthSessionRepository; import com.sentri.backend.service.MyspaceIntelligenceService; import com.sentri.backend.service.MyspaceVectorStoreService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; @@ -22,6 +24,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(IntelligenceController.class) +@AutoConfigureMockMvc(addFilters = false) class IntelligenceControllerTest { @Autowired @@ -33,6 +36,9 @@ class IntelligenceControllerTest { @MockBean private MyspaceVectorStoreService myspaceVectorStoreService; + @MockBean + private AuthSessionRepository authSessionRepository; + @Test void upsertsMyspaceVectors() throws Exception { doNothing().when(myspaceVectorStoreService).upsertAll(any()); diff --git a/backend/src/test/java/com/sentri/backend/controller/MyspaceGraphControllerTest.java b/backend/src/test/java/com/sentri/backend/controller/MyspaceGraphControllerTest.java index c929cce..c00093d 100644 --- a/backend/src/test/java/com/sentri/backend/controller/MyspaceGraphControllerTest.java +++ b/backend/src/test/java/com/sentri/backend/controller/MyspaceGraphControllerTest.java @@ -1,9 +1,11 @@ package com.sentri.backend.controller; import com.sentri.backend.dto.response.MyspaceGraphRelatedItemResponse; +import com.sentri.backend.repository.AuthSessionRepository; import com.sentri.backend.service.MyspaceGraphService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; @@ -17,6 +19,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(MyspaceGraphController.class) +@AutoConfigureMockMvc(addFilters = false) class MyspaceGraphControllerTest { @Autowired @@ -25,6 +28,9 @@ class MyspaceGraphControllerTest { @MockBean private MyspaceGraphService myspaceGraphService; + @MockBean + private AuthSessionRepository authSessionRepository; + @Test void syncsAllItems() throws Exception { when(myspaceGraphService.isAvailable()).thenReturn(true); diff --git a/backend/src/test/java/com/sentri/backend/controller/MyspaceItemControllerTest.java b/backend/src/test/java/com/sentri/backend/controller/MyspaceItemControllerTest.java index 4745a27..c2fb131 100644 --- a/backend/src/test/java/com/sentri/backend/controller/MyspaceItemControllerTest.java +++ b/backend/src/test/java/com/sentri/backend/controller/MyspaceItemControllerTest.java @@ -3,9 +3,11 @@ import com.sentri.backend.dto.response.BulkMyspaceItemsResponse; import com.sentri.backend.dto.response.MyspaceItemResponse; import com.sentri.backend.dto.response.MyspaceSearchResponse; +import com.sentri.backend.repository.AuthSessionRepository; import com.sentri.backend.service.MyspaceIntelligenceService; import com.sentri.backend.service.MyspaceItemService; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -25,6 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(MyspaceItemController.class) +@AutoConfigureMockMvc(addFilters = false) class MyspaceItemControllerTest { @Autowired @@ -36,6 +39,9 @@ class MyspaceItemControllerTest { @MockBean private MyspaceIntelligenceService myspaceIntelligenceService; + @MockBean + private AuthSessionRepository authSessionRepository; + @Test void upsertsItem() throws Exception { when(myspaceItemService.upsert(any())).thenReturn(new MyspaceItemResponse( diff --git a/backend/src/test/java/com/sentri/backend/service/AuthServiceTest.java b/backend/src/test/java/com/sentri/backend/service/AuthServiceTest.java index 7198b36..7f75e50 100644 --- a/backend/src/test/java/com/sentri/backend/service/AuthServiceTest.java +++ b/backend/src/test/java/com/sentri/backend/service/AuthServiceTest.java @@ -37,7 +37,10 @@ void signsUpWithPhoneThenVerifiesAndRestoresSession() { "+91 98765 43210", null, "secret123", - "phone" + "phone", + "SE", + "IT", + "II" )); assertThat(signup.requiresOtp()).isTrue(); @@ -69,7 +72,10 @@ void signsUpWithEmailAndLogsInLater() { null, "aditi@example.com", "secret123", - "email" + "email", + "SE", + "IT", + "II" )); assertThat(signup.requiresOtp()).isFalse(); diff --git a/backend/src/test/java/com/sentri/backend/service/HangoutRoomServiceTest.java b/backend/src/test/java/com/sentri/backend/service/HangoutRoomServiceTest.java index 1689d9c..c4ad487 100644 --- a/backend/src/test/java/com/sentri/backend/service/HangoutRoomServiceTest.java +++ b/backend/src/test/java/com/sentri/backend/service/HangoutRoomServiceTest.java @@ -34,7 +34,10 @@ void createsRoomAndJoinsByCode() { "+91 98765 43210", null, "secret123", - "phone" + "phone", + "SE", + "IT", + "II" )); AuthResultResponse verified = authService.verifyOtp(new AuthVerifyOtpRequest( diff --git a/backend/src/test/java/com/sentri/backend/service/TimetableBatchServiceTest.java b/backend/src/test/java/com/sentri/backend/service/TimetableBatchServiceTest.java index 747945b..41bba4d 100644 --- a/backend/src/test/java/com/sentri/backend/service/TimetableBatchServiceTest.java +++ b/backend/src/test/java/com/sentri/backend/service/TimetableBatchServiceTest.java @@ -63,6 +63,15 @@ void createsPlaceholderBatchAndListsIt() { assertThat(timetableBatchService.listBatches().get(0).sourceImageName()).isEqualTo("timetable.png"); } + @Test + void deletesBatch() { + TimetableBatchDetailResponse created = timetableBatchService.createPlaceholderBatch(null); + + timetableBatchService.deleteBatch(created.id()); + + assertThat(timetableBatchRepository.findById(created.id())).isEmpty(); + } + @Test void savesParsedTimetableAndReplacesEntries() { TimetableBatchDetailResponse created = timetableBatchService.createPlaceholderBatch(null);