-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dev' into bugfix/router-basename
- Loading branch information
Showing
11 changed files
with
222 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from django.contrib import admin | ||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin | ||
from django.contrib.auth.models import User | ||
|
||
from tom_common.models import Profile | ||
|
||
|
||
# Define an inline admin descriptor for the TomUser model | ||
# which acts a bit like a singleton | ||
class TomUserInline(admin.StackedInline): | ||
model = Profile | ||
can_delete = False | ||
verbose_name_plural = "profiles" | ||
|
||
|
||
# Define a new User admin | ||
class UserAdmin(BaseUserAdmin): | ||
inlines = [TomUserInline] | ||
|
||
|
||
# Re-register UserAdmin | ||
admin.site.unregister(User) | ||
admin.site.register(User, UserAdmin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Generated by Django 4.2.16 on 2024-11-22 22:08 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Profile', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('affiliation', models.CharField(blank=True, max_length=100, null=True)), | ||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | ||
], | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,21 @@ | ||
from django.conf import settings | ||
from django.db.models.signals import post_save | ||
from django.db import models | ||
from django.dispatch import receiver | ||
from django.contrib.auth.models import User | ||
from rest_framework.authtoken.models import Token | ||
|
||
|
||
@receiver(post_save, sender=settings.AUTH_USER_MODEL) | ||
def create_auth_token(sender, instance=None, created=False, **kwargs): | ||
if created: | ||
Token.objects.create(user=instance) | ||
|
||
|
||
class Profile(models.Model): | ||
"""Profile model for a TOMToolkit User""" | ||
user = models.OneToOneField(User, on_delete=models.CASCADE) | ||
affiliation = models.CharField(max_length=100, null=True, blank=True) | ||
|
||
def __str__(self): | ||
return f'{self.user.username} Profile' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from django.db.models.signals import post_save | ||
from django.contrib.auth.models import User | ||
from django.dispatch import receiver | ||
from tom_common.models import Profile | ||
|
||
|
||
@receiver(post_save, sender=User) | ||
def create_profile(sender, instance, created, **kwargs): | ||
"""When a new user is created, create a profile for them.""" | ||
if created: | ||
Profile.objects.create(user=instance) | ||
|
||
|
||
@receiver(post_save, sender=User) | ||
def save_profile(sender, instance, **kwargs): | ||
"""When a user is saved, save their profile.""" | ||
# Take advantage of the fact that logging in updates a user's last_login field | ||
# to create a profile for users that don't have one. | ||
try: | ||
instance.profile.save() | ||
except User.profile.RelatedObjectDoesNotExist: | ||
Profile.objects.create(user=instance) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
from django_comments.models import Comment | ||
|
||
from tom_targets.tests.factories import SiderealTargetFactory | ||
from tom_common.templatetags.tom_common_extras import verbose_name | ||
|
||
|
||
class TestCommonViews(TestCase): | ||
|
@@ -26,6 +27,17 @@ def test_index(self): | |
self.assertEqual(response.status_code, 200) | ||
|
||
|
||
class TestCommonExtras(TestCase): | ||
def setUp(self): | ||
pass | ||
|
||
def test_verbose_name(self): | ||
# Check that the verbose name for a model field is returned correctly | ||
self.assertEqual(verbose_name(User, 'email'), 'Email Address') | ||
# Check that the verbose name for a non-existent field is returned correctly | ||
self.assertEqual(verbose_name(User, 'definitely_not_a_field'), 'Definitely_Not_A_Field') | ||
|
||
|
||
class TestUserManagement(TestCase): | ||
def setUp(self): | ||
self.admin = User.objects.create_superuser(username='admin', password='admin', email='[email protected]') | ||
|
@@ -38,6 +50,8 @@ def test_user_list(self): | |
|
||
def test_user_create(self): | ||
user_data = { | ||
'profile-TOTAL_FORMS': '1', | ||
'profile-INITIAL_FORMS': '0', | ||
'username': 'testuser', | ||
'first_name': 'first', | ||
'last_name': 'last', | ||
|
@@ -83,6 +97,8 @@ def test_user_can_update_self(self): | |
user = User.objects.create(username='luke', password='forc3') | ||
self.client.force_login(user) | ||
user_data = { | ||
'profile-TOTAL_FORMS': '1', | ||
'profile-INITIAL_FORMS': '0', | ||
'username': 'luke', | ||
'first_name': 'Luke', | ||
'last_name': 'Skywalker', | ||
|
@@ -99,6 +115,8 @@ def test_user_cannot_update_other(self): | |
user = User.objects.create(username='luke', password='forc3') | ||
self.client.force_login(user) | ||
user_data = { | ||
'profile-TOTAL_FORMS': '1', | ||
'profile-INITIAL_FORMS': '0', | ||
'username': 'luke', | ||
'first_name': 'Luke', | ||
'last_name': 'Skywalker', | ||
|
@@ -111,6 +129,37 @@ def test_user_cannot_update_other(self): | |
self.assertRedirects(response, reverse('user-update', kwargs={'pk': user.id})) | ||
self.assertNotEqual(self.admin.username, user_data['username']) | ||
|
||
def test_user_can_delete_self(self): | ||
user = User.objects.create(username='luke', password='forc3') | ||
self.client.force_login(user) | ||
self.assertTrue(User.objects.filter(username='luke').exists()) | ||
response = self.client.post(reverse('user-delete', kwargs={'pk': user.id}), follow=True) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertFalse(User.objects.filter(username='luke').exists()) | ||
|
||
|
||
class TestUserProfile(TestCase): | ||
def setUp(self): | ||
self.admin = User.objects.create_superuser(username='admin', password='admin', email='[email protected]') | ||
self.client.force_login(self.admin) | ||
|
||
def test_user_profile(self): | ||
user_data = { | ||
'profile-TOTAL_FORMS': '1', | ||
'profile-INITIAL_FORMS': '0', | ||
'username': 'testuser', | ||
'first_name': 'first', | ||
'last_name': 'last', | ||
'email': '[email protected]', | ||
'password1': 'suchsecure543', | ||
'password2': 'suchsecure543', | ||
'profile-0-affiliation': 'Test University', | ||
} | ||
response = self.client.post(reverse('user-create'), data=user_data, follow=True) | ||
self.assertEqual(response.status_code, 200) | ||
user = User.objects.get(username='testuser') | ||
self.assertEqual(user.profile.affiliation, 'Test University') | ||
|
||
|
||
class TestAuthScheme(TestCase): | ||
@override_settings(AUTH_STRATEGY='LOCKED') | ||
|