Skip to content
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,7 @@ venv.bak/


#postgres-data
postgres-data/
postgres-data/

#vscode Visual Code Studio
.vscode/
25 changes: 0 additions & 25 deletions .vscode/launch.json

This file was deleted.

3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ services:
command: postgres -c listen_addresses='*'
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
command: sh -c "python manage.py wait_for_db && python manage.py runserver 0.0.0.0:8000"
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
- migration
migration:
build: .
Expand Down
32 changes: 28 additions & 4 deletions shop/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.contrib.admin import AdminSite
from .models import (Category, Product, OrderItem,
Order, Cart, CartItem, User)
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.utils.translation import gettext as _


class PythonShopAdminSite(AdminSite):
Expand All @@ -13,9 +15,8 @@ class PythonShopAdminSite(AdminSite):

class ProductAdmin(admin.ModelAdmin):
list_display = [field.name for field in Product._meta.fields
if field.name != "id" or field.name != 'updated_at'
or field.name != 'created_at'
or field.name != 'deleted_at'
if field.name != "id" or field.name != 'updated_at' or
field.name != 'created_at' or field.name != 'deleted_at'
]
exclude = ('deleted_at',)

Expand All @@ -24,6 +25,29 @@ class CategoryAdmin(admin.ModelAdmin):
exclude = ('deleted_at',)


class UserAdmin(BaseUserAdmin):
ordering = ['id']
list_display = ['email', 'firstname']
fieldsets = (
(None, {'fields': ('email', 'password')}),
(
_('Personal Info'),
{'fields': ('firstname', 'lastname', 'second_lastname')}
),
(
_('Permissions'),
{'fields': ('is_active', 'is_staff', 'is_superuser')}
),
(_('Important dates'), {'fields': ('last_login',)})
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2')
}),
)


admin_site = PythonShopAdminSite(name='shop_admin')

# Register your models here.
Expand All @@ -33,4 +57,4 @@ class CategoryAdmin(admin.ModelAdmin):
admin_site.register(OrderItem)
admin_site.register(Cart)
admin_site.register(CartItem)
admin_site.register(User)
admin_site.register(User, UserAdmin)
Empty file added shop/management/__init__.py
Empty file.
Empty file.
21 changes: 21 additions & 0 deletions shop/management/commands/wait_for_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import time

from django.db import connections
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand


class Command(BaseCommand):
"""Django commando to pause execution until database is available"""

def handle(self, *args, **options):
self.stdout.write('Waiting for database...')
db_conn = None
while not db_conn:
try:
db_conn = connections['default']
except OperationalError:
self.stdout.write('Database unavailable, waiting 1 second...')
time.sleep(1)

self.stdout.write(self.style.SUCCESS('Database available!'))
Empty file added shop/tests/__init__.py
Empty file.
41 changes: 41 additions & 0 deletions shop/tests/test_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from django.test import TestCase, Client
from django.contrib.auth import get_user_model
from django.urls import reverse


class AdminSiteTests(TestCase):

def setUp(self):
self.client = Client()
self.admin_user = get_user_model().objects.create_superuser(
email='test@test.com',
password='test123'
)
self.client.force_login(self.admin_user)
self.user = get_user_model().objects.create_user(
email='another@test.com',
password='password123',
firstname='Testing first name'
)

def test_users_listed(self):
"""Test that users are listed on user page of admin"""
url = reverse('admin:shop_user_changelist')
response = self.client.get(url)

self.assertContains(response, self.user.firstname)
self.assertContains(response, self.user.email)

def test_user_change_page(self):
"""Test that the user edit page works"""
url = reverse('admin:shop_user_change', args=[self.user.id])
response = self.client.get(url)

self.assertEqual(response.status_code, 200)

def test_create_user_page(self):
"""Test that the create user page works"""
url = reverse('admin:shop_user_add')
response = self.client.get(url)

self.assertEqual(response.status_code, 200)
23 changes: 23 additions & 0 deletions shop/tests/test_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from unittest.mock import patch

from django.core.management import call_command
from django.db.utils import OperationalError
from django.test import TestCase


class CommandTests(TestCase):

def test_wait_for_db_ready(self):
"""Test waiting for db when db is available"""
with patch('django.db.utils.ConnectionHandler.__getitem__') as gi:
gi.return_value = True
call_command('wait_for_db')
self.assertEqual(gi.call_count, 1)

@patch('time.sleep', return_value=True)
def test_wait_for_db(self, ts):
"""Test waiting for db"""
with patch('django.db.utils.ConnectionHandler.__getitem__') as gi:
gi.side_effect = [OperationalError] * 5 + [True]
call_command('wait_for_db')
self.assertEqual(gi.call_count, 6)
File renamed without changes.