Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

delete repository inline #2396

Merged
merged 5 commits into from
Nov 16, 2024
Merged

delete repository inline #2396

merged 5 commits into from
Nov 16, 2024

Conversation

rohitpaulk
Copy link
Member

@rohitpaulk rohitpaulk commented Nov 13, 2024

  • add repo id
  • Update delete repository modal to redirect to course introduction after deletion.

Summary by CodeRabbit

  • New Features

    • Enhanced routing logic to navigate to course details based on the last used repository.
    • Improved visual feedback during deletion with a dynamic button label.
  • Bug Fixes

    • Prevented multiple deletion attempts by introducing a state check.
  • Tests

    • Updated acceptance tests to reflect new navigation flow and repository count after deletion.
    • Enhanced tests for the delete repository modal to cover various submission count scenarios.

Copy link
Contributor

coderabbitai bot commented Nov 13, 2024

Walkthrough

The pull request introduces several changes primarily focused on enhancing the functionality and user feedback of the course management components. Key modifications include updates to the routing logic in the CourseCardComponent to utilize the last used repository's ID and improvements to the DeleteRepositoryModalComponent that add a deletion state indicator. Additionally, acceptance tests have been adjusted to reflect these changes, ensuring proper navigation and UI state after repository deletions.

Changes

File Path Change Summary
app/components/course-card.js Updated linkToRoute getter to change the query parameter from { fresh: null } to { repo: null }.
app/components/course-page/delete-repository-modal.hbs Modified button label in DangerButtonWithTimedConfirmation to conditionally display "Deleting..." based on this.isDeleting state.
app/components/course-page/delete-repository-modal.ts Added @tracked isDeleting property to prevent multiple deletions. Updated deleteRepository method to check isDeleting before proceeding. Changed routing to transition to 'course.introduction' after deletion.
tests/acceptance/course-page/delete-repository-test.js Enhanced acceptance tests for delete functionality, including updated URL assertions and new checks for repository count and modal message display under various conditions.

Possibly related PRs

🐇 In the meadow, changes bloom bright,
Course cards now link with delight.
Deleting with care, a button's new face,
Navigating smoothly, we quicken our pace.
Tests now ensure our paths are clear,
In CodeRabbit's world, we have nothing to fear! 🐰✨


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

github-actions bot commented Nov 13, 2024

Test Results

  1 files  ±0    1 suites  ±0   6m 18s ⏱️ - 2m 36s
582 tests ±0  542 ✅ ±0  40 💤 ±0  0 ❌ ±0 
597 runs  ±0  557 ✅ ±0  40 💤 ±0  0 ❌ ±0 

Results for commit 53b3f40. ± Comparison against base commit 748991a.

♻️ This comment has been updated with latest results.

Copy link

codecov bot commented Nov 13, 2024

Codecov Report

Attention: Patch coverage is 66.66667% with 2 lines in your changes missing coverage. Please review.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../components/course-page/delete-repository-modal.ts 66.66% 1 Missing and 1 partial ⚠️
Additional details and impacted files

📢 Thoughts on this report? Let us know!

Copy link

codecov bot commented Nov 13, 2024

Bundle Report

