From 9cfb3e76d01c277b955cc9b9fe06b8100d732819 Mon Sep 17 00:00:00 2001 From: Net Wolf UK Date: Mon, 7 Oct 2019 20:32:40 +1300 Subject: [PATCH] Support for associating WebHook templates with Projects This allows a WebHook Template to be created and associated with a project rather then just _Root. Now group admins can create templates for use with their own webhooks. This addresses issue #131 Note: WebHook Template Ids must be unique across a teamcity instance, even if the user creating the template is not aware and is not permissioned to see an existing template with that ID. - Uses templateId rather than templateName when referring to ID. - Added projectId field and getProjectId method to templates. - Added validators and permissions - Fixed up permissions for template editing in REST API - Added Templates to WebHook Project tab - Added Templates list to Webhook Project Config tab. - Added Project Name and link to Templates page. - WebHooks now resolve project specific templates when building payload. --- .../server/rest/WebHookApiUrlBuilder.java | 142 ++-- .../server/rest/data/DataProvider.java | 25 +- .../server/rest/data/TemplateFinder.java | 41 +- .../server/rest/data/TemplateValidator.java | 91 ++- .../data/WebHookTemplateConfigWrapper.java | 2 + .../WebHookTemplateItemConfigWrapper.java | 1 + .../rest/jersey/BeanContextProvider.java | 152 ++-- .../rest/jersey/DataProviderProvider.java | 124 +-- .../jersey/TemplateValidatorProvider.java | 87 +- .../server/rest/model/template/Template.java | 13 +- .../server/rest/request/TemplateRequest.java | 296 ++++--- .../server/rest/data/TemplateFinderTest.java | 15 +- .../rest/data/TemplateValidatorTest.java | 36 +- .../rest/request/CreateNewTemplateTest.java | 332 ++++---- .../rest/request/DeleteTemplateTest.java | 246 +++--- .../request/EditExistingTemplateTest.java | 587 +++++++------- .../rest/request/RelocateNewTemplateTest.java | 77 ++ .../request/ViewExistingTemplateTest.java | 765 +++++++++--------- .../WebHookAbstractSpringAwareJerseyTest.java | 16 + .../DataProviderTestContextProvider.java | 191 +++-- .../MockingBeanContextProvider.java | 176 ++-- .../jerseyprovider/ProjectIdResolverMock.java | 23 + .../TemplateValidatorTestContextProvider.java | 82 +- ...bHookApiUrlBuilderTestContextProvider.java | 95 +-- .../WebHookTemplateManagerTestProvider.java | 139 ++-- .../test/springmock/MockSecurityContext.java | 62 +- .../src/test/resources/TestSpringContext.xml | 4 + 27 files changed, 2159 insertions(+), 1661 deletions(-) create mode 100644 tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/RelocateNewTemplateTest.java create mode 100644 tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/ProjectIdResolverMock.java diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/WebHookApiUrlBuilder.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/WebHookApiUrlBuilder.java index 3ada5692..24d5737b 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/WebHookApiUrlBuilder.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/WebHookApiUrlBuilder.java @@ -1,71 +1,71 @@ -package webhook.teamcity.server.rest; - -import org.jetbrains.annotations.NotNull; - -import jetbrains.buildServer.server.rest.PathTransformer; -import jetbrains.buildServer.server.rest.util.ValueWithDefault.Value; -import webhook.teamcity.server.rest.data.WebHookTemplateItemConfigWrapper.WebHookTemplateItemRest; -import webhook.teamcity.server.rest.request.TemplateRequest; -import webhook.teamcity.server.rest.request.WebHooksRequest; -import webhook.teamcity.server.rest.util.webhook.WebHookManager; -import webhook.teamcity.settings.WebHookConfig; -import webhook.teamcity.settings.config.WebHookTemplateConfig; - -/** - * Adds the WebHooks urls into the resolver. - * @author netwolfuk - * - */ -public class WebHookApiUrlBuilder { - - private PathTransformer myPathTransformer; - - public WebHookApiUrlBuilder(@NotNull final PathTransformer pathTransformer) { - myPathTransformer = pathTransformer; - } - - public String getHref(final WebHookTemplateConfig template) { - return myPathTransformer.transform(TemplateRequest.getTemplateHref(template)); - } - - public String getHref(String projectExternalId, WebHookConfig config) { - return myPathTransformer.transform(WebHooksRequest.getWebHookHref(projectExternalId, config)); - } - - public String getTemplateDefaultItemHref(WebHookTemplateConfig WebHookTemplateConfig) { - return myPathTransformer.transform(TemplateRequest.getTemplateDefaultItemHref(WebHookTemplateConfig)); - } - - public String getTemplateItemHref(WebHookTemplateConfig WebHookTemplateConfig, WebHookTemplateItemRest webHookTemplateItem) { - return myPathTransformer.transform(TemplateRequest.getTemplateItemHref(WebHookTemplateConfig, webHookTemplateItem)); - } - - public String getDefaultTemplateTextHref(final WebHookTemplateConfig template) { - return myPathTransformer.transform(TemplateRequest.getDefaultTemplateTextHref(template)); - } - - public String getDefaultBranchTemplateTextHref(final WebHookTemplateConfig template) { - return myPathTransformer.transform(TemplateRequest.getDefaultBranchTemplateTextHref(template)); - } - - public String getTemplateItemTextHref(WebHookTemplateConfig WebHookTemplateConfig, WebHookTemplateItemRest webHookTemplateItem) { - return myPathTransformer.transform(TemplateRequest.getTemplateItemTextHref(WebHookTemplateConfig, webHookTemplateItem)); - } - - public String getTemplateItemBranchTextHref(WebHookTemplateConfig WebHookTemplateConfig, WebHookTemplateItemRest webHookTemplateItem) { - return myPathTransformer.transform(TemplateRequest.getTemplateItemBranchTextHref(WebHookTemplateConfig, webHookTemplateItem)); - } - - public String transformRelativePath(final String internalRelativePath) { - return myPathTransformer.transform(internalRelativePath); - } - - public String getWebHookTemplateStateUrl(WebHookTemplateConfig template, String state) { - return myPathTransformer.transform(TemplateRequest.getTemplateStateHref(template, state)); - } - - public String getWebHookTemplateItemStateUrl(WebHookTemplateConfig template, WebHookTemplateItemRest templateItem, String state) { - return myPathTransformer.transform(TemplateRequest.getTemplateItemStateHref(template, templateItem, state)); - } - -} +package webhook.teamcity.server.rest; + +import org.jetbrains.annotations.NotNull; + +import jetbrains.buildServer.server.rest.PathTransformer; +import jetbrains.buildServer.server.rest.util.ValueWithDefault.Value; +import webhook.teamcity.server.rest.data.WebHookTemplateItemConfigWrapper.WebHookTemplateItemRest; +import webhook.teamcity.server.rest.request.TemplateRequest; +import webhook.teamcity.server.rest.request.WebHooksRequest; +import webhook.teamcity.server.rest.util.webhook.WebHookManager; +import webhook.teamcity.settings.WebHookConfig; +import webhook.teamcity.settings.config.WebHookTemplateConfig; + +/** + * Adds the WebHooks urls into the resolver. + * @author netwolfuk + * + */ +public class WebHookApiUrlBuilder { + + private PathTransformer myPathTransformer; + + public WebHookApiUrlBuilder(@NotNull final PathTransformer pathTransformer) { + myPathTransformer = pathTransformer; + } + + public String getHref(final WebHookTemplateConfig template) { + return myPathTransformer.transform(TemplateRequest.getTemplateHref(template)); + } + + public String getHref(String projectExternalId, WebHookConfig config) { + return myPathTransformer.transform(WebHooksRequest.getWebHookHref(projectExternalId, config)); + } + + public String getTemplateDefaultItemHref(WebHookTemplateConfig WebHookTemplateConfig) { + return myPathTransformer.transform(TemplateRequest.getTemplateDefaultItemHref(WebHookTemplateConfig)); + } + + public String getTemplateItemHref(WebHookTemplateConfig WebHookTemplateConfig, WebHookTemplateItemRest webHookTemplateItem) { + return myPathTransformer.transform(TemplateRequest.getTemplateItemHref(WebHookTemplateConfig, webHookTemplateItem)); + } + + public String getDefaultTemplateTextHref(final WebHookTemplateConfig template) { + return myPathTransformer.transform(TemplateRequest.getDefaultTemplateTextHref(template)); + } + + public String getDefaultBranchTemplateTextHref(final WebHookTemplateConfig template) { + return myPathTransformer.transform(TemplateRequest.getDefaultBranchTemplateTextHref(template)); + } + + public String getTemplateItemTextHref(WebHookTemplateConfig WebHookTemplateConfig, WebHookTemplateItemRest webHookTemplateItem) { + return myPathTransformer.transform(TemplateRequest.getTemplateItemTextHref(WebHookTemplateConfig, webHookTemplateItem)); + } + + public String getTemplateItemBranchTextHref(WebHookTemplateConfig WebHookTemplateConfig, WebHookTemplateItemRest webHookTemplateItem) { + return myPathTransformer.transform(TemplateRequest.getTemplateItemBranchTextHref(WebHookTemplateConfig, webHookTemplateItem)); + } + + public String transformRelativePath(final String internalRelativePath) { + return myPathTransformer.transform(internalRelativePath); + } + + public String getWebHookTemplateStateUrl(WebHookTemplateConfig template, String state) { + return myPathTransformer.transform(TemplateRequest.getTemplateStateHref(template, state)); + } + + public String getWebHookTemplateItemStateUrl(WebHookTemplateConfig template, WebHookTemplateItemRest templateItem, String state) { + return myPathTransformer.transform(TemplateRequest.getTemplateItemStateHref(template, templateItem, state)); + } + +} diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/DataProvider.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/DataProvider.java index d8aff709..c05584e8 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/DataProvider.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/DataProvider.java @@ -9,6 +9,8 @@ import jetbrains.buildServer.server.rest.data.PermissionChecker; import jetbrains.buildServer.serverSide.ProjectManager; import jetbrains.buildServer.serverSide.SBuildServer; +import jetbrains.buildServer.serverSide.auth.SecurityContext; +import webhook.teamcity.ProjectIdResolver; import webhook.teamcity.payload.WebHookPayloadManager; import webhook.teamcity.payload.WebHookTemplateManager; import webhook.teamcity.payload.WebHookTemplateManager.TemplateState; @@ -26,6 +28,9 @@ public class DataProvider { @NotNull private final ProjectManager myProjectManager; @NotNull private final WebHookManager myWebHookManager; @NotNull private final WebHookFinder myWebHookFinder; + @NotNull private final ProjectIdResolver myProjectIdResolver; + @NotNull private final SecurityContext mySecurityContext; + public DataProvider(@NotNull final SBuildServer server, @NotNull final RootUrlHolder rootUrlHolder, @@ -35,7 +40,10 @@ public DataProvider(@NotNull final SBuildServer server, @NotNull final TemplateFinder templateFinder, @NotNull final ProjectManager projectManager, @NotNull final WebHookManager webHookManager, - @NotNull final WebHookFinder webHookFinder){ + @NotNull final WebHookFinder webHookFinder, + @NotNull final ProjectIdResolver projectIdResolver, + @NotNull final SecurityContext securityContext + ){ this.myServer = server; this.myRootUrlHolder = rootUrlHolder; @@ -46,13 +54,16 @@ public DataProvider(@NotNull final SBuildServer server, this.myProjectManager = projectManager; this.myWebHookManager = webHookManager; this.myWebHookFinder = webHookFinder; + this.myProjectIdResolver = projectIdResolver; + this.mySecurityContext = securityContext; } public List getWebHookTemplates(){ List templates = new ArrayList<>(); - for (WebHookTemplateConfig template : this.myTemplateManager.getRegisteredTemplateConfigs()){ - templates.add(new WebHookTemplateConfigWrapper(template, + for (WebHookTemplateConfig template : this.myTemplateManager.getRegisteredPermissionedTemplateConfigs()){ + templates.add(new WebHookTemplateConfigWrapper(template, + myProjectIdResolver.getExternalProjectId(template.getProjectInternalId()), this.myTemplateManager.getTemplateState(template.getId(), TemplateState.BEST), WebHookTemplateStates.build(template) ) @@ -88,4 +99,12 @@ public WebHookManager getWebHookManager() { public WebHookFinder getWebHookFinder() { return myWebHookFinder; } + + public ProjectIdResolver getProjectIdResolver() { + return myProjectIdResolver; + } + + public SecurityContext getSecurityContext() { + return mySecurityContext; + } } diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateFinder.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateFinder.java index 33a9c01d..598ada25 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateFinder.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateFinder.java @@ -6,6 +6,7 @@ import jetbrains.buildServer.server.rest.errors.BadRequestException; import jetbrains.buildServer.server.rest.errors.NotFoundException; import jetbrains.buildServer.util.StringUtil; +import webhook.teamcity.ProjectIdResolver; import webhook.teamcity.payload.WebHookTemplateManager; import webhook.teamcity.payload.WebHookTemplateManager.TemplateState; import webhook.teamcity.server.rest.data.WebHookTemplateItemConfigWrapper.WebHookTemplateItemRest; @@ -17,14 +18,21 @@ public class TemplateFinder { @NotNull private final WebHookTemplateManager myTemplateManager; + @NotNull private final ProjectIdResolver myProjectIdResolver; - public TemplateFinder(@NotNull final WebHookTemplateManager templateManager){ + + public TemplateFinder(@NotNull final WebHookTemplateManager templateManager, @NotNull final ProjectIdResolver projectIdResolver){ myTemplateManager = templateManager; + myProjectIdResolver = projectIdResolver; } public static String getLocator(final WebHookTemplateConfig template) { return Locator.createEmptyLocator().setDimension("id", template.getId()).getStringRepresentation(); } + + public static String getProjectLocator(final String projectId) { + return Locator.createEmptyLocator().setDimension("project", projectId).getStringRepresentation(); + } public static String getTemplateTextLocator(final String id){ return Locator.createEmptyLocator().setDimension("id", id).getStringRepresentation(); @@ -47,9 +55,12 @@ public WebHookTemplateConfigWrapper findTemplateById(String templateLocator) { final String singleValue = locator.getSingleValue(); template = myTemplateManager.getTemplateConfig(singleValue, TemplateState.BEST); if (template != null) { - return new WebHookTemplateConfigWrapper(template, - myTemplateManager.getTemplateState(template.getId(), TemplateState.BEST), - WebHookTemplateStates.build(template)); + return new WebHookTemplateConfigWrapper( + template, + myProjectIdResolver.getExternalProjectId(template.getProjectInternalId()), + myTemplateManager.getTemplateState(template.getId(), TemplateState.BEST), + WebHookTemplateStates.build(template) + ); } throw new NotFoundException( "No template found by id '" @@ -61,10 +72,12 @@ public WebHookTemplateConfigWrapper findTemplateById(String templateLocator) { @NotNull final TemplateState templateState = getTemplateStateDimension(locator); template = myTemplateManager.getTemplateConfig(templateId, templateState); if (template != null) { - return new WebHookTemplateConfigWrapper(template, - myTemplateManager.getTemplateState(template.getId(), templateState), - WebHookTemplateStates.build(template) - ); + return new WebHookTemplateConfigWrapper( + template, + myProjectIdResolver.getExternalProjectId(template.getProjectInternalId()), + myTemplateManager.getTemplateState(template.getId(), templateState), + WebHookTemplateStates.build(template) + ); } throw new NotFoundException( "No template found by id '" @@ -77,10 +90,12 @@ public WebHookTemplateConfigWrapper findTemplateById(String templateLocator) { template = myTemplateManager.getTemplateConfig(templateName, templateState); if (template != null) { - return new WebHookTemplateConfigWrapper(template, - myTemplateManager.getTemplateState(template.getId(), templateState), - WebHookTemplateStates.build(template) - ); + return new WebHookTemplateConfigWrapper( + template, + myProjectIdResolver.getExternalProjectId(template.getProjectInternalId()), + myTemplateManager.getTemplateState(template.getId(), templateState), + WebHookTemplateStates.build(template) + ); } throw new NotFoundException( "No template found by name '" @@ -136,7 +151,7 @@ private WebHookTemplateItemConfigWrapper buildWebHookTemplateItemConfigWrapper( templateId, null ); - return new WebHookTemplateItemConfigWrapper(defaultTemplateItem, templateConfigWrapper.getBuildStatesWithTemplate()); + return new WebHookTemplateItemConfigWrapper(templateConfigWrapper.getExternalProjectId(), defaultTemplateItem, templateConfigWrapper.getBuildStatesWithTemplate()); } else { throw new NotFoundException( "This template does not have a default template '" diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateValidator.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateValidator.java index 31ec9223..be638ed8 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateValidator.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/TemplateValidator.java @@ -2,16 +2,34 @@ import java.util.regex.Pattern; +import jetbrains.buildServer.server.rest.data.PermissionChecker; +import jetbrains.buildServer.serverSide.ProjectManager; +import jetbrains.buildServer.serverSide.SProject; +import jetbrains.buildServer.serverSide.auth.AccessDeniedException; +import jetbrains.buildServer.serverSide.auth.Permission; +import webhook.Constants; import webhook.teamcity.BuildStateEnum; +import webhook.teamcity.payload.WebHookPayloadTemplate; +import webhook.teamcity.payload.WebHookTemplateManager; import webhook.teamcity.server.rest.model.template.Template; import webhook.teamcity.server.rest.model.template.Template.TemplateItem; import webhook.teamcity.server.rest.model.template.Template.WebHookTemplateStateRest; import webhook.teamcity.server.rest.model.template.ErrorResult; -import webhook.teamcity.settings.config.WebHookTemplateConfig; public class TemplateValidator { + private static final String PROJECT_ID_KEY = "projectId"; + private final WebHookTemplateManager myTemplateManager; + private final PermissionChecker myPermissionChecker; + private final ProjectManager myProjectManager; - public ErrorResult validateNewTemplate(Template requestTemplate, ErrorResult result) { + public TemplateValidator(WebHookTemplateManager templateManager, PermissionChecker permissionChecker, + ProjectManager projectManager) { + this.myTemplateManager = templateManager; + this.myPermissionChecker = permissionChecker; + this.myProjectManager = projectManager; + } + + public ErrorResult validateNewTemplate(String projectId, Template requestTemplate, ErrorResult result) { if (requestTemplate.id == null || requestTemplate.id.trim().isEmpty()) { result.addError("id-empty", "The template id cannot be empty. It is used to identify the template and is referenced by webhook configuration"); @@ -29,6 +47,9 @@ public ErrorResult validateNewTemplate(Template requestTemplate, ErrorResult res result.addError("rank", "The template rank cannot be empty and must be between 0 and 1000."); } + validateProjectId(projectId, result); + validateTemplateIdAndProjectId(projectId, requestTemplate, result); + if (requestTemplate.defaultTemplate != null) { validateDefaultTemplateItem(requestTemplate.defaultTemplate, result); } @@ -42,19 +63,73 @@ public ErrorResult validateNewTemplate(Template requestTemplate, ErrorResult res } - public ErrorResult validateTemplate(WebHookTemplateConfig webHookTemplateConfig, Template requestTemplate, ErrorResult result) { + private ErrorResult validateProjectId(String projectId, ErrorResult result) { + if (projectId != null && !projectId.isEmpty()) { + SProject sProject = null; + try { + sProject = myProjectManager.findProjectByExternalId(projectId); + + } catch (AccessDeniedException ex) { + result.addError(PROJECT_ID_KEY, "The TeamCity project is not visible to your user"); + } + if (sProject == null) { + result.addError(PROJECT_ID_KEY, "The projectId must refer to a valid TeamCity project"); + } else { + if (! myPermissionChecker.isPermissionGranted(Permission.EDIT_PROJECT, sProject.getProjectId())) { + result.addError(PROJECT_ID_KEY, "The TeamCity project is not writable by your user"); + } + } + } else { + result.addError(PROJECT_ID_KEY, "The projectId cannot be empty"); + } + return result; + } + + private ErrorResult validateTemplateIdAndProjectId(String projectId, Template requestTemplate, ErrorResult result) { + if (!result.isErrored()) { // Skip if we already have errors. + WebHookPayloadTemplate template = myTemplateManager.getTemplate(requestTemplate.id); + if (template != null) { + SProject sProject = null; + try { + if (projectId != null ) { + sProject = myProjectManager.findProjectById(projectId); + } else { + sProject = myProjectManager.findProjectById(Constants.ROOT_PROJECT_ID); + } + result.addError("id-duplicate", "The template id is in use by another template registered to a project with id '" + sProject.getExternalId() + "'"); + } catch (AccessDeniedException ex) { + result.addError("id-duplicate", "The template id is in use by another template registered to a project that you're not permissioned to view"); + } + } + } + return result; + } + + public ErrorResult validateTemplate(WebHookTemplateConfigWrapper webHookTemplateConfigWrapper, Template requestTemplate, ErrorResult result) { - if ( ! webHookTemplateConfig.getId().equals(requestTemplate.id)) { + if ( ! webHookTemplateConfigWrapper.getTemplateConfig().getId().equals(requestTemplate.id)) { result.addError("id", "Sorry, it's not possible to change the id of an existing template. Please create a new template (or a copy) with a new id and delete this one."); } + if (requestTemplate.format != null && requestTemplate.format.trim().isEmpty()) { + result.addError("format", "The template format cannot be empty."); + } + + if (requestTemplate.rank != null && ( requestTemplate.rank < 0 || requestTemplate.rank > 1000 )) { + result.addError("rank", "The template rank cannot be empty and must be between 0 and 1000."); + } + + validateProjectId(webHookTemplateConfigWrapper.getExternalProjectId(), result); + if (requestTemplate.defaultTemplate != null) { - result.addError("defaultTemplate", "Sorry, it's not possible to update templateItems when updating a template. Please update the templateItem specifically."); + validateDefaultTemplateItem(requestTemplate.defaultTemplate, result); } - if (requestTemplate.getTemplates() != null) { - result.addError("templateItem", "Sorry, it's not possible to update templateItems when updating a template. Please update the templateItem specifically."); + if (requestTemplate.getTemplates() != null) { + for (TemplateItem templateItem : requestTemplate.getTemplates()) { + validateTemplateItem(templateItem, templateItem, result); + } } return result; @@ -76,7 +151,7 @@ public ErrorResult validateTemplateItem(TemplateItem templateItem, TemplateItem for (WebHookTemplateStateRest itemState : templateItem.getBuildStates()) { WebHookTemplateStateRest requestItemState = requestTemplateItem.findConfigForBuildState(itemState.getType()); - if (requestItemState != null && itemState.isEnabled() != requestItemState.isEnabled() && !itemState.getEditable()) { + if (requestItemState != null && itemState.isEnabled() != requestItemState.isEnabled() && !Boolean.TRUE.equals(itemState.getEditable())) { result.addError(itemState.getType(), itemState.getType() + " is not editable for this templateItem"); } } diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateConfigWrapper.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateConfigWrapper.java index 807321b6..aa394232 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateConfigWrapper.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateConfigWrapper.java @@ -10,6 +10,8 @@ public class WebHookTemplateConfigWrapper { private WebHookTemplateConfig templateConfig; + private String externalProjectId; + private WebHookTemplateManager.TemplateState status; private WebHookTemplateStates buildStatesWithTemplate; diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateItemConfigWrapper.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateItemConfigWrapper.java index c6e808ee..c6db1288 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateItemConfigWrapper.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/data/WebHookTemplateItemConfigWrapper.java @@ -13,6 +13,7 @@ @Getter @AllArgsConstructor public class WebHookTemplateItemConfigWrapper { + private String externalProjectId; private WebHookTemplateItemRest templateItem; private WebHookTemplateStates buildStatesWithTemplate; diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/BeanContextProvider.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/BeanContextProvider.java index 5024d1db..e1c9311a 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/BeanContextProvider.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/BeanContextProvider.java @@ -1,76 +1,76 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * 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 webhook.teamcity.server.rest.jersey; - -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import java.lang.reflect.Type; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.ext.Provider; - -import webhook.teamcity.server.rest.WebHookApiUrlBuilder; -import webhook.teamcity.server.rest.util.BeanContext; -import jetbrains.buildServer.ServiceLocator; -import jetbrains.buildServer.server.rest.RequestPathTransformInfo; -import jetbrains.buildServer.server.rest.jersey.SimplePathTransformer; -import jetbrains.buildServer.server.rest.util.BeanFactory; - -/** - * @author Yegor.Yarko - * Date: 15.11.2009 - */ -@Provider -@SuppressWarnings("squid:S1191") -public class BeanContextProvider implements InjectableProvider, Injectable { - private final RequestPathTransformInfo myRequestPathTransformInfo; - - // using request-specific field in singleton provider - // may lead to concurrency issue as this instance is - // created by spring not by Jersey! - @Context private HttpHeaders headers; - @Context private HttpServletRequest request; - - private final BeanFactory myFactory; - private final ServiceLocator myServiceLocator; - - public BeanContextProvider(final RequestPathTransformInfo requestPathTransformInfo, final BeanFactory factory, final ServiceLocator serviceLocator) { - myRequestPathTransformInfo = requestPathTransformInfo; - myFactory = factory; - myServiceLocator = serviceLocator; - } - - public ComponentScope getScope() { - return ComponentScope.PerRequest; - } - - public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { - if (type.equals(BeanContext.class)) { - return this; - } - return null; - } - - public BeanContext getValue() { - return new BeanContext(myFactory, myServiceLocator, new WebHookApiUrlBuilder(new SimplePathTransformer(request, headers, myRequestPathTransformInfo))); - } -} +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * 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 webhook.teamcity.server.rest.jersey; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import java.lang.reflect.Type; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.ext.Provider; + +import webhook.teamcity.server.rest.WebHookApiUrlBuilder; +import webhook.teamcity.server.rest.util.BeanContext; +import jetbrains.buildServer.ServiceLocator; +import jetbrains.buildServer.server.rest.RequestPathTransformInfo; +import jetbrains.buildServer.server.rest.jersey.SimplePathTransformer; +import jetbrains.buildServer.server.rest.util.BeanFactory; + +/** + * @author Yegor.Yarko + * Date: 15.11.2009 + */ +@Provider +@SuppressWarnings("squid:S1191") +public class BeanContextProvider implements InjectableProvider, Injectable { + private final RequestPathTransformInfo myRequestPathTransformInfo; + + // using request-specific field in singleton provider + // may lead to concurrency issue as this instance is + // created by spring not by Jersey! + @Context private HttpHeaders headers; + @Context private HttpServletRequest request; + + private final BeanFactory myFactory; + private final ServiceLocator myServiceLocator; + + public BeanContextProvider(final RequestPathTransformInfo requestPathTransformInfo, final BeanFactory factory, final ServiceLocator serviceLocator) { + myRequestPathTransformInfo = requestPathTransformInfo; + myFactory = factory; + myServiceLocator = serviceLocator; + } + + public ComponentScope getScope() { + return ComponentScope.PerRequest; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(BeanContext.class)) { + return this; + } + return null; + } + + public BeanContext getValue() { + return new BeanContext(myFactory, myServiceLocator, new WebHookApiUrlBuilder(new SimplePathTransformer(request, headers, myRequestPathTransformInfo))); + } +} diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/DataProviderProvider.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/DataProviderProvider.java index ee9ea2bb..339f7a76 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/DataProviderProvider.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/DataProviderProvider.java @@ -1,61 +1,65 @@ -package webhook.teamcity.server.rest.jersey; - -import java.lang.reflect.Type; - -import javax.ws.rs.core.Context; -import javax.ws.rs.ext.Provider; - -import org.jetbrains.annotations.NotNull; - -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import jetbrains.buildServer.RootUrlHolder; -import jetbrains.buildServer.server.rest.data.PermissionChecker; -import jetbrains.buildServer.serverSide.ProjectManager; -import jetbrains.buildServer.serverSide.SBuildServer; -import webhook.teamcity.payload.WebHookPayloadManager; -import webhook.teamcity.payload.WebHookTemplateManager; -import webhook.teamcity.server.rest.data.DataProvider; -import webhook.teamcity.server.rest.data.TemplateFinder; -import webhook.teamcity.server.rest.data.WebHookFinder; -import webhook.teamcity.server.rest.util.webhook.WebHookManager; - -@Provider -@SuppressWarnings("squid:S1191") -public class DataProviderProvider implements InjectableProvider, Injectable { - private final DataProvider dataProvider; - - public DataProviderProvider( - @NotNull final SBuildServer sBuildServer, - @NotNull final RootUrlHolder rootUrlHolder, - @NotNull final PermissionChecker permissionChecker, - @NotNull final WebHookPayloadManager payloadManager, - @NotNull final TemplateFinder templateFinder, - @NotNull final WebHookTemplateManager templateManager, - @NotNull final ProjectManager projectManager, - @NotNull final WebHookManager webHookManager, - @NotNull final WebHookFinder webHookFinder - - ) { - dataProvider = new DataProvider(sBuildServer, rootUrlHolder, permissionChecker, payloadManager, templateManager, templateFinder, projectManager, webHookManager, webHookFinder); - } - - public ComponentScope getScope() { - return ComponentScope.Singleton; - } - - public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { - if (type.equals(DataProvider.class)) { - return this; - } - return null; - } - - public DataProvider getValue() { - return dataProvider; - } - +package webhook.teamcity.server.rest.jersey; + +import java.lang.reflect.Type; + +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Provider; + +import org.jetbrains.annotations.NotNull; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import jetbrains.buildServer.RootUrlHolder; +import jetbrains.buildServer.server.rest.data.PermissionChecker; +import jetbrains.buildServer.serverSide.ProjectManager; +import jetbrains.buildServer.serverSide.SBuildServer; +import jetbrains.buildServer.serverSide.auth.SecurityContext; +import webhook.teamcity.ProjectIdResolver; +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.server.rest.data.DataProvider; +import webhook.teamcity.server.rest.data.TemplateFinder; +import webhook.teamcity.server.rest.data.WebHookFinder; +import webhook.teamcity.server.rest.util.webhook.WebHookManager; + +@Provider +@SuppressWarnings("squid:S1191") +public class DataProviderProvider implements InjectableProvider, Injectable { + private final DataProvider dataProvider; + + public DataProviderProvider( + @NotNull final SBuildServer sBuildServer, + @NotNull final RootUrlHolder rootUrlHolder, + @NotNull final PermissionChecker permissionChecker, + @NotNull final WebHookPayloadManager payloadManager, + @NotNull final TemplateFinder templateFinder, + @NotNull final WebHookTemplateManager templateManager, + @NotNull final ProjectManager projectManager, + @NotNull final WebHookManager webHookManager, + @NotNull final WebHookFinder webHookFinder, + @NotNull final ProjectIdResolver projectIdResolver, + @NotNull final SecurityContext securityContext + ) + { + dataProvider = new DataProvider(sBuildServer, rootUrlHolder, permissionChecker, payloadManager, templateManager, templateFinder, projectManager, webHookManager, webHookFinder, projectIdResolver, securityContext); + } + + public ComponentScope getScope() { + return ComponentScope.Singleton; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(DataProvider.class)) { + return this; + } + return null; + } + + public DataProvider getValue() { + return dataProvider; + } + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/TemplateValidatorProvider.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/TemplateValidatorProvider.java index a6d04658..34260a1a 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/TemplateValidatorProvider.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/jersey/TemplateValidatorProvider.java @@ -1,40 +1,49 @@ -package webhook.teamcity.server.rest.jersey; - -import java.lang.reflect.Type; - -import javax.ws.rs.core.Context; -import javax.ws.rs.ext.Provider; - -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import webhook.teamcity.server.rest.data.TemplateValidator; - -@Provider -@SuppressWarnings("squid:S1191") -public class TemplateValidatorProvider implements InjectableProvider, Injectable { - private final TemplateValidator templateValidator; - - public TemplateValidatorProvider() { - - this.templateValidator = new TemplateValidator(); - } - - public ComponentScope getScope() { - return ComponentScope.Singleton; - } - - public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { - if (type.equals(TemplateValidator.class)) { - return this; - } - return null; - } - - public TemplateValidator getValue() { - return templateValidator; - } - +package webhook.teamcity.server.rest.jersey; + +import java.lang.reflect.Type; + +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Provider; + +import org.jetbrains.annotations.NotNull; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import jetbrains.buildServer.server.rest.data.PermissionChecker; +import jetbrains.buildServer.serverSide.ProjectManager; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.server.rest.data.TemplateValidator; + +@Provider +@SuppressWarnings("squid:S1191") +public class TemplateValidatorProvider implements InjectableProvider, Injectable { + private final TemplateValidator templateValidator; + + public TemplateValidatorProvider( + @NotNull final WebHookTemplateManager templateManager, + @NotNull final PermissionChecker permissionChecker, + @NotNull final ProjectManager projectManager + ) + { + this.templateValidator = new TemplateValidator(templateManager, permissionChecker, projectManager); + } + + public ComponentScope getScope() { + return ComponentScope.Singleton; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(TemplateValidator.class)) { + return this; + } + return null; + } + + public TemplateValidator getValue() { + return templateValidator; + } + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/model/template/Template.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/model/template/Template.java index 446de465..997fce2b 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/model/template/Template.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/model/template/Template.java @@ -37,12 +37,15 @@ import webhook.teamcity.settings.config.WebHookTemplateConfig.WebHookTemplateText; @XmlRootElement(name = "template") -@XmlType(name = "template", propOrder = { "id", "description", "status", "format", "rank", "href", "webUrl", "defaultTemplate", "preferredDateFormat", "toolTip", "templates" }) +@XmlType(name = "template", propOrder = { "id", "description", "projectId", "status", "format", "rank", "href", "webUrl", "defaultTemplate", "preferredDateFormat", "toolTip", "templates" }) public class Template { @XmlAttribute @Getter public String id; + + @XmlAttribute + public String projectId; @XmlAttribute public String status; @@ -302,14 +305,18 @@ public Template(@NotNull final WebHookTemplateConfigWrapper templateWrapper, fields.isIncluded("description"), template.getTemplateDescription()); + projectId = ValueWithDefault.decideDefault( + fields.isIncluded("projectId", false, false), + templateWrapper.getExternalProjectId()); + status = ValueWithDefault.decideDefault(fields.isIncluded("status"), templateWrapper.getStatus().toString()); format = ValueWithDefault.decideDefault(fields.isIncluded("format"), template.getFormat()); - rank = ValueWithDefault.decideDefault(fields.isIncluded("rank"), - Integer.valueOf(template.getRank())); + rank = ValueWithDefault.decideDefault(fields.isIncluded("rank", false, true), + template.getRank()); preferredDateFormat = ValueWithDefault.decideDefault(fields.isIncluded("preferredDateFormat"), template.getPreferredDateTimeFormat()); diff --git a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/request/TemplateRequest.java b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/request/TemplateRequest.java index ee4a66f4..8dfd2bcd 100644 --- a/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/request/TemplateRequest.java +++ b/tcwebhooks-rest-api-legacy/src/main/java/webhook/teamcity/server/rest/request/TemplateRequest.java @@ -26,6 +26,7 @@ import com.github.difflib.patch.Patch; import jetbrains.buildServer.ServiceLocator; +import jetbrains.buildServer.server.rest.data.Locator; import jetbrains.buildServer.server.rest.data.PermissionChecker; import jetbrains.buildServer.server.rest.errors.AuthorizationFailedException; import jetbrains.buildServer.server.rest.errors.NotFoundException; @@ -33,6 +34,8 @@ import jetbrains.buildServer.server.rest.model.Fields; import jetbrains.buildServer.server.rest.model.PagerData; import jetbrains.buildServer.server.rest.util.ValueWithDefault; +import jetbrains.buildServer.serverSide.SProject; +import jetbrains.buildServer.serverSide.auth.AccessDeniedException; import jetbrains.buildServer.serverSide.auth.Permission; import webhook.teamcity.BuildStateEnum; import webhook.teamcity.ProbableJaxbJarConflictErrorException; @@ -67,19 +70,17 @@ @Path(TemplateRequest.API_TEMPLATES_URL) public class TemplateRequest { - private static final String DEFAULT_TEMPLATE = "defaultTemplate"; + private static final String UPDATE_TEMPLATE = "update Template"; +private static final String PROJECT_ID = "projectId"; +private static final String DEFAULT_TEMPLATE = "defaultTemplate"; private static final String TEMPLATE_ITEMS = "templateItems"; private static final String TEMPLATE_ITEM_CONTAINED_INVALID_DATA = "TemplateItem contained invalid data"; private static final String NO_TEMPLATE_FOUND_BY_THAT_ID = "No template found by that id"; private static final String TEMPLATE_CONTAINED_INVALID_DATA = "Template contained invalid data"; private static final String ERROR_SAVING_TEMPLATE = "There was an error saving your template. Sorry."; private static final String IT_WAS_NOT_POSSIBLE_TO_PROCESS_YOUR_REQUEST_FOR_TEMPLATE_CONTENT = "Sorry. It was not possible to process your request for template content."; - private static final Permission templateEditPermission = Permission.CHANGE_SERVER_SETTINGS; - private static final Permission[] templateReadPermissions = { - Permission.VIEW_PROJECT, - Permission.VIEW_BUILD_CONFIGURATION_SETTINGS, - Permission.EDIT_PROJECT - }; + private static final Permission PROJECT_TEMPLATE_READ_PERMISSION = Permission.VIEW_PROJECT; + private static final Permission PROJECT_TEMPLATE_EDIT_PERMISSION = Permission.EDIT_PROJECT; @Context @NotNull private DataProvider myDataProvider; @Context @NotNull private WebHookTemplateManager myTemplateManager; @@ -153,16 +154,18 @@ public Templates serveTemplates(@QueryParam("fields") String fields) { @Path("/{templateLocator}") @Produces({"application/xml", "application/json"}) public Template serveTemplate(@PathParam("templateLocator") String templateLocator, @QueryParam("fields") String fields) { - checkTemplateReadPermission(); - return new Template(myDataProvider.getTemplateFinder().findTemplateById(templateLocator), new Fields(fields), myBeanContext); + WebHookTemplateConfigWrapper wrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(wrapper.getExternalProjectId()); + return new Template(wrapper, new Fields(fields), myBeanContext); } @GET @Path("/{templateLocator}/export") @Produces({"application/json"}) public Response exportTemplate(@PathParam("templateLocator") String templateLocator, @QueryParam("fields") String fields) { - checkTemplateReadPermission(); - Template template = new Template(myDataProvider.getTemplateFinder().findTemplateById(templateLocator), new Fields(fields), myBeanContext); + WebHookTemplateConfigWrapper wrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(wrapper.getExternalProjectId()); + Template template = new Template(wrapper, new Fields(fields), myBeanContext); return Response.ok(template) .header("Content-Disposition", "attachment; filename=\"" + template.getId() + ".json\"") .build(); @@ -170,6 +173,7 @@ public Response exportTemplate(@PathParam("templateLocator") String templateLoca private Template buildAndPersistTemplate(Template newTemplate, String updateMode, WebHookTemplateConfig template) { template.setTemplateDescription(newTemplate.description); + template.setProjectInternalId(myDataProvider.getProjectIdResolver().getInternalProjectId(newTemplate.projectId)); template.setFormat(newTemplate.format); template.setRank(newTemplate.rank); @@ -199,22 +203,24 @@ private Template buildAndPersistTemplate(Template newTemplate, String updateMode myTemplateManager.registerTemplateFormatFromXmlConfig(template); if (persistAllXmlConfigTemplates(updateMode)){ - return new Template(new WebHookTemplateConfigWrapper(template, myTemplateManager.getTemplateState(newTemplate.id, TemplateState.BEST), WebHookTemplateStates.build(template)), Fields.LONG, myBeanContext); + return new Template(new WebHookTemplateConfigWrapper(template, myDataProvider.getProjectIdResolver().getExternalProjectId(template.getProjectInternalId()), myTemplateManager.getTemplateState(newTemplate.id, TemplateState.BEST), WebHookTemplateStates.build(template)), Fields.LONG, myBeanContext); } else { throw new OperationException(ERROR_SAVING_TEMPLATE); } } @POST + @Path("/{projectId}") @Consumes({"application/xml", "application/json"}) @Produces({"application/xml", "application/json"}) - public Template createNewTemplate(Template newTemplate) { + public Template createNewTemplate(@PathParam(PROJECT_ID) String externalProjectId, Template newTemplate) { String updateMode = "create Template"; - checkTemplateWritePermission(); - ErrorResult validationResult = myTemplateValidator.validateNewTemplate(newTemplate, new ErrorResult()); - if (validationResult.isErrored()) { - throw new UnprocessableEntityException(TEMPLATE_CONTAINED_INVALID_DATA, validationResult); - } + checkTemplateWritePermission(externalProjectId); + newTemplate.projectId = externalProjectId; + ErrorResult validationResult = myTemplateValidator.validateNewTemplate(externalProjectId, newTemplate, new ErrorResult()); + if (validationResult.isErrored()) { + throw new UnprocessableEntityException(TEMPLATE_CONTAINED_INVALID_DATA, validationResult); + } WebHookTemplateConfig template = new WebHookTemplateConfig(newTemplate.id, true); if (myTemplateManager.getTemplate(template.getId()) != null){ @@ -226,44 +232,78 @@ public Template createNewTemplate(Template newTemplate) { } - @PUT - @Path("/{templateLocator}") - @Consumes({"application/xml", "application/json"}) - @Produces({"application/xml", "application/json"}) + @PUT + @Path("/{templateLocator}") + @Consumes({ "application/xml", "application/json" }) + @Produces({ "application/xml", "application/json" }) public Template replaceTemplate(@PathParam("templateLocator") String templateLocator, Template newTemplate) { - final String updateMode = "replace Template"; - checkTemplateWritePermission(); - WebHookTemplateConfigWrapper templateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); - if (templateConfigWrapper.getTemplateConfig() == null){ - throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); - } - ErrorResult validationResult = myTemplateValidator.validateNewTemplate(newTemplate, new ErrorResult()); + final String updateMode = "replace Template"; + WebHookTemplateConfigWrapper templateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + + String externalProjectId = findExternalProjectId(templateLocator, newTemplate.projectId, templateConfigWrapper); + + checkTemplateWritePermission(externalProjectId); + checkTemplateWritePermission(templateConfigWrapper.getExternalProjectId()); + checkTemplateCanBeRelocated(externalProjectId, templateConfigWrapper); + + if (templateConfigWrapper.getTemplateConfig() == null) { + throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); + } + ErrorResult validationResult = myTemplateValidator.validateTemplate(templateConfigWrapper, newTemplate, new ErrorResult()); - if ( ! templateConfigWrapper.getTemplateConfig().getId().equals(newTemplate.id)) { - validationResult.addError("id", "The templateId in the template does not match the templateId in the URL."); - } + if (!templateConfigWrapper.getTemplateConfig().getId().equals(newTemplate.id)) { + validationResult.addError("id", "The templateId in the template does not match the templateId in the URL."); + } + + if (validationResult.isErrored()) { + throw new UnprocessableEntityException(TEMPLATE_CONTAINED_INVALID_DATA, validationResult); + } + WebHookTemplateConfig template = new WebHookTemplateConfig(newTemplate.id, true); - if (validationResult.isErrored()) { - throw new UnprocessableEntityException(TEMPLATE_CONTAINED_INVALID_DATA, validationResult); - } - WebHookTemplateConfig template = new WebHookTemplateConfig(newTemplate.id, true); + return buildAndPersistTemplate(newTemplate, updateMode, template); + } - return buildAndPersistTemplate(newTemplate, updateMode, template); - } + private void checkTemplateCanBeRelocated(String externalProjectId, WebHookTemplateConfigWrapper webHookTemplateConfigWrapper) { + if (!externalProjectId.equals(webHookTemplateConfigWrapper.getExternalProjectId())) { + if (webHookTemplateConfigWrapper.getTemplateConfig() == null){ + throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); + } + if (webHookTemplateConfigWrapper.getStatus().isStateProvided()) { + throw new OperationException("You cannot relocate a tcWebHooks provided template."); + } + if (webHookTemplateConfigWrapper.getStatus().isStateUnknown()) { + throw new OperationException("You cannot relocate a tcWebHooks template in an unknown state. Please report this as a bug against the tcPlugins/tcWebHooks project on GitHub."); + } + int templateUsageCount = myDataProvider.getWebHookFinder().getTemplateUsageCount(webHookTemplateConfigWrapper.getTemplateConfig().getId()); + if (webHookTemplateConfigWrapper.getStatus().equals(TemplateState.USER_DEFINED) && templateUsageCount > 0) { + throw new TemplateInUseException( + "Cannot relocate template with associated webhooks", + new ErrorResult() + .addError("error", "Cannot relocate template with associated webhooks") + .addError("webHookCount", "Associated webhook count: " + templateUsageCount)); + } + } + } - @POST + @POST @Path("/{templateLocator}/patch") @Consumes({"application/xml", "application/json"}) @Produces({"application/xml", "application/json"}) public Template updateTemplate(@PathParam("templateLocator") String templateLocator, Template newTemplate) { - final String updateMode = "update Template"; - checkTemplateWritePermission(); + final String updateMode = UPDATE_TEMPLATE; WebHookTemplateConfigWrapper templateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + + String externalProjectId = findExternalProjectId(templateLocator, newTemplate.projectId, templateConfigWrapper); + + checkTemplateWritePermission(externalProjectId); + checkTemplateWritePermission(templateConfigWrapper.getExternalProjectId()); + checkTemplateCanBeRelocated(externalProjectId, templateConfigWrapper); + if (templateConfigWrapper.getTemplateConfig() == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); } - ErrorResult validationResult = myTemplateValidator.validateTemplate(templateConfigWrapper.getTemplateConfig(), newTemplate, new ErrorResult()); + ErrorResult validationResult = myTemplateValidator.validateTemplate(templateConfigWrapper, newTemplate, new ErrorResult()); if (validationResult.isErrored()) { throw new UnprocessableEntityException(TEMPLATE_CONTAINED_INVALID_DATA, validationResult); } @@ -272,6 +312,10 @@ public Template updateTemplate(@PathParam("templateLocator") String templateLoca if(newTemplate.description != null) { template.setTemplateDescription(newTemplate.description); } + + if (newTemplate.projectId != null) { + template.setProjectInternalId(myDataProvider.getProjectIdResolver().getInternalProjectId(externalProjectId)); + } if(newTemplate.format != null) { template.setFormat(newTemplate.format); @@ -294,7 +338,7 @@ public Template updateTemplate(@PathParam("templateLocator") String templateLoca myTemplateManager.registerTemplateFormatFromXmlConfig(template); if (persistAllXmlConfigTemplates(updateMode)){ - return new Template(new WebHookTemplateConfigWrapper(template, myTemplateManager.getTemplateState(newTemplate.id, TemplateState.BEST), WebHookTemplateStates.build(template)), Fields.LONG, myBeanContext); + return new Template(new WebHookTemplateConfigWrapper(template, myDataProvider.getProjectIdResolver().getExternalProjectId(template.getProjectInternalId()), myTemplateManager.getTemplateState(newTemplate.id, TemplateState.BEST), WebHookTemplateStates.build(template)), Fields.LONG, myBeanContext); } else { throw new OperationException(ERROR_SAVING_TEMPLATE); } @@ -304,16 +348,18 @@ public Template updateTemplate(@PathParam("templateLocator") String templateLoca @Path("/{templateLocator}/rawConfig") @Produces({"application/xml"}) public WebHookTemplateEntity serveRawConfigTemplate(@PathParam("templateLocator") String templateLocator) { - checkTemplateReadPermission(); - return WebHookTemplateConfigBuilder.buildEntity(myDataProvider.getTemplateFinder().findTemplateById(templateLocator).getTemplateConfig()); + WebHookTemplateConfigWrapper wrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(wrapper.getExternalProjectId()); + return WebHookTemplateConfigBuilder.buildEntity(wrapper.getTemplateConfig()); } @GET @Path("/{templateLocator}/fullConfig") @Produces({"application/xml", "application/json"}) public WebHookTemplateConfig serveFullConfigTemplate(@PathParam("templateLocator") String templateLocator) { - checkTemplateReadPermission(); - return myDataProvider.getTemplateFinder().findTemplateById(templateLocator).getTemplateConfig(); + WebHookTemplateConfigWrapper wrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(wrapper.getExternalProjectId()); + return wrapper.getTemplateConfig(); } @PUT @@ -321,23 +367,29 @@ public WebHookTemplateConfig serveFullConfigTemplate(@PathParam("templateLocator @Produces({"application/xml", "application/json"}) @Consumes({"application/xml", "application/json"}) public WebHookTemplateConfig updateFullConfigTemplate(@PathParam("templateLocator") String templateLocator, WebHookTemplateConfig rawConfig) { - checkTemplateWritePermission(); - WebHookTemplateConfig webHookTemplateConfig = myDataProvider.getTemplateFinder().findTemplateById(templateLocator).getTemplateConfig(); - if (webHookTemplateConfig == null){ + WebHookTemplateConfigWrapper webHookTemplateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + if (webHookTemplateConfigWrapper == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); } + + String externalProjectId = findExternalProjectId(templateLocator, rawConfig); + checkTemplateWritePermission(externalProjectId); + checkTemplateWritePermission(webHookTemplateConfigWrapper.getExternalProjectId()); + checkTemplateCanBeRelocated(externalProjectId, webHookTemplateConfigWrapper); - Template newTemplate = new Template(new WebHookTemplateConfigWrapper(webHookTemplateConfig, myTemplateManager.getTemplateState(webHookTemplateConfig.getId(), TemplateState.BEST), WebHookTemplateStates.build(webHookTemplateConfig)), Fields.LONG, myBeanContext); + WebHookTemplateConfigWrapper newConfigWrapper = new WebHookTemplateConfigWrapper(rawConfig, externalProjectId, myTemplateManager.getTemplateState(webHookTemplateConfigWrapper.getTemplateConfig().getId(), TemplateState.BEST), WebHookTemplateStates.build(webHookTemplateConfigWrapper.getTemplateConfig())); + + Template newTemplate = new Template(newConfigWrapper, Fields.LONG, myBeanContext); - ErrorResult validationResult = myTemplateValidator.validateTemplate(webHookTemplateConfig, newTemplate, new ErrorResult()); + ErrorResult validationResult = myTemplateValidator.validateTemplate(webHookTemplateConfigWrapper, newTemplate, new ErrorResult()); if (validationResult.isErrored()) { throw new UnprocessableEntityException(TEMPLATE_CONTAINED_INVALID_DATA, validationResult); } // The above will throw errors if the template is not found, so let's attempt to update it. - if (webHookTemplateConfig.getId().equals(rawConfig.getId())) { + if (webHookTemplateConfigWrapper.getTemplateConfig().getId().equals(rawConfig.getId())) { myTemplateManager.registerTemplateFormatFromXmlConfig(rawConfig); - if (persistAllXmlConfigTemplates("update Template")){ + if (persistAllXmlConfigTemplates(UPDATE_TEMPLATE)){ return myTemplateManager.getTemplateConfig(rawConfig.getId(), TemplateState.BEST); } else { throw new OperationException(ERROR_SAVING_TEMPLATE); @@ -346,28 +398,58 @@ public WebHookTemplateConfig updateFullConfigTemplate(@PathParam("templateLocato throw new OperationException("The template id in the payload did not match the template id in the URL."); } + private String findExternalProjectId(String templateLocator, WebHookTemplateConfig rawConfig) { + final Locator locator = new Locator(templateLocator, PROJECT_ID); + if (locator.getSingleDimensionValue(PROJECT_ID) != null ) { + return locator.getSingleDimensionValue(PROJECT_ID); + } + return this.myDataProvider.getProjectIdResolver().getExternalProjectId(rawConfig.getProjectInternalId()); + } + + private String findExternalProjectId(String templateLocator, WebHookTemplateEntity rawConfig) { + final Locator locator = new Locator(templateLocator, PROJECT_ID); + if (locator.getSingleDimensionValue(PROJECT_ID) != null ) { + return locator.getSingleDimensionValue(PROJECT_ID); + } + return this.myDataProvider.getProjectIdResolver().getExternalProjectId(rawConfig.getAssociatedProjectId()); + } + + private String findExternalProjectId(String templateLocator, String externalProjectId, WebHookTemplateConfigWrapper configWrapper) { + final Locator locator = new Locator(templateLocator, PROJECT_ID); + if (locator.getSingleDimensionValue(PROJECT_ID) != null ) { + return locator.getSingleDimensionValue(PROJECT_ID); + } else if (externalProjectId != null) { + return externalProjectId; + } + return configWrapper.getExternalProjectId(); + } + @PUT @Path("/{templateLocator}/rawConfig") @Consumes({"application/xml"}) @Produces({"application/xml"}) public WebHookTemplateEntity updateFullConfigTemplateInPlainText(@PathParam("templateLocator") String templateLocator, WebHookTemplateEntity rawConfig) { - checkTemplateWritePermission(); - WebHookTemplateConfig webHookTemplateConfig = myDataProvider.getTemplateFinder().findTemplateById(templateLocator).getTemplateConfig(); - if (webHookTemplateConfig == null){ + WebHookTemplateConfigWrapper webHookTemplateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + if (webHookTemplateConfigWrapper == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); } + String externalProjectId = findExternalProjectId(templateLocator, rawConfig); + checkTemplateWritePermission(externalProjectId); + checkTemplateWritePermission(webHookTemplateConfigWrapper.getExternalProjectId()); + checkTemplateCanBeRelocated(externalProjectId, webHookTemplateConfigWrapper); + WebHookTemplateConfig newConfig = WebHookTemplateConfigBuilder.buildConfig(rawConfig); - Template newTemplate = new Template(new WebHookTemplateConfigWrapper(newConfig, myTemplateManager.getTemplateState(webHookTemplateConfig.getId(), TemplateState.BEST), WebHookTemplateStates.build(webHookTemplateConfig)), Fields.LONG, myBeanContext); + Template newTemplate = new Template(new WebHookTemplateConfigWrapper(newConfig, externalProjectId, myTemplateManager.getTemplateState(webHookTemplateConfigWrapper.getTemplateConfig().getId(), TemplateState.BEST), WebHookTemplateStates.build(webHookTemplateConfigWrapper.getTemplateConfig())), Fields.LONG, myBeanContext); - ErrorResult validationResult = myTemplateValidator.validateTemplate(webHookTemplateConfig, newTemplate, new ErrorResult()); + ErrorResult validationResult = myTemplateValidator.validateTemplate(webHookTemplateConfigWrapper, newTemplate, new ErrorResult()); if (validationResult.isErrored()) { throw new UnprocessableEntityException(TEMPLATE_CONTAINED_INVALID_DATA, validationResult); } - if (webHookTemplateConfig.getId().equals(rawConfig.getId())) { + if (webHookTemplateConfigWrapper.getTemplateConfig().getId().equals(rawConfig.getId())) { myTemplateManager.registerTemplateFormatFromXmlConfig(newConfig); - if (persistAllXmlConfigTemplates("update Template")){ + if (persistAllXmlConfigTemplates(UPDATE_TEMPLATE)){ return WebHookTemplateConfigBuilder.buildEntity(myDataProvider.getTemplateFinder().findTemplateById(templateLocator).getTemplateConfig()); } else { throw new OperationException(ERROR_SAVING_TEMPLATE); @@ -382,10 +464,10 @@ public WebHookTemplateEntity updateFullConfigTemplateInPlainText(@PathParam("tem @DELETE @Path("/{templateLocator}") @Produces({"application/xml", "application/json"}) - public void deleteTemplate(@PathParam("templateLocator") String templateLocator, - @QueryParam("fields") String fields) { - checkTemplateWritePermission(); + public void deleteTemplate(@PathParam("templateLocator") String templateLocator, @QueryParam("fields") String fields) { WebHookTemplateConfigWrapper webHookTemplateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(webHookTemplateConfigWrapper.getExternalProjectId()); + if (webHookTemplateConfigWrapper.getTemplateConfig() == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); } @@ -417,11 +499,9 @@ public void deleteTemplate(@PathParam("templateLocator") String templateLocator, @Path("/{templateLocator}/{templateType}/templateContent") @Produces({"text/plain"}) public String serveTemplateContent(@PathParam("templateLocator") String templateLocator, @PathParam("templateType") String templateType) { - checkTemplateReadPermission(); - WebHookTemplateConfig template = myDataProvider.getTemplateFinder().findTemplateById(templateLocator).getTemplateConfig(); - if (template == null){ - throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); - } + WebHookTemplateConfigWrapper wrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(wrapper.getExternalProjectId()); + WebHookTemplateConfig template = wrapper.getTemplateConfig(); if(templateType.equals(DEFAULT_TEMPLATE)){ if (template.getDefaultTemplate() == null){ throw new NotFoundException("This template does not have a default template configured."); @@ -441,11 +521,9 @@ public String serveTemplateContent(@PathParam("templateLocator") String template @Consumes({"text/plain"}) @Produces({"text/plain"}) public String updateTemplateContent(@PathParam("templateLocator") String templateLocator, @PathParam("templateType") String templateType, String templateText) { - checkTemplateWritePermission(); - WebHookTemplateConfig template = myDataProvider.getTemplateFinder().findTemplateById(templateLocator).getTemplateConfig(); - if (template == null){ - throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); - } + WebHookTemplateConfigWrapper wrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(wrapper.getExternalProjectId()); + WebHookTemplateConfig template = wrapper.getTemplateConfig(); if(templateType.equals(DEFAULT_TEMPLATE)){ WebHookTemplateText defaultTemplateText = template.getDefaultTemplate(); if (defaultTemplateText != null){ @@ -491,8 +569,8 @@ public String updateTemplateContent(@PathParam("templateLocator") String templat public String serveSpecificTemplateContent(@PathParam("templateLocator") String templateLocator, @PathParam("templateItemId") String templateItemId, @PathParam("templateContentType") String templateContentType) { - checkTemplateReadPermission(); WebHookTemplateItemConfigWrapper template = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator, templateItemId); + checkTemplateReadPermission(template.getExternalProjectId()); return getTemplateContent(template, templateContentType); } @@ -525,8 +603,8 @@ public String getTemplateContent(WebHookTemplateItemConfigWrapper template, Stri public TemplateItem serveTemplateItem(@PathParam("templateLocator") String templateLocator, @PathParam("templateItemId") String templateItemId, @QueryParam("fields") String fields) { - checkTemplateReadPermission(); WebHookTemplateConfigWrapper templateConfig = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateReadPermission(templateConfig.getExternalProjectId()); WebHookTemplateItemConfigWrapper template = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator, templateItemId); if (template.getTemplateItem() == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); @@ -554,13 +632,18 @@ public String diffTemplateItem( @PathParam("templateContentType2") String templateContentType2, @QueryParam("context") String context) { - checkTemplateReadPermission(); + WebHookTemplateConfigWrapper templateWrapper1 = myDataProvider.getTemplateFinder().findTemplateById(templateLocator1); + WebHookTemplateConfigWrapper templateWrapper2 = myDataProvider.getTemplateFinder().findTemplateById(templateLocator2); + checkTemplateReadPermission(templateWrapper1.getExternalProjectId()); + checkTemplateReadPermission(templateWrapper2.getExternalProjectId()); + WebHookTemplateItemConfigWrapper templateItem1 = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator1, templateItemId1); WebHookTemplateItemConfigWrapper templateItem2 = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator2, templateItemId2); + Integer contextLines = Objects.nonNull(context) ? Integer.valueOf(context) : 100; - Template template1 = new Template(myDataProvider.getTemplateFinder().findTemplateById(templateLocator1), new Fields("$short"), myBeanContext); - Template template2 = new Template(myDataProvider.getTemplateFinder().findTemplateById(templateLocator2), new Fields("$short"), myBeanContext); + Template template1 = new Template(templateWrapper1, new Fields("$short"), myBeanContext); + Template template2 = new Template(templateWrapper2, new Fields("$short"), myBeanContext); String content1 = getTemplateContent(templateItem1, templateContentType1); @@ -598,11 +681,14 @@ public String diffTemplateItem( @QueryParam("fields") String fields, @QueryParam("context") String context) { - checkTemplateReadPermission(); + WebHookTemplateConfigWrapper templateWrapper1 = myDataProvider.getTemplateFinder().findTemplateById(templateLocator1); + WebHookTemplateConfigWrapper templateWrapper2 = myDataProvider.getTemplateFinder().findTemplateById(templateLocator2); + checkTemplateReadPermission(templateWrapper1.getExternalProjectId()); + checkTemplateReadPermission(templateWrapper2.getExternalProjectId()); Integer contextLines = Objects.nonNull(context) ? Integer.valueOf(context) : 100; - Template template1 = new Template(myDataProvider.getTemplateFinder().findTemplateById(templateLocator1), new Fields(fields), myBeanContext); - Template template2 = new Template(myDataProvider.getTemplateFinder().findTemplateById(templateLocator2), new Fields(fields), myBeanContext); + Template template1 = new Template(templateWrapper1, new Fields(fields), myBeanContext); + Template template2 = new Template(templateWrapper2, new Fields(fields), myBeanContext); int maxTemplateTypes = template1.getTemplates().size() > template2.getTemplates().size() ? template1.getTemplates().size() : template2.getTemplates().size(); @@ -700,8 +786,8 @@ private List getTemplateItemBranchContentDiffs(Template template1, Templ public void deleteTemplateItem(@PathParam("templateLocator") String templateLocator, @PathParam("templateItemId") String templateItemId, @QueryParam("fields") String fields) { - checkTemplateWritePermission(); WebHookTemplateConfigWrapper templateConfig = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(templateConfig.getExternalProjectId()); WebHookTemplateItemConfigWrapper template = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator, templateItemId); if (template.getTemplateItem() == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); @@ -728,8 +814,8 @@ public void deleteTemplateItem(@PathParam("templateLocator") String templateLoca @Produces({"application/xml", "application/json"}) public TemplateItem updateTemplateItem(@PathParam("templateLocator") String templateLocator, @PathParam("templateItemId") String templateItemId, @QueryParam("fields") String fields, TemplateItem templateItem) { - checkTemplateWritePermission(); WebHookTemplateConfigWrapper templateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(templateConfigWrapper.getExternalProjectId()); WebHookTemplateItemConfigWrapper templateItemConfigWrapper = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator, templateItemId); if (templateItemConfigWrapper.getTemplateItem() == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); @@ -829,8 +915,8 @@ private boolean persistAllXmlConfigTemplates(String saveContext) { @Produces({"application/xml", "application/json"}) public Response createTemplateItem(@PathParam("templateLocator") String templateLocator, @QueryParam("fields") String fields, TemplateItem templateItem) { - checkTemplateWritePermission(); WebHookTemplateConfigWrapper templateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(templateConfigWrapper.getExternalProjectId()); WebHookTemplateItemConfigWrapper templateItemConfigWrapper = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator, "_new"); if (templateConfigWrapper.getTemplateConfig() == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); @@ -906,8 +992,8 @@ public WebHookTemplateStateRest serveTemplateItemBuildStateSetting(@PathParam("t @PathParam("templateItemId") String templateItemId, @PathParam("buildState") String buildState, @QueryParam("fields") String fields) { - checkTemplateReadPermission(); WebHookTemplateItemConfigWrapper template = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator, templateItemId); + checkTemplateReadPermission(template.getExternalProjectId()); if (template.getTemplateItem() == null){ throw new NotFoundException("No template item found by that id"); } @@ -933,8 +1019,8 @@ public WebHookTemplateStateRest updateTemplateItemBuildStateSetting(@PathParam(" @PathParam("templateItemId") String templateItemId, @PathParam("buildState") String buildState, WebHookTemplateStateRest updatedBuildState) { - checkTemplateWritePermission(); WebHookTemplateItemConfigWrapper template = myDataProvider.getTemplateFinder().findTemplateByIdAndTemplateContentById(templateLocator, templateItemId); + checkTemplateWritePermission(template.getExternalProjectId()); if (template.getTemplateItem() == null){ throw new NotFoundException("No template item found by that id"); } @@ -951,8 +1037,8 @@ public WebHookTemplateStateRest updateTemplateItemBuildStateSetting(@PathParam(" @Produces({"application/xml", "application/json"}) public Response createDefaultTemplateItem(@PathParam("templateLocator") String templateLocator, @QueryParam("fields") String fields, TemplateItem templateItem) { - checkTemplateWritePermission(); WebHookTemplateConfigWrapper templateConfigWrapper = myDataProvider.getTemplateFinder().findTemplateById(templateLocator); + checkTemplateWritePermission(templateConfigWrapper.getExternalProjectId()); if (templateConfigWrapper.getTemplateConfig() == null){ throw new NotFoundException(NO_TEMPLATE_FOUND_BY_THAT_ID); @@ -1017,19 +1103,37 @@ private WebHookTemplateItem buildDefaultTemplateItem(TemplateItem templateItem) private void checkTemplateReadPermission() { try { - myPermissionChecker.checkGlobalPermissionAnyOf(templateReadPermissions); + myDataProvider.getSecurityContext().getAuthorityHolder().isPermissionGrantedForAnyProject(Permission.EDIT_PROJECT); } catch (AuthorizationFailedException e) { - throw new TemplatePermissionException("Reading templates requires at least one of the following permissions: 'VIEW_PROJECT, VIEW_BUILD_CONFIGURATION_SETTINGS, EDIT_PROJECT'"); + throw new TemplatePermissionException("Reading Project templates requires permission 'VIEW_PROJECT' on any project project"); } } - - private void checkTemplateWritePermission() { + + private SProject checkTemplateReadPermission(String externalProjectId) { try { - myPermissionChecker.checkGlobalPermission(templateEditPermission); - } catch (AuthorizationFailedException e) { - throw new TemplatePermissionException("Writing templates requires permission 'CHANGE_SERVER_SETTINGS'"); + SProject sProject = myDataProvider.getProjectManager().findProjectByExternalId(externalProjectId); + if (sProject == null) { + throw new NotFoundException("No project found with supplied projectId"); + } + myPermissionChecker.checkProjectPermission(PROJECT_TEMPLATE_READ_PERMISSION, sProject.getProjectId()); + return sProject; + } catch (AccessDeniedException | AuthorizationFailedException e) { + throw new TemplatePermissionException("Reading Project templates requires permission 'VIEW_PROJECT' on the relevant project"); + } + } + + private SProject checkTemplateWritePermission(String externalProjectId) { + try { + SProject sProject = myDataProvider.getProjectManager().findProjectByExternalId(externalProjectId); + if (sProject == null) { + throw new NotFoundException("No project found with supplied projectId"); + } + myPermissionChecker.checkProjectPermission(PROJECT_TEMPLATE_EDIT_PERMISSION, sProject.getProjectId()); + return sProject; + } catch (AccessDeniedException | AuthorizationFailedException e) { + throw new TemplatePermissionException("Writing Project templates requires permission 'EDIT_PROJECT' on the relevant project"); } } - + } diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateFinderTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateFinderTest.java index 1356a8db..89195f57 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateFinderTest.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateFinderTest.java @@ -9,6 +9,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import webhook.teamcity.ProjectIdResolver; import webhook.teamcity.payload.WebHookPayloadManager; import webhook.teamcity.payload.WebHookTemplateManager; import webhook.teamcity.payload.template.AbstractXmlBasedWebHookTemplate; @@ -22,35 +23,39 @@ public class TemplateFinderTest { private WebHookTemplateManager webHookTemplateManager; + @Mock + private ProjectIdResolver projectIdResolver; + @Before public void setup(){ MockitoAnnotations.initMocks(this); when(server.getRootUrl()).thenReturn("http://test.url"); + when(projectIdResolver.getInternalProjectId("_Root")).thenReturn("preoject0"); WebHookPayloadManager webHookPayloadManager = new WebHookPayloadManager(server); - webHookTemplateManager = new WebHookTemplateManager(webHookPayloadManager, new WebHookTemplateJaxHelperImpl()); + webHookTemplateManager = new WebHookTemplateManager(webHookPayloadManager, new WebHookTemplateJaxHelperImpl(), projectIdResolver); - AbstractXmlBasedWebHookTemplate wht = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, new WebHookTemplateJaxHelperImpl()); + AbstractXmlBasedWebHookTemplate wht = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, new WebHookTemplateJaxHelperImpl(), projectIdResolver, null); wht.register(); } @Test public void testFindTemplateWithNoDimention() { - TemplateFinder templateFinder = new TemplateFinder(webHookTemplateManager); + TemplateFinder templateFinder = new TemplateFinder(webHookTemplateManager, projectIdResolver); WebHookTemplateConfig e = templateFinder.findTemplateById("slack.com-compact").getTemplateConfig(); assertEquals("slack.com-compact", e.getId()); } @Test public void testFindTemplateByIdDimension() { - TemplateFinder templateFinder = new TemplateFinder(webHookTemplateManager); + TemplateFinder templateFinder = new TemplateFinder(webHookTemplateManager, projectIdResolver); WebHookTemplateConfig e = templateFinder.findTemplateById("id:slack.com-compact").getTemplateConfig(); assertEquals("slack.com-compact", e.getId()); } @Test public void testFindTemplateByNameDimension() { - TemplateFinder templateFinder = new TemplateFinder(webHookTemplateManager); + TemplateFinder templateFinder = new TemplateFinder(webHookTemplateManager, projectIdResolver); WebHookTemplateConfig e = templateFinder.findTemplateById("name:slack.com-compact").getTemplateConfig(); assertEquals("slack.com-compact", e.getId()); System.out.println(e.getTemplateDescription()); diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateValidatorTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateValidatorTest.java index 56b122ab..97bb403f 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateValidatorTest.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/data/TemplateValidatorTest.java @@ -8,9 +8,15 @@ import javax.xml.bind.JAXBException; +import org.junit.Before; import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import jetbrains.buildServer.server.rest.data.PermissionChecker; +import jetbrains.buildServer.serverSide.ProjectManager; import webhook.teamcity.server.rest.model.template.Template.TemplateItem; +import webhook.teamcity.payload.WebHookTemplateManager; import webhook.teamcity.server.rest.model.template.ErrorResult; import webhook.teamcity.settings.entity.JaxHelper; @@ -19,9 +25,23 @@ public class TemplateValidatorTest { private static final String ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML = "src/test/resources/REST-examples/elasticsearch-templateItem-defaultTemplate.xml"; private static final String ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML = "src/test/resources/REST-examples/elasticsearch-templateItem-template1.xml"; + @Mock + ProjectManager projectManager; + + @Mock + WebHookTemplateManager webHookTemplateManager; + + @Mock + PermissionChecker permissionChecker; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + @Test public void testValidateTemplateItemThatFindsNoDifferences() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); ErrorResult result = tv.validateTemplateItem(templateItem, templateItem2, new ErrorResult()); @@ -31,7 +51,7 @@ public void testValidateTemplateItemThatFindsNoDifferences() throws FileNotFound @Test public void testValidateTemplateItemWhereTemplateIdIsUpdated() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); templateItem2.setId("someOtherId"); @@ -43,7 +63,7 @@ public void testValidateTemplateItemWhereTemplateIdIsUpdated() throws FileNotFou @Test public void testValidateTemplateItemWhereReadOnlyBuildStartedIsUpdated() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); templateItem2.findConfigForBuildState("buildStarted").setEnabled(false); @@ -55,7 +75,7 @@ public void testValidateTemplateItemWhereReadOnlyBuildStartedIsUpdated() throws @Test public void testValidateTemplateItemWhereBuildStartedIsRenamedToInvaliateBuildStateShortName() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_DEFAULT_TEMPLATE_XML, TemplateItem.class); templateItem2.findConfigForBuildState("buildStarted").setType("invalidname"); @@ -67,7 +87,7 @@ public void testValidateTemplateItemWhereBuildStartedIsRenamedToInvaliateBuildSt @Test public void testValidateTemplateItem1ThatFindsNoDifferences() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); ErrorResult result = tv.validateTemplateItem(templateItem, templateItem2, new ErrorResult()); @@ -77,7 +97,7 @@ public void testValidateTemplateItem1ThatFindsNoDifferences() throws FileNotFoun @Test public void testValidateTemplateItem1WhereTemplateIdIsUpdated() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); templateItem2.setId("someOtherId"); @@ -89,7 +109,7 @@ public void testValidateTemplateItem1WhereTemplateIdIsUpdated() throws FileNotFo @Test public void testValidateTemplateItem1WhereBuildStartedIsUpdated() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); templateItem2.findConfigForBuildState("buildStarted").setEnabled(false); @@ -100,7 +120,7 @@ public void testValidateTemplateItem1WhereBuildStartedIsUpdated() throws FileNot @Test public void testValidateTemplateItem1WhereBuildStartedIsRenamedToInvaliateBuildStateShortName() throws FileNotFoundException, JAXBException { - TemplateValidator tv = new TemplateValidator(); + TemplateValidator tv = new TemplateValidator(webHookTemplateManager, permissionChecker, projectManager); TemplateItem templateItem = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); TemplateItem templateItem2 = new JaxHelper().read(ELASTICSEARCH_TEMPLATE_ITEM_ONE_TEMPLATE_XML, TemplateItem.class); templateItem2.findConfigForBuildState("buildStarted").setType("invalidname"); diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/CreateNewTemplateTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/CreateNewTemplateTest.java index d654302b..d7995562 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/CreateNewTemplateTest.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/CreateNewTemplateTest.java @@ -1,167 +1,167 @@ -package webhook.teamcity.server.rest.request; - -import static org.junit.Assert.*; -import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; - -import javax.ws.rs.core.MediaType; - - -import org.junit.Before; -import org.junit.Test; - -import webhook.teamcity.payload.WebHookPayloadManager; -import webhook.teamcity.payload.WebHookPayloadTemplate; -import webhook.teamcity.payload.WebHookTemplateManager; -import webhook.teamcity.payload.template.ElasticSearchXmlWebHookTemplate; -import webhook.teamcity.server.rest.model.template.Template; -import webhook.teamcity.server.rest.model.template.Template.TemplateItem; -import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; -import webhook.teamcity.server.rest.model.template.Templates; - -import com.sun.jersey.api.client.UniformInterfaceException; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.filter.LoggingFilter; - -import org.springframework.beans.factory.annotation.Autowired; - -public class CreateNewTemplateTest extends WebHookAbstractSpringAwareJerseyTest { - - @Autowired - WebHookTemplateManager webHookTemplateManager; - - @Autowired - WebHookPayloadManager webHookPayloadManager; - - @Autowired - WebHookTemplateJaxHelper webHookTemplateJaxHelper; - - WebResource webResource; - - @Before - public void setup(){ - webResource = resource(); - webResource.addFilter(new LoggingFilter(System.out)); - } - - @Test - public void testRequestTemplatesUsingXmlWithNoneConfiguredReturnsZeroTemplates() { - WebResource webResource = resource(); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_XML_TYPE).get(Templates.class); - assertEquals("Templates count should be zero", 0, (int)responseMsg.count ); - } - - @Test - public void testRequestTemplatesUsingJsonWithNoneConfiguredReturnsZeroTemplates() { - WebResource webResource = resource(); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertTrue(responseMsg.count == 0); - } - - @Test - public void testCreateNewMinimalTemplateUsingJsonReturnsCreatedTemplate() { - WebResource webResource = resource(); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertTrue(responseMsg.count == 0); - - Template newTemplate = new Template(); - newTemplate.description = "A test template"; - newTemplate.id = "testTemplateFromUnitTest"; - newTemplate.format = "jsontemplate"; - newTemplate.rank = 500; - - webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); - Templates updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertTrue(updatedResponse.count == 1); - - } - - @Test(expected=com.sun.jersey.api.client.UniformInterfaceException.class) - public void testCreateAndUpdateUsingJsonFailsForSameTemplateName() { - WebResource webResource = resource(); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertEquals("Templates count should be zero", 0, (int)responseMsg.count); - - Template newTemplate = new Template(); - newTemplate.description = "A test template"; - newTemplate.id = "testTemplateFromUnitTest"; - - webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); - Templates updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertEquals("Templates count should now be one", 1, (int)updatedResponse.count); - - webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); - updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - - } - - @Test - public void testCreateTemplateItemOnExistingTempalteUsingJson() { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - WebResource webResource = resource(); - - Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertTrue(templateResponse.getTemplates().size() == 1); - - - TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").queryParam("fields","$long,templateItem,content").accept(MediaType.APPLICATION_JSON_TYPE).get(TemplateItem.class); - prettyPrint(responseMsg); - responseMsg.id= "_new"; - - webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItem").accept(MediaType.APPLICATION_JSON_TYPE).post(responseMsg); - - Template updatedResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertTrue(updatedResponse.getTemplates().size() == 2); - - prettyPrint(updatedResponse); - - } - - @Test(expected=UniformInterfaceException.class) - public void testCreateDefaultTemplateItemFailsUsingJsonWhenDefaultTemplateAlreadyExists() { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - WebResource webResource = resource(); - - Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertTrue(templateResponse.getTemplates().size() == 1); - - - TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(TemplateItem.class); - - responseMsg.id= "_new"; - prettyPrint(responseMsg); - - webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).post(responseMsg); - - } - - @Test - public void testCreateTemplateByRequestingAnExistingTemplateAndThenSubmittingItWithANewTemplateName() { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - WebResource webResource = resource(); - - Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").queryParam("fields","**").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertTrue(templateResponse.getTemplates().size() == 1); - - templateResponse.id ="newElastic"; - - webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).post(templateResponse); - - Template createdTemplateResponse = webResource.path(API_TEMPLATES_URL + "/id:newElastic").queryParam("fields","**").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - prettyPrint(createdTemplateResponse); - assertTrue(createdTemplateResponse.getTemplates().size() == 1); - assertTrue(createdTemplateResponse.defaultTemplate.getTemplateText() != null); - assertFalse(createdTemplateResponse.defaultTemplate.getTemplateText().content.isEmpty()); - assertTrue(createdTemplateResponse.defaultTemplate.getBranchTemplateText() != null); - assertFalse(createdTemplateResponse.defaultTemplate.getBranchTemplateText().content.isEmpty()); - - } +package webhook.teamcity.server.rest.request; + +import static org.junit.Assert.*; +import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; + +import javax.ws.rs.core.MediaType; + + +import org.junit.Before; +import org.junit.Test; + +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookPayloadTemplate; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.payload.template.ElasticSearchXmlWebHookTemplate; +import webhook.teamcity.server.rest.model.template.Template; +import webhook.teamcity.server.rest.model.template.Template.TemplateItem; +import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; +import webhook.teamcity.server.rest.model.template.Templates; + +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.LoggingFilter; + +import org.springframework.beans.factory.annotation.Autowired; + +public class CreateNewTemplateTest extends WebHookAbstractSpringAwareJerseyTest { + + @Autowired + WebHookTemplateManager webHookTemplateManager; + + @Autowired + WebHookPayloadManager webHookPayloadManager; + + @Autowired + WebHookTemplateJaxHelper webHookTemplateJaxHelper; + + WebResource webResource; + + @Before + public void setup(){ + webResource = resource(); + webResource.addFilter(new LoggingFilter(System.out)); + } + + @Test + public void testRequestTemplatesUsingXmlWithNoneConfiguredReturnsZeroTemplates() { + WebResource webResource = resource(); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_XML_TYPE).get(Templates.class); + assertEquals("Templates count should be zero", 0, (int)responseMsg.count ); + } + + @Test + public void testRequestTemplatesUsingJsonWithNoneConfiguredReturnsZeroTemplates() { + WebResource webResource = resource(); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertTrue(responseMsg.count == 0); + } + + @Test + public void testCreateNewMinimalTemplateUsingJsonReturnsCreatedTemplate() { + WebResource webResource = resource(); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertTrue(responseMsg.count == 0); + + Template newTemplate = new Template(); + newTemplate.description = "A test template"; + newTemplate.id = "testTemplateFromUnitTest"; + newTemplate.format = "jsontemplate"; + newTemplate.rank = 500; + + webResource.path(API_TEMPLATES_URL + "/_Root").accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); + Templates updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertTrue(updatedResponse.count == 1); + + } + + @Test(expected=com.sun.jersey.api.client.UniformInterfaceException.class) + public void testCreateAndUpdateUsingJsonFailsForSameTemplateName() { + WebResource webResource = resource(); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertEquals("Templates count should be zero", 0, (int)responseMsg.count); + + Template newTemplate = new Template(); + newTemplate.description = "A test template"; + newTemplate.id = "testTemplateFromUnitTest"; + + webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); + Templates updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertEquals("Templates count should now be one", 1, (int)updatedResponse.count); + + webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); + updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + + } + + @Test + public void testCreateTemplateItemOnExistingTempalteUsingJson() { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + WebResource webResource = resource(); + + Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertTrue(templateResponse.getTemplates().size() == 1); + + + TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").queryParam("fields","$long,templateItem,content").accept(MediaType.APPLICATION_JSON_TYPE).get(TemplateItem.class); + prettyPrint(responseMsg); + responseMsg.id= "_new"; + + webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItem").accept(MediaType.APPLICATION_JSON_TYPE).post(responseMsg); + + Template updatedResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertTrue(updatedResponse.getTemplates().size() == 2); + + prettyPrint(updatedResponse); + + } + + @Test(expected=UniformInterfaceException.class) + public void testCreateDefaultTemplateItemFailsUsingJsonWhenDefaultTemplateAlreadyExists() { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + WebResource webResource = resource(); + + Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertTrue(templateResponse.getTemplates().size() == 1); + + + TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(TemplateItem.class); + + responseMsg.id= "_new"; + prettyPrint(responseMsg); + + webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).post(responseMsg); + + } + + @Test + public void testCreateTemplateByRequestingAnExistingTemplateAndThenSubmittingItWithANewTemplateName() { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + WebResource webResource = resource(); + + Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").queryParam("fields","**").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertTrue(templateResponse.getTemplates().size() == 1); + + templateResponse.id ="newElastic"; + + webResource.path(API_TEMPLATES_URL + "/_Root").accept(MediaType.APPLICATION_JSON_TYPE).post(templateResponse); + + Template createdTemplateResponse = webResource.path(API_TEMPLATES_URL + "/id:newElastic").queryParam("fields","**").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + prettyPrint(createdTemplateResponse); + assertTrue(createdTemplateResponse.getTemplates().size() == 1); + assertTrue(createdTemplateResponse.defaultTemplate.getTemplateText() != null); + assertFalse(createdTemplateResponse.defaultTemplate.getTemplateText().content.isEmpty()); + assertTrue(createdTemplateResponse.defaultTemplate.getBranchTemplateText() != null); + assertFalse(createdTemplateResponse.defaultTemplate.getBranchTemplateText().content.isEmpty()); + + } } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/DeleteTemplateTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/DeleteTemplateTest.java index 8bcb01a4..c455e749 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/DeleteTemplateTest.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/DeleteTemplateTest.java @@ -1,124 +1,124 @@ -package webhook.teamcity.server.rest.request; - -import static org.junit.Assert.assertEquals; -import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; - -import javax.ws.rs.core.MediaType; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.filter.LoggingFilter; - -import webhook.teamcity.payload.WebHookPayloadManager; -import webhook.teamcity.payload.WebHookPayloadTemplate; -import webhook.teamcity.payload.WebHookTemplateManager; -import webhook.teamcity.payload.template.ElasticSearchXmlWebHookTemplate; -import webhook.teamcity.payload.template.SlackComCompactXmlWebHookTemplate; -import webhook.teamcity.server.rest.model.template.Template; -import webhook.teamcity.server.rest.model.template.Templates; -import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; - -public class DeleteTemplateTest extends WebHookAbstractSpringAwareJerseyTest { - - @Autowired - WebHookTemplateManager webHookTemplateManager; - - @Autowired - WebHookPayloadManager webHookPayloadManager; - - @Autowired - WebHookTemplateJaxHelper webHookTemplateJaxHelper; - - WebResource webResource; - - @Before - public void setup(){ - webResource = resource(); - webResource.addFilter(new LoggingFilter(System.out)); - } - - @Test - public void testDeleteTemplateUsingJson() { - - WebResource webResource = resource(); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertEquals(0, (int)responseMsg.count); - - Template newTemplate = new Template(); - newTemplate.description = "A test template"; - newTemplate.id = "testTemplateFromUnitTest"; - newTemplate.format = "jsontemplate"; - newTemplate.rank = 500; - - webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); - Templates updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertEquals(1, (int)updatedResponse.count); - - - webResource.path(API_TEMPLATES_URL + "/id:testTemplateFromUnitTest").delete(); - - updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertEquals(0, (int)updatedResponse.count); - - - } - @Test - public void testDeleteTemplateItemUsingJson() { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseTemplate = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - Template.TemplateItem responseTemplateItem = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - - prettyPrint(responseTemplate); - - assertEquals("slack.com-compact", responseTemplate.id); - assertEquals("slack.com-compact", responseTemplateItem.parentTemplate.getId()); - prettyPrint(responseTemplateItem); - - assertEquals(5, responseTemplate.getTemplates().size()); - - ClientResponse deleteResponse = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).delete(ClientResponse.class); - assertEquals(204, deleteResponse.getStatus()); - - ClientResponse getResponse = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); - // I've not figured out how to invoke the exception handler, so "NotFoundException" returns 500 - // in Grizzly tests. - assertEquals(500, getResponse.getStatus()); - - Template responseTemplate2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals(4, responseTemplate2.getTemplates().size()); - - } - - @Test - public void testDeleteDefaultTemplateItemUsingJson() { - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - WebResource webResource = resource(); - - Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals(1, templateResponse.getTemplates().size()); - - ClientResponse responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); - assertEquals(200, responseMsg.getStatus()); - - ClientResponse deleteResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).delete(ClientResponse.class); - assertEquals(204, deleteResponse.getStatus()); - - ClientResponse getResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); - // I've not figured out how to invoke the exception handler, so "NotFoundException" returns 500 - // in Grizzly tests. - assertEquals(500, getResponse.getStatus()); - - } - - - +package webhook.teamcity.server.rest.request; + +import static org.junit.Assert.assertEquals; +import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; + +import javax.ws.rs.core.MediaType; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.LoggingFilter; + +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookPayloadTemplate; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.payload.template.ElasticSearchXmlWebHookTemplate; +import webhook.teamcity.payload.template.SlackComCompactXmlWebHookTemplate; +import webhook.teamcity.server.rest.model.template.Template; +import webhook.teamcity.server.rest.model.template.Templates; +import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; + +public class DeleteTemplateTest extends WebHookAbstractSpringAwareJerseyTest { + + @Autowired + WebHookTemplateManager webHookTemplateManager; + + @Autowired + WebHookPayloadManager webHookPayloadManager; + + @Autowired + WebHookTemplateJaxHelper webHookTemplateJaxHelper; + + WebResource webResource; + + @Before + public void setup(){ + webResource = resource(); + webResource.addFilter(new LoggingFilter(System.out)); + } + + @Test + public void testDeleteTemplateUsingJson() { + + WebResource webResource = resource(); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertEquals(0, (int)responseMsg.count); + + Template newTemplate = new Template(); + newTemplate.description = "A test template"; + newTemplate.id = "testTemplateFromUnitTest"; + newTemplate.format = "jsontemplate"; + newTemplate.rank = 500; + + webResource.path(API_TEMPLATES_URL + "/_Root").accept(MediaType.APPLICATION_JSON_TYPE).post(newTemplate); + Templates updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertEquals(1, (int)updatedResponse.count); + + + webResource.path(API_TEMPLATES_URL + "/id:testTemplateFromUnitTest").delete(); + + updatedResponse = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertEquals(0, (int)updatedResponse.count); + + + } + @Test + public void testDeleteTemplateItemUsingJson() { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseTemplate = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + Template.TemplateItem responseTemplateItem = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + + prettyPrint(responseTemplate); + + assertEquals("slack.com-compact", responseTemplate.id); + assertEquals("slack.com-compact", responseTemplateItem.parentTemplate.getId()); + prettyPrint(responseTemplateItem); + + assertEquals(5, responseTemplate.getTemplates().size()); + + ClientResponse deleteResponse = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).delete(ClientResponse.class); + assertEquals(204, deleteResponse.getStatus()); + + ClientResponse getResponse = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); + // I've not figured out how to invoke the exception handler, so "NotFoundException" returns 500 + // in Grizzly tests. + assertEquals(500, getResponse.getStatus()); + + Template responseTemplate2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals(4, responseTemplate2.getTemplates().size()); + + } + + @Test + public void testDeleteDefaultTemplateItemUsingJson() { + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + WebResource webResource = resource(); + + Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals(1, templateResponse.getTemplates().size()); + + ClientResponse responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); + assertEquals(200, responseMsg.getStatus()); + + ClientResponse deleteResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).delete(ClientResponse.class); + assertEquals(204, deleteResponse.getStatus()); + + ClientResponse getResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); + // I've not figured out how to invoke the exception handler, so "NotFoundException" returns 500 + // in Grizzly tests. + assertEquals(500, getResponse.getStatus()); + + } + + + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/EditExistingTemplateTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/EditExistingTemplateTest.java index f2d76a0e..57fcaf44 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/EditExistingTemplateTest.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/EditExistingTemplateTest.java @@ -1,294 +1,295 @@ -package webhook.teamcity.server.rest.request; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; - -import java.io.FileNotFoundException; -import java.util.ArrayList; - -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.xml.bind.JAXBException; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import com.sun.jersey.api.client.UniformInterfaceException; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.filter.LoggingFilter; - -import webhook.teamcity.payload.WebHookPayloadManager; -import webhook.teamcity.payload.WebHookPayloadTemplate; -import webhook.teamcity.payload.WebHookTemplateManager; -import webhook.teamcity.payload.WebHookTemplateManager.TemplateState; -import webhook.teamcity.payload.template.SlackComCompactXmlWebHookTemplate; -import webhook.teamcity.server.rest.model.template.Template; -import webhook.teamcity.server.rest.model.template.Template.WebHookTemplateStateRest; -import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; - -public class EditExistingTemplateTest extends WebHookAbstractSpringAwareJerseyTest { - - @Autowired - WebHookTemplateManager webHookTemplateManager; - - @Autowired - WebHookPayloadManager webHookPayloadManager; - - @Autowired - WebHookTemplateJaxHelper webHookTemplateJaxHelper; - - WebResource webResource; - - @Before - public void setup(){ - webResource = resource(); - webResource.addFilter(new LoggingFilter(System.out)); - } - - @Test - public void testUpdateJsonTemplatesRequestUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - - assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); - - prettyPrint(responseMsg); - - // templateItem "id:1" is for buildFixed and buildSuccessful - // disable buildSuccessful - responseMsg.findConfigForBuildState("buildSuccessful").setEnabled(false); - Template.TemplateItem responseMsg2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).put(Template.TemplateItem.class, responseMsg); - - // check that the response back is false - assertFalse("buildSuccessful should now be false for template id:1", responseMsg2.findConfigForBuildState("buildSuccessful").isEnabled()); - prettyPrint(responseMsg2); - - // Get it again (and check it again just for an extra check) - Template.TemplateItem responseMsg3 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplateName,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - assertFalse("buildSuccessful should now be false for template id:1", responseMsg2.findConfigForBuildState("buildSuccessful").isEnabled()); - - // Now update the value and PUT it back - responseMsg3.findConfigForBuildState("buildSuccessful").setEnabled(true); - Template.TemplateItem responseMsg4 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).put(Template.TemplateItem.class, responseMsg3); - - // Check the response now has it set to true again. - assertTrue("buildSuccessful should now be false for template id:1", responseMsg4.findConfigForBuildState("buildSuccessful").isEnabled()); - prettyPrint(responseMsg4); - } - - @Test(expected=UniformInterfaceException.class) - public void testUpdateJsonTemplateTemplateItemByEnablingInvalidBuildStateRequestUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - - assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); - prettyPrint(responseMsg); - - responseMsg.findConfigForBuildState("buildFailed").setEnabled(true); - try { - webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).put(Template.TemplateItem.class, responseMsg); - } catch (UniformInterfaceException e) { - assertEquals("Client response status: 422", e.getMessage()); - throw e; - } - } - - @Test - public void testCreateDefaultTemplateUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - - assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); - prettyPrint(responseMsg); - - responseMsg.id= "_new"; - responseMsg.setBuildStates(new ArrayList()); - - Template.TemplateItem responseMsg2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(Template.TemplateItem.class, responseMsg); - prettyPrint(responseMsg2); - - } - - @Test - public void testEditTemplateUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("slack.com-compact", responseMsg.id); - assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); - prettyPrint(responseMsg); - - responseMsg.description = "New Description"; - responseMsg.rank = 999; - responseMsg.preferredDateFormat="YYYY-MM"; - responseMsg.toolTip = "Woot, a tooltip"; - - webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).put(Template.class, responseMsg); - - Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("slack.com-compact", responseAfterEdit.id); - assertEquals("New Description", responseAfterEdit.description); - assertEquals("YYYY-MM", responseAfterEdit.preferredDateFormat); - assertEquals("Woot, a tooltip", responseAfterEdit.toolTip); - assertEquals(TemplateState.USER_OVERRIDDEN.toString(), responseAfterEdit.status); - - prettyPrint(responseAfterEdit); - } - - @Test - public void testEditTemplateWithMinimalChangesUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("slack.com-compact", responseMsg.id); - assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); - prettyPrint(responseMsg); - - responseMsg.description = null; - responseMsg.rank = null; - responseMsg.preferredDateFormat = null; - responseMsg.toolTip = null; - webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); - - Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("Slack.com Compact Notification", responseAfterEdit.description); - assertEquals("slack.com-compact", responseAfterEdit.id); - assertEquals("", responseAfterEdit.preferredDateFormat); - assertEquals("POSTs a very compact slack.com notification", responseAfterEdit.toolTip); - assertEquals(TemplateState.USER_OVERRIDDEN.toString(), responseAfterEdit.status); - - prettyPrint(responseAfterEdit); - } - - @Test - public void testEditTemplateWithMinimalChangesCanRequestOriginalUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("slack.com-compact", responseMsg.id); - assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); - prettyPrint(responseMsg); - - responseMsg.description = null; - responseMsg.rank = null; - responseMsg.preferredDateFormat = null; - responseMsg.toolTip = "Something new for a tooltip"; - webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); - - Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact,status:PROVIDED").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("Slack.com Compact Notification", responseAfterEdit.description); - assertEquals("slack.com-compact", responseAfterEdit.id); - assertEquals("", responseAfterEdit.preferredDateFormat); - assertEquals("POSTs a very compact slack.com notification", responseAfterEdit.toolTip); - assertEquals(TemplateState.PROVIDED.toString(), responseAfterEdit.status); - - prettyPrint(responseAfterEdit); - } - - @Test - public void testEditTemplateWithMinimalChangesCanRequestOverridenUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("slack.com-compact", responseMsg.id); - assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); - prettyPrint(responseMsg); - - responseMsg.description = null; - responseMsg.rank = null; - responseMsg.preferredDateFormat = null; - responseMsg.toolTip = "Something new for a tooltip"; - webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); - - Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact,status:USER_OVERRIDDEN").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("Slack.com Compact Notification", responseAfterEdit.description); - assertEquals("slack.com-compact", responseAfterEdit.id); - assertEquals("", responseAfterEdit.preferredDateFormat); - assertEquals("Something new for a tooltip", responseAfterEdit.toolTip); - assertEquals(TemplateState.USER_OVERRIDDEN.toString(), responseAfterEdit.status); - - prettyPrint(responseAfterEdit); - } - - @Test - public void testDefaultTemplateDiff() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - - assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); - prettyPrint(responseMsg); - - responseMsg.id= "_new"; - responseMsg.setBuildStates(new ArrayList()); - - Template.TemplateItem responseMsg2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(Template.TemplateItem.class, responseMsg); - prettyPrint(responseMsg2); - - String responsePatch = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact,status:PROVIDED/templateItems/id:1/templateContent/diff/id:slack.com-compact,status:USER_OVERRIDDEN/templateItems/id:2/templateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); - - System.out.println("################################"); - System.out.println(responsePatch); - - } - - @Test - public void testEditTemplateFromEmptyTemplateUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = new Template(); - responseMsg.id = "slack.com-compact"; - webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); - - Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("Slack.com Compact Notification", responseAfterEdit.description); - assertEquals("slack.com-compact", responseAfterEdit.id); - assertEquals("", responseAfterEdit.preferredDateFormat); - assertEquals("POSTs a very compact slack.com notification", responseAfterEdit.toolTip); - prettyPrint(responseAfterEdit); - } - - @Test(expected=UniformInterfaceException.class) - public void testChangeExistingTemplateIdCausesExceptionAsJson() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals("slack.com-compact", responseMsg.id); - prettyPrint(responseMsg); - - responseMsg.id = "newDescription"; - try { - webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Response.class, responseMsg); - } catch (UniformInterfaceException ex) { - assertEquals(422, ex.getResponse().getStatus()); - throw ex; - } - } - +package webhook.teamcity.server.rest.request; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; + +import java.io.FileNotFoundException; +import java.util.ArrayList; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.xml.bind.JAXBException; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.LoggingFilter; + +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookPayloadTemplate; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.payload.WebHookTemplateManager.TemplateState; +import webhook.teamcity.payload.template.SlackComCompactXmlWebHookTemplate; +import webhook.teamcity.server.rest.model.template.Template; +import webhook.teamcity.server.rest.model.template.Template.WebHookTemplateStateRest; +import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; + +public class EditExistingTemplateTest extends WebHookAbstractSpringAwareJerseyTest { + + @Autowired + WebHookTemplateManager webHookTemplateManager; + + @Autowired + WebHookPayloadManager webHookPayloadManager; + + @Autowired + WebHookTemplateJaxHelper webHookTemplateJaxHelper; + + WebResource webResource; + + @Before + public void setup(){ + webResource = resource(); + webResource.addFilter(new LoggingFilter(System.out)); + } + + @Test + public void testUpdateJsonTemplatesRequestUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + + assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); + + prettyPrint(responseMsg); + + // templateItem "id:1" is for buildFixed and buildSuccessful + // disable buildSuccessful + responseMsg.findConfigForBuildState("buildSuccessful").setEnabled(false); + Template.TemplateItem responseMsg2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).put(Template.TemplateItem.class, responseMsg); + + // check that the response back is false + assertFalse("buildSuccessful should now be false for template id:1", responseMsg2.findConfigForBuildState("buildSuccessful").isEnabled()); + prettyPrint(responseMsg2); + + // Get it again (and check it again just for an extra check) + Template.TemplateItem responseMsg3 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplateName,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + assertFalse("buildSuccessful should now be false for template id:1", responseMsg2.findConfigForBuildState("buildSuccessful").isEnabled()); + + // Now update the value and PUT it back + responseMsg3.findConfigForBuildState("buildSuccessful").setEnabled(true); + Template.TemplateItem responseMsg4 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).put(Template.TemplateItem.class, responseMsg3); + + // Check the response now has it set to true again. + assertTrue("buildSuccessful should now be false for template id:1", responseMsg4.findConfigForBuildState("buildSuccessful").isEnabled()); + prettyPrint(responseMsg4); + } + + @Test(expected=UniformInterfaceException.class) + public void testUpdateJsonTemplateTemplateItemByEnablingInvalidBuildStateRequestUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + + assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); + prettyPrint(responseMsg); + + responseMsg.findConfigForBuildState("buildFailed").setEnabled(true); + try { + webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").accept(MediaType.APPLICATION_JSON_TYPE).put(Template.TemplateItem.class, responseMsg); + } catch (UniformInterfaceException e) { + assertEquals("Client response status: 422", e.getMessage()); + throw e; + } + } + + @Test + public void testCreateDefaultTemplateUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + + assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); + prettyPrint(responseMsg); + + responseMsg.id= "_new"; + responseMsg.setBuildStates(new ArrayList()); + + Template.TemplateItem responseMsg2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(Template.TemplateItem.class, responseMsg); + prettyPrint(responseMsg2); + + } + + @Test + public void testEditTemplateUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("slack.com-compact", responseMsg.id); + assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); + prettyPrint(responseMsg); + + responseMsg.description = "New Description"; + responseMsg.rank = 999; + responseMsg.preferredDateFormat="YYYY-MM"; + responseMsg.toolTip = "Woot, a tooltip"; + responseMsg.projectId = "TestProject"; + + webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).put(Template.class, responseMsg); + + Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("slack.com-compact", responseAfterEdit.id); + assertEquals("New Description", responseAfterEdit.description); + assertEquals("YYYY-MM", responseAfterEdit.preferredDateFormat); + assertEquals("Woot, a tooltip", responseAfterEdit.toolTip); + assertEquals(TemplateState.USER_OVERRIDDEN.toString(), responseAfterEdit.status); + + prettyPrint(responseAfterEdit); + } + + @Test + public void testEditTemplateWithMinimalChangesUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("slack.com-compact", responseMsg.id); + assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); + prettyPrint(responseMsg); + + responseMsg.description = null; + responseMsg.rank = null; + responseMsg.preferredDateFormat = null; + responseMsg.toolTip = null; + webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); + + Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("Slack.com Compact Notification", responseAfterEdit.description); + assertEquals("slack.com-compact", responseAfterEdit.id); + assertEquals("", responseAfterEdit.preferredDateFormat); + assertEquals("POSTs a very compact slack.com notification", responseAfterEdit.toolTip); + assertEquals(TemplateState.USER_OVERRIDDEN.toString(), responseAfterEdit.status); + + prettyPrint(responseAfterEdit); + } + + @Test + public void testEditTemplateWithMinimalChangesCanRequestOriginalUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("slack.com-compact", responseMsg.id); + assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); + prettyPrint(responseMsg); + + responseMsg.description = null; + responseMsg.rank = null; + responseMsg.preferredDateFormat = null; + responseMsg.toolTip = "Something new for a tooltip"; + webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); + + Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact,status:PROVIDED").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("Slack.com Compact Notification", responseAfterEdit.description); + assertEquals("slack.com-compact", responseAfterEdit.id); + assertEquals("", responseAfterEdit.preferredDateFormat); + assertEquals("POSTs a very compact slack.com notification", responseAfterEdit.toolTip); + assertEquals(TemplateState.PROVIDED.toString(), responseAfterEdit.status); + + prettyPrint(responseAfterEdit); + } + + @Test + public void testEditTemplateWithMinimalChangesCanRequestOverridenUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("slack.com-compact", responseMsg.id); + assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); + prettyPrint(responseMsg); + + responseMsg.description = null; + responseMsg.rank = null; + responseMsg.preferredDateFormat = null; + responseMsg.toolTip = "Something new for a tooltip"; + webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); + + Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact,status:USER_OVERRIDDEN").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("Slack.com Compact Notification", responseAfterEdit.description); + assertEquals("slack.com-compact", responseAfterEdit.id); + assertEquals("", responseAfterEdit.preferredDateFormat); + assertEquals("Something new for a tooltip", responseAfterEdit.toolTip); + assertEquals(TemplateState.USER_OVERRIDDEN.toString(), responseAfterEdit.status); + + prettyPrint(responseAfterEdit); + } + + @Test + public void testDefaultTemplateDiff() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/templateItems/id:1").queryParam("fields","id,content,parentTemplateDescription,parentTemplate,editable").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + + assertEquals("slack.com-compact", responseMsg.parentTemplate.getId()); + prettyPrint(responseMsg); + + responseMsg.id= "_new"; + responseMsg.setBuildStates(new ArrayList()); + + Template.TemplateItem responseMsg2 = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(Template.TemplateItem.class, responseMsg); + prettyPrint(responseMsg2); + + String responsePatch = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact,status:PROVIDED/templateItems/id:1/templateContent/diff/id:slack.com-compact,status:USER_OVERRIDDEN/templateItems/id:2/templateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); + + System.out.println("################################"); + System.out.println(responsePatch); + + } + + @Test + public void testEditTemplateFromEmptyTemplateUsingSlackCompactTemplateAndRequestAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = new Template(); + responseMsg.id = "slack.com-compact"; + webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Template.class, responseMsg); + + Template responseAfterEdit = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("Slack.com Compact Notification", responseAfterEdit.description); + assertEquals("slack.com-compact", responseAfterEdit.id); + assertEquals("", responseAfterEdit.preferredDateFormat); + assertEquals("POSTs a very compact slack.com notification", responseAfterEdit.toolTip); + prettyPrint(responseAfterEdit); + } + + @Test(expected=UniformInterfaceException.class) + public void testChangeExistingTemplateIdCausesExceptionAsJson() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").queryParam("fields","$short").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals("slack.com-compact", responseMsg.id); + prettyPrint(responseMsg); + + responseMsg.id = "newDescription"; + try { + webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/patch").accept(MediaType.APPLICATION_JSON_TYPE).post(Response.class, responseMsg); + } catch (UniformInterfaceException ex) { + assertEquals(422, ex.getResponse().getStatus()); + throw ex; + } + } + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/RelocateNewTemplateTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/RelocateNewTemplateTest.java new file mode 100644 index 00000000..02455810 --- /dev/null +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/RelocateNewTemplateTest.java @@ -0,0 +1,77 @@ +package webhook.teamcity.server.rest.request; + +import static org.junit.Assert.*; +import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; + +import javax.ws.rs.core.MediaType; + + +import org.junit.Before; +import org.junit.Test; + +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookPayloadTemplate; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.payload.template.ElasticSearchXmlWebHookTemplate; +import webhook.teamcity.server.rest.model.template.Template; +import webhook.teamcity.server.rest.model.template.Template.TemplateItem; +import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; +import webhook.teamcity.server.rest.model.template.Templates; + +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.LoggingFilter; + +import org.springframework.beans.factory.annotation.Autowired; + +public class RelocateNewTemplateTest extends WebHookAbstractSpringAwareJerseyTest { + + @Autowired + WebHookTemplateManager webHookTemplateManager; + + @Autowired + WebHookPayloadManager webHookPayloadManager; + + @Autowired + WebHookTemplateJaxHelper webHookTemplateJaxHelper; + + WebResource webResource; + + @Before + public void setup(){ + webResource = resource(); + webResource.addFilter(new LoggingFilter(System.out)); + } + + @Test + public void testCreateTemplateByRequestingAnExistingTemplateAndThenSubmittingItWithANewTemplateNameTheRelocatingIt() { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + WebResource webResource = resource(); + + Template templateResponse = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").queryParam("fields","**").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertTrue(templateResponse.getTemplates().size() == 1); + + templateResponse.id ="newElastic"; + + webResource.path(API_TEMPLATES_URL + "/TestProject").accept(MediaType.APPLICATION_JSON_TYPE).post(templateResponse); + + Template createdTemplateResponse = webResource.path(API_TEMPLATES_URL + "/id:newElastic").queryParam("fields","**").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + prettyPrint(createdTemplateResponse); + assertTrue(createdTemplateResponse.getTemplates().size() == 1); + assertTrue(createdTemplateResponse.defaultTemplate.getTemplateText() != null); + assertFalse(createdTemplateResponse.defaultTemplate.getTemplateText().content.isEmpty()); + assertTrue(createdTemplateResponse.defaultTemplate.getBranchTemplateText() != null); + assertFalse(createdTemplateResponse.defaultTemplate.getBranchTemplateText().content.isEmpty()); + + createdTemplateResponse.projectId = "_Root"; + webResource.path(API_TEMPLATES_URL + "/id:newElastic").accept(MediaType.APPLICATION_JSON_TYPE).put(Template.class, createdTemplateResponse); + + Template relocatedTemplateResponse = webResource.path(API_TEMPLATES_URL + "/id:newElastic").queryParam("fields","**").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + prettyPrint(relocatedTemplateResponse); + assertEquals("_Root", relocatedTemplateResponse.projectId); + + } +} \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/ViewExistingTemplateTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/ViewExistingTemplateTest.java index 2c493004..a77cca30 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/ViewExistingTemplateTest.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/ViewExistingTemplateTest.java @@ -1,384 +1,383 @@ -package webhook.teamcity.server.rest.request; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertTrue; -import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; - -import java.io.FileNotFoundException; - -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.xml.bind.JAXBException; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import com.sun.jersey.api.client.UniformInterfaceException; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.filter.LoggingFilter; - -import webhook.teamcity.BuildStateEnum; -import webhook.teamcity.payload.WebHookPayloadManager; -import webhook.teamcity.payload.WebHookPayloadTemplate; -import webhook.teamcity.payload.WebHookTemplateManager; -import webhook.teamcity.payload.WebHookTemplateManager.TemplateState; -import webhook.teamcity.payload.template.ElasticSearchXmlWebHookTemplate; -import webhook.teamcity.payload.template.FlowdockXmlWebHookTemplate; -import webhook.teamcity.payload.template.SlackComCompactXmlWebHookTemplate; -import webhook.teamcity.server.rest.model.template.Template; -import webhook.teamcity.server.rest.model.template.Template.WebHookTemplateStateRest; -import webhook.teamcity.server.rest.model.template.Templates; -import webhook.teamcity.settings.config.WebHookTemplateConfig; -import webhook.teamcity.settings.config.builder.WebHookTemplateConfigBuilder; -import webhook.teamcity.settings.entity.WebHookTemplateEntity; -import webhook.teamcity.settings.entity.WebHookTemplateEntity.WebHookTemplateItem; -import webhook.teamcity.settings.entity.WebHookTemplateEntity.WebHookTemplateState; -import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; -import webhook.teamcity.settings.entity.WebHookTemplates; - -public class ViewExistingTemplateTest extends WebHookAbstractSpringAwareJerseyTest { - - @Autowired - WebHookTemplateManager webHookTemplateManager; - - @Autowired - WebHookPayloadManager webHookPayloadManager; - - @Autowired - WebHookTemplateJaxHelper webHookTemplateJaxHelper; - - WebResource webResource; - - @Before - public void setup(){ - webResource = resource(); - webResource.addFilter(new LoggingFilter(System.out)); - } - - @Test - public void testXmlTemplatesRequest() { - WebResource webResource = resource(); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_XML_TYPE).get(Templates.class); - assertEquals(0, (int)responseMsg.count); - } - - @Test - public void testJsonTemplatesRequest() { - WebResource webResource = resource(); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertEquals(0, (int)responseMsg.count); - } - - @Test - public void testJsonTemplatesRequestUsingRegisteredTemplate() throws FileNotFoundException, JAXBException { - - WebResource webResource = resource(); - WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); - WebHookTemplateConfig templateEntity = WebHookTemplateConfigBuilder.buildConfig(templatesList.getWebHookTemplateList().get(0)); - webHookTemplateManager.registerTemplateFormatFromXmlConfig(templateEntity); - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - - prettyPrint(responseMsg); - - assertEquals(1, (int)responseMsg.count); - assertEquals(1, responseMsg.getTemplateList().size()); - } - - @Test - public void testJsonTemplatesRequestUsingLotsOfRegisteredTemplates() throws FileNotFoundException, JAXBException { - - WebResource webResource = resource(); - WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); - for (WebHookTemplateEntity templateEntity : templatesList.getWebHookTemplateList()){ - webHookTemplateManager.registerTemplateFormatFromXmlEntity(templateEntity); - } - Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); - assertEquals(3, (int)responseMsg.count); - assertEquals(3, responseMsg.getTemplateList().size()); - - prettyPrint(responseMsg); - } - - @Test(expected=UniformInterfaceException.class) - public void testJsonTemplateNotFoundWhenProvidedRequested() throws FileNotFoundException, JAXBException { - - WebResource webResource = resource(); - WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); - assertEquals("There should be 3 templates loaded from file", 3, templatesList.getWebHookTemplateList().size()); - - for (WebHookTemplateEntity templateEntity : templatesList.getWebHookTemplateList()){ - webHookTemplateManager.registerTemplateFormatFromXmlEntity(templateEntity); - } - - try { - webResource.path(API_TEMPLATES_URL + "/id:testXMLtemplate,status:PROVIDED").queryParam("fields","$long").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - } catch (UniformInterfaceException ex) { - // I've not figured out how to invoke the exception handler, so "NotFoundException" returns 500 - // in Grizzly tests. - assertEquals(500, ex.getResponse().getStatus()); - throw ex; - } - - } - - @Test - public void testJsonTemplatesRequestUsingLotsOfRegisteredTemplatesButOnlyReturningOne() throws FileNotFoundException, JAXBException { - - WebResource webResource = resource(); - WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); - assertEquals("There should be 3 templates loaded from file", 3, templatesList.getWebHookTemplateList().size()); - - for (WebHookTemplateEntity templateEntity : templatesList.getWebHookTemplateList()){ - webHookTemplateManager.registerTemplateFormatFromXmlEntity(templateEntity); - } - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:testXMLtemplate").queryParam("fields","$long").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals(1, responseMsg.getTemplates().size()); - assertEquals("testXMLtemplate", responseMsg.id); - - prettyPrint(responseMsg); - } - - @Test - public void testJsonTemplatesRequestUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals(1, responseMsg.getTemplates().size()); - assertEquals("elasticsearch", responseMsg.id); - assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); - prettyPrint(responseMsg); - } - - @Test - public void testJsonTemplatesRequestTemplateContentUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - String responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1/templateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); - assertEquals(elastic.getTemplateForState(BuildStateEnum.BUILD_FIXED).getTemplateText(), responseMsg); - prettyPrint(responseMsg); - - responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1/branchTemplateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); - assertEquals(elastic.getBranchTemplateForState(BuildStateEnum.BUILD_FIXED).getTemplateText(), responseMsg); - prettyPrint(responseMsg); - } - - @Test - public void testJsonTemplatesRequestDefaultTemplateContentUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - String responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate/templateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); - assertEquals(elastic.getTemplateForState(BuildStateEnum.BUILD_STARTED).getTemplateText(), responseMsg); - prettyPrint(responseMsg); - - responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate/branchTemplateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); - assertEquals(elastic.getBranchTemplateForState(BuildStateEnum.BUILD_STARTED).getTemplateText(), responseMsg); - prettyPrint(responseMsg); - } - - @Test - public void testJsonTemplatesRequestTemplateItemUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1").queryParam("fields","id,content").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - for (WebHookTemplateItem templateItem : elastic.getAsEntity().getTemplates().getTemplates()) { - if (Integer.valueOf(responseMsg.id) == templateItem.getId()){ - assertEquals(templateItem.getTemplateText().getTemplateContent(), responseMsg.getTemplateText().content); - } - } - prettyPrint(responseMsg); - - } - - @Test - public void testJsonTemplatesRequestTemplateUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").queryParam("fields","$long").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals(1, responseMsg.getTemplates().size()); - assertEquals("elasticsearch", responseMsg.id); - prettyPrint(responseMsg); - } - - @Test - public void testJsonTemplatesRequestTemplateUsingElasticTemplateShort() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").queryParam("fields","$short,templateItem").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - assertEquals(1, responseMsg.getTemplates().size()); - assertEquals("elasticsearch", responseMsg.id); - prettyPrint(responseMsg); - } - - @Test - public void testJsonTemplatesRequestTemplateItemForDefaultTemplateUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); //.queryParam("fields","id,content,parentTemplateDescription,parentTemplateName") - assertEquals("defaultTemplate", responseMsg.getId()); - prettyPrint(responseMsg); - - } - - @Test - public void testJsonTemplatesRequestTemplateItemWithParentNameAndDescriptionUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1").queryParam("fields","id,content,parentTemplate,parentTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); - boolean itemFound=false; - for (WebHookTemplateItem templateItem : elastic.getAsEntity().getTemplates().getTemplates()) { - if (Integer.valueOf(responseMsg.id) == templateItem.getId()){ - assertEquals(templateItem.getTemplateText().getTemplateContent(), responseMsg.getTemplateText().content); - assertEquals(elastic.getTemplateDescription(), responseMsg.parentTemplate.getDescription()); - assertEquals(elastic.getTemplateId(), responseMsg.parentTemplate.getId()); - itemFound = true; - } - } - assertTrue(itemFound); - prettyPrint(responseMsg); - - } - - @Test - public void testJsonTemplatesRequestBuildStateUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - - for (WebHookTemplateItem item : elastic.getAsEntity().getTemplates().getTemplates()){ - for (BuildStateEnum state : BuildStateEnum.getNotifyStates()){ - WebHookTemplateStateRest responseMsg = webResource.path(API_TEMPLATES_URL + - "/id:" + elastic.getTemplateId() + - "/templateItems/id:" + item.getId() + - "/buildStates/" + state.getShortName() - ) - .accept(MediaType.APPLICATION_JSON_TYPE) - .get(WebHookTemplateStateRest.class); - prettyPrint(responseMsg); - for (WebHookTemplateState templateState: item.getStates()){ - if (templateState.getType().equals(state.getShortName())){ - assertEquals(templateState.isEnabled(), responseMsg.isEnabled()); - assertEquals(templateState.getType(), responseMsg.getType()); - } - } - } - } - } - - @Test - public void testJsonTemplatesRequestDefaultBuildStateUsingElasticTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - elastic.register(); - - - for (WebHookTemplateItem item : elastic.getAsEntity().getTemplates().getTemplates()){ - for (BuildStateEnum state : BuildStateEnum.getNotifyStates()){ - WebHookTemplateStateRest responseMsg = webResource.path(API_TEMPLATES_URL + - "/id:" + elastic.getTemplateId() + - "/templateItems/id:defaultTemplate" + - "/buildStates/" + state.getShortName() - ) - .accept(MediaType.APPLICATION_JSON_TYPE) - .get(WebHookTemplateStateRest.class); - prettyPrint(responseMsg); - for (WebHookTemplateState templateState: item.getStates()){ - if (templateState.getType().equals(state.getShortName())){ - assertThat(templateState.isEnabled(), not(equalTo(responseMsg.isEnabled()))); - assertEquals(templateState.getType(), responseMsg.getType()); - assertEquals(false, responseMsg.getEditable()); - } - } - } - } - } - - @Test - public void testJsonTemplatesRequestBuildStateUsingFlowdockTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate flowdock = new FlowdockXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - flowdock.register(); - - - for (WebHookTemplateItem item : flowdock.getAsEntity().getTemplates().getTemplates()){ - for (BuildStateEnum state : BuildStateEnum.getNotifyStates()){ - WebHookTemplateStateRest responseMsg = webResource.path(API_TEMPLATES_URL + - "/id:" + flowdock.getTemplateId() + - "/templateItems/id:" + item.getId() + - "/buildStates/" + state.getShortName() - ) - .accept(MediaType.APPLICATION_JSON_TYPE) - .get(WebHookTemplateStateRest.class); - prettyPrint(responseMsg); - for (WebHookTemplateState templateState: item.getStates()){ - if (templateState.getType().equals(state.getShortName())){ - assertEquals(templateState.isEnabled(), responseMsg.isEnabled()); - assertEquals(templateState.getType(), responseMsg.getType()); - } - } - } - } - } - - - @Test - public void testJsonTemplatesRequestUsingSlackCompactTemplate() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); - - assertEquals(5, responseMsg.getTemplates().size()); - assertEquals("slack.com-compact", responseMsg.id); - prettyPrint(responseMsg); - } - - @Test - public void testJsonTemplatesRequestUsingSlackCompactTemplateAndRequestAsXml() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_XML_TYPE).get(Template.class); - - assertEquals(5, responseMsg.getTemplates().size()); - assertEquals("slack.com-compact", responseMsg.id); - //prettyPrint(responseMsg); - } - - @Test - public void testFullJsonTemplatesRequestUsingSlackCompactTemplateAndRequestAsXml() throws FileNotFoundException, JAXBException { - - WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper); - slackCompact.register(); - - WebHookTemplateConfig responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/fullConfig").accept(MediaType.APPLICATION_XML_TYPE).get(WebHookTemplateConfig.class); - - assertEquals(5, responseMsg.getTemplates().getTemplates().size()); - assertEquals("slack.com-compact", responseMsg.getId()); - //prettyPrint(responseMsg); - } - - +package webhook.teamcity.server.rest.request; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertTrue; +import static webhook.teamcity.server.rest.request.TemplateRequest.API_TEMPLATES_URL; + +import java.io.FileNotFoundException; + +import javax.ws.rs.core.MediaType; +import javax.xml.bind.JAXBException; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.LoggingFilter; + +import webhook.teamcity.BuildStateEnum; +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookPayloadTemplate; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.payload.WebHookTemplateManager.TemplateState; +import webhook.teamcity.payload.template.ElasticSearchXmlWebHookTemplate; +import webhook.teamcity.payload.template.FlowdockXmlWebHookTemplate; +import webhook.teamcity.payload.template.SlackComCompactXmlWebHookTemplate; +import webhook.teamcity.server.rest.model.template.Template; +import webhook.teamcity.server.rest.model.template.Template.WebHookTemplateStateRest; +import webhook.teamcity.server.rest.model.template.Templates; +import webhook.teamcity.settings.config.WebHookTemplateConfig; +import webhook.teamcity.settings.config.builder.WebHookTemplateConfigBuilder; +import webhook.teamcity.settings.entity.WebHookTemplateEntity; +import webhook.teamcity.settings.entity.WebHookTemplateEntity.WebHookTemplateItem; +import webhook.teamcity.settings.entity.WebHookTemplateEntity.WebHookTemplateState; +import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; +import webhook.teamcity.settings.entity.WebHookTemplates; + +public class ViewExistingTemplateTest extends WebHookAbstractSpringAwareJerseyTest { + + @Autowired + WebHookTemplateManager webHookTemplateManager; + + @Autowired + WebHookPayloadManager webHookPayloadManager; + + @Autowired + WebHookTemplateJaxHelper webHookTemplateJaxHelper; + + WebResource webResource; + + @Before + public void setup(){ + webResource = resource(); + webResource.addFilter(new LoggingFilter(System.out)); + } + + @Test + public void testXmlTemplatesRequest() { + WebResource webResource = resource(); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_XML_TYPE).get(Templates.class); + assertEquals(0, (int)responseMsg.count); + } + + @Test + public void testJsonTemplatesRequest() { + WebResource webResource = resource(); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertEquals(0, (int)responseMsg.count); + } + + @Test + public void testJsonTemplatesRequestUsingRegisteredTemplate() throws FileNotFoundException, JAXBException { + + WebResource webResource = resource(); + WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); + WebHookTemplateConfig templateEntity = WebHookTemplateConfigBuilder.buildConfig(templatesList.getWebHookTemplateList().get(0)); + webHookTemplateManager.registerTemplateFormatFromXmlConfig(templateEntity); + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + + prettyPrint(responseMsg); + + assertEquals(1, (int)responseMsg.count); + assertEquals(1, responseMsg.getTemplateList().size()); + } + + @Test + public void testJsonTemplatesRequestUsingLotsOfRegisteredTemplates() throws FileNotFoundException, JAXBException { + + WebResource webResource = resource(); + WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); + for (WebHookTemplateEntity templateEntity : templatesList.getWebHookTemplateList()){ + webHookTemplateManager.registerTemplateFormatFromXmlEntity(templateEntity); + } + Templates responseMsg = webResource.path(API_TEMPLATES_URL).accept(MediaType.APPLICATION_JSON_TYPE).get(Templates.class); + assertEquals(3, (int)responseMsg.count); + assertEquals(3, responseMsg.getTemplateList().size()); + + prettyPrint(responseMsg); + } + + @Test(expected=UniformInterfaceException.class) + public void testJsonTemplateNotFoundWhenProvidedRequested() throws FileNotFoundException, JAXBException { + + WebResource webResource = resource(); + WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); + assertEquals("There should be 3 templates loaded from file", 3, templatesList.getWebHookTemplateList().size()); + + for (WebHookTemplateEntity templateEntity : templatesList.getWebHookTemplateList()){ + webHookTemplateManager.registerTemplateFormatFromXmlEntity(templateEntity); + } + + try { + webResource.path(API_TEMPLATES_URL + "/id:testXMLtemplate,status:PROVIDED").queryParam("fields","$long").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + } catch (UniformInterfaceException ex) { + // I've not figured out how to invoke the exception handler, so "NotFoundException" returns 500 + // in Grizzly tests. + assertEquals(500, ex.getResponse().getStatus()); + throw ex; + } + + } + + @Test + public void testJsonTemplatesRequestUsingLotsOfRegisteredTemplatesButOnlyReturningOne() throws FileNotFoundException, JAXBException { + + WebResource webResource = resource(); + WebHookTemplates templatesList = webHookTemplateJaxHelper.readTemplates("../tcwebhooks-core/src/test/resources/webhook-templates.xml"); + assertEquals("There should be 3 templates loaded from file", 3, templatesList.getWebHookTemplateList().size()); + + for (WebHookTemplateEntity templateEntity : templatesList.getWebHookTemplateList()){ + webHookTemplateManager.registerTemplateFormatFromXmlEntity(templateEntity); + } + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:testXMLtemplate").queryParam("fields","$long").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals(1, responseMsg.getTemplates().size()); + assertEquals("testXMLtemplate", responseMsg.id); + + prettyPrint(responseMsg); + } + + @Test + public void testJsonTemplatesRequestUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals(1, responseMsg.getTemplates().size()); + assertEquals("elasticsearch", responseMsg.id); + assertEquals(TemplateState.PROVIDED.toString(), responseMsg.status); + prettyPrint(responseMsg); + } + + @Test + public void testJsonTemplatesRequestTemplateContentUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + String responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1/templateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); + assertEquals(elastic.getTemplateForState(BuildStateEnum.BUILD_FIXED).getTemplateText(), responseMsg); + prettyPrint(responseMsg); + + responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1/branchTemplateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); + assertEquals(elastic.getBranchTemplateForState(BuildStateEnum.BUILD_FIXED).getTemplateText(), responseMsg); + prettyPrint(responseMsg); + } + + @Test + public void testJsonTemplatesRequestDefaultTemplateContentUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + String responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate/templateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); + assertEquals(elastic.getTemplateForState(BuildStateEnum.BUILD_STARTED).getTemplateText(), responseMsg); + prettyPrint(responseMsg); + + responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate/branchTemplateContent").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); + assertEquals(elastic.getBranchTemplateForState(BuildStateEnum.BUILD_STARTED).getTemplateText(), responseMsg); + prettyPrint(responseMsg); + } + + @Test + public void testJsonTemplatesRequestTemplateItemUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1").queryParam("fields","id,content").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + for (WebHookTemplateItem templateItem : elastic.getAsEntity().getTemplates().getTemplates()) { + if (Integer.valueOf(responseMsg.id) == templateItem.getId()){ + assertEquals(templateItem.getTemplateText().getTemplateContent(), responseMsg.getTemplateText().content); + } + } + prettyPrint(responseMsg); + + } + + @Test + public void testJsonTemplatesRequestTemplateUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").queryParam("fields","$long").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals(1, responseMsg.getTemplates().size()); + assertEquals("elasticsearch", responseMsg.id); + prettyPrint(responseMsg); + } + + @Test + public void testJsonTemplatesRequestTemplateUsingElasticTemplateShort() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch").queryParam("fields","$short,templateItem").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + assertEquals(1, responseMsg.getTemplates().size()); + assertEquals("elasticsearch", responseMsg.id); + prettyPrint(responseMsg); + } + + @Test + public void testJsonTemplatesRequestTemplateItemForDefaultTemplateUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/defaultTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); //.queryParam("fields","id,content,parentTemplateDescription,parentTemplateName") + assertEquals("defaultTemplate", responseMsg.getId()); + prettyPrint(responseMsg); + + } + + @Test + public void testJsonTemplatesRequestTemplateItemWithParentNameAndDescriptionUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + Template.TemplateItem responseMsg = webResource.path(API_TEMPLATES_URL + "/id:elasticsearch/templateItems/id:1").queryParam("fields","id,content,parentTemplate,parentTemplate").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.TemplateItem.class); + boolean itemFound=false; + for (WebHookTemplateItem templateItem : elastic.getAsEntity().getTemplates().getTemplates()) { + if (Integer.valueOf(responseMsg.id) == templateItem.getId()){ + assertEquals(templateItem.getTemplateText().getTemplateContent(), responseMsg.getTemplateText().content); + assertEquals(elastic.getTemplateDescription(), responseMsg.parentTemplate.getDescription()); + assertEquals(elastic.getTemplateId(), responseMsg.parentTemplate.getId()); + itemFound = true; + } + } + assertTrue(itemFound); + prettyPrint(responseMsg); + + } + + @Test + public void testJsonTemplatesRequestBuildStateUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + + for (WebHookTemplateItem item : elastic.getAsEntity().getTemplates().getTemplates()){ + for (BuildStateEnum state : BuildStateEnum.getNotifyStates()){ + WebHookTemplateStateRest responseMsg = webResource.path(API_TEMPLATES_URL + + "/id:" + elastic.getTemplateId() + + "/templateItems/id:" + item.getId() + + "/buildStates/" + state.getShortName() + ) + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(WebHookTemplateStateRest.class); + prettyPrint(responseMsg); + for (WebHookTemplateState templateState: item.getStates()){ + if (templateState.getType().equals(state.getShortName())){ + assertEquals(templateState.isEnabled(), responseMsg.isEnabled()); + assertEquals(templateState.getType(), responseMsg.getType()); + } + } + } + } + } + + @Test + public void testJsonTemplatesRequestDefaultBuildStateUsingElasticTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate elastic = new ElasticSearchXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + elastic.register(); + + + for (WebHookTemplateItem item : elastic.getAsEntity().getTemplates().getTemplates()){ + for (BuildStateEnum state : BuildStateEnum.getNotifyStates()){ + WebHookTemplateStateRest responseMsg = webResource.path(API_TEMPLATES_URL + + "/id:" + elastic.getTemplateId() + + "/templateItems/id:defaultTemplate" + + "/buildStates/" + state.getShortName() + ) + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(WebHookTemplateStateRest.class); + prettyPrint(responseMsg); + for (WebHookTemplateState templateState: item.getStates()){ + if (templateState.getType().equals(state.getShortName())){ + assertThat(templateState.isEnabled(), not(equalTo(responseMsg.isEnabled()))); + assertEquals(templateState.getType(), responseMsg.getType()); + assertEquals(false, responseMsg.getEditable()); + } + } + } + } + } + + @Test + public void testJsonTemplatesRequestBuildStateUsingFlowdockTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate flowdock = new FlowdockXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + flowdock.register(); + + + for (WebHookTemplateItem item : flowdock.getAsEntity().getTemplates().getTemplates()){ + for (BuildStateEnum state : BuildStateEnum.getNotifyStates()){ + WebHookTemplateStateRest responseMsg = webResource.path(API_TEMPLATES_URL + + "/id:" + flowdock.getTemplateId() + + "/templateItems/id:" + item.getId() + + "/buildStates/" + state.getShortName() + ) + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(WebHookTemplateStateRest.class); + prettyPrint(responseMsg); + for (WebHookTemplateState templateState: item.getStates()){ + if (templateState.getType().equals(state.getShortName())){ + assertEquals(templateState.isEnabled(), responseMsg.isEnabled()); + assertEquals(templateState.getType(), responseMsg.getType()); + } + } + } + } + } + + + @Test + public void testJsonTemplatesRequestUsingSlackCompactTemplate() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_JSON_TYPE).get(Template.class); + + assertEquals(5, responseMsg.getTemplates().size()); + assertEquals("slack.com-compact", responseMsg.id); + prettyPrint(responseMsg); + } + + @Test + public void testJsonTemplatesRequestUsingSlackCompactTemplateAndRequestAsXml() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + Template responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact").accept(MediaType.APPLICATION_XML_TYPE).get(Template.class); + + assertEquals(5, responseMsg.getTemplates().size()); + assertEquals("slack.com-compact", responseMsg.id); + //prettyPrint(responseMsg); + } + + @Test + public void testFullJsonTemplatesRequestUsingSlackCompactTemplateAndRequestAsXml() throws FileNotFoundException, JAXBException { + + WebHookPayloadTemplate slackCompact = new SlackComCompactXmlWebHookTemplate(webHookTemplateManager, webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver, null); + slackCompact.register(); + + WebHookTemplateConfig responseMsg = webResource.path(API_TEMPLATES_URL + "/id:slack.com-compact/fullConfig").accept(MediaType.APPLICATION_XML_TYPE).get(WebHookTemplateConfig.class); + + assertEquals(5, responseMsg.getTemplates().getTemplates().size()); + assertEquals("slack.com-compact", responseMsg.getId()); + //prettyPrint(responseMsg); + } + + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/WebHookAbstractSpringAwareJerseyTest.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/WebHookAbstractSpringAwareJerseyTest.java index f5a8f394..8cbe3e8c 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/WebHookAbstractSpringAwareJerseyTest.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/server/rest/request/WebHookAbstractSpringAwareJerseyTest.java @@ -14,8 +14,12 @@ import com.sun.jersey.test.framework.JerseyTest; import com.sun.jersey.test.framework.WebAppDescriptor; +import webhook.teamcity.ProjectIdResolver; + public class WebHookAbstractSpringAwareJerseyTest extends AbstractSpringAwareJerseyTest { + ProjectIdResolver projectIdResolver; + public WebHookAbstractSpringAwareJerseyTest() { super(new WebAppDescriptor.Builder("webhook.teamcity.test.jerseyprovider", "webhook.teamcity.server.rest.errors", "webhook.teamcity.server.rest.request", "webhook.teamcity.server.rest.model", "webhook.teamcity.settings") .contextPath("testing") @@ -37,6 +41,18 @@ public void prettyPrint(Object responseMsg){ @Override public final void setUp() throws Exception { super.setUp(); + projectIdResolver = new ProjectIdResolver() { + + @Override + public String getInternalProjectId(String externalProjectId) { + return "_Root"; + } + + @Override + public String getExternalProjectId(String internalProjectId) { + return "project0"; + } + }; } /** diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/DataProviderTestContextProvider.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/DataProviderTestContextProvider.java index fd81300f..06ba68c3 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/DataProviderTestContextProvider.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/DataProviderTestContextProvider.java @@ -1,89 +1,104 @@ -package webhook.teamcity.test.jerseyprovider; - -import static org.mockito.Mockito.mock; - -import java.lang.reflect.Type; - -import javax.ws.rs.core.Context; -import javax.ws.rs.ext.Provider; - -import org.springframework.web.context.ContextLoader; - -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import jetbrains.buildServer.RootUrlHolder; -import jetbrains.buildServer.server.rest.data.PermissionChecker; -import jetbrains.buildServer.serverSide.ProjectManager; -import jetbrains.buildServer.serverSide.SBuildServer; -import webhook.teamcity.payload.WebHookPayloadManager; -import webhook.teamcity.payload.WebHookTemplateManager; -import webhook.teamcity.server.rest.data.DataProvider; -import webhook.teamcity.server.rest.data.TemplateFinder; -import webhook.teamcity.server.rest.data.WebHookFinder; -import webhook.teamcity.server.rest.request.Constants; -import webhook.teamcity.server.rest.util.webhook.WebHookManager; -import webhook.teamcity.test.springmock.MockProjectManager; - -@Provider -public class DataProviderTestContextProvider implements InjectableProvider, Injectable { - private DataProvider dataProvider; - private final SBuildServer sBuildServer; - private final PermissionChecker permissionChecker; - private final ProjectManager projectManager; - private TemplateFinder templateFinder; - private WebHookPayloadManager payloadManager; - @Context WebHookTemplateManager templateManager; - private WebHookManager webHookManager; - private WebHookFinder webHookFinder; - - - public DataProviderTestContextProvider() { - System.out.println("We are here: Trying to provide a testable DataProvider instance"); - sBuildServer = mock(SBuildServer.class); - permissionChecker = mock(PermissionChecker.class); - projectManager = new MockProjectManager(); - //templateFinder = mock(TemplateFinder.class); - } - - public ComponentScope getScope() { - return ComponentScope.Singleton; - } - - public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { - if (type.equals(DataProvider.class)) { - return this; - } - return null; - } - - public DataProvider getValue() { - if (dataProvider != null){ - return dataProvider; - } - payloadManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookPayloadManager.class); - templateFinder = ContextLoader.getCurrentWebApplicationContext().getBean(TemplateFinder.class); - webHookManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookManager.class); - webHookFinder = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookFinder.class); - - dataProvider = new DataProvider(sBuildServer, new TestUrlHolder(), permissionChecker, payloadManager, templateManager, templateFinder, projectManager, webHookManager, webHookFinder); - return dataProvider; - } - - public static class TestUrlHolder implements RootUrlHolder { - String url = Constants.API_URL; - - @Override - public void setRootUrl(String rootUrl) { - this.url = rootUrl; - - } - - @Override - public String getRootUrl() { - return url; - } - } +package webhook.teamcity.test.jerseyprovider; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.eq; + +import java.lang.reflect.Type; + +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Provider; + +import org.springframework.web.context.ContextLoader; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import jetbrains.buildServer.RootUrlHolder; +import jetbrains.buildServer.server.rest.data.PermissionChecker; +import jetbrains.buildServer.serverSide.ProjectManager; +import jetbrains.buildServer.serverSide.SBuildServer; +import jetbrains.buildServer.serverSide.SecurityContextEx; +import jetbrains.buildServer.serverSide.auth.AuthorityHolder; +import jetbrains.buildServer.serverSide.auth.Permission; +import webhook.teamcity.ProjectIdResolver; +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.server.rest.data.DataProvider; +import webhook.teamcity.server.rest.data.TemplateFinder; +import webhook.teamcity.server.rest.data.WebHookFinder; +import webhook.teamcity.server.rest.request.Constants; +import webhook.teamcity.server.rest.util.webhook.WebHookManager; +import webhook.teamcity.test.springmock.MockProjectManager; + +@Provider +public class DataProviderTestContextProvider implements InjectableProvider, Injectable { + private DataProvider dataProvider; + private final SBuildServer sBuildServer; + private final PermissionChecker permissionChecker; + private final ProjectManager projectManager; + private TemplateFinder templateFinder; + private WebHookPayloadManager payloadManager; + @Context WebHookTemplateManager templateManager; + private WebHookManager webHookManager; + private WebHookFinder webHookFinder; + private final ProjectIdResolver projectIdResolver; + private final SecurityContextEx securityContext; + private final AuthorityHolder authorityHolder; + + + public DataProviderTestContextProvider() { + System.out.println("We are here: Trying to provide a testable DataProvider instance"); + sBuildServer = mock(SBuildServer.class); + permissionChecker = mock(PermissionChecker.class); + projectManager = new MockProjectManager(); + projectIdResolver = mock(ProjectIdResolver.class); + securityContext = mock(SecurityContextEx.class); + authorityHolder = mock(AuthorityHolder.class); + when(securityContext.getAuthorityHolder()).thenReturn(authorityHolder); + when(authorityHolder.isPermissionGrantedForAnyProject(eq(Permission.EDIT_PROJECT))).thenReturn(true); + //templateFinder = mock(TemplateFinder.class); + } + + public ComponentScope getScope() { + return ComponentScope.Singleton; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(DataProvider.class)) { + return this; + } + return null; + } + + public DataProvider getValue() { + if (dataProvider != null){ + return dataProvider; + } + payloadManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookPayloadManager.class); + templateFinder = ContextLoader.getCurrentWebApplicationContext().getBean(TemplateFinder.class); + webHookManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookManager.class); + webHookFinder = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookFinder.class); + //projectIdResolver = ContextLoader.getCurrentWebApplicationContext().getBean(ProjectIdResolver.class); + + dataProvider = new DataProvider(sBuildServer, new TestUrlHolder(), permissionChecker, payloadManager, templateManager, templateFinder, projectManager, webHookManager, webHookFinder, projectIdResolver, securityContext); + return dataProvider; + } + + public static class TestUrlHolder implements RootUrlHolder { + String url = Constants.API_URL; + + @Override + public void setRootUrl(String rootUrl) { + this.url = rootUrl; + + } + + @Override + public String getRootUrl() { + return url; + } + } } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/MockingBeanContextProvider.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/MockingBeanContextProvider.java index 3d76ff1d..325b47a8 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/MockingBeanContextProvider.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/MockingBeanContextProvider.java @@ -1,88 +1,88 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * 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 webhook.teamcity.test.jerseyprovider; - -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import java.lang.reflect.Type; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.ext.Provider; - -import org.mockito.Mock; - -import static org.mockito.Mockito.*; -import webhook.teamcity.server.rest.WebHookApiUrlBuilder; -import webhook.teamcity.server.rest.WebHookWebLinks; -import webhook.teamcity.server.rest.util.BeanContext; -import jetbrains.buildServer.ServiceLocator; -import jetbrains.buildServer.server.rest.PathTransformer; -import jetbrains.buildServer.server.rest.RequestPathTransformInfo; -import jetbrains.buildServer.server.rest.util.BeanFactory; - -/** - * @author Yegor.Yarko - * Date: 15.11.2009 - */ -@Provider -public class MockingBeanContextProvider implements InjectableProvider, Injectable { - - @Mock private RequestPathTransformInfo myRequestPathTransformInfo; - - //TODO: using request-specific field in singleton provider - //TODO: may lead to concurrency issue as this instance is - //TODO: created by spring not by Jersey! - @Context private HttpHeaders headers; - @Context private HttpServletRequest request; - - @Mock private BeanFactory myFactory; - - @Mock private ServiceLocator myServiceLocator; - - public MockingBeanContextProvider() { - System.out.println("We are here: Trying to provide a test BeanContext instance"); - myServiceLocator = mock(ServiceLocator.class); - when(myServiceLocator.getSingletonService(WebHookWebLinks.class)).thenReturn(new WebHookWebLinks(new DataProviderTestContextProvider.TestUrlHolder())); - } - - public ComponentScope getScope() { - return ComponentScope.PerRequest; - } - - public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { - if (type.equals(BeanContext.class)) { - return this; - } - return null; - } - - public BeanContext getValue() { - //return new BeanContext(myFactory, myServiceLocator, new WebHookApiUrlBuilder(new SimplePathTransformer(request, headers, myRequestPathTransformInfo))); - return new BeanContext(myFactory, myServiceLocator, new WebHookApiUrlBuilder(new PathTransformer() { - - @Override - public String transform(String path) { - return path; - } - })); - } -} +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * 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 webhook.teamcity.test.jerseyprovider; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import java.lang.reflect.Type; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.ext.Provider; + +import org.mockito.Mock; + +import static org.mockito.Mockito.*; +import webhook.teamcity.server.rest.WebHookApiUrlBuilder; +import webhook.teamcity.server.rest.WebHookWebLinks; +import webhook.teamcity.server.rest.util.BeanContext; +import jetbrains.buildServer.ServiceLocator; +import jetbrains.buildServer.server.rest.PathTransformer; +import jetbrains.buildServer.server.rest.RequestPathTransformInfo; +import jetbrains.buildServer.server.rest.util.BeanFactory; + +/** + * @author Yegor.Yarko + * Date: 15.11.2009 + */ +@Provider +public class MockingBeanContextProvider implements InjectableProvider, Injectable { + + @Mock private RequestPathTransformInfo myRequestPathTransformInfo; + + //TODO: using request-specific field in singleton provider + //TODO: may lead to concurrency issue as this instance is + //TODO: created by spring not by Jersey! + @Context private HttpHeaders headers; + @Context private HttpServletRequest request; + + @Mock private BeanFactory myFactory; + + @Mock private ServiceLocator myServiceLocator; + + public MockingBeanContextProvider() { + System.out.println("We are here: Trying to provide a test BeanContext instance"); + myServiceLocator = mock(ServiceLocator.class); + when(myServiceLocator.getSingletonService(WebHookWebLinks.class)).thenReturn(new WebHookWebLinks(new DataProviderTestContextProvider.TestUrlHolder())); + } + + public ComponentScope getScope() { + return ComponentScope.PerRequest; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(BeanContext.class)) { + return this; + } + return null; + } + + public BeanContext getValue() { + //return new BeanContext(myFactory, myServiceLocator, new WebHookApiUrlBuilder(new SimplePathTransformer(request, headers, myRequestPathTransformInfo))); + return new BeanContext(myFactory, myServiceLocator, new WebHookApiUrlBuilder(new PathTransformer() { + + @Override + public String transform(String path) { + return path; + } + })); + } +} diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/ProjectIdResolverMock.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/ProjectIdResolverMock.java new file mode 100644 index 00000000..d5985297 --- /dev/null +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/ProjectIdResolverMock.java @@ -0,0 +1,23 @@ +package webhook.teamcity.test.jerseyprovider; + +import webhook.teamcity.ProjectIdResolver; + +public class ProjectIdResolverMock implements ProjectIdResolver { + + @Override + public String getExternalProjectId(String internalProjectId) { + if (internalProjectId.equalsIgnoreCase("_Root")) { + return "_Root"; + } + return "TestProject"; + } + + @Override + public String getInternalProjectId(String externalProjectId) { + if (externalProjectId.equalsIgnoreCase("_Root")) { + return "_Root"; + } + return "project1"; + } + +} diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/TemplateValidatorTestContextProvider.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/TemplateValidatorTestContextProvider.java index 579e7d7b..2c1c0d04 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/TemplateValidatorTestContextProvider.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/TemplateValidatorTestContextProvider.java @@ -1,23 +1,61 @@ -package webhook.teamcity.test.jerseyprovider; - -import java.lang.reflect.Type; - -import javax.ws.rs.core.Context; -import javax.ws.rs.ext.Provider; - -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import webhook.teamcity.server.rest.data.TemplateValidator; -import webhook.teamcity.server.rest.jersey.TemplateValidatorProvider; - -@Provider -public class TemplateValidatorTestContextProvider extends TemplateValidatorProvider - implements InjectableProvider, Injectable { - - public TemplateValidatorTestContextProvider() { - super(); - System.out.println("We are here: Trying to provide a testable TemplateValidator instance"); - } - +package webhook.teamcity.test.jerseyprovider; + +import java.lang.reflect.Type; + +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Provider; + +import org.mockito.Mockito; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import jetbrains.buildServer.server.rest.data.PermissionChecker; +import jetbrains.buildServer.serverSide.ProjectManager; +import jetbrains.buildServer.serverSide.SProject; +import jetbrains.buildServer.serverSide.auth.Permission; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.server.rest.data.TemplateValidator; +import webhook.teamcity.server.rest.jersey.TemplateValidatorProvider; + +@Provider +public class TemplateValidatorTestContextProvider implements InjectableProvider, Injectable { + + private final TemplateValidator templateValidator; + + public TemplateValidatorTestContextProvider() { + + System.out.println("We are here: Trying to provide a testable TemplateValidator instance"); + SProject sProject = Mockito.mock(SProject.class); + SProject testProject = Mockito.mock(SProject.class); + Mockito.when(sProject.getProjectId()).thenReturn("project01"); + Mockito.when(testProject.getProjectId()).thenReturn("project1"); + WebHookTemplateManager templateManager = Mockito.mock(WebHookTemplateManager.class); + PermissionChecker permissionChecker = Mockito.mock(PermissionChecker.class); + ProjectManager projectManager = Mockito.mock(ProjectManager.class); + Mockito.when(projectManager.findProjectByExternalId(Mockito.eq("_Root"))).thenReturn(sProject); + Mockito.when(projectManager.findProjectByExternalId(Mockito.eq("TestProject"))).thenReturn(testProject); + Mockito.when(projectManager.findProjectById("project01")).thenReturn(sProject); + Mockito.when(permissionChecker.isPermissionGranted(Permission.EDIT_PROJECT, "project01")).thenReturn(true); + Mockito.when(permissionChecker.isPermissionGranted(Permission.EDIT_PROJECT, "project1")).thenReturn(true); + this.templateValidator = new TemplateValidator(templateManager, permissionChecker, projectManager); + } + + public ComponentScope getScope() { + return ComponentScope.Singleton; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(TemplateValidator.class)) { + return this; + } + return null; + } + + public TemplateValidator getValue() { + return templateValidator; + } + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookApiUrlBuilderTestContextProvider.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookApiUrlBuilderTestContextProvider.java index 949f3aaa..4c6ec9b0 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookApiUrlBuilderTestContextProvider.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookApiUrlBuilderTestContextProvider.java @@ -1,48 +1,49 @@ -package webhook.teamcity.test.jerseyprovider; - -import java.lang.reflect.Type; - -import javax.ws.rs.core.Context; -import javax.ws.rs.ext.Provider; - -import jetbrains.buildServer.server.rest.PathTransformer; -import webhook.teamcity.server.rest.WebHookApiUrlBuilder; -import webhook.teamcity.server.rest.request.Constants; - -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -@Provider -public class WebHookApiUrlBuilderTestContextProvider implements InjectableProvider, Injectable { - private final WebHookApiUrlBuilder webHookApiUrlBuilder; - - public WebHookApiUrlBuilderTestContextProvider() { - System.out.println("We are here: Trying to provide a testable WebHookApiUrlBuilder instance"); - webHookApiUrlBuilder = new WebHookApiUrlBuilder(new PathTransformer() { - - @Override - public String transform(String path) { - return Constants.API_URL + "/" + path; - } - }); - - } - - public ComponentScope getScope() { - return ComponentScope.Singleton; - } - - public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { - if (type.equals(WebHookApiUrlBuilder.class)) { - return this; - } - return null; - } - - public WebHookApiUrlBuilder getValue() { - return webHookApiUrlBuilder; - } - +package webhook.teamcity.test.jerseyprovider; + +import java.lang.reflect.Type; + +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Provider; + +import jetbrains.buildServer.server.rest.PathTransformer; +import webhook.teamcity.ProjectIdResolver; +import webhook.teamcity.server.rest.WebHookApiUrlBuilder; +import webhook.teamcity.server.rest.request.Constants; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +@Provider +public class WebHookApiUrlBuilderTestContextProvider implements InjectableProvider, Injectable { + private final WebHookApiUrlBuilder webHookApiUrlBuilder; + + public WebHookApiUrlBuilderTestContextProvider() { + System.out.println("We are here: Trying to provide a testable WebHookApiUrlBuilder instance"); + webHookApiUrlBuilder = new WebHookApiUrlBuilder(new PathTransformer() { + + @Override + public String transform(String path) { + return Constants.API_URL + "/" + path; + } + }); + + } + + public ComponentScope getScope() { + return ComponentScope.Singleton; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(WebHookApiUrlBuilder.class)) { + return this; + } + return null; + } + + public WebHookApiUrlBuilder getValue() { + return webHookApiUrlBuilder; + } + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookTemplateManagerTestProvider.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookTemplateManagerTestProvider.java index 457f509a..9444720c 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookTemplateManagerTestProvider.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/jerseyprovider/WebHookTemplateManagerTestProvider.java @@ -1,69 +1,72 @@ -package webhook.teamcity.test.jerseyprovider; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Type; - -import javax.ws.rs.core.Context; -import javax.ws.rs.ext.Provider; - -import org.springframework.web.context.ContextLoader; - -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import webhook.teamcity.payload.WebHookPayloadManager; -import webhook.teamcity.payload.WebHookTemplateManager; -import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; - -@Provider -public class WebHookTemplateManagerTestProvider implements InjectableProvider, Injectable { - WebHookTemplateManager webHookTemplateManager; - WebHookPayloadManager webHookPayloadManager; - WebHookTemplateJaxHelper webHookTemplateJaxHelper; - - public WebHookTemplateManagerTestProvider() throws IOException { - System.out.println("We are here: Trying to provide a testable WebHookTemplateManager instance"); - //webHookTemplateManager = new WebHookTemplateManager(webHookPayloadManager); - - - } - - public ComponentScope getScope() { - return ComponentScope.Singleton; - } - - public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { - if (type.equals(WebHookTemplateManager.class)) { - return this; - } - return null; - } - - public WebHookTemplateManager getValue() { - - webHookPayloadManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookPayloadManager.class); - webHookTemplateManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookTemplateManager.class); - webHookTemplateJaxHelper = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookTemplateJaxHelper.class); - - if (webHookTemplateManager != null){ - System.out.println("WebHookTemplateManagerTestProvider: Providing (existing) value " + webHookTemplateManager.toString()); - return webHookTemplateManager; - } - File tempDir; - try { - tempDir = File.createTempFile("tempWebHooksDir", "", new File("target/")); - tempDir.mkdir(); - webHookTemplateManager = new WebHookTemplateManager(webHookPayloadManager, webHookTemplateJaxHelper); - webHookTemplateManager.setConfigFilePath(tempDir.getAbsolutePath()); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - System.out.println("WebHookTemplateManagerTestProvider: Providing (new) value " + webHookTemplateManager.toString()); - return webHookTemplateManager; - } - +package webhook.teamcity.test.jerseyprovider; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; + +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Provider; + +import org.springframework.web.context.ContextLoader; + +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import webhook.teamcity.ProjectIdResolver; +import webhook.teamcity.payload.WebHookPayloadManager; +import webhook.teamcity.payload.WebHookTemplateManager; +import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper; + +@Provider +public class WebHookTemplateManagerTestProvider implements InjectableProvider, Injectable { + WebHookTemplateManager webHookTemplateManager; + WebHookPayloadManager webHookPayloadManager; + WebHookTemplateJaxHelper webHookTemplateJaxHelper; +private ProjectIdResolver projectIdResolver; + + public WebHookTemplateManagerTestProvider() throws IOException { + System.out.println("We are here: Trying to provide a testable WebHookTemplateManager instance"); + //webHookTemplateManager = new WebHookTemplateManager(webHookPayloadManager); + + + } + + public ComponentScope getScope() { + return ComponentScope.Singleton; + } + + public Injectable getInjectable(final ComponentContext ic, final Context context, final Type type) { + if (type.equals(WebHookTemplateManager.class)) { + return this; + } + return null; + } + + public WebHookTemplateManager getValue() { + + webHookPayloadManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookPayloadManager.class); + webHookTemplateManager = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookTemplateManager.class); + webHookTemplateJaxHelper = ContextLoader.getCurrentWebApplicationContext().getBean(WebHookTemplateJaxHelper.class); + projectIdResolver = ContextLoader.getCurrentWebApplicationContext().getBean(ProjectIdResolver.class); + + if (webHookTemplateManager != null){ + System.out.println("WebHookTemplateManagerTestProvider: Providing (existing) value " + webHookTemplateManager.toString()); + return webHookTemplateManager; + } + File tempDir; + try { + tempDir = File.createTempFile("tempWebHooksDir", "", new File("target/")); + tempDir.mkdir(); + webHookTemplateManager = new WebHookTemplateManager(webHookPayloadManager, webHookTemplateJaxHelper, projectIdResolver); + webHookTemplateManager.setConfigFilePath(tempDir.getAbsolutePath()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + System.out.println("WebHookTemplateManagerTestProvider: Providing (new) value " + webHookTemplateManager.toString()); + return webHookTemplateManager; + } + } \ No newline at end of file diff --git a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/springmock/MockSecurityContext.java b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/springmock/MockSecurityContext.java index 1d313947..290cd143 100644 --- a/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/springmock/MockSecurityContext.java +++ b/tcwebhooks-rest-api-legacy/src/test/java/webhook/teamcity/test/springmock/MockSecurityContext.java @@ -1,14 +1,74 @@ package webhook.teamcity.test.springmock; +import java.util.Collection; +import java.util.Map; + import jetbrains.buildServer.serverSide.auth.AuthorityHolder; +import jetbrains.buildServer.serverSide.auth.Permission; +import jetbrains.buildServer.serverSide.auth.Permissions; import jetbrains.buildServer.serverSide.auth.SecurityContext; +import jetbrains.buildServer.users.User; public class MockSecurityContext implements SecurityContext { @Override public AuthorityHolder getAuthorityHolder() { // TODO Auto-generated method stub - return null; + return new AuthorityHolder() { + + @Override + public boolean isPermissionGrantedGlobally(Permission permission) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isPermissionGrantedForProject(String projectId, Permission permission) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isPermissionGrantedForAnyProject(Permission permission) { + return true; + } + + @Override + public boolean isPermissionGrantedForAllProjects(Collection projectIds, Permission permission) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Map getProjectsPermissions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Permissions getPermissionsGrantedForProject(String projectId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Permissions getPermissionsGrantedForAllProjects(Collection projectIds) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Permissions getGlobalPermissions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public User getAssociatedUser() { + // TODO Auto-generated method stub + return null; + } + }; } } diff --git a/tcwebhooks-rest-api-legacy/src/test/resources/TestSpringContext.xml b/tcwebhooks-rest-api-legacy/src/test/resources/TestSpringContext.xml index 164b3f14..6fd2cf31 100644 --- a/tcwebhooks-rest-api-legacy/src/test/resources/TestSpringContext.xml +++ b/tcwebhooks-rest-api-legacy/src/test/resources/TestSpringContext.xml @@ -102,5 +102,9 @@ + + \ No newline at end of file