Coverage for tests/test_items.py: 100%

72 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-05 11:17 +0200

1"""Tests du sous-client items (synchrone et asynchrone).""" 

2 

3from __future__ import annotations 

4 

5from typing import Any 

6from unittest.mock import AsyncMock, MagicMock 

7 

8import pytest 

9 

10from henrri_connect.connect import ( 

11 AsyncHenrriClient, SyncHenrriClient, # type: ignore[import] 

12) 

13from henrri_connect.models import Item, ItemsQuery 

14from tests.conftest import ITEM_JSON, PAGED_META, make_response 

15 

16 

17def _paged(elements: list[Any]) -> dict[str, Any]: 

18 return {"elements": elements, "meta": PAGED_META} 

19 

20 

21class TestSyncItems: 

22 """Tests du sous-client items (synchrone).""" 

23 def test_list_retourne_articles( 

24 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

25 ) -> None: 

26 """Test de la méthode list_items().""" 

27 mock_http.request.return_value = make_response(_paged([ITEM_JSON])) 

28 

29 result = sync_client.items.list_items( 

30 request=ItemsQuery( 

31 min_id=0, 

32 from_date="", 

33 to_date="" 

34 ), 

35 with_selected_fields=False 

36 ) 

37 

38 assert result.elements is not None 

39 assert len(result.elements) == 1 

40 assert result.elements[0].id == 5 

41 assert result.elements[0].vat_percent == pytest.approx(20.0) # type: ignore[misc] 

42 

43 def test_list_passe_les_filtres( 

44 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

45 ) -> None: 

46 """Test de la méthode list_items().""" 

47 mock_http.request.return_value = make_response(_paged([])) 

48 

49 sync_client.items.list_items( 

50 request=ItemsQuery( 

51 search="conseil", 

52 min_id=3, 

53 from_date="", 

54 to_date="" 

55 ), 

56 with_selected_fields=False 

57 ) 

58 

59 _, kwargs = mock_http.request.call_args 

60 params = kwargs["params"] 

61 assert params["search"] == "conseil" 

62 assert params["minId"] == 3 

63 

64 def test_add_cree_article( 

65 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

66 ) -> None: 

67 """Test de la méthode add_item().""" 

68 mock_http.request.return_value = make_response({**ITEM_JSON, "id": 99}) 

69 item = Item(vat_percent=20.0, creation_date="2025-01-01") # type: ignore[call-arg] 

70 

71 result = sync_client.items.add(item) 

72 

73 assert result.id == 99 

74 assert mock_http.request.call_args.args[0] == "POST" 

75 

76 def test_get_retourne_article( 

77 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

78 ) -> None: 

79 """Test de la méthode get_item().""" 

80 mock_http.request.return_value = make_response(ITEM_JSON) 

81 

82 result = sync_client.items.get(5) 

83 

84 assert result.id == 5 

85 assert "/v1/items/5" in mock_http.request.call_args.args[1] 

86 

87 def test_modify_met_a_jour( 

88 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

89 ) -> None: 

90 """Test de la méthode modify_item().""" 

91 updated: dict[str, Any] = {**ITEM_JSON, "description": "Conseil modifié"} 

92 mock_http.request.return_value = make_response(updated) 

93 

94 result = sync_client.items.modify( 

95 5, 

96 Item( # type: ignore[call-arg] 

97 vat_percent=20.0, 

98 creation_date="2025-01-01" 

99 ) 

100 ) 

101 

102 assert result.description == "Conseil modifié" 

103 assert mock_http.request.call_args.args[0] == "PUT" 

104 

105 def test_delete_article( 

106 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

107 ) -> None: 

108 """Test de la méthode delete_item().""" 

109 mock_http.request.return_value = make_response({}) 

110 

111 sync_client.items.delete(5) 

112 

113 assert mock_http.request.call_args.args[0] == "DELETE" 

114 assert "/v1/items/5" in mock_http.request.call_args.args[1] 

115 

116 def test_get_most_used( 

117 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

118 ) -> None: 

119 """Test de la méthode get_most_used().""" 

120 mock_http.request.return_value = make_response(_paged([ITEM_JSON])) 

121 

122 result = sync_client.items.get_most_used() 

123 

124 assert result.elements is not None 

125 assert len(result.elements) == 1 

126 assert "/items/most-used" in mock_http.request.call_args.args[1] 

127 

128 def test_get_best_sales( 

129 self, sync_client: SyncHenrriClient, mock_http: MagicMock 

130 ) -> None: 

131 """Test de la méthode get_best_sales().""" 

132 mock_http.request.return_value = make_response(_paged([ITEM_JSON])) 

133 

134 result = sync_client.items.get_best_sales(year=2025) 

135 

136 assert result.elements is not None 

137 assert len(result.elements) == 1 

138 assert "/with-selected-fields" in mock_http.request.call_args.args[1] 

139 

140 

141class TestAsyncItems: 

142 """Test de la classe AsyncItems.""" 

143 async def test_list_retourne_articles( 

144 self, async_client: AsyncHenrriClient, mock_async_http: AsyncMock 

145 ) -> None: 

146 """Test de la méthode list_items().""" 

147 mock_async_http.request.return_value = make_response(_paged([ITEM_JSON])) 

148 

149 result = await async_client.items.list_items( 

150 request=ItemsQuery( 

151 min_id=0, 

152 from_date="", 

153 to_date="" 

154 ), 

155 with_selected_fields=False 

156 ) 

157 

158 assert result.elements is not None 

159 assert len(result.elements) == 1 

160 

161 async def test_get_retourne_article( 

162 self, async_client: AsyncHenrriClient, mock_async_http: AsyncMock 

163 ) -> None: 

164 """Test de la méthode get_item().""" 

165 mock_async_http.request.return_value = make_response(ITEM_JSON) 

166 

167 result = await async_client.items.get(5) 

168 

169 assert result.id == 5 

170 

171 async def test_delete_article( 

172 self, async_client: AsyncHenrriClient, mock_async_http: AsyncMock 

173 ) -> None: 

174 """Test de la méthode delete_item().""" 

175 mock_async_http.request.return_value = make_response({}) 

176 

177 await async_client.items.delete(5) 

178 

179 assert mock_async_http.request.call_args.args[0] == "DELETE"