/** * The MIT License (MIT) * * Copyright (c) 2014-2017 Yegor Bugayenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.takes.facets.auth.social; import java.io.IOException; import java.net.URI; import javax.json.Json; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.takes.HttpException; import org.takes.Request; import org.takes.Response; import org.takes.Take; import org.takes.facets.auth.Identity; import org.takes.facets.fork.FkRegex; import org.takes.facets.fork.TkFork; import org.takes.http.FtRemote; import org.takes.rq.RqFake; import org.takes.rq.RqGreedy; import org.takes.rq.RqHref; import org.takes.rq.form.RqFormBase; import org.takes.rq.form.RqFormSmart; import org.takes.rs.RsJson; import org.takes.rs.xe.RsXembly; import org.takes.rs.xe.XeDirectives; import org.xembly.Directives; /** * Test case for {@link org.takes.rq.RqMethod}. * @author Dmitry Zaytsev (dmitry.zaytsev@gmail.com) * @version $Id: 62e644deaf81da069c197cd9e299c11f43db5205 $ * @since 0.15.2 * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) */ public final class PsGithubTest { /** * GitHubToken. */ private static final String GIT_HUB_TOKEN = "GitHubToken"; /** * XPath access_token string. */ private static final String ACCESS_TOKEN = "access_token"; /** * XPath login string. */ private static final String LOGIN = "login"; /** * Octocat URL string. */ private static final String OCTOCAT_GIF_URL = "https://github.com/img/octocat.gif"; /** * XPath octocat string. */ private static final String OCTOCAT = "octocat"; /** * A Junit Exception test variable. */ @Rule public transient ExpectedException thrown = ExpectedException.none(); /** * PsGithub can fail on no access token. * @throws IOException If some problem inside. */ @Test public void failsOnNoAccessToken() throws IOException { this.thrown.expect(HttpException.class); this.thrown.expectMessage("No access token"); this.performLogin(PsGithubTest.directiveWithoutAccessToken()); } /** * PsGithub can login. * @throws IOException If some problem inside. */ @Test public void canLogin() throws IOException { this.performLogin( PsGithubTest.directiveWithoutAccessToken() .add(PsGithubTest.ACCESS_TOKEN) .set(PsGithubTest.GIT_HUB_TOKEN) ); } /** * Performs the basic login. * @param directive The directive object. * @throws IOException If some problem inside. */ private void performLogin(final Directives directive) throws IOException { final String app = "app"; final String key = "key"; final Take take = new TkFork( new FkRegex( "/login/oauth/access_token", new Take() { @Override public Response act(final Request req) throws IOException { final Request greq = new RqGreedy(req); final String code = "code"; PsGithubTest.assertParam(greq, code, code); PsGithubTest.assertParam(greq, "client_id", app); PsGithubTest.assertParam(greq, "client_secret", key); return new RsXembly( new XeDirectives(directive.toString()) ); } } ), new FkRegex( "/user", new TkFakeLogin() ) ); new FtRemote(take).exec( // @checkstyle AnonInnerLengthCheck (100 lines) new FtRemote.Script() { @Override public void exec(final URI home) throws IOException { final Identity identity = new PsGithub( app, key, home.toString(), home.toString() ).enter(new RqFake("GET", "?code=code")).get(); MatcherAssert.assertThat( identity.urn(), Matchers.equalTo("urn:github:1") ); MatcherAssert.assertThat( identity.properties().get(PsGithubTest.LOGIN), Matchers.equalTo(PsGithubTest.OCTOCAT) ); MatcherAssert.assertThat( identity.properties().get("avatar"), Matchers.equalTo(PsGithubTest.OCTOCAT_GIF_URL) ); } } ); } /** * Creates the basic directives, without access token. * @return A basic directive. */ private static Directives directiveWithoutAccessToken() { return new Directives().add("OAuth") .add("token_type").set("bearer").up() .add("scope").set("repo,gist").up(); } /** * Checks the parameter value for the expected value. * @param req Request * @param param Parameter name * @param value Parameter value * @throws IOException If some problem inside */ private static void assertParam(final Request req, final CharSequence param, final String value) throws IOException { MatcherAssert.assertThat( new RqFormSmart(new RqFormBase(req)).single(param), Matchers.equalTo(value) ); } /** * An inner class for the Take implementation testing. */ private static final class TkFakeLogin implements Take { @Override public Response act(final Request req) throws IOException { MatcherAssert.assertThat( new RqHref.Base(req).href() .param(PsGithubTest.ACCESS_TOKEN) .iterator().next(), Matchers.containsString(PsGithubTest.GIT_HUB_TOKEN) ); return new RsJson( Json.createObjectBuilder() .add(PsGithubTest.LOGIN, PsGithubTest.OCTOCAT) .add("id", 1) .add( "avatar_url", PsGithubTest.OCTOCAT_GIF_URL ) .build() ); } } }