/** Tests that we are able to add a basic starter. */
  @Test
  public void addStarter() throws Exception {
    IProject project = harness.createBootProject("foo", withStarters("web"));
    final ISpringBootProject bootProject = springBootCore.project(project);
    EditStartersModel wizard = createWizard(project);
    assertEquals(bootProject.getBootVersion(), wizard.getBootVersion());
    assertStarterDeps(wizard.dependencies.getCurrentSelection(), "web");

    PopularityTracker popularities = new PopularityTracker(prefs);
    assertUsageCounts(bootProject, popularities /*none*/);

    wizard.addDependency("actuator");
    assertStarterDeps(wizard.dependencies.getCurrentSelection(), "web", "actuator");
    wizard.performOk();

    Job.getJobManager().join(EditStartersModel.JOB_FAMILY, null);

    assertUsageCounts(bootProject, popularities, "actuator:1");

    StsTestUtil.assertNoErrors(project); // force project build

    assertStarters(bootProject.getBootStarters(), "web", "actuator");

    // check that the 'scope' is not set in the pom.xml:
    IDOMDocument pom = parsePom(project);

    Element depEl = findDependency(bootProject, pom, "actuator");
    assertEquals("org.springframework.boot", getGroupId(depEl));
    assertEquals("spring-boot-starter-actuator", getArtifactId(depEl));
    assertEquals(null, getScope(depEl));
  }
  /**
   * Tests that the EditStartersModel is parsed and that existing starters already present on the
   * project are initially selected.
   */
  @Test
  public void existingStartersSelected() throws Exception {
    IProject project = harness.createBootProject("foo", withStarters("web", "actuator"));
    ISpringBootProject bootProject = springBootCore.project(project);
    EditStartersModel wizard = createWizard(project);
    assertTrue(wizard.isSupported());

    assertEquals(bootProject.getBootVersion(), wizard.getBootVersion());
    assertStarterDeps(wizard.dependencies.getCurrentSelection(), "web", "actuator");
  }
  /** Tests that we are able to remove a starter. */
  @Test
  public void removeStarter() throws Exception {
    IProject project = harness.createBootProject("foo", withStarters("web", "actuator"));
    final ISpringBootProject bootProject = springBootCore.project(project);
    EditStartersModel wizard = createWizard(project);
    assertEquals(bootProject.getBootVersion(), wizard.getBootVersion());
    assertStarterDeps(wizard.dependencies.getCurrentSelection(), "web", "actuator");

    wizard.removeDependency("web");
    assertStarterDeps(wizard.dependencies.getCurrentSelection(), /* removed: "web",*/ "actuator");
    wizard.performOk();

    StsTestUtil.assertNoErrors(project); // force project build

    assertStarters(bootProject.getBootStarters(), "actuator");
  }
  @Test
  public void addStarterWithBom() throws Exception {
    // We'll be adding this starter:
    //	      "id": "cloud-eureka",
    //	      "groupId": "org.springframework.cloud",
    //	      "artifactId": "spring-cloud-starter-eureka",
    //	      "scope": "compile",
    //	      "bom": "cloud-bom"

    IProject project = harness.createBootProject("foo", withStarters("web"));
    final ISpringBootProject bootProject = springBootCore.project(project);
    EditStartersModel wizard = createWizard(project);
    wizard.addDependency("cloud-eureka");
    wizard.performOk();

    Job.getJobManager().join(EditStartersModel.JOB_FAMILY, null);
    StsTestUtil.assertNoErrors(project); // force project build

    assertStarters(bootProject.getBootStarters(), "web", "cloud-eureka");
  }
  @Test
  public void addStarterWithTestScope() throws Exception {
    IProject project = harness.createBootProject("foo", withStarters("web"));
    final ISpringBootProject bootProject = springBootCore.project(project);
    EditStartersModel wizard = createWizard(project);
    wizard.addDependency("restdocs");
    wizard.performOk();

    Job.getJobManager().join(EditStartersModel.JOB_FAMILY, null);

    StsTestUtil.assertNoErrors(project); // force project build

    assertStarters(bootProject.getBootStarters(), "web", "restdocs");

    // check that the 'scope' is set properly
    IDOMDocument pom = parsePom(project);
    Element depEl = findDependency(bootProject, pom, "restdocs");
    assertEquals("spring-restdocs-mockmvc", getArtifactId(depEl));
    assertEquals("test", getScope(depEl));
  }
  @Test
  public void addMultipleStartersWithSameBom() throws Exception {
    // This test uses more 'controlled' parameters:
    IProject project =
        harness.createBootProject(
            "foo",
            bootVersion(BOOT_1_3_X_RELEASE), // boot version fixed
            withStarters("web"));
    initializr.setInputs("sample"); // sample intializr json captured for this version
    final ISpringBootProject bootProject = springBootCore.project(project);
    int initialBomCount = getBomCount(parsePom(project));

    EditStartersModel wizard = createWizard(project);
    wizard.addDependency("cloud-eureka");
    wizard.addDependency("cloud-config-client");
    wizard.performOk();

    Job.getJobManager().join(EditStartersModel.JOB_FAMILY, null);
    StsTestUtil.assertNoErrors(project); // force project build

    assertStarters(bootProject.getBootStarters(), "web", "cloud-eureka", "cloud-config-client");

    IDOMDocument pom = parsePom(project);
    int finalBomCount = getBomCount(pom);
    assertEquals(initialBomCount + 1, finalBomCount);

    // check that both repos got added
    assertRepoCount(2, pom);

    Element repo = getRepo(pom, "spring-snapshots");
    assertNotNull(repo);
    assertEquals("Spring Snapshots", getTextChild(repo, "name"));
    assertEquals("https://repo.spring.io/snapshot", getTextChild(repo, "url"));
    assertEquals("true", getSnapshotsEnabled(repo));

    repo = getRepo(pom, "spring-milestones");
    assertNotNull(repo);
    assertEquals("Spring Milestones", getTextChild(repo, "name"));
    assertEquals("https://repo.spring.io/milestone", getTextChild(repo, "url"));
    assertEquals("false", getSnapshotsEnabled(repo));
  }
  @Test
  public void addMultipleStartersWithDifferentBom() throws Exception {
    // This test uses more 'controlled' parameters:
    IProject project =
        harness.createBootProject(
            "foo",
            bootVersion(BOOT_1_3_X_RELEASE), // boot version fixed
            withStarters("web"));
    initializr.setInputs("sample"); // sample intializr json captured for this version
    final ISpringBootProject bootProject = springBootCore.project(project);
    int initialBomCount = getBomCount(parsePom(project));

    EditStartersModel wizard = createWizard(project);
    wizard.addDependency("cloud-eureka");
    wizard.addDependency("vaadin");
    wizard.performOk();

    Job.getJobManager().join(EditStartersModel.JOB_FAMILY, null);
    StsTestUtil.assertNoErrors(project); // force project build

    assertStarters(bootProject.getBootStarters(), "web", "cloud-eureka", "vaadin");

    IDOMDocument pom = parsePom(project);
    int finalBomCount = getBomCount(pom);
    assertEquals(initialBomCount + 2, finalBomCount);
    {
      Element bom = getBom(pom, "spring-cloud-starter-parent");
      assertEquals("org.springframework.cloud", getTextChild(bom, GROUP_ID));
      assertEquals("Brixton.M3", getTextChild(bom, VERSION));
      assertEquals("pom", getTextChild(bom, TYPE));
      assertEquals("import", getTextChild(bom, SCOPE));
    }
    {
      Element bom = getBom(pom, "vaadin-bom");
      assertEquals("com.vaadin", getTextChild(bom, GROUP_ID));
      assertEquals("7.5.5", getTextChild(bom, VERSION));
      assertEquals("pom", getTextChild(bom, TYPE));
      assertEquals("import", getTextChild(bom, SCOPE));
    }
  }