Skip to content

Leuber bug 246/247 #322

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 31 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions accounts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ def is_mutual(self, obj):
is_mutual.short_description = "Mutual Like"


# Register the Like model with the admin site
# admin.site.register(Like, LikeAdmin)


@admin.register(Match)
class MatchAdmin(admin.ModelAdmin):
list_display = (
Expand Down
80 changes: 62 additions & 18 deletions accounts/templates/accounts/account.html
Original file line number Diff line number Diff line change
@@ -1,25 +1,69 @@
{% extends 'base.html' %}

{% block title %} Account Page {% endblock %}
{% block title %}Account Page{% endblock %}

{% block content %}
<h2>Your Account</h2>
<p>Username: {{ request.user.username }}</p>
<p>Email: {{ request.user.email }}</p>
<h2>Your Account</h2>
<p>Username: {{ request.user.username }}</p>
<p>Email: {{ request.user.email }}</p>

<h3>Change Username</h3>
<form method="post">
{% csrf_token %}
<div class="form-group">
<input type="text" name="username" class="form-control" placeholder="New Username">
</div>
<button type="submit" class="btn btn-primary">Change Username</button>
</form>
<h3 class="mt-4">Change Password</h3>
<form id="change-password-form" method="post" action="{% url 'account' %}">
{% csrf_token %}
{{ password_form.as_p }}
<button type="submit" class="btn btn-primary">Change Password</button>
</form>

<h3 class="mt-4">Change Password</h3>
<form method="post">
{% csrf_token %}
{{ password_form.as_p }}
<button type="submit" class="btn btn-primary">Change Password</button>
</form>
<!-- Modal for messages -->
<div class="modal" tabindex="-1" role="dialog" id="messageModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Notification</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<!-- Placeholder for the message content will be styled in scripts block -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
{% endblock %}

{% block scripts %}
<script>
$(document).ready(function() {
$('#change-password-form').submit(function(event) {
event.preventDefault();
var formData = $(this).serialize();

$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: formData,
dataType: 'json', // Make sure the dataType is set to 'json'
success: function(response) {
$('#messageModal .modal-body').html('<div class="text-success">' + response.message + '</div>');
$('#messageModal').modal('show');
},
error: function(xhr) {
var response = xhr.responseJSON;
var message = '<div class="text-danger">' + response.message + '</div>';
var errors = '<ul class="text-danger">';
$.each(response.errors, function(key, error) {
errors += '<li>' + error + '</li>';
});
errors += '</ul>';
$('#messageModal .modal-body').html(message + errors);
$('#messageModal').modal('show');
}
});
});
});
</script>
{% endblock %}
231 changes: 138 additions & 93 deletions accounts/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.auth.forms import PasswordChangeForm
from .models import *
import tempfile
import tempfile, json
from django.core.files import File
from .forms import EditProfileForm, CustomUserCreationForm
from django.core.files.uploadedfile import SimpleUploadedFile
Expand All @@ -26,6 +26,7 @@
from unittest.mock import patch
from django.core.management.base import CommandError
from game.models import GameSession, Player, GameTurn
from django.conf import settings


class ProfileModelTest(TestCase):
Expand Down Expand Up @@ -148,58 +149,41 @@ def test_logged_in_uses_correct_template(self):
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "accounts/account.html")

def test_change_username_successfully(self):
# Test checks if a logged-in user can successfully change
# their username
self.client.login(username="testuser", password="testpassword123")
response = self.client.post(self.account_url, {"username": "newusername"})
self.user.refresh_from_db()
self.assertEqual(self.user.username, "newusername")
messages = list(get_messages(response.wsgi_request))
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), "Username updated successfully")

def test_change_username_to_existing_one(self):
# Test that a logged-in user cannot change their username
# to one that already exists in the database
User.objects.create_user(username="existinguser", password="testpassword123")
self.client.login(username="testuser", password="testpassword123")
response = self.client.post(self.account_url, {"username": "existinguser"})
messages = list(get_messages(response.wsgi_request))
self.assertEqual(len(messages), 1)
self.assertEqual(
str(messages[0]), "This username is already taken. Choose another."
)

