Skip to content
This repository has been archived by the owner on Dec 5, 2020. It is now read-only.

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Aug 15, 2017
2 parents 92aef33 + daad69b commit ae5026b
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 37 deletions.
31 changes: 31 additions & 0 deletions src/main/java/com/amihaiemil/charles/github/CachedRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
*/
package com.amihaiemil.charles.github;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;

import javax.json.JsonObject;

import com.jcabi.github.Content;
import org.hamcrest.Matchers;

import com.jcabi.github.Repo;
Expand Down Expand Up @@ -62,6 +64,11 @@ public class CachedRepo {
*/
private Boolean ghPagesBranch;

/**
* Cached .charles.yml file
*/
private CharlesYml yml;

/**
* Ctor.
* @param repo Github repository.
Expand Down Expand Up @@ -143,4 +150,28 @@ public boolean isOwnedByOrganization() throws IOException {
);
}

/**
* The charles.yml file contained in the repo.
* @return {@link CharlesYml}
* @throws IOException
*/
public CharlesYml charlesYml() throws IOException {
if(this.yml == null) {
if(this.repo.contents().exists(".charles.yml", "master")) {
this.yml = new CharlesYmlInput(
new ByteArrayInputStream(
new Content.Smart(
this.repo
.contents()
.get(".charles.yml")
).decoded()
)
);
} else {
this.yml = new CharlesYml.Default();
}
}
return this.yml;
}

}
20 changes: 18 additions & 2 deletions src/main/java/com/amihaiemil/charles/github/CharlesYml.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/
package com.amihaiemil.charles.github;

