Skip to content

feat(logout): add logout button and tests #37

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

Merged
merged 1 commit into from
Mar 18, 2025

Conversation

DevanB
Copy link
Owner

@DevanB DevanB commented Mar 18, 2025

Summary by CodeRabbit

  • New Features

    • Added a logout button to the Dashboard, allowing users to end their session quickly and securely.
  • Tests

    • Strengthened test coverage for login and logout processes to ensure a reliable and seamless user experience.
    • Introduced functional tests for user session management, including login and logout scenarios.

@DevanB DevanB linked an issue Mar 18, 2025 that may be closed by this pull request
Copy link

coderabbitai bot commented Mar 18, 2025

Walkthrough

The pull request introduces a logout option in the dashboard by adding a Link element from the @inertiajs/react package that navigates to the /logout route using the HTTP DELETE method. Additionally, tests have been updated and added in both controller and system test files to verify the login and logout functionalities with valid and invalid credentials, ensuring proper session creation, redirection, and destruction.

Changes

Files Change Summary
app/frontend/.../Dashboard.tsx Added import for Link from @inertiajs/react and inserted a logout button that sends a DELETE request to /logout in the Dashboard component.
test/controllers/sessions_controller_test.rb Enhanced session management tests by adding tests for login (valid/invalid) and logout, including assertions for session count and redirection.
test/system/sessions_test.rb Restructured tests for user session management, added tests for logging in and out, and introduced a setup block for user fixtures.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant D as Dashboard
    participant S as Server
    U->>D: Click "Log Out" button
    D->>S: Send DELETE request to /logout
    S-->>U: Respond with redirect to login page
Loading
sequenceDiagram
    participant U as User
    participant L as LoginPage
    participant S as Server
    U->>L: Visit login page
    U->>L: Enter credentials
    L->>S: POST credentials to /sessions
    S-->>U: Respond with dashboard redirection on success
Loading

Possibly related PRs

Poem

I'm a bunny, hopping through the code,
Where logout links and tests are bestowed.
I nibble on bugs with each clever line,
Login and logout now perfectly align.
With tiny paws and a carrot cheer,
I celebrate changes from ear to ear! 🐰🥕

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 RuboCop (1.73)
test/controllers/sessions_controller_test.rb

[!] There was an error parsing Gemfile: windows is not a valid platform. The available options are: [:ruby, :ruby_18, :ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24, :ruby_25, :ruby_26, :mri, :mri_18, :mri_19, :mri_20, :mri_21, :mri_22, :mri_23, :mri_24, :mri_25, :mri_26, :rbx, :truffleruby, :jruby, :jruby_18, :jruby_19, :mswin, :mswin_18, :mswin_19, :mswin_20, :mswin_21, :mswin_22, :mswin_23, :mswin_24, :mswin_25, :mswin_26, :mswin64, :mswin64_19, :mswin64_20, :mswin64_21, :mswin64_22, :mswin64_23, :mswin64_24, :mswin64_25, :mswin64_26, :mingw, :mingw_18, :mingw_19, :mingw_20, :mingw_21, :mingw_22, :mingw_23, :mingw_24, :mingw_25, :mingw_26, :x64_mingw, :x64_mingw_20, :x64_mingw_21, :x64_mingw_22, :x64_mingw_23, :x64_mingw_24, :x64_mingw_25, :x64_mingw_26]. Bundler cannot continue.

from /Gemfile:20

-------------------------------------------

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem

gem "tzinfo-data", platforms: %i[ windows jruby ]

-------------------------------------------

/usr/lib/ruby/3.1.0/bundler/dsl.rb:357:in block in normalize_options' /usr/lib/ruby/3.1.0/bundler/dsl.rb:355:in each'
/usr/lib/ruby/3.1.0/bundler/dsl.rb:355:in normalize_options' /usr/lib/ruby/3.1.0/bundler/dsl.rb:100:in gem'
/Gemfile:20:in eval_gemfile' /usr/lib/ruby/3.1.0/bundler/dsl.rb:49:in instance_eval'
/usr/lib/ruby/3.1.0/bundler/dsl.rb:49:in eval_gemfile' /usr/lib/ruby/3.1.0/bundler/dsl.rb:12:in evaluate'
/usr/lib/ruby/3.1.0/bundler/definition.rb:38:in build' /usr/lib/ruby/3.1.0/bundler.rb:197:in definition'
/usr/lib/ruby/3.1.0/bundler.rb:180:in load' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:295:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:83:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:81:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:81:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:75:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:75:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader.rb:67:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:160:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:47:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:81:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:43:in run' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/exe/rubocop:19:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'

