forked from hswaw/spejstore
Compare commits
1 Commits
master
...
storage-un
Author | SHA1 | Date |
---|---|---|
![]() |
76e0d405e0 |
|
@ -17,6 +17,14 @@ docker-compose up
|
|||
docker-compose build
|
||||
```
|
||||
|
||||
### Tests
|
||||
|
||||
Before test run containers. See "Build & run".
|
||||
|
||||
```sh
|
||||
docker-compose exec web python manage.py test --noinput
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
- https://askubuntu.com/q/615394/413683
|
||||
|
|
|
@ -14,3 +14,5 @@ pyldap==2.4.28
|
|||
requests==2.16.5
|
||||
urllib3==1.21.1
|
||||
django_markdown2==0.3.0
|
||||
factory-boy==2.11.1
|
||||
Faker==0.8.16
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.models import Group, User
|
||||
|
||||
from django_select2.forms import ModelSelect2Widget, Select2MultipleWidget
|
||||
from django_select2.forms import Select2MultipleWidget
|
||||
|
||||
from .models import Item, ItemImage, Category, Label
|
||||
from .widgets import ItemSelectWidget, PropsSelectWidget
|
||||
|
@ -36,7 +37,8 @@ class ItemAdmin(admin.ModelAdmin):
|
|||
inlines = [ItemImageInline, LabelInline]
|
||||
save_on_top = True
|
||||
|
||||
def _name(self, obj):
|
||||
@classmethod
|
||||
def _name(cls, obj):
|
||||
return '-' * obj.get_level() + '> ' + obj.name
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
|
@ -72,9 +74,5 @@ class ItemAdmin(admin.ModelAdmin):
|
|||
|
||||
admin.site.register(Item, ItemAdmin)
|
||||
admin.site.register(Category)
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.models import Group
|
||||
|
||||
admin.site.unregister(User)
|
||||
admin.site.unregister(Group)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from rest_framework import viewsets, generics, filters
|
||||
from rest_framework import viewsets, filters
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.decorators import detail_route
|
||||
from rest_framework.permissions import AllowAny
|
||||
|
@ -46,7 +46,6 @@ class ItemViewSet(viewsets.ModelViewSet):
|
|||
filter_backends = (SmartSearchFilterBackend, filters.OrderingFilter)
|
||||
ordering_fields = '__all__'
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
return Item.get_roots()
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
from factory import LazyAttribute, SubFactory
|
||||
from factory.django import DjangoModelFactory
|
||||
from faker import Faker
|
||||
from random import randint
|
||||
from tree.fields import Path
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from .models import Category, Item, ItemImage, Label, STATES
|
||||
|
||||
fake = Faker('pl_PL')
|
||||
|
||||
|
||||
class UserFactory(DjangoModelFactory):
|
||||
"""
|
||||
Creates and returns instance of User model
|
||||
"""
|
||||
username = LazyAttribute(lambda n: '{}{}'.format(fake.user_name(), randint(0, 100000)))
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
||||
|
||||
class CategoryFactory(DjangoModelFactory):
|
||||
"""
|
||||
Creates and returns instance of Category
|
||||
"""
|
||||
name = 'elektronika'
|
||||
icon_id = 'elka'
|
||||
|
||||
class Meta:
|
||||
model = Category
|
||||
|
||||
|
||||
class ItemFactory(DjangoModelFactory):
|
||||
"""
|
||||
Creates and returns instance of Item
|
||||
"""
|
||||
path = Path(field='field1', value='path1')
|
||||
name = 'śrubokręt'
|
||||
description = 'czerwony śrubokręt krzyżakowy'
|
||||
state = STATES[0][0]
|
||||
|
||||
class Meta:
|
||||
model = Item
|
||||
|
||||
|
||||
class ItemImageFactory(DjangoModelFactory):
|
||||
"""
|
||||
Creates and returns instance of ItemImage and creates related Item
|
||||
"""
|
||||
item = SubFactory(ItemFactory)
|
||||
|
||||
class Meta:
|
||||
model = ItemImage
|
||||
|
||||
|
||||
class LabelFactory(DjangoModelFactory):
|
||||
"""
|
||||
Creates and returns instance of Label and creates related Item
|
||||
"""
|
||||
item = SubFactory(ItemFactory)
|
||||
|
||||
class Meta:
|
||||
model = Label
|
|
@ -1,8 +1,9 @@
|
|||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.core.management.base import BaseCommand
|
||||
from storage.models import Item
|
||||
from io import StringIO
|
||||
import csv
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Imports book library from specified wiki page dump'
|
||||
|
||||
|
|
|
@ -8,9 +8,11 @@ class ItemSerializer(HStoreSerializer):
|
|||
model = Item
|
||||
fields = ('uuid', 'name', 'description', 'props', 'state', 'parent')
|
||||
|
||||
|
||||
class LabelSerializer(serializers.ModelSerializer):
|
||||
item = ItemSerializer(required=False)
|
||||
item_id = serializers.PrimaryKeyRelatedField(queryset=Item.objects, source='item')
|
||||
|
||||
class Meta:
|
||||
model = Label
|
||||
fields = ('id', 'item', 'item_id', 'style')
|
||||
|
|
111
storage/tests.py
111
storage/tests.py
|
@ -1,3 +1,112 @@
|
|||
from django.contrib.auth.models import User
|
||||
from django.shortcuts import reverse
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
from .factories import CategoryFactory, ItemFactory, ItemImageFactory, LabelFactory, UserFactory
|
||||
from .models import Category, Item, ItemImage, Label
|
||||
|
||||
|
||||
class ModelsTestCase(TestCase):
|
||||
"""
|
||||
Test factories and models
|
||||
"""
|
||||
def test_user_factory(self):
|
||||
"""
|
||||
Test user creation
|
||||
"""
|
||||
u1 = UserFactory()
|
||||
u2 = UserFactory(email='kowalski@example.com')
|
||||
|
||||
self.assertIsInstance(u1, User)
|
||||
self.assertIsInstance(u2, User)
|
||||
|
||||
def test_category_factory(self):
|
||||
"""
|
||||
test category creation
|
||||
"""
|
||||
c = CategoryFactory()
|
||||
|
||||
self.assertIsInstance(c, Category)
|
||||
|
||||
def test_category_model(self):
|
||||
"""
|
||||
create category instance
|
||||
"""
|
||||
c = CategoryFactory(
|
||||
name='Elektronika',
|
||||
icon_id='elektronika-icon-id',
|
||||
)
|
||||
self.assertIsInstance(c, Category)
|
||||
|
||||
# TODO: create tests for Item and ItemImage and Label models
|
||||
# TODO: create tests for parent items
|
||||
|
||||
def test_item_factory(self):
|
||||
"""
|
||||
test item creation
|
||||
"""
|
||||
i = ItemFactory()
|
||||
|
||||
self.assertIsInstance(i, Item)
|
||||
|
||||
def test_item_image_factory(self):
|
||||
"""
|
||||
test item creation
|
||||
"""
|
||||
ii = ItemImageFactory()
|
||||
|
||||
self.assertIsInstance(ii, ItemImage)
|
||||
|
||||
def test_get_or_create_label(self):
|
||||
"""
|
||||
test get_or_create_label method
|
||||
"""
|
||||
i = ItemFactory()
|
||||
|
||||
obj = i.get_or_create_label()
|
||||
|
||||
self.assertIsInstance(obj, Label)
|
||||
|
||||
def test_label_factory(self):
|
||||
"""
|
||||
test label creation
|
||||
"""
|
||||
label = LabelFactory()
|
||||
|
||||
self.assertIsInstance(label, Label)
|
||||
|
||||
|
||||
class ViewsTestCase(TestCase):
|
||||
def setUp(self):
|
||||
"""
|
||||
Create some models
|
||||
"""
|
||||
c = CategoryFactory(
|
||||
name='Elektronika',
|
||||
icon_id='elektronika-icon-id',
|
||||
)
|
||||
i = ItemFactory(name='butelka')
|
||||
i.categories.add(c)
|
||||
|
||||
i = ItemFactory(name='nakrętka')
|
||||
i.categories.add(c)
|
||||
|
||||
def test_search_view(self):
|
||||
"""
|
||||
test search with query
|
||||
"""
|
||||
url = reverse('item-search')
|
||||
self.assertEqual('/search', url)
|
||||
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertTemplateUsed(response, 'results.html')
|
||||
|
||||
# Additional, try to check some content
|
||||
self.assertEqual(2, len(response.context[0]['results']))
|
||||
for item in response.context[0]['results']:
|
||||
self.assertIsInstance(item, Item)
|
||||
|
||||
# TODO: create tests for other views
|
||||
# TODO: test searching items
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from django.conf.urls import include, url
|
||||
from django.conf.urls import url
|
||||
from storage.views import (
|
||||
index, search, item_display, label_lookup, ItemSelectView, PropSelectView
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', index),
|
||||
url(r'^search$', search),
|
||||
url(r'^search$', search, name='item-search'),
|
||||
url(r'^item/(?P<pk>.*)$', item_display, name='item-display'),
|
||||
url(r'^autocomplete.json$', ItemSelectView.as_view(), name='item-complete'),
|
||||
url(r'^autocomplete_prop.json$', PropSelectView.as_view(), name='prop-complete'),
|
||||
|
|
|
@ -31,7 +31,10 @@ class PropsSelectWidget(DictionaryFieldWidget):
|
|||
attrs = {}
|
||||
# it's called "original" because it will be replaced by a copy
|
||||
attrs['class'] = 'hstore-original-textarea'
|
||||
w = HeavySelect2Widget(data_view='prop-complete', attrs={'data-tags': 'true', 'class': 'hs-key'})
|
||||
w = HeavySelect2Widget(
|
||||
data_view='prop-complete',
|
||||
attrs={'data-tags': 'true', 'class': 'hs-key'},
|
||||
)
|
||||
|
||||
# get default HTML from AdminTextareaWidget
|
||||
html = AdminTextareaWidget.render(self, name, value, attrs)
|
||||
|
|
Loading…
Reference in New Issue