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

feat: allow deletion of all activities independent of status and distinguish between hard and soft deletion in backend #4294

Merged
merged 8 commits into from
Oct 5, 2024

Conversation

sjschlapbach
Copy link
Member

@sjschlapbach sjschlapbach commented Oct 4, 2024

This pull requests adds the following functionalities - potentially more detailed deletion modals with specific required confirmations follow on separate PRs for better readability:

  • Deletion of practice quizzes independent of state
    • If practice quiz is DRAFT / SCHEDULED -> hard deletion
    • If practice quiz is PUBLISHED, but does not have and responses linked to it -> hard deletion
    • If practice quiz is PUBLISHED and has responses linked to it -> soft deletion
  • Deletion of microlearnings independent of state
    • If microlearning is DRAFT / SCHEDULED -> hard deletion
    • If microlearning is PUBLISHED, but does not have and responses linked to it -> hard deletion
    • If microlearning is PUBLISHED and has responses linked to it -> soft deletion
  • Deletion of group activities independent of state
    • If group activity is DRAFT -> hard deletion
    • If group activity is PUBLISHED / GRADED with no instances linked to it -> hard deletion
    • If group activity is PUBLISHED / GRADED with instances linked to it -> soft deletion

Summary by CodeRabbit

Release Notes

  • New Features

    • Added deletion options for group activities, micro-learning elements, and practice quizzes within their respective dropdown menus, enhancing user experience.
    • Implemented soft deletion for quizzes and group activities, allowing users to manage content without permanent removal.
    • Enhanced filtering to ensure only non-deleted items are displayed in various contexts, improving data integrity.
  • Bug Fixes

    • Resolved issues related to visibility of deleted items in user interfaces.
  • Documentation

    • Updated seeding logic to reflect new attributes for courses and activities, ensuring accurate data representation in the system.

…inguish between hard and soft deletion in backend
Copy link

aviator-app bot commented Oct 4, 2024

Current Aviator status

Aviator will automatically update this comment as the status of the PR changes.
Comment /aviator refresh to force Aviator to re-examine your PR (or learn about other /aviator commands).

This PR was merged manually (without Aviator). Merging manually can negatively impact the performance of the queue. Consider using Aviator next time.


See the real-time status of this PR on the Aviator webapp.
Use the Aviator Chrome Extension to see the status of your PR within GitHub.

Copy link

coderabbitai bot commented Oct 4, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces a series of changes across various components and services related to course management. Key modifications include the implementation of deletion functionality through new deletionItem and deletionElement objects in the UI components, ensuring consistent handling of deletion across different states. Additionally, backend services have been updated to incorporate soft deletion logic, filtering out deleted items in queries, and enhancing error handling. The changes aim to improve the overall management of course elements, ensuring that only active items are processed and displayed.

Changes

