Coverage for apps/kwai-api/src/kwai_api/v1/portal/news/presenters.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2024-01-01 00:00 +0000

1"""Module that defines presenters for the portal/news endpoint.""" 

2 

3from typing import Self 

4 

5from kwai_bc_portal.domain.news_item import NewsItemEntity 

6from kwai_core.domain.presenter import AsyncPresenter, IterableResult, Presenter 

7from kwai_core.json_api import JsonApiPresenter, Meta, Relationship, ResourceMeta 

8 

9from kwai_api.converter import MarkdownConverter 

10from kwai_api.schemas.resources import ApplicationResourceIdentifier 

11from kwai_api.v1.portal.news.schemas import ( 

12 NewsApplicationAttributes, 

13 NewsApplicationResource, 

14 NewsItemAttributes, 

15 NewsItemDocument, 

16 NewsItemRelationships, 

17 NewsItemResource, 

18 NewsItemsDocument, 

19 NewsItemText, 

20) 

21 

22 

23class JsonApiNewsItemPresenter( 

24 JsonApiPresenter[NewsItemDocument], Presenter[NewsItemEntity] 

25): 

26 """A presenter that transform a news item entity into a JSON:API document.""" 

27 

28 def present(self, news_item: NewsItemEntity) -> Self: 

29 self._document = NewsItemDocument( 

30 data=NewsItemResource( 

31 id=str(news_item.id), 

32 meta=ResourceMeta( 

33 created_at=str(news_item.traceable_time.created_at), 

34 updated_at=None 

35 if news_item.traceable_time.updated_at 

36 else str(news_item.traceable_time.updated_at), 

37 ), 

38 attributes=NewsItemAttributes( 

39 publish_date=str(news_item.period.start_date), 

40 texts=[ 

41 NewsItemText( 

42 locale=text.locale.value, 

43 title=text.title, 

44 summary=MarkdownConverter().convert(text.summary), 

45 content=MarkdownConverter().convert(text.content) 

46 if text.content 

47 else None, 

48 ) 

49 for text in news_item.texts 

50 ], 

51 priority=news_item.promotion.priority, 

52 ), 

53 relationships=NewsItemRelationships( 

54 application=Relationship[ApplicationResourceIdentifier]( 

55 data=ApplicationResourceIdentifier( 

56 id=str(news_item.application.id) 

57 ) 

58 ) 

59 ), 

60 ), 

61 included={ 

62 NewsApplicationResource( 

63 id=str(news_item.application.id), 

64 attributes=NewsApplicationAttributes( 

65 name=news_item.application.name, 

66 title=news_item.application.title, 

67 ), 

68 ) 

69 }, 

70 ) 

71 return self 

72 

73 

74class JsonApiNewsItemsPresenter( 

75 JsonApiPresenter[NewsItemsDocument], AsyncPresenter[IterableResult[NewsItemEntity]] 

76): 

77 """A presenter that transfer an iterable list of news items into a JSON:API document.""" 

78 

79 async def present(self, result: IterableResult[NewsItemEntity]) -> Self: 

80 self._document = NewsItemsDocument( 

81 meta=Meta(count=result.count, offset=result.offset, limit=result.limit) 

82 ) 

83 async for news_item in result.iterator: 

84 news_item_document = ( 

85 JsonApiNewsItemPresenter().present(news_item).get_document() 

86 ) 

87 self._document.data.append(news_item_document.data) 

88 self._document.included |= news_item_document.included 

89 

90 return self