public void GivenAMissingCallBackUriParam_AuthenticateClient_ThrowsAnAuthenticationException()
            {
                // Arrange.
                var mockRestResponse = new Mock<IRestResponse<InstagramAccessTokenResult>>();
                mockRestResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.BadRequest);
                mockRestResponse.Setup(x => x.StatusDescription).Returns("Bad Request");
                mockRestResponse.Setup(x => x.Content)
                                .Returns(
                                    "{\"error\":{\"message\":\"Missing redirect_uri parameter.\",\"type\":\"OAuthException\",\"code\":191}}");

                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponse.Object);

                mockRestClient.Setup(x => x.Execute<InstagramAccessTokenResult>(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponse.Object);

                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                instagramProvider.CallBackUri = new Uri("http://2p1s.com");
                const string existingState = "http://2p1s.com";
                var queryStringParameters = new NameValueCollection
                {
                    {"state", existingState},
                    {"code", "whatever"}
                };

                // Act.
                var result =
                    Assert.Throws<AuthenticationException>(
                        () => instagramProvider.AuthenticateClient(queryStringParameters, existingState));

                // Assert.
                Assert.NotNull(result);
                Assert.Equal(
                    "Failed to obtain an Access Token from Instagram OR the the response was not an HTTP Status 200 OK. Response Status: BadRequest. Response Description: Bad Request. Error Content: {\"error\":{\"message\":\"Missing redirect_uri parameter.\",\"type\":\"OAuthException\",\"code\":191}}",
                    result.Message);
            }
            public void GivenAFailedCSRFStateCheck_AuthenticateClient_ThrowsAnAuthenticationException()
            {
                // Arrange.
                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>())).Returns(It.IsAny<IRestResponse>);
                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                var queryStringParameters = new NameValueCollection
                {
                    {"code", "aaa"},
                    {"state", "bbb"}
                };

                // Act.
                var result =
                    Assert.Throws<AuthenticationException>(
                        () => instagramProvider.AuthenticateClient(queryStringParameters, "meh"));

                // Assert.
                Assert.NotNull(result);
                Assert.Equal("The states do not match. It's possible that you may be a victim of a CSRF.",
                             result.Message);
            }
            public void GivenAnExceptionOccursWhileTryingToRequestAnAccessToken_AuthenticateClient_ThrowsAnAuthenticationException()
            {
                // Arrange.
                const string exceptionMessage =
                    "1st World Problems: Too many rooms in my house. Can't decide where to sleep.";
                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>()))
                              .Throws(new Exception(exceptionMessage));

                mockRestClient.Setup(x => x.Execute<InstagramAccessTokenResult>(It.IsAny<IRestRequest>()))
                              .Throws(new Exception(exceptionMessage));

                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                instagramProvider.CallBackUri = new Uri("http://2p1s.com");
                const string existingState = "http://2p1s.com";
                var queryStringParameters = new NameValueCollection
                {
                    {"state", existingState},
                    {"code", "whatever"}
                };

                // Act.
                var result =
                    Assert.Throws<AuthenticationException>(
                        () => instagramProvider.AuthenticateClient(queryStringParameters, existingState));

                // Assert.
                Assert.NotNull(result);
                Assert.Equal("Failed to retrieve an oauth access token from Instagram.", result.Message);
                Assert.NotNull(result.InnerException);
                Assert.Equal(exceptionMessage, result.InnerException.Message);
            }
            public void GivenValidCredentials_AuthenticateClient_ReturnsAnAuthenticatedClientWithUserInformation()
            {
                // Arrange.
                var mockRestResponseAccessToken = new Mock<IRestResponse>();
                mockRestResponseAccessToken.Setup(x => x.StatusCode).Returns(HttpStatusCode.OK);
                mockRestResponseAccessToken.Setup(x => x.Content).Returns("access_token=foo");

                var selfResult = new InstagramSelfResult
                {
                    Data = new InstagramSelfResult.DataInner
                    {
                        Id = 1,
                        FullName = "Jan Kowalski",
                        Username = "******",
                        ProfilePicture = "http://some-url"
                    }
                };

                var mockRestResponseApiMe = new Mock<IRestResponse<InstagramSelfResult>>();
                mockRestResponseApiMe.Setup(x => x.StatusCode).Returns(HttpStatusCode.OK);
                mockRestResponseApiMe.Setup(x => x.Data).Returns(selfResult);

                var mockRestResponseApiToken = new Mock<IRestResponse<InstagramAccessTokenResult>>();
                mockRestResponseApiToken.Setup(x => x.StatusCode).Returns(HttpStatusCode.OK);
                mockRestResponseApiToken.Setup(x => x.Data).Returns(new InstagramAccessTokenResult
                {
                    AccessToken = "some"
                });

                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponseAccessToken.Object);

                mockRestClient.Setup(x => x.Execute<InstagramSelfResult>(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponseApiMe.Object);

                mockRestClient.Setup(x => x.Execute<InstagramAccessTokenResult>(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponseApiToken.Object);

                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                instagramProvider.CallBackUri = new Uri("http://2p1s.com");
                const string existingState = "http://2p1s.com";
                var queryStringParameters = new NameValueCollection
                {
                    {"state", existingState},
                    {"code", "whatever"}
                };
                // Act.
                var result =
                    instagramProvider.AuthenticateClient(queryStringParameters, existingState);

                // Assert.
                Assert.NotNull(result);
                Assert.Equal("instagram", result.ProviderName);
                Assert.NotNull(result.AccessToken);
                Assert.NotNull(result.UserInformation);
                Assert.False(string.IsNullOrEmpty(result.UserInformation.Id));
                Assert.NotNull(result.UserInformation.Name);
                Assert.NotNull(result.UserInformation.UserName);
            }
            public void GivenSomeInvalidRequestToken_AuthenticateClient_ThrowsAnAuthenticationException()
            {
                // Arrange.
                var mockRestResponse = new Mock<IRestResponse<InstagramAccessTokenResult>>();
                mockRestResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.Unauthorized);
                mockRestResponse.Setup(x => x.StatusDescription).Returns("Unauthorised");
                mockRestResponse.Setup(x => x.Content).Returns("{error:hi there asshat}");

                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponse.Object);

                mockRestClient.Setup(x => x.Execute<InstagramAccessTokenResult>(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponse.Object);

                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                instagramProvider.CallBackUri = new Uri("http://2p1s.com");
                const string existingState = "http://2p1s.com";
                var queryStringParameters = new NameValueCollection
                {
                    {"state", existingState},
                    {"code", "whatever"}
                };

                // Act.
                var result =
                    Assert.Throws<AuthenticationException>(
                        () => instagramProvider.AuthenticateClient(queryStringParameters, existingState));

                // Assert.
                Assert.NotNull(result);
                Assert.Equal(
                    "Failed to obtain an Access Token from Instagram OR the the response was not an HTTP Status 200 OK. Response Status: Unauthorized. Response Description: Unauthorised. Error Content: {error:hi there asshat}",
                    result.Message);
            }
            public void GivenSomeErrorOccuredWhileTryingToRetrieveAccessToken_AuthenticateClient_ThrowsAnAuthenticationException()
            {
                // Arrange.
                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>())).Returns(It.IsAny<IRestResponse>);
                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                const string existingState = "http://2p1s.com";
                var queryStringParameters = new NameValueCollection
                {
                    {"state", existingState},
                    {"error_reason", "aaa"},
                    {"error", "bbb"},
                    {"error_description", "ccc"}
                };

                // Act.
                var result =
                    Assert.Throws<AuthenticationException>(
                        () => instagramProvider.AuthenticateClient(queryStringParameters, existingState));

                // Assert.
                Assert.NotNull(result);
                Assert.Equal("Reason: aaa. Error: bbb. Description: ccc.", result.Message);
            }
            public void GivenNoValidAccessTokenParams_AuthenticateClient_ThrowsAnAuthenticationException()
            {
                // Arrange.
                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>())).Returns(It.IsAny<IRestResponse>);
                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                const string existingState = "http://2p1s.com";
                var queryStringParameters = new NameValueCollection
                {
                    {"state", existingState} // No code param.
                };

                // Act.
                var result =
                    Assert.Throws<AuthenticationException>(
                        () => instagramProvider.AuthenticateClient(queryStringParameters, existingState));

                // Assert.
                Assert.NotNull(result);
                Assert.Equal("No code parameter provided in the response query string from Instagram.", result.Message);
            }
            public void GivenAValidAccessTokenButApiMeThrowsAnException_AuthenticateClient_ThrowsAnAuthenticationException()
            {
                // Arrange.
                const string exceptionMessage =
                    "1st World Problems: The Pizza guy arrived. Before I finished downloading the movie.";
                var mockRestResponse = new Mock<IRestResponse<InstagramSelfResult>>();
                mockRestResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.OK);
                mockRestResponse.Setup(x => x.Content).Returns("access_token=foo");

                var mockRestResponseApiToken = new Mock<IRestResponse<InstagramAccessTokenResult>>();
                mockRestResponseApiToken.Setup(x => x.StatusCode).Returns(HttpStatusCode.OK);
                mockRestResponseApiToken.Setup(x => x.Data).Returns(new InstagramAccessTokenResult
                {
                    AccessToken = "some"
                });
                var mockRestClient = new Mock<IRestClient>();
                mockRestClient.Setup(x => x.Execute(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponse.Object);

                mockRestClient.Setup(x => x.Execute<InstagramSelfResult>(It.IsAny<IRestRequest>()))
                              .Throws(new Exception(exceptionMessage));

                mockRestClient.Setup(x => x.Execute<InstagramAccessTokenResult>(It.IsAny<IRestRequest>()))
                              .Returns(mockRestResponseApiToken.Object);

                var instagramProvider = new InstagramProvider("a", "b",
                                                            null, new RestClientFactory(mockRestClient.Object));
                instagramProvider.CallBackUri = new Uri("http://2p1s.com");
                const string existingState = "http://2p1s.com";
                var queryStringParameters = new NameValueCollection
                {
                    {"state", existingState},
                    {"code", "whatever"}
                };

                // Act.
                var result =
                    Assert.Throws<AuthenticationException>(
                        () => instagramProvider.AuthenticateClient(queryStringParameters, existingState));

                // Assert.
                Assert.NotNull(result);
                Assert.Equal("Failed to retrieve any Self data from the Instagram Api.", result.Message);
            }