@Test
  public void shouldGetConfigAsXml() throws Exception {
    configHelper.addPipeline("pipeline", "stage", "build1", "build2");

    controller.getCurrentConfigXml(null, response);
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    new MagicalGoConfigXmlWriter(new ConfigCache(), registry, metricsProbeService)
        .write(goConfigDao.loadForEditing(), os, true);
    assertValidContentAndStatus(SC_OK, "text/xml", os.toString());
    assertThat(
        response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(goConfigDao.md5OfConfigFile()));
  }
  @Test
  public void shouldReturnConflictIfGetRequestUsesIncorrectConfigMD5() throws Exception {
    String oldMd5 = goConfigDao.md5OfConfigFile();

    configHelper.addPipeline("pipeline", "stage", "build1", "build2");

    String newMd5 = goConfigDao.md5OfConfigFile();

    controller.getBuildAsXmlPartial("pipeline", "stage", 1, oldMd5, response);
    assertValidContentAndStatus(
        SC_CONFLICT, RESPONSE_CHARSET, ConfigFileHasChangedException.CONFIG_CHANGED_PLEASE_REFRESH);
    assertThat(response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(newMd5));
  }
 @Test
 public void shouldReturnXmlAndErrorMessageWhenPostOfPipelineAsInvalidPartialXml()
     throws Exception {
   groupName = BasicPipelineConfigs.DEFAULT_GROUP;
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String badXml =
       "<pipeline name=\"cruise\" labeltemplate=\"invalid\">\n"
           + "  <materials>\n"
           + "    <svn url=\"file:///tmp/foo\" checkexternals=\"true\" />\n"
           + "  </materials>\n"
           + "  <stage name=\"dev\">\n"
           + "    <jobs>\n"
           + "      <job name=\"linux\" />\n"
           + "      <job name=\"windows\" />\n"
           + "    </jobs>\n"
           + "  </stage>\n"
           + "</pipeline>";
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav = controller.postPipelineAsXmlPartial(0, groupName, badXml, md5, response);
   assertThat(response.getStatus(), is(SC_CONFLICT));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map<String, String> json = (Map) mav.getModel().get("json");
   assertThat(json.get("result").toString(), containsString("Label is invalid"));
   assertThat(json.get("originalContent"), is(badXml));
 }
  @Test
  public void shouldConflictWhenGivenMd5IsDifferent() throws Exception {
    configHelper.addPipeline("pipeline", "stage", "build1", "build2");

    controller.getCurrentConfigXml("crapy_md5", response);
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    new MagicalGoConfigXmlWriter(
            new ConfigCache(),
            ConfigElementImplementationRegistryMother.withNoPlugins(),
            metricsProbeService)
        .write(goConfigDao.loadForEditing(), os, true);
    assertValidContentAndStatus(
        SC_CONFLICT, "text/plain; charset=utf-8", CONFIG_CHANGED_PLEASE_REFRESH);
    assertThat(
        response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(goConfigDao.md5OfConfigFile()));
  }
  @Test
  public void shouldGetBuildAsPartialXml() throws Exception {
    configHelper.addPipeline("pipeline", "stage", "build1", "build2");

    String md5 = goConfigDao.md5OfConfigFile();

    controller.getBuildAsXmlPartial("pipeline", "stage", 1, null, response);
    assertValidContentAndStatus(SC_OK, "text/xml", "<job name=\"build2\" />");
    assertThat(response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(md5));
  }
 @Test
 public void shouldPostGroupWithChangedNameAsPartialXml() throws Exception {
   configHelper.addPipelineWithGroup("group", "pipeline", "dev", "linux", "windows");
   String newXml = RENAMED_GROUP;
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav = controller.postGroupAsXmlPartial("group", newXml, md5, response);
   assertThat(response.getStatus(), is(SC_OK));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   assertResponseMessage(mav, "Group changed successfully.");
 }
 @Test
 public void shouldPostStageAsPartialXml() throws Exception {
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String newXml = NEW_STAGE;
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav = controller.postStageAsXmlPartial("pipeline", 0, newXml, md5, response);
   assertThat(response.getStatus(), is(SC_OK));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map json = (Map) mav.getModel().get("json");
   new JsonTester(json).shouldContain("{ 'result' : 'Stage changed successfully.' }");
 }
  private String setUpPipelineGroupsWithAdminPermissions() throws IOException {
    setCurrentUser("ram");
    assertThat(CaseInsensitiveString.str(UserHelper.getUserName().getUsername()), is("ram"));

    configHelper.addPipelineWithGroup("studios", "go", "stage", "build1", "build2");
    configHelper.setAdminPermissionForGroup("studios", "barrow");

    configHelper.addPipelineWithGroup("consulting", "bcg", "stage", "build1", "build2");
    configHelper.setAdminPermissionForGroup("consulting", "ram");
    configHelper.addTemplate("newTemplate", "stage");

    return goConfigDao.md5OfConfigFile();
  }
 @Test
 public void shouldReturnXmlAndErrorMessageWhenInvalidPostOfStageAsPartialXml() throws Exception {
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav = controller.postStageAsXmlPartial("pipeline", 4, NEW_STAGE, md5, response);
   assertThat(response.getStatus(), is(SC_NOT_FOUND));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map<String, Object> json = (Map) mav.getModel().get("json");
   Map<String, Object> jsonMap = new LinkedHashMap<>();
   jsonMap.put("result", "Stage does not exist.");
   jsonMap.put("originalContent", NEW_STAGE);
   assertThat(json, is(jsonMap));
 }
 @Test
 public void shouldModifyExistingPipelineTemplateWhenPostedAsPartial() throws Exception {
   configHelper.addPipelineWithGroup(
       "some-group", "some-pipeline", "some-dev", "some-linux", "some-windows");
   configHelper.addAgent("some-home", "UUID");
   String newXml = NEW_TEMPLATES;
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav =
       controller.postGroupAsXmlPartial("Pipeline Templates", newXml, md5, response);
   assertResponseMessage(mav, "Template changed successfully.");
   assertThat(response.getStatus(), is(SC_OK));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   assertThat(configHelper.currentConfig().getTemplates().size(), is(1));
 }
 @Test
 public void shouldReturnXmlAndErrorMessageWhenInvalidPostOfBuildAsPartialXml() throws Exception {
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String newXml = "<job name=\"build3\" />";
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav =
       controller.postBuildAsXmlPartial("pipeline", "stage", 4, newXml, md5, response);
   assertThat(response.getStatus(), is(SC_NOT_FOUND));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map json = (Map) mav.getModel().get("json");
   new JsonTester(json)
       .shouldContain(
           "{ 'result' : 'Build does not exist.'," + "  'originalContent' : '" + newXml + "' }");
 }
 @Test
 public void shouldReturnXmlAndErrorMessageWhenPostOfStageAsInvalidPartialXml() throws Exception {
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String badXml = "<;askldjfa;dsklfja;sdjas;lkdf";
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav = controller.postStageAsXmlPartial("pipeline", 0, badXml, md5, response);
   assertThat(response.getStatus(), is(SC_CONFLICT));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map json = (Map) mav.getModel().get("json");
   new JsonTester(json)
       .shouldContain(
           "{ 'result' : 'Error on line 1 of document  : The markup in the document preceding the root element must be well-formed. Nested exception: The markup in the document preceding the root element must be well-formed.',"
               + "  'originalContent' : '"
               + badXml
               + "' }");
 }
 @Test
 public void shouldReturnXmlAndErrorMessageWhenPostOfBuildWithDuplicatedNameAsPartialXml()
     throws Exception {
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String newXml = "<job name=\"build2\" />";
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav =
       controller.postBuildAsXmlPartial("pipeline", "stage", 0, newXml, md5, response);
   assertThat(response.getStatus(), is(SC_CONFLICT));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map<String, Object> json = (Map) mav.getModel().get("json");
   Map<String, Object> expected = new LinkedHashMap<>();
   expected.put(
       "result",
       "Duplicate unique value [build2] declared for identity constraint \"uniqueJob\" of element \"jobs\".");
   expected.put("originalContent", newXml);
   assertThat(json, is(expected));
 }
 @Test
 public void shouldReturnErrorMessageIfConfigFileChangesBeforePostBuildAsPartialXml()
     throws Exception {
   String md5 = goConfigDao.md5OfConfigFile();
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String newXml = "<job name=\"build3\" />";
   ModelAndView mav =
       controller.postBuildAsXmlPartial("pipeline", "stage", 0, newXml, md5, response);
   assertThat(response.getStatus(), is(SC_CONFLICT));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map json = (Map) mav.getModel().get("json");
   new JsonTester(json)
       .shouldContain(
           "{ 'result' : '"
               + ConfigFileHasChangedException.CONFIG_CHANGED_PLEASE_REFRESH
               + "',"
               + "  'originalContent' : '"
               + newXml
               + "' }");
 }
 @Test
 public void shouldReturnErrorMessageWhenPostOfJobContainsDotForExecWorkingDir() throws Exception {
   configHelper.addPipeline("pipeline", "stage", "build1", "build2");
   String badXml =
       "<job name=\"build3\" >"
           + "<tasks>"
           + "<exec command=\"ant\" workingdir=\".\"/>"
           + "</tasks>"
           + "</job>";
   String md5 = goConfigDao.md5OfConfigFile();
   ModelAndView mav =
       controller.postBuildAsXmlPartial("pipeline", "stage", 0, badXml, md5, response);
   assertThat(response.getStatus(), is(SC_CONFLICT));
   assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON));
   Map json = (Map) mav.getModel().get("json");
   JsonValue jsonValue = JsonUtils.from(json);
   assertThat(unescapeJavaScript(jsonValue.getString("originalContent")), is(badXml));
   assertThat(
       unescapeJavaScript(jsonValue.getString("result")), containsString("File path is invalid"));
 }
  @Test
  public void shouldGetPipelineAsPartialXml() throws Exception {
    // get the pipeline XML
    configHelper.addPipeline("pipeline", "dev", "linux", "windows");
    groupName = BasicPipelineConfigs.DEFAULT_GROUP;
    controller.getPipelineAsXmlPartial(0, groupName, null, response);
    String xml = response.getContentAsString();
    assertThat(xml, containsString("pass"));

    // save the pipeline XML
    MockHttpServletResponse postResponse = new MockHttpServletResponse();
    String modifiedXml = xml.replace("pass", "secret");
    controller.postPipelineAsXmlPartial(
        0, groupName, modifiedXml, goConfigDao.md5OfConfigFile(), postResponse);

    // get the pipeline XML again
    MockHttpServletResponse getResponse = new MockHttpServletResponse();
    controller.getPipelineAsXmlPartial(0, groupName, null, getResponse);
    assertThat(getResponse.getContentAsString(), containsString("secret"));
    assertThat(getResponse.getContentAsString(), is(modifiedXml));
  }
  @Test
  public void shouldGetTemplateAsPartialXmlOnlyIfUserHasAdminRights() throws Exception {
    // get the pipeline XML
    configHelper.addPipeline("pipeline", "dev", "linux", "windows");
    configHelper.addTemplate("new-template", "dev");
    controller.getPipelineAsXmlPartial(
        0, TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME, null, response);
    String xml = response.getContentAsString();
    assertThat(xml, containsString("new-template"));

    // save the pipeline XML
    MockHttpServletResponse postResponse = new MockHttpServletResponse();
    String modifiedXml = xml.replace("new-template", "new-name-for-template");
    controller.postPipelineAsXmlPartial(
        0,
        TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME,
        modifiedXml,
        goConfigDao.md5OfConfigFile(),
        postResponse);

    // get the pipeline XML again
    MockHttpServletResponse getResponse = new MockHttpServletResponse();
    controller.getPipelineAsXmlPartial(
        0, TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME, null, getResponse);
    assertThat(getResponse.getContentAsString(), containsString("new-name-for-template"));
    assertThat(getResponse.getContentAsString(), is(modifiedXml));

    setCurrentUser("user");
    MockHttpServletResponse nonAdminResponse = new MockHttpServletResponse();
    controller.getPipelineAsXmlPartial(
        0, TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME, null, nonAdminResponse);
    assertThat(nonAdminResponse.getStatus(), is(SC_UNAUTHORIZED));
    assertThat(
        nonAdminResponse.getContentAsString(),
        is("User 'user' does not have permission to administer pipeline templates"));
  }