Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit bb4fc91
Author: Alex Eng <aeng@redhat.com>
Date:   Mon Nov 3 14:44:37 2014 +1000

    Fix unit test

commit 2134069
Merge: acfd4b9 89389da
Author: Alex Eng <aeng@redhat.com>
Date:   Mon Nov 3 14:36:25 2014 +1000

    Merge branch 'integration/master' into rhbz1122776

commit acfd4b9
Author: Alex Eng <aeng@redhat.com>
Date:   Mon Nov 3 11:07:44 2014 +1000

    Implement asynchronous event for document statistic update

commit bfd4d8b
Author: Alex Eng <aeng@redhat.com>
Date:   Fri Oct 31 14:02:17 2014 +1000

    Revert org.zanata.model* to org.zanata.ui.model.* due to arquillian test

commit 4c54956
Merge: 94138d5 d15e2d7
Author: Alex Eng <aeng@redhat.com>
Date:   Fri Oct 31 11:27:07 2014 +1000

    Merge branch 'rhbz1122776' of github.com:zanata/zanata-server into rhbz1122776

commit 94138d5
Author: Alex Eng <aeng@redhat.com>
Date:   Fri Oct 31 11:25:34 2014 +1000

    Refactor org.zanata.ui.model.statistic to org.zanata.model.statistic, change webhook event to translated+approved and approved

commit 3e4b87c
Merge: 0c97c6b c8facd7
Author: Alex Eng <aeng@redhat.com>
Date:   Fri Oct 31 11:06:46 2014 +1000

    Merge branch 'integration/master' into rhbz1122776

    Conflicts:
    	zanata-war/src/main/java/org/zanata/util/StatisticsUtil.java

commit 0c97c6b
Author: Alex Eng <aeng@redhat.com>
Date:   Fri Oct 31 11:05:24 2014 +1000

    Fix loading on webook, add message when removing webhook

commit d15e2d7
Author: Damian Jansen <djansen@redhat.com>
Date:   Fri Oct 31 09:42:30 2014 +1000

    Functional test for project webhooks

commit a13bc8f
Merge: 0a13a33 240a396
Author: Alex Eng <aeng@redhat.com>
Date:   Tue Oct 28 10:35:44 2014 +1000

    Merge branch 'integration/master' into rhbz1122776

    Conflicts:
    	zanata-war/src/main/resources/db/db.changelog.xml

commit 0a13a33
Merge: 0822d48 11a9b5e
Author: Alex Eng <aeng@redhat.com>
Date:   Fri Oct 24 09:37:51 2014 +1000

    Merge branch 'integration/master' into rhbz1122776

commit 0822d48
Author: Alex Eng <aeng@redhat.com>
Date:   Wed Oct 22 13:29:24 2014 +1000

    Implement webhooks: https://bugzilla.redhat.com/show_bug.cgi?id=1122776
  • Loading branch information
Alex Eng committed Nov 3, 2014
1 parent 34625de commit 036ba2e
Show file tree
Hide file tree
Showing 34 changed files with 1,240 additions and 18 deletions.
Expand Up @@ -36,6 +36,7 @@
import com.google.common.base.Predicate;

import lombok.extern.slf4j.Slf4j;
import org.zanata.page.projects.projectsettings.ProjectWebHooksTab;