import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -40,12 +41,27 @@ public interface CharlesYml {
* Usernames of users who are allowed to command the bot.
* @return String[]
*/
abstract List<String> commanders();
List<String> commanders();

/**
* Should the bot tweet its activity?
* @return Boolean.
*/
abstract boolean tweet();
boolean tweet();

/**
* Default .charles.yml file.
*/
public static final class Default implements CharlesYml {
@Override
public List<String> commanders() {
return new ArrayList<>();
}

@Override
public boolean tweet() {
return false;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
package com.amihaiemil.charles.github;

import org.slf4j.Logger;

import java.io.IOException;

/**
Expand All @@ -40,48 +39,91 @@
* @author Mihai Andronache ([email protected])
* @version $Id$
* @since 1.0.1
* @todo #219:1h Write some integration tests for this step, check that
* the tree of steps executes correctly/in the right order. For this, you
* need to mock a Github server (use MkGithub) in appropriate ways, to check
* each flow.
*/
public final class GeneralPreconditionsCheck extends PreconditionCheckStep {
public final class GeneralPreconditionsCheck extends IntermediaryStep {

/**
* .charles.yml config file.
* Ctor.
* @param next Next step, after all precondition have passed.
*/
private CharlesYml charlesYml;
public GeneralPreconditionsCheck(final Step next) {
super(next);
}

@Override
public void perform(Command command, Logger logger) throws IOException {
final PreconditionCheckStep all;

final PreconditionCheckStep repoForkCheck = new RepoForkCheck(
command.repo().json(), this.next(),
this.finalCommentStep(command, "denied.fork.comment", command.authorLogin())
);

if(!this.isCommanderAllowed(command)) {
final PreconditionCheckStep authorOwnerCheck = new AuthorOwnerCheck(
repoForkCheck,
new OrganizationAdminCheck(
repoForkCheck,
this.finalCommentStep(command, "denied.commander.comment", command.authorLogin())
)
);
all = new RepoNameCheck(
command.repo().json(), authorOwnerCheck,
new GhPagesBranchCheck(
authorOwnerCheck,
this.finalCommentStep(command, "denied.name.comment", command.authorLogin())
)
);
} else {
all = new RepoNameCheck(
command.repo().json(), repoForkCheck,
new GhPagesBranchCheck(
repoForkCheck,
this.finalCommentStep(command, "denied.name.comment", command.authorLogin())
)
);
}
all.perform(command, logger);
}

/**
* Ctor.
* @param onTrue Step that should be performed next if the check is true.
* @param onFalse Step that should be performed next if the check is false.
* @param charlesYml This is the .charles.yml config file.
* Builds the final comment to be sent to the issue.
* <b>This should be the last in the steps' chain</b>.
* @param com Command.
* @param formatParts Parts to format the response %s elements with.
* @return SendReply step.
*/
public GeneralPreconditionsCheck(
final Step onTrue,
final Step onFalse,
final CharlesYml charlesYml
private SendReply finalCommentStep(
Command com, String messagekey, String ... formatParts
) {
super(onTrue, onFalse);
this.charlesYml = charlesYml;
return new SendReply(
new TextReply(
com,
String.format(
com.language().response(messagekey),
(Object[]) formatParts
)
),
new Step.FinalStep()
);
}

@Override
public void perform(Command command, Logger logger) throws IOException {
// PreconditionCheckStep repoForkCheck = new RepoForkCheck(
// command.repo().json(), action,
// this.finalCommentStep(command, lang, "denied.fork.comment", command.authorLogin())
// );
// PreconditionCheckStep authorOwnerCheck = new AuthorOwnerCheck(
// repoForkCheck,
// new OrganizationAdminCheck(
// repoForkCheck,
// this.finalCommentStep(command, lang, "denied.commander.comment", command.authorLogin())
// )
// );
// PreconditionCheckStep repoNameCheck = new RepoNameCheck(
// command.repo().json(), authorOwnerCheck,
// new GhPagesBranchCheck(
// authorOwnerCheck,
// this.finalCommentStep(command, lang, "denied.name.comment", command.authorLogin())
// )
// );
/**
* Is the command's author specified in .charles.yml as a commander?
* @param com Initial command.
* @throws IOException if the commanders' list cannot be read from Github.
* @return True of False
*/
private boolean isCommanderAllowed(Command com) throws IOException {
for(String commander : com.repo().charlesYml().commanders()) {
if(commander.equalsIgnoreCase(com.authorLogin())) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@
import javax.json.Json;
import javax.json.JsonObject;

import org.apache.commons.codec.binary.Base64;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.mockito.Mockito;

import com.amihaiemil.camel.Yaml;
import com.jcabi.github.Repo;
import com.jcabi.github.Repos.RepoCreate;
import com.jcabi.github.mock.MkGithub;
Expand All @@ -62,7 +66,7 @@ public class CachedRepoTestCase {
@Test
public void repoHasGhPagesBranch() throws Exception {
int port = this.port();
MkContainer server = new MkGrizzlyContainer()
MkContainer server = new MkGrizzlyContainer()
.next(new MkAnswer.Simple(HttpURLConnection.HTTP_OK))
.start(port);
try {
Expand Down Expand Up @@ -167,6 +171,56 @@ public void getsJson() throws Exception {
assertTrue(repoJson == repoFromCache);
}

/**
* CachedRepo can return the .charles.yml which is in the repo.
* @throws Exception If something goes wrong.
*/
@Test
public void getsExistingCharlesYml() throws Exception {
final MkGithub gh = new MkGithub("amihaiemil");
final Repo repo = gh.repos().create(new RepoCreate("charlesrepo", false));
repo.contents()
.create(
Json.createObjectBuilder()
.add("path", ".charles.yml")
.add("message", "just a test")
.add(
"content",
Base64.encodeBase64String(
Yaml.createYamlMappingBuilder()
.add("tweet", "true")
.add(
"commanders",
Yaml.createYamlSequenceBuilder()
.add("johndoe")
.add("amihaiemil")
.add("queeney")
.build()
).build().toString().getBytes()
)
).build()
);
final CharlesYml yml = new CachedRepo(repo).charlesYml();
MatcherAssert.assertThat(yml.commanders(), Matchers.hasSize(3));
MatcherAssert.assertThat(yml.commanders().get(0), Matchers.equalTo("amihaiemil"));//YAML orders them alphabetically
MatcherAssert.assertThat(yml.commanders().get(1), Matchers.equalTo("johndoe"));
MatcherAssert.assertThat(yml.commanders().get(2), Matchers.equalTo("queeney"));
MatcherAssert.assertThat(yml.tweet(), Matchers.is(true));
}

/**
* CachedRepo can return a default ChalesYml if the repo does not have it.
* @throws Exception If something goes worng.
*/
@Test
public void getsDefaultCharlesYml() throws Exception {
MkGithub gh = new MkGithub("amihaiemil");
Repo rep = gh.repos().create(new RepoCreate("charlesrepo", false));
CharlesYml yml = new CachedRepo(rep).charlesYml();
MatcherAssert.assertThat(yml.commanders(), Matchers.emptyIterable());
MatcherAssert.assertThat(yml.tweet(), Matchers.is(false));
}

/**
* Find a free port.
* @return A free port.
Expand Down

1 comment on commit ae5026b

@0pdd
Copy link

@0pdd 0pdd commented on ae5026b Aug 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 219-dd617bae discovered in src/main/java/com/amihaiemil/charles/github/GeneralPreconditionsCheck.java and submitted as #234.

Please sign in to comment.