public void AddsParentIdToOneToManyPolygonAttributes()
        {
            var features = new[]
            {
                new SpatialFeature
                {
                    FeatureId = 1,
                    Type = "Terrestrial",
                    SubType = "one",
                    Action = "a"
                },
                new SpatialFeature
                {
                    FeatureId = 1,
                    Type = "Terrestrial",
                    SubType = "one",
                    Action = "b"
                },
                new SpatialFeature
                {
                    FeatureId = 1,
                    Type = "Terrestrial",
                    SubType = "one",
                    Action = "c"
                },
                new SpatialFeature
                {
                    FeatureId = 2,
                    Type = "Terrestrial",
                    SubType = "two",
                    Action = "a"
                }
            };

            var model = new ProjectWithFeaturesResponse
            {
                Features = features
            };

            var actual = model.Features.ToList();

            // there should be one more item since a header is added for items with related data
            Assert.That(actual.Count(), Is.EqualTo(5));

            var header = actual.Single(x => x.Id == 4);
            Assert.That(header.FeatureId, Is.EqualTo(1));
            Assert.That(header.HasChildren, Is.True);
            Assert.That(header.Parent, Is.Null);
            Assert.That(header.Type, Is.EqualTo("Terrestrial"));

            // id's are added to each feature starting from 0. the header gets the max+1 value
            Assert.That(actual.Count(x => x.Parent == 4), Is.EqualTo(3));
        }
        public void NormalizesHerbicides()
        {
            var features = new[]
            {
                new SpatialFeature
                {
                    FeatureId = 4766,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Aerial (fixed-wing)",
                    Action = "Herbicide application",
                    Retreatment = 'Y',
                    Herbicide = "2 4-D"
                }, new SpatialFeature
                {
                    FeatureId = 4766,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Ely (2-way)",
                    Action = "Anchor chainb",
                    Retreatment = 'Y',
                    Herbicide = null
                }, new SpatialFeature
                {
                    FeatureId = 4767,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Aerial (fixed-wing)",
                    Action = "Herbicide application",
                    Retreatment = 'N',
                    Herbicide = "Aquaneat"
                }, new SpatialFeature
                {
                    FeatureId = 4767,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Aerial (fixed-wing)",
                    Action = "Herbicide application",
                    Retreatment = 'N',
                    Herbicide = "Milestone"
                }, new SpatialFeature
                {
                    FeatureId = 4767,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Aerial (helicopter)",
                    Action = "Herbicide application",
                    Retreatment = 'N',
                    Herbicide = "Aquaneat"
                }, new SpatialFeature
                {
                    FeatureId = 4768,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Aerial (fixed-wing)",
                    Action = "Herbicide application",
                    Retreatment = 'N',
                    Herbicide = "Grazon P+D"
                }, new SpatialFeature
                {
                    FeatureId = 4768,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Ground",
                    Action = "Herbicide application",
                    Retreatment = 'N',
                    Herbicide = "Outpost 22k"
                }, new SpatialFeature
                {
                    FeatureId = 4768,
                    Type = "Terrestrial Treatment Area",
                    SubType = "Spot treatment",
                    Action = "Herbicide application",
                    Retreatment = 'N',
                    Herbicide = "Pathfinder II"
                }, new SpatialFeature
                {
                    FeatureId = 4765,
                    Type = "Affected Area"
                }
            };

            var model = new ProjectWithFeaturesResponse
            {
                Features = features
            };

            var actual = model.Features.ToList();

            // there are 3 distinct terrestrials
            Assert.That(actual.Count(x=>x.Type == "Terrestrial Treatment Area"), Is.EqualTo(3));
            // one distinct affected area
            Assert.That(actual.Count(x=>x.Type == "Affected Area"), Is.EqualTo(1));
            // herbicide gets transfered to herbicides array
            Assert.That(actual.Single(x => x.FeatureId == 4766 && x.Action == "Herbicide application").Herbicides, Is.EquivalentTo(new[] { "2 4-D" }));
            // duplicate herbicides get simplified into one array
            Assert.That(actual.Single(x=>x.FeatureId == 4767 && x.SubType == "Aerial (fixed-wing)").Herbicides, Is.EquivalentTo(new []{ "Aquaneat", "Milestone"}));
            // Herbide should be empty and all items shoud lbe in herbicides property
            Assert.That(actual.Count(x=>!string.IsNullOrEmpty(x.Herbicide)), Is.EqualTo(0));
        }
Example #3
0
        public ProjectModule(IQuery queries)
            : base("/project")
        {
            Get["/{id:int}", true] = async (_, ctx) =>
            {
                var id = int.Parse(_.id);
                var model = this.Bind<UserDetailsRequest>();
                var response = new ProjectWithFeaturesResponse();

                var incompleteAttributes = string.IsNullOrEmpty(model.Token) || string.IsNullOrEmpty(model.Key);
                response.AllowEdits = !incompleteAttributes;

                var db = await queries.OpenConnection();
                using (var connection = db.Connection)
                {
                    if (!db.Open)
                    {
                        return Negotiate.WithReasonPhrase("Database Error")
                            .WithStatusCode(HttpStatusCode.InternalServerError)
                            .WithModel("Unable to connect to the database.");
                    }

                    var project = await queries.ProjectQueryAsync(connection, new {id});
                    response.Project = project;

                    var features = await queries.FeatureQueryAsync(connection, new {id});
                    response.Features = features;

                    var reason = "";
                    if (incompleteAttributes)
                    {
                        return Negotiate.WithModel(response)
                            .WithStatusCode(HttpStatusCode.OK)
                            .WithHeader("reason", "incomplete attributes");
                    }

                    var users = await queries.UserQueryAsync(connection, new {key = model.Key, token = model.Token});
                    var user = users.FirstOrDefault();

                    // make sure user is valid
                    if (user == null)
                    {
                        response.AllowEdits = false;
                        reason = "User is null. ";
                    }

                    else if (response.Project == null)
                    {
                        response.AllowEdits = false;
                        reason = "Project not found. ";
                    }

                    // anonymous and public users cannot create features
                    else if (new[] {"GROUP_ANONYMOUS", "GROUP_PUBLIC"}.Contains(user.Role))
                    {
                        response.AllowEdits = false;
                        reason += "Roles is anonymous or public. ";
                    }

                    // if project has features no or null, block feature creation
                    else if (response.Project.Features == "No" && user.Role != "GROUP_ADMIN")
                    {
                        response.AllowEdits = false;
                        reason += "Project is designated to have no features. ";
                    }

                    // cancelled and completed projects cannot be edited
                    else if (new[] {"Cancelled", "Completed"}.Contains(response.Project.Status) &&
                             user.Role != "GROUP_ADMIN")
                    {
                        response.AllowEdits = false;
                    }

                    // check if a user is a contributor
                    else if (response.Project.ProjectManagerId != user.Id && user.Role != "GROUP_ADMIN")
                    {
                        var counts = await queries.ContributorQueryAsync(connection, new {id, userId = user.Id});
                        var count = counts.FirstOrDefault();

                        if (count == 0)
                        {
                            response.AllowEdits = false;
                            reason += "User is not a contributor. ";
                        }
                    }

                    return Negotiate.WithModel(response)
                            .WithHeader("reason", reason);
                }
            };
        }