diff --git a/pom.xml b/pom.xml
index 3125158..29522d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,19 @@
jackson-annotations
${jackson-annotations.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.9.4
+
+
+
+ com.github.tomakehurst
+ wiremock
+ ${wiremock.version}
+ test
+
diff --git a/src/main/java/edu/allegro/exercise/Constant.java b/src/main/java/edu/allegro/exercise/Constant.java
index e0f1513..c5aaff9 100644
--- a/src/main/java/edu/allegro/exercise/Constant.java
+++ b/src/main/java/edu/allegro/exercise/Constant.java
@@ -8,7 +8,8 @@ public enum Constant {
ACCEPT("Accept"),
USER_AGENT("User-Agent"),
CONFIG_YAML("config.yaml"),
- CLIENT_POOL_SIZE("clientPoolSize"), CLIENT_TIMEOUT("clientTimeout");
+ CLIENT_POOL_SIZE("clientPoolSize"),
+ CLIENT_TIMEOUT("clientTimeout");
private final String prop;
diff --git a/src/main/java/edu/allegro/exercise/handlers/RepositoryInfo.java b/src/main/java/edu/allegro/exercise/handlers/RepositoryInfo.java
index 7277a98..3a9caf1 100644
--- a/src/main/java/edu/allegro/exercise/handlers/RepositoryInfo.java
+++ b/src/main/java/edu/allegro/exercise/handlers/RepositoryInfo.java
@@ -18,9 +18,10 @@ import static edu.allegro.exercise.Constant.*;
public class RepositoryInfo {
- public static final String GITHUB_USER_BASIC = "githubUserBasic";
+ private static final String GITHUB_USER_BASIC = "githubUserBasic";
private static final String AUTHORIZATION = "Authorization";
private static final String BASIC = "Basic ";
+ private static final String REPOS = "/repos/";
private final HttpClient client;
private final String resourceLink;
private final Headers headers;
@@ -31,6 +32,7 @@ public class RepositoryInfo {
this.client = initHttpClient(poolSize, timeout);
this.resourceLink = (String) configuration.get(GITHUB_REPOSITORY_OWNER_INFO.getName());
this.headers = setHeaders(configuration);
+
}
private HttpClient initHttpClient(int poolSize, int timeout) throws Exception {
@@ -44,7 +46,7 @@ public class RepositoryInfo {
}
public Promise getInfo(String owner, String repo) throws URISyntaxException {
- String url = resourceLink + owner + "/" + repo;
+ String url = resourceLink + REPOS + owner + "/" + repo;
return client.get(new URI(url),
this::setHeaders);
diff --git a/src/test/java/edu/allegro/exercise/ResultCodesTest.java b/src/test/java/edu/allegro/exercise/ResultCodesTest.java
new file mode 100644
index 0000000..7b68d82
--- /dev/null
+++ b/src/test/java/edu/allegro/exercise/ResultCodesTest.java
@@ -0,0 +1,44 @@
+package edu.allegro.exercise;
+
+import edu.allegro.exercise.model.github.ErrorResponse;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertTrue;
+
+public class ResultCodesTest {
+
+ @Test
+ public void errorResponseShouldBe404Test() {
+ ErrorResponse errorResponse = ResultCodes.fromCode(404);
+ assertTrue("Github error server 404 should be mapped on 404 error response", errorResponse.getStatusCode() == 404);
+ }
+
+
+ @Test
+ public void errorResponseShouldBe400Test() {
+ ErrorResponse errorResponse = ResultCodes.fromCode(403);
+ assertTrue("Github error server 403 should be mapped on 400 error response", errorResponse.getStatusCode() == 403);
+ }
+
+
+ @Test
+ public void errorResponseShouldBe500Test() {
+ ErrorResponse errorResponse = ResultCodes.fromCode(500);
+ assertTrue("Github error server 500 should be mapped on 500 error response", errorResponse.getStatusCode() == 500);
+ }
+
+ @Test
+ public void anyErrorDiffrentThanAboveShouldBePresentedAs500() {
+ Set notUsed = new HashSet<>(Arrays.asList(400, 403, 404));
+ for (int i = 100; i < 511; i++) {
+ if (!notUsed.contains(i)) {
+ ErrorResponse errorResponse = ResultCodes.fromCode(i);
+ assertTrue("Github error server 404 should be mapped on 404 error response", errorResponse.getStatusCode() == 500);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/edu/allegro/exercise/handlers/GetUserRepoInfoTest.java b/src/test/java/edu/allegro/exercise/handlers/GetUserRepoInfoTest.java
index 9c24733..8f19cc5 100644
--- a/src/test/java/edu/allegro/exercise/handlers/GetUserRepoInfoTest.java
+++ b/src/test/java/edu/allegro/exercise/handlers/GetUserRepoInfoTest.java
@@ -6,7 +6,7 @@ import java.util.Map;
public class GetUserRepoInfoTest {
private static final Map CONFIGURATION = new HashMap() {{
- put("githubResourceV3", "https://api.github.com/repos/");
+ put("githubResourceV3", "http://localhost:1111");
put("githubUserAgent", "Allegro-exercise");
put("githubAccept", "application/vnd.github.v3+json");
put("githubUserBasic", "YWxsZWdyb0V4ZXJjaXNlOkNpSHVuQmFIaWR1andpNg==");
diff --git a/src/test/java/edu/allegro/exercise/handlers/IntegrationTest.java b/src/test/java/edu/allegro/exercise/handlers/IntegrationTest.java
index a6f38e7..a0ec8de 100644
--- a/src/test/java/edu/allegro/exercise/handlers/IntegrationTest.java
+++ b/src/test/java/edu/allegro/exercise/handlers/IntegrationTest.java
@@ -1,71 +1,91 @@
package edu.allegro.exercise.handlers;
+import com.github.tomakehurst.wiremock.common.Slf4jNotifier;
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.junit.After;
import org.junit.Assert;
-import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import ratpack.http.client.ReceivedResponse;
import ratpack.server.RatpackServer;
import ratpack.server.ServerConfigBuilder;
import ratpack.test.embed.EmbeddedApp;
import ratpack.test.http.TestHttpClient;
-public class IntegrationTest {
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
+public class IntegrationTest {
+ private static final Logger log = LoggerFactory.getLogger(IntegrationTest.class);
private static final String GITHUB_OWNER = "sinu0";
private static final String GIHTUB_REPO = "SiSPD";
private static final String GIHTUB_REPO_NOK = "SiSPDs";
+ private static final String GITHUB_REPO_FORBIDDEN = "Forbidden";
+ private final EmbeddedApp app;
- private EmbeddedApp app;
+ @Rule
+ public WireMockRule rule = new WireMockRule(wireMockConfig().port(1111).notifier(new Slf4jNotifier(true)));
- @Before
- public void setUp() throws Exception {
+ public IntegrationTest() throws Exception {
+ rule.start();
GetUserRepoInfoService getUserRepoInfoService = GetUserRepoInfoTest.userRepoTest();
app = EmbeddedApp.fromServer(RatpackServer.of(ratpackServerSpec ->
ratpackServerSpec
.serverConfig(ServerConfigBuilder::build)
.handlers(getUserRepoInfoService.create())));
-
}
+
@After
public void endTests() throws Exception {
+ rule.stop();
app.getServer().stop();
- app = null;
}
@Test
- public void shouldReturnOKInfoAboutOwnerRepo() throws Exception {
+ public void shouldReturnForbiddenTest() throws Exception {
+ app.test(this::githubShouldReturnForbiddenAppShouldReturn403);
+ }
+
+
+ @Test
+ public void shouldReturnOKInfoAboutOwnerRepoTest() throws Exception {
app.test(this::shouldReturnOKInfoAboutOwnerRepo);
}
@Test
- public void shouldReturnNOKInfoAboutOwnerRepo() throws Exception {
- app.test(this::shouldReturnNOKInfoAboutOwnerRepo);
+ public void forNotExistingRepoShouldReturn404Test() throws Exception {
+ app.test(this::forNotExistingReposhouldReturn404);
+ }
+
+ @Test
+ public void WhenGithubShutdownShouldReturn500OnGithubUnavailabilityTest() throws Exception {
+ rule.stop();
+ app.test(this::forNotExistingReposhouldReturn404);
+ }
+
+ private void githubShouldReturnForbiddenAppShouldReturn403(TestHttpClient testHttpClient) {
+ ReceivedResponse receivedResponse = testHttpClient.get(String.format("/repositories/%s/%s", GITHUB_OWNER, GITHUB_REPO_FORBIDDEN));
+ Assert.assertTrue("Response should be nok for owner: " + GITHUB_OWNER + " and for repo: " + GITHUB_REPO_FORBIDDEN, receivedResponse.getStatusCode() == HttpResponseStatus.FORBIDDEN.code());
}
private void shouldReturnOKInfoAboutOwnerRepo(TestHttpClient testHttpClient) {
ReceivedResponse receivedResponse = testHttpClient.get(String.format("/repositories/%s/%s", GITHUB_OWNER, GIHTUB_REPO));
- responseShouldBeValid(receivedResponse);
+ logResponse(receivedResponse);
+ Assert.assertTrue("Response should be ok for owner: " + GITHUB_OWNER + " and for repo: " + GIHTUB_REPO, receivedResponse.getStatusCode() == HttpResponseStatus.OK.code());
}
- private void shouldReturnNOKInfoAboutOwnerRepo(TestHttpClient testHttpClient) {
+ private void forNotExistingReposhouldReturn404(TestHttpClient testHttpClient) {
ReceivedResponse receivedResponse = testHttpClient.get(String.format("/repositories/%s/%s", GITHUB_OWNER, GIHTUB_REPO_NOK));
- responseShouldBeNotValid(receivedResponse);
+ Assert.assertTrue("Response should be nok for owner: " + GITHUB_OWNER + " and for repo: " + GIHTUB_REPO_NOK, receivedResponse.getStatusCode() != HttpResponseStatus.OK.code());
}
- private void responseShouldBeValid(ReceivedResponse receivedResponse) {
- System.out.println(receivedResponse.getHeaders().asMultiValueMap().toString());
- System.out.println(receivedResponse.getBody().getText());
- Assert.assertTrue("Response should be ok for owner:" + GITHUB_OWNER + " and for repo: " + GIHTUB_REPO, receivedResponse.getStatusCode() == HttpResponseStatus.OK.code());
+ private void logResponse(ReceivedResponse response) {
+ log.info(response.getHeaders().asMultiValueMap().toString());
+ log.info(response.getStatus().toString());
+ log.info(response.getBody().getText());
}
- private void responseShouldBeNotValid(ReceivedResponse receivedResponse) {
- System.out.println(receivedResponse.getHeaders().asMultiValueMap().toString());
- System.out.println(receivedResponse.getBody().getText());
- Assert.assertTrue("Response should be nok for owner:" + GITHUB_OWNER + " and for repo: " + GIHTUB_REPO_NOK, receivedResponse.getStatusCode() != HttpResponseStatus.OK.code());
- }
-
-
}
diff --git a/src/test/resources/__files/repos_sinu0_sispd-570cfa1e-8aaa-4cd6-8037-d919654649d5.json b/src/test/resources/__files/repos_sinu0_sispd-570cfa1e-8aaa-4cd6-8037-d919654649d5.json
new file mode 100644
index 0000000..e873713
--- /dev/null
+++ b/src/test/resources/__files/repos_sinu0_sispd-570cfa1e-8aaa-4cd6-8037-d919654649d5.json
@@ -0,0 +1,275 @@
+{
+ "id": 6338269,
+ "name": "SiSPD",
+ "full_name": "sinu0/SiSPD",
+ "owner": {
+ "login": "sinu0",
+ "id": 1923291,
+ "avatar_url": "https://avatars1.githubusercontent.com/u/1923291?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/sinu0",
+ "html_url": "https://github.com/sinu0",
+ "followers_url": "https://api.github.com/users/sinu0/followers",
+ "following_url": "https://api.github.com/users/sinu0/following{/other_user}",
+ "gists_url": "https://api.github.com/users/sinu0/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/sinu0/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/sinu0/subscriptions",
+ "organizations_url": "https://api.github.com/users/sinu0/orgs",
+ "repos_url": "https://api.github.com/users/sinu0/repos",
+ "events_url": "https://api.github.com/users/sinu0/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/sinu0/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/sinu0/SiSPD",
+ "description": "Symulacja i sterowanie procesów dyskretnych - projekt.",
+ "fork": true,
+ "url": "https://api.github.com/repos/sinu0/SiSPD",
+ "forks_url": "https://api.github.com/repos/sinu0/SiSPD/forks",
+ "keys_url": "https://api.github.com/repos/sinu0/SiSPD/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/sinu0/SiSPD/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/sinu0/SiSPD/teams",
+ "hooks_url": "https://api.github.com/repos/sinu0/SiSPD/hooks",
+ "issue_events_url": "https://api.github.com/repos/sinu0/SiSPD/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/sinu0/SiSPD/events",
+ "assignees_url": "https://api.github.com/repos/sinu0/SiSPD/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/sinu0/SiSPD/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/sinu0/SiSPD/tags",
+ "blobs_url": "https://api.github.com/repos/sinu0/SiSPD/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/sinu0/SiSPD/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/sinu0/SiSPD/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/sinu0/SiSPD/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/sinu0/SiSPD/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/sinu0/SiSPD/languages",
+ "stargazers_url": "https://api.github.com/repos/sinu0/SiSPD/stargazers",
+ "contributors_url": "https://api.github.com/repos/sinu0/SiSPD/contributors",
+ "subscribers_url": "https://api.github.com/repos/sinu0/SiSPD/subscribers",
+ "subscription_url": "https://api.github.com/repos/sinu0/SiSPD/subscription",
+ "commits_url": "https://api.github.com/repos/sinu0/SiSPD/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/sinu0/SiSPD/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/sinu0/SiSPD/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/sinu0/SiSPD/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/sinu0/SiSPD/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/sinu0/SiSPD/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/sinu0/SiSPD/merges",
+ "archive_url": "https://api.github.com/repos/sinu0/SiSPD/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/sinu0/SiSPD/downloads",
+ "issues_url": "https://api.github.com/repos/sinu0/SiSPD/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/sinu0/SiSPD/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/sinu0/SiSPD/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/sinu0/SiSPD/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/sinu0/SiSPD/labels{/name}",
+ "releases_url": "https://api.github.com/repos/sinu0/SiSPD/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/sinu0/SiSPD/deployments",
+ "created_at": "2012-10-22T16:19:46Z",
+ "updated_at": "2013-01-12T19:04:16Z",
+ "pushed_at": "2012-10-22T16:18:13Z",
+ "git_url": "git://github.com/sinu0/SiSPD.git",
+ "ssh_url": "git@github.com:sinu0/SiSPD.git",
+ "clone_url": "https://github.com/sinu0/SiSPD.git",
+ "svn_url": "https://github.com/sinu0/SiSPD",
+ "homepage": null,
+ "size": 7064,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": null,
+ "has_issues": false,
+ "has_projects": true,
+ "has_downloads": true,
+ "has_wiki": false,
+ "has_pages": false,
+ "forks_count": 0,
+ "mirror_url": null,
+ "archived": false,
+ "open_issues_count": 0,
+ "license": null,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "parent": {
+ "id": 6212829,
+ "name": "SiSPD",
+ "full_name": "wojciechcibor/SiSPD",
+ "owner": {
+ "login": "wojciechcibor",
+ "id": 2141316,
+ "avatar_url": "https://avatars2.githubusercontent.com/u/2141316?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/wojciechcibor",
+ "html_url": "https://github.com/wojciechcibor",
+ "followers_url": "https://api.github.com/users/wojciechcibor/followers",
+ "following_url": "https://api.github.com/users/wojciechcibor/following{/other_user}",
+ "gists_url": "https://api.github.com/users/wojciechcibor/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/wojciechcibor/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/wojciechcibor/subscriptions",
+ "organizations_url": "https://api.github.com/users/wojciechcibor/orgs",
+ "repos_url": "https://api.github.com/users/wojciechcibor/repos",
+ "events_url": "https://api.github.com/users/wojciechcibor/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/wojciechcibor/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/wojciechcibor/SiSPD",
+ "description": "Symulacja i sterowanie procesów dyskretnych - projekt.",
+ "fork": false,
+ "url": "https://api.github.com/repos/wojciechcibor/SiSPD",
+ "forks_url": "https://api.github.com/repos/wojciechcibor/SiSPD/forks",
+ "keys_url": "https://api.github.com/repos/wojciechcibor/SiSPD/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/wojciechcibor/SiSPD/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/wojciechcibor/SiSPD/teams",
+ "hooks_url": "https://api.github.com/repos/wojciechcibor/SiSPD/hooks",
+ "issue_events_url": "https://api.github.com/repos/wojciechcibor/SiSPD/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/wojciechcibor/SiSPD/events",
+ "assignees_url": "https://api.github.com/repos/wojciechcibor/SiSPD/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/wojciechcibor/SiSPD/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/wojciechcibor/SiSPD/tags",
+ "blobs_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/wojciechcibor/SiSPD/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/wojciechcibor/SiSPD/languages",
+ "stargazers_url": "https://api.github.com/repos/wojciechcibor/SiSPD/stargazers",
+ "contributors_url": "https://api.github.com/repos/wojciechcibor/SiSPD/contributors",
+ "subscribers_url": "https://api.github.com/repos/wojciechcibor/SiSPD/subscribers",
+ "subscription_url": "https://api.github.com/repos/wojciechcibor/SiSPD/subscription",
+ "commits_url": "https://api.github.com/repos/wojciechcibor/SiSPD/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/wojciechcibor/SiSPD/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/wojciechcibor/SiSPD/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/wojciechcibor/SiSPD/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/wojciechcibor/SiSPD/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/wojciechcibor/SiSPD/merges",
+ "archive_url": "https://api.github.com/repos/wojciechcibor/SiSPD/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/wojciechcibor/SiSPD/downloads",
+ "issues_url": "https://api.github.com/repos/wojciechcibor/SiSPD/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/wojciechcibor/SiSPD/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/wojciechcibor/SiSPD/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/wojciechcibor/SiSPD/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/wojciechcibor/SiSPD/labels{/name}",
+ "releases_url": "https://api.github.com/repos/wojciechcibor/SiSPD/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/wojciechcibor/SiSPD/deployments",
+ "created_at": "2012-10-14T11:03:28Z",
+ "updated_at": "2013-10-20T12:47:33Z",
+ "pushed_at": "2012-10-22T21:09:02Z",
+ "git_url": "git://github.com/wojciechcibor/SiSPD.git",
+ "ssh_url": "git@github.com:wojciechcibor/SiSPD.git",
+ "clone_url": "https://github.com/wojciechcibor/SiSPD.git",
+ "svn_url": "https://github.com/wojciechcibor/SiSPD",
+ "homepage": null,
+ "size": 7297,
+ "stargazers_count": 2,
+ "watchers_count": 2,
+ "language": null,
+ "has_issues": true,
+ "has_projects": true,
+ "has_downloads": true,
+ "has_wiki": false,
+ "has_pages": false,
+ "forks_count": 1,
+ "mirror_url": null,
+ "archived": false,
+ "open_issues_count": 0,
+ "license": null,
+ "forks": 1,
+ "open_issues": 0,
+ "watchers": 2,
+ "default_branch": "master"
+ },
+ "source": {
+ "id": 6212829,
+ "name": "SiSPD",
+ "full_name": "wojciechcibor/SiSPD",
+ "owner": {
+ "login": "wojciechcibor",
+ "id": 2141316,
+ "avatar_url": "https://avatars2.githubusercontent.com/u/2141316?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/wojciechcibor",
+ "html_url": "https://github.com/wojciechcibor",
+ "followers_url": "https://api.github.com/users/wojciechcibor/followers",
+ "following_url": "https://api.github.com/users/wojciechcibor/following{/other_user}",
+ "gists_url": "https://api.github.com/users/wojciechcibor/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/wojciechcibor/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/wojciechcibor/subscriptions",
+ "organizations_url": "https://api.github.com/users/wojciechcibor/orgs",
+ "repos_url": "https://api.github.com/users/wojciechcibor/repos",
+ "events_url": "https://api.github.com/users/wojciechcibor/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/wojciechcibor/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/wojciechcibor/SiSPD",
+ "description": "Symulacja i sterowanie procesów dyskretnych - projekt.",
+ "fork": false,
+ "url": "https://api.github.com/repos/wojciechcibor/SiSPD",
+ "forks_url": "https://api.github.com/repos/wojciechcibor/SiSPD/forks",
+ "keys_url": "https://api.github.com/repos/wojciechcibor/SiSPD/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/wojciechcibor/SiSPD/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/wojciechcibor/SiSPD/teams",
+ "hooks_url": "https://api.github.com/repos/wojciechcibor/SiSPD/hooks",
+ "issue_events_url": "https://api.github.com/repos/wojciechcibor/SiSPD/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/wojciechcibor/SiSPD/events",
+ "assignees_url": "https://api.github.com/repos/wojciechcibor/SiSPD/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/wojciechcibor/SiSPD/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/wojciechcibor/SiSPD/tags",
+ "blobs_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/wojciechcibor/SiSPD/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/wojciechcibor/SiSPD/languages",
+ "stargazers_url": "https://api.github.com/repos/wojciechcibor/SiSPD/stargazers",
+ "contributors_url": "https://api.github.com/repos/wojciechcibor/SiSPD/contributors",
+ "subscribers_url": "https://api.github.com/repos/wojciechcibor/SiSPD/subscribers",
+ "subscription_url": "https://api.github.com/repos/wojciechcibor/SiSPD/subscription",
+ "commits_url": "https://api.github.com/repos/wojciechcibor/SiSPD/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/wojciechcibor/SiSPD/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/wojciechcibor/SiSPD/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/wojciechcibor/SiSPD/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/wojciechcibor/SiSPD/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/wojciechcibor/SiSPD/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/wojciechcibor/SiSPD/merges",
+ "archive_url": "https://api.github.com/repos/wojciechcibor/SiSPD/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/wojciechcibor/SiSPD/downloads",
+ "issues_url": "https://api.github.com/repos/wojciechcibor/SiSPD/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/wojciechcibor/SiSPD/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/wojciechcibor/SiSPD/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/wojciechcibor/SiSPD/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/wojciechcibor/SiSPD/labels{/name}",
+ "releases_url": "https://api.github.com/repos/wojciechcibor/SiSPD/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/wojciechcibor/SiSPD/deployments",
+ "created_at": "2012-10-14T11:03:28Z",
+ "updated_at": "2013-10-20T12:47:33Z",
+ "pushed_at": "2012-10-22T21:09:02Z",
+ "git_url": "git://github.com/wojciechcibor/SiSPD.git",
+ "ssh_url": "git@github.com:wojciechcibor/SiSPD.git",
+ "clone_url": "https://github.com/wojciechcibor/SiSPD.git",
+ "svn_url": "https://github.com/wojciechcibor/SiSPD",
+ "homepage": null,
+ "size": 7297,
+ "stargazers_count": 2,
+ "watchers_count": 2,
+ "language": null,
+ "has_issues": true,
+ "has_projects": true,
+ "has_downloads": true,
+ "has_wiki": false,
+ "has_pages": false,
+ "forks_count": 1,
+ "mirror_url": null,
+ "archived": false,
+ "open_issues_count": 0,
+ "license": null,
+ "forks": 1,
+ "open_issues": 0,
+ "watchers": 2,
+ "default_branch": "master"
+ },
+ "network_count": 1,
+ "subscribers_count": 1
+}
diff --git a/src/test/resources/mappings/repos_sinu0_sispd-570cfa1e-8aaa-4cd6-8037-d919654649d5.json b/src/test/resources/mappings/repos_sinu0_sispd-570cfa1e-8aaa-4cd6-8037-d919654649d5.json
new file mode 100644
index 0000000..8201416
--- /dev/null
+++ b/src/test/resources/mappings/repos_sinu0_sispd-570cfa1e-8aaa-4cd6-8037-d919654649d5.json
@@ -0,0 +1,39 @@
+{
+ "id": "570cfa1e-8aaa-4cd6-8037-d919654649d5",
+ "name": "repos_sinu0_sispd",
+ "request": {
+ "url": "/repos/sinu0/SiSPD",
+ "method": "GET"
+ },
+ "response": {
+ "status": 200,
+ "bodyFileName": "repos_sinu0_sispd-570cfa1e-8aaa-4cd6-8037-d919654649d5.json",
+ "headers": {
+ "Server": "GitHub.com",
+ "Date": "Fri, 16 Mar 2018 22:04:16 GMT",
+ "Content-Type": "application/json; charset=utf-8",
+ "Status": "200 OK",
+ "X-RateLimit-Limit": "60",
+ "X-RateLimit-Remaining": "47",
+ "X-RateLimit-Reset": "1521240469",
+ "Cache-Control": "public, max-age=60, s-maxage=60",
+ "Vary": "Accept",
+ "ETag": "W/\"7a441b97c24d52980b539d9d4ae38cd3\"",
+ "Last-Modified": "Sat, 12 Jan 2013 19:04:16 GMT",
+ "X-GitHub-Media-Type": "unknown, github.v3",
+ "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval",
+ "Access-Control-Allow-Origin": "*",
+ "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+ "X-Frame-Options": "deny",
+ "X-Content-Type-Options": "nosniff",
+ "X-XSS-Protection": "1; mode=block",
+ "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+ "Content-Security-Policy": "default-src 'none'",
+ "X-Runtime-rack": "0.054554",
+ "X-GitHub-Request-Id": "8956:23E8:D5D24:1D7E85:5AAC3F5F"
+ }
+ },
+ "uuid": "570cfa1e-8aaa-4cd6-8037-d919654649d5",
+ "persistent": true,
+ "insertionIndex": 3
+}
\ No newline at end of file
diff --git a/src/test/resources/mappings/repos_sinu0_sispds-2a04e50f-19c2-4b93-a3dd-17101e481e5f.json b/src/test/resources/mappings/repos_sinu0_sispds-2a04e50f-19c2-4b93-a3dd-17101e481e5f.json
new file mode 100644
index 0000000..313b36a
--- /dev/null
+++ b/src/test/resources/mappings/repos_sinu0_sispds-2a04e50f-19c2-4b93-a3dd-17101e481e5f.json
@@ -0,0 +1,35 @@
+{
+ "id": "2a04e50f-19c2-4b93-a3dd-17101e481e5f",
+ "name": "repos_sinu0_sispds",
+ "request": {
+ "url": "/repos/sinu0/Forbidden",
+ "method": "GET"
+ },
+ "response": {
+ "status": 403,
+ "body": "{\n\"documentation_url\": \"https://developer.github.com/v3/#abuse-rate-limits\",\n\"message\": \"You have triggered an abuse detection mechanism. Please wait a few minutes before you try again.\"\n}\n",
+ "headers": {
+ "Server": "GitHub.com",
+ "Date": "Sat, 17 Mar 2018 10:09:53 GMT",
+ "Content-Type": "application/json; charset=utf-8",
+ "Transfer-Encoding": "chunked",
+ "Status": "403 Forbidden",
+ "Retry-After": "60",
+ "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval",
+ "Access-Control-Allow-Origin": "*",
+ "X-GitHub-Media-Type": "github.v3; format=json",
+ "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+ "X-Frame-Options": "deny",
+ "X-Content-Type-Options": "nosniff",
+ "X-XSS-Protection": "1; mode=block",
+ "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+ "Expect-CT": "max-age=2592000, report-uri='https://api.github.com/_private/browser/errors'",
+ "Content-Security-Policy": "default-src 'none'; base-uri 'self'; block-all-mixed-content; child-src render.githubusercontent.com; connect-src 'self' uploads.github.com status.github.com collector.githubapp.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com; font-src assets-cdn.github.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; img-src 'self' data: assets-cdn.github.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com collector.githubapp.com avatars0.githubusercontent.com avatars1.githubusercontent.com avatars2.githubusercontent.com avatars3.githubusercontent.com github-cloud.s3.amazonaws.com; manifest-src 'self'; media-src 'none'; script-src assets-cdn.github.com; style-src 'unsafe-inline' assets-cdn.github.com; worker-src 'self'",
+ "X-Runtime-rack": "0.007926",
+ "X-GitHub-Request-Id": "BC42:23E6:27A97E:59F513:5AACE971"
+ }
+ },
+ "uuid": "2a04e50f-19c2-4b93-a3dd-17101e481e8f",
+ "persistent": true,
+ "insertionIndex": 5
+}
\ No newline at end of file
diff --git a/src/test/resources/mappings/repos_sinu0_sispds-2a04e50f-19c2-4b93-a3dd-17101e481e8f.json b/src/test/resources/mappings/repos_sinu0_sispds-2a04e50f-19c2-4b93-a3dd-17101e481e8f.json
new file mode 100644
index 0000000..a55f20c
--- /dev/null
+++ b/src/test/resources/mappings/repos_sinu0_sispds-2a04e50f-19c2-4b93-a3dd-17101e481e8f.json
@@ -0,0 +1,35 @@
+{
+ "id": "2a04e50f-19c2-4b93-a3dd-17101e481e8f",
+ "name": "repos_sinu0_sispds",
+ "request": {
+ "url": "/repos/sinu0/SiSPDs",
+ "method": "GET"
+ },
+ "response": {
+ "status": 404,
+ "body": "{\n \"message\": \"Not Found\",\n \"documentation_url\": \"https://developer.github.com/v3/repos/#get\"\n}\n",
+ "headers": {
+ "Server": "GitHub.com",
+ "Date": "Fri, 16 Mar 2018 22:05:04 GMT",
+ "Content-Type": "application/json; charset=utf-8",
+ "Status": "404 Not Found",
+ "X-RateLimit-Limit": "60",
+ "X-RateLimit-Remaining": "45",
+ "X-RateLimit-Reset": "1521240469",
+ "X-GitHub-Media-Type": "unknown, github.v3",
+ "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval",
+ "Access-Control-Allow-Origin": "*",
+ "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+ "X-Frame-Options": "deny",
+ "X-Content-Type-Options": "nosniff",
+ "X-XSS-Protection": "1; mode=block",
+ "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+ "Content-Security-Policy": "default-src 'none'",
+ "X-Runtime-rack": "0.019445",
+ "X-GitHub-Request-Id": "8A96:23E8:D6E71:1DA44B:5AAC3F8C"
+ }
+ },
+ "uuid": "2a04e50f-19c2-4b93-a3dd-17101e481e8f",
+ "persistent": true,
+ "insertionIndex": 5
+}
\ No newline at end of file