public void GetSerializedJson()
        {
            //act
            var multiGeocodeContainer = new MultipleGeocodeContainerArgs
            {
                Addresses = new List<AddressWithId>
                {
                    new AddressWithId
                    {
                        Id = 1,
                        Street = "160 w main st",
                        Zone = "84652",
                    },
                    new AddressWithId
                    {
                        Id = 2,
                        Street = "80 w 100 s",
                        Zone = "84754",
                    },
                    new AddressWithId
                    {
                        Id = 3,
                        Zone = "84754",
                        Street = "83 W 100 S"
                    },
                    new AddressWithId
                    {
                        Id = 4,
                        Zone = "84754",
                        Street = "64 S Main St"
                    },
                    new AddressWithId
                    {
                        Id = 5,
                        Zone = "84620",
                        Street = "360 S Main St"
                    },
                    new AddressWithId
                    {
                        Id = 6,
                        Zone = "84104",
                        Street = "1 state office building"
                    }
                }
            };

            var serializer = JsonConvert.SerializeObject(multiGeocodeContainer,
                                                         new JsonSerializerSettings());

            Debug.Print(serializer);
        }
        public HttpResponseMessage Multiple(MultipleGeocodeContainerArgs addresseses, [FromUri] GeocodeOptions options)
        {
            var notifications = "";

            #region validation

            if (addresseses == null)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest,
                                                            new ResultContainer<MultipleGeocdeAddressResultContainer>
                                                                {
                                                                    Status = (int) HttpStatusCode.BadRequest,
                                                                    Message =
                                                                        "Could not deserialize json. Please validate json to make sure it is in correct format. Try http://jsonlint.com"
                                                                })
                            .AddCache()
                            .AddTypeHeader(typeof(ResultContainer<MultipleGeocdeAddressResultContainer>));
            }

            if (!addresseses.Addresses.Any())
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest,
                                                            new ResultContainer<MultipleGeocdeAddressResultContainer>
                                                                {
                                                                    Status = (int) HttpStatusCode.BadRequest,
                                                                    Message =
                                                                        "No addresses to geocode. Please validate json to make sure it is in correct format. Try http://jsonlint.com"
                                                                })
                            .AddCache()
                            .AddTypeHeader(typeof(ResultContainer<MultipleGeocdeAddressResultContainer>));
            }

            if (addresseses.Addresses.Count > MaxAddresses)
            {
                notifications = string.Format("Input {0}/{1} - Only processed {1}. ", addresseses.Addresses.Count,
                                              MaxAddresses);
                addresseses.Addresses = addresseses.Addresses.OrderBy(x => x.Id).Take(MaxAddresses).ToList();
            }

            var duplicateIds = addresseses.Addresses.GroupBy(x => x.Id)
                                          .Where(x => x.Count() > 1)
                                          .Select(x => x.Key)
                                          .ToList();

            if (duplicateIds.Count > 0)
            {
                notifications +=
                    string.Format("Found duplicate id's in list for ({0}). These addresses will not be geocoded.",
                                  string.Join(", ", duplicateIds));
            }

            #endregion

            var batchAddressResults = new Dictionary<int, GeocodeAddressResult>();

            foreach (var address in addresseses.Addresses)
            {
                if (duplicateIds.Contains(address.Id))
                {
                    continue;
                }

                batchAddressResults.Add(address.Id,
                                        CommandExecutor.ExecuteCommand(new OrchesrateeGeocodeCommand(address.Street,
                                                                                                     address.Zone,
                                                                                                     options)));
            }

            var result = new MultipleGeocdeAddressResultContainer
                {
                    Addresses = batchAddressResults.Select(MultipleGeocodeAddressResult.MapResult).ToList()
                };

            duplicateIds.ForEach(x => result.Addresses.Add(new MultipleGeocodeAddressResult
                {
                    Id = x,
                    Score = -2,
                    ErrorMessage = "Duplicate Id; Skipping."
                }));

            HttpResponseMessage response = null;
            try
            {
                response = Request.CreateResponse(HttpStatusCode.OK,
                                                  new ResultContainer
                                                      <MultipleGeocdeAddressResultContainer>
                                                      {
                                                          Status = (int) HttpStatusCode.OK,
                                                          Message = notifications,
                                                          Result = result
                                                      })
                                  .AddCache()
                                  .AddTypeHeader(typeof (ResultContainer<MultipleGeocdeAddressResultContainer>));
            }
            catch (InvalidOperationException)
            {
                response = new HttpResponseMessage(HttpStatusCode.BadGateway) {
                    Content = new ObjectContent(typeof(ResultContainer), new ResultContainer
                    {
                        Message = "JSONP does not work with POST requests.", 
                        Status = 400
                    }, new JsonMediaTypeFormatter())};
            }
            return response;
        }
        public void MultipleAddressGetGeocodedAndIdsMatch()
        {
            //arrange
            var client = new HttpClient();

            //act
            var multiGeocodeContainer = new MultipleGeocodeContainerArgs
            {
                Addresses = new List<AddressWithId>
                {
                    new TestAddress
                    {
                        Id = 1,
                        Street = "160 w main st",
                        Zone = "84652",
                        KnownScore = 100,
                        KnownLocation = new Location
                        {
                            X = 424888.4,
                            Y = 4317812.22
                        }
                    },
                    new TestAddress
                    {
                        Id = 2,
                        Street = "80 w 100 s",
                        Zone = "84754",
                        KnownScore = 100,
                        KnownLocation = new Location
                        {
                            X = 404232.41,
                            Y = 4284199.87
                        }
                    },
                    new TestAddress
                    {
                        Id = 3,
                        Zone = "84754",
                        KnownLocation = new Location
                        {
                            X = 404244.06,
                            Y = 4284146.85
                        },
                        KnownScore = 100,
                        Street = "83 W 100 S"
                    },
                    new TestAddress
                    {
                        Id = 4,
                        Zone = "84754",
                        KnownLocation = new Location
                        {
                            X = 404410.09,
                            Y = 4284257.9
                        },
                        KnownScore = 100,
                        Street = "64 S Main St"
                    },
                    new TestAddress
                    {
                        Id = 5,
                        Zone = "84620",
                        KnownLocation = new Location
                        {
                            X = 418702.33,
                            Y = 4307790.93
                        },
                        KnownScore = 100,
                        Street = "360 S Main St"
                    },
                    new TestAddress
                    {
                        Id = 6,
                        Zone = "84104",
                        Street = "1 state office building",
                        KnownScore = 0
                    }
                }
            };

            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var response =
                client.PostAsJsonAsync("http://webapi/api/v1/Geocode/multiple?apiKey=AGRC-ApiExplorer",
                                       multiGeocodeContainer).Result;
            stopwatch.Stop();

            Debug.Print(response.Content.ReadAsStringAsync().Result);

            Debug.Print(stopwatch.ElapsedMilliseconds.ToString(CultureInfo.InvariantCulture));

            //assert
            var resultContainer =
                response.Content.ReadAsAsync<ResultContainer<MultipleGeocdeAddressResultContainer>>().Result;

            Assert.That(response.StatusCode == HttpStatusCode.OK);
            Assert.That(resultContainer.Status, Is.EqualTo((int) HttpStatusCode.OK), "api key");
            Assert.That(resultContainer.Result.Addresses.Count, Is.EqualTo(multiGeocodeContainer.Addresses.Count),
                        "counts sbould be equal");

            var first = multiGeocodeContainer.Addresses.First(x => x.Id == 1);
            Assert.That(resultContainer.Result.Addresses.First(x => x.Id == 1).InputAddress,
                        Is.EqualTo(first.Street + ", " + first.Zone), "streets are the same?");
        }
        public void RequestWithCallbackReturnsError()
        {
            //arrange
            var fixture = new Fixture();
            var client = new HttpClient();

            //act
            var multiGeocodeContainer = new MultipleGeocodeContainerArgs
            {
                Addresses = fixture.CreateMany<AddressWithId>(8).ToList()
            };

            var response =
                client.PostAsJsonAsync(
                    "http://webapi/api/v1/Geocode/multiple?apiKey=AGRC-ApiExplorer&callback=cb",
                    multiGeocodeContainer).Result;

            Debug.Print(response.Content.ReadAsStringAsync().Result);

            //assert
            var resultContainer = response.Content.ReadAsAsync<ResultContainer<MultipleGeocodeContainerArgs>>().Result;

            Assert.That(response.StatusCode == HttpStatusCode.OK);
            Assert.That(resultContainer.Message.Contains("does not work"));
            Assert.That(resultContainer.Status, Is.EqualTo(400));
        }
        public void RequestTruncatesReponseToMaxAllowedAddresses()
        {
            //arrange
            var fixture = new Fixture();
            var client = new HttpClient();

            //act
            var multiGeocodeContainer = new MultipleGeocodeContainerArgs
            {
                Addresses = fixture.Build<AddressWithId>().CreateMany(110).ToList()
            };

            var response =
                client.PostAsJsonAsync("http://webapi/api/v1/Geocode/multiple?apiKey=AGRC-ApiExplorer",
                                       multiGeocodeContainer).Result;

            Debug.Print(response.Content.ReadAsStringAsync().Result);

            //assert
            var resultContainer = response.Content.ReadAsAsync<ResultContainer<MultipleGeocodeContainerArgs>>().Result;

            Assert.That(response.StatusCode == HttpStatusCode.OK);
            Assert.That(resultContainer.Status, Is.EqualTo((int) HttpStatusCode.OK), "api key");
            Assert.That(resultContainer.Result.Addresses.Count, Is.EqualTo(100), "maxed out");
            Assert.That(resultContainer.Result.Addresses.Count(x => x.Id > 100), Is.EqualTo(0), "uses first set of id's");
        }
        public void RequestSkipsIdsThatAreNotUnique()
        {
            //arrange
            var fixture = new Fixture();
            var client = new HttpClient();
            var multiGeocodeContainer = new MultipleGeocodeContainerArgs
            {
                Addresses = fixture.Build<AddressWithId>().With(x => x.Id, 1).CreateMany(2).ToList()
            };

            fixture.AddManyTo(multiGeocodeContainer.Addresses, 8);

            Assert.That(multiGeocodeContainer.Addresses.Count, Is.EqualTo(10), "test data");
            Assert.That(multiGeocodeContainer.Addresses.Count(x => x.Id == 1), Is.EqualTo(3),
                        "test data has right amount of duplicates");

            //act
            var response =
                client.PostAsJsonAsync("http://webapi/api/v1/Geocode/multiple?apiKey=AGRC-ApiExplorer",
                                       multiGeocodeContainer).Result;

            Debug.Print(response.Content.ReadAsStringAsync().Result);

            //assert
            var resultContainer = response.Content.ReadAsAsync<ResultContainer<MultipleGeocodeContainerArgs>>().Result;

            Assert.That(response.StatusCode == HttpStatusCode.OK);
            Assert.That(resultContainer.Status, Is.EqualTo((int) HttpStatusCode.OK), "api key");
            Assert.That(resultContainer.Result.Addresses.Count, Is.EqualTo(8), "trim duplicate id's");
            Assert.That(resultContainer.Result.Addresses.Count(x => x.Id > 100), Is.EqualTo(0), "uses first set of id's");
        }
        public void RequestReturnsSameNumberOfResultsBelowMaxAllowed()
        {
            //arrange
            var fixture = new Fixture();
            var client = new HttpClient();

            //act
            var multiGeocodeContainer = new MultipleGeocodeContainerArgs
            {
                Addresses = fixture.CreateMany<AddressWithId>(8).ToList()
            };

            var response =
                client.PostAsJsonAsync("http://webapi/api/v1/Geocode/multiple?apiKey=AGRC-ApiExplorer",
                                       multiGeocodeContainer).Result;

            Debug.Print(response.Content.ReadAsStringAsync().Result);

            //assert
            var resultContainer = response.Content.ReadAsAsync<ResultContainer<MultipleGeocodeContainerArgs>>().Result;

            Assert.That(response.StatusCode == HttpStatusCode.OK);
            Assert.That(resultContainer.Status, Is.EqualTo((int) HttpStatusCode.OK), "api key");
            Assert.That(resultContainer.Result.Addresses.Count, Is.EqualTo(multiGeocodeContainer.Addresses.Count),
                        "same number as passed in");
        }