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.

ProjectAlmBindingDaoTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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.db.alm;
  21. import java.util.Arrays;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Objects;
  25. import java.util.Optional;
  26. import javax.annotation.Nullable;
  27. import org.assertj.core.api.AbstractAssert;
  28. import org.junit.Rule;
  29. import org.junit.Test;
  30. import org.junit.rules.ExpectedException;
  31. import org.sonar.api.utils.System2;
  32. import org.sonar.core.util.UuidFactory;
  33. import org.sonar.db.DbClient;
  34. import org.sonar.db.DbSession;
  35. import org.sonar.db.DbTester;
  36. import org.sonar.db.component.ComponentDto;
  37. import org.sonar.db.component.ComponentTesting;
  38. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  39. import static org.assertj.core.api.Assertions.assertThat;
  40. import static org.assertj.core.api.Assertions.tuple;
  41. import static org.mockito.Mockito.mock;
  42. import static org.mockito.Mockito.when;
  43. import static org.sonar.db.alm.ALM.BITBUCKETCLOUD;
  44. import static org.sonar.db.alm.ALM.GITHUB;
  45. public class ProjectAlmBindingDaoTest {
  46. private static final String A_UUID = "abcde1234";
  47. private static final String ANOTHER_UUID = "xyz789";
  48. private static final String EMPTY_STRING = "";
  49. private static final String A_REPO = "my_repo";
  50. private static final String ANOTHER_REPO = "another_repo";
  51. private static final String A_GITHUB_SLUG = null;
  52. private static final String ANOTHER_GITHUB_SLUG = "example/foo";
  53. private static final String A_URL = "foo url";
  54. private static final String ANOTHER_URL = "bar url";
  55. private static final long DATE = 1_600_000_000_000L;
  56. private static final long DATE_LATER = 1_700_000_000_000L;
  57. private System2 system2 = mock(System2.class);
  58. @Rule
  59. public ExpectedException expectedException = ExpectedException.none();
  60. @Rule
  61. public DbTester dbTester = DbTester.create(system2);
  62. private DbClient dbClient = dbTester.getDbClient();
  63. private DbSession dbSession = dbTester.getSession();
  64. private UuidFactory uuidFactory = mock(UuidFactory.class);
  65. private ProjectAlmBindingDao underTest = new ProjectAlmBindingDao(system2, uuidFactory);
  66. @Test
  67. public void insert_throws_NPE_if_alm_is_null() {
  68. expectAlmNPE();
  69. underTest.insertOrUpdate(dbSession, null, A_REPO, A_UUID, A_GITHUB_SLUG, A_URL);
  70. }
  71. @Test
  72. public void insert_throws_IAE_if_repo_id_is_null() {
  73. expectRepoIdNullOrEmptyIAE();
  74. underTest.insertOrUpdate(dbSession, GITHUB, null, A_UUID, A_GITHUB_SLUG, A_URL);
  75. }
  76. @Test
  77. public void insert_throws_IAE_if_repo_id_is_empty() {
  78. expectRepoIdNullOrEmptyIAE();
  79. underTest.insertOrUpdate(dbSession, GITHUB, EMPTY_STRING, A_UUID, A_GITHUB_SLUG, A_URL);
  80. }
  81. @Test
  82. public void insert_throws_IAE_if_project_uuid_is_null() {
  83. expectProjectUuidNullOrEmptyIAE();
  84. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, null, A_GITHUB_SLUG, A_URL);
  85. }
  86. @Test
  87. public void insert_throws_IAE_if_project_uuid_is_empty() {
  88. expectProjectUuidNullOrEmptyIAE();
  89. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, EMPTY_STRING, A_GITHUB_SLUG, A_URL);
  90. }
  91. @Test
  92. public void insert_throws_IAE_if_url_is_null() {
  93. expectUrlNullOrEmptyIAE();
  94. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, A_UUID, A_GITHUB_SLUG, null);
  95. }
  96. @Test
  97. public void insert_throws_IAE_if_url_is_empty() {
  98. expectUrlNullOrEmptyIAE();
  99. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, A_UUID, A_GITHUB_SLUG, EMPTY_STRING);
  100. }
  101. @Test
  102. public void insert() {
  103. when(system2.now()).thenReturn(DATE);
  104. when(uuidFactory.create()).thenReturn("uuid1");
  105. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, A_UUID, A_GITHUB_SLUG, A_URL);
  106. assertThatProjectAlmBinding(GITHUB, A_REPO)
  107. .hasProjectUuid(A_UUID)
  108. .hasGithubSlug(A_GITHUB_SLUG)
  109. .hasUrl(A_URL)
  110. .hasCreatedAt(DATE)
  111. .hasUpdatedAt(DATE);
  112. }
  113. @Test
  114. public void update() {
  115. when(system2.now()).thenReturn(DATE);
  116. when(uuidFactory.create()).thenReturn("uuid1");
  117. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, A_UUID, A_GITHUB_SLUG, A_URL);
  118. when(system2.now()).thenReturn(DATE_LATER);
  119. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, ANOTHER_UUID, ANOTHER_GITHUB_SLUG, ANOTHER_URL);
  120. assertThatProjectAlmBinding(GITHUB, A_REPO)
  121. .hasProjectUuid(ANOTHER_UUID)
  122. .hasGithubSlug(ANOTHER_GITHUB_SLUG)
  123. .hasUrl(ANOTHER_URL)
  124. .hasCreatedAt(DATE)
  125. .hasUpdatedAt(DATE_LATER);
  126. }
  127. @Test
  128. public void insert_multiple() {
  129. when(system2.now()).thenReturn(DATE);
  130. when(uuidFactory.create()).thenReturn("uuid1").thenReturn("uuid2");
  131. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, A_UUID, A_GITHUB_SLUG, A_URL);
  132. underTest.insertOrUpdate(dbSession, GITHUB, ANOTHER_REPO, ANOTHER_UUID, ANOTHER_GITHUB_SLUG, ANOTHER_URL);
  133. assertThatProjectAlmBinding(GITHUB, A_REPO)
  134. .hasProjectUuid(A_UUID)
  135. .hasGithubSlug(A_GITHUB_SLUG)
  136. .hasUrl(A_URL)
  137. .hasCreatedAt(DATE)
  138. .hasUpdatedAt(DATE);
  139. assertThatProjectAlmBinding(GITHUB, ANOTHER_REPO)
  140. .hasProjectUuid(ANOTHER_UUID)
  141. .hasGithubSlug(ANOTHER_GITHUB_SLUG)
  142. .hasUrl(ANOTHER_URL)
  143. .hasCreatedAt(DATE)
  144. .hasUpdatedAt(DATE);
  145. }
  146. @Test
  147. public void select_by_repo_id() {
  148. when(system2.now()).thenReturn(DATE);
  149. when(uuidFactory.create())
  150. .thenReturn("uuid1")
  151. .thenReturn("uuid2")
  152. .thenReturn("uuid3");
  153. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, A_UUID, A_GITHUB_SLUG, A_URL);
  154. underTest.insertOrUpdate(dbSession, GITHUB, ANOTHER_REPO, ANOTHER_UUID, null, ANOTHER_URL);
  155. underTest.insertOrUpdate(dbSession, BITBUCKETCLOUD, ANOTHER_REPO, "foo", null, "http://foo");
  156. assertThat(underTest.selectByRepoId(dbSession, GITHUB, "foo")).isNotPresent();
  157. Optional<ProjectAlmBindingDto> dto = underTest.selectByRepoId(dbSession, GITHUB, A_REPO);
  158. assertThat(dto).isPresent();
  159. assertThat(dto.get().getUuid()).isEqualTo("uuid1");
  160. assertThat(dto.get().getAlm()).isEqualTo(GITHUB);
  161. assertThat(dto.get().getRepoId()).isEqualTo(A_REPO);
  162. assertThat(dto.get().getProjectUuid()).isEqualTo(A_UUID);
  163. assertThat(dto.get().getUrl()).isEqualTo(A_URL);
  164. assertThat(dto.get().getGithubSlug()).isEqualTo(A_GITHUB_SLUG);
  165. }
  166. @Test
  167. public void select_by_project_uuid() {
  168. when(system2.now()).thenReturn(DATE);
  169. when(uuidFactory.create())
  170. .thenReturn("uuid1")
  171. .thenReturn("uuid2")
  172. .thenReturn("uuid3");
  173. underTest.insertOrUpdate(dbSession, BITBUCKETCLOUD, A_REPO, A_UUID, A_GITHUB_SLUG, A_URL);
  174. underTest.insertOrUpdate(dbSession, BITBUCKETCLOUD, ANOTHER_REPO, ANOTHER_UUID, null, ANOTHER_URL);
  175. underTest.insertOrUpdate(dbSession, GITHUB, ANOTHER_REPO, "foo", null, "http://foo");
  176. assertThat(underTest.selectByProjectUuid(dbSession, "missing")).isNotPresent();
  177. Optional<ProjectAlmBindingDto> dto = underTest.selectByProjectUuid(dbSession, A_UUID);
  178. assertThat(dto).isPresent();
  179. assertThat(dto.get().getUuid()).isEqualTo("uuid1");
  180. assertThat(dto.get().getAlm()).isEqualTo(BITBUCKETCLOUD);
  181. assertThat(dto.get().getRepoId()).isEqualTo(A_REPO);
  182. assertThat(dto.get().getProjectUuid()).isEqualTo(A_UUID);
  183. assertThat(dto.get().getUrl()).isEqualTo(A_URL);
  184. assertThat(dto.get().getGithubSlug()).isEqualTo(A_GITHUB_SLUG);
  185. }
  186. @Test
  187. public void select_by_repo_ids() {
  188. when(system2.now()).thenReturn(DATE);
  189. when(uuidFactory.create())
  190. .thenReturn("uuid1")
  191. .thenReturn("uuid2")
  192. .thenReturn("uuid3");
  193. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, A_UUID, A_GITHUB_SLUG, A_URL);
  194. underTest.insertOrUpdate(dbSession, GITHUB, ANOTHER_REPO, ANOTHER_UUID, null, ANOTHER_URL);
  195. underTest.insertOrUpdate(dbSession, BITBUCKETCLOUD, ANOTHER_REPO, "foo", null, "http://foo");
  196. assertThat(underTest.selectByRepoIds(dbSession, GITHUB, Arrays.asList(A_REPO, ANOTHER_REPO, "foo")))
  197. .extracting(ProjectAlmBindingDto::getUuid, ProjectAlmBindingDto::getAlm, ProjectAlmBindingDto::getRepoId, ProjectAlmBindingDto::getProjectUuid,
  198. ProjectAlmBindingDto::getUrl, ProjectAlmBindingDto::getGithubSlug)
  199. .containsExactlyInAnyOrder(
  200. tuple("uuid1", GITHUB, A_REPO, A_UUID, A_URL, A_GITHUB_SLUG),
  201. tuple("uuid2", GITHUB, ANOTHER_REPO, ANOTHER_UUID, ANOTHER_URL, null));
  202. }
  203. @Test
  204. public void findProjectKey_throws_NPE_when_alm_is_null() {
  205. expectAlmNPE();
  206. underTest.findProjectKey(dbSession, null, A_REPO);
  207. }
  208. @Test
  209. public void findProjectKey_throws_IAE_when_repo_id_is_null() {
  210. expectRepoIdNullOrEmptyIAE();
  211. underTest.findProjectKey(dbSession, GITHUB, null);
  212. }
  213. @Test
  214. public void findProjectKey_throws_IAE_when_repo_id_is_empty() {
  215. expectRepoIdNullOrEmptyIAE();
  216. underTest.findProjectKey(dbSession, GITHUB, EMPTY_STRING);
  217. }
  218. @Test
  219. public void findProjectKey_returns_empty_when_entry_does_not_exist_in_DB() {
  220. assertThat(underTest.findProjectKey(dbSession, GITHUB, A_REPO)).isEmpty();
  221. }
  222. @Test
  223. public void findProjectKey_returns_projectKey_when_entry_exists() {
  224. String projectKey = randomAlphabetic(10);
  225. ComponentDto project = createProject(projectKey);
  226. when(uuidFactory.create()).thenReturn("uuid1");
  227. underTest.insertOrUpdate(dbSession, GITHUB, A_REPO, project.projectUuid(), A_GITHUB_SLUG, A_URL);
  228. assertThat(underTest.findProjectKey(dbSession, GITHUB, A_REPO)).contains(projectKey);
  229. }
  230. private void expectAlmNPE() {
  231. expectedException.expect(NullPointerException.class);
  232. expectedException.expectMessage("alm can't be null");
  233. }
  234. private void expectRepoIdNullOrEmptyIAE() {
  235. expectedException.expect(IllegalArgumentException.class);
  236. expectedException.expectMessage("repoId can't be null nor empty");
  237. }
  238. private void expectProjectUuidNullOrEmptyIAE() {
  239. expectedException.expect(IllegalArgumentException.class);
  240. expectedException.expectMessage("projectUuid can't be null nor empty");
  241. }
  242. private void expectUrlNullOrEmptyIAE() {
  243. expectedException.expect(IllegalArgumentException.class);
  244. expectedException.expectMessage("url can't be null nor empty");
  245. }
  246. private ProjectAlmBindingAssert assertThatProjectAlmBinding(ALM alm, String repoId) {
  247. return new ProjectAlmBindingAssert(dbTester, dbSession, alm, repoId);
  248. }
  249. private static class ProjectAlmBindingAssert extends AbstractAssert<ProjectAlmBindingAssert, ProjectAlmBinding> {
  250. private ProjectAlmBindingAssert(DbTester dbTester, DbSession dbSession, ALM alm, String repoId) {
  251. super(asProjectAlmBinding(dbTester, dbSession, alm, repoId), ProjectAlmBindingAssert.class);
  252. }
  253. private static ProjectAlmBinding asProjectAlmBinding(DbTester dbTester, DbSession dbSession, ALM alm, String repoId) {
  254. List<Map<String, Object>> rows = dbTester.select(
  255. dbSession,
  256. "select" +
  257. " project_uuid as \"projectUuid\", github_slug as \"githubSlug\", url as \"url\", " +
  258. " created_at as \"createdAt\", updated_at as \"updatedAt\"" +
  259. " from project_alm_bindings" +
  260. " where alm_id='" + alm.getId() + "' and repo_id='" + repoId + "'");
  261. if (rows.isEmpty()) {
  262. return null;
  263. }
  264. if (rows.size() > 1) {
  265. throw new IllegalStateException("Unique index violation");
  266. }
  267. return new ProjectAlmBinding(
  268. (String) rows.get(0).get("projectUuid"),
  269. (String) rows.get(0).get("githubSlug"),
  270. (String) rows.get(0).get("url"),
  271. (Long) rows.get(0).get("createdAt"),
  272. (Long) rows.get(0).get("updatedAt"));
  273. }
  274. public void doesNotExist() {
  275. isNull();
  276. }
  277. ProjectAlmBindingAssert hasProjectUuid(String expected) {
  278. isNotNull();
  279. if (!Objects.equals(actual.projectUuid, expected)) {
  280. failWithMessage("Expected Project ALM Binding to have column PROJECT_UUID to be <%s> but was <%s>", expected, actual.projectUuid);
  281. }
  282. return this;
  283. }
  284. ProjectAlmBindingAssert hasGithubSlug(String expected) {
  285. isNotNull();
  286. if (!Objects.equals(actual.githubSlug, expected)) {
  287. failWithMessage("Expected Project ALM Binding to have column GITHUB_SLUG to be <%s> but was <%s>", expected, actual.githubSlug);
  288. }
  289. return this;
  290. }
  291. ProjectAlmBindingAssert hasUrl(String expected) {
  292. isNotNull();
  293. if (!Objects.equals(actual.url, expected)) {
  294. failWithMessage("Expected Project ALM Binding to have column URL to be <%s> but was <%s>", expected, actual.url);
  295. }
  296. return this;
  297. }
  298. ProjectAlmBindingAssert hasCreatedAt(long expected) {
  299. isNotNull();
  300. if (!Objects.equals(actual.createdAt, expected)) {
  301. failWithMessage("Expected Project ALM Binding to have column CREATED_AT to be <%s> but was <%s>", expected, actual.createdAt);
  302. }
  303. return this;
  304. }
  305. ProjectAlmBindingAssert hasUpdatedAt(long expected) {
  306. isNotNull();
  307. if (!Objects.equals(actual.updatedAt, expected)) {
  308. failWithMessage("Expected Project ALM Binding to have column UPDATED_AT to be <%s> but was <%s>", expected, actual.updatedAt);
  309. }
  310. return this;
  311. }
  312. }
  313. private static final class ProjectAlmBinding {
  314. private final String projectUuid;
  315. private final String githubSlug;
  316. private final String url;
  317. private final Long createdAt;
  318. private final Long updatedAt;
  319. ProjectAlmBinding(@Nullable String projectUuid, @Nullable String githubSlug, @Nullable String url, @Nullable Long createdAt, @Nullable Long updatedAt) {
  320. this.projectUuid = projectUuid;
  321. this.githubSlug = githubSlug;
  322. this.url = url;
  323. this.createdAt = createdAt;
  324. this.updatedAt = updatedAt;
  325. }
  326. }
  327. private ComponentDto createProject(String projectKey) {
  328. ComponentDto project = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert()).setDbKey(projectKey);
  329. dbClient.componentDao().insert(dbSession, project);
  330. dbSession.commit();
  331. return project;
  332. }
  333. }