You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RequestTest.java 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.api.server.ws;
  21. import com.google.common.collect.ArrayListMultimap;
  22. import com.google.common.collect.ListMultimap;
  23. import com.tngtech.java.junit.dataprovider.DataProvider;
  24. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  25. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  26. import java.io.InputStream;
  27. import java.util.Date;
  28. import java.util.HashMap;
  29. import java.util.List;
  30. import java.util.Map;
  31. import java.util.Optional;
  32. import java.util.concurrent.atomic.AtomicInteger;
  33. import java.util.function.Consumer;
  34. import java.util.stream.Collectors;
  35. import javax.annotation.Nullable;
  36. import org.apache.commons.io.IOUtils;
  37. import org.junit.Before;
  38. import org.junit.Rule;
  39. import org.junit.Test;
  40. import org.junit.rules.ExpectedException;
  41. import org.junit.runner.RunWith;
  42. import org.sonar.api.rule.RuleStatus;
  43. import org.sonar.api.impl.ws.PartImpl;
  44. import org.sonar.api.impl.ws.ValidatingRequest;
  45. import org.sonar.api.utils.DateUtils;
  46. import static com.google.common.base.Strings.repeat;
  47. import static com.google.common.collect.Lists.newArrayList;
  48. import static java.lang.String.format;
  49. import static org.assertj.core.api.Assertions.assertThat;
  50. import static org.assertj.core.api.Assertions.assertThatThrownBy;
  51. import static org.assertj.core.api.Assertions.fail;
  52. import static org.mockito.Mockito.mock;
  53. import static org.mockito.Mockito.when;
  54. import static org.sonar.api.utils.DateUtils.parseDate;
  55. import static org.sonar.api.utils.DateUtils.parseDateTime;
  56. @RunWith(DataProviderRunner.class)
  57. public class RequestTest {
  58. @Rule
  59. public ExpectedException expectedException = ExpectedException.none();
  60. private FakeRequest underTest = new FakeRequest();
  61. @Before
  62. public void before() {
  63. WebService.Context context = new WebService.Context();
  64. new FakeWs().define(context);
  65. underTest.setAction(context.controller("my_controller").action("my_action"));
  66. }
  67. @Test
  68. public void has_param() {
  69. underTest.setParam("a_required_string", "foo");
  70. assertThat(underTest.hasParam("a_required_string")).isTrue();
  71. assertThat(underTest.hasParam("unknown")).isFalse();
  72. }
  73. @Test
  74. public void required_param_is_missing() {
  75. expectedException.expect(IllegalArgumentException.class);
  76. expectedException.expectMessage("The 'required_param' parameter is missing");
  77. underTest.mandatoryParam("required_param");
  78. }
  79. @Test
  80. public void required_param() {
  81. underTest.setParam("a_required_string", "foo");
  82. underTest.setParam("a_required_number", "42");
  83. underTest.setParam("a_required_boolean", "true");
  84. underTest.setParam("a_required_enum", "BETA");
  85. assertThat(underTest.mandatoryParam("a_required_string")).isEqualTo("foo");
  86. assertThat(underTest.mandatoryParamAsBoolean("a_required_boolean")).isTrue();
  87. assertThat(underTest.mandatoryParamAsInt("a_required_number")).isEqualTo(42);
  88. assertThat(underTest.mandatoryParamAsLong("a_required_number")).isEqualTo(42L);
  89. assertThat(underTest.mandatoryParamAsEnum("a_required_enum", RuleStatus.class)).isEqualTo(RuleStatus.BETA);
  90. }
  91. @Test
  92. public void maximum_length_ok() {
  93. String parameter = "maximum_length_param";
  94. defineParameterTestAction(newParam -> newParam.setMaximumLength(10), parameter);
  95. String value = repeat("X", 10);
  96. String param = underTest.setParam(parameter, value).param(parameter);
  97. assertThat(param).isEqualTo(value);
  98. }
  99. @Test
  100. public void maximum_length_not_ok() {
  101. String parameter = "maximum_length_param";
  102. defineParameterTestAction(newParam -> newParam.setMaximumLength(10), parameter);
  103. expectedException.expect(IllegalArgumentException.class);
  104. expectedException.expectMessage(format("'%s' length (11) is longer than the maximum authorized (10)", parameter));
  105. underTest.setParam(parameter, repeat("X", 11)).param(parameter);
  106. }
  107. @Test
  108. public void maximum_value_ok() {
  109. String param = "maximum_value_param";
  110. defineParameterTestAction(newParam -> newParam.setMaximumValue(10), param);
  111. String expected = "10";
  112. String actual = underTest.setParam(param, expected).param(param);
  113. assertThat(actual).isEqualTo(expected);
  114. }
  115. @Test
  116. public void maximum_value_not_ok() {
  117. String param = "maximum_value_param";
  118. defineParameterTestAction(newParam -> newParam.setMaximumValue(10), param);
  119. expectedException.expect(IllegalArgumentException.class);
  120. expectedException.expectMessage(format("'%s' value (11) must be less than 10", param));
  121. underTest.setParam(param, "11").param(param);
  122. }
  123. @Test
  124. public void paramAsInt_throws_IAE_if_maximum_defined_and_value_not_a_number() {
  125. String param = "maximum_value_param";
  126. defineParameterTestAction(newParam -> newParam.setMaximumValue(10), param);
  127. expectedException.expect(IllegalArgumentException.class);
  128. expectedException.expectMessage("'maximum_value_param' value 'foo' cannot be parsed as an integer");
  129. underTest.setParam(param, "foo").paramAsInt(param);
  130. }
  131. @Test
  132. public void required_param_as_strings() {
  133. underTest.setParam("a_required_string", "foo,bar");
  134. assertThat(underTest.mandatoryParamAsStrings("a_required_string")).containsExactly("foo", "bar");
  135. }
  136. @Test
  137. public void fail_if_no_required_param_as_strings() {
  138. expectedException.expect(IllegalArgumentException.class);
  139. expectedException.expectMessage("The 'a_required_string' parameter is missing");
  140. underTest.mandatoryParamAsStrings("a_required_string");
  141. }
  142. @Test
  143. public void multi_param() {
  144. assertThat(underTest.multiParam("a_required_multi_param")).isEmpty();
  145. underTest.setMultiParam("a_required_multi_param", newArrayList("firstValue", "secondValue", "thirdValue"));
  146. assertThat(underTest.multiParam("a_required_multi_param")).containsExactly("firstValue", "secondValue", "thirdValue");
  147. }
  148. @Test
  149. public void fail_when_multi_param_has_more_values_than_maximum_values() {
  150. underTest.setMultiParam("has_maximum_values", newArrayList("firstValue", "secondValue", "thirdValue"));
  151. expectedException.expect(IllegalArgumentException.class);
  152. expectedException.expectMessage("'has_maximum_values' can contains only 2 values, got 3");
  153. underTest.multiParam("has_maximum_values");
  154. }
  155. @Test
  156. public void mandatory_multi_param() {
  157. underTest.setMultiParam("a_required_multi_param", newArrayList("firstValue", "secondValue", "thirdValue"));
  158. List<String> result = underTest.mandatoryMultiParam("a_required_multi_param");
  159. assertThat(result).containsExactly("firstValue", "secondValue", "thirdValue");
  160. }
  161. @Test
  162. public void fail_when_no_multi_param() {
  163. expectedException.expect(IllegalArgumentException.class);
  164. expectedException.expectMessage("The 'a_required_multi_param' parameter is missing");
  165. underTest.mandatoryMultiParam("a_required_multi_param");
  166. }
  167. @Test
  168. public void default_value_of_optional_param() {
  169. assertThat(underTest.param("has_default_string")).isEqualTo("the_default_string");
  170. }
  171. @Test
  172. public void param_as_string() {
  173. assertThat(underTest.setParam("a_string", "foo").param("a_string")).isEqualTo("foo");
  174. assertThat(underTest.setParam("a_string", " f o o \r\n ").param("a_string")).isEqualTo("f o o");
  175. }
  176. @Test
  177. public void param_contains_NUL_char_should_throw_exception() {
  178. underTest.setParam("a_string", "value\0value");
  179. assertThatThrownBy(() -> underTest.param("a_string"))
  180. .isInstanceOf(IllegalArgumentException.class)
  181. .hasMessage("Request parameters are not allowed to contain NUL character");
  182. }
  183. @Test
  184. public void null_param() {
  185. assertThat(underTest.param("a_string")).isNull();
  186. assertThat(underTest.paramAsBoolean("a_boolean")).isNull();
  187. assertThat(underTest.paramAsInt("a_number")).isNull();
  188. assertThat(underTest.paramAsLong("a_number")).isNull();
  189. }
  190. @Test
  191. public void paramAsInt() {
  192. assertThat(underTest.setParam("a_number", "123").paramAsInt("a_number")).isEqualTo(123);
  193. }
  194. @Test
  195. public void fail_when_param_is_not_an_int() {
  196. expectedException.expect(IllegalArgumentException.class);
  197. expectedException.expectMessage("The 'a_number' parameter cannot be parsed as an integer value: not-an-int");
  198. assertThat(underTest.setParam("a_number", "not-an-int").paramAsInt("a_number")).isEqualTo(123);
  199. }
  200. @Test
  201. public void param_as_long() {
  202. assertThat(underTest.setParam("a_number", "123").paramAsLong("a_number")).isEqualTo(123L);
  203. }
  204. @Test
  205. public void fail_when_param_is_not_a_long() {
  206. expectedException.expect(IllegalArgumentException.class);
  207. expectedException.expectMessage("The 'a_number' parameter cannot be parsed as a long value: not_a_long");
  208. underTest.setParam("a_number", "not_a_long").paramAsLong("a_number");
  209. }
  210. @Test
  211. public void param_as_boolean() {
  212. assertThat(underTest.setParam("a_boolean", "true").paramAsBoolean("a_boolean")).isTrue();
  213. assertThat(underTest.setParam("a_boolean", "yes").paramAsBoolean("a_boolean")).isTrue();
  214. assertThat(underTest.setParam("a_boolean", "false").paramAsBoolean("a_boolean")).isFalse();
  215. assertThat(underTest.setParam("a_boolean", "no").paramAsBoolean("a_boolean")).isFalse();
  216. }
  217. @Test
  218. public void fail_if_incorrect_param_as_boolean() {
  219. expectedException.expect(IllegalArgumentException.class);
  220. expectedException.expectMessage("Property a_boolean is not a boolean value: oui");
  221. underTest.setParam("a_boolean", "oui").paramAsBoolean("a_boolean");
  222. }
  223. @Test
  224. public void param_as_enum() {
  225. assertThat(underTest.setParam("a_enum", "BETA").paramAsEnum("a_enum", RuleStatus.class)).isEqualTo(RuleStatus.BETA);
  226. }
  227. @Test
  228. public void param_as_enums() {
  229. assertThat(underTest.setParam("a_enum", "BETA,READY").paramAsEnums("a_enum", RuleStatus.class)).containsOnly(RuleStatus.BETA, RuleStatus.READY);
  230. assertThat(underTest.setParam("a_enum", "").paramAsEnums("a_enum", RuleStatus.class)).isEmpty();
  231. }
  232. @Test
  233. public void param_as_enums_returns_null_when_no_value() {
  234. assertThat(underTest.paramAsEnums("a_enum", RuleStatus.class)).isNull();
  235. }
  236. @Test
  237. public void fail_when_param_as_enums_has_more_values_than_maximum_values() {
  238. expectedException.expect(IllegalArgumentException.class);
  239. expectedException.expectMessage("'has_maximum_values' can contains only 2 values, got 3");
  240. underTest.setParam("has_maximum_values", "BETA,READY,REMOVED").paramAsEnums("has_maximum_values", RuleStatus.class);
  241. }
  242. @Test
  243. public void param_as_date() {
  244. assertThat(underTest.setParam("a_date", "2014-05-27").paramAsDate("a_date")).isEqualTo(DateUtils.parseDate("2014-05-27"));
  245. }
  246. @Test
  247. public void getParam_of_missing_string_parameter() {
  248. Request.StringParam stringParam = underTest.getParam("a_string");
  249. assertThat(stringParam.isPresent()).isFalse();
  250. expectSupplierCanNotBeNullNPE(() -> stringParam.or(null));
  251. assertThat(stringParam.or(() -> "foo")).isEqualTo("foo");
  252. expectGetValueFailureWithISE(stringParam::getValue);
  253. Request.StringParam emptyAsNull = stringParam.emptyAsNull();
  254. assertThat(emptyAsNull).isSameAs(stringParam);
  255. assertThat(emptyAsNull.isPresent()).isFalse();
  256. expectSupplierCanNotBeNullNPE(() -> emptyAsNull.or(null));
  257. assertThat(emptyAsNull.or(() -> "bar")).isEqualTo("bar");
  258. expectGetValueFailureWithISE(emptyAsNull::getValue);
  259. }
  260. @Test
  261. public void getParam_of_existing_string_parameter_with_non_empty_value() {
  262. underTest.setParam("a_string", "sorry");
  263. Request.StringParam stringParam = underTest.getParam("a_string");
  264. assertThat(stringParam.isPresent()).isTrue();
  265. expectSupplierCanNotBeNullNPE(() -> stringParam.or(null));
  266. assertThat(stringParam.or(() -> "foo")).isEqualTo("sorry");
  267. assertThat(stringParam.getValue()).isEqualTo("sorry");
  268. Request.StringParam emptyAsNull = stringParam.emptyAsNull();
  269. assertThat(emptyAsNull).isSameAs(stringParam);
  270. assertThat(emptyAsNull.isPresent()).isTrue();
  271. expectSupplierCanNotBeNullNPE(() -> emptyAsNull.or(null));
  272. assertThat(emptyAsNull.or(() -> "bar")).isEqualTo("sorry");
  273. assertThat(emptyAsNull.getValue()).isEqualTo("sorry");
  274. }
  275. @Test
  276. public void getParam_of_existing_string_parameter_with_empty_value() {
  277. underTest.setParam("a_string", "");
  278. Request.StringParam stringParam = underTest.getParam("a_string");
  279. assertThat(stringParam.isPresent()).isTrue();
  280. expectSupplierCanNotBeNullNPE(() -> stringParam.or(null));
  281. assertThat(stringParam.or(() -> "foo")).isEqualTo("");
  282. assertThat(stringParam.getValue()).isEqualTo("");
  283. Request.StringParam emptyAsNull = stringParam.emptyAsNull();
  284. assertThat(emptyAsNull).isNotSameAs(stringParam);
  285. assertThat(emptyAsNull.isPresent()).isTrue();
  286. expectSupplierCanNotBeNullNPE(() -> emptyAsNull.or(null));
  287. assertThat(emptyAsNull.or(() -> "bar")).isNull();
  288. assertThat(emptyAsNull.getValue()).isNull();
  289. }
  290. @Test
  291. public void getParam_with_validation_of_missing_string_parameter() {
  292. Request.StringParam stringParam = underTest.getParam("a_string", (str) -> {
  293. throw new IllegalStateException("validator should not be called");
  294. });
  295. assertThat(stringParam.isPresent()).isFalse();
  296. expectSupplierCanNotBeNullNPE(() -> stringParam.or(null));
  297. assertThat(stringParam.or(() -> "foo")).isEqualTo("foo");
  298. expectGetValueFailureWithISE(stringParam::getValue);
  299. Request.StringParam emptyAsNull = stringParam.emptyAsNull();
  300. assertThat(emptyAsNull).isSameAs(stringParam);
  301. assertThat(emptyAsNull.isPresent()).isFalse();
  302. expectSupplierCanNotBeNullNPE(() -> emptyAsNull.or(null));
  303. assertThat(emptyAsNull.or(() -> "bar")).isEqualTo("bar");
  304. expectGetValueFailureWithISE(emptyAsNull::getValue);
  305. }
  306. @Test
  307. public void getParam_with_validation_of_existing_string_parameter_with_non_empty_value() {
  308. underTest.setParam("a_string", "sorry");
  309. AtomicInteger calls = new AtomicInteger();
  310. Request.StringParam stringParam = underTest.getParam("a_string", (str) -> calls.incrementAndGet());
  311. assertThat(calls.get()).isEqualTo(1);
  312. assertThat(stringParam.isPresent()).isTrue();
  313. expectSupplierCanNotBeNullNPE(() -> stringParam.or(null));
  314. assertThat(stringParam.or(() -> "foo")).isEqualTo("sorry");
  315. assertThat(stringParam.getValue()).isEqualTo("sorry");
  316. Request.StringParam emptyAsNull = stringParam.emptyAsNull();
  317. assertThat(emptyAsNull).isSameAs(stringParam);
  318. assertThat(emptyAsNull.isPresent()).isTrue();
  319. expectSupplierCanNotBeNullNPE(() -> emptyAsNull.or(null));
  320. assertThat(emptyAsNull.or(() -> "bar")).isEqualTo("sorry");
  321. assertThat(emptyAsNull.getValue()).isEqualTo("sorry");
  322. }
  323. @Test
  324. public void getParam_with_validation_of_existing_string_parameter_with_empty_value() {
  325. underTest.setParam("a_string", "");
  326. AtomicInteger calls = new AtomicInteger();
  327. Request.StringParam stringParam = underTest.getParam("a_string", (str) -> calls.incrementAndGet());
  328. assertThat(calls.get()).isEqualTo(1);
  329. assertThat(stringParam.isPresent()).isTrue();
  330. expectSupplierCanNotBeNullNPE(() -> stringParam.or(null));
  331. assertThat(stringParam.or(() -> "foo")).isEqualTo("");
  332. assertThat(stringParam.getValue()).isEqualTo("");
  333. Request.StringParam emptyAsNull = stringParam.emptyAsNull();
  334. assertThat(emptyAsNull).isNotSameAs(stringParam);
  335. assertThat(emptyAsNull.isPresent()).isTrue();
  336. expectSupplierCanNotBeNullNPE(() -> emptyAsNull.or(null));
  337. assertThat(emptyAsNull.or(() -> "bar")).isNull();
  338. assertThat(emptyAsNull.getValue()).isNull();
  339. }
  340. @Test
  341. public void getParam_with_validation_of_existing_string_parameter_does_not_catch_unchecked_exception_throws_by_validator() {
  342. underTest.setParam("a_string", "boo");
  343. IllegalArgumentException expected = new IllegalArgumentException("Faking validation of parameter value failed");
  344. try {
  345. underTest.getParam("a_string", (str) -> {
  346. throw expected;
  347. });
  348. fail("an IllegalStateException should have been raised");
  349. } catch (IllegalArgumentException e) {
  350. assertThat(e).isSameAs(expected);
  351. }
  352. }
  353. @Test
  354. public void getParam_of_missing_parameter_of_unspecified_type() {
  355. Request.Param<Object> param = underTest.getParam("a_string", (rqt, key) -> {
  356. throw new IllegalStateException("retrieveAndValidate BiConsumer should not be called");
  357. });
  358. assertThat(param.isPresent()).isFalse();
  359. expectSupplierCanNotBeNullNPE(() -> param.or(null));
  360. assertThat(param.or(() -> "foo")).isEqualTo("foo");
  361. expectGetValueFailureWithISE(param::getValue);
  362. }
  363. @Test
  364. public void getParam_of_existing_parameter_of_unspecified_type_with_null_value() {
  365. underTest.setParam("a_string", "value in fake request actually does not matter");
  366. Request.Param<Object> param = underTest.getParam("a_string", (rqt, key) -> null);
  367. assertThat(param.isPresent()).isTrue();
  368. expectSupplierCanNotBeNullNPE(() -> param.or(null));
  369. assertThat(param.or(() -> "foo")).isNull();
  370. assertThat(param.getValue()).isNull();
  371. }
  372. @Test
  373. public void getParam_of_existing_parameter_of_unspecified_type_with_empty_string() {
  374. underTest.setParam("a_string", "value in fake request actually does not matter");
  375. Request.Param<Object> param = underTest.getParam("a_string", (rqt, key) -> "");
  376. assertThat(param.isPresent()).isTrue();
  377. expectSupplierCanNotBeNullNPE(() -> param.or(null));
  378. assertThat(param.or(() -> "foo")).isEqualTo("");
  379. assertThat(param.getValue()).isEqualTo("");
  380. }
  381. @Test
  382. public void getParam_of_existing_parameter_of_unspecified_type_with_object() {
  383. underTest.setParam("a_string", "value in fake request actually does not matter");
  384. Object value = new Object();
  385. Request.Param<Object> param = underTest.getParam("a_string", (rqt, key) -> value);
  386. assertThat(param.isPresent()).isTrue();
  387. expectSupplierCanNotBeNullNPE(() -> param.or(null));
  388. assertThat(param.or(() -> "foo")).isSameAs(value);
  389. assertThat(param.getValue()).isSameAs(value);
  390. }
  391. @Test
  392. public void getParam_of_existing_parameter_of_unspecified_type_does_not_catch_unchecked_exception_thrown_by_BiConsumer() {
  393. underTest.setParam("a_string", "value in fake request actually does not matter");
  394. RuntimeException expected = new RuntimeException("Faking BiConsumer throwing unchecked exception");
  395. try {
  396. underTest.getParam("a_string", (rqt, key) -> {
  397. throw expected;
  398. });
  399. fail("an RuntimeException should have been raised");
  400. } catch (RuntimeException e) {
  401. assertThat(e).isSameAs(expected);
  402. }
  403. }
  404. private void expectGetValueFailureWithISE(Runnable runnable) {
  405. try {
  406. runnable.run();
  407. fail("An IllegalStateException should have been raised");
  408. } catch (IllegalStateException e) {
  409. assertThat(e).hasMessage("Param has no value. Use isPresent() before calling getValue()");
  410. }
  411. }
  412. private void expectSupplierCanNotBeNullNPE(Runnable runnable) {
  413. try {
  414. runnable.run();
  415. fail("A NullPointerException should have been raised");
  416. } catch (NullPointerException e) {
  417. assertThat(e).hasMessage("default value supplier can't be null");
  418. }
  419. }
  420. @DataProvider
  421. public static Object[][] date_times() {
  422. return new Object[][] {
  423. {"2014-05-27", parseDate("2014-05-27")},
  424. {"2014-05-27T15:50:45+0100", parseDateTime("2014-05-27T15:50:45+0100")},
  425. {null, null}
  426. };
  427. }
  428. @Test
  429. @UseDataProvider("date_times")
  430. public void param_as__date_time(String stringDate, Date expectedDate) {
  431. assertThat(underTest.setParam("a_date", stringDate).paramAsDateTime("a_date")).isEqualTo(expectedDate);
  432. }
  433. @Test
  434. public void fail_when_param_as_date_not_a_date() {
  435. expectedException.expect(IllegalArgumentException.class);
  436. expectedException.expectMessage("The date 'polop' does not respect format 'yyyy-MM-dd'");
  437. underTest.setParam("a_date", "polop").paramAsDate("a_date");
  438. }
  439. @Test
  440. public void fail_when_param_as_datetime_not_a_datetime() {
  441. expectedException.expect(IllegalArgumentException.class);
  442. expectedException.expectMessage("'polop' cannot be parsed as either a date or date+time");
  443. underTest.setParam("a_datetime", "polop").paramAsDateTime("a_datetime");
  444. }
  445. @Test
  446. public void param_as_strings() {
  447. assertThat(underTest.paramAsStrings("a_string")).isNull();
  448. assertThat(underTest.setParam("a_string", "").paramAsStrings("a_string")).isEmpty();
  449. assertThat(underTest.setParam("a_string", "bar").paramAsStrings("a_string")).containsExactly("bar");
  450. assertThat(underTest.setParam("a_string", "bar,baz").paramAsStrings("a_string")).containsExactly("bar", "baz");
  451. assertThat(underTest.setParam("a_string", "bar , baz").paramAsStrings("a_string")).containsExactly("bar", "baz");
  452. }
  453. @Test
  454. public void fail_when_param_as_strings_has_more_values_than_maximum_values() {
  455. expectedException.expect(IllegalArgumentException.class);
  456. expectedException.expectMessage("'has_maximum_values' can contains only 2 values, got 3");
  457. underTest.setParam("has_maximum_values", "foo,bar,baz").paramAsStrings("has_maximum_values");
  458. }
  459. @Test
  460. public void deprecated_key() {
  461. assertThat(underTest.setParam("deprecated_param", "bar").param("new_param")).isEqualTo("bar");
  462. }
  463. @Test
  464. public void fail_if_param_is_not_defined() {
  465. expectedException.expect(IllegalArgumentException.class);
  466. expectedException.expectMessage("BUG - parameter 'unknown' is undefined for action 'my_action'");
  467. underTest.param("unknown");
  468. }
  469. @Test
  470. public void fail_if_multi_param_is_not_defined() {
  471. expectedException.expect(IllegalArgumentException.class);
  472. expectedException.expectMessage("Parameter 'unknown' not found for action 'my_action'");
  473. underTest.multiParam("unknown");
  474. }
  475. @Test
  476. public void verify_possible_values() {
  477. underTest.setParam("has_possible_values", "foo");
  478. assertThat(underTest.param("has_possible_values")).isEqualTo("foo");
  479. }
  480. @Test
  481. public void fail_if_not_a_possible_value() {
  482. underTest.setParam("has_possible_values", "not_possible");
  483. expectedException.expect(IllegalArgumentException.class);
  484. expectedException.expectMessage("Value of parameter 'has_possible_values' (not_possible) must be one of: [foo, bar]");
  485. underTest.param("has_possible_values");
  486. }
  487. @Test
  488. public void param_as_input_stream() throws Exception {
  489. assertThat(underTest.paramAsInputStream("a_string")).isNull();
  490. assertThat(IOUtils.toString(underTest.setParam("a_string", "").paramAsInputStream("a_string"))).isEmpty();
  491. assertThat(IOUtils.toString(underTest.setParam("a_string", "foo").paramAsInputStream("a_string"))).isEqualTo("foo");
  492. }
  493. @Test
  494. public void param_as_part() {
  495. InputStream inputStream = mock(InputStream.class);
  496. underTest.setPart("key", inputStream, "filename");
  497. Request.Part part = underTest.paramAsPart("key");
  498. assertThat(part.getInputStream()).isEqualTo(inputStream);
  499. assertThat(part.getFileName()).isEqualTo("filename");
  500. assertThat(underTest.paramAsPart("unknown")).isNull();
  501. }
  502. @Test
  503. public void mandatory_param_as_part() {
  504. expectedException.expect(IllegalArgumentException.class);
  505. expectedException.expectMessage("The 'required_param' parameter is missing");
  506. underTest.mandatoryParamAsPart("required_param");
  507. }
  508. private void defineParameterTestAction(Consumer<WebService.NewParam> newParam, String parameter) {
  509. String controllerPath = "my_controller";
  510. String actionPath = "my_action";
  511. WebService.Context context = new WebService.Context();
  512. WebService.NewController controller = context.createController(controllerPath);
  513. WebService.NewAction action = controller
  514. .createAction(actionPath)
  515. .setHandler(mock(RequestHandler.class));
  516. WebService.NewParam param = action.createParam(parameter);
  517. newParam.accept(param);
  518. controller.done();
  519. underTest.setAction(context.controller(controllerPath).action(actionPath));
  520. }
  521. private static class FakeRequest extends ValidatingRequest {
  522. private final ListMultimap<String, String> multiParams = ArrayListMultimap.create();
  523. private final Map<String, String> params = new HashMap<>();
  524. private final Map<String, Part> parts = new HashMap<>();
  525. private final Map<String, String> headers = new HashMap<>();
  526. @Override
  527. public String method() {
  528. return "GET";
  529. }
  530. @Override
  531. public String getMediaType() {
  532. return "application/json";
  533. }
  534. @Override
  535. public boolean hasParam(String key) {
  536. return params.keySet().contains(key);
  537. }
  538. @Override
  539. public String getPath() {
  540. return null;
  541. }
  542. public FakeRequest setParam(String key, @Nullable String value) {
  543. if (value != null) {
  544. params.put(key, value);
  545. }
  546. return this;
  547. }
  548. public FakeRequest setMultiParam(String key, List<String> values) {
  549. multiParams.putAll(key, values);
  550. return this;
  551. }
  552. @Override
  553. protected String readParam(String key) {
  554. return params.get(key);
  555. }
  556. @Override
  557. public Map<String, String[]> getParams() {
  558. ArrayListMultimap<String, String> result = ArrayListMultimap.create(multiParams);
  559. params.forEach(result::put);
  560. return result.asMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toArray(new String[0])));
  561. }
  562. @Override
  563. protected List<String> readMultiParam(String key) {
  564. return multiParams.get(key);
  565. }
  566. @Override
  567. protected InputStream readInputStreamParam(String key) {
  568. String param = readParam(key);
  569. return param == null ? null : IOUtils.toInputStream(param);
  570. }
  571. @Override
  572. protected Part readPart(String key) {
  573. return parts.get(key);
  574. }
  575. public FakeRequest setPart(String key, InputStream input, String fileName) {
  576. parts.put(key, new PartImpl(input, fileName));
  577. return this;
  578. }
  579. @Override
  580. public Optional<String> header(String name) {
  581. return Optional.ofNullable(headers.get(name));
  582. }
  583. public FakeRequest setHeader(String name, String value) {
  584. headers.put(name, value);
  585. return this;
  586. }
  587. }
  588. private static class FakeWs implements WebService {
  589. @Override
  590. public void define(Context context) {
  591. NewController controller = context.createController("my_controller");
  592. NewAction action = controller.createAction("my_action")
  593. .setDescription("Action Description")
  594. .setPost(true)
  595. .setSince("5.2")
  596. .setHandler(mock(RequestHandler.class));
  597. action
  598. .createParam("required_param")
  599. .setRequired(true);
  600. action.createParam("a_string");
  601. action.createParam("a_boolean");
  602. action.createParam("a_number");
  603. action.createParam("a_enum");
  604. action.createParam("a_date");
  605. action.createParam("a_datetime");
  606. action.createParam("a_required_string").setRequired(true);
  607. action.createParam("a_required_boolean").setRequired(true);
  608. action.createParam("a_required_number").setRequired(true);
  609. action.createParam("a_required_enum").setRequired(true);
  610. action.createParam("a_required_multi_param").setRequired(true);
  611. action.createParam("has_default_string").setDefaultValue("the_default_string");
  612. action.createParam("has_default_number").setDefaultValue("10");
  613. action.createParam("has_default_boolean").setDefaultValue("true");
  614. action.createParam("has_possible_values").setPossibleValues("foo", "bar");
  615. action.createParam("has_maximum_values").setMaxValuesAllowed(2);
  616. action.createParam("new_param").setDeprecatedKey("deprecated_param", "6.3");
  617. action.createParam("new_param_with_default_value").setDeprecatedKey("deprecated_new_param_with_default_value", "6.2").setDefaultValue("the_default_string");
  618. controller.done();
  619. }
  620. }
  621. }