test/system/sessions_test.rb

[!] There was an error parsing Gemfile: windows is not a valid platform. The available options are: [:ruby, :ruby_18, :ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24, :ruby_25, :ruby_26, :mri, :mri_18, :mri_19, :mri_20, :mri_21, :mri_22, :mri_23, :mri_24, :mri_25, :mri_26, :rbx, :truffleruby, :jruby, :jruby_18, :jruby_19, :mswin, :mswin_18, :mswin_19, :mswin_20, :mswin_21, :mswin_22, :mswin_23, :mswin_24, :mswin_25, :mswin_26, :mswin64, :mswin64_19, :mswin64_20, :mswin64_21, :mswin64_22, :mswin64_23, :mswin64_24, :mswin64_25, :mswin64_26, :mingw, :mingw_18, :mingw_19, :mingw_20, :mingw_21, :mingw_22, :mingw_23, :mingw_24, :mingw_25, :mingw_26, :x64_mingw, :x64_mingw_20, :x64_mingw_21, :x64_mingw_22, :x64_mingw_23, :x64_mingw_24, :x64_mingw_25, :x64_mingw_26]. Bundler cannot continue.

from /Gemfile:20

-------------------------------------------

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem

gem "tzinfo-data", platforms: %i[ windows jruby ]

-------------------------------------------

/usr/lib/ruby/3.1.0/bundler/dsl.rb:357:in block in normalize_options' /usr/lib/ruby/3.1.0/bundler/dsl.rb:355:in each'
/usr/lib/ruby/3.1.0/bundler/dsl.rb:355:in normalize_options' /usr/lib/ruby/3.1.0/bundler/dsl.rb:100:in gem'
/Gemfile:20:in eval_gemfile' /usr/lib/ruby/3.1.0/bundler/dsl.rb:49:in instance_eval'
/usr/lib/ruby/3.1.0/bundler/dsl.rb:49:in eval_gemfile' /usr/lib/ruby/3.1.0/bundler/dsl.rb:12:in evaluate'
/usr/lib/ruby/3.1.0/bundler/definition.rb:38:in build' /usr/lib/ruby/3.1.0/bundler.rb:197:in definition'
/usr/lib/ruby/3.1.0/bundler.rb:180:in load' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:295:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:83:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:81:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:81:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:75:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader_resolver.rb:75:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_loader.rb:67:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:160:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:47:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:81:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.73.0/lib/rubocop/cli.rb:43:in run' /var/lib/gems/3.1.0/gems/rubocop-1.73.0/exe/rubocop:19:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 generate docstrings to generate docstrings for this 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.

@DevanB DevanB force-pushed the 23-add-logout-functionality branch from 7d8381a to aa4b6d9 Compare March 18, 2025 20:02
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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b2a9ca4 and aa4b6d9.

📒 Files selected for processing (3)
  • app/frontend/pages/AppPage/Dashboard.tsx (1 hunks)
  • test/controllers/sessions_controller_test.rb (1 hunks)
  • test/system/sessions_test.rb (1 hunks)
🔇 Additional comments (8)
app/frontend/pages/AppPage/Dashboard.tsx (2)

2-2: Well structured import addition.

The import of Link from @inertiajs/react allows the Dashboard component to handle navigation with proper HTTP method support.


10-10: Correctly implemented logout button.

The implementation follows best practices:

  • Uses as="button" for proper semantics and accessibility
  • Correctly specifies method="delete" for the logout action
  • Provides clear "Log Out" text for the user
test/system/sessions_test.rb (3)

4-6: Good use of setup for test data reuse.

The setup block efficiently initializes the user fixture that will be used across multiple tests, following DRY principles.


8-18: Well-structured login test with clear assertions.

The test thoroughly validates the login flow by:

  • Visiting the login page
  • Filling in credentials
  • Verifying both the success message and correct redirection path