Changes will increase total bundle size by 2.13kB (0.01%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
client-array-push 35.84MB 2.13kB (0.01%) ⬆️

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
app/components/course-page/delete-repository-modal.ts (1)

Line range hint 27-30: Remove redundant null check

Since repository is required in the component's interface (Args type), this null check is redundant and can be removed.

  @action
  async deleteRepository() {
-    if (!this.args.repository) {
-      return;
-    }
app/components/course-page/delete-repository-modal.hbs (1)

36-40: LGTM! Consider enhancing accessibility and UX.

The conditional rendering provides clear user feedback during the deletion process. Consider these improvements:

 <DangerButtonWithTimedConfirmation 
   @onConfirm={{this.deleteRepository}} 
   @size="regular" 
+  disabled={{this.isDeleting}}
+  aria-busy={{this.isDeleting}}
   data-test-delete-repository-button
 >
   {{#if this.isDeleting}}
     Deleting...
   {{else}}
     Delete
   {{/if}}
 </DangerButtonWithTimedConfirmation>
tests/acceptance/course-page/delete-repository-test.js (1)

154-159: LGTM! Consider adding a test for repository ID.

The test changes look good and properly verify:

  1. Redirection to the course introduction page with correct query parameters
  2. UI state after deletion (repository count and available actions)

Since the PR objectives mention the addition of a repository ID, consider adding an assertion to verify the repository ID is properly cleared/reset after deletion.

 await waitUntil(() => currentURL() === '/courses/dummy/introduction?repo=new&track=python');
 await settled(); // Delete request triggers after redirect

 await coursePage.repositoryDropdown.click();
 assert.strictEqual(coursePage.repositoryDropdown.content.nonActiveRepositoryCount, 0, 'no repositories should be available');
 assert.notOk(coursePage.repositoryDropdown.content.text.includes('Delete Repository'), 'delete repository action should not be available');
+// Verify repository ID is cleared
+assert.notOk(coursePage.repositoryDropdown.content.text.includes('repository-id'), 'repository ID should be cleared after deletion');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 748991a and ab37245.

📒 Files selected for processing (4)
  • app/components/course-card.js (1 hunks)
  • app/components/course-page/delete-repository-modal.hbs (1 hunks)
  • app/components/course-page/delete-repository-modal.ts (3 hunks)
  • tests/acceptance/course-page/delete-repository-test.js (1 hunks)
🔇 Additional comments (6)
app/components/course-card.js (2)

49-49: LGTM! Query parameter change aligns with PR objectives.

The change from using a generic parameter to explicitly including the repository ID (repo: this.lastUsedRepository.id) improves the routing logic and supports the new repository deletion workflow.

Let's verify the integration with the delete repository modal:

✅ Verification successful

Query parameter change is consistent with repository handling across components

The verification confirms that:

  • The lastUsedRepository.id is properly accessed in the course-card component
  • Other components (delete-repository-modal and repository-dropdown) consistently use the repo query parameter for routing
  • The pattern aligns with the repository-centric navigation flow
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the consistency of repository ID usage across components
# Expected: Find matching usage of repo parameter in delete repository modal

# Search for repository ID usage in routing logic
rg -A 5 "transitionTo.*course.*introduction.*repo" app/components/

# Search for repository parameter handling in routes
ast-grep --pattern 'queryParams.*repo'

Length of output: 1649


Script:

#!/bin/bash
# Let's verify the route definition and query param handling

# Search for route definitions related to course.introduction
rg -A 5 "course\.introduction" app/routes/

# Search for query param declarations in route files
ast-grep --pattern 'queryParams = [$$$]'

# Search for lastUsedRepository usage to verify its availability
rg "lastUsedRepository" app/components/course-card.js -A 3

Length of output: 432


Line range hint 46-53: Verify handling of edge cases in repository state transitions.

While the implementation looks correct, please ensure proper handling of these scenarios:

  1. Repository deletion state: Verify the behavior when lastUsedRepository references a recently deleted repository
  2. Loading state: Confirm there are no race conditions between repository deletion and route transition

Let's check for error handling in related components:

app/components/course-page/delete-repository-modal.ts (3)

8-8: LGTM: Well-structured state management addition

The addition of the tracked property for managing deletion state is well-implemented and properly typed.

Also applies to: 20-20


31-36: LGTM: Good concurrent deletion prevention

The isDeleting flag effectively prevents multiple concurrent deletion attempts.


39-39: Verify the navigation behavior

The transition includes query parameters that might affect the course introduction page's behavior.

Let's verify the navigation handling:

✅ Verification successful

Navigation behavior is properly handled

The verification shows that:

  • The query parameters repo and track are properly defined in the course controller (app/controllers/course.ts)
  • The course route (app/routes/course.ts) has explicit handling for both repo and track query parameters
  • The navigation pattern is consistent with other components in the codebase:
    • repository-dropdown.ts uses the same transition pattern
    • Multiple components handle these query parameters similarly for repository and track selection

The transition behavior in the delete-repository-modal is consistent with the codebase's navigation patterns and query parameter handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for course.introduction route definition and its handling of query parameters

# Search for route definition
rg -A 5 "course\.introduction" app/router.js

# Search for query params handling in the introduction route
ast-grep --pattern 'class IntroductionRoute {
  $$$
  queryParams = {
    $$$
  }
  $$$
}'

Length of output: 193


Script:

#!/bin/bash
# Let's try different approaches to find route and query params handling

# Find router.js file first as it might be in a different location
fd router.js

# Search for introduction route handling across the codebase
rg -g '!*.{json,lock}' -i "course\.introduction"

# Look for query params handling specifically for repo and track
rg -g '!*.{json,lock}' "queryParams.*(?:repo|track)"

# Search for route files related to introduction
fd -g "*introduction*route*.{js,ts}"

Length of output: 3347

app/components/course-page/delete-repository-modal.hbs (1)

36-40: Verify routing behavior after deletion.

The AI summary indicates that after deletion, users should be redirected to the course introduction page. Let's verify this implementation:

✅ Verification successful

Routing behavior after deletion is correctly implemented

The code inspection confirms that the routing behavior matches the AI summary:

  • The DeleteRepositoryModalComponent includes the correct routing logic to transition to 'course.introduction' with the specified query parameters (repo: 'new', track: trackSlug).
  • The implementation is verified by acceptance tests in tests/acceptance/course-page/delete-repository-test.js which cover both the modal opening and repository deletion scenarios.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the routing logic implementation in the component and tests

# Check component implementation
echo "Checking DeleteRepositoryModalComponent implementation..."
rg -A 10 "deleteRepository.*=" "app/components/course-page/"

# Verify test expectations
echo "Checking test assertions..."
rg -A 5 "course\.introduction" "tests/acceptance/"

Length of output: 2716


Script:

#!/bin/bash
# Let's check the component implementation and test files more thoroughly

# Check the delete repository modal component implementation
echo "Checking DeleteRepositoryModal component implementation..."
rg -A 15 "class DeleteRepositoryModal" app/components/course-page/

# Check for any transition/redirect logic in the component
echo "Checking for transition/redirect logic..."
rg -A 10 "transition|redirect" app/components/course-page/delete-repository-modal.ts

# Look for the deleteRepository action implementation
echo "Looking for deleteRepository action..."
ast-grep --pattern 'deleteRepository = async function() { $$$ }'

# Check test files for delete repository scenarios
echo "Checking test files for delete repository scenarios..."
rg -A 10 "test.*delete.*repository" tests/

Length of output: 6298

Comment on lines +37 to +38
const trackSlug = this.args.repository.language?.slug; // Store this before we destroy the record
await this.args.repository.destroyRecord(); // TODO: Add failure handling
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling and null checks

Two concerns in the deletion logic:

  1. The TODO comment indicates missing error handling for destroyRecord()
  2. The trackSlug derivation doesn't handle the case where language is null

Consider implementing this safer version:

-    const trackSlug = this.args.repository.language?.slug; // Store this before we destroy the record
-    await this.args.repository.destroyRecord(); // TODO: Add failure handling
+    const trackSlug = this.args.repository.language?.slug || 'unknown';
+    try {
+      await this.args.repository.destroyRecord();
+    } catch (error) {
+      // Handle error (e.g., show error message to user)
+      this.isDeleting = false;
+      throw error;
+    }

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ab37245 and 53b3f40.

📒 Files selected for processing (2)
  • app/components/course-card.js (1 hunks)
  • app/components/course-page/delete-repository-modal.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/components/course-card.js
🧰 Additional context used
🪛 GitHub Check: codecov/patch
app/components/course-page/delete-repository-modal.ts

[warning] 32-32: app/components/course-page/delete-repository-modal.ts#L32
Added line #L32 was not covered by tests

🔇 Additional comments (2)
app/components/course-page/delete-repository-modal.ts (2)

7-7: LGTM! Good use of tracked property

The addition of @tracked isDeleting is a good practice to prevent concurrent deletions and manage the component's state.

Also applies to: 19-19


36-38: ⚠️ Potential issue

Improve error handling and state management

Several improvements needed for robustness:

  1. The trackSlug could be undefined if language is null
  2. The navigation could fail
  3. The isDeleting state isn't reset on error

Consider this safer implementation:

-    const trackSlug = this.args.repository.language?.slug; // Store this before we destroy the record
-    await this.args.repository.destroyRecord(); // TODO: Add failure handling
-    this.router.transitionTo('course.introduction', { queryParams: { repo: 'new', track: trackSlug } }).followRedirects();
+    const trackSlug = this.args.repository.language?.slug ?? 'unknown';
+    try {
+      await this.args.repository.destroyRecord();
+      await this.router.transitionTo('course.introduction', { 
+        queryParams: { repo: 'new', track: trackSlug } 
+      }).followRedirects();
+    } catch (error) {
+      this.isDeleting = false;
+      // TODO: Show error message to user
+      throw error;
+    }

Likely invalid or redundant comment.

Comment on lines +30 to +35
if (this.isDeleting) {
return;
}

this.isDeleting = true;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Add test for concurrent deletion prevention

The test suite lacks coverage for the concurrent deletion prevention logic (isDeleting flag). The existing tests only verify basic deletion flow but don't test the protection against multiple deletion attempts. Add a test case that:

  • Triggers multiple delete clicks in quick succession
  • Verifies only one deletion request is made
  • Confirms the repository is deleted successfully

Example test:

test('prevents concurrent deletion attempts', async function (assert) {
  // ... setup code ...
  
  await coursePage.deleteRepositoryModal.deleteRepositoryButton.press();
  await coursePage.deleteRepositoryModal.deleteRepositoryButton.press(); // Second click should be ignored
  
  assert.strictEqual(server.schema.repositories.all().length, 0, 'repository should be deleted once');
});
🔗 Analysis chain

Add test coverage for concurrent deletion prevention

The concurrent deletion prevention logic is not covered by tests. This is important functionality that should be verified.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for existing tests of concurrent deletion prevention

# Look for test files related to delete repository
fd "delete-repository.*test" -t f

# Search for concurrent deletion tests in found files
rg -l "concurrent|multiple.*deletion|isDeleting" $(fd "delete-repository.*test" -t f)

Length of output: 233


Script:

#!/bin/bash
# Let's examine the actual test content to verify coverage
cat tests/acceptance/course-page/delete-repository-test.js

# Also check the component implementation for complete context
cat app/components/course-page/delete-repository-modal.ts

Length of output: 8523

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 32-32: app/components/course-page/delete-repository-modal.ts#L32
Added line #L32 was not covered by tests

@rohitpaulk rohitpaulk merged commit 3a94ecc into main Nov 16, 2024
7 of 9 checks passed
@rohitpaulk rohitpaulk deleted the delete-repository-inline branch November 16, 2024 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant