From 2b4bd5aaa267f6dec98b34e58dcc3e15d20c3c2c Mon Sep 17 00:00:00 2001 From: Luis Miguel Del Valle Date: Wed, 4 Dec 2024 22:04:00 +0000 Subject: [PATCH] adding featured course to tech --- .../0053_assettechnology_featured_course.py | 27 ++++++++++++ breathecode/registry/models.py | 8 ++++ breathecode/registry/serializers.py | 8 ++++ .../tests/urls/v1/tests_academy_technology.py | 1 + .../tests/urls/v1/tests_technology.py | 44 +++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 breathecode/registry/migrations/0053_assettechnology_featured_course.py diff --git a/breathecode/registry/migrations/0053_assettechnology_featured_course.py b/breathecode/registry/migrations/0053_assettechnology_featured_course.py new file mode 100644 index 000000000..a597a8123 --- /dev/null +++ b/breathecode/registry/migrations/0053_assettechnology_featured_course.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.2 on 2024-12-04 17:44 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("marketing", "0091_course_cohorts_order"), + ("registry", "0052_assettechnology_marketing_information"), + ] + + operations = [ + migrations.AddField( + model_name="assettechnology", + name="featured_course", + field=models.ForeignKey( + blank=True, + default=None, + help_text="The featured course for this technology", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="marketing.course", + ), + ), + ] diff --git a/breathecode/registry/models.py b/breathecode/registry/models.py index c6c46d54e..c93ffd439 100644 --- a/breathecode/registry/models.py +++ b/breathecode/registry/models.py @@ -60,6 +60,14 @@ class AssetTechnology(models.Model): default=False, help_text="If True, the technology will be programmatically deleted." ) featured_asset = models.ForeignKey("Asset", on_delete=models.SET_NULL, default=None, blank=True, null=True) + featured_course = models.ForeignKey( + "marketing.Course", + on_delete=models.SET_NULL, + null=True, + blank=True, + default=None, + help_text="The featured course for this technology", + ) visibility = models.CharField( max_length=20, choices=VISIBILITY, diff --git a/breathecode/registry/serializers.py b/breathecode/registry/serializers.py index 1b93d26a3..d637ae660 100644 --- a/breathecode/registry/serializers.py +++ b/breathecode/registry/serializers.py @@ -8,6 +8,7 @@ from breathecode.admissions.models import Academy from breathecode.authenticate.models import ProfileAcademy +from breathecode.marketing.serializers import GetCourseSmallSerializer from breathecode.utils import serpy from .models import ( @@ -497,8 +498,15 @@ class AssetBigTechnologySerializer(AssetTechnologySerializer): assets = serpy.MethodField() alias = serpy.MethodField() sort_priority = serpy.Field() + featured_course = serpy.MethodField() marketing_information = serpy.Field() + def get_featured_course(self, obj): + if obj.featured_course: + obj.featured_course.lang = obj.lang or "en" + return GetCourseSmallSerializer(obj.featured_course).data + return None + def get_assets(self, obj): assets = Asset.objects.filter(technologies__id=obj.id) return list(map(lambda t: t.slug, assets)) diff --git a/breathecode/registry/tests/urls/v1/tests_academy_technology.py b/breathecode/registry/tests/urls/v1/tests_academy_technology.py index b56b26239..a6c975123 100644 --- a/breathecode/registry/tests/urls/v1/tests_academy_technology.py +++ b/breathecode/registry/tests/urls/v1/tests_academy_technology.py @@ -39,6 +39,7 @@ def get_serializer(asset_technology, assets=[], asset_technologies=[], data={}): "title": asset_technology.title, "visibility": asset_technology.visibility, "sort_priority": asset_technology.sort_priority, + "featured_course": asset_technology.marketing_information, "marketing_information": asset_technology.marketing_information, **data, } diff --git a/breathecode/registry/tests/urls/v1/tests_technology.py b/breathecode/registry/tests/urls/v1/tests_technology.py index 2aabcd206..05ef360b9 100644 --- a/breathecode/registry/tests/urls/v1/tests_technology.py +++ b/breathecode/registry/tests/urls/v1/tests_technology.py @@ -29,6 +29,23 @@ def get_detailed_serializer(asset_technology, assets=[], asset_technologies=[]): "icon_url": asset_technology.icon_url, "lang": None, "is_deprecated": asset_technology.is_deprecated, + "featured_course": ( + { + "slug": asset_technology.featured_course.slug, + "icon_url": asset_technology.featured_course.icon_url, + "academy": asset_technology.featured_course.academy.id, + "syllabus": ( + [x for x in asset_technology.featured_course.syllabus.all().values_list("id", flat=True)] + if asset_technology.featured_course and asset_technology.featured_course.syllabus + else [] + ), + "color": asset_technology.featured_course.color, + "course_translation": None, + "technologies": asset_technology.featured_course.technologies, + } + if asset_technology.featured_course is not None + else None + ), "marketing_information": asset_technology.marketing_information, "parent": None, "slug": asset_technology.slug, @@ -141,6 +158,32 @@ def test_with_two_asset_technologies__passing_sort_priority__found_for_get_techn # teardown self.bc.database.delete("registry.AssetTechnology") + def test_asset_technology_with_featured_course(self): + + courseModel = self.generate_models(course=1) + + asset_technology = { + "slug": self.bc.fake.slug(), + "title": self.bc.fake.word(), + "featured_course": courseModel.course, + } + + model = self.generate_models( + asset_technology=asset_technology, + ) + + url = reverse_lazy("registry:get_technology_detail", kwargs={"tech_slug": model.asset_technology.slug}) + response = self.client.get(url) + json = response.json() + + expected = get_detailed_serializer(model.asset_technology) + + self.assertEqual(json, expected) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # teardown + self.bc.database.delete("registry.AssetTechnology") + def test_asset_technology_with_marketing_information(self): marketing_info = { "title": {"us": "Practice python", "es": "Practica python"}, @@ -171,6 +214,7 @@ def test_asset_technology_with_marketing_information(self): expected = get_detailed_serializer(model.asset_technology) self.assertEqual(json, expected) + self.assertIsNotNone(json["marketing_information"]["title"]) self.assertEqual(response.status_code, status.HTTP_200_OK) # teardown