diff --git a/app/core/admin.py b/app/core/admin.py index dda6946d..1848cbf9 100644 --- a/app/core/admin.py +++ b/app/core/admin.py @@ -15,6 +15,7 @@ from .models import Project from .models import Skill from .models import SponsorPartner +from .models import StackElementType from .models import Technology from .models import User @@ -203,3 +204,11 @@ class TechnologyAdmin(admin.ModelAdmin): @admin.register(PermissionType) class PermissionTypeAdmin(admin.ModelAdmin): list_display = ("name", "description") + + +@admin.register(StackElementType) +class StackElementType(admin.ModelAdmin): + list_display = ( + "name", + "description", + ) diff --git a/app/core/api/serializers.py b/app/core/api/serializers.py index c7625140..a8545216 100644 --- a/app/core/api/serializers.py +++ b/app/core/api/serializers.py @@ -11,6 +11,7 @@ from core.models import Project from core.models import Skill from core.models import SponsorPartner +from core.models import StackElementType from core.models import Technology from core.models import User @@ -256,3 +257,20 @@ class Meta: "created_at", "updated_at", ) + + +class StackElementTypeSerializer(serializers.ModelSerializer): + """Used to retrieve stack element types""" + + class Meta: + model = StackElementType + fields = ( + "uuid", + "name", + "description", + ) + read_only_fields = ( + "uuid", + "created_at", + "updated_at", + ) diff --git a/app/core/api/urls.py b/app/core/api/urls.py index c843bc75..c2b6d293 100644 --- a/app/core/api/urls.py +++ b/app/core/api/urls.py @@ -11,6 +11,7 @@ from .views import ProjectViewSet from .views import SkillViewSet from .views import SponsorPartnerViewSet +from .views import StackElementTypeViewSet from .views import TechnologyViewSet from .views import UserProfileAPIView from .views import UserViewSet @@ -28,6 +29,9 @@ router.register(r"skills", SkillViewSet, basename="skill") router.register(r"technologies", TechnologyViewSet, basename="technology") router.register(r"permission-types", PermissionTypeViewSet, basename="permission-type") +router.register( + r"stack-element-types", StackElementTypeViewSet, basename="stack-element-type" +) urlpatterns = [ path("me/", UserProfileAPIView.as_view(), name="my_profile"), diff --git a/app/core/api/views.py b/app/core/api/views.py index 544371d9..30dab2ad 100644 --- a/app/core/api/views.py +++ b/app/core/api/views.py @@ -21,6 +21,7 @@ from ..models import Project from ..models import Skill from ..models import SponsorPartner +from ..models import StackElementType from ..models import Technology from .serializers import EventSerializer from .serializers import FaqSerializer @@ -32,6 +33,7 @@ from .serializers import ProjectSerializer from .serializers import SkillSerializer from .serializers import SponsorPartnerSerializer +from .serializers import StackElementTypeSerializer from .serializers import TechnologySerializer from .serializers import UserSerializer @@ -282,3 +284,17 @@ class PermissionTypeViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated] queryset = PermissionType.objects.all() serializer_class = PermissionTypeSerializer + + +@extend_schema_view( + list=extend_schema(description="Return a list of all the stack element types"), + create=extend_schema(description="Create a new stack element type"), + retrieve=extend_schema(description="Return the details stack element type"), + destroy=extend_schema(description="Delete a stack element type"), + update=extend_schema(description="Update a stack element type"), + partial_update=extend_schema(description="Patch a stack element type"), +) +class StackElementTypeViewSet(viewsets.ModelViewSet): + permission_classes = [IsAuthenticated] + queryset = StackElementType.objects.all() + serializer_class = StackElementTypeSerializer diff --git a/app/core/migrations/0019_stackelementtype.py b/app/core/migrations/0019_stackelementtype.py new file mode 100644 index 00000000..26fdff4d --- /dev/null +++ b/app/core/migrations/0019_stackelementtype.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.10 on 2023-11-16 15:05 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0018_rename_recurringevent_event'), + ] + + operations = [ + migrations.CreateModel( + name='StackElementType', + fields=[ + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField(blank=True)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/core/migrations/max_migration.txt b/app/core/migrations/max_migration.txt index 4d905073..8810f9cd 100644 --- a/app/core/migrations/max_migration.txt +++ b/app/core/migrations/max_migration.txt @@ -1 +1 @@ -0018_rename_recurringevent_event +0019_stackelementtype diff --git a/app/core/models.py b/app/core/models.py index 39ac4f6c..708db933 100644 --- a/app/core/models.py +++ b/app/core/models.py @@ -299,3 +299,17 @@ def __str__(self): return f"{self.name}: {self.description}" else: return f"{self.name}" + + +class StackElementType(AbstractBaseModel): + """ + Stack element type used to update a shared data store across projects + """ + + name = models.CharField(max_length=255) + description = models.TextField(blank=True) + + # PK of this model is the ForeignKey for stack_element + + def __str__(self): + return f"{self.name}" diff --git a/app/core/tests/conftest.py b/app/core/tests/conftest.py index c6f95528..3fbe27f2 100644 --- a/app/core/tests/conftest.py +++ b/app/core/tests/conftest.py @@ -11,6 +11,7 @@ from ..models import Project from ..models import Skill from ..models import SponsorPartner +from ..models import StackElementType from ..models import Technology @@ -127,3 +128,8 @@ def permission_type2(): return PermissionType.objects.create( name="Test Permission Type", description="A permission type description" ) + + +@pytest.fixture +def stack_element_type(): + return StackElementType.objects.create(name="Test Stack Element Type") diff --git a/app/core/tests/test_api.py b/app/core/tests/test_api.py index 299052eb..0e17bcb0 100644 --- a/app/core/tests/test_api.py +++ b/app/core/tests/test_api.py @@ -20,6 +20,7 @@ SKILL_URL = reverse("skill-list") TECHNOLOGY_URL = reverse("technology-list") PERMISSION_TYPE = reverse("permission-type-list") +STACK_ELEMENT_TYPE_URL = reverse("stack-element-type-list") CREATE_USER_PAYLOAD = { "username": "TestUserAPI", @@ -290,3 +291,13 @@ def test_create_permission_type(auth_client): assert res.status_code == status.HTTP_201_CREATED assert res.data["name"] == payload["name"] assert res.data["description"] == payload["description"] + + +def test_create_stack_element_type(auth_client): + payload = { + "name": "Test Stack Element Type", + "description": "Stack Element Type description", + } + res = auth_client.post(STACK_ELEMENT_TYPE_URL, payload) + assert res.status_code == status.HTTP_201_CREATED + assert res.data["name"] == payload["name"] diff --git a/app/core/tests/test_models.py b/app/core/tests/test_models.py index 488060f5..afca7eaf 100644 --- a/app/core/tests/test_models.py +++ b/app/core/tests/test_models.py @@ -62,3 +62,7 @@ def test_permission_type2(permission_type2): assert ( str(permission_type2) == "Test Permission Type: A permission type description" ) + + +def test_stack_element_type(stack_element_type): + assert str(stack_element_type) == "Test Stack Element Type"