File Path Change Summary
apps/frontend-manage/src/components/courses/*.tsx Introduced deletionItem or deletionElement objects in GroupActivityElement, MicroLearningElement, and PracticeQuizElement components to encapsulate deletion actions in dropdown menus, replacing inline definitions.
packages/graphql/src/services/courses.ts Added filtering for non-deleted items in getCourseSummary, getCourseData, and getControlCourse functions, ensuring only active entities are counted or retrieved.
packages/graphql/src/services/groups.ts Updated deleteGroupActivity for soft deletion logic and included checks for isDeleted in multiple functions to filter out deleted activities. Enhanced error handling and group activity management.
packages/graphql/src/services/microLearning.ts Implemented isDeleted checks in several functions to ensure only non-deleted micro-learning records are processed. Restructured deleteMicroLearning for soft deletion logic.
packages/graphql/src/services/participants.ts Enhanced participant profile update logic and added conditions to filter out deleted items in getParticipations and getPracticeQuizList functions.
packages/graphql/src/services/practiceQuizzes.ts Added isDeleted filtering in various queries and refactored deletePracticeQuiz for soft deletion, ensuring that deleted quizzes are not processed in operations.
packages/prisma/src/data/helpers.ts Updated prepareGroupActivityStack and prepareStackVariety functions to set default values for parameters, simplifying function calls.
packages/prisma/src/data/seedTEST.ts Modified seeding logic to include new attributes and refined decision-making for creating educational elements.
packages/prisma/src/prisma/schema/quiz.prisma Added isDeleted Boolean field to PracticeQuiz, MicroLearning, and GroupActivity models, defaulting to false to enable soft deletion functionality.
packages/prisma/src/prisma/migrations/*.sql Added isDeleted column to GroupActivity, MicroLearning, and PracticeQuiz tables in migration scripts to support soft deletion functionality.
cypress/cypress/e2e/H-practice-quiz-workflow.cy.ts Enhanced Cypress tests to include deletion functionality for practice quizzes, verifying that deleted quizzes are no longer accessible to students.

Possibly related PRs

Suggested reviewers

  • rschlaefli

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between ae666db and 78af6bc.

📒 Files selected for processing (3)
  • cypress/cypress/e2e/G-microlearning-workflow.cy.ts (5 hunks)
  • cypress/cypress/e2e/H-practice-quiz-workflow.cy.ts (5 hunks)
  • cypress/cypress/e2e/K-group-activity-workflow.cy.ts (1 hunks)
🔇 Additional comments (4)
cypress/cypress/e2e/K-group-activity-workflow.cy.ts (1)

Line range hint 1-819: LGTM! New deletion test enhances coverage, minor improvements suggested.

The changes in this file successfully implement a new test case for deleting group activities, which aligns well with the PR objectives. The new test fits seamlessly into the existing comprehensive test suite for group activity workflows.

While the implementation is generally good, I've suggested a few minor improvements:

  1. Adding more assertions to the deletion test for robustness.
  2. Considering some general enhancements to the overall test structure, including error handling, consistency, reusability, and cleanup.

These suggestions aim to further improve the quality and maintainability of the test suite. Overall, the changes are approved and ready for merging, subject to addressing the minor suggestions if deemed necessary.

cypress/cypress/e2e/H-practice-quiz-workflow.cy.ts (3)

66-66: LGTM: Force click added to course selection.

The addition of { force: true } to the course selection click action is a good practice. This ensures that the course can be selected even if the element is momentarily obscured or not immediately clickable, which can happen in dynamic web applications.


894-920: LGTM: Consistent implementation of deletion and verification steps.

This segment correctly implements the deletion and verification steps for the fourth test case, maintaining consistency with the previous implementations.

As mentioned in the previous comments:

  1. Consider adding a separating comment before the student verification steps (before line 907) to improve readability.
  2. Consider refactoring these repeated deletion and verification steps into a custom Cypress command, as suggested in the previous comment, to adhere to the DRY principle and improve maintainability.

These changes would significantly improve the overall structure and maintainability of your test suite.


Line range hint 1-920: Overall assessment: Well-implemented changes with room for minor improvements

The changes in this file effectively implement the deletion functionality for practice quizzes across multiple test cases, aligning well with the PR objectives. The consistency in implementation across different test cases is commendable.

Key points:

  1. Deletion steps are correctly implemented for both lecturer and student views.
  2. Verification steps ensure that deleted quizzes are no longer accessible.
  3. The use of { force: true } in course selection improves test reliability.

Suggestions for improvement:

  1. Add separating comments before student verification steps to enhance readability.
  2. Consider refactoring the repeated deletion and verification steps into a custom Cypress command to adhere to the DRY principle and improve maintainability.

These changes have significantly enhanced the test coverage for practice quiz lifecycles, including the new deletion functionality. With the suggested minor improvements, the code quality and maintainability of the test suite would be further optimized.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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.

@sjschlapbach sjschlapbach marked this pull request as draft October 4, 2024 21:47
@sjschlapbach sjschlapbach marked this pull request as ready for review October 4, 2024 21:52
Copy link

@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: 0

🧹 Outside diff range and nitpick comments (4)
packages/prisma/src/prisma/migrations/20241004214633_activity_soft_deletion_booleans/migration.sql (4)

1-2: LGTM! Consider adding an index for performance.

The addition of the isDeleted column to the GroupActivity table is correct and aligns with the PR objectives for implementing soft deletion. The BOOLEAN type, NOT NULL constraint, and default value of false are appropriate for this use case.

Consider adding an index on the isDeleted column to optimize queries that filter on this column:

CREATE INDEX idx_group_activity_is_deleted ON "GroupActivity" ("isDeleted");

This can improve performance when querying for non-deleted or deleted group activities.


4-5: LGTM! Consider adding an index for performance.

The addition of the isDeleted column to the MicroLearning table is correct and consistent with the implementation for the GroupActivity table. It aligns with the PR objectives for implementing soft deletion.

Consider adding an index on the isDeleted column to optimize queries that filter on this column:

CREATE INDEX idx_micro_learning_is_deleted ON "MicroLearning" ("isDeleted");

This can improve performance when querying for non-deleted or deleted microlearnings.


7-8: LGTM! Consider adding an index for performance.

The addition of the isDeleted column to the PracticeQuiz table is correct and consistent with the implementations for the GroupActivity and MicroLearning tables. It aligns with the PR objectives for implementing soft deletion.

Consider adding an index on the isDeleted column to optimize queries that filter on this column:

CREATE INDEX idx_practice_quiz_is_deleted ON "PracticeQuiz" ("isDeleted");

This can improve performance when querying for non-deleted or deleted practice quizzes.


1-8: Overall implementation looks good. Consider application logic implications.

The migration script successfully adds the isDeleted column to all three tables (GroupActivity, MicroLearning, and PracticeQuiz) consistently. This implementation aligns well with the PR objectives for implementing soft deletion.

Consider the following points for the application logic:

  1. Ensure that all queries in the application are updated to include a WHERE clause filtering out soft-deleted records (e.g., WHERE isDeleted = false) unless explicitly querying for deleted items.
  2. Implement a mechanism to periodically clean up soft-deleted records if necessary.
  3. Update any unique constraints or indexes that should not consider soft-deleted records.
  4. Consider implementing an audit trail for deletion operations to track when and by whom items were soft-deleted.

These considerations will help ensure that the soft deletion functionality is fully integrated into the application's behavior.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c6daf41 and cb02e7b.

📒 Files selected for processing (2)
  • packages/graphql/src/services/courses.ts (6 hunks)
  • packages/prisma/src/prisma/migrations/20241004214633_activity_soft_deletion_booleans/migration.sql (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/graphql/src/services/courses.ts

Copy link

cypress bot commented Oct 4, 2024

klicker-uzh    Run #3147

Run Properties:  status check passed Passed #3147  •  git commit 4fe85e074d ℹ️: Merge 78af6bc2c8c850bec8a7cf9c6fdf4c6e545fb289 into a99c2be78613c195a56eb715c4b3...
Project klicker-uzh
Branch Review soft-deletion-activities
Run status status check passed Passed #3147
Run duration 10m 16s
Commit git commit 4fe85e074d ℹ️: Merge 78af6bc2c8c850bec8a7cf9c6fdf4c6e545fb289 into a99c2be78613c195a56eb715c4b3...
Committer Julius Schlapbach
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 1
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 47
View all changes introduced in this branch ↗︎

Copy link
Member

@rschlaefli rschlaefli left a comment

Choose a reason for hiding this comment

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

Nice and logic looks good :) Maybe we can add a Cypress test that just deletes the quizzes that we have created in the other tests at the end?

Copy link

sonarqubecloud bot commented Oct 5, 2024

Copy link

@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.

Caution

Inline review comments failed to post

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (5)
cypress/cypress/e2e/K-group-activity-workflow.cy.ts (2)

309-319: New test case for deleting a group activity looks good, but consider adding assertions.

The new test case successfully demonstrates the deletion of a group activity after it has been created and published. This aligns well with the PR objectives of enhancing deletion functionalities. However, there are a few suggestions to improve the test:

  1. Consider adding an assertion to verify the success message after deletion.
  2. It might be beneficial to check if the activity is truly gone by attempting to find it again, expecting a failure.

Here's a suggested improvement:

    cy.get(`[data-cy="delete-groupActivity-${newName}"]`).click()
    cy.get(`[data-cy="confirm-delete-groupActivity"]`).click()
+   cy.get('[data-cy="success-message"]').should('contain', 'Group activity deleted successfully')
    cy.get(`[data-cy="groupActivity-actions-${newName}"]`).should('not.exist')
+   cy.get(`[data-cy="groupActivity-${newName}"]`).should('not.exist')

These additions will make the test more robust by ensuring the deletion was successful and the activity is no longer visible in the UI.


Line range hint 1-819: Overall test structure is solid, but consider enhancing error handling and consistency.

The test file provides comprehensive coverage for group activity workflows, including the new deletion functionality. However, there are a few general suggestions to improve the overall quality of the test suite:

  1. Error Handling: Consider adding more robust error handling throughout the tests. For example, use cy.on('uncaught:exception', ...) to handle any unexpected errors.

  2. Consistency: Ensure consistent naming conventions for data-cy attributes across all tests. This will make maintenance easier in the future.

  3. Reusability: Some common operations (like logging in, navigating to specific pages) are repeated across tests. Consider extracting these into custom Cypress commands to reduce duplication.

  4. Cleanup: After each test, especially the new deletion test, consider adding cleanup steps to ensure a consistent state for subsequent tests.

Here's an example of how you could implement a custom command for login:

// In cypress/support/commands.js
Cypress.Commands.add('loginUser', (username, password) => {
  cy.visit(Cypress.env('URL_STUDENT'))
  cy.get('[data-cy="username-field"]').type(username)
  cy.get('[data-cy="password-field"]').type(password)
  cy.get('[data-cy="submit-login"]').click()
  cy.wait(1000) // Consider using a more robust wait strategy
})

// In your test file
it('can send a message to the group', function () {
  cy.loginUser(Cypress.env('STUDENT_USERNAME'), Cypress.env('STUDENT_PASSWORD'))
  // Rest of the test...
})

Implementing these suggestions will improve the maintainability and robustness of your test suite.

cypress/cypress/e2e/H-practice-quiz-workflow.cy.ts (3)

209-236: LGTM: Deletion and verification steps added.

The new steps to delete the practice quiz and verify its inaccessibility are well-implemented and align with the PR objectives. The verification process is thorough, checking both the lecturer's view and the student's access.

Consider adding a comment before line 223 to clearly separate the lecturer actions from the student verification steps. This would improve readability:

 cy.get(`[data-cy="practice-quiz-actions-${practiceQuizName}"]`).should(
   'not.exist'
 )

+// Verify that the deleted quiz is no longer accessible to students
 // make sure that the practice quiz is no longer accessible to students
 cy.clearAllCookies()
 cy.visit(Cypress.env('URL_STUDENT'))

439-465: LGTM: Consistent implementation of deletion and verification steps.

This segment correctly implements the deletion and verification steps for another test case, maintaining consistency with the previous implementation. This consistency is good for code maintainability and readability.

As suggested in the previous comment, consider adding a separating comment before the student verification steps (before line 452) to improve readability.


660-686: LGTM: Consistent implementation of deletion and verification steps.

This segment correctly implements the deletion and verification steps for the third test case, maintaining consistency with the previous implementations.

Consider refactoring these repeated deletion and verification steps into a custom Cypress command to adhere to the DRY (Don't Repeat Yourself) principle. This would improve maintainability and reduce the chance of inconsistencies in future updates. For example:

// In commands.js
Cypress.Commands.add('deletePracticeQuizAndVerify', (quizName, quizDisplayName, courseName) => {
  // Lecturer deletion steps
  cy.loginLecturer()
  cy.get('[data-cy="courses"]').click()
  cy.findByText(courseName).click()
  cy.get('[data-cy="tab-practiceQuizzes"]').click()
  cy.get(`[data-cy="practice-quiz-actions-${quizName}"]`).click()
  cy.get(`[data-cy="delete-practice-quiz-${quizName}"]`).click()
  cy.get(`[data-cy="confirm-delete-practice-quiz"]`).click()
  cy.get(`[data-cy="practice-quiz-actions-${quizName}"]`).should('not.exist')

  // Student verification steps
  cy.loginStudent()
  cy.get('[data-cy="quizzes"]').click()
  cy.get(`[data-cy="practice-quiz-${quizDisplayName}"]`).should('not.exist')
})

// In the test file
cy.deletePracticeQuizAndVerify(practiceQuizName2, practiceQuizDisplayName2, courseName)

This refactoring would significantly reduce code duplication across your test cases.

🛑 Comments failed to post (6)
cypress/cypress/e2e/G-microlearning-workflow.cy.ts (6)

327-337: 🛠️ Refactor suggestion

Refactor microlearning deletion steps into a custom Cypress command

The steps to delete a microlearning as a lecturer are repeated across multiple tests. To improve maintainability and reduce code duplication, consider creating a custom Cypress command or helper function for this process.

For example, you can add the following custom command in your cypress/support/commands.js:

Cypress.Commands.add('deleteMicrolearning', (microlearningName) => {
  cy.clearAllCookies()
  cy.loginLecturer()
  cy.get('[data-cy="courses"]').click()
  cy.findByText(courseName).click()
  cy.get('[data-cy="tab-microLearnings"]').click()
  cy.get(`[data-cy="microlearning-actions-${microlearningName}"]`).click()
  cy.get(`[data-cy="delete-microlearning-${microlearningName}"]`).click()
  cy.get('[data-cy="confirm-delete-microlearning"]').click()
  cy.get(`[data-cy="microlearning-actions-${microlearningName}"]`).should('not.exist')
})

Then, in your test file, you can simply call:

cy.deleteMicrolearning(microLearningName)

340-350: 🛠️ Refactor suggestion

Refactor student login steps into a custom Cypress command

The steps to log in as a student are repeated across multiple tests. Consider creating a custom Cypress command to encapsulate this logic, enhancing maintainability and reducing code duplication.

For example, add the following to your cypress/support/commands.js:

Cypress.Commands.add('loginStudent', () => {
  cy.clearAllCookies()
  cy.visit(Cypress.env('URL_STUDENT'))
  cy.get('[data-cy="username-field"]')
    .click()
    .type(Cypress.env('STUDENT_USERNAME'))
  cy.get('[data-cy="password-field"]')
    .click()
    .type(Cypress.env('STUDENT_PASSWORD'))
  cy.get('[data-cy="submit-login"]').click()
})

Then, replace the login steps in your test with:

cy.loginStudent()

464-470: 🛠️ Refactor suggestion

Refactor microlearning deletion steps into a custom Cypress command

The deletion steps here duplicate code used elsewhere. Consider using the cy.deleteMicrolearning() command to streamline your tests.


571-582: 🛠️ Refactor suggestion

Refactor microlearning deletion steps into a custom Cypress command

Again, you're repeating the deletion logic. Using a custom command like cy.deleteMicrolearning(microLearningName) can improve code readability.


854-880: 🛠️ Refactor suggestion

Refactor microlearning deletion and student login into custom commands

The code for deleting a microlearning and logging in as a student is repeated. To enhance maintainability, consider using the cy.deleteMicrolearning() and cy.loginStudent() custom commands.


1429-1454: 🛠️ Refactor suggestion

Refactor microlearning deletion and student login into custom commands

The deletion and student login steps are duplicated here. Utilizing custom commands will reduce redundancy and ease future maintenance.

@sjschlapbach sjschlapbach merged commit 6d47105 into v3 Oct 5, 2024
11 of 14 checks passed
@sjschlapbach sjschlapbach deleted the soft-deletion-activities branch October 5, 2024 12:51
Copy link

cypress bot commented Oct 5, 2024

klicker-uzh    Run #3148

Run Properties:  status check passed Passed #3148  •  git commit 6d47105285: feat: allow deletion of all activities independent of status and distinguish bet...
Project klicker-uzh
Branch Review v3
Run status status check passed Passed #3148
Run duration 09m 48s
Commit git commit 6d47105285: feat: allow deletion of all activities independent of status and distinguish bet...
Committer Julius Schlapbach
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 2
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 47
View all changes introduced in this branch ↗︎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants