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

32 statements  

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

1"""Presenters for the portal trainings API.""" 

2 

3from typing import Self 

4 

5from kwai_bc_training.trainings.training import TrainingEntity 

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

7from kwai_core.json_api import ( 

8 JsonApiPresenter, 

9 Meta, 

10 ResourceMeta, 

11) 

12 

13from kwai_api.converter import MarkdownConverter 

14from kwai_api.schemas.resources import ( 

15 TeamResourceIdentifier, 

16 TrainingScheduleResourceIdentifier, 

17) 

18from kwai_api.v1.portal.trainings.schemas import ( 

19 TeamAttributes, 

20 TeamDocument, 

21 TeamResource, 

22 TeamsRelationship, 

23 TrainingAttributes, 

24 TrainingDocument, 

25 TrainingEvent, 

26 TrainingRelationships, 

27 TrainingResource, 

28 TrainingScheduleAttributes, 

29 TrainingScheduleDocument, 

30 TrainingScheduleRelationship, 

31 TrainingScheduleResource, 

32 TrainingsDocument, 

33 TrainingText, 

34) 

35 

36 

37class JsonApiTrainingPresenter( 

38 JsonApiPresenter[TrainingDocument], Presenter[TrainingEntity] 

39): 

40 """A presenter that transforms a training entity into a JSON:API document.""" 

41 

42 def __init__(self): 

43 super().__init__() 

44 

45 def present(self, training: TrainingEntity) -> Self: 

46 self._document = TrainingDocument( 

47 data=TrainingResource( 

48 id=str(training.id), 

49 meta=ResourceMeta( 

50 created_at=str(training.traceable_time.created_at), 

51 updated_at=str(training.traceable_time.updated_at), 

52 ), 

53 attributes=TrainingAttributes( 

54 texts=[ 

55 TrainingText( 

56 title=text.title, 

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

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

59 if text.content 

60 else None, 

61 ) 

62 for text in training.texts 

63 ], 

64 event=TrainingEvent( 

65 start_date=str(training.period.start_date), 

66 end_date=str(training.period.end_date), 

67 location=training.location or "", 

68 cancelled=training.cancelled, 

69 ), 

70 remark=training.remark or "", 

71 ), 

72 relationships=TrainingRelationships( 

73 teams=TeamsRelationship(), 

74 schedule=TrainingScheduleRelationship(), 

75 ), 

76 ) 

77 ) 

78 

79 if training.schedule: 

80 training_schedule_document = TrainingScheduleDocument( 

81 data=TrainingScheduleResource( 

82 id=str(training.schedule.id), 

83 attributes=TrainingScheduleAttributes(name=training.schedule.name), 

84 ) 

85 ) 

86 self._document.data.relationships.schedule.data = ( 

87 TrainingScheduleResourceIdentifier(id=str(training.schedule.id)) 

88 ) 

89 self._document.included.add(training_schedule_document.data) 

90 self._document.included |= training_schedule_document.included 

91 

92 for team in training.teams: 

93 self._document.data.relationships.teams.data.append( 

94 TeamResourceIdentifier(id=str(team.id)) 

95 ) 

96 team_document = TeamDocument( 

97 data=TeamResource( 

98 id=str(team.id), attributes=TeamAttributes(name=team.name) 

99 ) 

100 ) 

101 self._document.included.add(team_document.data) 

102 

103 return self 

104 

105 

106class JsonApiTrainingsDocumentPresenter( 

107 JsonApiPresenter[TrainingsDocument], AsyncPresenter[IterableResult[TrainingEntity]] 

108): 

109 """A presenter for transforming an iterator with trainings into a JSON:API document.""" 

110 

111 async def present(self, result: IterableResult[TrainingEntity]) -> Self: 

112 self._document = TrainingsDocument( 

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

114 ) 

115 async for training in result.iterator: 

116 training_presenter = JsonApiTrainingPresenter() 

117 training_presenter.present(training) 

118 training_document = training_presenter.get_document() 

119 self._document.data.append(training_document.data) 

120 self._document.included |= training_document.included 

121 

122 return self