def test_change_password_successfully(self):
# Test checks if a logged-in user can successfully change
# their password.
# Test if a logged-in user can successfully change their password
self.client.login(username="testuser", password="testpassword123")
data = {
"old_password": "testpassword123",
"new_password1": "newtestpassword123",
"new_password2": "newtestpassword123",
}
response = self.client.post(self.account_url, data)
self.user.refresh_from_db()
self.assertTrue(self.user.check_password("newtestpassword123"))
messages = list(get_messages(response.wsgi_request))
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), "Password updated successfully")
response = self.client.post(
self.account_url, data, HTTP_X_REQUESTED_WITH="XMLHttpRequest"
)
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.content)
self.assertEqual(response_data["status"], "success")
self.assertEqual(response_data["message"], "Password updated successfully")

def test_change_password_with_invalid_data(self):
# Test checks if the error message is shown when a user tries to change
# their password with invalid data (e.g. mismatched new passwords)
# Test if the error message is shown when a user tries to change
# their password with invalid data (e.g., mismatched new passwords)
self.client.login(username="testuser", password="testpassword123")
data = {
"old_password": "testpassword123",
"new_password1": "newtestpassword123",
"new_password2": "differentnewtestpassword123", # Mismatched password
}
response = self.client.post(self.account_url, data)
messages = list(get_messages(response.wsgi_request))
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), "Please correct the errors below.")
response = self.client.post(
self.account_url, data, HTTP_X_REQUESTED_WITH="XMLHttpRequest"
)
self.assertEqual(response.status_code, 400)
response_data = json.loads(response.content)
self.assertEqual(response_data["status"], "error")
self.assertIn("Some errors occurred:", response_data["message"])
self.assertIn(
"The two password fields didn’t match.", response_data["errors"][0]
)


@override_settings(
Expand Down Expand Up @@ -872,6 +856,27 @@ def test_reset_likes(self):
self.assertEqual(Profile.objects.get(user=self.user1).likes_remaining, 3)
self.assertEqual(Profile.objects.get(user=self.user2).likes_remaining, 3)

def test_reset_likes_with_dbname(self):
# Pass the --dbname argument to the command
dbname = "custom_db_name"
call_command("reset_likes", dbname=dbname)

# Now check if the likes are reset and the output message contains the dbname
self.assertEqual(Like.objects.count(), 0)
self.assertEqual(Profile.objects.get(user=self.user1).likes_remaining, 3)
self.assertEqual(Profile.objects.get(user=self.user2).likes_remaining, 3)

# You need to check the output of the command.
# For this, you'll need to capture the output. Here's one way to do it using StringIO:
from io import StringIO

out = StringIO()
call_command("reset_likes", dbname=dbname, stdout=out)
output = out.getvalue()

# Assert that the output contains the expected string
self.assertIn(f"Using database: {dbname}", output)


class NotifyMatchesCommandTest(TestCase):
@classmethod
Expand Down Expand Up @@ -1197,68 +1202,54 @@ def test_already_liked_profile(self):
match_count = Match.objects.filter(user1=self.user1, user2=self.user2).count()
self.assertEqual(match_count, 0)


class ResetLikesViewTest(TestCase):
def setUp(self):
# Set up test data
self.client = Client()

# Create two users
self.user1 = User.objects.create_user(username="user1", password="password1")
self.user2 = User.objects.create_user(username="user2", password="password2")

# Create profiles for the users if they don't already exist
self.profile1, _ = Profile.objects.get_or_create(user=self.user1)
self.profile2, _ = Profile.objects.get_or_create(user=self.user2)

# Set initial likes_remaining for the profiles
self.profile1.likes_remaining = 1 # Set a non-zero initial value
self.profile1.save()
self.profile2.likes_remaining = 2 # Set a non-zero initial value
self.profile2.save()

def test_reset_likes(self):
# Create a staff user and login
staff_user = User.objects.create_user(
username="staffuser", password="staffpassword", is_staff=True
)
self.client.login(username="staffuser", password="staffpassword")
# Set up initial likes and likes_remaining for test users
Like.objects.create(from_user=self.user1, to_user=self.user2)
self.profile1.likes_remaining = 1
def test_like_profile_with_no_likes_remaining(self):
# Set likes_remaining to 0 for user1
self.profile1.likes_remaining = 0
self.profile1.save()
self.profile2.likes_remaining = 2
self.profile2.save()

# Make a POST request to reset likes
response = self.client.post(reverse("reset_likes_view"))

# Check if the response is successful
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content.decode(), "Likes have been reset.")
# Login as user1 with the correct password
login_successful = self.client.login(username="user1", password="password1")
self.assertTrue(login_successful, "Login failed, check setup and credentials.")

