Make watched.projects:delete respect the filter

The previous implementation of watched.projects:delete only took the
project's name as the sole criterion for deleting a project.
This change makes the code respect the filter attribute as well as users
can set multiple watch notifications per project using different
filters.

Change-Id: I5a35421fe7bb361ccf372240f29788da66bd129b
This commit is contained in:
Patrick Hiesel
2016-05-17 17:32:42 -07:00
parent 750a6c1e49
commit 57d50755b7
5 changed files with 63 additions and 19 deletions

View File

@@ -1540,7 +1540,7 @@ The result is sorted by project name in ascending order.
--
Projects posted to this endpoint will no longer be watched. The posted body
can contain an array of project names as strings.
can contain a list of link:#project-watch-info[ProjectWatchInfo] entities.
.Request
----
@@ -1548,7 +1548,10 @@ can contain an array of project names as strings.
Content-Type: application/json;charset=UTF-8
[
"Test Project 1"
{
"project": "Test Project 1",
"filter": "branch:master"
}
]
----

View File

@@ -81,7 +81,7 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
// Persist watched projects
gApi.accounts().self().setWatchedProjects(projectsToWatch);
List<String> d = Lists.newArrayList(projectName2);
List<ProjectWatchInfo> d = Lists.newArrayList(pwi);
gApi.accounts().self().deleteWatchedProjects(d);
projectsToWatch.remove(pwi);
@@ -127,7 +127,7 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
gApi.accounts().self().setWatchedProjects(projectsToWatch);
// Try to delete a watched project using a different user
List<String> d = Lists.newArrayList(projectName);
List<ProjectWatchInfo> d = Lists.newArrayList(pwi);
gApi.accounts().self().deleteWatchedProjects(d);
setApiUser(user);
@@ -166,4 +166,40 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
assertThat(watchedProjects).containsAllIn(projectsToWatch);
}
@Test
public void setAndDeleteWatchedProjectsWithDifferentFilter()
throws Exception {
String projectName = project.get();
List<ProjectWatchInfo> projectsToWatch = new LinkedList<>();
ProjectWatchInfo pwi = new ProjectWatchInfo();
pwi.project = projectName;
pwi.filter = "branch:stable";
pwi.notifyAbandonedChanges = true;
pwi.notifyNewChanges = true;
pwi.notifyAllComments = true;
projectsToWatch.add(pwi);
pwi = new ProjectWatchInfo();
pwi.project = projectName;
pwi.filter = "branch:master";
pwi.notifySubmittedChanges = true;
pwi.notifyNewPatchSets = true;
projectsToWatch.add(pwi);
// Persist watched projects
gApi.accounts().self().setWatchedProjects(projectsToWatch);
List<ProjectWatchInfo> d = Lists.newArrayList(pwi);
gApi.accounts().self().deleteWatchedProjects(d);
projectsToWatch.remove(pwi);
List<ProjectWatchInfo> persistedWatchedProjects =
gApi.accounts().self().getWatchedProjects();
assertThat(persistedWatchedProjects).doesNotContain(pwi);
assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch);
}
}

View File

@@ -50,7 +50,7 @@ public interface AccountApi {
List<ProjectWatchInfo> getWatchedProjects() throws RestApiException;
List<ProjectWatchInfo> setWatchedProjects(List<ProjectWatchInfo> in)
throws RestApiException;
void deleteWatchedProjects(List<String> in)
void deleteWatchedProjects(List<ProjectWatchInfo> in)
throws RestApiException;
void starChange(String changeId) throws RestApiException;
@@ -131,7 +131,7 @@ public interface AccountApi {
}
@Override
public void deleteWatchedProjects(List<String> in)
public void deleteWatchedProjects(List<ProjectWatchInfo> in)
throws RestApiException {
throw new NotImplementedException();
}

View File

@@ -13,11 +13,13 @@
// limitations under the License.
package com.google.gerrit.server.account;
import com.google.gerrit.extensions.client.ProjectWatchInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.reviewdb.client.AccountProjectWatch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gwtorm.server.OrmException;
@@ -32,7 +34,7 @@ import java.util.List;
@Singleton
public class DeleteWatchedProjects
implements RestModifyView<AccountResource, List<String>> {
implements RestModifyView<AccountResource, List<ProjectWatchInfo>> {
private final Provider<ReviewDb> dbProvider;
private final Provider<IdentifiedUser> self;
@@ -46,7 +48,7 @@ public class DeleteWatchedProjects
@Override
public Response<?> apply(
AccountResource rsrc, List<String> input)
AccountResource rsrc, List<ProjectWatchInfo> input)
throws UnprocessableEntityException, OrmException, AuthException {
if (self.get() != rsrc.getUser()) {
throw new AuthException("It is not allowed to edit project watches "
@@ -55,24 +57,27 @@ public class DeleteWatchedProjects
ResultSet<AccountProjectWatch> watchedProjects =
dbProvider.get().accountProjectWatches()
.byAccount(rsrc.getUser().getAccountId());
HashMap<String, AccountProjectWatch> watchedProjectsMap = new HashMap<>();
HashMap<AccountProjectWatch.Key, AccountProjectWatch>
watchedProjectsMap = new HashMap<>();
for (AccountProjectWatch watchedProject : watchedProjects) {
watchedProjectsMap
.put(watchedProject.getProjectNameKey().get(), watchedProject);
watchedProjectsMap.put(watchedProject.getKey(), watchedProject);
}
if (input != null) {
List<AccountProjectWatch.Key> keysToDelete = new LinkedList<>();
for (String projectKeyToDelete : input) {
if (!watchedProjectsMap.containsKey(projectKeyToDelete)) {
throw new UnprocessableEntityException(projectKeyToDelete
List<AccountProjectWatch> watchesToDelete = new LinkedList<>();
for (ProjectWatchInfo projectInfo : input) {
AccountProjectWatch.Key key = new AccountProjectWatch.Key(
rsrc.getUser().getAccountId(),
new Project.NameKey(projectInfo.project),
projectInfo.filter);
if (!watchedProjectsMap.containsKey(key)) {
throw new UnprocessableEntityException(projectInfo.project
+ " is not currently watched by this user.");
}
keysToDelete.add(watchedProjectsMap.get(projectKeyToDelete).getKey());
watchesToDelete.add(watchedProjectsMap.get(key));
}
dbProvider.get().accountProjectWatches().deleteKeys(keysToDelete);
dbProvider.get().accountProjectWatches().delete(watchesToDelete);
}
return Response.none();
}
}

View File

@@ -237,7 +237,7 @@ public class AccountApiImpl implements AccountApi {
}
@Override
public void deleteWatchedProjects(List<String> in)
public void deleteWatchedProjects(List<ProjectWatchInfo> in)
throws RestApiException {
try {
deleteWatchedProjects.apply(account, in);