diff --git a/src/main/groovy/com/wooga/spock/extensions/github/GithubRepositoryExtension.groovy b/src/main/groovy/com/wooga/spock/extensions/github/GithubRepositoryExtension.groovy index 6457cf6..ffd3cb0 100644 --- a/src/main/groovy/com/wooga/spock/extensions/github/GithubRepositoryExtension.groovy +++ b/src/main/groovy/com/wooga/spock/extensions/github/GithubRepositoryExtension.groovy @@ -17,7 +17,7 @@ package com.wooga.spock.extensions.github - +import com.wooga.spock.extensions.github.interceptor.FieldInterceptor import com.wooga.spock.extensions.github.interceptor.GithubRepositoryFeatureInterceptor import com.wooga.spock.extensions.github.interceptor.GithubRepositoryInterceptor import com.wooga.spock.extensions.github.interceptor.SharedGithubRepositoryInterceptor @@ -27,23 +27,18 @@ import org.spockframework.runtime.model.FieldInfo class GithubRepositoryExtension extends AbstractAnnotationDrivenExtension { + @Override void visitFeatureAnnotation(GithubRepository annotation, FeatureInfo feature) { - def interceptor - - interceptor = new GithubRepositoryFeatureInterceptor(annotation) + def interceptor = GithubRepositoryFeatureInterceptor.withMetadata(annotation) interceptor.install(feature) } @Override void visitFieldAnnotation(GithubRepository annotation, FieldInfo field) { - def interceptor - - if (field.isShared()) { - interceptor = new SharedGithubRepositoryInterceptor(annotation) - } else { - interceptor = new GithubRepositoryInterceptor(annotation) - } + FieldInterceptor interceptor = field.isShared()? + SharedGithubRepositoryInterceptor.withMetadata(annotation, field) : + GithubRepositoryInterceptor.withMetadata(annotation, field) interceptor.install(field) } diff --git a/src/main/groovy/com/wooga/spock/extensions/github/Repository.groovy b/src/main/groovy/com/wooga/spock/extensions/github/Repository.groovy index 7605144..9eca52a 100644 --- a/src/main/groovy/com/wooga/spock/extensions/github/Repository.groovy +++ b/src/main/groovy/com/wooga/spock/extensions/github/Repository.groovy @@ -32,6 +32,7 @@ class Repository { private interface GHRepositoryDelegateExcludes { String getDefaultBranch() + void delete() } @Delegate(excludeTypes = [GHRepositoryDelegateExcludes.class]) @@ -61,9 +62,9 @@ class Repository { boolean exists() { try { - client.getRepository(fullName) + client.getRepositoryById(repository.id) return true - } catch (ignored) { + } catch (FileNotFoundException) { return false } } @@ -129,6 +130,23 @@ class Repository { findTag(tagName).orElse(null) } + void delete(int retries=3) { + try { + if(this.exists()) { + repository.delete() + } + } catch (FileNotFoundException _) { + } catch (Exception e) { + if(retries > 0) { + sleep(500) + delete(retries-1) + } else { + throw e + } + } + + } + Optional findTag(String tagName) { //there is no other way at the moment to load a GHTag Optional.ofNullable(listTags().find { it.name == tagName } as GHTag) @@ -235,6 +253,8 @@ class Repository { } } + + private static void tryToDelete(GHRef ref) { try { ref.delete() diff --git a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryManagingInterceptor.groovy b/src/main/groovy/com/wooga/spock/extensions/github/RepositoryFactory.groovy similarity index 52% rename from src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryManagingInterceptor.groovy rename to src/main/groovy/com/wooga/spock/extensions/github/RepositoryFactory.groovy index 176c06d..b29ecd2 100644 --- a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryManagingInterceptor.groovy +++ b/src/main/groovy/com/wooga/spock/extensions/github/RepositoryFactory.groovy @@ -1,159 +1,142 @@ -/* - * Copyright 2019 Wooga GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.wooga.spock.extensions.github.interceptor - -import com.wooga.spock.extensions.github.GithubRepository -import com.wooga.spock.extensions.github.Repository -import com.wooga.spock.extensions.github.api.RepositoryPostFix -import groovy.transform.InheritConstructors -import org.kohsuke.github.GHRepository -import org.kohsuke.github.GitHub -import org.kohsuke.github.GitHubBuilder -import org.spockframework.runtime.extension.AbstractMethodInterceptor -import org.spockframework.runtime.extension.IMethodInvocation -import org.spockframework.runtime.model.NodeInfo - -@InheritConstructors -abstract class GithubRepositoryManagingInterceptor extends AbstractMethodInterceptor { - - protected final GithubRepository metadata - - private GitHub client - private String repositoryName - private String repositoryOwner - private String token - private T info - - T getInfo() { - this.info - } - - GithubRepositoryManagingInterceptor(GithubRepository metadata) { - super() - this.metadata = metadata - } - - void install(T info) { - this.info = info - } - - void maybeDelete(String repoName) { - try { - def repository = getClient().getRepository(repoName) - repository.delete() - } - catch (Exception e) { - } - } - - String getRepositoryBaseName() { - info.name.replaceAll(/\s|\[|\]|\(|\)|\{|\}/, '-') - } - - String getRepositoryName() { - if (!repositoryName) { - - String prefix = metadata.repositoryNamePrefix() - List postFixProvider = metadata.repositoryPostFixProvider().collect { - it.getDeclaredConstructor().newInstance() - } as List - - String postfix = postFixProvider.inject("") { String postFix, provider -> - String post = provider.postFix - if (post && !post.empty) { - postFix += "-${provider.postFix}" - } - postFix - } - - repositoryName = "${getRepositoryBaseName()}${postfix}" - - if(prefix) { - repositoryName = "${prefix}-${repositoryName}" - } - } - - repositoryName - } - - String getRepositoryFullName() { - "${getRepositoryOwner()}/${getRepositoryName()}" - } - - String getRepositoryOwner() { - if (!repositoryOwner) { - repositoryOwner = System.getenv(metadata.usernameEnv()) - } - - repositoryOwner - } - - String getToken() { - if (!token) { - token = System.getenv(metadata.tokenEnv()) - } - - token - } - - GitHub getClient() { - if (!client) { - def builder = new GitHubBuilder() - client = builder.withOAuthToken(System.getenv()[metadata.tokenEnv()]) - .withEndpoint(metadata.endpoint()) - .withRateLimitHandler(metadata.rateLimitHandler().getDeclaredConstructor().newInstance()) - .build() - } - - client - } - - Repository setupRepository(IMethodInvocation invocation) { - maybeDelete(getRepositoryFullName()) - - //create github repo - def builder = getClient().createRepository(getRepositoryName()) - builder.description(metadata.repositoryDescription()) - builder.autoInit(metadata.autoInit()) - - if (metadata.autoInit()) { - builder.licenseTemplate(metadata.licenseTemplate()) - if (metadata.gitignoreTemplate()) { - builder.gitignoreTemplate(metadata.gitignoreTemplate()) - } - } - - builder.private_(metadata.createPrivateRepository()) - builder.issues(metadata.setupIssues()) - builder.wiki(metadata.setupWiki()) - builder.allowSquashMerge(metadata.allowSquashMerge()) - builder.allowRebaseMerge(metadata.allowRebaseMerge()) - builder.allowMergeCommit(metadata.allowMergeCommit()) - builder.downloads(metadata.enableDownloads()) - - - GHRepository repository = builder.create() - new Repository(repository, getClient(), getRepositoryOwner(), getToken()) - } - - abstract void destroyRepository(IMethodInvocation invocation) - - abstract void resetRepository(IMethodInvocation invocation) - - abstract void captureResetRef(IMethodInvocation invocation) +/* + * Copyright 2019 Wooga GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.wooga.spock.extensions.github + + +import com.wooga.spock.extensions.github.api.RepositoryPostFix +import groovy.transform.InheritConstructors +import org.kohsuke.github.GHRepository +import org.kohsuke.github.GitHub +import org.kohsuke.github.GitHubBuilder +import org.spockframework.runtime.model.NodeInfo + +@InheritConstructors +class RepositoryFactory { + + protected final GithubRepository metadata + + private GitHub client + private String repositoryOwner + private String token + + static String getRepositoryBaseName(NodeInfo info) { + info.name.replaceAll(/\s|\[|\]|\(|\)|\{|\}/, '-') + } + + RepositoryFactory(GithubRepository metadata) { + this.metadata = metadata + } + + Repository setupRepository(String repositoryBaseName) { + def repositoryName = createRepositoryName(repositoryBaseName) + deleteRepoIfExists(getRepositoryFullName(repositoryName)) + + //create github repo + def builder = getClient().createRepository(repositoryName) + builder.description(metadata.repositoryDescription()) + builder.autoInit(metadata.autoInit()) + + if (metadata.autoInit()) { + builder.licenseTemplate(metadata.licenseTemplate()) + if (metadata.gitignoreTemplate()) { + builder.gitignoreTemplate(metadata.gitignoreTemplate()) + } + } + + builder.private_(metadata.createPrivateRepository()) + builder.issues(metadata.setupIssues()) + builder.wiki(metadata.setupWiki()) + builder.allowSquashMerge(metadata.allowSquashMerge()) + builder.allowRebaseMerge(metadata.allowRebaseMerge()) + builder.allowMergeCommit(metadata.allowMergeCommit()) + builder.downloads(metadata.enableDownloads()) + + + GHRepository repository = builder.create() + new Repository(repository, getClient(), getRepositoryOwner(), getToken()) + } + + protected void deleteRepoIfExists(String repoName) { + try { + def repository = getClient().getRepository(repoName) + repository?.delete() + } + catch (FileNotFoundException e) { + } + } + + protected String createRepositoryName(String repositoryBaseName) { + String prefix = metadata.repositoryNamePrefix() + List postFixProvider = metadata.repositoryPostFixProvider().collect { + it.getDeclaredConstructor().newInstance() + } as List + + String postfix = postFixProvider.inject("") { String postFix, provider -> + String post = provider.postFix + if (post && !post.empty) { + postFix += "-${provider.postFix}" + } + return postFix + } + + def repositoryName = "${repositoryBaseName}${postfix}" + if(prefix) { + repositoryName = "${prefix}-${repositoryName}" + } + return repositoryName + } + + protected String getRepositoryFullName(String repositoryName) { + return "${getRepositoryOwner()}/${repositoryName}" + } + + protected String getRepositoryOwner() { + if (!repositoryOwner) { + repositoryOwner = getClient().myself.login + } + repositoryOwner + } + + protected String getToken() { + if (!token) { + token = mustGetEnvVar(metadata.tokenEnv()) + } + token + } + + protected GitHub getClient() { + if (!client) { + def builder = new GitHubBuilder() + client = builder.withOAuthToken(getToken()) + .withEndpoint(metadata.endpoint()) + .withRateLimitHandler(metadata.rateLimitHandler().getDeclaredConstructor().newInstance()) + .build() + } + return client + } + + private static String mustGetEnvVar(String envVar){ + def value = System.getenv(envVar) + if (!value) { + throw new IllegalArgumentException("Couldn't find environment variable ${envVar}") + } + return value + } + + } \ No newline at end of file diff --git a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/FieldInterceptor.groovy b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/FieldInterceptor.groovy new file mode 100644 index 0000000..0372a54 --- /dev/null +++ b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/FieldInterceptor.groovy @@ -0,0 +1,7 @@ +package com.wooga.spock.extensions.github.interceptor + +import org.spockframework.runtime.model.FieldInfo + +interface FieldInterceptor { + void install(FieldInfo info) +} diff --git a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryFeatureInterceptor.groovy b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryFeatureInterceptor.groovy index 01b77c6..670d6bb 100644 --- a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryFeatureInterceptor.groovy +++ b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryFeatureInterceptor.groovy @@ -19,23 +19,29 @@ package com.wooga.spock.extensions.github.interceptor import com.wooga.spock.extensions.github.GithubRepository import com.wooga.spock.extensions.github.Repository +import com.wooga.spock.extensions.github.RepositoryFactory import groovy.transform.InheritConstructors +import org.spockframework.runtime.extension.AbstractMethodInterceptor import org.spockframework.runtime.extension.IMethodInvocation import org.spockframework.runtime.model.FeatureInfo import java.lang.reflect.Parameter @InheritConstructors -class GithubRepositoryFeatureInterceptor extends GithubRepositoryManagingInterceptor { +class GithubRepositoryFeatureInterceptor extends AbstractMethodInterceptor { - GithubRepositoryFeatureInterceptor(GithubRepository metadata) { - super(metadata) - } + private RepositoryFactory factory + private GithubRepository metadata + Repository repo; - Repository repo + static GithubRepositoryFeatureInterceptor withMetadata(GithubRepository metadata) { + def repoFactory = new RepositoryFactory(metadata) + return new GithubRepositoryFeatureInterceptor(metadata, repoFactory) + } - boolean getResetAfterTestCase() { - this.metadata.resetAfterTestCase() + GithubRepositoryFeatureInterceptor(GithubRepository metadata, RepositoryFactory factory) { + this.metadata = metadata + this.factory = factory } private static void injectRepository(IMethodInvocation invocation, Repository repo) { @@ -78,8 +84,8 @@ class GithubRepositoryFeatureInterceptor extends GithubRepositoryManagingInterce invocation.proceed() } finally { - if (resetAfterTestCase) { - resetRepository(invocation) + if (metadata.resetAfterTestCase()) { + repo.resetRepository() } } } @@ -87,8 +93,7 @@ class GithubRepositoryFeatureInterceptor extends GithubRepositoryManagingInterce @Override void interceptSetupMethod(IMethodInvocation invocation) throws Throwable { invocation.proceed() - setupRepository(invocation) - + setupRepository(invocation.feature) invocation.spec.setupInterceptors.remove(this) } @@ -96,42 +101,24 @@ class GithubRepositoryFeatureInterceptor extends GithubRepositoryManagingInterce @Override void interceptFeatureExecution(IMethodInvocation invocation) throws Throwable { invocation.spec.addSetupInterceptor(this) - try { invocation.proceed() } finally { - destroyRepository(invocation) + repo.delete() } } - @Override void install(FeatureInfo info) { - super.install(info) info.addInterceptor(this) info.addIterationInterceptor(this) info.featureMethod.addInterceptor(this) } - @Override - Repository setupRepository(IMethodInvocation invocation) { - repo = super.setupRepository(invocation) - captureResetRef(invocation) - repo - } - - @Override - void destroyRepository(IMethodInvocation invocation) { - repo.delete() - } - - @Override - void resetRepository(IMethodInvocation invocation) { - repo.resetRepository() - } - - @Override - void captureResetRef(IMethodInvocation invocation) { + Repository setupRepository(FeatureInfo info) { + def repoBaseName = RepositoryFactory.getRepositoryBaseName(info) + this.repo = factory.setupRepository(repoBaseName) repo.captureResetRefs() + return repo } -} \ No newline at end of file +} diff --git a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryInterceptor.groovy b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryInterceptor.groovy index f6dbb4b..a2ba0cd 100644 --- a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryInterceptor.groovy +++ b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryInterceptor.groovy @@ -17,18 +17,31 @@ package com.wooga.spock.extensions.github.interceptor - +import com.wooga.spock.extensions.github.GithubRepository +import com.wooga.spock.extensions.github.RepositoryFactory import groovy.transform.InheritConstructors +import org.spockframework.runtime.extension.AbstractMethodInterceptor import org.spockframework.runtime.extension.IMethodInvocation import org.spockframework.runtime.model.FieldInfo -import org.spockframework.runtime.model.SpecInfo @InheritConstructors -class GithubRepositoryInterceptor extends GithubRepositoryFieldInterceptor { +class GithubRepositoryInterceptor extends AbstractMethodInterceptor implements FieldInterceptor { + + private RepositoryFieldOperations ops; + + static GithubRepositoryInterceptor withMetadata(GithubRepository metadata, FieldInfo field) { + def repoFactory = new RepositoryFactory(metadata) + def repoOps = new RepositoryFieldOperations(field, repoFactory) + return new GithubRepositoryInterceptor(repoOps) + } + + GithubRepositoryInterceptor(RepositoryFieldOperations ops) { + this.ops = ops + } @Override void interceptSetupMethod(IMethodInvocation invocation) { - setupRepository(invocation) + ops.setupRepository(invocation) invocation.proceed() } @@ -37,14 +50,12 @@ class GithubRepositoryInterceptor extends GithubRepositoryFieldInterceptor { try { invocation.proceed() } finally { - destroyRepository(invocation) + ops.destroyRepository(invocation) } } @Override void install(FieldInfo info) { - super.install(info) - final spec = info.parent.getTopSpec() spec.setupInterceptors.add(this) spec.cleanupInterceptors.add(this) diff --git a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryFieldInterceptor.groovy b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/RepositoryFieldOperations.groovy similarity index 79% rename from src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryFieldInterceptor.groovy rename to src/main/groovy/com/wooga/spock/extensions/github/interceptor/RepositoryFieldOperations.groovy index c61cc85..fdad634 100644 --- a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/GithubRepositoryFieldInterceptor.groovy +++ b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/RepositoryFieldOperations.groovy @@ -19,46 +19,52 @@ package com.wooga.spock.extensions.github.interceptor import com.wooga.spock.extensions.github.Repository +import com.wooga.spock.extensions.github.RepositoryFactory import groovy.transform.InheritConstructors import org.spockframework.runtime.extension.IMethodInvocation import org.spockframework.runtime.model.FieldInfo import spock.lang.Specification @InheritConstructors -abstract class GithubRepositoryFieldInterceptor extends GithubRepositoryManagingInterceptor { +class RepositoryFieldOperations { + + RepositoryFactory repoFactory + FieldInfo info + + RepositoryFieldOperations(FieldInfo info, RepositoryFactory repoFactory) { + this.info = info + this.repoFactory = repoFactory + } - @Override Repository setupRepository(IMethodInvocation invocation) { - def repo = super.setupRepository(invocation) + def repoBaseName = RepositoryFactory.getRepositoryBaseName(info) + def repo = repoFactory.setupRepository(repoBaseName) def spec = getSpec(invocation) info.writeValue(spec, repo) - repo + return repo } - @Override void destroyRepository(IMethodInvocation invocation) { Repository repository = getRepository(invocation) - repository.repository.delete() + repository.delete() } - @Override void resetRepository(IMethodInvocation invocation) { Repository repository = getRepository(invocation) repository.resetRepository() } - @Override void captureResetRef(IMethodInvocation invocation) { Repository repository = getRepository(invocation) repository.captureResetRefs() } - protected Specification getSpec(IMethodInvocation invocation) { - ((info.shared) ? invocation.sharedInstance : invocation.instance) as Specification - } - protected Repository getRepository(IMethodInvocation invocation) { final specInstance = getSpec(invocation) info.readValue(specInstance) as Repository } + + protected Specification getSpec(IMethodInvocation invocation) { + ((info.shared) ? invocation.sharedInstance : invocation.instance) as Specification + } } diff --git a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/SharedGithubRepositoryInterceptor.groovy b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/SharedGithubRepositoryInterceptor.groovy index 05eec40..98a2456 100644 --- a/src/main/groovy/com/wooga/spock/extensions/github/interceptor/SharedGithubRepositoryInterceptor.groovy +++ b/src/main/groovy/com/wooga/spock/extensions/github/interceptor/SharedGithubRepositoryInterceptor.groovy @@ -17,24 +17,35 @@ package com.wooga.spock.extensions.github.interceptor - +import com.wooga.spock.extensions.github.GithubRepository +import com.wooga.spock.extensions.github.RepositoryFactory import groovy.transform.InheritConstructors +import org.spockframework.runtime.extension.AbstractMethodInterceptor import org.spockframework.runtime.extension.IMethodInvocation import org.spockframework.runtime.model.FieldInfo -import org.spockframework.runtime.model.SpecInfo @InheritConstructors -class SharedGithubRepositoryInterceptor extends GithubRepositoryFieldInterceptor { +class SharedGithubRepositoryInterceptor extends AbstractMethodInterceptor implements FieldInterceptor { + + GithubRepository metadata; + RepositoryFieldOperations ops; - boolean getResetAfterTestCase() { - this.metadata.resetAfterTestCase() + static SharedGithubRepositoryInterceptor withMetadata(GithubRepository metadata, FieldInfo field) { + def repoFactory = new RepositoryFactory(metadata) + def repoOps = new RepositoryFieldOperations(field, repoFactory) + return new SharedGithubRepositoryInterceptor(metadata, repoOps) + } + + SharedGithubRepositoryInterceptor(GithubRepository metadata, RepositoryFieldOperations ops) { + this.metadata = metadata + this.ops = ops } @Override void interceptSetupSpecMethod(IMethodInvocation invocation) { - setupRepository(invocation) + ops.setupRepository(invocation) invocation.proceed() - captureResetRef(invocation) + ops.captureResetRef(invocation) } @Override @@ -42,7 +53,7 @@ class SharedGithubRepositoryInterceptor extends GithubRepositoryFieldInterceptor try { invocation.proceed() } finally { - destroyRepository(invocation) + ops.destroyRepository(invocation) } } @@ -51,19 +62,17 @@ class SharedGithubRepositoryInterceptor extends GithubRepositoryFieldInterceptor try { invocation.proceed() } finally { - resetRepository(invocation) + ops.resetRepository(invocation) } } @Override void install(FieldInfo info) { - super.install(info) - final spec = info.getParent().getTopSpec() spec.setupSpecInterceptors.add(this) spec.cleanupSpecInterceptors.add(this) - if (resetAfterTestCase) { + if (metadata.resetAfterTestCase()) { spec.cleanupInterceptors.add(this) } } diff --git a/src/test/groovy/com/wooga/spock/extensions/github/GithubRepositorySpec.groovy b/src/test/groovy/com/wooga/spock/extensions/github/GithubRepositorySpec.groovy index 221d434..97d24e5 100644 --- a/src/test/groovy/com/wooga/spock/extensions/github/GithubRepositorySpec.groovy +++ b/src/test/groovy/com/wooga/spock/extensions/github/GithubRepositorySpec.groovy @@ -51,4 +51,5 @@ class GithubRepositorySpec extends BaseGithubRepositorySpec { expect: testRepository != null } + } diff --git a/src/test/groovy/com/wooga/spock/extensions/github/RepositoryFactorySpec.groovy b/src/test/groovy/com/wooga/spock/extensions/github/RepositoryFactorySpec.groovy new file mode 100644 index 0000000..9a62cdd --- /dev/null +++ b/src/test/groovy/com/wooga/spock/extensions/github/RepositoryFactorySpec.groovy @@ -0,0 +1,71 @@ +package com.wooga.spock.extensions.github + +import spock.lang.Specification + +import java.lang.reflect.InvocationHandler +import java.lang.reflect.Method +import java.lang.reflect.Proxy + +class RepositoryFactorySpec extends Specification{ + + def "creates new repository"() { + given: "some repository metadata" + def baseName = "basereponame" + def defaultMetadata = proxyDefaultMetadata(usernameEnv: "ATLAS_GITHUB_INTEGRATION_USER", + tokenEnv: "ATLAS_GITHUB_INTEGRATION_PASSWORD") + + when: "creating new repo with same name as existing repository" + def newRepo = new RepositoryFactory(defaultMetadata).setupRepository(baseName) + + then: "repository is created successfully" + newRepo.exists() + + cleanup: + tryToDelete(newRepo) + } + + + def "deletes existing repository when creating new repository with existing name"() { + given: "some repository metadata" + def baseName = "basereponame" + def defaultMetadata = proxyDefaultMetadata(usernameEnv: "ATLAS_GITHUB_INTEGRATION_USER", + tokenEnv: "ATLAS_GITHUB_INTEGRATION_PASSWORD") + and: "a existing repository" + def existingRepo = new RepositoryFactory(defaultMetadata).setupRepository(baseName) + + when: "creating new repo with same name as existing repository" + def newRepo = new RepositoryFactory(defaultMetadata).setupRepository(baseName) + + then: "repository is created successfully" + newRepo.exists() + and: "previous existing repository is deleted" + !existingRepo.exists() + + cleanup: + tryToDelete(existingRepo) + tryToDelete(newRepo) + } + + boolean tryToDelete(Repository repo) { + try { + repo?.delete() + return true + } catch(FileNotFoundException) { + return false + } + } + + GithubRepository proxyDefaultMetadata(Map overrides = new HashMap<>()) { + Class[] proxyInterface = [GithubRepository.class] + GithubRepository repo = Proxy.newProxyInstance(getClass().classLoader, proxyInterface, new InvocationHandler() { + @Override + Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if(overrides.containsKey(method.name)) { + return overrides[method.name] + } + return method.defaultValue + } + }) as GithubRepository + return repo + } +}