@Test(
      dataProvider = "basicInfo",
      dependsOnMethods = {"testExecuteNoAction"},
      alwaysRun = true)
  public void testRemoveArticles(
      ArticleList articleList,
      Map<String, Integer> indices,
      Set<String> validDois,
      Set<String> orphanDois)
      throws Exception {
    // delete first three dois
    List<Article> articlesToDelete =
        dummyDataStore.get(ArticleList.class, articleList.getID()).getArticles().subList(0, 3);
    String[] articlesToDeleteArray = new String[3];
    for (int i = 0; i < 3; i++) {
      articlesToDeleteArray[i] = articlesToDelete.get(i).getDoi();
    }

    action.setCommand("REMOVE_ARTICLES");
    action.setListKey(articleList.getListKey());
    action.setArticlesToRemove(articlesToDeleteArray);

    String result = action.execute();
    assertEquals(result, Action.SUCCESS, "Action didn't return success");

    assertEquals(action.getActionErrors().size(), 0, "Action returned error messages");
    assertEquals(
        action.getActionMessages().size(), 1, "Action didn't return messages indicating success");

    for (Article article : articlesToDelete) {
      String doi = article.getDoi();
      assertFalse(
          getDois(action.getArticleList().getArticles()).contains(doi),
          "Article " + doi + " didn't get removed from action's article list");
      assertFalse(
          action.getArticleOrderCSV().contains(doi),
          "Article " + doi + " didn't get removed from action's csv");
    }

    // check the values in the db
    List<Article> storedArticleList =
        dummyDataStore.get(ArticleList.class, articleList.getID()).getArticles();
    for (Article article : articlesToDelete) {
      String doi = article.getDoi();
      assertFalse(
          getDois(storedArticleList).contains(doi),
          "Article " + doi + " didn't get removed from list in the database");
      try {
        articleService.getArticle(doi, DEFAULT_ADMIN_AUTHID);
      } catch (NoSuchArticleIdException e) {
        fail(
            "Article "
                + doi
                + " got deleted from the database instead of just being removed from the list");
      }
    }
  }
  @Test(
      dataProvider = "basicInfo",
      dependsOnMethods = {"testExecuteNoAction", "testUpdateArticleList"},
      alwaysRun = true)
  public void testAddArticle(
      ArticleList articleList,
      Map<String, Integer> indices,
      Set<String> validDois,
      Set<String> orphanDois)
      throws Exception {
    String articlesToAddCsv = "id:new-article-for-adding-1,id:new-article-for-adding-2";
    for (String doi : articlesToAddCsv.split(",")) {
      Article article = new Article();
      article.setDoi(doi);
      article.setTitle("New article for adding");
      dummyDataStore.store(article);
    }

    action.setCommand("ADD_ARTICLE");
    action.setListKey(articleList.getListKey());
    action.setArticlesToAddCsv(articlesToAddCsv);

    String result = action.execute();
    assertEquals(result, Action.SUCCESS, "Action didn't return success");

    assertEquals(action.getActionErrors().size(), 0, "Action returned error messages");
    assertEquals(
        action.getActionMessages().size(), 1, "Action didn't return messages indicating success");

    for (String doi : articlesToAddCsv.split(",")) {
      assertTrue(
          action.getArticleOrderCSV().contains(doi),
          "Article " + doi + " didn't get added to action's csv");
      assertTrue(
          getDois(action.getArticleList().getArticles()).contains(doi),
          "Article " + doi + " didn't get added to action's articleList");
    }

    // check the values that got stored to the database
    List<Article> storedArticles =
        dummyDataStore.get(ArticleList.class, articleList.getID()).getArticles();
    for (String doi : articlesToAddCsv.split(",")) {
      assertTrue(
          getDois(storedArticles).contains(doi),
          "Article " + doi + " didn't get added to the list in the database");
    }
  }
  @Test(
      dataProvider = "basicInfo",
      dependsOnMethods = {"testExecuteNoAction"},
      alwaysRun = true)
  public void testUpdateArticleList(
      ArticleList articleList,
      Map<String, Integer> indices,
      Set<String> validDois,
      Set<String> orphanDois)
      throws Exception {
    // execute the action to get the current CSV
    action.setCommand("foo");
    action.setListKey(articleList.getListKey());
    action.execute();
    clearMessages();

    List<Article> existingArticles =
        dummyDataStore.get(ArticleList.class, articleList.getID()).getArticles();

    // move first doi to last in reorder
    String reorderedArticleCsv = action.getArticleOrderCSV();
    String articleToReorder = reorderedArticleCsv.substring(0, reorderedArticleCsv.indexOf(","));
    reorderedArticleCsv = reorderedArticleCsv.replaceFirst(articleToReorder + ",", "");
    reorderedArticleCsv += ("," + articleToReorder);
    List<String> orderedArticlesForDb = Arrays.asList(reorderedArticleCsv.split(","));
    Map<String, Integer> newIndices = new HashMap<String, Integer>();
    for (int i = 0; i < orderedArticlesForDb.size(); ++i) {
      newIndices.put(orderedArticlesForDb.get(i), i);
    }

    String displayName = "Spam";

    action.setCommand("UPDATE_LIST");
    action.setListKey(articleList.getListKey());
    action.setArticleOrderCSV(reorderedArticleCsv);
    action.setDisplayName(displayName);

    String result = action.execute();
    assertEquals(result, Action.SUCCESS, "Action didn't return success");

    assertEquals(action.getActionErrors().size(), 0, "Action returned error messages");
    assertTrue(
        action.getActionMessages().size() > 0, "Action didn't return messages indicating success");

    // check properties on action
    assertEquals(
        action.getArticleList().getListKey(),
        articleList.getListKey(),
        "action changed article list after update");
    assertEquals(action.getDisplayName(), displayName, "action had incorrect display name");

    assertEquals(
        getDois(action.getArticleList().getArticles()),
        orderedArticlesForDb,
        "Action returned wrong Dois in articleList");

    assertEquals(
        action.getArticleOrderCSV(),
        reorderedArticleCsv,
        "Action returned different articleOrderCSV");

    // the action should show the article csv in order of the valid articles
    assertEquals(
        isSorted(action.getArticleOrderCSV().split(","), newIndices),
        true,
        "Action returned wrong order after update articles");

    for (ArticleInfo articleInfo : action.getArticleInfoList()) {
      String doi = articleInfo.getDoi();
      assertEquals(
          validDois.contains(doi), true, "Action returned orphan articles in articleInfoList");
    }

    // check what got stored to the database
    ArticleList storedArticleList = dummyDataStore.get(ArticleList.class, articleList.getID());

    assertEquals(
        storedArticleList.getDisplayName(),
        displayName,
        "Article List got saved to the database with incorrect display name");

    assertEqualsNoOrder(
        storedArticleList.getArticles().toArray(),
        existingArticles.toArray(),
        "Articles got removed or added from the list on reordering");
  }