@Slf4j
public class ProjectBasePage extends BasePage {
Expand Down Expand Up @@ -67,6 +68,8 @@ public class ProjectBasePage extends BasePage {
@FindBy(id = "settings-about_tab")
private WebElement settingsAboutTab;

private By settingsWebHooksTab = By.id("settings-webhooks_tab");

public ProjectBasePage(final WebDriver driver) {
super(driver);
}
Expand Down Expand Up @@ -197,6 +200,13 @@ public boolean apply(WebDriver input) {
return new ProjectLanguagesTab(getDriver());
}

public ProjectWebHooksTab gotoSettingsWebHooksTab() {
log.info("Click WebHooks settings sub-tab");
clickWhenTabEnabled(waitForWebElement(settingsWebHooksTab));
waitForWebElement(By.id("settings-webhooks"));
return new ProjectWebHooksTab(getDriver());
}

public ProjectAboutTab gotoSettingsAboutTab() {
log.info("Click About settings sub-tab");
clickWhenTabEnabled(settingsAboutTab);
Expand Down
@@ -0,0 +1,95 @@
/*
* Copyright 2014, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.page.projects.projectsettings;

import com.google.common.base.Predicate;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.zanata.page.projects.ProjectBasePage;
import org.zanata.util.WebElementUtil;

import java.util.List;

/**
* @author Damian Jansen <a href="mailto:djansen@redhat.com">djansen@redhat.com</a>
*/
@Slf4j
public class ProjectWebHooksTab extends ProjectBasePage {

private By webHooksList = By.id("settings-webhooks-list");
private By urlInputField = By.id("payloadUrlInput");

public ProjectWebHooksTab(WebDriver driver) {
super(driver);
}

public ProjectWebHooksTab enterUrl(String url) {
waitForWebElement(urlInputField).sendKeys(url + Keys.ENTER);
return new ProjectWebHooksTab(getDriver());
}

public List<String> getWebHooks() {
return WebElementUtil.elementsToText(waitForWebElement(webHooksList)
.findElement(By.className("list--slat"))
.findElements(By.className("list-item")));
}

public ProjectWebHooksTab waitForWebHooksContains(final String url) {
waitForAMoment().until(new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver input) {
return getWebHooks().contains(url);
}
});
return new ProjectWebHooksTab(getDriver());
}

public ProjectWebHooksTab waitForWebHooksNotContains(final String url) {
waitForAMoment().until(new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver input) {
return !getWebHooks().contains(url);
}
});
return new ProjectWebHooksTab(getDriver());
}

public ProjectWebHooksTab clickRemoveOn(String url) {
List<WebElement> listItems = waitForWebElement(webHooksList)
.findElement(By.className("list--slat"))
.findElements(By.className("list-item"));
boolean clicked = false;
for (WebElement listItem : listItems) {
if (listItem.getText().contains(url)) {
listItem.findElement(By.tagName("a")).click();
clicked = true;
break;
}
}
if (!clicked) {
log.info("Did not find item {}", url);
}
return new ProjectWebHooksTab(getDriver());
}
}
@@ -0,0 +1,82 @@
/*
* Copyright 2014, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.feature.project;

import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.zanata.feature.Feature;
import org.zanata.feature.testharness.TestPlan.DetailedTest;
import org.zanata.feature.testharness.ZanataTestCase;
import org.zanata.page.projects.projectsettings.ProjectWebHooksTab;
import org.zanata.util.SampleProjectRule;
import org.zanata.workflow.LoginWorkFlow;

import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Damian Jansen <a href="mailto:djansen@redhat.com">djansen@redhat.com</a>
*/
@Category(DetailedTest.class)
public class EditWebHooksTest extends ZanataTestCase {

@Rule
public SampleProjectRule sampleProjectRule = new SampleProjectRule();

@Feature(summary = "The maintainer can add WebHooks for a project",
tcmsTestPlanIds = 5316, tcmsTestCaseIds = 0)
@Test(timeout = ZanataTestCase.MAX_SHORT_TEST_DURATION)
public void addWebHook() throws Exception {
String testUrl = "http://www.example.com";
ProjectWebHooksTab projectWebHooksTab = new LoginWorkFlow()
.signIn("admin", "admin")
.goToProjects()
.goToProject("about fedora")
.gotoSettingsTab()
.gotoSettingsWebHooksTab()
.enterUrl(testUrl)
.waitForWebHooksContains(testUrl);

assertThat(projectWebHooksTab.getWebHooks())
.contains(testUrl)
.as("The web hook was added");
}

@Feature(summary = "The maintainer can add WebHooks for a project",
tcmsTestPlanIds = 5316, tcmsTestCaseIds = 0)
@Test(timeout = ZanataTestCase.MAX_SHORT_TEST_DURATION)
public void removeWebHook() throws Exception {
String testUrl = "http://www.example.com";
ProjectWebHooksTab projectWebHooksTab = new LoginWorkFlow()
.signIn("admin", "admin")
.goToProjects()
.goToProject("about fedora")
.gotoSettingsTab()
.gotoSettingsWebHooksTab()
.enterUrl(testUrl)
.waitForWebHooksContains(testUrl)
.clickRemoveOn(testUrl)
.waitForWebHooksNotContains(testUrl);

assertThat(projectWebHooksTab.getWebHooks())
.doesNotContain(testUrl)
.as("The web hook was removed");
}
}
6 changes: 6 additions & 0 deletions zanata-model/src/main/java/org/zanata/model/HProject.java
Expand Up @@ -31,6 +31,7 @@

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
Expand All @@ -52,8 +53,10 @@

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.Where;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.validator.constraints.NotEmpty;
Expand Down Expand Up @@ -118,6 +121,9 @@ public class HProject extends SlugEntityBase implements Serializable,
name = "localeId"))
private Set<HLocale> customizedLocales = Sets.newHashSet();

@OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
private List<WebHook> webHooks = Lists.newArrayList();

@Enumerated(EnumType.STRING)
private ProjectType defaultProjectType;

Expand Down
75 changes: 75 additions & 0 deletions zanata-model/src/main/java/org/zanata/model/WebHook.java
@@ -0,0 +1,75 @@
/*
* Copyright 2014, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/

package org.zanata.model;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import org.zanata.model.validator.Url;

import com.google.common.annotations.VisibleForTesting;

/**
* @author Alex Eng <a href="mailto:aeng@redhat.com">aeng@redhat.com</a>
*/
@Entity
@Getter
@Setter(AccessLevel.PRIVATE)
@NoArgsConstructor
public class WebHook implements Serializable {

private Long id;

private HProject project;

@Url
private String url;

public WebHook(HProject project, String url) {
this.project = project;
this.url = url;
}

@Id
@GeneratedValue
public Long getId() {
return id;
}

@ManyToOne
@JoinColumn(name = "projectId", nullable = false)
public HProject getProject() {
return project;
}
}
41 changes: 41 additions & 0 deletions zanata-war/src/main/java/org/zanata/action/ProjectHome.java
Expand Up @@ -52,13 +52,15 @@
import org.zanata.common.LocaleId;
import org.zanata.common.ProjectType;
import org.zanata.dao.AccountRoleDAO;
import org.zanata.dao.WebHookDAO;
import org.zanata.i18n.Messages;
import org.zanata.model.HAccount;
import org.zanata.model.HAccountRole;
import org.zanata.model.HLocale;
import org.zanata.model.HPerson;
import org.zanata.model.HProject;
import org.zanata.model.HProjectIteration;
import org.zanata.model.WebHook;
import org.zanata.seam.scope.ConversationScopeMessages;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.LocaleService;
Expand All @@ -69,6 +71,7 @@
import org.zanata.ui.autocomplete.LocaleAutocomplete;
import org.zanata.ui.autocomplete.MaintainerAutocomplete;
import org.zanata.util.ComparatorUtil;
import org.zanata.util.UrlUtil;
import org.zanata.webtrans.shared.model.ValidationAction;
import org.zanata.webtrans.shared.model.ValidationId;
import org.zanata.webtrans.shared.validation.ValidationFactory;
Expand Down Expand Up @@ -110,6 +113,9 @@ public class ProjectHome extends SlugHome<HProject> {
@In
private AccountRoleDAO accountRoleDAO;

@In
private WebHookDAO webHookDAO;

@In
private ValidationService validationServiceImpl;

Expand Down Expand Up @@ -533,6 +539,41 @@ public List<ValidationAction> getValidationList() {
return sortedList;
}

@Restrict("#{s:hasPermission(projectHome.instance, 'update')}")
public void addWebHook(String url) {
if (isValidUrl(url)) {
WebHook webHook = new WebHook(this.getInstance(), url);
getInstance().getWebHooks().add(webHook);
update();
FacesMessages.instance().add(StatusMessage.Severity.INFO,
msgs.format("jsf.project.AddNewWebhook", webHook.getUrl()));
}
}

@Restrict("#{s:hasPermission(projectHome.instance, 'update')}")
public void removeWebHook(WebHook webHook) {
getInstance().getWebHooks().remove(webHook);
webHookDAO.makeTransient(webHook);
FacesMessages.instance().add(StatusMessage.Severity.INFO,
msgs.format("jsf.project.RemoveWebhook", webHook.getUrl()));
}

private boolean isValidUrl(String url) {
if (!UrlUtil.isValidUrl(url)) {
FacesMessages.instance().add(StatusMessage.Severity.ERROR,
msgs.format("jsf.project.InvalidUrl", url));
return false;
}
for(WebHook webHook: getInstance().getWebHooks()) {
if(StringUtils.equalsIgnoreCase(webHook.getUrl(), url)) {
FacesMessages.instance().add(StatusMessage.Severity.ERROR,
msgs.format("jsf.project.DuplicateUrl", url));
return false;
}
}
return true;
}

/**
* If this action is enabled(Warning or Error), then it's exclusive
* validation will be turn off
Expand Down

0 comments on commit 036ba2e

Please sign in to comment.