diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java index 06988a2ec..89de17bb6 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java @@ -104,10 +104,9 @@ public BitbucketGitSCMBuilder(@NonNull BitbucketSCMSource scmSource, @NonNull SC this.scmSource = scmSource; String serverURL = scmSource.getServerUrl(); - AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(serverURL); - if (endpoint == null) { - endpoint = new BitbucketServerEndpoint(null, serverURL, false, null); - } + AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(serverURL) + .orElse(new BitbucketServerEndpoint(null, serverURL, false, null)); String repositoryURL = endpoint.getRepositoryUrl(scmSource.getRepoOwner(), scmSource.getRepository()); if (BitbucketApiUtils.isCloud(endpoint.getServerUrl())) { diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator.java index b9243386f..5cd9fee2d 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator.java @@ -102,6 +102,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.interceptor.RequirePOST; import static com.cloudbees.jenkins.plugins.bitbucket.impl.util.BitbucketApiUtils.getFromBitbucket; @@ -290,7 +291,7 @@ public String getServerUrl() { @DataBoundSetter public void setServerUrl(String serverUrl) { serverUrl = BitbucketEndpointConfiguration.normalizeServerUrl(serverUrl); - if (!StringUtils.equals(this.serverUrl, serverUrl)) { + if (serverUrl != null && !StringUtils.equals(this.serverUrl, serverUrl)) { this.serverUrl = serverUrl; resetId(); } @@ -384,14 +385,14 @@ public String getPattern() { @DataBoundSetter public void setBitbucketServerUrl(String url) { url = BitbucketEndpointConfiguration.normalizeServerUrl(url); - AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(url); - if (endpoint != null) { - // we have a match - setServerUrl(url); - return; + url = StringUtils.defaultIfBlank(url, BitbucketCloudEndpoint.SERVER_URL); + AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(url) + .orElse(null); + if (endpoint == null) { + LOGGER.log(Level.WARNING, "Call to legacy setBitbucketServerUrl({0}) method is configuring a url missing " + + "from the global configuration.", url); } - LOGGER.log(Level.WARNING, "Call to legacy setBitbucketServerUrl({0}) method is configuring a url missing " - + "from the global configuration.", url); setServerUrl(url); } @@ -400,7 +401,10 @@ public void setBitbucketServerUrl(String url) { @RestrictedSince("2.2.0") @CheckForNull public String getBitbucketServerUrl() { - if (BitbucketEndpointConfiguration.get().findEndpoint(serverUrl) instanceof BitbucketCloudEndpoint) { + if (BitbucketEndpointConfiguration.get() + .findEndpoint(serverUrl) + .filter(BitbucketCloudEndpoint.class::isInstance) + .isPresent()) { return null; } return serverUrl; @@ -629,7 +633,7 @@ public String getIconClassName() { @Override public SCMNavigator newInstance(String name) { BitbucketSCMNavigator instance = new BitbucketSCMNavigator(StringUtils.defaultString(name)); - instance.setTraits((List) getTraitsDefaults()); + instance.setTraits(getTraitsDefaults()); return instance; } @@ -647,16 +651,21 @@ public ListBoxModel doFillServerUrlItems(@AncestorInPath SCMSourceOwner context) return BitbucketEndpointConfiguration.get().getEndpointItems(); } + @RequirePOST @SuppressWarnings("unused") // used By stapler - public FormValidation doCheckCredentialsId(@AncestorInPath SCMSourceOwner context, @QueryParameter String serverUrl, @QueryParameter String value) { - return BitbucketCredentials.checkCredentialsId(context, value, serverUrl); + public static FormValidation doCheckCredentialsId(@AncestorInPath SCMSourceOwner context, + @QueryParameter(fixEmpty = true, value = "serverUrl") String serverURL, + @QueryParameter String value) { + return BitbucketCredentials.checkCredentialsId(context, value, serverURL); } + @RequirePOST @SuppressWarnings("unused") // used By stapler - public static FormValidation doCheckMirrorId(@QueryParameter String value, @QueryParameter String serverUrl) { + public static FormValidation doCheckMirrorId(@QueryParameter String value, + @QueryParameter(fixEmpty = true, value = "serverUrl") String serverURL) { if (!value.isEmpty()) { BitbucketServerWebhookImplementation webhookImplementation = - BitbucketServerEndpoint.findWebhookImplementation(serverUrl); + BitbucketServerEndpoint.findWebhookImplementation(serverURL); if (webhookImplementation == BitbucketServerWebhookImplementation.PLUGIN) { return FormValidation.error("Mirror can only be used with native webhooks"); } @@ -666,13 +675,13 @@ public static FormValidation doCheckMirrorId(@QueryParameter String value, @Quer @SuppressWarnings("unused") // used By stapler public ListBoxModel doFillCredentialsIdItems(@AncestorInPath SCMSourceOwner context, - @QueryParameter String serverUrl) { - return BitbucketCredentials.fillCredentialsIdItems(context, serverUrl); + @QueryParameter(fixEmpty = true, value = "serverUrl") String serverURL) { + return BitbucketCredentials.fillCredentialsIdItems(context, serverURL); } @SuppressWarnings("unused") // used By stapler public ListBoxModel doFillMirrorIdItems(@AncestorInPath SCMSourceOwner context, - @QueryParameter String serverUrl, + @QueryParameter(fixEmpty = true, value = "serverUrl") String serverUrl, @QueryParameter String credentialsId, @QueryParameter String repoOwner) throws FormFillFailure { diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java index 01bdee406..8b453abd7 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java @@ -375,7 +375,11 @@ public String getServerUrl() { @DataBoundSetter public void setServerUrl(@CheckForNull String serverUrl) { - this.serverUrl = BitbucketEndpointConfiguration.normalizeServerUrl(serverUrl); + if (serverUrl == null) { + this.serverUrl = BitbucketEndpointConfiguration.get().getDefaultEndpoint().getServerUrl(); + } else { + this.serverUrl = BitbucketEndpointConfiguration.normalizeServerUrl(serverUrl); + } } @NonNull @@ -401,7 +405,10 @@ public void setTraits(@CheckForNull List traits) { @DataBoundSetter public void setBitbucketServerUrl(String url) { url = BitbucketEndpointConfiguration.normalizeServerUrl(url); - AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(url); + url = StringUtils.defaultIfBlank(url, BitbucketCloudEndpoint.SERVER_URL); + AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(url) + .orElse(null); if (endpoint != null) { // we have a match setServerUrl(endpoint.getServerUrl()); @@ -418,7 +425,10 @@ public void setBitbucketServerUrl(String url) { @CheckForNull public String getBitbucketServerUrl() { String serverUrl = getServerUrl(); - if (BitbucketEndpointConfiguration.get().findEndpoint(serverUrl) instanceof BitbucketCloudEndpoint) { + if (BitbucketEndpointConfiguration.get() + .findEndpoint(serverUrl) + .filter(BitbucketCloudEndpoint.class::isInstance) + .isPresent()) { return null; } return serverUrl; @@ -1336,8 +1346,8 @@ public String getDisplayName() { @SuppressWarnings("unused") // used By stapler public FormValidation doCheckCredentialsId(@CheckForNull @AncestorInPath SCMSourceOwner context, @QueryParameter String value, - @QueryParameter String serverUrl) { - return BitbucketCredentials.checkCredentialsId(context, value, serverUrl); + @QueryParameter(fixEmpty = true, value = "serverUrl") String serverURL) { + return BitbucketCredentials.checkCredentialsId(context, value, serverURL); } @SuppressWarnings("unused") // used By stapler @@ -1353,11 +1363,13 @@ public static FormValidation doCheckServerUrl(@AncestorInPath SCMSourceOwner con return FormValidation.ok(); } + @RequirePOST @SuppressWarnings("unused") // used By stapler - public static FormValidation doCheckMirrorId(@QueryParameter String value, @QueryParameter String serverUrl) { + public static FormValidation doCheckMirrorId(@QueryParameter String value, + @QueryParameter(fixEmpty = true, value = "serverUrl") String serverURL) { if (!value.isEmpty()) { BitbucketServerWebhookImplementation webhookImplementation = - BitbucketServerEndpoint.findWebhookImplementation(serverUrl); + BitbucketServerEndpoint.findWebhookImplementation(serverURL); if (webhookImplementation == BitbucketServerWebhookImplementation.PLUGIN) { return FormValidation.error("Mirror can only be used with native webhooks"); } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceBuilder.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceBuilder.java index 27f8145da..204f48695 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceBuilder.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceBuilder.java @@ -23,7 +23,6 @@ */ package com.cloudbees.jenkins.plugins.bitbucket; -import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import jenkins.scm.api.trait.SCMSourceBuilder; @@ -74,7 +73,7 @@ public BitbucketSCMSourceBuilder(@CheckForNull String id, @NonNull String server @NonNull String repoName, @CheckForNull String mirrorId) { super(BitbucketSCMSource.class, repoName); this.id = id; - this.serverUrl = BitbucketEndpointConfiguration.normalizeServerUrl(serverUrl); + this.serverUrl = serverUrl; this.credentialsId = credentialsId; this.mirrorId = mirrorId; this.repoOwner = repoOwner; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiFactory.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiFactory.java index 493419c0c..dcf712209 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiFactory.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiFactory.java @@ -22,14 +22,16 @@ protected boolean isMatch(@Nullable String serverUrl) { @Override protected BitbucketApi create(@Nullable String serverUrl, @Nullable BitbucketAuthenticator authenticator, @NonNull String owner, @CheckForNull String projectKey, @CheckForNull String repository) { - AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(BitbucketCloudEndpoint.SERVER_URL); + AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(BitbucketCloudEndpoint.SERVER_URL) + .orElse(null); boolean enableCache = false; int teamCacheDuration = 0; int repositoriesCacheDuration = 0; - if (endpoint != null && endpoint instanceof BitbucketCloudEndpoint) { - enableCache = ((BitbucketCloudEndpoint) endpoint).isEnableCache(); - teamCacheDuration = ((BitbucketCloudEndpoint) endpoint).getTeamCacheDuration(); - repositoriesCacheDuration = ((BitbucketCloudEndpoint) endpoint).getRepositoriesCacheDuration(); + if (endpoint instanceof BitbucketCloudEndpoint cloudEndpoint) { + enableCache = cloudEndpoint.isEnableCache(); + teamCacheDuration = cloudEndpoint.getTeamCacheDuration(); + repositoriesCacheDuration = cloudEndpoint.getRepositoriesCacheDuration(); } return new BitbucketCloudApiClient( enableCache, teamCacheDuration, repositoriesCacheDuration, diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/AbstractBitbucketEndpoint.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/AbstractBitbucketEndpoint.java index 7e4100fcd..c4d3558cb 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/AbstractBitbucketEndpoint.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/AbstractBitbucketEndpoint.java @@ -144,10 +144,11 @@ public void setBitbucketJenkinsRootUrl(String bitbucketJenkinsRootUrl) { */ @NonNull public String getEndpointJenkinsRootUrl() { - if (StringUtils.isBlank(bitbucketJenkinsRootUrl)) + if (StringUtils.isBlank(bitbucketJenkinsRootUrl)) { return ClassicDisplayURLProvider.get().getRoot(); - else + } else { return bitbucketJenkinsRootUrl; + } } /** @@ -172,7 +173,9 @@ public static String getEndpointJenkinsRootUrl(String serverUrl) { // Note: do not pre-initialize to the global value, so it can be // reconfigured on the fly. - AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(serverUrl); + AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(serverUrl) + .orElse(null); if (endpoint != null) { return endpoint.getEndpointJenkinsRootUrl(); } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfiguration.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfiguration.java index 1df6e0f9b..accef9273 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfiguration.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfiguration.java @@ -36,10 +36,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Locale; +import java.util.Objects; import java.util.Optional; import java.util.Set; import jenkins.model.GlobalConfiguration; @@ -85,6 +85,7 @@ public static BitbucketEndpointConfiguration get() { public Permission getRequiredGlobalConfigPagePermission() { return Jenkins.MANAGE; } + /** * Called from a {@code readResolve()} method only to convert the old {@code bitbucketServerUrl} field into the new * {@code serverUrl} field. When called from {@link ACL#SYSTEM} this will update the configuration with the @@ -97,8 +98,9 @@ public Permission getRequiredGlobalConfigPagePermission() { @NonNull public String readResolveServerUrl(@CheckForNull String bitbucketServerUrl) { String serverUrl = normalizeServerUrl(bitbucketServerUrl); - AbstractBitbucketEndpoint endpoint = findEndpoint(serverUrl); - if (endpoint == null && ACL.SYSTEM.equals(Jenkins.getAuthentication())) { + serverUrl = StringUtils.defaultIfBlank(serverUrl, BitbucketCloudEndpoint.SERVER_URL); + AbstractBitbucketEndpoint endpoint = findEndpoint(serverUrl).orElse(null); + if (endpoint == null && ACL.SYSTEM2.equals(Jenkins.getAuthentication2())) { if (BitbucketCloudEndpoint.SERVER_URL.equals(serverUrl) || BitbucketCloudEndpoint.BAD_SERVER_URL.equals(serverUrl)) { // exception case @@ -107,7 +109,7 @@ public String readResolveServerUrl(@CheckForNull String bitbucketServerUrl) { addEndpoint(new BitbucketServerEndpoint(null, serverUrl, false, null)); } } - return endpoint == null ? serverUrl : endpoint.getServerUrl(); + return endpoint == null ? serverUrl : endpoint.getServerUrl(); } /** @@ -238,66 +240,65 @@ public boolean removeEndpoint(@NonNull AbstractBitbucketEndpoint endpoint) { /** * Removes an endpoint. * - * @param serverUrl the server URL to remove. + * @param serverURL the server URL to remove. * @return {@code true} if the list of endpoints was modified */ - public synchronized boolean removeEndpoint(@CheckForNull String serverUrl) { - serverUrl = normalizeServerUrl(serverUrl); - boolean modified = false; - List endpoints = new ArrayList<>(getEndpoints()); - for (Iterator iterator = endpoints.iterator(); iterator.hasNext(); ) { - if (serverUrl.equals(iterator.next().getServerUrl())) { - iterator.remove(); - modified = true; - } - } - setEndpoints(endpoints); + public synchronized boolean removeEndpoint(@CheckForNull String serverURL) { + String fixedServerURL = normalizeServerUrl(serverURL); + List newEndpoints = new ArrayList<>(getEndpoints()); + boolean modified = newEndpoints.removeIf(endpoint -> Objects.equals(fixedServerURL, endpoint.getServerUrl())); + setEndpoints(newEndpoints); return modified; } /** * Checks to see if the supplied server URL is defined in the global configuration. * - * @param serverUrl the server url to check. + * @param serverURL the server url to check. * @return the global configuration for the specified server url or {@code null} if not defined. */ - @CheckForNull - public synchronized AbstractBitbucketEndpoint findEndpoint(@CheckForNull String serverUrl) { - serverUrl = normalizeServerUrl(serverUrl); + public synchronized Optional findEndpoint(@CheckForNull String serverURL) { + serverURL = normalizeServerUrl(serverURL); for (AbstractBitbucketEndpoint endpoint : getEndpoints()) { - if (serverUrl.equals(endpoint.getServerUrl())) { - return endpoint; + if (Objects.equals(serverURL, endpoint.getServerUrl())) { + return Optional.of(endpoint); } } - return null; + return Optional.empty(); } /** * Checks to see if the supplied server URL is defined in the global configuration. * - * @param serverUrl the server url to check. + * @param serverURL the server url to check. * @param clazz the class to check. * @return the global configuration for the specified server url or {@code null} if not defined. */ - public synchronized Optional findEndpoint(@CheckForNull String serverUrl, - Class clazz) { - return getEndpoints().stream() + public synchronized Optional findEndpoint(@CheckForNull String serverURL, + Class clazz) { + return findEndpoint(serverURL) .filter(clazz::isInstance) - .filter(endpoint -> normalizeServerUrl(serverUrl).equals(endpoint.getServerUrl())) - .findFirst(); + .map(clazz::cast); + } + + @NonNull + public synchronized AbstractBitbucketEndpoint getDefaultEndpoint() { + return getEndpoints().get(0); } /** * Fix a serverUrl. * - * @param serverUrl the server URL. + * @param serverURL the server URL. * @return the normalized server URL. */ - @NonNull - public static String normalizeServerUrl(@CheckForNull String serverUrl) { - serverUrl = StringUtils.defaultIfBlank(serverUrl, BitbucketCloudEndpoint.SERVER_URL); + @CheckForNull + public static String normalizeServerUrl(@CheckForNull String serverURL) { + if (StringUtils.isBlank(serverURL)) { + return null; + } try { - URI uri = new URI(serverUrl).normalize(); + URI uri = new URI(serverURL).normalize(); String scheme = uri.getScheme(); if ("http".equals(scheme) || "https".equals(scheme)) { // we only expect http / https, but also these are the only ones where we know the authority @@ -311,7 +312,7 @@ public static String normalizeServerUrl(@CheckForNull String serverUrl) { } else if ("https".equals(scheme) && port == 443) { port = -1; } - serverUrl = new URI( + serverURL = new URI( scheme, uri.getUserInfo(), host, @@ -324,7 +325,7 @@ public static String normalizeServerUrl(@CheckForNull String serverUrl) { } catch (URISyntaxException e) { // ignore, this was a best effort tidy-up } - return serverUrl.replaceAll("/$", ""); + return serverURL.replaceAll("/$", ""); } } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketServerEndpoint.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketServerEndpoint.java index cbd25577f..4de4c1c0c 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketServerEndpoint.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketServerEndpoint.java @@ -103,11 +103,16 @@ public class BitbucketServerEndpoint extends AbstractBitbucketEndpoint { * @param credentialsId The {@link StandardCredentials#getId()} of the credentials to use for * auto-management of hooks. */ + @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "normalizeServerUrl never return null if given serverUrl is not null") @DataBoundConstructor - public BitbucketServerEndpoint(@CheckForNull String displayName, @NonNull String serverUrl, - boolean manageHooks, @CheckForNull String credentialsId) { + public BitbucketServerEndpoint(@CheckForNull String displayName, + @NonNull String serverUrl, + boolean manageHooks, + @CheckForNull String credentialsId) { super(manageHooks, credentialsId); - this.serverUrl = BitbucketEndpointConfiguration.normalizeServerUrl(serverUrl); + + this.serverUrl = BitbucketEndpointConfiguration.normalizeServerUrl(serverUrl); // NOSONAR + assert this.serverUrl != null; this.displayName = StringUtils.isBlank(displayName) ? SCMName.fromUrl(this.serverUrl, COMMON_PREFIX_HOSTNAMES) : displayName.trim(); @@ -122,9 +127,11 @@ public BitbucketServerEndpoint(@CheckForNull String displayName, @NonNull String @NonNull public static BitbucketServerWebhookImplementation findWebhookImplementation(String serverUrl) { - final AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(serverUrl); - if (endpoint instanceof BitbucketServerEndpoint) { - return ((BitbucketServerEndpoint) endpoint).getWebhookImplementation(); + final BitbucketServerEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(serverUrl, BitbucketServerEndpoint.class) + .orElse(null); + if (endpoint != null) { + return endpoint.getWebhookImplementation(); } return BitbucketServerWebhookImplementation.PLUGIN; @@ -150,12 +157,10 @@ public void setCallChanges(boolean callChanges) { @NonNull public static BitbucketServerVersion findServerVersion(String serverUrl) { - final AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(serverUrl); - if (endpoint instanceof BitbucketServerEndpoint) { - return ((BitbucketServerEndpoint) endpoint).getServerVersion(); - } - - return BitbucketServerVersion.VERSION_7; + return BitbucketEndpointConfiguration.get() + .findEndpoint(serverUrl, BitbucketServerEndpoint.class) + .map(endpoint -> endpoint.getServerVersion()) + .orElse(BitbucketServerVersion.VERSION_7); } @NonNull diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java index 863dc7141..e27f50371 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java @@ -32,10 +32,8 @@ import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApiFactory; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; -import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient; -import com.cloudbees.jenkins.plugins.bitbucket.endpoints.AbstractBitbucketEndpoint; -import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.BitbucketApiUtils; import com.cloudbees.jenkins.plugins.bitbucket.server.BitbucketServerVersion; import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; @@ -166,7 +164,7 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch return null; } - if (apiClient instanceof BitbucketCloudApiClient) { + if (BitbucketApiUtils.isCloud(apiClient)) { // support lightweight checkout for branches with same owner and repository if (prHead.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD && prHead.getRepoOwner().equals(src.getRepoOwner()) && @@ -184,9 +182,8 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch // Bitbucket server v7 doesn't have the `merge` ref for PRs // We don't return `ref` when working with v7 // so that pipeline falls back to heavyweight checkout properly - AbstractBitbucketEndpoint endpointConfig = BitbucketEndpointConfiguration.get().findEndpoint(src.getServerUrl()); - if (endpointConfig instanceof BitbucketServerEndpoint endpoint && - endpoint.getServerVersion() != BitbucketServerVersion.VERSION_7) { + boolean ligthCheckout = BitbucketServerEndpoint.findServerVersion(serverUrl) != BitbucketServerVersion.VERSION_7; + if (ligthCheckout) { ref = "pull-requests/" + prHead.getId() + "/merge"; } else { // returning null to fall back to heavyweight checkout diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookAutoRegisterListener.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookAutoRegisterListener.java index d8a728aea..1a523e791 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookAutoRegisterListener.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookAutoRegisterListener.java @@ -139,8 +139,9 @@ private synchronized void registerHooks(SCMSourceOwner owner) throws IOException case DISABLE: continue; case SYSTEM: - AbstractBitbucketEndpoint endpoint = - BitbucketEndpointConfiguration.get().findEndpoint(source.getServerUrl()); + AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(source.getServerUrl()) + .orElse(null); if (endpoint == null || !endpoint.isManageHooks()) { continue; } @@ -215,8 +216,9 @@ private BitbucketApi bitbucketApiFor(BitbucketSCMSource source) { case DISABLE: return null; case SYSTEM: - AbstractBitbucketEndpoint endpoint = - BitbucketEndpointConfiguration.get().findEndpoint(source.getServerUrl()); + AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(source.getServerUrl()) + .orElse(null); return endpoint == null || !endpoint.isManageHooks() ? null : BitbucketApiFactory.newInstance( diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookConfiguration.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookConfiguration.java index bbd14c4de..43275f44a 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookConfiguration.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookConfiguration.java @@ -26,7 +26,6 @@ import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketWebHook; import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketRepositoryHook; -import com.cloudbees.jenkins.plugins.bitbucket.endpoints.AbstractBitbucketEndpoint; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketCloudEndpoint; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint; @@ -213,9 +212,11 @@ public BitbucketWebHook getHook(BitbucketSCMSource owner) { } private static List getNativeServerEvents(String serverUrl) { - AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(serverUrl); - if (endpoint instanceof BitbucketServerEndpoint) { - switch (((BitbucketServerEndpoint) endpoint).getServerVersion()) { + BitbucketServerEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(serverUrl, BitbucketServerEndpoint.class) + .orElse(null); + if (endpoint != null) { + switch (endpoint.getServerVersion()) { case VERSION_5: return NATIVE_SERVER_EVENTS_v5; case VERSION_5_10: diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketApiUtils.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketApiUtils.java index 74f605397..11434df0e 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketApiUtils.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketApiUtils.java @@ -28,6 +28,10 @@ @Restricted(NoExternalUse.class) public class BitbucketApiUtils { + public interface BitbucketSupplier { + T get(BitbucketApi bitbucketApi) throws IOException, InterruptedException; + } + private static final Logger logger = Logger.getLogger(BitbucketApiUtils.class.getName()); public static boolean isCloud(BitbucketApi client) { @@ -39,7 +43,7 @@ public static boolean isCloud(@NonNull String serverURL) { } public static ListBoxModel getFromBitbucket(SCMSourceOwner context, - String serverUrl, + String serverURL, String credentialsId, String repoOwner, String repository, @@ -57,40 +61,35 @@ public static ListBoxModel getFromBitbucket(SCMSourceOwner context, return new ListBoxModel(); // not permitted to try connecting with these credentials } - String serverUrlFallback = BitbucketCloudEndpoint.SERVER_URL; - // if at least one bitbucket server is configured use it instead of bitbucket cloud - if (!BitbucketEndpointConfiguration.get().getEndpointItems().isEmpty()) { - serverUrlFallback = BitbucketEndpointConfiguration.get().getEndpointItems().get(0).value; - } - - serverUrl = StringUtils.defaultIfBlank(serverUrl, serverUrlFallback); + serverURL = BitbucketEndpointConfiguration.get() + .findEndpoint(serverURL) + .orElse(BitbucketEndpointConfiguration.get().getDefaultEndpoint()) + .getServerUrl(); StandardCredentials credentials = BitbucketCredentials.lookupCredentials( - serverUrl, + serverURL, context, credentialsId, StandardCredentials.class ); - BitbucketAuthenticator authenticator = AuthenticationTokens.convert(BitbucketAuthenticator.authenticationContext(serverUrl), credentials); + BitbucketAuthenticator authenticator = AuthenticationTokens.convert(BitbucketAuthenticator.authenticationContext(serverURL), credentials); try { - BitbucketApi bitbucket = BitbucketApiFactory.newInstance(serverUrl, authenticator, repoOwner, null, repository); + BitbucketApi bitbucket = BitbucketApiFactory.newInstance(serverURL, authenticator, repoOwner, null, repository); return listBoxModelSupplier.get(bitbucket); } catch (FormFillFailure | OutOfMemoryError e) { throw e; } catch (IOException e) { - if (e instanceof BitbucketRequestException) { - if (((BitbucketRequestException) e).getHttpCode() == 401) { - throw FormFillFailure.error(credentials == null - ? Messages.BitbucketSCMSource_UnauthorizedAnonymous(repoOwner) - : Messages.BitbucketSCMSource_UnauthorizedOwner(repoOwner)).withSelectionCleared(); - } - } else if (e.getCause() instanceof BitbucketRequestException) { - if (((BitbucketRequestException) e.getCause()).getHttpCode() == 401) { + if (e instanceof BitbucketRequestException bbe) { + if (bbe.getHttpCode() == 401) { throw FormFillFailure.error(credentials == null ? Messages.BitbucketSCMSource_UnauthorizedAnonymous(repoOwner) : Messages.BitbucketSCMSource_UnauthorizedOwner(repoOwner)).withSelectionCleared(); } + } else if (e.getCause() instanceof BitbucketRequestException cause && cause.getHttpCode() == 401) { + throw FormFillFailure.error(credentials == null + ? Messages.BitbucketSCMSource_UnauthorizedAnonymous(repoOwner) + : Messages.BitbucketSCMSource_UnauthorizedOwner(repoOwner)).withSelectionCleared(); } logger.log(Level.SEVERE, e.getMessage(), e); throw FormFillFailure.error(e.getMessage()); @@ -100,8 +99,4 @@ public static ListBoxModel getFromBitbucket(SCMSourceOwner context, } } - public interface BitbucketSupplier { - T get(BitbucketApi bitbucketApi) throws IOException, InterruptedException; - } - } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketCredentials.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketCredentials.java index 3bd691680..31883c001 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketCredentials.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/BitbucketCredentials.java @@ -24,6 +24,7 @@ package com.cloudbees.jenkins.plugins.bitbucket.impl.util; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; +import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardCertificateCredentials; @@ -41,8 +42,6 @@ import jenkins.model.Jenkins; import jenkins.scm.api.SCMSourceOwner; import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.AncestorInPath; -import org.kohsuke.stapler.QueryParameter; import org.springframework.security.core.Authentication; /** @@ -79,9 +78,7 @@ public static T lookupCredentials(@CheckForNull return null; } - public static ListBoxModel fillCredentialsIdItems( - @AncestorInPath SCMSourceOwner context, - @QueryParameter String serverUrl) { + public static ListBoxModel fillCredentialsIdItems(SCMSourceOwner context, String serverURL) { StandardListBoxModel result = new StandardListBoxModel(); result.includeEmptyValue(); AccessControlled contextToCheck = context == null ? Jenkins.get() : context; @@ -92,21 +89,28 @@ public static ListBoxModel fillCredentialsIdItems( ? task.getDefaultAuthentication2() : ACL.SYSTEM2; + serverURL = BitbucketEndpointConfiguration.get() + .findEndpoint(serverURL) + .orElse(BitbucketEndpointConfiguration.get().getDefaultEndpoint()) + .getServerUrl(); + result.includeMatchingAs( authentication, context, StandardCredentials.class, - URIRequirementBuilder.fromUri(serverUrl).build(), - AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverUrl)) + URIRequirementBuilder.fromUri(serverURL).build(), + AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverURL)) ); return result; } - public static FormValidation checkCredentialsId( - @AncestorInPath @CheckForNull SCMSourceOwner context, - @QueryParameter String value, - @QueryParameter String serverUrl) { - if (!value.isEmpty()) { + public static FormValidation checkCredentialsId(@CheckForNull SCMSourceOwner context, String value, String serverURL) { + if (StringUtils.isNotBlank(value)) { + serverURL = BitbucketEndpointConfiguration.get() + .findEndpoint(serverURL) + .orElse(BitbucketEndpointConfiguration.get().getDefaultEndpoint()) + .getServerUrl(); + AccessControlled contextToCheck = context == null ? Jenkins.get() : context; contextToCheck.checkPermission(CredentialsProvider.VIEW); @@ -119,10 +123,10 @@ public static FormValidation checkCredentialsId( StandardCertificateCredentials.class, context, authentication, - URIRequirementBuilder.fromUri(serverUrl).build()), + URIRequirementBuilder.fromUri(serverURL).build()), CredentialsMatchers.allOf( CredentialsMatchers.withId(value), - AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverUrl)) + AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverURL)) ) ) != null) { return FormValidation.warning("A certificate was selected. You will likely need to configure Checkout over SSH."); @@ -132,4 +136,5 @@ public static FormValidation checkCredentialsId( return FormValidation.warning("Credentials are required for build notifications"); } } + } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java index 06addc5fb..ccd7d59ca 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java @@ -264,8 +264,9 @@ private List getPullRequests(UriTemplate template) pullRequests.removeIf(this::shouldIgnore); - BitbucketServerEndpoint endpoint = (BitbucketServerEndpoint) BitbucketEndpointConfiguration.get(). - findEndpoint(this.baseURL, BitbucketServerEndpoint.class).orElse(null); + BitbucketServerEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(this.baseURL, BitbucketServerEndpoint.class) + .orElse(null); for (BitbucketServerPullRequest pullRequest : pullRequests) { setupPullRequest(pullRequest, endpoint); @@ -395,8 +396,11 @@ public BitbucketPullRequest getPullRequestById(@NonNull Integer id) throws IOExc try { BitbucketServerPullRequest pr = JsonParser.toJava(response, BitbucketServerPullRequest.class); setupClosureForPRBranch(pr); - setupPullRequest(pr, (BitbucketServerEndpoint) BitbucketEndpointConfiguration.get(). - findEndpoint(this.baseURL, BitbucketServerEndpoint.class).orElse(null)); + + BitbucketServerEndpoint endpoint = BitbucketEndpointConfiguration.get() + .findEndpoint(this.baseURL, BitbucketServerEndpoint.class) + .orElse(null); + setupPullRequest(pr, endpoint); return pr; } catch (IOException e) { throw new IOException("I/O error when accessing URL: " + url, e); diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java index ab4b756b8..6052e20d4 100644 --- a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java +++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java @@ -69,7 +69,7 @@ private String loadPayload(String api) throws IOException { @Test @WithJenkins - public void test_proxy_configurad_without_password(JenkinsRule r) throws Exception { + void test_proxy_configurad_without_password(JenkinsRule r) throws Exception { Proxy proxy = mock(Proxy.class); when(proxy.address()).thenReturn(new InetSocketAddress("proxy.lan", 8080)); ProxyConfiguration proxyConfiguration = mock(ProxyConfiguration.class); diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfigurationTest.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfigurationTest.java index ed5a85e9b..76b5f1315 100644 --- a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfigurationTest.java +++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfigurationTest.java @@ -45,32 +45,35 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import jenkins.model.Jenkins; import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assume.assumeThat; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; -public class BitbucketEndpointConfigurationTest { +@WithJenkins +class BitbucketEndpointConfigurationTest { - @ClassRule - public static JenkinsRule j = new JenkinsRule(); + private static JenkinsRule r; - @Before - public void cleanUp() throws IOException { + @BeforeAll + static void init(JenkinsRule rule) { + r = rule; + } + + @AfterEach + void cleanUp() throws IOException { BitbucketEndpointConfiguration.get().setEndpoints(null); new XmlFile(new File(Jenkins.get().getRootDir(), BitbucketEndpointConfiguration.get().getId() + ".xml")) .delete(); @@ -79,259 +82,284 @@ public void cleanUp() throws IOException { } @Test - public void given__newInstance__when__notConfigured__then__cloudPresent() { + void given__newInstance__when__notConfigured__then__cloudPresent() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); } @Test - public void given__newInstance__when__configuredWithEmpty__then__cloudPresent() { + void given__newInstance__when__configuredWithEmpty__then__cloudPresent() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints(Collections.emptyList()); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); } @Test - public void given__newInstance__when__configuredWithCloud__then__cloudPresent() { + void given__newInstance__when__configuredWithCloud__then__cloudPresent() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), not(is("dummy"))); + assumeFalse("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); instance.setEndpoints( Collections.singletonList(new BitbucketCloudEndpoint(true, "dummy"))); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); } @Test - public void given__newInstance__when__configuredWithMultipleCloud__then__onlyFirstCloudPresent() { + void given__newInstance__when__configuredWithMultipleCloud__then__onlyFirstCloudPresent() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), not(is("first"))); + assumeFalse("first".equals(instance.getEndpoints().get(0).getCredentialsId())); instance.setEndpoints(Arrays.asList( new BitbucketCloudEndpoint(true, "first"), new BitbucketCloudEndpoint(true, "second"), new BitbucketCloudEndpoint(true, "third"))); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("first"); + }); } @Test - public void given__newInstance__when__configuredAsAnon__then__permissionError() { + void given__newInstance__when__configuredAsAnon__then__permissionError() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - j.jenkins.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy()); + r.jenkins.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy()); try (ACLContext context = ACL.as(Jenkins.ANONYMOUS)) { - instance.setEndpoints(Arrays.asList( - new BitbucketCloudEndpoint(true, "first"), - new BitbucketCloudEndpoint(true, "second"), - new BitbucketCloudEndpoint(true, "third"))); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); - } catch (RuntimeException x) { - assertThat(x.getMessage(), is(hudson.security.Messages.AccessDeniedException2_MissingPermission("anonymous", "Overall/Administer"))); + assertThatThrownBy(() -> instance.setEndpoints(Arrays.asList( + new BitbucketCloudEndpoint(true, "first"), + new BitbucketCloudEndpoint(true, "second"), + new BitbucketCloudEndpoint(true, "third")))) + .hasMessage(hudson.security.Messages.AccessDeniedException2_MissingPermission("anonymous", "Overall/Administer")); } finally { - j.jenkins.setAuthorizationStrategy(AuthorizationStrategy.UNSECURED); + r.jenkins.setAuthorizationStrategy(AuthorizationStrategy.UNSECURED); } } @Test - public void given__newInstance__when__configuredAsManage__then__OK() { + void given__newInstance__when__configuredAsManage__then__OK() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - try { - j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - MockAuthorizationStrategy mockStrategy = new MockAuthorizationStrategy(); - mockStrategy.grant(Jenkins.MANAGE).onRoot().to("admin"); - j.jenkins.setAuthorizationStrategy(mockStrategy); - try (ACLContext context = ACL.as(User.get("admin"))) { - instance.setEndpoints(Arrays.asList( - new BitbucketCloudEndpoint(true, "first"), - new BitbucketCloudEndpoint(true, "second"), - new BitbucketCloudEndpoint(true, "third"))); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); - } catch (RuntimeException x) { - Assertions.fail("No exception should be thrown"); - } + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + MockAuthorizationStrategy mockStrategy = new MockAuthorizationStrategy(); + mockStrategy.grant(Jenkins.MANAGE).onRoot().to("admin"); + r.jenkins.setAuthorizationStrategy(mockStrategy); + try (ACLContext context = ACL.as(User.get("admin"))) { + instance.setEndpoints(Arrays.asList( + new BitbucketCloudEndpoint(true, "first"), + new BitbucketCloudEndpoint(true, "second"), + new BitbucketCloudEndpoint(true, "third"))); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("first"); + }); } finally { - j.jenkins.setAuthorizationStrategy(AuthorizationStrategy.UNSECURED); + r.jenkins.setAuthorizationStrategy(AuthorizationStrategy.UNSECURED); } } - @Test - public void given__newInstance__when__configuredWithServerUsingCloudUrl__then__convertedToCloud() { + @Test + void given__newInstance__when__configuredWithServerUsingCloudUrl__then__convertedToCloud() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), not(is("dummy"))); + assumeFalse("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); instance.setEndpoints(Arrays.asList( new BitbucketServerEndpoint("I am silly", BitbucketCloudEndpoint.SERVER_URL, true, "dummy"), new BitbucketCloudEndpoint(true, "second"), new BitbucketCloudEndpoint(true, "third"))); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); } @Test - public void given__newInstance__when__configuredWithServer__then__serverPresent() { + void given__newInstance__when__configuredWithServer__then__serverPresent() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), not(is("dummy"))); + assumeFalse("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"))); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getDisplayName(), is("Example Inc")); - assertThat(instance.getEndpoints().get(0).getServerUrl(), is("https://bitbucket.example.com")); - assertThat(instance.getEndpoints().get(0).isManageHooks(), is(true)); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); + + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(endpoint.getServerUrl()).isEqualTo("https://bitbucket.example.com"); + assertThat(endpoint.isManageHooks()).isTrue(); + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); } @Test - public void given__newInstance__when__configuredWithTwoServers__then__serversPresent() { + void given__newInstance__when__configuredWithTwoServers__then__serversPresent() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), not(is("dummy"))); + assumeFalse("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); instance.setEndpoints( Arrays.asList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", false, null))); - assertThat(instance.getEndpoints(), - contains(instanceOf(BitbucketServerEndpoint.class), instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getDisplayName(), is("Example Inc")); - assertThat(instance.getEndpoints().get(0).getServerUrl(), is("https://bitbucket.example.com")); - assertThat(instance.getEndpoints().get(0).isManageHooks(), is(true)); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.getEndpoints().get(1).getDisplayName(), is("Example Org")); - assertThat(instance.getEndpoints().get(1).getServerUrl(), is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpoints().get(1).isManageHooks(), is(false)); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is(nullValue())); + + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(endpoint.getServerUrl()).isEqualTo("https://bitbucket.example.com"); + assertThat(endpoint.isManageHooks()).isTrue(); + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); + assertThat(instance.getEndpoints()).element(1).satisfies(endpoint -> { + assertThat(endpoint.getDisplayName()).isEqualTo("Example Org"); + assertThat(endpoint.getServerUrl()).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(endpoint.isManageHooks()).isFalse(); + assertThat(endpoint.getCredentialsId()).isNull(); + }); } @Test - public void given__instanceWithCloud__when__addingAnotherCloud__then__onlyFirstCloudRetained() { + void given__instanceWithCloud__when__addingAnotherCloud__then__onlyFirstCloudRetained() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList(new BitbucketCloudEndpoint(true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.addEndpoint(new BitbucketCloudEndpoint(false, null)), is(false)); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); + assumeTrue("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); + + assertThat(instance.addEndpoint(new BitbucketCloudEndpoint(false, null))).isFalse(); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); } @Test - public void given__instanceWithServer__when__addingCloud__then__cloudAdded() { + void given__instanceWithServer__when__addingCloud__then__cloudAdded() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.addEndpoint(new BitbucketCloudEndpoint(true, "added")), is(true)); - assertThat(instance.getEndpoints(), - contains(instanceOf(BitbucketServerEndpoint.class), instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is("added")); + assumeTrue("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); + + assertThat(instance.addEndpoint(new BitbucketCloudEndpoint(true, "added"))).isTrue(); + assertThat(instance.getEndpoints()).hasExactlyElementsOfTypes(BitbucketServerEndpoint.class, BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); + + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); + assertThat(instance.getEndpoints()).element(1).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("added"); + }); } @Test - public void given__instanceWithServer__when__addingDifferentServer__then__serverAdded() { + void given__instanceWithServer__when__addingDifferentServer__then__serverAdded() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.addEndpoint( - new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "added")), - is(true)); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class), instanceOf( - BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is("added")); + assumeTrue("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); + + assertThat(instance.addEndpoint(new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "added"))).isTrue(); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); + assertThat(instance.getEndpoints()).element(1).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("added"); + }); } @Test - public void given__instanceWithServer__when__addingSameServer__then__onlyFirstServerRetained() { + void given__instanceWithServer__when__addingSameServer__then__onlyFirstServerRetained() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.addEndpoint( - new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", false, null)), is(false)); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); + assumeTrue("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); + + assertThat(instance.addEndpoint(new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", false, null))).isFalse(); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); } @Test - public void given__instanceWithCloud__when__updatingCloud__then__cloudUpdated() { + void given__instanceWithCloud__when__updatingCloud__then__cloudUpdated() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList(new BitbucketCloudEndpoint(true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); + assumeTrue("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); + instance.updateEndpoint(new BitbucketCloudEndpoint(false, null)); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is(nullValue())); + + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isNull(); + }); } @Test - public void given__instanceWithServer__when__updatingCloud__then__cloudAdded() { + void given__instanceWithServer__when__updatingCloud__then__cloudAdded() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); + assumeTrue("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); instance.updateEndpoint(new BitbucketCloudEndpoint(true, "added")); - assertThat(instance.getEndpoints(), - contains(instanceOf(BitbucketServerEndpoint.class), instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is("added")); + + assertThat(instance.getEndpoints()).hasExactlyElementsOfTypes(BitbucketServerEndpoint.class, BitbucketCloudEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); + assertThat(instance.getEndpoints()).element(1).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("added"); + }); } @Test - public void given__instanceWithServer__when__updatingDifferentServer__then__serverAdded() { + void given__instanceWithServer__when__updatingDifferentServer__then__serverAdded() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - instance.updateEndpoint( - new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "added")); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class), instanceOf( - BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is("added")); + assumeTrue("dummy".equals(instance.getEndpoints().get(0).getCredentialsId())); + + instance.updateEndpoint(new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "added")); + + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("dummy"); + }); + assertThat(instance.getEndpoints()).element(1).satisfies(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("added"); + }); } @Test - public void given__instanceWithServer__when__updatingSameServer__then__serverUpdated() { + void given__instanceWithServer__when__updatingSameServer__then__serverUpdated() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"))); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getDisplayName(), is("Example Inc")); - assertThat(instance.getEndpoints().get(0).getServerUrl(), is("https://bitbucket.example.com")); - assertThat(instance.getEndpoints().get(0).isManageHooks(), is(true)); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("dummy")); - instance.updateEndpoint( - new BitbucketServerEndpoint("Example, Inc.", "https://bitbucket.example.com/", false, null)); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getDisplayName(), is("Example, Inc.")); - assertThat(instance.getEndpoints().get(0).getServerUrl(), is("https://bitbucket.example.com")); - assertThat(instance.getEndpoints().get(0).isManageHooks(), is(false)); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is(nullValue())); - } - - @Test - public void given__newInstance__when__removingCloud__then__defaultRestored() { + + instance.updateEndpoint(new BitbucketServerEndpoint("Example, Inc.", "https://bitbucket.example.com/", false, null)); + + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints()).element(0).satisfies(endpoint -> { + assertThat(endpoint.getDisplayName()).isEqualTo("Example, Inc."); + assertThat(endpoint.getServerUrl()).isEqualTo("https://bitbucket.example.com"); + assertThat(endpoint.isManageHooks()).isFalse(); + assertThat(endpoint.getCredentialsId()).isNull(); + }); + } + + @Test + void given__newInstance__when__removingCloud__then__defaultRestored() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assumeThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is(nullValue())); - assertThat(instance.removeEndpoint(new BitbucketCloudEndpoint(true, "dummy")), is(true)); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketCloudEndpoint.class))); + assertThat(instance.getEndpoints().get(0).getCredentialsId()).isNull(); + assertThat(instance.removeEndpoint(new BitbucketCloudEndpoint(true, "dummy"))).isTrue(); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketCloudEndpoint.class); } @Test - public void given__instanceWithCloudAndServers__when__removingServer__then__matchingServerRemoved() { + void given__instanceWithCloudAndServers__when__removingServer__then__matchingServerRemoved() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -339,22 +367,18 @@ public void given__instanceWithCloudAndServers__when__removingServer__then__matc new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "second"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); - assumeThat(instance.getEndpoints(), - contains(instanceOf(BitbucketCloudEndpoint.class), instanceOf(BitbucketServerEndpoint.class), - instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); - assumeThat(instance.getEndpoints().get(1).getCredentialsId(), is("second")); - assumeThat(instance.getEndpoints().get(2).getCredentialsId(), is("third")); - assertThat(instance.removeEndpoint( - new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", false, null)), is(true)); - assertThat(instance.getEndpoints(), - contains(instanceOf(BitbucketCloudEndpoint.class), instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is("third")); - } - - @Test - public void given__instanceWithCloudAndServers__when__removingCloud__then__cloudRemoved() { + assumeTrue("first".equals(instance.getEndpoints().get(0).getCredentialsId())); + assumeTrue("second".equals(instance.getEndpoints().get(1).getCredentialsId())); + assumeTrue("third".equals(instance.getEndpoints().get(2).getCredentialsId())); + + assertThat(instance.removeEndpoint(new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", false, null))).isTrue(); + assertThat(instance.getEndpoints()).hasExactlyElementsOfTypes(BitbucketCloudEndpoint.class, BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints().get(0).getCredentialsId()).isEqualTo("first"); + assertThat(instance.getEndpoints().get(1).getCredentialsId()).isEqualTo("third"); + } + + @Test + void given__instanceWithCloudAndServers__when__removingCloud__then__cloudRemoved() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -362,22 +386,18 @@ public void given__instanceWithCloudAndServers__when__removingCloud__then__cloud new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "second"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); - assumeThat(instance.getEndpoints(), - contains(instanceOf(BitbucketCloudEndpoint.class), instanceOf(BitbucketServerEndpoint.class), - instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); - assumeThat(instance.getEndpoints().get(1).getCredentialsId(), is("second")); - assumeThat(instance.getEndpoints().get(2).getCredentialsId(), is("third")); - assertThat(instance.removeEndpoint( - new BitbucketCloudEndpoint(false, null)), is(true)); - assertThat(instance.getEndpoints(), - contains(instanceOf(BitbucketServerEndpoint.class), instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("second")); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is("third")); - } - - @Test - public void given__instanceWithCloudAndServers__when__removingNonExisting__then__noChange() { + assumeTrue("first".equals(instance.getEndpoints().get(0).getCredentialsId())); + assumeTrue("second".equals(instance.getEndpoints().get(1).getCredentialsId())); + assumeTrue("third".equals(instance.getEndpoints().get(2).getCredentialsId())); + + assertThat(instance.removeEndpoint(new BitbucketCloudEndpoint(false, null))).isTrue(); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints().get(0).getCredentialsId()).isEqualTo("second"); + assertThat(instance.getEndpoints().get(1).getCredentialsId()).isEqualTo("third"); + } + + @Test + void given__instanceWithCloudAndServers__when__removingNonExisting__then__noChange() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -385,34 +405,29 @@ public void given__instanceWithCloudAndServers__when__removingNonExisting__then_ new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "second"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); - assumeThat(instance.getEndpoints(), - contains(instanceOf(BitbucketCloudEndpoint.class), instanceOf(BitbucketServerEndpoint.class), - instanceOf(BitbucketServerEndpoint.class))); - assumeThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); - assumeThat(instance.getEndpoints().get(1).getCredentialsId(), is("second")); - assumeThat(instance.getEndpoints().get(2).getCredentialsId(), is("third")); - assertThat(instance.removeEndpoint( - new BitbucketServerEndpoint("Test", "http://bitbucket.test", true, "fourth")), is(false)); - assertThat(instance.getEndpoints(), - contains(instanceOf(BitbucketCloudEndpoint.class), instanceOf(BitbucketServerEndpoint.class), - instanceOf(BitbucketServerEndpoint.class))); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is("first")); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is("second")); - assertThat(instance.getEndpoints().get(2).getCredentialsId(), is("third")); - } - - @Test - public void given__instance__when__onlyOneEndpoint__then__endpointsNotSelectable() { + assumeTrue("first".equals(instance.getEndpoints().get(0).getCredentialsId())); + assumeTrue("second".equals(instance.getEndpoints().get(1).getCredentialsId())); + assumeTrue("third".equals(instance.getEndpoints().get(2).getCredentialsId())); + + assertThat(instance.removeEndpoint(new BitbucketServerEndpoint("Test", "http://bitbucket.test", true, "fourth"))).isFalse(); + assertThat(instance.getEndpoints()).hasExactlyElementsOfTypes(BitbucketCloudEndpoint.class, BitbucketServerEndpoint.class, BitbucketServerEndpoint.class); + assertThat(instance.getEndpoints().get(0).getCredentialsId()).isEqualTo("first"); + assertThat(instance.getEndpoints().get(1).getCredentialsId()).isEqualTo("second"); + assertThat(instance.getEndpoints().get(2).getCredentialsId()).isEqualTo("third"); + } + + @Test + void given__instance__when__onlyOneEndpoint__then__endpointsNotSelectable() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Collections.singletonList( new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "dummy") )); - assertThat(instance.isEndpointSelectable(), is(false)); + assertThat(instance.isEndpointSelectable()).isFalse(); } @Test - public void given__instance__when__multipleEndpoints__then__endpointsSelectable() { + void given__instance__when__multipleEndpoints__then__endpointsSelectable() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -420,11 +435,11 @@ public void given__instance__when__multipleEndpoints__then__endpointsSelectable( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "second"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); - assertThat(instance.isEndpointSelectable(), is(true)); + assertThat(instance.isEndpointSelectable()).isTrue(); } @Test - public void given__instanceWithCloudAndServers__when__findingExistingEndpoint__then__endpointFound() { + void given__instanceWithCloudAndServers__when__findingExistingEndpoint__then__endpointFound() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -432,47 +447,51 @@ public void given__instanceWithCloudAndServers__when__findingExistingEndpoint__t new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "second"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); - AbstractBitbucketEndpoint ep = instance.findEndpoint(BitbucketCloudEndpoint.SERVER_URL); - assertThat(ep, notNullValue()); - assertThat(ep.getCredentialsId(), is("first")); + Optional ep = instance.findEndpoint(BitbucketCloudEndpoint.SERVER_URL); + assertThat(ep).isPresent() + .hasValueSatisfying(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("first"); + }); ep = instance.findEndpoint("https://bitbucket.example.com/"); - assertThat(ep, notNullValue()); - assertThat(ep.getCredentialsId(), is("second")); - - ep = instance.findEndpoint("https://bitbucket.example.com"); - assertThat(ep, notNullValue()); - assertThat(ep.getCredentialsId(), is("second")); + assertThat(ep).isPresent() + .hasValueSatisfying(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("second"); + }); ep = instance.findEndpoint("https://BITBUCKET.EXAMPLE.COM:443/"); - assertThat(ep, notNullValue()); - assertThat(ep.getCredentialsId(), is("second")); + assertThat(ep).isPresent() + .hasValueSatisfying(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("second"); + }); ep = instance.findEndpoint("http://example.org:8080/bitbucket/../bitbucket/"); - assertThat(ep, notNullValue()); - assertThat(ep.getCredentialsId(), is("third")); + assertThat(ep).isPresent() + .hasValueSatisfying(endpoint -> { + assertThat(endpoint.getCredentialsId()).isEqualTo("third"); + }); } @Test - public void given__instanceWithServers__when__findingNonExistingEndpoint__then__endpointNotFound() { + void given__instanceWithServers__when__findingNonExistingEndpoint__then__endpointNotFound() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "dummy"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "dummy") )); - assertThat(instance.findEndpoint(BitbucketCloudEndpoint.SERVER_URL), nullValue()); - assertThat(instance.findEndpoint("http://bitbucket.example.com/"), nullValue()); - assertThat(instance.findEndpoint("http://bitbucket.example.com:80/"), nullValue()); - assertThat(instance.findEndpoint("http://bitbucket.example.com:443"), nullValue()); - assertThat(instance.findEndpoint("https://BITBUCKET.EXAMPLE.COM:443/bitbucket/"), nullValue()); - assertThat(instance.findEndpoint("http://example.org/bitbucket/../bitbucket/"), nullValue()); - assertThat(instance.findEndpoint("bitbucket.org"), nullValue()); - assertThat(instance.findEndpoint("bitbucket.example.com"), nullValue()); + assertThat(instance.findEndpoint(BitbucketCloudEndpoint.SERVER_URL)).isEmpty(); + assertThat(instance.findEndpoint("http://bitbucket.example.com/")).isEmpty(); + assertThat(instance.findEndpoint("http://bitbucket.example.com:80/")).isEmpty(); + assertThat(instance.findEndpoint("http://bitbucket.example.com:443")).isEmpty(); + assertThat(instance.findEndpoint("https://BITBUCKET.EXAMPLE.COM:443/bitbucket/")).isEmpty(); + assertThat(instance.findEndpoint("http://example.org/bitbucket/../bitbucket/")).isEmpty(); + assertThat(instance.findEndpoint("bitbucket.org")).isEmpty(); + assertThat(instance.findEndpoint("bitbucket.example.com")).isEmpty(); } @Test - public void given__instanceWithCloudAndServers__when__findingInvalid__then__endpointNotFound() { + void given__instanceWithCloudAndServers__when__findingInvalid__then__endpointNotFound() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -480,13 +499,13 @@ public void given__instanceWithCloudAndServers__when__findingInvalid__then__endp new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "second"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); - assertThat(instance.findEndpoint("0schemes-start-with+digits:no leading slash"), nullValue()); - assertThat(instance.findEndpoint("http://host name with spaces:443"), nullValue()); - assertThat(instance.findEndpoint("http://invalid.port.test:65536/bitbucket/"), nullValue()); + assertThat(instance.findEndpoint("0schemes-start-with+digits:no leading slash")).isEmpty(); + assertThat(instance.findEndpoint("http://host name with spaces:443")).isEmpty(); + assertThat(instance.findEndpoint("http://invalid.port.test:65536/bitbucket/")).isEmpty(); } @Test - public void given__instanceWithCloudAndServers__when__populatingDropBox__then__endpointsListed() { + void given__instanceWithCloudAndServers__when__populatingDropBox__then__endpointsListed() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -495,18 +514,17 @@ public void given__instanceWithCloudAndServers__when__populatingDropBox__then__e new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); ListBoxModel items = instance.getEndpointItems(); - assertThat(items, hasSize(3)); - assertThat(items.get(0).name, is(Messages.BitbucketCloudEndpoint_displayName() + " (" - + BitbucketCloudEndpoint.SERVER_URL + ")")); - assertThat(items.get(0).value, is(BitbucketCloudEndpoint.SERVER_URL)); - assertThat(items.get(1).name, is("Example Inc (https://bitbucket.example.com)")); - assertThat(items.get(1).value, is("https://bitbucket.example.com")); - assertThat(items.get(2).name, is("Example Org (http://example.org:8080/bitbucket)")); - assertThat(items.get(2).value, is("http://example.org:8080/bitbucket")); + assertThat(items).hasSize(3); + assertThat(items.get(0).name).isEqualTo(Messages.BitbucketCloudEndpoint_displayName() + " (" + BitbucketCloudEndpoint.SERVER_URL + ")"); + assertThat(items.get(0).value).isEqualTo(BitbucketCloudEndpoint.SERVER_URL); + assertThat(items.get(1).name).isEqualTo("Example Inc (https://bitbucket.example.com)"); + assertThat(items.get(1).value).isEqualTo("https://bitbucket.example.com"); + assertThat(items.get(2).name).isEqualTo("Example Org (http://example.org:8080/bitbucket)"); + assertThat(items.get(2).value).isEqualTo("http://example.org:8080/bitbucket"); } @Test - public void given__instanceWithCloudAndServers__when__resolvingExistingEndpoint__then__normalizedReturned() { + void given__instanceWithCloudAndServers__when__resolvingExistingEndpoint__then__normalizedReturned() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints( Arrays.asList( @@ -514,109 +532,98 @@ public void given__instanceWithCloudAndServers__when__resolvingExistingEndpoint_ new BitbucketServerEndpoint("Example Inc", "https://bitbucket.example.com/", true, "second"), new BitbucketServerEndpoint("Example Org", "http://example.org:8080/bitbucket/", true, "third") )); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl(null), is(BitbucketCloudEndpoint.SERVER_URL)); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl(""), is(BitbucketCloudEndpoint.SERVER_URL)); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl("https://bitbucket.EXAMPLE.COM:443/"), - is("https://bitbucket.example.com")); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl("https://bitbucket.example.com"), - is("https://bitbucket.example.com")); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/"), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/foo/../"), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/foo/../bitbucket/."), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(3)); - } - - @Test - public void - given__instanceWithCloudAndServers__when__resolvingNewEndpointAsSystem__then__addedAndNormalizedReturned() { - BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - instance.setEndpoints(Collections.singletonList( - new BitbucketServerEndpoint("existing", "https://bitbucket.test", false, null))); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl(null), is(BitbucketCloudEndpoint.SERVER_URL)); - assertThat(instance.getEndpointItems(), hasSize(2)); - assertThat(instance.readResolveServerUrl(""), is(BitbucketCloudEndpoint.SERVER_URL)); - assertThat(instance.getEndpointItems(), hasSize(2)); - assertThat(instance.readResolveServerUrl("https://bitbucket.EXAMPLE.COM:443/"), - is("https://bitbucket.example.com")); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl("https://bitbucket.example.com"), - is("https://bitbucket.example.com")); - assertThat(instance.getEndpointItems(), hasSize(3)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/"), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(4)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/foo/../"), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(4)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/foo/../bitbucket/."), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(4)); - assertThat(instance.getEndpoints().get(0).getDisplayName(), is("existing")); - assertThat(instance.getEndpoints().get(0).getServerUrl(), is("https://bitbucket.test")); - assertThat(instance.getEndpoints().get(0).isManageHooks(), is(false)); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is(nullValue())); - assertThat(instance.getEndpoints().get(1).getDisplayName(), is(Messages.BitbucketCloudEndpoint_displayName())); - assertThat(instance.getEndpoints().get(1).getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getEndpoints().get(1).isManageHooks(), is(false)); - assertThat(instance.getEndpoints().get(1).getCredentialsId(), is(nullValue())); - assertThat(instance.getEndpoints().get(2).getDisplayName(), is("example")); - assertThat(instance.getEndpoints().get(2).getServerUrl(), is("https://bitbucket.example.com")); - assertThat(instance.getEndpoints().get(2).isManageHooks(), is(false)); - assertThat(instance.getEndpoints().get(2).getCredentialsId(), is(nullValue())); - assertThat(instance.getEndpoints().get(3).getDisplayName(), is("example")); - assertThat(instance.getEndpoints().get(3).getServerUrl(), is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpoints().get(3).isManageHooks(), is(false)); - assertThat(instance.getEndpoints().get(3).getCredentialsId(), is(nullValue())); - } - - @Test - public void - given__instanceWithCloudAndServers__when__resolvingNewEndpointAsAnon__then__normalizedReturnedNotAdded() { + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl(null)).isEqualTo(BitbucketCloudEndpoint.SERVER_URL); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("")).isEqualTo(BitbucketCloudEndpoint.SERVER_URL); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("https://bitbucket.EXAMPLE.COM:443/")).isEqualTo("https://bitbucket.example.com"); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("https://bitbucket.example.com")).isEqualTo("https://bitbucket.example.com"); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/foo/../")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("http://example.org:8080/foo/../bitbucket/.")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(3); + } + + @Test + void given__instanceWithCloudAndServers__when__resolvingNewEndpointAsSystem__then__addedAndNormalizedReturned() { + Authentication prevAuth = SecurityContextHolder.getContext().getAuthentication(); + try { + SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM2); + + BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); + instance.setEndpoints(Collections.singletonList( + new BitbucketServerEndpoint("existing", "https://bitbucket.test", false, null))); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl(null)).isEqualTo(BitbucketCloudEndpoint.SERVER_URL); + assertThat(instance.getEndpointItems()).hasSize(2); + assertThat(instance.readResolveServerUrl("")).isEqualTo(BitbucketCloudEndpoint.SERVER_URL); + assertThat(instance.getEndpointItems()).hasSize(2); + assertThat(instance.readResolveServerUrl("https://bitbucket.EXAMPLE.COM:443/")).isEqualTo("https://bitbucket.example.com"); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("https://bitbucket.example.com")).isEqualTo("https://bitbucket.example.com"); + assertThat(instance.getEndpointItems()).hasSize(3); + assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(4); + assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/foo/../")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(4); + assertThat(instance.readResolveServerUrl("http://example.org:8080/foo/../bitbucket/.")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(4); + assertThat(instance.getEndpoints().get(0).getDisplayName()).isEqualTo("existing"); + assertThat(instance.getEndpoints().get(0).getServerUrl()).isEqualTo("https://bitbucket.test"); + assertThat(instance.getEndpoints().get(0).isManageHooks()).isFalse(); + assertThat(instance.getEndpoints().get(0).getCredentialsId()).isNull(); + assertThat(instance.getEndpoints().get(1).getDisplayName()).isEqualTo(Messages.BitbucketCloudEndpoint_displayName()); + assertThat(instance.getEndpoints().get(1).getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getEndpoints().get(1).isManageHooks()).isFalse(); + assertThat(instance.getEndpoints().get(1).getCredentialsId()).isNull(); + assertThat(instance.getEndpoints().get(2).getDisplayName()).isEqualTo("example"); + assertThat(instance.getEndpoints().get(2).getServerUrl()).isEqualTo("https://bitbucket.example.com"); + assertThat(instance.getEndpoints().get(2).isManageHooks()).isFalse(); + assertThat(instance.getEndpoints().get(2).getCredentialsId()).isNull(); + assertThat(instance.getEndpoints().get(3).getDisplayName()).isEqualTo("example"); + assertThat(instance.getEndpoints().get(3).getServerUrl()).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpoints().get(3).isManageHooks()).isFalse(); + assertThat(instance.getEndpoints().get(3).getCredentialsId()).isNull(); + } finally { + SecurityContextHolder.getContext().setAuthentication(prevAuth); + } + } + + @Test + void given__instanceWithCloudAndServers__when__resolvingNewEndpointAsAnon__then__normalizedReturnedNotAdded() { BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); instance.setEndpoints(Collections.singletonList( new BitbucketServerEndpoint("existing", "https://bitbucket.test", false, null))); try (ACLContext context = ACL.as(Jenkins.ANONYMOUS)) { - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl(null), is(BitbucketCloudEndpoint.SERVER_URL)); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl(""), is(BitbucketCloudEndpoint.SERVER_URL)); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl("https://bitbucket.EXAMPLE.COM:443/"), - is("https://bitbucket.example.com")); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl("https://bitbucket.example.com"), - is("https://bitbucket.example.com")); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/"), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/foo/../"), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.readResolveServerUrl("http://example.org:8080/foo/../bitbucket/."), - is("http://example.org:8080/bitbucket")); - assertThat(instance.getEndpointItems(), hasSize(1)); - assertThat(instance.getEndpoints().get(0).getDisplayName(), - is("existing")); - assertThat(instance.getEndpoints().get(0).getServerUrl(), is("https://bitbucket.test")); - assertThat(instance.getEndpoints().get(0).isManageHooks(), is(false)); - assertThat(instance.getEndpoints().get(0).getCredentialsId(), is(nullValue())); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl(null)).isEqualTo(BitbucketCloudEndpoint.SERVER_URL); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl("")).isEqualTo(BitbucketCloudEndpoint.SERVER_URL); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl("https://bitbucket.EXAMPLE.COM:443/")).isEqualTo("https://bitbucket.example.com"); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl("https://bitbucket.example.com")).isEqualTo("https://bitbucket.example.com"); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl("http://example.org:8080/bitbucket/foo/../")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.readResolveServerUrl("http://example.org:8080/foo/../bitbucket/.")).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(instance.getEndpointItems()).hasSize(1); + assertThat(instance.getEndpoints().get(0).getDisplayName()).isEqualTo("existing"); + assertThat(instance.getEndpoints().get(0).getServerUrl()).isEqualTo("https://bitbucket.test"); + assertThat(instance.getEndpoints().get(0).isManageHooks()).isFalse(); + assertThat(instance.getEndpoints().get(0).getCredentialsId()).isNull(); } } @Test - public void given__instanceWithConfig__when__configRoundtrip__then__configRetained() throws Exception { + void given__instanceWithConfig__when__configRoundtrip__then__configRetained() throws Exception { BitbucketEndpointConfiguration instance = BitbucketEndpointConfiguration.get(); instance.setEndpoints( Arrays.asList( @@ -634,169 +641,169 @@ public void given__instanceWithConfig__when__configRoundtrip__then__configRetain CredentialsScope.SYSTEM, "third", null, "user3", "pass3") ))); - j.configRoundtrip(); + r.configRoundtrip(); - assertThat(instance.getEndpoints(), hasSize(3)); + assertThat(instance.getEndpoints()).hasSize(3); BitbucketCloudEndpoint endpoint1 = (BitbucketCloudEndpoint) instance.getEndpoints().get(0); - assertThat(endpoint1.getDisplayName(), is(Messages.BitbucketCloudEndpoint_displayName())); - assertThat(endpoint1.getServerUrl(), is("https://bitbucket.org")); - assertThat(endpoint1.isManageHooks(), is(true)); - assertThat(endpoint1.getCredentialsId(), is("first")); + assertThat(endpoint1.getDisplayName()).isEqualTo(Messages.BitbucketCloudEndpoint_displayName()); + assertThat(endpoint1.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(endpoint1.isManageHooks()).isTrue(); + assertThat(endpoint1.getCredentialsId()).isEqualTo("first"); BitbucketServerEndpoint endpoint2 = (BitbucketServerEndpoint) instance.getEndpoints().get(1); - assertThat(endpoint2.getDisplayName(), is("Example Inc")); - assertThat(endpoint2.getServerUrl(), is("https://bitbucket.example.com")); - assertThat(endpoint2.isManageHooks(), is(true)); - assertThat(endpoint2.getCredentialsId(), is("second")); + assertThat(endpoint2.getDisplayName()).isEqualTo("Example Inc"); + assertThat(endpoint2.getServerUrl()).isEqualTo("https://bitbucket.example.com"); + assertThat(endpoint2.isManageHooks()).isTrue(); + assertThat(endpoint2.getCredentialsId()).isEqualTo("second"); BitbucketServerEndpoint endpoint3 = (BitbucketServerEndpoint) instance.getEndpoints().get(2); - assertThat(endpoint3.getDisplayName(), is("Example Org")); - assertThat(endpoint3.getServerUrl(), is("http://example.org:8080/bitbucket")); - assertThat(endpoint3.isManageHooks(), is(false)); - assertThat(endpoint3.getCredentialsId(), is(nullValue())); + assertThat(endpoint3.getDisplayName()).isEqualTo("Example Org"); + assertThat(endpoint3.getServerUrl()).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(endpoint3.isManageHooks()).isFalse(); + assertThat(endpoint3.getCredentialsId()).isNull(); } @Test - public void given__serverConfig__without__webhookImplementation__then__usePlugin() throws Exception { + void given__serverConfig__without__webhookImplementation__then__usePlugin() throws Exception { final URL configWithoutWebhookImpl = Resources.getResource(getClass(), "config-without-webhook-impl.xml"); final File configFile = new File(Jenkins.get().getRootDir(), BitbucketEndpointConfiguration.class.getName() + ".xml"); FileUtils.copyURLToFile(configWithoutWebhookImpl, configFile); final BitbucketEndpointConfiguration instance = new BitbucketEndpointConfiguration(); - assertThat(instance.getEndpoints(), contains(instanceOf(BitbucketServerEndpoint.class))); + assertThat(instance.getEndpoints()).hasOnlyElementsOfType(BitbucketServerEndpoint.class); final BitbucketServerEndpoint endpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(0); - assertThat(endpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); + assertThat(endpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); } @Test - public void should_support_configuration_as_code() throws Exception { + void should_support_configuration_as_code() throws Exception { ConfigurationAsCode.get().configure(getClass().getResource(getClass().getSimpleName() + "/configuration-as-code.yml").toString()); BitbucketEndpointConfiguration instance = BitbucketEndpointConfiguration.get(); - assertThat(instance.getEndpoints(), hasSize(12)); + assertThat(instance.getEndpoints()).hasSize(12); BitbucketCloudEndpoint endpoint1 = (BitbucketCloudEndpoint) instance.getEndpoints().get(0); - assertThat(endpoint1.getDisplayName(), is(Messages.BitbucketCloudEndpoint_displayName())); - assertThat(endpoint1.getServerUrl(), is("https://bitbucket.org")); - assertThat(endpoint1.isManageHooks(), is(true)); - assertThat(endpoint1.getCredentialsId(), is("first")); - assertThat(endpoint1.isEnableCache(), is(true)); - assertThat(endpoint1.getTeamCacheDuration(), is(1)); - assertThat(endpoint1.getRepositoriesCacheDuration(), is(2)); + assertThat(endpoint1.getDisplayName()).isEqualTo(Messages.BitbucketCloudEndpoint_displayName()); + assertThat(endpoint1.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(endpoint1.isManageHooks()).isTrue(); + assertThat(endpoint1.getCredentialsId()).isEqualTo("first"); + assertThat(endpoint1.isEnableCache()).isTrue(); + assertThat(endpoint1.getTeamCacheDuration()).isEqualTo(1); + assertThat(endpoint1.getRepositoriesCacheDuration()).isEqualTo(2); BitbucketServerEndpoint serverEndpoint; serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(1); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("https://bitbucket.example.com")); - assertThat(serverEndpoint.isManageHooks(), is(true)); - assertThat(serverEndpoint.getCredentialsId(), is("second")); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_7)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("https://bitbucket.example.com"); + assertThat(serverEndpoint.isManageHooks()).isTrue(); + assertThat(serverEndpoint.getCredentialsId()).isEqualTo("second"); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_7); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(2); - assertThat(serverEndpoint.getDisplayName(), is("Example Org")); - assertThat(serverEndpoint.getServerUrl(), is("http://example.org:8080/bitbucket")); - assertThat(serverEndpoint.isManageHooks(), is(false)); - assertThat(serverEndpoint.getCredentialsId(), is(nullValue())); - assertThat(serverEndpoint.isCallCanMerge(), is(true)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_7)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Org"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://example.org:8080/bitbucket"); + assertThat(serverEndpoint.isManageHooks()).isFalse(); + assertThat(serverEndpoint.getCredentialsId()).isNull(); + assertThat(serverEndpoint.isCallCanMerge()).isTrue(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_7); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(3); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8083")); - assertThat(serverEndpoint.isManageHooks(), is(true)); - assertThat(serverEndpoint.getCredentialsId(), is("third")); - assertThat(serverEndpoint.isCallCanMerge(), is(true)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.NATIVE)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_7)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8083"); + assertThat(serverEndpoint.isManageHooks()).isTrue(); + assertThat(serverEndpoint.getCredentialsId()).isEqualTo("third"); + assertThat(serverEndpoint.isCallCanMerge()).isTrue(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.NATIVE); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_7); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(4); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8084")); - assertThat(serverEndpoint.isManageHooks(), is(true)); - assertThat(serverEndpoint.getCredentialsId(), is("fourth")); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(false)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_7)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8084"); + assertThat(serverEndpoint.isManageHooks()).isTrue(); + assertThat(serverEndpoint.getCredentialsId()).isEqualTo("fourth"); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isFalse(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_7); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(5); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8085")); - assertThat(serverEndpoint.isManageHooks(), is(true)); - assertThat(serverEndpoint.getCredentialsId(), is("fifth")); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_7)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8085"); + assertThat(serverEndpoint.isManageHooks()).isTrue(); + assertThat(serverEndpoint.getCredentialsId()).isEqualTo("fifth"); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_7); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(6); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8086")); - assertThat(serverEndpoint.isManageHooks(), is(false)); - assertThat(serverEndpoint.getCredentialsId(), is(nullValue())); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(false)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_7)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8086"); + assertThat(serverEndpoint.isManageHooks()).isFalse(); + assertThat(serverEndpoint.getCredentialsId()).isNull(); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isFalse(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_7); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(7); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8087")); - assertThat(serverEndpoint.isManageHooks(), is(false)); - assertThat(serverEndpoint.getCredentialsId(), is(nullValue())); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(false)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_7)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8087"); + assertThat(serverEndpoint.isManageHooks()).isFalse(); + assertThat(serverEndpoint.getCredentialsId()).isNull(); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isFalse(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_7); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(8); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8088")); - assertThat(serverEndpoint.isManageHooks(), is(false)); - assertThat(serverEndpoint.getCredentialsId(), is(nullValue())); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_6_5)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8088"); + assertThat(serverEndpoint.isManageHooks()).isFalse(); + assertThat(serverEndpoint.getCredentialsId()).isNull(); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_6_5); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(9); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8089")); - assertThat(serverEndpoint.isManageHooks(), is(false)); - assertThat(serverEndpoint.getCredentialsId(), is(nullValue())); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_6)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8089"); + assertThat(serverEndpoint.isManageHooks()).isFalse(); + assertThat(serverEndpoint.getCredentialsId()).isNull(); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_6); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(10); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8090")); - assertThat(serverEndpoint.isManageHooks(), is(false)); - assertThat(serverEndpoint.getCredentialsId(), is(nullValue())); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_5_10)); + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8090"); + assertThat(serverEndpoint.isManageHooks()).isFalse(); + assertThat(serverEndpoint.getCredentialsId()).isNull(); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_5_10); serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(11); - assertThat(serverEndpoint.getDisplayName(), is("Example Inc")); - assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8091")); - assertThat(serverEndpoint.isManageHooks(), is(false)); - assertThat(serverEndpoint.getCredentialsId(), is(nullValue())); - assertThat(serverEndpoint.isCallCanMerge(), is(false)); - assertThat(serverEndpoint.isCallChanges(), is(true)); - assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN)); - assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_5)); - + assertThat(serverEndpoint.getDisplayName()).isEqualTo("Example Inc"); + assertThat(serverEndpoint.getServerUrl()).isEqualTo("http://bitbucket.example.com:8091"); + assertThat(serverEndpoint.isManageHooks()).isFalse(); + assertThat(serverEndpoint.getCredentialsId()).isNull(); + assertThat(serverEndpoint.isCallCanMerge()).isFalse(); + assertThat(serverEndpoint.isCallChanges()).isTrue(); + assertThat(serverEndpoint.getWebhookImplementation()).isEqualTo(BitbucketServerWebhookImplementation.PLUGIN); + assertThat(serverEndpoint.getServerVersion()).isEqualTo(BitbucketServerVersion.VERSION_5); } + }