# Verify that all likes have been cleared
self.assertEqual(Like.objects.count(), 0)
# User1 tries to like User2's profile with no likes remaining
response = self.client.post(reverse("like_profile", args=[self.user2.pk]))

# Verify that likes_remaining is reset to 3 for all users
self.profile1.refresh_from_db()
self.profile2.refresh_from_db()
self.assertEqual(self.profile1.likes_remaining, 3)
self.assertEqual(self.profile2.likes_remaining, 3)
# Check if the response code and message are correct
self.assertEqual(
response.status_code,
200,
"Expected status code 200, got {0}".format(response.status_code),
)
data = response.json()
self.assertFalse(data["success"], "Expected success to be False.")
self.assertEqual(
data["error"],
"You have reached your daily likes limit",
"Error message does not match expected.",
)

def test_like_profile_invalid_method(self):
# This test will check if the correct error is returned when using a GET request
self.client.login(username="user1", password="password1")
response = self.client.get(reverse("like_profile", args=[self.user2.pk]))

def test_invalid_method(self):
# Create a staff user and login
staff_user = User.objects.create_user(
username="staffuser", password="staffpassword", is_staff=True
)
self.client.login(username="staffuser", password="staffpassword")
# Make a GET request (or any method other than POST)
response = self.client.get(reverse("reset_likes_view"))
# Check if the response code is 405 Method Not Allowed
self.assertEqual(
response.status_code,
405,
"Expected status code 405 for invalid request method.",
)

# Check if the response indicates an invalid method
self.assertEqual(response.status_code, 400)
self.assertEqual(response.content.decode(), "Invalid method")
# Check the error message
data = response.json()
self.assertFalse(
data["success"], "Expected success to be False for invalid request method."
)
self.assertEqual(
data["error"],
"Invalid request method.",
"Error message does not match expected for invalid request method.",
)


class MatchModelTest(TestCase):
Expand Down Expand Up @@ -1293,3 +1284,57 @@ def test_create_match_with_swapped_users(self):
# Ensure still only one match in the database
match_count = Match.objects.count()
self.assertEqual(match_count, 1)


class LikeModelTest(TestCase):
def setUp(self):
self.user1 = User.objects.create_user(username="user1", password="password1")
self.user2 = User.objects.create_user(username="user2", password="password2")
self.user3 = User.objects.create_user(username="user3", password="password3")

# Create mutual likes between user1 and user2
Like.objects.create(from_user=self.user1, to_user=self.user2)
Like.objects.create(from_user=self.user2, to_user=self.user1)

# Create a one-way like from user1 to user3
Like.objects.create(from_user=self.user1, to_user=self.user3)

def test_is_mutual(self):
mutual_like = Like.objects.get(from_user=self.user1, to_user=self.user2)
self.assertTrue(mutual_like.is_mutual(), "The like should be mutual")

def test_is_not_mutual(self):
non_mutual_like = Like.objects.get(from_user=self.user1, to_user=self.user3)
self.assertFalse(non_mutual_like.is_mutual(), "The like should not be mutual")


class RolePlayDateURLsTest(TestCase):
@classmethod
def setUpTestData(cls):
# Create a staff user for testing the views
cls.staff_user = User.objects.create_user(
username="staff", password="testpass", is_staff=True
)
cls.client = Client()

def test_notify_matches_view(self):
# Login as the staff user
self.client.login(username="staff", password="testpass")

# Call the notify_matches view
response = self.client.get(reverse("notify_matches_view"))

# Check the response
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Match notifications have been sent.")

def test_reset_likes_view(self):
# Login as the staff user
self.client.login(username="staff", password="testpass")

# Call the reset_likes view
response = self.client.get(reverse("reset_likes_view"))

# Check the response
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Likes have been reset.")
Loading