From 6a215c8bf095b8c94d4fa571b19e3b5846dd2451 Mon Sep 17 00:00:00 2001 From: Nikolas Falco Date: Tue, 26 Nov 2024 19:45:31 +0100 Subject: [PATCH] Fix null credentialsId passed to GitSCM when authentication is username/password or the StandardUsernameCredential provided by the BitbucketAuthenticator is null. (#924) --- pom.xml | 6 + .../plugins/bitbucket/BitbucketSCMSource.java | 109 +- ...itbucketUsernamePasswordAuthenticator.java | 13 - .../bitbucket/BitbucketSCMSourceTest.java | 1038 +++++++---------- 4 files changed, 519 insertions(+), 647 deletions(-) diff --git a/pom.xml b/pom.xml index 476932d79..cb4287063 100644 --- a/pom.xml +++ b/pom.xml @@ -121,6 +121,12 @@ mockito-core test + + org.assertj + assertj-core + 3.26.3 + test + org.jenkins-ci.plugins git 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 02ccbad4c..4d8c19d14 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java @@ -48,6 +48,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; import com.cloudbees.plugins.credentials.CredentialsNameProvider; import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials; import com.damnhandy.uri.template.UriTemplate; import com.fasterxml.jackson.databind.util.StdDateFormat; import edu.umd.cs.findbugs.annotations.CheckForNull; @@ -66,6 +67,7 @@ import hudson.model.Items; import hudson.model.TaskListener; import hudson.plugins.git.GitSCM; +import hudson.plugins.git.extensions.GitSCMExtension; import hudson.scm.SCM; import hudson.security.AccessControlled; import hudson.util.FormFillFailure; @@ -377,6 +379,7 @@ public String getEndpointJenkinsRootUrl() { return AbstractBitbucketEndpoint.getEndpointJenkinsRootUrl(serverUrl); } + @Override @NonNull public List getTraits() { return Collections.unmodifiableList(traits); @@ -397,11 +400,11 @@ public void setBitbucketServerUrl(String url) { if (endpoint != null) { // we have a match setServerUrl(endpoint.getServerUrl()); - return; + } else { + LOGGER.log(Level.WARNING, "Call to legacy setBitbucketServerUrl({0}) method is configuring a url missing " + + "from the global configuration.", url); + setServerUrl(url); } - LOGGER.log(Level.WARNING, "Call to legacy setBitbucketServerUrl({0}) method is configuring a url missing " - + "from the global configuration.", url); - setServerUrl(url); } @Deprecated @@ -422,8 +425,8 @@ public String getBitbucketServerUrl() { @CheckForNull public String getCheckoutCredentialsId() { for (SCMSourceTrait t : traits) { - if (t instanceof SSHCheckoutTrait) { - return StringUtils.defaultString(((SSHCheckoutTrait) t).getCredentialsId(), DescriptorImpl.ANONYMOUS); + if (t instanceof SSHCheckoutTrait sshTrait) { + return StringUtils.defaultString(sshTrait.getCredentialsId(), DescriptorImpl.ANONYMOUS); } } return DescriptorImpl.SAME; @@ -446,8 +449,8 @@ public void setCheckoutCredentialsId(String checkoutCredentialsId) { @NonNull public String getIncludes() { for (SCMSourceTrait trait : traits) { - if (trait instanceof WildcardSCMHeadFilterTrait) { - return ((WildcardSCMHeadFilterTrait) trait).getIncludes(); + if (trait instanceof WildcardSCMHeadFilterTrait wildcardTrait) { + return wildcardTrait.getIncludes(); } } return "*"; @@ -588,8 +591,7 @@ protected void retrieve(@CheckForNull SCMSourceCriteria criteria, @NonNull SCMHe @Override protected Iterable create() { try { - if (event instanceof HasPullRequests) { - HasPullRequests hasPrEvent = (HasPullRequests) event; + if (event instanceof HasPullRequests hasPrEvent) { return getBitbucketPullRequestsFromEvent(hasPrEvent, listener); } @@ -1000,12 +1002,34 @@ private BitbucketCommit findPRDestinationCommit(BitbucketPullRequest pr, TaskLis public SCM build(SCMHead head, SCMRevision revision) { initCloneLinks(); - boolean sshAuth = traits.stream() - .anyMatch(SSHCheckoutTrait.class::isInstance); + String scmCredentialsId = credentialsId; BitbucketAuthenticator authenticator = authenticator(); - return new BitbucketGitSCMBuilder(this, head, revision, null) - .withExtension(new GitClientAuthenticatorExtension(authenticator == null || sshAuth ? null : authenticator.getCredentialsForSCM())) + GitSCMExtension scmExtension; + if (authenticator != null) { + // workaround to force git-plugin to use the configured username/password credentialsId as is + // remove this workaround as https://github.com/jenkinsci/bitbucket-branch-source-plugin/pull/867 will be merged + boolean sshAuth = traits.stream() + .anyMatch(SSHCheckoutTrait.class::isInstance); + if (sshAuth) { + // trait will do the magic + scmCredentialsId = null; + scmExtension = new GitClientAuthenticatorExtension(null); + } else { + StandardUsernameCredentials scmCredentials = authenticator.getCredentialsForSCM(); + // extension overrides the configured credentialsId with a custom StandardUsernameCredentials provided by the Authenticator + scmExtension = new GitClientAuthenticatorExtension(scmCredentials); + if (scmCredentials != null) { + // will be overridden by git extension + scmCredentialsId = null; + } + } + } else { + scmExtension = new GitClientAuthenticatorExtension(null); + } + + return new BitbucketGitSCMBuilder(this, head, revision, scmCredentialsId) + .withExtension(scmExtension) .withCloneLinks(primaryCloneLinks, mirrorCloneLinks) .withTraits(traits) .build(); @@ -1115,20 +1139,18 @@ protected List retrieveActions(@NonNull SCMHead head, template = UriTemplate.fromTemplate(getServerUrl() + CLOUD_REPO_TEMPLATE + "/{branchOrPR}/{prIdOrHead}") .set("owner", repoOwner) .set("repo", repository); - if (head instanceof PullRequestSCMHead) { - PullRequestSCMHead pr = (PullRequestSCMHead) head; - template.set("branchOrPR", "pull-requests").set("prIdOrHead", pr.getId()); + if (head instanceof PullRequestSCMHead prHead) { + template.set("branchOrPR", "pull-requests").set("prIdOrHead", prHead.getId()); } else { template.set("branchOrPR", "branch").set("prIdOrHead", head.getName()); } } else { - if (head instanceof PullRequestSCMHead) { - PullRequestSCMHead pr = (PullRequestSCMHead) head; + if (head instanceof PullRequestSCMHead prHead) { template = UriTemplate .fromTemplate(getServerUrl() + SERVER_REPO_TEMPLATE + "/pull-requests/{id}/overview") .set("owner", repoOwner) .set("repo", repository) - .set("id", pr.getId()); + .set("id", prHead.getId()); } else { template = UriTemplate .fromTemplate(getServerUrl() + SERVER_REPO_TEMPLATE + "/compare/commits{?sourceBranch}") @@ -1137,10 +1159,9 @@ protected List retrieveActions(@NonNull SCMHead head, .set("sourceBranch", Constants.R_HEADS + head.getName()); } } - if (head instanceof PullRequestSCMHead) { - PullRequestSCMHead pr = (PullRequestSCMHead) head; - title = getPullRequestTitleCache().get(pr.getId()); - ContributorMetadataAction contributor = getPullRequestContributorCache().get(pr.getId()); + if (head instanceof PullRequestSCMHead prHead) { + title = getPullRequestTitleCache().get(prHead.getId()); + ContributorMetadataAction contributor = getPullRequestContributorCache().get(prHead.getId()); if (contributor != null) { result.add(contributor); } @@ -1149,8 +1170,8 @@ protected List retrieveActions(@NonNull SCMHead head, result.add(new BitbucketLink("icon-bitbucket-branch", url)); result.add(new ObjectMetadataAction(title, null, url)); SCMSourceOwner owner = getOwner(); - if (owner instanceof Actionable) { - for (BitbucketDefaultBranch p : ((Actionable) owner).getActions(BitbucketDefaultBranch.class)) { + if (owner instanceof Actionable actionable) { + for (BitbucketDefaultBranch p : actionable.getActions(BitbucketDefaultBranch.class)) { if (StringUtils.equals(getRepoOwner(), p.getRepoOwner()) && StringUtils.equals(repository, p.getRepository()) && StringUtils.equals(p.getDefaultBranch(), head.getName())) { @@ -1371,8 +1392,7 @@ public ListBoxModel doFillCredentialsIdItems(@AncestorInPath SCMSourceOwner cont public ListBoxModel doFillRepositoryItems(@AncestorInPath SCMSourceOwner context, @QueryParameter String serverUrl, @QueryParameter String credentialsId, - @QueryParameter String repoOwner) - throws IOException, InterruptedException { + @QueryParameter String repoOwner) throws IOException { BitbucketSupplier listBoxModelSupplier = bitbucket -> { ListBoxModel result = new ListBoxModel(); BitbucketTeam team = bitbucket.getTeam(); @@ -1439,6 +1459,7 @@ public List> getTraitsDescrip return result; } + @Override public List getTraitsDefaults() { return Arrays.asList( new BranchDiscoveryTrait(true, false), @@ -1465,7 +1486,6 @@ public void record(@NonNull SCMHead scmHead, SCMRevision revision, boolean isMat request.listener().getLogger().println(" Met criteria"); } else { request.listener().getLogger().println(" Does not meet criteria"); - return; } } @@ -1484,8 +1504,8 @@ public BitbucketProbeFactory(BitbucketApi bitbucket, BitbucketSCMSourceRequest r @NonNull @Override public Probe create(@NonNull final SCMHead head, @CheckForNull final I revisionInfo) throws IOException, InterruptedException { - final String hash = (revisionInfo instanceof BitbucketCommit) // - ? ((BitbucketCommit) revisionInfo).getHash() // + final String hash = (revisionInfo instanceof BitbucketCommit bbRevision) // + ? bbRevision.getHash() // : (String) revisionInfo; return new SCMSourceCriteria.Probe() { @@ -1501,8 +1521,8 @@ public long lastModified() { try { BitbucketCommit commit = null; if (hash != null) { - commit = (revisionInfo instanceof BitbucketCommit) // - ? (BitbucketCommit) revisionInfo // + commit = (revisionInfo instanceof BitbucketCommit bbRevision) // + ? bbRevision // : bitbucket.resolveCommit(hash); } @@ -1559,8 +1579,7 @@ public SCMRevision create(@NonNull SCMHead head, BitbucketCommit targetCommit = asCommit(targetInput); SCMRevision revision; - if (head instanceof PullRequestSCMHead) { - PullRequestSCMHead prHead = (PullRequestSCMHead) head; + if (head instanceof PullRequestSCMHead prHead) { SCMHead targetHead = prHead.getTarget(); return new PullRequestSCMRevision( // @@ -1574,10 +1593,10 @@ public SCMRevision create(@NonNull SCMHead head, } private BitbucketCommit asCommit(I input) throws IOException, InterruptedException { - if (input instanceof String) { - return client.resolveCommit((String) input); - } else if (input instanceof BitbucketCommit) { - return (BitbucketCommit) input; + if (input instanceof String value) { + return client.resolveCommit(value); + } else if (input instanceof BitbucketCommit commit) { + return commit; } return null; } @@ -1626,14 +1645,14 @@ public WrappedException(Throwable cause) { public void unwrap() throws IOException, InterruptedException { Throwable cause = getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; + if (cause instanceof IOException ioEx) { + throw ioEx; } - if (cause instanceof InterruptedException) { - throw (InterruptedException) cause; + if (cause instanceof InterruptedException interruptedEx) { + throw interruptedEx; } - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; + if (cause instanceof RuntimeException rtEx) { + throw rtEx; } throw this; } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketUsernamePasswordAuthenticator.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketUsernamePasswordAuthenticator.java index 86d000a6c..fbdd55d1b 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketUsernamePasswordAuthenticator.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketUsernamePasswordAuthenticator.java @@ -26,11 +26,7 @@ package com.cloudbees.jenkins.plugins.bitbucket.api.credentials; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; -import com.cloudbees.plugins.credentials.CredentialsScope; -import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials; import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; -import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; -import hudson.model.Descriptor.FormException; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.http.HttpHost; @@ -79,13 +75,4 @@ public void configureContext(HttpClientContext context, HttpHost host) { context.setAuthCache(authCache); } - @Override - public StandardUsernameCredentials getCredentialsForSCM() { - try { - return new UsernamePasswordCredentialsImpl( - CredentialsScope.GLOBAL, getId(), null, httpCredentials.getUserName(), httpCredentials.getPassword()); - } catch (FormException e) { - throw new RuntimeException(e); - } - } } diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceTest.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceTest.java index 2341d5663..f9d157898 100644 --- a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceTest.java +++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceTest.java @@ -4,18 +4,21 @@ import com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest.BitbucketPullRequestCommit; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.AbstractBitbucketEndpoint; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; +import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials; import hudson.plugins.git.GitSCM; +import hudson.plugins.git.extensions.GitSCMExtension; import hudson.scm.SCM; import java.net.URL; -import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.List; import jenkins.model.Jenkins; import jenkins.model.JenkinsLocationConfiguration; import jenkins.scm.api.trait.SCMSourceTrait; import jenkins.scm.impl.trait.WildcardSCMHeadFilterTrait; -import org.hamcrest.Matchers; +import org.assertj.core.api.ThrowingConsumer; import org.jenkinsci.plugins.displayurlapi.ClassicDisplayURLProvider; +import org.jenkinsci.plugins.gitclient.GitClient; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; @@ -23,15 +26,12 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.hamcrest.MatcherAssert.assertThat; +import static org.assertj.core.api.Assertions.anyOf; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; public class BitbucketSCMSourceTest { @ClassRule @@ -39,6 +39,30 @@ public class BitbucketSCMSourceTest { @Rule public TestName currentTestName = new TestName(); + private ThrowingConsumer hasForkPRTrait = t -> assertThat(t) + .isInstanceOfSatisfying(ForkPullRequestDiscoveryTrait.class, trait -> { // + assertThat(trait.getStrategyId()).isEqualTo(2); // + assertThat(trait.getTrust()).isInstanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class); // + }); + private ThrowingConsumer hasBranchDiscoveryTrait = t -> assertThat(t) + .isInstanceOfSatisfying(BranchDiscoveryTrait.class, trait -> { // + assertThat(trait.isBuildBranch()).isTrue(); // + assertThat(trait.isBuildBranchesWithPR()).isTrue(); // + }); + private ThrowingConsumer hasOriginPRTrait = t -> assertThat(t) + .isInstanceOfSatisfying(OriginPullRequestDiscoveryTrait.class, trait -> assertThat(trait.getStrategyId()).isEqualTo(2)); + private ThrowingConsumer hasPublicRepoTrait = trait -> assertThat(trait).isInstanceOf(PublicRepoPullRequestFilterTrait.class); + private ThrowingConsumer hasWebhookDisabledTrait = t -> assertThat(t) + .isInstanceOfSatisfying(WebhookRegistrationTrait.class, trait -> assertThat(trait.getMode()).isEqualTo(WebhookRegistration.DISABLE)); + private ThrowingConsumer hasWebhookItemTrait = t -> assertThat(t) + .isInstanceOfSatisfying(WebhookRegistrationTrait.class, trait -> assertThat(trait.getMode()).isEqualTo(WebhookRegistration.ITEM)); + private ThrowingConsumer hasWebhookSystemTrait = t -> assertThat(t) + .isInstanceOfSatisfying(WebhookRegistrationTrait.class, trait -> assertThat(trait.getMode()).isEqualTo(WebhookRegistration.SYSTEM)); + private ThrowingConsumer hasSSHTrait = t -> assertThat(t) + .isInstanceOfSatisfying(SSHCheckoutTrait.class, trait -> assertThat(trait.getCredentialsId()).isEqualTo("other-credentials")); + private ThrowingConsumer hasSSHAnonymousTrait = t -> assertThat(t) + .isInstanceOfSatisfying(SSHCheckoutTrait.class, trait -> assertThat(trait.getCredentialsId()).isNull()); + private BitbucketSCMSource load() { return load(currentTestName.getMethodName()); } @@ -46,8 +70,7 @@ private BitbucketSCMSource load() { private BitbucketSCMSource load(String dataSet) { String path = getClass().getSimpleName() + "/" + dataSet + ".xml"; URL url = getClass().getResource(path); - BitbucketSCMSource bss = - (BitbucketSCMSource) Jenkins.XSTREAM2.fromXML(url); + BitbucketSCMSource bss = (BitbucketSCMSource) Jenkins.XSTREAM2.fromXML(url); return bss; } @@ -76,357 +99,209 @@ private BitbucketEndpointConfiguration loadBEC(String dataSet) { @Test public void modern() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("e4d8c11a-0d24-472f-b86b-4b017c160e9a")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("curl")); - assertThat(instance.getTraits(), is(Collections.emptyList())); + assertThat(instance.getId()).isEqualTo("e4d8c11a-0d24-472f-b86b-4b017c160e9a"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("curl"); + assertThat(instance.getTraits()).isEmpty(); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(true)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isTrue(); } @Test public void basic_cloud_git() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bitbucket-cloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bitbucket-cloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasPublicRepoTrait, // + hasWebhookDisabledTrait, // + hasForkPRTrait)); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(false)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isFalse(); } @Test public void basic_server() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.test::DUB::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.test")); - assertThat(instance.getRepoOwner(), is("DUB")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bb-beescloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket" + + ".BitbucketSCMNavigator::https://bitbucket.test::DUB::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.test"); + assertThat(instance.getRepoOwner()).isEqualTo("DUB"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bb-beescloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasPublicRepoTrait, // + hasWebhookDisabledTrait, // + hasForkPRTrait)); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is("https://bitbucket.test")); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(false)); + assertThat(instance.getBitbucketServerUrl()).isEqualTo("https://bitbucket.test"); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isFalse(); } @Test public void custom_checkout_credentials() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bitbucket-cloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ), - Matchers.allOf( - Matchers.instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is("other-credentials")) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bitbucket-cloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasPublicRepoTrait, // + hasWebhookDisabledTrait, // + hasForkPRTrait, // + hasSSHTrait)); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is("other-credentials")); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(false)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo("other-credentials"); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isFalse(); } @Issue("JENKINS-45467") @Test public void same_checkout_credentials() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bitbucket-cloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket" + + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bitbucket-cloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasPublicRepoTrait, // + hasWebhookDisabledTrait, // + hasForkPRTrait)); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(false)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isFalse(); } @Test public void exclude_branches() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bitbucket-cloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("*")), - hasProperty("excludes", is("main")) - ), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bitbucket-cloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasPublicRepoTrait, // + hasWebhookDisabledTrait, // + hasForkPRTrait, + trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcardTrait -> { + assertThat(wildcardTrait.getIncludes()).isEqualTo("*"); + assertThat(wildcardTrait.getExcludes()).isEqualTo("main"); + }))); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("main")); - assertThat(instance.isAutoRegisterHook(), is(false)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEqualTo("main"); + assertThat(instance.isAutoRegisterHook()).isFalse(); } @Test public void limit_branches() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bitbucket-cloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("")) - ), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bitbucket-cloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasPublicRepoTrait, // + hasWebhookDisabledTrait, // + hasForkPRTrait, + trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcardTrait -> { + assertThat(wildcardTrait.getIncludes()).isEqualTo("feature/*"); + assertThat(wildcardTrait.getExcludes()).isEmpty(); + }))); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(false)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isFalse(); } @Test public void register_hooks() throws Exception { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bitbucket-cloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.ITEM)) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bitbucket-cloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasForkPRTrait, + hasPublicRepoTrait, // + hasWebhookItemTrait)); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(true)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isTrue(); } @Test - public void use_agent_checkout() throws Exception { + public void use_agent_checkout() { BitbucketSCMSource instance = load(); - assertThat(instance.getId(), is("com.cloudbees.jenkins.plugins.bitbucket" - + ".BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure")); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getRepoOwner(), is("cloudbeers")); - assertThat(instance.getRepository(), is("stunning-adventure")); - assertThat(instance.getCredentialsId(), is("bitbucket-cloud")); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(true)) - ), - Matchers.allOf( - instanceOf(OriginPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)) - ), - Matchers.allOf( - instanceOf(ForkPullRequestDiscoveryTrait.class), - hasProperty("strategyId", is(2)), - hasProperty("trust", instanceOf(ForkPullRequestDiscoveryTrait.TrustEveryone.class)) - ), - Matchers.instanceOf(PublicRepoPullRequestFilterTrait.class), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ), - Matchers.allOf( - Matchers.instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is(nullValue())) - ) - ) - ); + assertThat(instance.getId()).isEqualTo("com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::stunning-adventure"); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getRepoOwner()).isEqualTo("cloudbeers"); + assertThat(instance.getRepository()).isEqualTo("stunning-adventure"); + assertThat(instance.getCredentialsId()).isEqualTo("bitbucket-cloud"); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + hasBranchDiscoveryTrait, // + hasOriginPRTrait, // + hasForkPRTrait, // + hasPublicRepoTrait, // + hasWebhookDisabledTrait, // + hasSSHAnonymousTrait)); // Legacy API - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.ANONYMOUS)); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.isAutoRegisterHook(), is(false)); + assertThat(instance.getBitbucketServerUrl()).isNull(); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.ANONYMOUS); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.isAutoRegisterHook()).isFalse(); } @Test @@ -439,503 +314,469 @@ public void test_that_clone_url_does_not_contains_username() { BitbucketSCMSource instance = new BitbucketSCMSource("amuniz", "test-repo"); BitbucketMockApiFactory.add(instance.getServerUrl(), BitbucketIntegrationClientFactory.getApiMockClient(instance.getServerUrl())); SCM scm = instance.build(head, new BitbucketGitSCMRevision(head, commit)); - assertInstanceOf(GitSCM.class, scm); + assertThat(scm).isInstanceOf(GitSCM.class); GitSCM gitSCM = (GitSCM) scm; - assertThat(gitSCM.getUserRemoteConfigs().get(0).getUrl(), is("https://bitbucket.org/amuniz/test-repos.git")); + assertThat(gitSCM.getUserRemoteConfigs()).isNotEmpty() + .element(0) + .satisfies(urc -> { + assertThat(urc.getUrl()).isEqualTo("https://bitbucket.org/amuniz/test-repos.git"); + }); } @Test public void given__instance__when__setTraits_empty__then__traitsEmpty() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setTraits(Collections.emptyList()); - assertThat(instance.getTraits(), is(Collections.emptyList())); + assertThat(instance.getTraits()).isEmpty(); } @Test public void given__instance__when__setTraits__then__traitsSet() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList(new BranchDiscoveryTrait(1), + instance.setTraits(List.of(new BranchDiscoveryTrait(1), new WebhookRegistrationTrait(WebhookRegistration.DISABLE))); - assertThat(instance.getTraits(), - containsInAnyOrder( - Matchers.allOf( - instanceOf(BranchDiscoveryTrait.class), - hasProperty("buildBranch", is(true)), - hasProperty("buildBranchesWithPR", is(false)) - ), - Matchers.allOf( - instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE)) - ) - ) - ); + assertThat(instance.getTraits()).allSatisfy(anyOf( // + trait -> assertThat(trait) + .isInstanceOfSatisfying(BranchDiscoveryTrait.class, branchTrait -> { // + assertThat(branchTrait.isBuildBranch()).isTrue(); // + assertThat(branchTrait.isBuildBranchesWithPR()).isFalse(); // + }), // + hasWebhookDisabledTrait)); } @Test public void given__instance__when__setServerUrl__then__urlNormalized() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setServerUrl("https://bitbucket.org:443/foo/../bar/../"); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); } @Test public void given__instance__when__setCredentials_empty__then__credentials_null() { BitbucketSCMSource instance = new BitbucketSCMSource( "testing", "test-repo"); instance.setCredentialsId(""); - assertThat(instance.getCredentialsId(), is(nullValue())); + assertThat(instance.getCredentialsId()).isNull(); } @Test public void given__instance__when__setCredentials_null__then__credentials_null() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setCredentialsId(""); - assertThat(instance.getCredentialsId(), is(nullValue())); + assertThat(instance.getCredentialsId()).isNull(); } @Test public void given__instance__when__setCredentials__then__credentials_set() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setCredentialsId("test"); - assertThat(instance.getCredentialsId(), is("test")); + assertThat(instance.getCredentialsId()).isEqualTo("test"); } @Test public void given__instance__when__setBitbucketServerUrl_null__then__cloudUrlApplied() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setBitbucketServerUrl(null); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getBitbucketServerUrl()).isNull(); } @Test public void given__instance__when__setBitbucketServerUrl_value__then__valueApplied() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setBitbucketServerUrl("https://bitbucket.test"); - assertThat(instance.getServerUrl(), is("https://bitbucket.test")); - assertThat(instance.getBitbucketServerUrl(), is("https://bitbucket.test")); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.test"); + assertThat(instance.getBitbucketServerUrl()).isEqualTo("https://bitbucket.test"); } @Test public void given__instance__when__setBitbucketServerUrl_value__then__valueNormalized() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setBitbucketServerUrl("https://bitbucket.test/foo/bar/../../"); - assertThat(instance.getServerUrl(), is("https://bitbucket.test")); - assertThat(instance.getBitbucketServerUrl(), is("https://bitbucket.test")); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.test"); + assertThat(instance.getBitbucketServerUrl()).isEqualTo("https://bitbucket.test"); } @Test public void given__instance__when__setBitbucketServerUrl_cloudUrl__then__valueApplied() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); instance.setBitbucketServerUrl("https://bitbucket.org"); - assertThat(instance.getServerUrl(), is("https://bitbucket.org")); - assertThat(instance.getBitbucketServerUrl(), is(nullValue())); + assertThat(instance.getServerUrl()).isEqualTo("https://bitbucket.org"); + assertThat(instance.getBitbucketServerUrl()).isNull(); } @Test public void given__legacyCode__when__setAutoRegisterHook_true__then__traitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new SSHCheckoutTrait("dummy"))); - assertThat(instance.isAutoRegisterHook(), is(true)); - assertThat(instance.getTraits(), - not(Matchers.hasItem(instanceOf(WebhookRegistrationTrait.class)))); + assertThat(instance.isAutoRegisterHook()).isEqualTo(true); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(WebhookRegistrationTrait.class); instance.setAutoRegisterHook(true); - assertThat(instance.isAutoRegisterHook(), is(true)); - assertThat(instance.getTraits(), Matchers.hasItem( - allOf(instanceOf(WebhookRegistrationTrait.class), hasProperty("mode", is(WebhookRegistration.ITEM))))); + assertThat(instance.isAutoRegisterHook()).isEqualTo(true); + assertThat(instance.getTraits()).anySatisfy(hasWebhookItemTrait); } @Test public void given__legacyCode__when__setAutoRegisterHook_changes__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList(new BranchDiscoveryTrait(true, false), + instance.setTraits(List.of(new BranchDiscoveryTrait(true, false), new SSHCheckoutTrait("dummy"))); - assertThat(instance.isAutoRegisterHook(), is(true)); - assertThat(instance.getTraits(), - not(Matchers.hasItem(instanceOf(WebhookRegistrationTrait.class)))); + assertThat(instance.isAutoRegisterHook()).isEqualTo(true); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(WebhookRegistrationTrait.class); instance.setAutoRegisterHook(false); - assertThat(instance.isAutoRegisterHook(), is(false)); - assertThat(instance.getTraits(), Matchers.hasItem( - allOf(instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.DISABLE))))); + assertThat(instance.isAutoRegisterHook()).isEqualTo(false); + assertThat(instance.getTraits()).anySatisfy(hasWebhookDisabledTrait); } @Test public void given__legacyCode__when__setAutoRegisterHook_false__then__traitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList(new BranchDiscoveryTrait(true, false), - new SSHCheckoutTrait("dummy"), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.isAutoRegisterHook(), is(true)); - assertThat(instance.getTraits(), Matchers.hasItem( - allOf(instanceOf(WebhookRegistrationTrait.class), - hasProperty("mode", is(WebhookRegistration.SYSTEM))))); + instance.setTraits(List.of(new BranchDiscoveryTrait(true, false), + new SSHCheckoutTrait("dummy"), + new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); + assertThat(instance.isAutoRegisterHook()).isEqualTo(true); + assertThat(instance.getTraits()).anySatisfy(hasWebhookSystemTrait); instance.setAutoRegisterHook(true); - assertThat(instance.isAutoRegisterHook(), is(true)); - assertThat(instance.getTraits(), Matchers.hasItem( - allOf(instanceOf(WebhookRegistrationTrait.class), hasProperty("mode", is(WebhookRegistration.ITEM))))); + assertThat(instance.isAutoRegisterHook()).isEqualTo(true); + assertThat(instance.getTraits()).anySatisfy(hasWebhookItemTrait); } @Test public void given__legacyCode__when__setCheckoutCredentials_SAME__then__noTraitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); instance.setCheckoutCredentialsId(BitbucketSCMSource.DescriptorImpl.SAME); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); } @Test public void given__legacyCode__when__setCheckoutCredentials_SAME__then__traitRemoved() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM), new SSHCheckoutTrait("value"))); - assertThat(instance.getCheckoutCredentialsId(), is("value")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is("value")) - ))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo("value"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(SSHCheckoutTrait.class, sshTrait -> assertThat(sshTrait.getCredentialsId()).isEqualTo("value"))); instance.setCheckoutCredentialsId(BitbucketSCMSource.DescriptorImpl.SAME); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); } @Test public void given__legacyCode__when__setCheckoutCredentials_null__then__noTraitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); instance.setCheckoutCredentialsId(null); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); } @Test public void given__legacyCode__when__setCheckoutCredentials_null__then__traitRemoved() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM), - new SSHCheckoutTrait("value"))); - assertThat(instance.getCheckoutCredentialsId(), is("value")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is("value")) - ))); + new SSHCheckoutTrait("other-credentials"))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo("other-credentials"); + assertThat(instance.getTraits()).anySatisfy(hasSSHTrait); instance.setCheckoutCredentialsId(null); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); } @Test public void given__legacyCode__when__setCheckoutCredentials_value__then__traitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); - instance.setCheckoutCredentialsId("value"); - assertThat(instance.getCheckoutCredentialsId(), is("value")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is("value")) - ))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); + instance.setCheckoutCredentialsId("other-credentials"); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo("other-credentials"); + assertThat(instance.getTraits()).anySatisfy(hasSSHTrait); } @Test public void given__legacyCode__when__setCheckoutCredentials_value__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM), new SSHCheckoutTrait(null))); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.ANONYMOUS)); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is(nullValue())) - ))); - instance.setCheckoutCredentialsId("value"); - assertThat(instance.getCheckoutCredentialsId(), is("value")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is("value")) - ))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.ANONYMOUS); + assertThat(instance.getTraits()).anySatisfy(hasSSHAnonymousTrait); + instance.setCheckoutCredentialsId("other-credentials"); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo("other-credentials"); + assertThat(instance.getTraits()).anySatisfy(hasSSHTrait); } @Test public void given__legacyCode__when__setCheckoutCredentials_ANONYMOUS__then__traitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.SAME)); - assertThat(instance.getTraits(), not(Matchers.hasItem(instanceOf(SSHCheckoutTrait.class)))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.SAME); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); instance.setCheckoutCredentialsId(BitbucketSCMSource.DescriptorImpl.ANONYMOUS); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.ANONYMOUS)); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is(nullValue())) - ))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.ANONYMOUS); + assertThat(instance.getTraits()).anySatisfy(hasSSHAnonymousTrait); } @Test public void given__legacyCode__when__setCheckoutCredentials_ANONYMOUS__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM), - new SSHCheckoutTrait("value"))); - assertThat(instance.getCheckoutCredentialsId(), is("value")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is("value")) - ))); + new SSHCheckoutTrait("other-credentials"))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo("other-credentials"); + assertThat(instance.getTraits()).anySatisfy(hasSSHTrait); instance.setCheckoutCredentialsId(BitbucketSCMSource.DescriptorImpl.ANONYMOUS); - assertThat(instance.getCheckoutCredentialsId(), is(BitbucketSCMSource.DescriptorImpl.ANONYMOUS)); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(SSHCheckoutTrait.class), - hasProperty("credentialsId", is(nullValue())) - ))); + assertThat(instance.getCheckoutCredentialsId()).isEqualTo(BitbucketSCMSource.DescriptorImpl.ANONYMOUS); + assertThat(instance.getTraits()).anySatisfy(hasSSHAnonymousTrait); + } @Test public void given__legacyCode_withoutExcludes__when__setIncludes_default__then__traitRemoved() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("feature/*", ""), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEmpty(); // + })); instance.setIncludes("*"); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), not(Matchers.hasItem( - instanceOf(WildcardSCMHeadFilterTrait.class) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(WildcardSCMHeadFilterTrait.class); } @Test public void given__legacyCode_withoutExcludes__when__setIncludes_value__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("feature/*", ""), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEmpty(); // + })); instance.setIncludes("bug/*"); - assertThat(instance.getIncludes(), is("bug/*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("bug/*")), - hasProperty("excludes", is("")) - ))); + assertThat(instance.getIncludes()).isEqualTo("bug/*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("bug/*"); // + assertThat(wildcarTrait.getExcludes()).isEmpty(); // + })); } @Test public void given__legacyCode_withoutTrait__when__setIncludes_value__then__traitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), not(Matchers.hasItem( - instanceOf(WildcardSCMHeadFilterTrait.class) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(WildcardSCMHeadFilterTrait.class); instance.setIncludes("feature/*"); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEqualTo(""); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEmpty(); // + })); } @Test public void given__legacyCode_withExcludes__when__setIncludes_default__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("feature/*", "feature/ignore"), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); instance.setIncludes("*"); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); } @Test public void given__legacyCode_withExcludes__when__setIncludes_value__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("feature/*", "feature/ignore"), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); + instance.setIncludes("bug/*"); - assertThat(instance.getIncludes(), is("bug/*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("bug/*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("bug/*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("bug/*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); } @Test public void given__legacyCode_withoutIncludes__when__setExcludes_default__then__traitRemoved() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("*", "feature/ignore"), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); instance.setExcludes(""); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), not(Matchers.hasItem( - instanceOf(WildcardSCMHeadFilterTrait.class) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(SSHCheckoutTrait.class); } @Test public void given__legacyCode_withoutIncludes__when__setExcludes_value__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("*", "feature/ignore"), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); + instance.setExcludes("bug/ignore"); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("bug/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("*")), - hasProperty("excludes", is("bug/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEqualTo("bug/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("bug/ignore"); // + })); } @Test public void given__legacyCode_withoutTrait__when__setExcludes_value__then__traitAdded() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), not(Matchers.hasItem( - instanceOf(WildcardSCMHeadFilterTrait.class) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).doesNotHaveAnyElementsOfTypes(WildcardSCMHeadFilterTrait.class); instance.setExcludes("feature/ignore"); - assertThat(instance.getIncludes(), is("*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); } @Test public void given__legacyCode_withIncludes__when__setExcludes_default__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("feature/*", "feature/ignore"), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); + instance.setExcludes(""); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEmpty(); // + })); } @Test public void given__legacyCode_withIncludes__when__setExcludes_value__then__traitUpdated() { BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); - instance.setTraits(Arrays.asList( + instance.setTraits(List.of( new BranchDiscoveryTrait(true, false), new WildcardSCMHeadFilterTrait("feature/*", ""), new WebhookRegistrationTrait(WebhookRegistration.SYSTEM))); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEmpty(); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEmpty(); // + })); + instance.setExcludes("feature/ignore"); - assertThat(instance.getIncludes(), is("feature/*")); - assertThat(instance.getExcludes(), is("feature/ignore")); - assertThat(instance.getTraits(), Matchers.hasItem(allOf( - instanceOf(WildcardSCMHeadFilterTrait.class), - hasProperty("includes", is("feature/*")), - hasProperty("excludes", is("feature/ignore")) - ))); + assertThat(instance.getIncludes()).isEqualTo("feature/*"); + assertThat(instance.getExcludes()).isEqualTo("feature/ignore"); + assertThat(instance.getTraits()).anySatisfy(trait -> assertThat(trait) + .isInstanceOfSatisfying(WildcardSCMHeadFilterTrait.class, wildcarTrait -> { // + assertThat(wildcarTrait.getIncludes()).isEqualTo("feature/*"); // + assertThat(wildcarTrait.getExcludes()).isEqualTo("feature/ignore"); // + })); } // NOTE: The tests below require that a BitbucketEndpointConfiguration with @@ -948,43 +789,62 @@ public void given__legacyCode_withIncludes__when__setExcludes_value__then__trait public void bitbucketJenkinsRootUrl_emptyDefaulted() throws Exception { loadBEC(); BitbucketSCMSource instance = load(); - assertThat(instance.getEndpointJenkinsRootUrl(), is(ClassicDisplayURLProvider.get().getRoot())); + assertThat(instance.getEndpointJenkinsRootUrl()).isEqualTo(ClassicDisplayURLProvider.get().getRoot()); // Verify that an empty custom URL keeps returning the // current global root URL (ending with a slash), // meaning "current value at the moment when we ask". JenkinsLocationConfiguration.get().setUrl("http://localjenkins:80"); - assertThat(instance.getEndpointJenkinsRootUrl(), is("http://localjenkins:80/")); + assertThat(instance.getEndpointJenkinsRootUrl()).isEqualTo("http://localjenkins:80/"); JenkinsLocationConfiguration.get().setUrl("https://ourjenkins.master:8443/ci"); - assertThat(instance.getEndpointJenkinsRootUrl(), is("https://ourjenkins.master:8443/ci/")); + assertThat(instance.getEndpointJenkinsRootUrl()).isEqualTo("https://ourjenkins.master:8443/ci/"); } @Test - public void bitbucketJenkinsRootUrl_goodAsIs() throws Exception { + public void bitbucketJenkinsRootUrl_goodAsIs() { loadBEC(); BitbucketSCMSource instance = load(); - assertThat(instance.getEndpointJenkinsRootUrl(), is("http://jenkins.test:8080/")); + assertThat(instance.getEndpointJenkinsRootUrl()).isEqualTo("http://jenkins.test:8080/"); } @Test - public void bitbucketJenkinsRootUrl_normalized() throws Exception { + public void bitbucketJenkinsRootUrl_normalized() { loadBEC(); BitbucketSCMSource instance = load(); - assertThat(instance.getEndpointJenkinsRootUrl(), is("https://jenkins.test/")); + assertThat(instance.getEndpointJenkinsRootUrl()).isEqualTo("https://jenkins.test/"); } @Test - public void bitbucketJenkinsRootUrl_slashed() throws Exception { + public void bitbucketJenkinsRootUrl_slashed() { loadBEC(); BitbucketSCMSource instance = load(); - assertThat(instance.getEndpointJenkinsRootUrl(), is("https://jenkins.test/jenkins/")); + assertThat(instance.getEndpointJenkinsRootUrl()).isEqualTo("https://jenkins.test/jenkins/"); } @Test - public void bitbucketJenkinsRootUrl_notslashed() throws Exception { + public void bitbucketJenkinsRootUrl_notslashed() { loadBEC(); BitbucketSCMSource instance = load(); - assertThat(instance.getEndpointJenkinsRootUrl(), is("https://jenkins.test/jenkins/")); + assertThat(instance.getEndpointJenkinsRootUrl()).isEqualTo("https://jenkins.test/jenkins/"); + } + + @Test + public void verify_built_scm_with_username_password_authenticator() throws Exception { + BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo"); + instance.setCredentialsId("other-credentials"); + BitbucketMockApiFactory.add(instance.getServerUrl(), BitbucketIntegrationClientFactory.getApiMockClient(instance.getServerUrl())); + BranchSCMHead head = new BranchSCMHead("master"); + GitSCM scm = (GitSCM) instance.build(head); + assertThat(scm.getUserRemoteConfigs()) + .hasSize(1) + .first() + .satisfies(urc -> assertThat(urc.getCredentialsId()).isEqualTo("other-credentials")); + + GitClient c = mock(GitClient.class); + for (GitSCMExtension ext : scm.getExtensions()) { + c = ext.decorate(scm, c); + } + verify(c, never()).setCredentials(any(StandardUsernameCredentials.class)); } }