Skip to content

updated code so that "now i want to teach class form" don't require email or captcha if the user is logged in#535

Merged
A1L13N merged 2 commits into
alphaonelabs:mainfrom
IITI-tushar:fixes-526
Apr 19, 2025
Merged

updated code so that "now i want to teach class form" don't require email or captcha if the user is logged in#535
A1L13N merged 2 commits into
alphaonelabs:mainfrom
IITI-tushar:fixes-526

Conversation

@IITI-tushar
Copy link
Copy Markdown
Contributor

@IITI-tushar IITI-tushar commented Apr 11, 2025

fixes: issue#526

Summary by CodeRabbit

  • New Features
    • The course creation form now adapts based on your authentication status.
    • For logged-in users, redundant input fields (email and captcha) are hidden to simplify the process.
    • The form submission process for authenticated users has been streamlined, eliminating unnecessary email requirements.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 11, 2025

Walkthrough

The changes update the course creation flow by adapting form behavior based on user authentication. An __init__ method has been added to the TeachForm class to remove the "email" and "captcha" fields for authenticated users. The corresponding template now conditionally omits these fields during rendering. Additionally, the view no longer validates that the submitted email matches the authenticated user’s email during course creation.

Changes

Files Change Summary
web/forms.py,
web/templates/teach.html
Added authentication-based logic to remove/hide the "email" and "captcha" fields for authenticated users in both the form initialization and template rendering.
web/views.py Updated the teach function to allow the form to recognize the authenticated user and removed the email matching validation during course creation.
web/tests/test_teach.py Renamed and modified the test for authenticated users to reflect the removal of email and captcha requirements, expecting a successful redirect instead of an error.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant F as TeachForm
    participant T as Template
    participant V as View

    U->>F: Initialize form (pass user)
    alt User is authenticated
        F-->>F: Remove "email" and "captcha" fields
        F->>T: Render form without "email"/"captcha"
    else Not authenticated
        F->>T: Render complete form
    end
    U->>V: Submit form data
    V->>F: Validate form (without strict email matching)
    V->>U: Return confirmation or error response
Loading

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ 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 plan to trigger planning for file edits and PR creation.
  • @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.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 11, 2025
@IITI-tushar
Copy link
Copy Markdown
Contributor Author

@coderabbitai
please fix the failing tests

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 11, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll help you fix the failing tests. First, let's examine what's failing to understand the issue better.


🏁 Script executed:

#!/bin/bash
# Find relevant test files that might be affected by the TeachForm changes
find . -name "*test*.py" | grep -v "__pycache__"

Length of output: 947


Let's examine the relevant test files that might be affected by our changes to the TeachForm class. The most relevant would be web/tests/test_teach.py and web/tests/test_forms.py.


🏁 Script executed:

#!/bin/bash
# Check content of test_teach.py which might be failing due to our form changes
cat ./web/tests/test_teach.py

Length of output: 18665


Let's look at the test_forms.py file as well to see if it has any tests related to the TeachForm class:


🏁 Script executed:

#!/bin/bash
# Check content of test_forms.py which might also be failing
cat ./web/tests/test_forms.py

Length of output: 31707


Now, let's look at the view code to understand how the TeachForm is being initialized with the user parameter:


🏁 Script executed:

#!/bin/bash
# Check the teach view in web/views.py to see how the form is initialized
rg -A 10 -B 5 "def teach" web/views.py

Length of output: 1464


Let's check the actual TeachForm implementation in web/forms.py to understand what we need to fix:


🏁 Script executed:

#!/bin/bash
# View the TeachForm implementation in web/forms.py
cat web/forms.py

Length of output: 65555


Fixing the Failing Tests

Looking at the code and tests, I found that the main issue is in the teach view function, where the form is being instantiated without passing the user parameter, meaning the form isn't removing the email and captcha fields for authenticated users as intended.

Here's how I'll fix it:

flowchart TB
    A["Issue: Tests Failing"]
    A --o B["Fix `teach` view: pass user to form"]
    A --o C["Update tests to match new behavior"]
    
    B --o D["Pass request.user to TeachForm constructor"]
    B --o E["Also pass user on GET requests"]
    
    C --o F["Update test_post_authenticated_email_mismatch"]
    C --o G["Ensure other tests handle auth users correctly"]