This covers both the UI feedback and the navigation behavior expected after login.


20-28: Complete logout test covering the full user flow.

This test effectively validates the logout functionality by:

  1. First logging in the user
  2. Clicking the logout button
  3. Verifying both the success message and redirect behavior

Good job ensuring both the UI feedback and navigation behavior are tested.

test/controllers/sessions_controller_test.rb (3)

8-11: Simple and effective login page test.

The test correctly verifies that the login page is accessible and returns a successful response.


13-19: Good test for successful login.

The test effectively:

  • Verifies that a new session is created using assert_difference
  • Confirms proper redirection to the dashboard after login

21-25: Important negative test case for invalid login.

This test is crucial for security as it verifies that no session is created when invalid credentials are provided.

Comment on lines 27 to 35
test "should log out" do
post sessions_path, params: { email_address: @user.email_address, password: "password" }

assert_difference("Session.count", -1) do
delete delete_session_path(@user)
end

assert_redirected_to new_session_path
end
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify parameter usage in the logout path.

The test correctly verifies session destruction and redirection, but check if passing @user to delete_session_path is intentional.

Most logout implementations don't require a user parameter since they operate on the current session.


🏁 Script executed:

#!/bin/bash
# Check the route definition for delete_session_path
grep -r "delete_session" --include="*.rb" config/routes.rb

Length of output: 119


Clarify parameter usage on logout route.

The test is asserting that the session is correctly destroyed and redirection is performed, which is great. However, the route definition for delete_session_path is:

delete "logout" => "sessions#destroy", as: :delete_session

This route doesn't require any parameters, so passing @user appears unnecessary. Please verify if this extra parameter is intentional. If not required, remove @user from the call to avoid potential confusion and ensure consistency with the route definition.

@DevanB DevanB force-pushed the 23-add-logout-functionality branch from aa4b6d9 to cc230ae Compare March 18, 2025 20:10
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

🧹 Nitpick comments (1)
test/controllers/sessions_controller_test.rb (1)

21-25: Consider adding response verification.

While the test correctly verifies that no session is created with invalid credentials, it doesn't check what happens afterward. Consider adding assertions to verify either a redirection or an appropriate response status.

  test "should not log in with invalid credentials" do
    assert_no_difference("Session.count") do
      post sessions_path, params: { email_address: @user.email_address, password: "wrong_password" }
    end
+   
+   # Verify the response - either a redirect back to login page or render with errors
+   assert_response :unprocessable_entity
+   # Or
+   # assert_redirected_to new_session_path
  end
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa4b6d9 and cc230ae.

📒 Files selected for processing (3)
  • app/frontend/pages/AppPage/Dashboard.tsx (1 hunks)
  • test/controllers/sessions_controller_test.rb (1 hunks)
  • test/system/sessions_test.rb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/frontend/pages/AppPage/Dashboard.tsx
🔇 Additional comments (7)
test/system/sessions_test.rb (4)

25-25: Verify element type for logout action.

There appears to be a potential mismatch between this test and the implementation. The test is looking for a "Log Out" button, but according to the PR summary, the implementation uses a Link component from @inertiajs/react. Ensure the element type in the test matches what's actually rendered in the UI to prevent test failures.


8-18: LGTM! Well-structured login test.

This test effectively verifies the complete login flow, including form submission and post-login state verification.


20-28: LGTM! Well-structured logout test.

The test properly verifies the logout workflow by first logging in, then performing the logout action, and finally verifying the post-logout state.


4-6: LGTM! Good test setup.

The setup method correctly initializes test data using fixtures, following Rails testing conventions.

test/controllers/sessions_controller_test.rb (3)

8-10: LGTM! Simple and effective test.

This test correctly verifies that the login page is accessible.


13-19: LGTM! Great session verification.

This test effectively verifies both session creation and proper redirection after successful login.


27-34: LGTM! Comprehensive logout test.

This test effectively verifies session destruction and proper redirection after logout.

@DevanB DevanB merged commit 9c3ff31 into master Mar 18, 2025
4 checks passed
@DevanB DevanB deleted the 23-add-logout-functionality branch March 18, 2025 20: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.

Add logout functionality
1 participant