Skip to content
Snippets Groups Projects
Commit f8d48287 authored by Martin Lowe's avatar Martin Lowe :flag_ca: Committed by Martin Lowe
Browse files

Added unit tests, secret config to be used w/k8s, licenses


Signed-off-by: Martin Lowe's avatarMartin Lowe <martin.lowe@eclipse-foundation.org>
parent 22c12212
No related branches found
No related tags found
No related merge requests found
Showing
with 1321 additions and 93 deletions
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.namespace;
import com.fasterxml.jackson.annotation.JsonValue;
......
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.namespace;
import com.fasterxml.jackson.annotation.JsonValue;
......@@ -20,4 +28,4 @@ public enum ProviderType {
public String getValue() {
return name().toLowerCase();
}
}
\ No newline at end of file
}
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.oauth;
import com.github.scribejava.core.builder.api.DefaultApi20;
......
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.resource;
import java.util.List;
......@@ -40,7 +49,7 @@ import org.slf4j.LoggerFactory;
* @author Martin Lowe
*
*/
@Path("/git/eca")
@Path("/eca")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public class ValidationResource {
......@@ -81,74 +90,98 @@ public class ValidationResource {
// check that we have commits to validate
if (req.getCommits() == null || req.getCommits().isEmpty()) {
addError(r, "A commit is required to validate", null);
r.updateStatus(APIStatusCode.ERROR_DEFAULT);
return r.toResponse();
}
// check that we have a repo set
if (req.getRepoUrl() == null) {
addError(r, "A base repo URL needs to be set in order to validate", null);
r.updateStatus(APIStatusCode.ERROR_DEFAULT);
return r.toResponse();
}
// check that we have a type set
if (req.getProvider() == null) {
addError(r, "A provider needs to be set to validate a request", null);
r.updateStatus(APIStatusCode.ERROR_DEFAULT);
return r.toResponse();
}
for (Commit c : req.getCommits()) {
// ensure the commit is valid, and has required fields
if (!CommitHelper.validateCommit(c)) {
addError(r, "One or more commits were invalid. Please check the payload and try again", null);
r.updateStatus(APIStatusCode.ERROR_DEFAULT);
return r.toResponse();
// only process if we have no errors
if (r.getErrorCount() == 0) {
for (Commit c : req.getCommits()) {
// process the request, capturing if we should continue processing
boolean continueProcessing = processCommit(c, r, req);
// if there is a reason to stop processing, break the loop
if (!continueProcessing) {
break;
}
}
// retrieve the author + committer for the current request
GitUser author = c.getAuthor();
GitUser committer = c.getCommitter();
}
// depending on number of errors found, set response status
if (r.getErrorCount() == 0) {
r.setPassed(true);
}
return r.toResponse();
}
/**
* Process the current request, validating that the passed commit is valid. The
* author and committers Eclipse Account is retrieved, which are then used to
* check if the current commit is valid for the current project.
*
* @param c the commit to process
* @param response the response container
* @param request the current validation request
* @return true if we should continue processing, false otherwise.
*/
private boolean processCommit(Commit c, ValidationResponse response, ValidationRequest request) {
// ensure the commit is valid, and has required fields
if (!CommitHelper.validateCommit(c)) {
addError(response, "One or more commits were invalid. Please check the payload and try again", c.getHash());
return false;
}
// retrieve the author + committer for the current request
GitUser author = c.getAuthor();
GitUser committer = c.getCommitter();
addMessage(r, String.format("Reviewing commit: %1$s", c.getHash()), c.getHash());
addMessage(r, String.format("Authored by: %1$s <%2$s>", author.getName(), author.getMail()), c.getHash());
addMessage(response, String.format("Reviewing commit: %1$s", c.getHash()), c.getHash());
addMessage(response, String.format("Authored by: %1$s <%2$s>", author.getName(), author.getMail()),
c.getHash());
// retrieve the eclipse account for the author
EclipseUser eclipseAuthor = getIdentifiedUser(author);
if (eclipseAuthor == null) {
addMessage(r, String.format("Could not find an Eclipse user with mail '%1$s' for author of commit %2$s",
committer.getMail(), c.getHash()), c.getHash());
addError(r, "Author must have an Eclipse Account", c.getHash());
continue;
}
// skip processing if a merge commit
if (c.getParents().size() > 1) {
addMessage(response,
String.format("Commit '%1$s' has multiple parents, merge commit detected, passing", c.getHash()),
c.getHash());
return true;
}
// retrieve the eclipse account for the committer
EclipseUser eclipseCommitter = getIdentifiedUser(committer);
if (eclipseCommitter == null) {
addMessage(r,
String.format("Could not find an Eclipse user with mail '%1$s' for committer of commit %2$s",
committer.getMail(), c.getHash()),
c.getHash());
addError(r, "Committing user must have an Eclipse Account", c.getHash());
continue;
}
// validate author access to the current repo
validateAuthorAccess(r, c, eclipseAuthor, req.getRepoUrl());
// retrieve the eclipse account for the author
EclipseUser eclipseAuthor = getIdentifiedUser(author);
if (eclipseAuthor == null) {
addMessage(response,
String.format("Could not find an Eclipse user with mail '%1$s' for author of commit %2$s",
committer.getMail(), c.getHash()),
c.getHash());
addError(response, "Author must have an Eclipse Account", c.getHash());
return true;
}
// only committers can push on behalf of other users
if (!eclipseAuthor.equals(eclipseCommitter)
&& !isCommitter(r, eclipseCommitter, c.getHash(), req.getRepoUrl())) {
addMessage(r, "You are not a project committer.", c.getHash());
addMessage(r, "Only project committers can push on behalf of others.", c.getHash());
addError(r, "You must be a committer to push on behalf of others.", c.getHash());
}
// retrieve the eclipse account for the committer
EclipseUser eclipseCommitter = getIdentifiedUser(committer);
if (eclipseCommitter == null) {
addMessage(response,
String.format("Could not find an Eclipse user with mail '%1$s' for committer of commit %2$s",
committer.getMail(), c.getHash()),
c.getHash());
addError(response, "Committing user must have an Eclipse Account", c.getHash());
return true;
}
if (r.getErrorCount() == 0) {
r.setPassed(true);
r.updateStatus(APIStatusCode.SUCCESS_DEFAULT);
} else {
r.updateStatus(APIStatusCode.ERROR_DEFAULT);
// validate author access to the current repo
validateAuthorAccess(response, c, eclipseAuthor, request.getRepoUrl());
// only committers can push on behalf of other users
if (!eclipseAuthor.equals(eclipseCommitter)
&& !isCommitter(response, eclipseCommitter, c.getHash(), request.getRepoUrl())) {
addMessage(response, "You are not a project committer.", c.getHash());
addMessage(response, "Only project committers can push on behalf of others.", c.getHash());
addError(response, "You must be a committer to push on behalf of others.", c.getHash());
}
r.updateStatus(APIStatusCode.ERROR_DEFAULT);
return r.toResponse();
return true;
}
/**
......@@ -166,7 +199,6 @@ public class ValidationResource {
// check if the author matches to an eclipse user and is a committer
if (isCommitter(r, eclipseAuthor, c.getHash(), repoUrl)) {
addMessage(r, "The author is a committer on the project.", c.getHash());
r.updateStatus(APIStatusCode.SUCCESS_COMMITTER);
} else {
addMessage(r, "The author is not a committer on the project.", c.getHash());
// check if the author is signed off if not a committer
......@@ -189,8 +221,8 @@ public class ValidationResource {
"The author has not \"signed-off\" on the contribution.\n"
+ "If there are multiple commits, please ensure that each commit is signed-off.",
c.getHash());
addError(r, "The contributor must \"sign-off\" on the contribution.", c.getHash());
r.updateStatus(APIStatusCode.ERROR_SIGN_OFF);
addError(r, "The contributor must \"sign-off\" on the contribution.", c.getHash(),
APIStatusCode.ERROR_SIGN_OFF);
}
}
}
......@@ -212,16 +244,22 @@ public class ValidationResource {
* @return true if user is considered a committer, false otherwise.
*/
private boolean isCommitter(ValidationResponse r, EclipseUser user, String hash, String repoUrl) {
// TODO repo URL doesn't currently filter, so this may return false positives
// atm
// check for all projects that make use of the given repo
Optional<List<Project>> filteredProjects = cache.get("projects|" + repoUrl, () -> projects.getProject(repoUrl),
@SuppressWarnings("unchecked")
Optional<List<Project>> cachedProjects = cache.get("projects|" + repoUrl, () -> projects.getProject(),
(Class<List<Project>>) (Object) List.class);
if (!filteredProjects.isPresent() || filteredProjects.get().isEmpty()) {
if (!cachedProjects.isPresent() || cachedProjects.get().isEmpty()) {
return false;
}
// filter the projects based on the repo URL. At least one repo in project must
// match the repo URL to be valid
List<Project> filteredProjects = cachedProjects.get().stream()
.filter(p -> p.getRepos().stream().anyMatch(re -> re.getUrl().equals(repoUrl)))
.collect(Collectors.toList());
// iterate over filtered projects
for (Project p : filteredProjects.get()) {
for (Project p : filteredProjects) {
LOGGER.debug("Checking project '{}' for user '{}'", p.getName(), user.getName());
// check if any of the committers usernames match the current user
......@@ -233,7 +271,6 @@ public class ValidationResource {
r.addError(hash, String.format(
"Project is a specification for the working group '%1$s', but user does not have permission to modify a specification project",
p.getSpecWorkingGroup()), APIStatusCode.ERROR_SPEC_PROJECT);
r.updateStatus(APIStatusCode.ERROR_SPEC_PROJECT);
return false;
} else {
LOGGER.debug("User '{}' was found to be a committer on current project repo '{}'", user.getMail(),
......@@ -243,6 +280,7 @@ public class ValidationResource {
}
// get a list of all bots that Eclipse is aware of
@SuppressWarnings("unchecked")
Optional<List<BotUser>> allBots = cache.get("allBots", () -> bots.getBots(),
(Class<List<BotUser>>) (Object) List.class);
// check that we have bots to iterate over
......@@ -276,6 +314,7 @@ public class ValidationResource {
// get the Eclipse account for the user
try {
// use cache to avoid asking for the same user repeatedly on repeated requests
@SuppressWarnings("unchecked")
Optional<List<EclipseUser>> users = cache.get("user|" + user.getMail(),
() -> accounts.getUsers("Bearer " + oauth.getToken(), null, null, user.getMail()),
(Class<List<EclipseUser>>) (Object) List.class);
......@@ -296,7 +335,7 @@ public class ValidationResource {
}
private void addMessage(ValidationResponse r, String message, String hash) {
addMessage(r, hash, message, APIStatusCode.SUCCESS_DEFAULT);
addMessage(r, message, hash, APIStatusCode.SUCCESS_DEFAULT);
}
private void addError(ValidationResponse r, String message, String hash) {
......
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
/* Copyright (c) 2019 Eclipse Foundation and others.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License 2.0
......
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.service;
/**
......
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.service.impl;
import java.io.IOException;
......@@ -69,9 +78,7 @@ public class DefaultOAuthService implements OAuthService {
LOGGER.error("Issue communicating with OAuth server for authentication", e);
} catch (InterruptedException e) {
LOGGER.error("Authentication communication was interrupted before completion", e);
// re-throw as we shouldn't hold on to an interrupt
throw new RuntimeException(e);
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
LOGGER.error("Error while retrieving access token for request", e);
}
......
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
/* Copyright (c) 2019 Eclipse Foundation and others.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License 2.0
......@@ -103,7 +112,6 @@ public class GuavaCachingService implements CachingService {
@Override
public Set<String> getCacheKeys() {
// TODO we probably want to change how this is returned
// create a set and return all keys
Set<String> out = new HashSet<>();
caches.values().stream().forEach(c -> out.addAll(c.asMap().keySet()));
......
apiVersion: apps/v1
kind: Deployment
metadata:
name: git-eca-rest-api
namespace: foundation-internal-webdev-apps
spec:
selector:
matchLabels:
app: git-eca-rest-api
environment: production
replicas: 2
template:
metadata:
labels:
app: git-eca-rest-api
environment: production
spec:
containers:
- name: app
image: eclipsefdn/git-eca-rest-api:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
limits:
cpu: '1'
memory: 512Mi
requests:
cpu: 200m
memory: 512Mi
---
apiVersion: "v1"
kind: "Service"
metadata:
name: git-eca-rest-api
namespace: foundation-internal-webdev-apps
spec:
ports:
- name: "http"
port: 80
protocol: "TCP"
targetPort: 8080
selector:
app: git-eca-rest-api
environment: production
---
apiVersion: "route.openshift.io/v1"
kind: "Route"
metadata:
name: git-eca-rest-api
namespace: foundation-internal-webdev-apps
annotations:
haproxy.router.openshift.io/timeout: 20s
spec:
host: "api.eclipse.org"
path: "/git"
port:
targetPort: "http"
tls:
insecureEdgeTerminationPolicy: "Redirect"
termination: "edge"
to:
kind: "Service"
name: git-eca-rest-api
weight: 100
\ No newline at end of file
apiVersion: apps/v1
kind: Deployment
metadata:
name: git-eca-rest-api
namespace: foundation-internal-webdev-apps
spec:
selector:
matchLabels:
app: git-eca-rest-api
environment: staging
replicas: 1
template:
metadata:
labels:
app: git-eca-rest-api
environment: staging
spec:
containers:
- name: app
image: eclipsefdn/git-eca-rest-api:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 512Mi
---
apiVersion: "v1"
kind: "Service"
metadata:
name: git-eca-rest-api
namespace: foundation-internal-webdev-apps
spec:
ports:
- name: "http"
port: 80
protocol: "TCP"
targetPort: 8080
selector:
app: git-eca-rest-api
environment: staging
---
apiVersion: "route.openshift.io/v1"
kind: "Route"
metadata:
name: git-eca-rest-api
namespace: foundation-internal-webdev-apps
annotations:
haproxy.router.openshift.io/timeout: 20s
spec:
host: "api-staging.eclipse.org"
path: "/git"
port:
targetPort: "http"
tls:
insecureEdgeTerminationPolicy: "Redirect"
termination: "edge"
to:
kind: "Service"
name: git-eca-rest-api
weight: 100
\ No newline at end of file
#!/usr/bin/env ruby
require 'json'
require 'httparty'
require 'multi_json'
## Read in the arguments passed from GitLab and split them to an arg array
stdin_raw = ARGF.read;
stdin_args = stdin_raw.split(/\s+/)
## Set the vars for the commit hashes of current pre-receive event
previous_head_commit = stdin_args[0]
new_head_commit = stdin_args[1]
## Create either a range of commits for existing refs, or the HEAD commit SHA for new refs
commit_range_declaration = ''
if (previous_head_commit.match(/^0+$/)) then
commit_range_declaration = new_head_commit
else
commit_range_declaration = "#{previous_head_commit}..#{new_head_commit}"
end
## Retrieve the list of commits for the given range
git_commit_data = `git rev-list --first-parent #{commit_range_declaration}`
## Create a list of commits to iterate over from the command line response
git_commits = git_commit_data.split(/\s+/)
## Process each of the commits, creating a line of formatted JSON data to POST
processed_git_data = []
git_commits.each do |commit|
## Process Git data into JSON for each commit found
git_data = `git show -s --format='{"author": {"name":"%an","mail":"%ae"},"committer":{"name":"%cn","mail":"%ce"},"body":"%B","subject":"%s","hash":"%H", "parents":["%P"]}' #{commit}`
## Strip new lines as they FUBAR JSON parsers
git_data = git_data.gsub(/[\n\r]/, ' ')
processed_git_data.push(MultiJson.load(git_data))
end
## Get the project ID from env var, extracting from pattern 'project-###'
project_id = ENV['GL_REPOSITORY'][8..-1]
## Get data about project from API
project_response = HTTParty.get("http://localhost/api/v4/projects/#{project_id}")
## Format data to be able to easily read and process it
project_json_data = MultiJson.load(project_response.body)
## Get the web URL
project_url = project_json_data['web_url']
## Create the JSON payload
json_data = {
:repoUrl => project_url,
:provider => 'gitlab',
:commits => processed_git_data
}
## Generate request
response = HTTParty.post("http://172.21.0.1:8083/git/eca", :body => MultiJson.dump(json_data), :headers => { 'Content-Type' => 'application/json' })
## convert request to hash map
parsed_response = MultiJson.load(response.body)
## for each discovered hash commit tracked by response, report if it was OK
commit_keys = parsed_response['commits'].keys
commit_keys.each do |key|
commit_status = parsed_response['commits'][key]
if (commit_status['errors'].empty?) then
puts "Commit: #{key}\t\t\n\n"
commit_status['messages'].each do |msg|
puts "\t#{msg['message']}"
end
puts "\n\n"
else
puts "Commit: #{key}\t\tX\n\n"
commit_status['messages'].each do |msg|
puts "\t#{msg['message']}"
end
puts "\n"
commit_status['errors'].each do |error|
puts "ERROR: #{error['message']}"
end
puts "\n\n"
end
end
## If error, exit as status 1
if (response.code == 403) then
#exit 1
end
## Hardcode exit for testing
exit 1
org.eclipsefoundation.git.eca.config.SecretConfigSource
\ No newline at end of file
......@@ -2,12 +2,6 @@ org.eclipsefoundation.git.eca.api.AccountsAPI/mp-rest/url=https://api.eclipse.or
org.eclipsefoundation.git.eca.api.ProjectsAPI/mp-rest/url=https://projects.eclipse.org
org.eclipsefoundation.git.eca.api.BotsAPI/mp-rest/url=https://api.eclipse.org
gitlab.host=http://localhost:32769
gitlab.access-token=iNcHw5A4ZeavyGbdaAJz
## OAUTH CONFIG
oauth2.client-id=sample
oauth2.client-secret=sample
oauth2.scope=eclipsefdn_view_all_profiles
quarkus.http.port=8083
\ No newline at end of file
quarkus.http.port=8080
\ No newline at end of file
#!/bin/bash
read in;
OLD_HEAD="$(echo $in | cut -d" " -f1)"
NEW_HEAD="$(echo $in | cut -d" " -f2)"
GIT_LOG="$(git rev-list --first-parent $OLD_HEAD..$NEW_HEAD)";
COMMIT_HASHES=($GIT_LOG);
COMMITS=( )
for i in "${COMMIT_HASHES[@]}"
do
COMMITS=("$(git show -s --format='{"author": {"name":"%an","mail":"%ae"},"commiter":{"name":"%cn","mail":"%ce"},"body":"%B","subject":"%s","hash":"%H", "parents":"%P"}' $i)" "${COMMITS[@]}");
done
body=$(printf ",%s" "${COMMITS[@]}" | tr "\\n" "\n");
body=${body:1};
POST_COMMAND="curl http://192.168.1.178:8080/git/eca --data '{\"project_id\":\"1\",\"commits\":[$body]}' -H \"Content-Type:application/json\"";
echo $POST_COMMAND;
$("$POST_COMMAND");
exit 1
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.api;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.eclipsefoundation.git.eca.model.EclipseUser;
import org.eclipsefoundation.git.eca.model.EclipseUser.ECA;
import io.quarkus.test.Mock;
@Mock
@RestClient
@ApplicationScoped
public class MockAccountsAPI implements AccountsAPI {
private List<EclipseUser> src;
@PostConstruct
public void build() {
this.src = new ArrayList<>();
int id = 0;
EclipseUser e1 = new EclipseUser();
e1.setCommitter(false);
e1.setId(id++);
e1.setMail("newbie@important.co");
e1.setName("newbieAnon");
e1.setEca(new ECA());
src.add(e1);
EclipseUser e2 = new EclipseUser();
e2.setCommitter(false);
e2.setId(id++);
e2.setMail("slom@eclipse-foundation.org");
e2.setName("barshall_blathers");
e2.setEca(new ECA(true, true));
src.add(e2);
EclipseUser e3 = new EclipseUser();
e3.setCommitter(false);
e3.setId(id++);
e3.setMail("tester@eclipse-foundation.org");
e3.setName("mctesterson");
e3.setEca(new ECA(true, false));
src.add(e3);
EclipseUser e4 = new EclipseUser();
e4.setCommitter(true);
e4.setId(id++);
e4.setMail("code.wiz@important.co");
e4.setName("da_wizz");
e4.setEca(new ECA(true, true));
src.add(e4);
EclipseUser e5 = new EclipseUser();
e5.setCommitter(true);
e5.setId(id++);
e5.setMail("grunt@important.co");
e5.setName("grunter");
e5.setEca(new ECA(true, false));
src.add(e5);
EclipseUser e6 = new EclipseUser();
e6.setCommitter(false);
e6.setId(id++);
e6.setMail("paper.pusher@important.co");
e6.setName("sumAnalyst");
e6.setEca(new ECA(true, false));
src.add(e6);
}
@Override
public List<EclipseUser> getUsers(String authBearer, String id, String name, String mail) {
return src.stream().filter(user -> {
boolean matches = true;
if (id != null && !Integer.toString(user.getId()).equals(id)) {
matches = false;
}
if (name != null && !user.getName().equals(name)) {
matches = false;
}
if (mail != null && !user.getMail().equals(mail)) {
matches = false;
}
return matches;
}).collect(Collectors.toList());
}
}
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.api;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.eclipsefoundation.git.eca.model.BotUser;
import io.quarkus.test.Mock;
@Mock
@RestClient
@ApplicationScoped
public class MockBotsAPI implements BotsAPI {
private List<BotUser> src;
@PostConstruct
public void build() {
this.src = new ArrayList<>();
BotUser b1 = new BotUser();
b1.setId("1");
b1.setEmail("1.bot@eclipse.org");
b1.setProjectId("sample.proj");
b1.setUsername("projbot");
src.add(b1);
BotUser b2 = new BotUser();
b2.setId("10");
b2.setEmail("2.bot@eclipse.org");
b2.setProjectId("sample.proto");
b2.setUsername("protobot");
src.add(b2);
BotUser b3 = new BotUser();
b3.setId("11");
b3.setEmail("3.bot@eclipse.org");
b3.setProjectId("spec.proj");
b3.setUsername("specbot");
src.add(b3);
}
@Override
public List<BotUser> getBots() {
return new ArrayList<>(src);
}
}
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.api;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.eclipsefoundation.git.eca.model.Project;
import org.eclipsefoundation.git.eca.model.Project.Repo;
import org.eclipsefoundation.git.eca.model.Project.User;
import io.quarkus.test.Mock;
@Mock
@RestClient
@ApplicationScoped
public class MockProjectsAPI implements ProjectsAPI {
private List<Project> src;
@PostConstruct
public void build() {
this.src = new ArrayList<>();
// sample repos
Repo r1 = new Repo();
r1.setUrl("http://www.github.com/eclipsefdn/sample");
Repo r2 = new Repo();
r2.setUrl("http://www.github.com/eclipsefdn/test");
Repo r3 = new Repo();
r3.setUrl("http://www.github.com/eclipsefdn/prototype");
Repo r4 = new Repo();
r4.setUrl("http://www.github.com/eclipsefdn/tck-proto");
// sample users, correlates to users in Mock projects API
User u1 = new User();
u1.setUrl("");
u1.setUsername("da_wizz");
User u2 = new User();
u2.setUrl("");
u2.setUsername("grunter");
// projects
Project p1 = new Project();
p1.setName("Sample project");
p1.setProjectId("sample.proj");
p1.setSpecWorkingGroup(null);
p1.setRepos(Arrays.asList(r1, r2));
p1.setCommitters(Arrays.asList(u1, u2));
src.add(p1);
Project p2 = new Project();
p2.setName("Prototype thing");
p2.setProjectId("sample.proto");
p2.setSpecWorkingGroup(null);
p2.setRepos(Arrays.asList(r3));
p2.setCommitters(Arrays.asList(u2));
src.add(p2);
Project p3 = new Project();
p3.setName("Spec project");
p3.setProjectId("spec.proj");
p3.setSpecWorkingGroup("proj1");
p3.setRepos(Arrays.asList(r4));
p3.setCommitters(Arrays.asList(u1, u2));
src.add(p3);
}
@Override
public List<Project> getProject() {
return new ArrayList<>(src);
}
}
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.helper;
import java.util.ArrayList;
import org.eclipsefoundation.git.eca.model.Commit;
import org.eclipsefoundation.git.eca.model.GitUser;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
/**
* Tests related to the {@linkplain CommitHelper} class.
*
* @author Martin Lowe
*
*/
@QuarkusTest
public class CommitHelperTest {
// represents a known good commit before the start of each test
GitUser testUser;
Commit baseCommit;
@BeforeEach
public void setup() {
// basic good user
testUser = new GitUser();
testUser.setMail("test.user@eclipse-foundation.org");
testUser.setName("Tester McTesterson");
// basic known good commit
baseCommit = new Commit();
baseCommit.setBody(
String.format("Sample body content\n\nSigned-off-by: %s <%s>", testUser.getName(), testUser.getMail()));
baseCommit.setHash("abc123f");
baseCommit.setHead(false);
baseCommit.setParents(new ArrayList<>());
baseCommit.setSubject("Testing CommitHelper class #1337");
baseCommit.setAuthor(testUser);
baseCommit.setCommitter(testUser);
}
@Test
public void getSignedOffByEmailNullCommit() {
Assertions.assertNull(CommitHelper.getSignedOffByEmail(null), "Expected null return for null commit");
}
@Test
public void getSignedOffByEmailOnlyFooter() {
baseCommit.setBody(String.format("Signed-off-by: %s <%s>", testUser.getName(), testUser.getMail()));
String actualMail = CommitHelper.getSignedOffByEmail(baseCommit);
Assertions.assertEquals(testUser.getMail(), actualMail);
}
@Test
public void getSignedOffByEmailBodyAndFooter() {
baseCommit.setBody(
String.format("Sample body content\n\nSigned-off-by: %s <%s>", testUser.getName(), testUser.getMail()));
String actualMail = CommitHelper.getSignedOffByEmail(baseCommit);
Assertions.assertEquals(testUser.getMail(), actualMail);
}
@Test
public void getSignedOffByEmailNoNameFooter() {
baseCommit.setBody(
String.format("Sample body content\n\nSigned-off-by:<%s>", testUser.getMail()));
String actualMail = CommitHelper.getSignedOffByEmail(baseCommit);
Assertions.assertEquals(testUser.getMail(), actualMail);
}
@Test
public void getSignedOffByEmailNoBrackets() {
baseCommit.setBody(
String.format("Sample body content\n\nSigned-off-by:%s", testUser.getMail()));
String actualMail = CommitHelper.getSignedOffByEmail(baseCommit);
Assertions.assertNull(actualMail);
}
@Test
public void getSignedOffByEmailBadFooterName() {
baseCommit.setBody(
String.format("Sample body content\n\nSign-off-by: %s <%s>", testUser.getName(), testUser.getMail()));
Assertions.assertNull(CommitHelper.getSignedOffByEmail(baseCommit), "Expected no result with typo in footer name");
baseCommit.setBody(
String.format("Sample body content\n\nSIGNED-OFF-BY: %s <%s>", testUser.getName(), testUser.getMail()));
Assertions.assertNull(CommitHelper.getSignedOffByEmail(baseCommit), "Expected no result with bad casing");
}
@Test
public void validateCommitKnownGood() {
Assertions.assertTrue(CommitHelper.validateCommit(baseCommit), "Expected basic commit to pass validation");
}
@Test
public void validateCommitNullCommit() {
Assertions.assertFalse(CommitHelper.validateCommit(null), "Expected null commit to fail validation");
}
@Test
public void validateCommitNoAuthor() {
baseCommit.setAuthor(null);
Assertions.assertFalse(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to fail validation w/ no author");
}
@Test
public void validateCommitNoAuthorMail() {
GitUser noMail = new GitUser();
noMail.setName("Some Name");
baseCommit.setAuthor(noMail);
Assertions.assertFalse(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to fail validation w/ no author mail address");
}
@Test
public void validateCommitNoCommitter() {
baseCommit.setCommitter(null);
Assertions.assertFalse(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to fail validation w/ no committer");
}
@Test
public void validateCommitNoCommitterMail() {
GitUser noMail = new GitUser();
noMail.setName("Some Name");
baseCommit.setCommitter(noMail);
Assertions.assertFalse(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to fail validation w/ no committer mail address");
}
@Test
public void validateCommitNoHash() {
baseCommit.setHash(null);
Assertions.assertFalse(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to fail validation w/ no commit hash");
}
@Test
public void validateCommitNoBody() {
baseCommit.setBody(null);
Assertions.assertTrue(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to pass validation w/ no body");
}
@Test
public void validateCommitNoParents() {
baseCommit.setParents(new ArrayList<>());
Assertions.assertTrue(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to pass validation w/ no parents");
}
@Test
public void validateCommitNoSubject() {
baseCommit.setSubject(null);
Assertions.assertTrue(CommitHelper.validateCommit(baseCommit),
"Expected basic commit to pass validation w/ no subject");
}
}
/*******************************************************************************
* Copyright (C) 2020 Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipsefoundation.git.eca.resource;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipsefoundation.git.eca.model.Commit;
import org.eclipsefoundation.git.eca.model.GitUser;
import org.eclipsefoundation.git.eca.model.ValidationRequest;
import org.eclipsefoundation.git.eca.namespace.APIStatusCode;
import org.eclipsefoundation.git.eca.namespace.ProviderType;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
/**
* Tests for verifying end to end validation via the endpoint. Uses restassured
* to create pseudo requests, and Mock API endpoints to ensure that all data is
* kept internal for test checks.
*
* @author Martin Lowe
*
*/
@QuarkusTest
public class ValidationResourceTest {
@Test
public void validate() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("The Wizard");
g1.setMail("code.wiz@important.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody("Signed-off-by: The Wizard <code.wiz@important.co>");
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Collections.emptyList());
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/sample");
vr.setCommits(commits);
// test output w/ assertions
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(200)
.body("passed", is(true),
"errorCount", is(0));
}
@Test
public void validateMultipleCommits() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("The Wizard");
g1.setMail("code.wiz@important.co");
GitUser g2 = new GitUser();
g2.setName("Grunts McGee");
g2.setMail("grunt@important.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody("Signed-off-by: The Wizard <code.wiz@important.co>");
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Collections.emptyList());
commits.add(c1);
Commit c2 = new Commit();
c2.setAuthor(g2);
c2.setCommitter(g2);
c2.setBody("Signed-off-by: Grunts McGee<grunt@important.co>");
c2.setHash("c044dca1847c94e709601651339f88a5c82e3cc7");
c2.setSubject("Add in feature");
c2.setParents(
Arrays.asList("46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c10"));
commits.add(c2);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/sample");
vr.setCommits(commits);
// test output w/ assertions
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(200)
.body("passed", is(true),
"errorCount", is(0));
}
@Test
public void validateMergeCommit() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("Rando Calressian");
g1.setMail("rando@nowhere.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody(String.format("Signed-off-by: %s <%s>", g1.getName(), g1.getMail()));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Arrays.asList("46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c10", "46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c11"));
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/sample");
vr.setCommits(commits);
// test output w/ assertions
// No errors expected, should pass as only commit is a valid merge commit
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(200)
.body("passed", is(true),
"errorCount", is(0));
}
@Test
public void validateCommitNoSignOffCommitter() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("Grunts McGee");
g1.setMail("grunt@important.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody("");
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Collections.emptyList());
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/prototype");
vr.setCommits(commits);
// test output w/ assertions
// Should be valid as Grunt is a committer on the prototype project
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(200)
.body("passed", is(true),
"errorCount", is(0));
}
@Test
public void validateCommitNoSignOffNonCommitter() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("The Wizard");
g1.setMail("code.wiz@important.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody("");
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Collections.emptyList());
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/prototype");
vr.setCommits(commits);
// test output w/ assertions
// Should be invalid as Wizard is not a committer on the prototype project
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(403)
.body("passed", is(false),
"errorCount", is(1),
"commits.123456789abcdefghijklmnop.errors[0].code",
is(APIStatusCode.ERROR_SIGN_OFF.getValue()));
}
@Test
public void validateCommitInvalidSignOff() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("Barshall Blathers");
g1.setMail("slom@eclipse-foundation.org");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody(String.format("Signed-off-by: %s <%s>", g1.getName(), "barshallb@personal.co"));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Collections.emptyList());
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/prototype");
vr.setCommits(commits);
// test output w/ assertions
// Should be invalid as a different email was associated with the footer
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(403)
.body("passed", is(false),
"errorCount", is(1),
"commits.123456789abcdefghijklmnop.errors[0].code",
is(APIStatusCode.ERROR_SIGN_OFF.getValue()));
}
@Test
public void validateWorkingGroupSpecAccess() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("The Wizard");
g1.setMail("code.wiz@important.co");
GitUser g2 = new GitUser();
g2.setName("Grunts McGee");
g2.setMail("grunt@important.co");
// CASE 1: WG Spec project write access valid
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody("Signed-off-by: The Wizard <code.wiz@important.co>");
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Collections.emptyList());
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/tck-proto");
vr.setCommits(commits);
// test output w/ assertions
// Should be valid as Wizard has spec project write access + is committer
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(200)
.body("passed", is(true),
"errorCount", is(0));
// CASE 2: No WG Spec proj write access
commits = new ArrayList<>();
// create sample commits
c1 = new Commit();
c1.setAuthor(g2);
c1.setCommitter(g2);
c1.setBody(String.format("Signed-off-by: %s <%s>", g2.getName(), g2.getMail()));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Arrays.asList("46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c10"));
commits.add(c1);
vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/tck-proto");
vr.setCommits(commits);
// test output w/ assertions
// Should be invalid as Grunt does not have spec project write access
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(403)
.body("passed", is(false),
"errorCount", is(1),
"commits.123456789abcdefghijklmnop.errors[0].code",
is(APIStatusCode.ERROR_SPEC_PROJECT.getValue()));
}
@Test
public void validateProxyCommitPush() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("The Wizard");
g1.setMail("code.wiz@important.co");
GitUser g2 = new GitUser();
g2.setName("Barshall Blathers");
g2.setMail("slom@eclipse-foundation.org");
// CASE 1: Committer pushing for non-committer author
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g2);
c1.setCommitter(g1);
c1.setBody(String.format("Signed-off-by: %s <%s>", g2.getName(), g2.getMail()));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Collections.emptyList());
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/tck-proto");
vr.setCommits(commits);
// test output w/ assertions
// Should be valid as Wizard is a committer on proj
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(200)
.body("passed", is(true),
"errorCount", is(0));
// CASE 2: Non-committer pushing for non-committer author
commits = new ArrayList<>();
// create sample commits
c1 = new Commit();
c1.setAuthor(g2);
c1.setCommitter(g1);
c1.setBody(String.format("Signed-off-by: %s <%s>", g2.getName(), g2.getMail()));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Arrays.asList("46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c10"));
commits.add(c1);
vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/prototype");
vr.setCommits(commits);
// test output w/ assertions
// Should be invalid as Wizard is not a committer on proj
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(403)
.body("passed", is(false),
"errorCount", is(1));
}
@Test
public void validateNoECA() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("Newbie Anon");
g1.setMail("newbie@important.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g1);
c1.setBody(String.format("Signed-off-by: %s <%s>", g1.getName(), g1.getMail()));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Arrays.asList("46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c10"));
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/sample");
vr.setCommits(commits);
// test output w/ assertions
// Error should be singular + that there's no ECA on file
// Status 403 (forbidden) is the standard return for invalid requests
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(403)
.body("passed", is(false),
"errorCount", is(1));
}
@Test
public void validateAuthorNoEclipseAccount() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("Rando Calressian");
g1.setMail("rando@nowhere.co");
GitUser g2 = new GitUser();
g2.setName("Grunts McGee");
g2.setMail("grunt@important.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g1);
c1.setCommitter(g2);
c1.setBody(String.format("Signed-off-by: %s <%s>", g1.getName(), g1.getMail()));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Arrays.asList("46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c10"));
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/sample");
vr.setCommits(commits);
// test output w/ assertions
// Error should be singular + that there's no Eclipse Account on file for author
// Status 403 (forbidden) is the standard return for invalid requests
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(403)
.body("passed", is(false),
"errorCount", is(1));
}
@Test
public void validateCommitterNoEclipseAccount() {
// set up test users
GitUser g1 = new GitUser();
g1.setName("Rando Calressian");
g1.setMail("rando@nowhere.co");
GitUser g2 = new GitUser();
g2.setName("Grunts McGee");
g2.setMail("grunt@important.co");
List<Commit> commits = new ArrayList<>();
// create sample commits
Commit c1 = new Commit();
c1.setAuthor(g2);
c1.setCommitter(g1);
c1.setBody(String.format("Signed-off-by: %s <%s>", g2.getName(), g2.getMail()));
c1.setHash("123456789abcdefghijklmnop");
c1.setSubject("All of the things");
c1.setParents(Arrays.asList("46bb69bf6aa4ed26b2bf8c322ae05bef0bcc5c10"));
commits.add(c1);
ValidationRequest vr = new ValidationRequest();
vr.setProvider(ProviderType.GITHUB);
vr.setRepoUrl("http://www.github.com/eclipsefdn/sample");
vr.setCommits(commits);
// test output w/ assertions
// Error should be singular + that there's no Eclipse Account on file for committer
// Status 403 (forbidden) is the standard return for invalid requests
given()
.body(vr)
.contentType(ContentType.JSON)
.when().post("/git/eca")
.then()
.statusCode(403)
.body("passed", is(false),
"errorCount", is(1));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment