Skip to content
Open
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: 3 additions & 1 deletion src/grimoirelab/core/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
TokenObtainPairView,
TokenRefreshView,
)
from ..views import api_login
from ..views import api_login, change_password

from grimoirelab.core.scheduler.urls import urlpatterns as sched_urlpatterns
from grimoirelab.core.datasources.urls import urlpatterns as datasources_urlpatterns


urlpatterns = [
path("login", api_login, name="api_login"),
path('password_change/', change_password, name='password_change'),
path("token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
path("scheduler/", include(sched_urlpatterns)),
Expand Down
18 changes: 18 additions & 0 deletions src/grimoirelab/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#

from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import PasswordChangeForm
from rest_framework import permissions
from rest_framework.decorators import (
api_view,
Expand Down Expand Up @@ -48,3 +49,20 @@ def api_login(request):
'isAdmin': user.is_superuser,
}
return Response(response)


@api_view(['POST'])
def change_password(request):
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
response = {
'updated': user.username
}
return Response(response)
else:
response = {
'errors': form.errors.get_json_data()
}

return Response(response, status=400)
97 changes: 97 additions & 0 deletions tests/unit/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) GrimoireLab Contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

from django.contrib.auth import get_user_model
from django.urls import reverse
from django.test import TestCase, Client


class TestViews(TestCase):
"""Unit tests for views."""

def setUp(self):
self.user = get_user_model().objects.create_user(
username='testuser',
password='testpassword'
)
self.client = Client()

def test_api_login(self):
"""Test the api_login view."""

url = reverse('api_login')
data = {
'username': 'testuser',
'password': 'testpassword'
}
response = self.client.post(url, data, format='json')

self.assertEqual(response.status_code, 200)
self.assertIn('user', response.data)
self.assertIn('isAdmin', response.data)

def test_api_login_invalid(self):
"""Test the api_login view with invalid credentials."""

url = reverse('api_login')
data = {
'username': 'testuser',
'password': 'wrongpassword'
}
response = self.client.post(url, data, format='json')

self.assertEqual(response.status_code, 403)
self.assertIn('errors', response.data)
self.assertEqual(response.data['errors'], 'Invalid credentials.')

def test_change_password(self):
"""Test the change_password view."""

self.client.login(username='testuser', password='testpassword')

url = reverse('password_change')
data = {
'old_password': 'testpassword',
'new_password1': 'TestNewPassword123',
'new_password2': 'TestNewPassword123'
}
response = self.client.post(url, data, format='json')

self.assertEqual(response.status_code, 200)
self.assertIn('updated', response.data)
self.assertEqual(response.data['updated'], 'testuser')

# Check if the password has been changed
self.user.refresh_from_db()
self.assertTrue(self.user.check_password('TestNewPassword123'))

def test_change_password_invalid(self):
"""Test the change_password view with invalid data."""

self.client.login(username='testuser', password='testpassword')

url = reverse('password_change')
data = {
'old_password': 'wrongpassword',
'new_password1': 'TestNewPassword123',
'new_password2': 'TestNewPassword123'
}
response = self.client.post(url, data, format='json')

self.assertEqual(response.status_code, 400)
self.assertIn('errors', response.data)