public void should_not_return_oauth_token_if_Token_not_provided()
		{
			var requestData = new RequestData
				{
					RequiresSignature = true
				};

			var actual = GetAuthHeader(requestData);

			Assert.That(actual, Is.Not.StringContaining("oauth_token="));
		}
		public void should_not_do_oauth_if_not_required()
		{
			var requestData = new RequestData
				{
					RequiresSignature = false
				};

			var actual = GetAuthHeader(requestData);

			Assert.That(actual, Is.Not.StringContaining("oauth_token"));
			Assert.That(actual, Is.StringContaining("oauth_consumer_key="));
		}
		public void should_return_oauth_token_if_Token_provided()
		{
			var requestData = new RequestData
				{
					RequiresSignature = true,
					OAuthToken = "TOKEN",
					OAuthTokenSecret = "SECRET"
				};

			var actual = GetAuthHeader(requestData);

			Assert.That(actual, Is.StringContaining("oauth_token="));
		}
		public ApiRequest SubstituteParamsInRequest(RequestData requestData)
		{
			var apiBaseUrl = GetApiBaseUrl(requestData);

			var withoutRouteParameters = new Dictionary<string, string>(requestData.Parameters);

			var pathWithRouteParamsSubstituted = SubstituteRouteParameters(requestData.Endpoint, withoutRouteParameters);

			return new ApiRequest
			{
				AbsoluteUrl = UriPath.Combine(apiBaseUrl, pathWithRouteParamsSubstituted),
				Parameters = withoutRouteParameters
			};
		}
		public void Should_return_data()
		{
			var requestData = new RequestData
				{
					HttpMethod = HttpMethod.Get,
					Endpoint = "testpath",
				};

			var routeParamsSubstitutor = new RouteParamsSubstitutor(_apiUri);
			var result = routeParamsSubstitutor.SubstituteParamsInRequest(requestData);

			Assert.That(result, Is.Not.Null);
			Assert.That(result.AbsoluteUrl, Is.Not.Empty);
			Assert.That(result.Parameters, Is.Not.Null);
		}
		public void Should_substitue_route_parameters()
		{
			var requestData = new RequestData
			{
				Endpoint = "something/{route}",
				Parameters = new Dictionary<string, string>
					{
						{"route","routevalue"}
					}
			};

			var routeParamsSubstitutor = new RouteParamsSubstitutor(_apiUri);
			var result = routeParamsSubstitutor.SubstituteParamsInRequest(requestData);

			Assert.That(result.AbsoluteUrl, Is.StringContaining("something/routevalue"));
		}
		public void Should_not_care_how_many_times_you_create_an_endpoint()
		{
			var endPointState = new RequestData
			{
				Endpoint = "{slug}",
				HttpMethod = HttpMethod.Get,
				Parameters = new Dictionary<string, string>
				{
					{"slug", "something"}
				}
			};

			var result1 = _requestBuilder.BuildRequest(endPointState);
			var result2 = _requestBuilder.BuildRequest(endPointState);

			Assert.That(result1.Url, Is.EqualTo(result2.Url));
		}
		public void should_return_Authorization_OAuth_headers_as_outlined_in_OAuthspec_if_endpoint_requires_signature_without_usertoken()
		{
			var requestData = new RequestData
				{
					RequiresSignature = true
				};

			var actual = GetAuthHeader(requestData);

			Assert.That(actual, Is.Not.Empty);
			Assert.That(actual, Is.StringStarting("OAuth"));
			Assert.That(actual, Is.StringContaining("oauth_consumer_key="));
			Assert.That(actual, Is.StringContaining("oauth_signature_method="));
			Assert.That(actual, Is.StringContaining("oauth_signature="));
			Assert.That(actual, Is.StringContaining("oauth_timestamp="));
			Assert.That(actual, Is.StringContaining("oauth_nonce="));
			Assert.That(actual, Is.StringContaining("oauth_version="));
		}
		public void Should_use_api_uri_provided_by_IApiUri_interface()
		{
			const string expectedApiUri = "http://api.7dizzle";

			var apiUri = A.Fake<IApiUri>();
			A.CallTo(() => apiUri.Uri).Returns(expectedApiUri);
			_requestBuilder = new RequestBuilder(apiUri, EssentialDependencyCheck<IOAuthCredentials>.Instance);

			var requestData = new RequestData
			{
				Endpoint = "test",
				HttpMethod = HttpMethod.Get,
				Headers = new Dictionary<string, string>()
			};

			var response = _requestBuilder.BuildRequest(requestData);

			Assert.That(response.Url, Is.StringStarting(expectedApiUri));
		}
		public void Should_substitue_multiple_route_parameters()
		{
			var requestData = new RequestData
			{
				Endpoint = "something/{firstRoute}/{secondRoute}/thrid/{thirdRoute}",
				Parameters = new Dictionary<string, string>
					{
						{"firstRoute" , "firstValue"},
						{"secondRoute","secondValue"},
						{"thirdRoute" , "thirdValue"}
							
					}
			};

			var routeParamsSubstitutor = new RouteParamsSubstitutor(_apiUri);
			var result = routeParamsSubstitutor.SubstituteParamsInRequest(requestData);

			Assert.That(result.AbsoluteUrl, Is.StringContaining("something/firstvalue/secondvalue/thrid/thirdvalue"));
		}
		public void Should_make_url_with_url_encoded_parameters()
		{
			const string unEncodedParameterValue = "Alive & Amplified";
			const string encodedParameterValue = "Alive%20%26%20Amplified";

			var testParameters = new Dictionary<string, string> { { "q", unEncodedParameterValue } };
			var expectedUrl = string.Format("{0}/test?q={1}", API_URL, encodedParameterValue);

			var requestData = new RequestData
				{
					Endpoint = "test",
					HttpMethod = HttpMethod.Get,
					Parameters = testParameters
				};

			var request = _requestBuilder.BuildRequest(requestData);

			Assert.That(request.Url, Is.EqualTo(expectedUrl));
		}
		public void Should_add_traceId_header_as_a_valid_guid()
		{
			const string expectedApiUri = "http://api.7dizzle";
			var baseUriProvider = A.Fake<IBaseUriProvider>();
			A.CallTo(() => baseUriProvider.BaseUri(A<RequestData>.Ignored)).Returns(expectedApiUri);

			var requestData = new RequestData
			{
				Endpoint = "test",
				HttpMethod = HttpMethod.Get,
				Headers = new Dictionary<string, string>(),
				BaseUriProvider = baseUriProvider
			};
			var request = _requestBuilder.BuildRequest(requestData);

			var traceIdHeader = request.Headers["x-7d-traceid"];
			Assert.That(traceIdHeader, Is.Not.Null);
			Assert.DoesNotThrow(() => Guid.Parse(traceIdHeader));
		}
		public void Post_data_with_requestBody_does_not_add_query_string_params()
		{
			var queryStringParameters = new Dictionary<string, string>();
			var requestData = new RequestData
			{
				HttpMethod = HttpMethod.Post,
				Payload = new RequestPayload("application/x-www-form-urlencoded", "foo=bar"),
				RequiresSignature = true
			};

			var credentials = A.Fake<IOAuthCredentials>();
			A.CallTo(() => credentials.ConsumerKey).Returns("MyKey");
			A.CallTo(() => credentials.ConsumerSecret).Returns("MySecret");

			var substitutor = A.Fake<IRouteParamsSubstitutor>();
			A.CallTo(() => substitutor.SubstituteParamsInRequest(requestData))
				.Returns(new ApiRequest
				{
					Parameters = queryStringParameters,
					AbsoluteUrl = "http://www.7digital.com"
				});

			_requestBuilder = new RequestBuilder(substitutor, credentials);
			_requestBuilder.BuildRequest(requestData);

			Assert.That(queryStringParameters.Count, Is.EqualTo(0), "Unexpected query string parameter");
		}
		public void Should_allow_a_custom_traceId_to_be_specified()
		{
			const string expectedApiUri = "http://api.7dizzle";
			var baseUriProvider = A.Fake<IBaseUriProvider>();
			A.CallTo(() => baseUriProvider.BaseUri(A<RequestData>.Ignored)).Returns(expectedApiUri);

			const string customTraceId = "Immagonnatrace4you";

			var requestData = new RequestData
			{
				Endpoint = "test",
				HttpMethod = HttpMethod.Get,
				Headers = new Dictionary<string, string>(),
				BaseUriProvider = baseUriProvider,
				TraceId = customTraceId
			};
			var request = _requestBuilder.BuildRequest(requestData);

			var traceIdHeader = request.Headers["x-7d-traceid"];
			Assert.That(traceIdHeader, Is.Not.Null);
			Assert.That(traceIdHeader, Is.EqualTo(customTraceId));
		}
		public void Should_remove_parameters_that_match()
		{
			var requestData = new RequestData
			{
				Endpoint = "something/{route}",
				Parameters = new Dictionary<string, string>
					{
						{"route","routevalue"},
						{"foo","bar"}
					}
			};

			var routeParamsSubstitutor = new RouteParamsSubstitutor(_apiUri);
			var result = routeParamsSubstitutor.SubstituteParamsInRequest(requestData);

			Assert.That(result.Parameters.ContainsKey("route"), Is.False);
			Assert.That(result.Parameters.ContainsKey("foo"), Is.True);
		}
		public void Post_data_with_params_defaults_to_form_urlencoded_payload()
		{
			var parameters = new Dictionary<string, string>
			{
				{"one", "foo"}
			};
			var requestData = new RequestData
			{
				Parameters = parameters,
				HttpMethod = HttpMethod.Post
			};

			var request = _requestBuilder.BuildRequest(requestData);
			Assert.That(request.Url, Is.Not.StringContaining("?one=foo"));
			Assert.That(request.Body.Data, Is.StringContaining("one=foo"));
			Assert.That(request.Body.ContentType, Is.StringContaining("application/x-www-form-urlencoded"));
		}
		public void Post_data_with_requestBody_passes_post_body_to_main_request()
		{
			var requestData = new RequestData
			{
				HttpMethod = HttpMethod.Post,
				Payload = new RequestPayload("text/plain", "I am a payload")
			};

			var buildRequest = _requestBuilder.BuildRequest(requestData);
			Assert.That(buildRequest.Body.Data, Is.EqualTo("I am a payload"));
			Assert.That(buildRequest.Body.ContentType, Is.EqualTo("text/plain"));
		}
		public void Should_use_base_uri_when_it_is_present()
		{
			const string expectedApiUri = "http://api.7dizzle";
			var baseUriProvider = A.Fake<IBaseUriProvider>();
			A.CallTo(() => baseUriProvider.BaseUri(A<RequestData>.Ignored)).Returns(expectedApiUri);

			var requestData = new RequestData
			{
				Endpoint = "test",
				HttpMethod = HttpMethod.Get,
				Headers = new Dictionary<string, string>(),
				BaseUriProvider = baseUriProvider
			};

			var response = _requestBuilder.BuildRequest(requestData);

			Assert.That(response.Url, Is.StringStarting(expectedApiUri));
		}
		public void Should_include_request_params()
		{
			var requestData = new RequestData
			{
				HttpMethod = HttpMethod.Get,
				Endpoint = "http://api.com/endpoint",
				Parameters = new Dictionary<string, string>
					{
						{ "a", "b" },
						{ "c", "d" }
					},
				RequiresSignature = true,
				OAuthToken = "TOKEN",
				OAuthTokenSecret = "SECRET",
				Payload = null
			};

			var actual = GetAuthHeader(requestData);

			Assert.That(actual, Is.StringContaining("oauth_token="));
		}
		public void Post_data_with_params_defaults_to_key_value_pair_post_body()
		{
			var parameters = new Dictionary<string, string>
			{
				{"one", "one"}
			};
			var requestData = new RequestData
			{
				Parameters = parameters,
				HttpMethod = HttpMethod.Post
			};

			var buildRequest = _requestBuilder.BuildRequest(requestData);
			Assert.That(buildRequest.Body.Data, Is.EqualTo(parameters.ToQueryString()));
			Assert.That(buildRequest.Body.ContentType, Is.EqualTo("application/x-www-form-urlencoded"));
		}
		private string GetApiBaseUrl(RequestData requestData)
		{
			var baseUriProvider = requestData.BaseUriProvider ?? _defaultBaseUriProvider;

			return baseUriProvider.BaseUri(requestData);
		}
		public void Domain_should_be_case_insensitive_routes_should_be_case_sensitive()
		{
			var requestData = new RequestData
			{
				Endpoint = "someThing/{firstRoUte}/{secOndrouTe}/third/{tHirdRoute}",
				Parameters = new Dictionary<string, string>
					{
						{"firstRoute" , "firstValue"},
						{"secondRoute","secondValue"},
						{"thirdRoute" , "thirdValue"}
							
					}
			};

			var routeParamsSubstitutor = new RouteParamsSubstitutor(_apiUri);
			var result = routeParamsSubstitutor.SubstituteParamsInRequest(requestData);

			Assert.That(result.AbsoluteUrl, Is.EqualTo("http://example.com/someThing/firstValue/secondValue/third/thirdValue"));
		}
		public void Should_remove_multiple_parameters_that_match()
		{
			var requestData = new RequestData
			{
				Endpoint = "something/{firstRoute}/{secondRoute}/thrid/{thirdRoute}",
				Parameters = new Dictionary<string, string>
					{
						{"firstRoute" , "firstValue"},
						{"secondRoute","secondValue"},
						{"thirdRoute" , "thirdValue"},
						{"foo","bar"},
					}
			};

			var routeParamsSubstitutor = new RouteParamsSubstitutor(_apiUri);
			var result = routeParamsSubstitutor.SubstituteParamsInRequest(requestData);

			Assert.That(result.Parameters.ContainsKey("firstRoute"), Is.False);
			Assert.That(result.Parameters.ContainsKey("secondRoute"), Is.False);
			Assert.That(result.Parameters.ContainsKey("thirdRoute"), Is.False);
			Assert.That(result.Parameters.ContainsKey("foo"), Is.True);
		}
		public void Should_include_form_url_encoded_post_body()
		{
			var requestData = new RequestData
			{
				HttpMethod = HttpMethod.Post,
				Endpoint = "http://api.com/endpoint",
				Payload = new RequestPayload("application/x-www-form-urlencoded", "a=b&c=d"),
				RequiresSignature = true,
				OAuthToken = "TOKEN",
				OAuthTokenSecret = "SECRET"
			};

			var actual = GetAuthHeader(requestData);

			Assert.That(actual, Is.StringContaining("oauth_token="));
		}
		public void Should_not_include_json_post_body()
		{
			var requestData = new RequestData
			{
				HttpMethod = HttpMethod.Post,
				Endpoint = "http://api.com/endpoint",
				Payload = new RequestPayload("application/json", "{ a: 1, c: 2 }"),
				RequiresSignature = true,
				OAuthToken = "TOKEN",
				OAuthTokenSecret = "SECRET"
			};

			var actual = GetAuthHeader(requestData);

			Assert.That(actual, Is.StringContaining("oauth_token="));
		}
		private string GetAuthHeader(RequestData requestData)
		{
			var request = _requestBuilder.BuildRequest(requestData);

			return request.Headers["Authorization"];
		}
		public void Routes_should_be_case_insensitive()
		{
			var requestData = new RequestData
			{
				Endpoint = "something/{firstRoUte}/{secOndrouTe}/thrid/{tHirdRoute}",
				Parameters = new Dictionary<string, string>
					{
						{"firstRoute" , "firstValue"},
						{"secondRoute","secondValue"},
						{"thirdRoute" , "thirdValue"}
							
					}
			};

			var routeParamsSubstitutor = new RouteParamsSubstitutor(_apiUri);
			var result = routeParamsSubstitutor.SubstituteParamsInRequest(requestData);

			Assert.That(result.AbsoluteUrl, Is.StringContaining("something/firstvalue/secondvalue/thrid/thirdvalue"));
		}
		public void Post_data_with_params_and_requestBody_defaults_to_params_and_retains_request_body()
		{
			var parameters = new Dictionary<string, string>
			{
				{"one", "foo"}
			};
			var requestData = new RequestData
			{
				Parameters = parameters,
				HttpMethod = HttpMethod.Post,
				Payload = new RequestPayload("text/plain", "I am a payload")
			};

			var request = _requestBuilder.BuildRequest(requestData);
			Assert.That(request.Url, Is.Not.StringContaining("?one=foo"));
			Assert.That(request.Body.Data, Is.EqualTo(requestData.Payload.Data));
			Assert.That(request.Body.ContentType, Is.EqualTo("text/plain"));
		}