Coverage for src/tests/api/v1/portal/news/test_presenters.py: 100%

37 statements  

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

1"""Module for testing the presenters of the api/v1/portal/news endpoint.""" 

2 

3import json 

4 

5from typing import AsyncGenerator 

6 

7import pytest 

8 

9from deepdiff import DeepDiff 

10from kwai_api.v1.portal.news.presenters import ( 

11 JsonApiNewsItemPresenter, 

12 JsonApiNewsItemsPresenter, 

13) 

14from kwai_bc_portal.domain.application import ApplicationEntity 

15from kwai_bc_portal.domain.news_item import NewsItemEntity 

16from kwai_core.domain.presenter import IterableResult 

17from kwai_core.domain.value_objects.text import DocumentFormat, Locale, LocaleText 

18 

19 

20@pytest.fixture 

21def news_item(make_news_item, make_author): 

22 """A fixture for a news item.""" 

23 return make_news_item( 

24 texts=( 

25 LocaleText( 

26 locale=Locale.EN, 

27 title="Test", 

28 summary="When do we start?", 

29 content="The first training is today.", 

30 format=DocumentFormat.MARKDOWN, 

31 author=make_author(), 

32 ), 

33 ), 

34 application=ApplicationEntity( 

35 name="trainings", 

36 title="Trainings", 

37 short_description="Information about our trainings", 

38 ), 

39 ) 

40 

41 

42@pytest.fixture 

43def expected_news_item_json(news_item): 

44 """A fixture for the expected json for a news item.""" 

45 return { 

46 "data": { 

47 "id": str(news_item.id), 

48 "type": "news_items", 

49 "meta": { 

50 "created_at": str(news_item.traceable_time.created_at), 

51 "updated_at": None, 

52 }, 

53 "attributes": { 

54 "publish_date": str(news_item.period.start_date), 

55 "texts": [ 

56 { 

57 "locale": "en", 

58 "title": "Test", 

59 "summary": "<p>When do we start?</p>", 

60 "content": "<p>The first training is today.</p>", 

61 } 

62 ], 

63 "priority": 0, 

64 }, 

65 "relationships": { 

66 "application": { 

67 "data": { 

68 "id": str(news_item.application.id), 

69 "type": "applications", 

70 } 

71 } 

72 }, 

73 }, 

74 "included": [ 

75 { 

76 "id": str(news_item.application.id), 

77 "type": "applications", 

78 "attributes": {"name": "trainings", "title": "Trainings"}, 

79 } 

80 ], 

81 } 

82 

83 

84def test_json_api_news_item_presenter(news_item, expected_news_item_json): 

85 """Test a presenter that transforms a news item into a JSON:API document.""" 

86 document = JsonApiNewsItemPresenter().present(news_item).get_document() 

87 assert document is not None 

88 assert document.data.type == "news_items" 

89 

90 json_resource = json.loads(document.model_dump_json()) 

91 

92 diff = DeepDiff(json_resource, expected_news_item_json, ignore_order=True) 

93 assert not diff, f"JSON structure is not expected:{diff}" 

94 

95 

96async def news_item_generator( 

97 make_news_item, make_application 

98) -> AsyncGenerator[NewsItemEntity, None]: 

99 """A generator for news items.""" 

100 application = make_application() 

101 yield make_news_item(application=application) 

102 yield make_news_item(application=application) 

103 

104 

105@pytest.fixture 

106def iterable_result(make_news_item, make_application) -> IterableResult[NewsItemEntity]: 

107 """A fixture that creates a IterableResult for news item entitites.""" 

108 return IterableResult[NewsItemEntity]( 

109 count=2, iterator=news_item_generator(make_news_item, make_application) 

110 ) 

111 

112 

113async def test_json_api_news_items_presenter(iterable_result): 

114 """Test a presenter with an iterable result containing news items.""" 

115 presenter = JsonApiNewsItemsPresenter() 

116 await presenter.present(iterable_result) 

117 document = presenter.get_document() 

118 assert document is not None, "The presenter should contain a document" 

119 assert document.meta.count == 2, "Count should be 2" 

120 assert len(document.data) == 2, "There should be 2 resources" 

121 assert len(document.included) == 1, "There should be 1 included application"