Coverage for tests/utils/test_args.py: 100%

56 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-02-09 12:09 +0100

1from __future__ import annotations 

2 

3from typing import Dict 

4from typing import List 

5from typing import Optional 

6from typing import Type 

7 

8import pytest 

9import typer 

10from pydantic import BaseModel 

11 

12from harbor_cli.utils.args import create_updated_model 

13from harbor_cli.utils.args import model_params_from_ctx 

14from harbor_cli.utils.args import parse_commalist 

15from harbor_cli.utils.args import parse_key_value_args 

16 

17 

18class Model(BaseModel): 

19 a: str 

20 b: Optional[str] 

21 c: int 

22 d: Optional[int] 

23 e: bool 

24 f: Optional[bool] 

25 foo: str = "foo" 

26 

27 

28class ModelUpdateReq(BaseModel): 

29 a: Optional[str] 

30 b: Optional[str] 

31 c: Optional[int] 

32 d: Optional[int] 

33 e: Optional[bool] 

34 f: Optional[bool] 

35 bar: str = "bar" 

36 

37 

38@pytest.mark.parametrize("b", [None, "b"]) 

39def test_model_params_from_ctx(mock_ctx: typer.Context, b: Optional[str]) -> None: 

40 

41 mock_ctx.params = { 

42 "a": "a-updated", 

43 "b": b, 

44 "c": 11, 

45 "e": False, 

46 "foo": "foo-updated", 

47 "bar": "bar-updated", 

48 } 

49 params = model_params_from_ctx(mock_ctx, Model) 

50 # kinda primitive but whatever 

51 if b is None: 

52 assert params == { 

53 "a": "a-updated", 

54 "c": 11, 

55 "e": False, 

56 "foo": "foo-updated", 

57 } 

58 else: 

59 assert params == { 

60 "a": "a-updated", 

61 "b": "b", 

62 "c": 11, 

63 "e": False, 

64 "foo": "foo-updated", 

65 } 

66 

67 

68def test_create_updated_model(mock_ctx: typer.Context) -> None: 

69 # The model we retrieve from the API (GET /<resource>) 

70 model = Model(a="a", b="b", c=1, d=2, e=True, f=False) 

71 

72 # The params we get from the context (CLI) 

73 mock_ctx.params = { 

74 "a": "a-updated", 

75 "b": "b-updated", 

76 "c": 11, 

77 "e": False, 

78 "foo": "foo-updated", 

79 "bar": "bar-updated", 

80 } 

81 

82 # Create the updated model combining the two 

83 updated_model = create_updated_model(model, ModelUpdateReq, mock_ctx) 

84 assert updated_model == ModelUpdateReq( 

85 a="a-updated", 

86 b="b-updated", 

87 c=11, 

88 d=2, 

89 e=False, 

90 f=False, 

91 bar="bar-updated", 

92 ) 

93 

94 # Test with the "API" model as well 

95 updated_model_base = create_updated_model(model, Model, mock_ctx) 

96 assert updated_model_base == Model( 

97 a="a-updated", 

98 b="b-updated", 

99 c=11, 

100 d=2, 

101 e=False, 

102 f=False, 

103 foo="foo-updated", 

104 ) 

105 

106 

107@pytest.mark.parametrize( 

108 "arg,expected", 

109 [ 

110 ([], []), 

111 (["foo"], ["foo"]), 

112 (["foo,bar"], ["foo", "bar"]), 

113 (["foo,bar", "baz"], ["foo", "bar", "baz"]), 

114 (["foo,bar", "baz,qux"], ["foo", "bar", "baz", "qux"]), 

115 ], 

116) 

117def test_parse_commalist(arg: list[str], expected: list[str]) -> None: 

118 assert parse_commalist(arg) == expected 

119 

120 

121@pytest.mark.parametrize( 

122 "arg,expected", 

123 [ 

124 ([], {}), 

125 (["foo=bar"], {"foo": "bar"}), 

126 (["foo=bar", "baz=qux"], {"foo": "bar", "baz": "qux"}), 

127 ( 

128 ["foo=bar", "baz=qux", "quux=quuz"], 

129 {"foo": "bar", "baz": "qux", "quux": "quuz"}, 

130 ), 

131 ], 

132) 

133def test_parse_key_value_arg(arg: list[str], expected: dict[str, str]) -> None: 

134 assert parse_key_value_args(arg) == expected 

135 

136 

137@pytest.mark.parametrize( 

138 "arg,expected,raises,exception", 

139 [ 

140 # Valid 

141 ([], {}, False, None), 

142 (["foo=bar"], {"foo": "bar"}, False, None), 

143 (["foo=bar", "baz=qux"], {"foo": "bar", "baz": "qux"}, False, None), 

144 ( 

145 ["foo=bar", "spam=grok", "baz=qux"], 

146 {"foo": "bar", "spam": "grok", "baz": "qux"}, 

147 False, 

148 None, 

149 ), 

150 ( 

151 ["foo=bar,spam=grok", "baz=qux"], 

152 {"foo": "bar", "spam": "grok", "baz": "qux"}, 

153 False, 

154 None, 

155 ), 

156 ( 

157 ["foo=bar", "spam=grok", "baz=qux", "idk=lol"], 

158 {"foo": "bar", "spam": "grok", "baz": "qux", "idk": "lol"}, 

159 False, 

160 None, 

161 ), 

162 ( 

163 ["foo=bar,spam=grok", "baz=qux,idk=lol"], 

164 {"foo": "bar", "spam": "grok", "baz": "qux", "idk": "lol"}, 

165 False, 

166 None, 

167 ), 

168 # Invalid 

169 (["foo"], {"foo": None}, True, typer.BadParameter), 

170 (["foo=bar", "baz"], {"foo": "bar", "baz": None}, True, typer.BadParameter), 

171 ( 

172 ["foo=bar", "baz=qux", "quux"], 

173 {"foo": "bar", "baz": "qux", "quux": None}, 

174 True, 

175 typer.BadParameter, 

176 ), 

177 ], 

178) 

179def test_parse_key_value_arg_with_comma( 

180 arg: List[str], 

181 expected: Dict[str, str], 

182 raises: bool, 

183 exception: Optional[Type[Exception]], 

184) -> None: 

185 if raises and exception is not None: 

186 with pytest.raises(exception): 

187 args = parse_commalist(arg) 

188 parse_key_value_args(args) 

189 else: 

190 args = parse_commalist(arg) 

191 assert parse_key_value_args(args) == expected