Skip to content

Commit

Permalink
Merge pull request #1495 from lumi-tip/development-lumi-7920
Browse files Browse the repository at this point in the history
❇️ added tech/slug
  • Loading branch information
jefer94 authored Nov 15, 2024
2 parents a9f8ee4 + 76deff2 commit 95d6c85
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 5.1.2 on 2024-11-15 19:01

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("registry", "0051_alter_assetcontext_status"),
]

operations = [
migrations.AddField(
model_name="assettechnology",
name="marketing_information",
field=models.JSONField(
blank=True, default=None, help_text="JSON structure for marketing information", null=True
),
),
]
4 changes: 4 additions & 0 deletions breathecode/registry/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ class AssetTechnology(models.Model):
help_text="Priority to sort technology (1, 2, or 3): One is more important and goes first than three.",
)

marketing_information = models.JSONField(
null=True, blank=True, default=None, help_text="JSON structure for marketing information"
)

def __str__(self):
return self.title

Expand Down
2 changes: 1 addition & 1 deletion breathecode/registry/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,10 @@ class AssetTechnologySerializer(ParentAssetTechnologySerializer):


class AssetBigTechnologySerializer(AssetTechnologySerializer):

assets = serpy.MethodField()
alias = serpy.MethodField()
sort_priority = serpy.Field()
marketing_information = serpy.Field()

def get_assets(self, obj):
assets = Asset.objects.filter(technologies__id=obj.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
"marketing_information": asset_technology.marketing_information,
**data,
}

Expand Down
52 changes: 52 additions & 0 deletions breathecode/registry/tests/urls/v1/tests_technology.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@ def get_serializer(asset_technology, assets=[], asset_technologies=[]):
}


def get_detailed_serializer(asset_technology, assets=[], asset_technologies=[]):
return {
"description": asset_technology.description,
"icon_url": asset_technology.icon_url,
"lang": None,
"is_deprecated": asset_technology.is_deprecated,
"marketing_information": asset_technology.marketing_information,
"parent": None,
"slug": asset_technology.slug,
"title": asset_technology.title,
"visibility": asset_technology.visibility,
"alias": [],
"assets": [],
"sort_priority": asset_technology.sort_priority,
}


class RegistryTestSuite(RegistryTestCase):
"""
🔽🔽🔽 Auth
Expand Down Expand Up @@ -123,3 +140,38 @@ 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_marketing_information(self):
marketing_info = {
"title": {"us": "Practice python", "es": "Practica python"},
"description": {"us": "Description in English", "es": "Descripción en español"},
"video": {"us": "https://video-url-us", "es": "https://video-url-es"},
}

asset_technology = {
"slug": self.bc.fake.slug(),
"title": self.bc.fake.word(),
"marketing_information": marketing_info,
}

model = self.generate_models(
authenticate=True,
profile_academy=True,
role=1,
asset_technology=asset_technology,
capability="read_technology",
)

self.headers(academy=model.academy.id)

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")
9 changes: 5 additions & 4 deletions breathecode/registry/urls/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@
AcademyKeywordClusterView,
AcademyKeywordView,
AcademyTechnologyView,
AssetContextView,
AssetImageView,
AssetSupersedesView,
AssetThumbnailView,
AssetView,
TechnologyView,
forward_asset_url,
get_alias_redirects,
get_categories,
get_config,
get_keywords,
get_technologies,
get_translations,
handle_test_asset,
render_preview_html,
render_readme,
AssetSupersedesView,
AssetContextView,
)

app_name = "registry"
Expand Down Expand Up @@ -63,7 +63,8 @@
path("academy/keywordcluster", AcademyKeywordClusterView.as_view()),
path("academy/keywordcluster/<str:cluster_slug>", AcademyKeywordClusterView.as_view()),
path("category", get_categories),
path("technology", get_technologies, name="technology"),
path("technology", TechnologyView.as_view(), name="technology"),
path("technology/<str:tech_slug>", TechnologyView.as_view(), name="get_technology_detail"),
path("academy/technology", AcademyTechnologyView.as_view(), name="academy_technology"),
path("academy/technology/<str:tech_slug>", AcademyTechnologyView.as_view()),
path("translation", get_translations),
Expand Down
81 changes: 49 additions & 32 deletions breathecode/registry/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,51 +162,68 @@ def render_preview_html(request, asset_slug):
return response


@api_view(["GET"])
@permission_classes([AllowAny])
def get_technologies(request):
lang = get_user_language(request)
# Create your views here.

items = AssetTechnology.objects.filter(parent__isnull=True)

if "sort_priority" in request.GET:
param = request.GET.get("sort_priority")
class TechnologyView(APIView):
"""
View to retrieve a list of technologies or a specific technology by slug.
"""

try:
permission_classes = [AllowAny]
extensions = APIViewExtensions(cache=TechnologyCache, paginate=True, sort="sort_priority")

param = int(param)
def get(self, request, tech_slug=None):
lang = request.GET.get("lang", "en")
if lang == "en":
lang = "us"

items = items.filter(sort_priority__exact=param)
except Exception:
raise ValidationException(
translation(
lang,
en="The parameter must be an integer, nothing else",
es="El parametró debera ser un entero y nada mas ",
slug="integer-not-found",
handler = self.extensions(request)
cache = handler.cache.get()
if cache is not None:
return cache

if tech_slug:
try:
technology = AssetTechnology.objects.get(slug=tech_slug)
except AssetTechnology.DoesNotExist:
raise ValidationException(f"Technology with slug '{tech_slug}' not found", code=404)
serializer = AssetBigTechnologySerializer(technology)
return Response(serializer.data)

items = AssetTechnology.objects.filter(parent__isnull=True)

if "sort_priority" in request.GET:
try:
param = int(request.GET.get("sort_priority"))
items = items.filter(sort_priority__exact=param)
except ValueError:
raise ValidationException(
translation(
lang,
en="The parameter must be an integer, nothing else",
es="El parametró debera ser un entero y nada mas ",
slug="integer-not-found",
)
)
)

if "lang" in request.GET:
param = request.GET.get("lang")
if param == "en":
param = "us"
items = items.filter(Q(lang__iexact=param) | Q(lang="") | Q(lang__isnull=True))
if "lang" in request.GET:
param = request.GET.get("lang")
items = items.filter(Q(lang__iexact=param) | Q(lang="") | Q(lang__isnull=True))

if "is_deprecated" not in request.GET or request.GET.get("is_deprecated").lower() == "false":
items = items.filter(is_deprecated=False)
if "is_deprecated" not in request.GET or request.GET.get("is_deprecated").lower() == "false":
items = items.filter(is_deprecated=False)

like = request.GET.get("like", None)
if like is not None and like != "undefined" and like != "":
items = items.filter(Q(slug__icontains=slugify(like)) | Q(title__icontains=like))
like = request.GET.get("like", None)
if like and like not in ["undefined", ""]:
items = items.filter(Q(slug__icontains=like) | Q(title__icontains=like))

items = items.order_by("sort_priority")
items = handler.queryset(items)

serializer = AssetTechnologySerializer(items, many=True)
return Response(serializer.data)
serializer = AssetTechnologySerializer(items, many=True)
return handler.response(serializer.data)


# Create your views here.
class AcademyTechnologyView(APIView, GenerateLookupsMixin):
"""
List all snippets, or create a new snippet.
Expand Down

0 comments on commit 95d6c85

Please sign in to comment.