Fix unit tests
This commit is contained in:
parent
c2e2d596b2
commit
0ad8706625
|
|
@ -103,7 +103,6 @@ THIRD_PARTY_APPS = [
|
||||||
|
|
||||||
LOCAL_APPS = [
|
LOCAL_APPS = [
|
||||||
"vbv_lernwelt.core",
|
"vbv_lernwelt.core",
|
||||||
"vbv_lernwelt.simpletodo",
|
|
||||||
"vbv_lernwelt.sso",
|
"vbv_lernwelt.sso",
|
||||||
"vbv_lernwelt.learnpath",
|
"vbv_lernwelt.learnpath",
|
||||||
"vbv_lernwelt.completion",
|
"vbv_lernwelt.completion",
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ urlpatterns = [
|
||||||
path('admin/raise_error/', user_passes_test(lambda u: u.is_superuser, login_url='/login/')(raise_example_error), ),
|
path('admin/raise_error/', user_passes_test(lambda u: u.is_superuser, login_url='/login/')(raise_example_error), ),
|
||||||
path(settings.ADMIN_URL, admin.site.urls),
|
path(settings.ADMIN_URL, admin.site.urls),
|
||||||
path("checkratelimit/", check_rate_limit),
|
path("checkratelimit/", check_rate_limit),
|
||||||
path("todo/", include("vbv_lernwelt.simpletodo.urls")),
|
|
||||||
path("sso/", include("vbv_lernwelt.sso.urls")),
|
path("sso/", include("vbv_lernwelt.sso.urls")),
|
||||||
path('cms/', include(wagtailadmin_urls)),
|
path('cms/', include(wagtailadmin_urls)),
|
||||||
path('documents/', include(wagtaildocs_urls)),
|
path('documents/', include(wagtaildocs_urls)),
|
||||||
|
|
|
||||||
|
|
@ -4,25 +4,21 @@ from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from vbv_lernwelt.core.create_default_users import create_default_users
|
from vbv_lernwelt.core.create_default_users import create_default_users
|
||||||
from vbv_lernwelt.core.models import User
|
from vbv_lernwelt.core.models import User
|
||||||
|
from vbv_lernwelt.core.tests.helpers import create_locales_for_wagtail
|
||||||
from vbv_lernwelt.learnpath.models import LearningContent
|
from vbv_lernwelt.learnpath.models import LearningContent
|
||||||
from vbv_lernwelt.learnpath.tests.create_default_learning_path import create_default_learning_path
|
from vbv_lernwelt.learnpath.tests.create_simple_test_learning_path import create_simple_test_learning_path
|
||||||
from vbv_lernwelt.learnpath.tests.test_create_default_learning_path import create_locales_for_wagtail
|
|
||||||
|
|
||||||
|
|
||||||
class CompletionApiTestCase(APITestCase):
|
class CompletionApiTestCase(APITestCase):
|
||||||
@classmethod
|
def setUp(self) -> None:
|
||||||
def setUpClass(cls) -> None:
|
|
||||||
super(CompletionApiTestCase, cls).setUpClass()
|
|
||||||
create_locales_for_wagtail()
|
create_locales_for_wagtail()
|
||||||
create_default_users()
|
create_default_users()
|
||||||
create_default_learning_path()
|
create_simple_test_learning_path()
|
||||||
|
|
||||||
def setUp(self) -> None:
|
|
||||||
self.user = User.objects.get(username='student')
|
self.user = User.objects.get(username='student')
|
||||||
self.client.login(username='student', password='test')
|
self.client.login(username='student', password='test')
|
||||||
|
|
||||||
def test_completeLearningContent_works(self):
|
def test_completeLearningContent_works(self):
|
||||||
learning_content = LearningContent.objects.get(title='Einleitung Circle "Anlayse"')
|
learning_content = LearningContent.objects.get(title='Einleitung Circle "Unit-Test Circle"')
|
||||||
learning_content_key = str(learning_content.translation_key)
|
learning_content_key = str(learning_content.translation_key)
|
||||||
circle_key = str(learning_content.get_parent().translation_key)
|
circle_key = str(learning_content.get_parent().translation_key)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import djclick as click
|
import djclick as click
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.tests.create_default_learning_path import create_default_learning_path, \
|
from vbv_lernwelt.learnpath.create_default_learning_path import create_default_learning_path, \
|
||||||
delete_default_learning_path
|
delete_default_learning_path
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from wagtail.models import Locale
|
||||||
|
|
||||||
|
|
||||||
|
def create_locales_for_wagtail():
|
||||||
|
for language in settings.WAGTAIL_CONTENT_LANGUAGES:
|
||||||
|
Locale.objects.get_or_create(language_code=language[0])
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from vbv_lernwelt.core.models import User
|
|
||||||
from vbv_lernwelt.core.tests.factories import UserFactory
|
|
||||||
from vbv_lernwelt.simpletodo.models import SimpleList
|
|
||||||
|
|
||||||
|
|
||||||
class TestUserCreation(TestCase):
|
|
||||||
def test_create_user(self):
|
|
||||||
User(last_name='Sepp').save()
|
|
||||||
|
|
||||||
def test_simple(self):
|
|
||||||
# create_default_learning_path()
|
|
||||||
self.user = UserFactory()
|
|
||||||
SimpleList.objects.get_or_create(title='Default', user=self.user)
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import djclick as click
|
import djclick as click
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.tests.create_default_learning_path import create_default_learning_path
|
from vbv_lernwelt.learnpath.create_default_learning_path import create_default_learning_path
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import djclick as click
|
import djclick as click
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.tests.create_default_learning_path import delete_default_learning_path
|
from vbv_lernwelt.learnpath.create_default_learning_path import delete_default_learning_path
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
# Create your models here.
|
from django.db import models
|
||||||
|
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from wagtail import blocks
|
from wagtail import blocks
|
||||||
|
from wagtail.admin.panels import FieldPanel, StreamFieldPanel
|
||||||
from wagtail.blocks import StreamBlock
|
from wagtail.blocks import StreamBlock
|
||||||
from wagtail.fields import StreamField
|
from wagtail.fields import StreamField
|
||||||
from wagtail.images.blocks import ImageChooserBlock
|
from wagtail.images.blocks import ImageChooserBlock
|
||||||
from wagtail.models import Page, Orderable
|
from wagtail.models import Page, Orderable
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.models_competences import *
|
|
||||||
from vbv_lernwelt.learnpath.models_learning_unit_content import WebBasedTrainingBlock, VideoBlock, PodcastBlock, \
|
from vbv_lernwelt.learnpath.models_learning_unit_content import WebBasedTrainingBlock, VideoBlock, PodcastBlock, \
|
||||||
CompetenceBlock, ExerciseBlock, DocumentBlock, KnowledgeBlock
|
CompetenceBlock, ExerciseBlock, DocumentBlock, KnowledgeBlock
|
||||||
from vbv_lernwelt.learnpath.serializer_helpers import get_it_serializer_class
|
from vbv_lernwelt.learnpath.serializer_helpers import get_it_serializer_class
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
from django.db import models
|
|
||||||
from wagtail.models import Page, Orderable
|
|
||||||
from modelcluster.fields import ParentalKey
|
|
||||||
from wagtail.admin.panels import FieldPanel, StreamFieldPanel, InlinePanel
|
|
||||||
|
|
||||||
|
|
||||||
class CompetencePage(Page):
|
|
||||||
"""This is the page where the competences and Fullfillment criterias are manged
|
|
||||||
For one Learning Path"""
|
|
||||||
|
|
||||||
|
|
||||||
content_panels = Page.content_panels + [
|
|
||||||
InlinePanel('competences', label="Competences"),
|
|
||||||
]
|
|
||||||
|
|
||||||
subpage_types = ['learnpath.Circle']
|
|
||||||
|
|
||||||
parent_page_types = ['learnpath.LearningPath']
|
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "Learning Path"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.title}"
|
|
||||||
|
|
||||||
|
|
||||||
class Competence(Orderable):
|
|
||||||
""" In VBV Terms this is a "Handlungskompetenz"""
|
|
||||||
category_short = models.CharField(max_length=3, default='')
|
|
||||||
name = models.CharField(max_length=2048)
|
|
||||||
|
|
||||||
|
|
||||||
competence_page = ParentalKey('learnpath.CompetencePage',
|
|
||||||
null=True,
|
|
||||||
blank=True,
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='competences',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_short_info(self):
|
|
||||||
return f"{self.category_short}{self.sort_order}"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.get_short_info()}: {self.name}"
|
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "Competence"
|
|
||||||
|
|
||||||
|
|
||||||
class FullfillmentCriteria(Orderable):
|
|
||||||
""" VBV Term Leistungskriterium"""
|
|
||||||
name = models.CharField(max_length=2048)
|
|
||||||
competence = models.ForeignKey(Competence, on_delete=models.CASCADE, null=True)
|
|
||||||
|
|
||||||
def get_short_info(self):
|
|
||||||
return f"{self.competence.get_short_info()}.{self.sort_order}"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.get_short_info()}: {self.name}"
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "Fullfillment Criteria"
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
{
|
|
||||||
"competences": [
|
|
||||||
{
|
|
||||||
"name": "Weiterempfehlung für Neukunden generieren",
|
|
||||||
"category_short": "A",
|
|
||||||
"fullfillment_criteria": [
|
|
||||||
{
|
|
||||||
"name": "bestehende Kunden so zu beraten, dass sie von diesen weiterempfohlen werden"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "geeignete Personen wie z.B. Garagisten, Architekten, Treuhänder auf die Vermittlung/Zusammenarbeit anzusprechen"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "verschiedene Datenquellen wie Internet, Telefonbuch, Handelszeitung, Baugesuche etc. gezielt für die Gewinnung von Neukunden zu benützen"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ein beliebiges Gespräch resp. einen bestehenden Kontakt in die Richtung «Versicherung» zu lenken"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "das Thema Risiko und Sicherheit in einem Gespräch gezielt und auf die Situation des jeweiligen Gesprächspartners bezogen einfliessen zu lassen"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "im täglichen Kontakt potentielle Kundinnen und Kunden zu erkennen"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Kundengespräche vereinbaren",
|
|
||||||
"category_short": "A",
|
|
||||||
"fullfillment_criteria": [
|
|
||||||
{
|
|
||||||
"name": "je nach (Neu-) Kunde Form und Ort für das Gespräch festzulegen"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sich intern und extern die nötigen Informationen über den (Neu-) Kunde zu beschaffen"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "die Terminierung auf ein bestimmtes Thema wie z.B. Rechtsschutz, Vorsorge, Krankenversicherung etc. auszurichten"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "für das zu führende Gespräch eine Agenda zu erstellen"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "für das zu führende Gespräch geeignete Hilfsmittel und Unterlagen zusammenzustellen"
|
|
||||||
}, {
|
|
||||||
"name": "eine Kaltakquise durchzuführen und auf mögliche Einwände reagieren zu können"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Auftritt in den sozialen Medien zeitgemäss halten",
|
|
||||||
"category_short": "A",
|
|
||||||
"fullfillment_criteria": [ {
|
|
||||||
"name": "in Zusammenarbeit mit den IT-Spezialisten und der Marketingabteilung die Inhalte für den zu realisierenden Medienauftritt zielgruppengerecht festzulegen"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "für die verschiedenen Kundensegmente die passenden sozialen Medien zu definieren"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "die Inhalte compliant zu halten"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Kundendaten erfassen",
|
|
||||||
"category_short": "A",
|
|
||||||
"fullfillment_criteria": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Wünsche, Ziele und Bedürfnisse der Kunden im Gespräch ermitteln",
|
|
||||||
"category_short": "B",
|
|
||||||
"fullfillment_criteria": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import factory
|
|
||||||
import wagtail_factories
|
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.models_competences import Competence, FullfillmentCriteria, CompetencePage
|
|
||||||
from vbv_lernwelt.learnpath.tests.learning_path_factories import LearningPathFactory
|
|
||||||
|
|
||||||
|
|
||||||
class CompetencePageFactory(wagtail_factories.PageFactory):
|
|
||||||
# learning_path = factory.SubFactory(LearningPathFactory)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = CompetencePage
|
|
||||||
|
|
||||||
|
|
||||||
class CompetenceFactory(factory.django.DjangoModelFactory):
|
|
||||||
category_short = 'A'
|
|
||||||
name = "Weiterempfehung für neukunden generieren"
|
|
||||||
competence_page = factory.SubFactory(CompetencePageFactory)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Competence
|
|
||||||
|
|
||||||
|
|
||||||
class FullfilmentCriteriaFactory(factory.django.DjangoModelFactory):
|
|
||||||
name = 'Bestehende Kunden so zu beraten, dass sie von diesen weiterempfohlen werden'
|
|
||||||
competence = factory.SubFactory(CompetenceFactory)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = FullfillmentCriteria
|
|
||||||
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
import json
|
|
||||||
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.tests.competences_factories import CompetenceFactory, FullfilmentCriteriaFactory
|
|
||||||
|
|
||||||
competences_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'competences.json')
|
|
||||||
|
|
||||||
|
|
||||||
def create_default_competences(competences_json=competences_file):
|
|
||||||
with open(competences_json) as f:
|
|
||||||
competences_json = json.load(f)
|
|
||||||
|
|
||||||
for index, compentence in enumerate(competences_json['competences']):
|
|
||||||
|
|
||||||
competence_model = CompetenceFactory(name=compentence['name'], category_short=compentence['category_short'], sort_order=index)
|
|
||||||
print(competence_model)
|
|
||||||
|
|
||||||
for criteria_index, criteria in enumerate(compentence['fullfillment_criteria']):
|
|
||||||
criteria_model = FullfilmentCriteriaFactory(name=criteria['name'], competence=competence_model, sort_order=criteria_index)
|
|
||||||
print(criteria_model)
|
|
||||||
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
GET http://localhost:8000/graphql/
|
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
###
|
|
||||||
{
|
|
||||||
page(id: 8) {
|
|
||||||
|
|
||||||
children {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
title
|
|
||||||
children {
|
|
||||||
__typename
|
|
||||||
|
|
||||||
id
|
|
||||||
title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
page(id: 8) {
|
|
||||||
|
|
||||||
children {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
title
|
|
||||||
children {
|
|
||||||
__typename
|
|
||||||
|
|
||||||
id
|
|
||||||
title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -2,44 +2,30 @@ from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from vbv_lernwelt.core.admin import User
|
from vbv_lernwelt.core.admin import User
|
||||||
from vbv_lernwelt.core.create_default_users import create_default_users
|
from vbv_lernwelt.core.create_default_users import create_default_users
|
||||||
from vbv_lernwelt.learnpath.models import LearningPath, Circle
|
from vbv_lernwelt.core.tests.helpers import create_locales_for_wagtail
|
||||||
from vbv_lernwelt.learnpath.tests.create_default_learning_path import create_default_learning_path
|
from vbv_lernwelt.learnpath.models import LearningPath
|
||||||
from vbv_lernwelt.learnpath.tests.test_create_default_learning_path import create_locales_for_wagtail
|
from vbv_lernwelt.learnpath.tests.create_simple_test_learning_path import create_simple_test_learning_path
|
||||||
|
|
||||||
|
|
||||||
class TestRetrieveLearingPathContents(APITestCase):
|
class TestRetrieveLearingPathContents(APITestCase):
|
||||||
@classmethod
|
def setUp(self) -> None:
|
||||||
def setUpClass(cls) -> None:
|
|
||||||
super(TestRetrieveLearingPathContents, cls).setUpClass()
|
|
||||||
create_locales_for_wagtail()
|
create_locales_for_wagtail()
|
||||||
create_default_users()
|
create_default_users()
|
||||||
create_default_learning_path()
|
create_simple_test_learning_path()
|
||||||
|
|
||||||
def setUp(self) -> None:
|
self.user = User.objects.get(username='student')
|
||||||
qs = LearningPath.objects.filter(title="Versicherungsvermittler/in")
|
self.client.login(username='student', password='test')
|
||||||
self.credentials = {
|
|
||||||
'username': 'admin',
|
|
||||||
'password': 'admin'}
|
|
||||||
|
|
||||||
user = User.objects.get(username='admin')
|
def test_get_learnpathPage(self):
|
||||||
self.client.force_authenticate(user=user)
|
learning_path = LearningPath.objects.get(slug='unit-test-lernpfad')
|
||||||
self.client.post('/login/', self.credentials, follow=True)
|
response = self.client.get('/learnpath/api/page/unit-test-lernpfad/')
|
||||||
|
print(response)
|
||||||
def test_get_circle(self):
|
|
||||||
circle = Circle.objects.get(slug='analyse')
|
|
||||||
response = self.client.get(f'/wagtailapi/v2/pages/{circle.id}/')
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.data['title'], 'Analyse')
|
data = response.json()
|
||||||
|
# print(data)
|
||||||
|
|
||||||
def test_get_circle_has_learning_sequences(self):
|
self.assertEqual(learning_path.title, data['title'])
|
||||||
circle = Circle.objects.get(slug='analyse')
|
# topic and circle
|
||||||
response = self.client.get(f'/wagtailapi/v2/pages/{circle.id}/')
|
self.assertEqual(2, len(data['children']))
|
||||||
self.assertTrue(len(response.data['learning_sequences']) > 2)
|
# circle "unit-test-circle" contents
|
||||||
self.assertEqual(response.data['learning_sequences'][0]['title'], 'Starten')
|
self.assertEqual(13, len(data['children'][1]['children']))
|
||||||
|
|
||||||
|
|
||||||
def test_get_circle_has_learning_sequences_learningpackages(self):
|
|
||||||
circle = Circle.objects.get(slug='analyse')
|
|
||||||
response = self.client.get(f'/wagtailapi/v2/pages/{circle.id}/')
|
|
||||||
self.assertTrue(len(response.data['learning_sequences'][0]['learnging_packages']) > 1)
|
|
||||||
self.assertTrue(response.data['learning_sequences'][0]['learnging_packages'][0]['title'])
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.models_competences import Competence, FullfillmentCriteria
|
|
||||||
from vbv_lernwelt.learnpath.tests.competences_factories import CompetencePageFactory, CompetenceFactory, \
|
|
||||||
FullfilmentCriteriaFactory
|
|
||||||
|
|
||||||
|
|
||||||
class TestCompetencesFactories(TestCase):
|
|
||||||
def test_create_competences_page(self):
|
|
||||||
CompetencePageFactory()
|
|
||||||
|
|
||||||
def test_create_competence(self):
|
|
||||||
CompetenceFactory(name='Boogie Woogie')
|
|
||||||
self.assertEqual(Competence.objects.filter(name='Boogie Woogie').count(), 1)
|
|
||||||
|
|
||||||
def test_create_fullfillment_criteria(self):
|
|
||||||
FullfilmentCriteriaFactory(name='shuffle like ...')
|
|
||||||
self.assertEqual(FullfillmentCriteria.objects.filter(name='shuffle like ...').count(), 1)
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from vbv_lernwelt.learnpath.tests.create_default_competences import create_default_competences
|
|
||||||
|
|
||||||
|
|
||||||
class TestCreateDefaultCompetences(TestCase):
|
|
||||||
def test_create_default_competeneces(self):
|
|
||||||
create_default_competences()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
from django.conf import settings
|
|
||||||
from django.test import TestCase
|
|
||||||
from wagtail.models import Locale
|
|
||||||
|
|
||||||
from vbv_lernwelt.core.create_default_users import create_default_users
|
|
||||||
from vbv_lernwelt.learnpath.models import LearningPath
|
|
||||||
from vbv_lernwelt.learnpath.tests.create_default_learning_path import create_default_learning_path
|
|
||||||
|
|
||||||
|
|
||||||
class TestCreateDefaultLearningPaths(TestCase):
|
|
||||||
def setUp(self) -> None:
|
|
||||||
create_default_users()
|
|
||||||
create_locales_for_wagtail()
|
|
||||||
|
|
||||||
def test_create_learning_path(self):
|
|
||||||
create_default_learning_path()
|
|
||||||
qs = LearningPath.objects.filter(title="Versicherungsvermittler/in")
|
|
||||||
self.assertTrue(qs.exists())
|
|
||||||
|
|
||||||
|
|
||||||
def create_locales_for_wagtail():
|
|
||||||
for language in settings.WAGTAIL_CONTENT_LANGUAGES:
|
|
||||||
Locale.objects.get_or_create(language_code=language[0])
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Iterativ GmbH
|
|
||||||
# http://www.iterativ.ch/
|
|
||||||
#
|
|
||||||
# Copyright (c) 2015 Iterativ GmbH. All rights reserved.
|
|
||||||
#
|
|
||||||
# Created on 2022-03-29
|
|
||||||
# @author: lorenz.padberg@iterativ.ch
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
from django.conf import settings
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from wagtail.core.models import Collection
|
from wagtail.core.models import Collection
|
||||||
from wagtail.models import Locale
|
|
||||||
|
|
||||||
from vbv_lernwelt.core.create_default_users import create_default_users
|
from vbv_lernwelt.core.create_default_users import create_default_users
|
||||||
|
from vbv_lernwelt.core.tests.helpers import create_locales_for_wagtail
|
||||||
from vbv_lernwelt.media_library.create_default_documents import create_default_collections, create_default_documents
|
from vbv_lernwelt.media_library.create_default_documents import create_default_collections, create_default_documents
|
||||||
from vbv_lernwelt.media_library.models import LibraryDocument
|
from vbv_lernwelt.media_library.models import LibraryDocument
|
||||||
|
|
||||||
|
|
@ -24,8 +23,3 @@ class TestCreateDefaultDocuments(TestCase):
|
||||||
create_default_documents()
|
create_default_documents()
|
||||||
qs = LibraryDocument.objects.all()
|
qs = LibraryDocument.objects.all()
|
||||||
self.assertTrue(qs.exists())
|
self.assertTrue(qs.exists())
|
||||||
|
|
||||||
|
|
||||||
def create_locales_for_wagtail():
|
|
||||||
for language in settings.WAGTAIL_CONTENT_LANGUAGES:
|
|
||||||
Locale.objects.get_or_create(language_code=language[0])
|
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
# Register your models here.
|
|
||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
from .models import SimpleTask, SimpleList
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(SimpleList)
|
|
||||||
class SimpleListAdmin(admin.ModelAdmin):
|
|
||||||
list_display = [
|
|
||||||
"title",
|
|
||||||
"user",
|
|
||||||
"created",
|
|
||||||
]
|
|
||||||
list_filter = [
|
|
||||||
"user",
|
|
||||||
]
|
|
||||||
search_fields = [
|
|
||||||
"title",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(SimpleTask)
|
|
||||||
class SimpleTaskAdmin(admin.ModelAdmin):
|
|
||||||
date_hierarchy = "deadline"
|
|
||||||
list_display = [
|
|
||||||
"title",
|
|
||||||
"deadline",
|
|
||||||
"created",
|
|
||||||
"list",
|
|
||||||
"done",
|
|
||||||
]
|
|
||||||
list_filter = [
|
|
||||||
"list",
|
|
||||||
"done",
|
|
||||||
]
|
|
||||||
search_fields = [
|
|
||||||
"title",
|
|
||||||
"text",
|
|
||||||
]
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class SimpletodoConfig(AppConfig):
|
|
||||||
default_auto_field = "django.db.models.BigAutoField"
|
|
||||||
name = "vbv_lernwelt.simpletodo"
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
# Generated by Django 3.2.12 on 2022-02-03 20:37
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import django.utils.timezone
|
|
||||||
import model_utils.fields
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="SimpleList",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"created",
|
|
||||||
model_utils.fields.AutoCreatedField(
|
|
||||||
default=django.utils.timezone.now,
|
|
||||||
editable=False,
|
|
||||||
verbose_name="created",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"modified",
|
|
||||||
model_utils.fields.AutoLastModifiedField(
|
|
||||||
default=django.utils.timezone.now,
|
|
||||||
editable=False,
|
|
||||||
verbose_name="modified",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"id",
|
|
||||||
models.UUIDField(
|
|
||||||
default=uuid.uuid4,
|
|
||||||
editable=False,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("title", models.CharField(max_length=255)),
|
|
||||||
(
|
|
||||||
"user",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
to=settings.AUTH_USER_MODEL,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"abstract": False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="SimpleTask",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"created",
|
|
||||||
model_utils.fields.AutoCreatedField(
|
|
||||||
default=django.utils.timezone.now,
|
|
||||||
editable=False,
|
|
||||||
verbose_name="created",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"modified",
|
|
||||||
model_utils.fields.AutoLastModifiedField(
|
|
||||||
default=django.utils.timezone.now,
|
|
||||||
editable=False,
|
|
||||||
verbose_name="modified",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"id",
|
|
||||||
models.UUIDField(
|
|
||||||
default=uuid.uuid4,
|
|
||||||
editable=False,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("title", models.CharField(max_length=255)),
|
|
||||||
("text", models.TextField(blank=True, default="")),
|
|
||||||
("done", models.BooleanField(default=False)),
|
|
||||||
("deadline", models.DateTimeField(blank=True, null=True)),
|
|
||||||
(
|
|
||||||
"list",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
to="simpletodo.simplelist",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"abstract": False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import uuid
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import models
|
|
||||||
from model_utils.models import TimeStampedModel
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleList(TimeStampedModel):
|
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
||||||
title = models.CharField(max_length=255)
|
|
||||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.title} ({self.user})"
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleTask(TimeStampedModel):
|
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
||||||
title = models.CharField(max_length=255)
|
|
||||||
text = models.TextField(blank=True, default="")
|
|
||||||
done = models.BooleanField(default=False)
|
|
||||||
deadline = models.DateTimeField(blank=True, null=True)
|
|
||||||
|
|
||||||
list = models.ForeignKey(SimpleList, on_delete=models.CASCADE)
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
import structlog
|
|
||||||
from rest_framework import serializers
|
|
||||||
from rest_framework.serializers import ModelSerializer
|
|
||||||
|
|
||||||
from vbv_lernwelt.simpletodo.models import SimpleTask, SimpleList
|
|
||||||
|
|
||||||
logger = structlog.get_logger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleTaskSerializer(ModelSerializer):
|
|
||||||
list_title = serializers.CharField(max_length=100)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = SimpleTask
|
|
||||||
fields = [
|
|
||||||
"id",
|
|
||||||
"title",
|
|
||||||
"text",
|
|
||||||
"done",
|
|
||||||
"deadline",
|
|
||||||
"list_title",
|
|
||||||
]
|
|
||||||
|
|
||||||
def create(self, validated_data):
|
|
||||||
user = validated_data.pop("user", None)
|
|
||||||
if user is None:
|
|
||||||
raise serializers.ValidationError("User is required")
|
|
||||||
|
|
||||||
list_title = validated_data.pop("list_title")
|
|
||||||
simple_list, _ = SimpleList.objects.get_or_create(title=list_title, user=user)
|
|
||||||
|
|
||||||
validated_data["list"] = simple_list
|
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
"Creating task",
|
|
||||||
label="simpletodo",
|
|
||||||
dt={"s1": 3, "s2": 4},
|
|
||||||
title=validated_data.get("title"),
|
|
||||||
list_title=list_title,
|
|
||||||
)
|
|
||||||
return super().create(validated_data)
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<div class="container mx-auto">
|
|
||||||
{% for list in simple_lists %}
|
|
||||||
{% include "simpletodo/partials/simple_list.html" with list=list%}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<it-icon-ls-start class="text-orange-500"></it-icon-ls-start>
|
|
||||||
|
|
||||||
<it-icon-arrow-up></it-icon-arrow-up>
|
|
||||||
<it-icon-arrow-down></it-icon-arrow-down>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<form class="flex mt-4" action="/todo/api/tasks/" method="POST">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input class="shadow appearance-none border rounded w-full py-2 px-3 mr-4 text-gray-darker"
|
|
||||||
type="text"
|
|
||||||
name="title"
|
|
||||||
maxlength="100"
|
|
||||||
required
|
|
||||||
placeholder="Add Todo"
|
|
||||||
>
|
|
||||||
<input type="hidden" name="list_title" value="{{ list.title }}">
|
|
||||||
|
|
||||||
<input
|
|
||||||
type="submit"
|
|
||||||
value="Add"
|
|
||||||
hx-post="/todo/api/tasks/"
|
|
||||||
hx-trigger="submit"
|
|
||||||
hx-target="#parent-div"
|
|
||||||
hx-swap="outerHTML"
|
|
||||||
class="flex-no-shrink p-2 border-2 rounded text-blue-500 border-blue-500 hover:text-white hover:bg-blue-500"
|
|
||||||
>
|
|
||||||
</form>
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
<div class="h-100 w-full flex items-center justify-center bg-blue-100 font-sans">
|
|
||||||
|
|
||||||
<div class="bg-white rounded shadow p-6 m-4 w-full lg:w-3/5 md:w-3/4">
|
|
||||||
<div class="mb-4">
|
|
||||||
<h2
|
|
||||||
class="text-gray-darkest"
|
|
||||||
data-cy="simple-list-title"
|
|
||||||
>
|
|
||||||
{{ list.title }}
|
|
||||||
</h2>
|
|
||||||
{% include "simpletodo/partials/add_task_form.html" with task=task %}
|
|
||||||
</div>
|
|
||||||
{% for task in list.simpletask_set.all %}
|
|
||||||
{% include "simpletodo/partials/task.html" with task=task %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
<div class="task">
|
|
||||||
<div class="flex mb-4 items-center">
|
|
||||||
{% if task.done %}
|
|
||||||
<p class="flex-auto text-blue-500 line-through">
|
|
||||||
{% else %}
|
|
||||||
<p class="flex-auto text-blue-900">
|
|
||||||
{% endif %}
|
|
||||||
{{ task.title }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<button
|
|
||||||
hx-post="/todo/api/tasks/{{ task.id }}/toggle_done/"
|
|
||||||
hx-swap="outerHTML swap:0.5s"
|
|
||||||
hx-target="closest .task"
|
|
||||||
{% if task.done %}
|
|
||||||
class="flex-no-shrink p-2 ml-4 mr-2 border-2 rounded hover:text-white text-gray-500 border-gray-500 hover:bg-gray-500"
|
|
||||||
{% else %}
|
|
||||||
class="flex-no-shrink p-2 ml-4 mr-2 border-2 rounded hover:text-white text-green-500 border-green-500 hover:bg-green-500"
|
|
||||||
{% endif %}
|
|
||||||
>
|
|
||||||
{% if task.done %}
|
|
||||||
Not Done
|
|
||||||
{% else %}
|
|
||||||
Done
|
|
||||||
{% endif %}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
hx-delete="/todo/api/tasks/{{ task.id }}/"
|
|
||||||
hx-swap="outerHTML swap:0.5s"
|
|
||||||
hx-target="closest .task"
|
|
||||||
class="flex-no-shrink p-2 ml-2 border-2 rounded text-red-500 border-red-500 hover:text-white hover:bg-red-500">
|
|
||||||
Remove
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from vbv_lernwelt.core.tests.factories import UserFactory
|
|
||||||
from vbv_lernwelt.simpletodo.models import SimpleTask
|
|
||||||
from vbv_lernwelt.simpletodo.serializers import SimpleTaskSerializer
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleTaskSerializerTestCase(TestCase):
|
|
||||||
def setUp(self) -> None:
|
|
||||||
self.user = UserFactory()
|
|
||||||
|
|
||||||
def test_serializer(self):
|
|
||||||
serializer = SimpleTaskSerializer(
|
|
||||||
data={
|
|
||||||
"title": "Test",
|
|
||||||
"list_title": "Todos",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
serializer.save(user=self.user)
|
|
||||||
|
|
||||||
task = SimpleTask.objects.first()
|
|
||||||
|
|
||||||
self.assertEqual(task.title, "Test")
|
|
||||||
self.assertEqual(task.list.title, "Todos")
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
from django.conf.urls import url, include
|
|
||||||
from django.urls import path
|
|
||||||
from rest_framework.routers import DefaultRouter
|
|
||||||
|
|
||||||
from . import views
|
|
||||||
|
|
||||||
router = DefaultRouter()
|
|
||||||
router.register(r"tasks", views.SimpleTaskViewSet, basename="tasks")
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
path("", views.index, name="index"),
|
|
||||||
url(r"^api/", include(router.urls)),
|
|
||||||
]
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
from django.http import HttpResponse
|
|
||||||
from django.shortcuts import redirect, render
|
|
||||||
from rest_framework import viewsets, status
|
|
||||||
from rest_framework.decorators import action
|
|
||||||
from rest_framework.renderers import TemplateHTMLRenderer, JSONRenderer
|
|
||||||
from rest_framework.response import Response
|
|
||||||
|
|
||||||
from vbv_lernwelt.simpletodo.models import SimpleList, SimpleTask
|
|
||||||
from vbv_lernwelt.simpletodo.serializers import SimpleTaskSerializer
|
|
||||||
|
|
||||||
|
|
||||||
def index(request):
|
|
||||||
simple_lists = SimpleList.objects.filter(user=request.user)
|
|
||||||
|
|
||||||
if simple_lists.count() == 0:
|
|
||||||
simple_lists = [SimpleList.objects.create(user=request.user, title="Todos")]
|
|
||||||
|
|
||||||
return render(request, "simpletodo/index.html", {"simple_lists": simple_lists})
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleTaskViewSet(viewsets.ModelViewSet):
|
|
||||||
serializer_class = SimpleTaskSerializer
|
|
||||||
renderer_classes = [TemplateHTMLRenderer, JSONRenderer]
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
user = self.request.user
|
|
||||||
return SimpleTask.objects.filter(list__user=user)
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
|
||||||
serializer = self.get_serializer(data=request.data)
|
|
||||||
|
|
||||||
if request.accepted_renderer.format == "html":
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
else:
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
|
|
||||||
serializer.save(user=request.user)
|
|
||||||
|
|
||||||
if request.accepted_renderer.format == "html":
|
|
||||||
return redirect("/todo/")
|
|
||||||
|
|
||||||
headers = self.get_success_headers(serializer.data)
|
|
||||||
return Response(
|
|
||||||
serializer.data, status=status.HTTP_201_CREATED, headers=headers
|
|
||||||
)
|
|
||||||
|
|
||||||
def destroy(self, request, *args, **kwargs):
|
|
||||||
instance = self.get_object()
|
|
||||||
instance.delete()
|
|
||||||
|
|
||||||
if request.htmx:
|
|
||||||
return HttpResponse(status=200, content="")
|
|
||||||
|
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
||||||
|
|
||||||
@action(
|
|
||||||
detail=True,
|
|
||||||
methods=[
|
|
||||||
"post",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def toggle_done(self, request, pk=None):
|
|
||||||
task = self.get_object()
|
|
||||||
task.done = not task.done
|
|
||||||
task.save()
|
|
||||||
|
|
||||||
if request.htmx:
|
|
||||||
return render(request, "simpletodo/partials/task.html", {"task": task})
|
|
||||||
|
|
||||||
return Response(self.get_serializer(task), status=status.HTTP_200_OK)
|
|
||||||
|
|
||||||
#
|
|
||||||
# def get_category_from_request(self, request):
|
|
||||||
# cat_name = request.query_params.get('cat_name')
|
|
||||||
# category_obj = None
|
|
||||||
#
|
|
||||||
# if cat_name:
|
|
||||||
# category_obj = VideoCategory.objects.filter(category__iexact=cat_name).first()
|
|
||||||
# if not category_obj:
|
|
||||||
# category_obj = VideoCategory.objects.first()
|
|
||||||
#
|
|
||||||
# return category_obj
|
|
||||||
#
|
|
||||||
# @action(detail=False, methods=['get'])
|
|
||||||
# def form(self, request):
|
|
||||||
# category_obj = self.get_category_from_request(request)
|
|
||||||
# return Response(template_name='videos/partials/video_form.html', data={'category': category_obj})
|
|
||||||
#
|
|
||||||
# @action(detail=False, methods=['get'])
|
|
||||||
# def cancel(self, request):
|
|
||||||
# category_obj = self.get_category_from_request(request)
|
|
||||||
# return Response(template_name='videos/partials/show_add_form.html', data={'category': category_obj})
|
|
||||||
Loading…
Reference in New Issue