Loading

@IITI-tushar I've identified the issue with the tests. The problem is that in the teach view function, we're not passing the user parameter to the TeachForm constructor, so the form isn't removing the email and captcha fields for authenticated users as intended.

Here's what needs to be fixed:

  1. In web/views.py, update how the form is created to pass the user:
# For POST requests
form = TeachForm(request.POST, request.FILES, user=request.user)

# For GET requests
form = TeachForm(user=request.user)
  1. We also need to update the test that expects email validation, since that field is now removed for authenticated users.

I've created a plan to fix these issues - the changes will be implemented by another agent. The fixes ensure that the form works correctly by having the email and captcha fields removed for authenticated users, and updates the tests to match this new behavior.

Would you like me to explain any part of the solution in more detail?


⏳ Preparing changes...

@IITI-tushar
Copy link
Copy Markdown
Contributor Author

@coderabbitai
please give copyable code to fix the failing tests

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 11, 2025

A summary of the edits CodeRabbit can apply:

Update the teach view function in web/views.py to pass the user parameter to the TeachForm constructor for both GET and POST requests.

Update the test_post_authenticated_email_mismatch test in web/tests/test_teach.py to match the new behavior where the email field is no longer present for authenticated users.

We are going to update the teach view function in web/views.py so that the TeachForm constructor always receives the request.user parameter for both POST and GET requests.

We are going to update the authenticated user test in web/tests/test_teach.py to reflect the new behavior where the email and captcha fields are omitted and the form submission redirects on success.

We will update the teach view in web/views.py so that for both POST and GET requests the TeachForm is instantiated with the user parameter.

We will update the failing test in web/tests/test_teach.py (renaming it to test_form_prepopulates_authenticated_user_email) so that the email and captcha fields are removed from form submission for authenticated users, and assertions verify that the response is a redirect and the course is created with the authenticated user as teacher.

A plan of each step that CodeRabbit will take in order to execute the edits for each file (with inline rough draft snippets):

✏️ web/views.py

Modify the POST request handling to pass the user parameter to the TeachForm constructor:

def teach(request):
    """Handles the course creation process for both authenticated and unauthenticated users."""
    if request.method == "POST":
        form = TeachForm(request.POST, request.FILES, user=request.user)
        if form.is_valid():
            # Extract cleaned data
            email = form.cleaned_data.get("email", request.user.email if request.user.is_authenticated else None)
            course_title = form.cleaned_data["course_title"]
            course_description = form.cleaned_data["course_description"]
            course_image = form.cleaned_data.get("course_image")
            preferred_session_times = form.cleaned_data["preferred_session_times"]

This change passes the user parameter to the TeachForm constructor, which will cause the form to remove the email and captcha fields for authenticated users as defined in the TeachForm.init method.


Modify the GET request handling to also pass the user parameter to the TeachForm constructor:

    else:
        # GET request
        initial_data = {}
        if "subject" in request.GET:
            initial_data["course_title"] = request.GET.get("subject")
        form = TeachForm(user=request.user, initial=initial_data)

This ensures that the form is properly initialized with the user parameter for GET requests as well, maintaining consistency between GET and POST handling.


Update the email extraction in the form.is_valid() block to handle the case where the email field might not be present for authenticated users:

# Extract cleaned data
email = form.cleaned_data.get("email", request.user.email if request.user.is_authenticated else None)

This ensures that for authenticated users, where the email field is removed from the form, we still have access to the user's email for further processing.

✏️ web/tests/test_teach.py

Rename the test to better reflect its new purpose and update the test logic:

@patch("captcha.fields.CaptchaField.clean", return_value="PASSED")
def test_form_prepopulates_authenticated_user_email(self, mock_captcha):
    """Test that for authenticated users, the form uses the user's email and doesn't include email/captcha fields"""
    self.client.login(username="testuser", password="testpass123")

    form_data = {
        "course_title": "Test Course",
        "course_description": "This is a test course",
        "preferred_session_times": (timezone.now() + timezone.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"),
        "flexible_timing": True,
    }

    response = self.client.post(self.teach_url, {**form_data, "course_image": self.get_test_image()})

    # Should redirect to course detail page since the form should be valid
    self.assertEqual(response.status_code, 302)
    self.assertTrue(response.url.startswith("/courses/"))
    
    # Verify that a course was created with the authenticated user's email
    course = Course.objects.get(title="Test Course")
    self.assertEqual(course.teacher, self.user)

This updated test verifies that when an authenticated user submits the form without an email field (since it's removed for authenticated users), the form is still valid and creates a course using the user's account email.

✏️ web/views.py

Locate the POST branch inside the teach() function and change the form initialization from

TeachForm(request.POST, request.FILES)

to

TeachForm(request.POST, request.FILES, user=request.user)

.


Locate the GET branch inside the same function and change the form initialization from

TeachForm()

to

TeachForm(user=request.user)

.

✏️ web/tests/test_teach.py

Rename the test function from

test_post_authenticated_email_mismatch

to

test_form_prepopulates_authenticated_user_email

to better reflect its updated purpose.


Remove the

"email"

and

"captcha"

keys from the

form_data

dictionary, as these fields should now be omitted for authenticated users.


Update the assertions: Instead of expecting a 200 status code and specific form error messages, assert that the response status code is

302

(indicating a successful redirect). Then retrieve the created course and verify that

course.teacher

matches

self.user

.

✏️ web/views.py

Replace the POST branch where TeachForm is instantiated:

if request.method == "POST": form = TeachForm(request.POST, request.FILES, user=request.user) if form.is_valid(): # Extract cleaned data email = form.cleaned_data["email"] course_title = form.cleaned_data["course_title"] course_description = form.cleaned_data["course_description"] course_image = form.cleaned_data.get("course_image") preferred_session_times = form.cleaned_data["preferred_session_times"] …

Replace the GET branch instantiation:

else: # GET request initial_data = {} if "subject" in request.GET: initial_data["course_title"] = request.GET.get("subject") form = TeachForm(user=request.user)
✏️ web/tests/test_teach.py

Update the test by replacing the previous version with:

@patch("captcha.fields.CaptchaField.clean", return_value="PASSED") -def test_post_authenticated_email_mismatch(self, mock_captcha): +def test_form_prepopulates_authenticated_user_email(self, mock_captcha): """Test POST for authenticated user with mismatched email""" - self.client.login(username="testuser", password="testpass123") - - form_data = { - "course_title": "Test Course", - "course_description": "This is a test course", - "email": "different@example.com", - "preferred_session_times": (timezone.now() + timezone.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"), - "flexible_timing": True, - "captcha": "dummy", - } - - response = self.client.post(self.teach_url, {**form_data, "course_image": self.get_test_image()}) - - self.assertEqual(response.status_code, 200) - self.assertIn("form", response.context) - self.assertIn("The provided email does not match your account email", str(response.context["form"].errors)) + self.client.login(username="testuser", password="testpass123") + + form_data = { + "course_title": "Test Course", + "course_description": "This is a test course", + "preferred_session_times": (timezone.now() + timezone.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"), + "flexible_timing": True, + } + + response = self.client.post(self.teach_url, {**form_data, "course_image": self.get_test_image()}) + + # For authenticated users, the updated view should produce a redirect (302) + self.assertEqual(response.status_code, 302) + + # Verify that the course is created using the authenticated user's email + course = Course.objects.get(title="Test Course") + self.assertEqual(course.teacher, self.user)

A summary of the context that CodeRabbit is considering across the codebase:

First, let's examine the TeachForm class to understand what parameters it expects and how it handles the user parameter.

Let's look at the failing tests to understand what's expected behavior.

Let's check if there are other tests that might be affected by this change.

Let's check the current implementation of the teach view function to understand what needs to be changed.

Let's also check the GET part of the teach view function.

Let's check the test_post_authenticated test to understand how it's expected to work when the user parameter is passed correctly.

This change was necessary because the TeachForm was instantiated without the request.user parameter in the teach view. Without passing request.user, the form retains fields (such as email and captcha) that should be omitted for authenticated users. A grep search confirmed that TeachForm is used without the extra parameter, hence failing tests that expect this behavior.

This update is required because the test for authenticated users expected an error message on email mismatch. With the updated behavior, the email (and captcha) fields are omitted for authenticated users so that the form submission should now succeed with a redirect. A search in the tests confirmed that the function originally named test_post_authenticated_email_mismatch in web/tests/test_teach.py is now outdated in its expectations.

We verified that the TeachForm is not being instantiated with the current request.user in the teach view. Without the user parameter, the form does not remove the email and captcha fields for authenticated users. This behavior causes tests expecting a redirect and course creation (instead of email mismatch errors) to fail.

Our investigation of the tests showed that the test expecting an email mismatch for an authenticated user should instead verify that the form submission succeeds and that a course is created with the authenticated user as teacher. A shell search confirms that the test function needs to be updated.

  • ✅ Create PR with these edits

  • 📋 Get copyable edits

  • 📌 Create commit in current branch

  • 🔄 Try a different approach

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 11, 2025

Tip

For best results, initiate chat on the files or code changes.

@IITI-tushar Here's the copyable code to fix the failing tests:

1. First, update the teach function in web/views.py:

def teach(request):
    """Handles the course creation process for both authenticated and unauthenticated users."""
    if request.method == "POST":
        form = TeachForm(request.POST, request.FILES, user=request.user)
        if form.is_valid():
            # Extract cleaned data
            email = form.cleaned_data.get("email")
            course_title = form.cleaned_data["course_title"]
            course_description = form.cleaned_data["course_description"]
            course_image = form.cleaned_data.get("course_image")
            preferred_session_times = form.cleaned_data["preferred_session_times"]
            
            # Handle duplicate course titles
            if Course.objects.filter(title=course_title).exists():
                form.add_error("course_title", "A course with this title already exists")
                return render(request, "teach.html", {"form": form})
            
            # Create the course
            course = Course.objects.create(
                title=course_title,
                subject=course_title,
                description=course_description,
                time=preferred_session_times,
                teacher=request.user if request.user.is_authenticated else None,
                email=email if not request.user.is_authenticated else request.user.email
            )
            
            # Process course image if provided
            if course_image:
                course.image = course_image
                course.save()
                
            # Redirect authenticated users to dashboard, others to thank-you page
            if request.user.is_authenticated:
                return redirect("dashboard")
            else:
                return redirect("thank-you")
    else:
        # GET request
        initial_data = {}
        if "subject" in request.GET:
            initial_data["course_title"] = request.GET.get("subject")
        form = TeachForm(initial=initial_data, user=request.user)
        
    return render(request, "teach.html", {"form": form})

2. Update the test in web/tests/test_teach.py:

@patch("captcha.fields.CaptchaField.clean", return_value="PASSED")
def test_form_for_authenticated_user(self, mock_captcha):
    """Test form behavior for authenticated users - no email or captcha required"""
    self.client.login(username="testuser", password="testpass123")

    form_data = {
        "course_title": "Test Course",
        "course_description": "This is a test course",
        "preferred_session_times": (timezone.now() + timezone.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"),
        "flexible_timing": True,
    }

    response = self.client.post(self.teach_url, {**form_data, "course_image": self.get_test_image()})

    # For authenticated users, we expect a successful submission without email/captcha
    self.assertEqual(response.status_code, 302)  # Successful redirect
    
    # Verify a course is created with the authenticated user's email
    course = Course.objects.get(title="Test Course")
    self.assertEqual(course.teacher, self.user)
    self.assertEqual(course.email, self.user.email)

The key changes:

  1. Added user=request.user when creating the form in both POST and GET scenarios
  2. Used get() for email access since it might not exist for authenticated users
  3. Updated the test to reflect that authenticated users don't need to provide email/captcha

Remember to replace the old test_post_authenticated_email_mismatch function with the new test function above.

@IITI-tushar
Copy link
Copy Markdown
Contributor Author

@coderabbitai
help me in fixing these tests

python manage.py test web.tests.test_teach
Using console email backend with Slack notifications for development
Warning: Service account file not found at C:\Tushar_CODES\OpenSource\Alpha-One-education-website\your-service-account-file-path
Found 13 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E..EE.......E
======================================================================
ERROR: test_form_for_authenticated_user (web.tests.test_teach.TeachViewTests.test_form_for_authenticated_user)
Test form behavior for authenticated users - no email or captcha required
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0\Lib\unittest\mock.py", line 1396, in patched
    return func(*newargs, **newkeywargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\tests\test_teach.py", line 144, in test_form_for_authenticated_user
    response = self.client.post(self.teach_url, {**form_data, "course_image": self.get_test_image()})
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1158, in post
    response = super().post(
               ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 503, in post
    return self.generic(
           ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 676, in generic
    return self.request(**r)
           ^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1092, in request
    self.check_exception(response)
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 805, in check_exception       
    raise exc_value
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner      
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response  
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\views.py", line 1113, in teach
    email = form.cleaned_data["email"]
            ~~~~~~~~~~~~~~~~~^^^^^^^^^
KeyError: 'email'

======================================================================
ERROR: test_post_authenticated_duplicate_title (web.tests.test_teach.TeachViewTests.test_post_authenticated_duplicate_title)
Test POST for authenticated user with duplicate course title
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0\Lib\unittest\mock.py", line 1396, in patched
    return func(*newargs, **newkeywargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\tests\test_teach.py", line 177, in test_post_authenticated_duplicate_title    
    response = self.client.post(self.teach_url, {**form_data, "course_image": self.get_test_image()})
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1158, in post
    response = super().post(
               ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 503, in post
    return self.generic(
           ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 676, in generic
    return self.request(**r)
           ^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1092, in request
    self.check_exception(response)
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 805, in check_exception       
    raise exc_value
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner      
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response  
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\views.py", line 1113, in teach
    email = form.cleaned_data["email"]
            ~~~~~~~~~~~~~~~~~^^^^^^^^^
KeyError: 'email'

======================================================================
ERROR: test_post_authenticated_valid (web.tests.test_teach.TeachViewTests.test_post_authenticated_valid)
Test POST for authenticated user with valid data
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0\Lib\unittest\mock.py", line 1396, in patched
    return func(*newargs, **newkeywargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\tests\test_teach.py", line 121, in test_post_authenticated_valid
    response = self.client.post(self.teach_url, {**form_data, "course_image": self.get_test_image()})
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1158, in post
    response = super().post(
               ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 503, in post
    return self.generic(
           ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 676, in generic
    return self.request(**r)
           ^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1092, in request
    self.check_exception(response)
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 805, in check_exception       
    raise exc_value
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner      
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response  
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\views.py", line 1113, in teach
    email = form.cleaned_data["email"]
            ~~~~~~~~~~~~~~~~~^^^^^^^^^
KeyError: 'email'

======================================================================
ERROR: test_post_with_image (web.tests.test_teach.TeachViewTests.test_post_with_image)
Test POST with image upload
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0\Lib\unittest\mock.py", line 1396, in patched
    return func(*newargs, **newkeywargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\tests\test_teach.py", line 275, in test_post_with_image
    response = self.client.post(self.teach_url, form_data)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1158, in post
    response = super().post(
               ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 503, in post
    return self.generic(
           ^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 676, in generic
    return self.request(**r)
           ^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 1092, in request
    self.check_exception(response)
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\test\client.py", line 805, in check_exception       
    raise exc_value
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner      
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response  
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Tushar_CODES\OpenSource\Alpha-One-education-website\web\views.py", line 1113, in teach
    email = form.cleaned_data["email"]
            ~~~~~~~~~~~~~~~~~^^^^^^^^^
KeyError: 'email'

----------------------------------------------------------------------
Ran 13 tests in 20.648s

FAILED (errors=4)
Destroying test database for alias 'default'...
(venv) 

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 11, 2025

Tip

For best results, initiate chat on the files or code changes.

@IITI-tushar I see the issue in your tests. The error is happening because we're trying to access form.cleaned_data["email"] directly in the view, but for authenticated users, the email field is removed from the form.

Here's the fix for web/views.py:

def teach(request):
    """Handles the course creation process for both authenticated and unauthenticated users."""
    if request.method == "POST":
        form = TeachForm(request.POST, request.FILES, user=request.user)
        if form.is_valid():
            # Extract cleaned data - safely get email or use user's email if authenticated
            email = form.cleaned_data.get("email", None)
            if email is None and request.user.is_authenticated:
                email = request.user.email
                
            course_title = form.cleaned_data["course_title"]
            course_description = form.cleaned_data["course_description"]
            course_image = form.cleaned_data.get("course_image")
            preferred_session_times = form.cleaned_data["preferred_session_times"]
            
            # Handle duplicate course titles
            if Course.objects.filter(title=course_title).exists():
                form.add_error("course_title", "A course with this title already exists")
                return render(request, "teach.html", {"form": form})
            
            # Create the course
            course = Course.objects.create(
                title=course_title,
                subject=course_title,
                description=course_description,
                time=preferred_session_times,
                teacher=request.user if request.user.is_authenticated else None,
                email=email
            )
            
            # Process course image if provided
            if course_image:
                course.image = course_image
                course.save()
                
            # Handle redirects based on user authentication status
            if request.user.is_authenticated:
                return redirect("courses:detail", pk=course.id)
            else:
                # For unauthenticated users, redirect to email verification
                return redirect("account_email_verification_sent")
    else:
        # GET request
        initial_data = {}
        if "subject" in request.GET:
            initial_data["course_title"] = request.GET.get("subject")
        form = TeachForm(user=request.user, initial=initial_data)
        
    return render(request, "teach.html", {"form": form})

The key changes:

  1. Changed email = form.cleaned_data["email"] to email = form.cleaned_data.get("email", None)
  2. Added fallback logic: if email is None and request.user.is_authenticated: email = request.user.email
  3. Made sure all TeachForm instantiations include the user=request.user parameter

This change handles the case where the email field is removed for authenticated users while maintaining backward compatibility for unauthenticated users.

✏️ Learnings added
Learnt from: IITI-tushar
URL: https://github.com/alphaonelabs/alphaonelabs-education-website/pull/535

Timestamp: 2025-04-11T14:48:32.253Z
Learning: In the Django TeachForm, when handling forms that conditionally remove fields based on user authentication status (like removing email and captcha fields for authenticated users), always use get() with a fallback value when accessing form.cleaned_data in the view function to avoid KeyError exceptions.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Copy Markdown
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: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cda7a3d and c0d90fb.

📒 Files selected for processing (2)
  • web/tests/test_teach.py (1 hunks)
  • web/views.py (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
web/tests/test_teach.py (1)
web/models.py (1)
  • Course (233-327)
web/views.py (1)
web/forms.py (1)
  • TeachForm (883-980)
🪛 Ruff (0.8.2)
web/tests/test_teach.py

133-133: Missing return type annotation for public function test_form_for_authenticated_user

Add return type annotation: None

(ANN201)


133-133: Missing type annotation for function argument mock_captcha

(ANN001)


133-133: Unused method argument: mock_captcha

(ARG002)


135-135: Possible hardcoded password assigned to argument: "password"

(S106)


147-147: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


151-151: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Run Tests
  • GitHub Check: build-and-test
🔇 Additional comments (6)
web/views.py (3)

1110-1110: Pass user parameter to TeachForm for conditional field removal.

This change is essential for the form to know whether the current user is authenticated, allowing it to conditionally remove the email and captcha fields for logged-in users as implemented in the TeachForm's __init__ method.


1113-1115: Handle email retrieval when field may not exist for authenticated users.

This correctly implements the form's new behavior by:

  1. Using get() with a default value to safely retrieve the email field (which may not exist for authenticated users)
  2. Falling back to the user's email when the field is missing but the user is authenticated

This ensures the email is properly captured regardless of whether the field is present or not.


1252-1252: Pass user to TeachForm in GET requests.

This change ensures the TeachForm correctly removes email and captcha fields for authenticated users when the form is initially rendered, not just on form submission. This provides a consistent user experience from the start.

web/tests/test_teach.py (3)

133-135: Good update to align test name with new functionality.

The method rename from test_post_authenticated_email_mismatch to test_form_for_authenticated_user accurately reflects the new behavior being tested, and the updated docstring clearly explains the purpose of the test.

🧰 Tools
🪛 Ruff (0.8.2)

133-133: Missing return type annotation for public function test_form_for_authenticated_user

Add return type annotation: None

(ANN201)


133-133: Missing type annotation for function argument mock_captcha

(ANN001)


133-133: Unused method argument: mock_captcha

(ARG002)


135-135: Possible hardcoded password assigned to argument: "password"

(S106)


137-142: Correctly removed email and captcha fields for authenticated user test.

This reflects the updated behavior where authenticated users don't need to provide email or captcha fields in the form. The test data properly focuses on only the required fields for an authenticated user submission.


146-152: Appropriate assertion updates for the new behavior.

The assertions have been correctly updated to:

  1. Check for a successful redirect (302 status code) instead of an error case
  2. Verify that a course is created with the authenticated user as the teacher

This properly tests that the form submission works without email/captcha for authenticated users, aligning with the PR objective.

🧰 Tools
🪛 Ruff (0.8.2)

147-147: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


151-151: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)

Comment thread web/tests/test_teach.py
Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
web/tests/test_teach.py (1)

133-135: 🧹 Nitpick (assertive)

Good test case renaming and docstring update.

The test has been appropriately renamed from test_post_authenticated_email_mismatch to test_form_for_authenticated_user, and the docstring clearly explains the new test purpose.

The mock_captcha parameter is flagged as unused, but it's still needed because the @patch decorator injects it. Consider adding a comment to clarify this:

@patch("captcha.fields.CaptchaField.clean", return_value="PASSED")
-def test_form_for_authenticated_user(self, mock_captcha):
+def test_form_for_authenticated_user(self, mock_captcha):  # mock_captcha is needed for the patch decorator
🧰 Tools
🪛 Ruff (0.8.2)

133-133: Missing return type annotation for public function test_form_for_authenticated_user

Add return type annotation: None

(ANN201)


133-133: Missing type annotation for function argument mock_captcha

(ANN001)


133-133: Unused method argument: mock_captcha

(ARG002)


135-135: Possible hardcoded password assigned to argument: "password"

(S106)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c0d90fb and cf1f857.

📒 Files selected for processing (4)
  • web/forms.py (1 hunks)
  • web/templates/teach.html (1 hunks)
  • web/tests/test_teach.py (1 hunks)
  • web/views.py (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
web/tests/test_teach.py (1)
web/models.py (1)
  • Course (233-327)
web/views.py (1)
web/forms.py (1)
  • TeachForm (883-980)
🪛 Ruff (0.8.2)
web/forms.py

949-949: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


949-949: Missing type annotation for *args

(ANN002)


949-949: Missing type annotation for **kwargs

(ANN003)

web/tests/test_teach.py

133-133: Missing return type annotation for public function test_form_for_authenticated_user

Add return type annotation: None

(ANN201)


133-133: Missing type annotation for function argument mock_captcha

(ANN001)


133-133: Unused method argument: mock_captcha

(ARG002)


135-135: Possible hardcoded password assigned to argument: "password"

(S106)


147-147: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


151-151: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests
🔇 Additional comments (6)
web/views.py (3)

1110-1110: Necessary change to pass user parameter to TeachForm.

The form now correctly receives the current user as a parameter, allowing it to conditionally display fields based on authentication status.


1113-1115: Good defensive programming to handle authenticated users.

This change safely handles the case where the email field is removed for authenticated users. Using get() with a default value avoids KeyError exceptions, and falling back to the user's email ensures the field is always populated.


1252-1252: Consistent initialization of form for both GET and POST requests.

The form is now correctly initialized with the user parameter when rendering the form initially, ensuring consistency between form display and submission logic.

web/templates/teach.html (1)

49-52: Good implementation of conditional field rendering.

The template now correctly skips rendering the email and captcha fields for authenticated users. This provides a better user experience by hiding fields that aren't needed and aligns perfectly with the changes in the form class.

web/tests/test_teach.py (2)

137-144: Correctly omitted email and captcha from form data.

The test data no longer includes the email and captcha fields, which accurately represents the form data that an authenticated user would submit with the updated form.


146-151: Good assertions and verification logic.

The test now correctly expects a successful redirect (status code 302) and verifies that a course is created with the authenticated user as the teacher. This validates the key functionality being implemented.

🧰 Tools
🪛 Ruff (0.8.2)

147-147: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


151-151: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)

Comment thread web/forms.py
@A1L13N A1L13N added this pull request to the merge queue Apr 19, 2025
Merged via the queue into alphaonelabs:main with commit 9481082 Apr 19, 2025
6 checks passed
Satyamkumarnavneet pushed a commit to Satyamkumarnavneet/education-website that referenced this pull request Apr 19, 2025
…mail or captcha if the user is logged in (alphaonelabs#535)

* done

* fixed
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.

Make the I want to teach a class form not require email or captcha if the user is logged in

2 participants