public void WhenToObjectContentIsInvokedThenObjectContentIsReturned()
 {
     var document = new ReadDocument();
     var content = document.ToObjectContent() as ObjectContent<IReadDocument>;
     content.ShouldNotBeNull();
     content.Value.ShouldEqual(document);
 }
        public async Task<HttpResponseMessage> GetTags(string projectName)
        {
            var document = new ReadDocument();

            var collectionSelfUri = MakeUri<TagController>(c => c.GetTags(projectName));

            //root object
            var tagsCollection = new Collection { Version = "1.0", Href = collectionSelfUri };

            //partial rep of each tag
            var tags = await Context.ProjectTagSet.Where(t => t.ProjectName.Equals(projectName)).ToListAsync();
            foreach (var tag in tags)
            {
                var particularProjectUri = MakeUri<TagController>(c => c.GetTagByName(projectName, tag.TagName));
                var item = new Item { Href = particularProjectUri };
                item.Data.Add(new Data { Name = "name", Value = tag.TagName, Prompt = "name of tag" });
                tagsCollection.Items.Add(item);
            }

            //template to insert new project
            var template = tagsCollection.Template.Data;
            template.Add(new Data { Name = "name", Prompt = "name of tag" });
            template.Add(new Data { Name = "top_entity", Prompt = "name of project", Value = projectName });


            document.Collection = tagsCollection;
            return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
        }
 public void WhenToHttpResponseMessageIsInvokedOnReadDocumentThenResponseMessageIsReturned()
 {
     var document = new ReadDocument();
     var response = document.ToHttpResponseMessage();
     response.ShouldNotBeNull();
     response.Content.ShouldNotBeNull();
     response.Content.ShouldBeType<ObjectContent<IReadDocument>>();
 }
        public async Task<ReadDocument> Index()
        {
            var instructors = await db
                .Instructors
                .Include(i => i.OfficeAssignment)
                .ToListAsync();

            var doc = new ReadDocument
            {
                Collection =
                {
                    Href = new Uri(Url.Action("Index", "Instructor", null, Request.GetUri().Scheme, null)),
                    Version = "1.0"
                }
            };
            foreach (var item in instructors.Select(i => new Item
            {
                Href = new Uri(Url.Action("Details", "Instructor", new { id=i.ID }, Request.GetUri().Scheme, null)),
                Data = new List<Data>
                {
                    new Data
                    {
                        Name = "last-name",
                        Prompt = "Surname",
                        Value = i.LastName
                    },
                    new Data
                    {
                        Name = "first-name",
                        Prompt = "First Name",
                        Value = i.FirstMidName
                    },
                    new Data
                    {
                        Name = "hire-date",
                        Prompt = "Hire Date",
                        Value = i.HireDate.ToShortDateString()
                    },
                    new Data
                    {
                        Name = "office",
                        Prompt = "Office",
                        Value = i.OfficeAssignment?.Location
                    },
                },
                Links = new List<Link>
                {
                    new Link { Href = new Uri(Url.Action("Courses", "Instructor", new { id=i.ID }, Request.GetUri().Scheme, null)), Prompt = "Courses", Rel = "courses" }
                }
            }))
            {
                doc.Collection.Items.Add(item);
            }

            return doc;
        }
        public async Task<ReadDocument> Index()
        {
            var instructors = await db.Instructors.Include(i => i.OfficeAssignment).ToListAsync();
            var doc = new ReadDocument
            {
                Collection =
                {
                    Href = new Uri(Url.Action("Index")),
                    Version = "1.0"
                }
            };
            foreach (var item in instructors.Select(i => new Item
            {
                Href = Url.Link<InstructorController>(c => c.Details(i.ID)),
                Data = new List<Data>
                {
                    new Data
                    {
                        Name = "last-name",
                        Prompt = "Last Name",
                        Value = i.LastName
                    },
                    new Data
                    {
                        Name = "first-name",
                        Prompt = "First Name",
                        Value = i.FirstMidName
                    },
                    new Data
                    {
                        Name = "hire-date",
                        Prompt = "Hire Date",
                        Value = i.HireDate.ToShortDateString()
                    },
                    new Data
                    {
                        Name = "office",
                        Prompt = "Office",
                        Value = i.OfficeAssignment == null ? null : i.OfficeAssignment.Location
                    },
                },
                Links = new List<Link>
                {
                    new Link { Href = new Uri(Url.Link<InstructorController>(c => c.Courses(i.ID)) + "/courses"), Prompt = "Courses", Rel = "courses" }
                }
            }))
            {
                doc.Collection.Items.Add(item);
            }

            return doc.ToHttpResponseMessage();
        }
        public async Task<HttpResponseMessage> GetProjects(int page = 0, string containsName = "")
        {
            var document = new ReadDocument();

            var collectionSelfUri = MakeUri<ProjectsController>(c => c.GetProjects(page, containsName));

            //root object
            var allProjectsCollection = new Collection {Version = "1.0", Href = collectionSelfUri};

            //partial representation of all the projects
            const string idProperty = "id", nameProperty = "name";
            var allProjectsFound = Context.Projects.Where(p => p.Name.Contains(containsName)).OrderBy(p => p.Name);
            var projectsConsidered = await allProjectsFound.Skip(PageSize*page).Take(PageSize).ToListAsync();
            foreach (var project in projectsConsidered)
            {
                var particularProjectUri = MakeUri<ProjectsController>(c => c.FindSingleProject(project.Name));
                var item = new Item {Href = particularProjectUri};
                item.Data.Add(new Data {Name = idProperty, Value = project.Id.ToString(), Prompt = "ID of project"});
                item.Data.Add(new Data {Name = nameProperty, Value = project.Name, Prompt = "name of project"});
                allProjectsCollection.Items.Add(item);
            }

            //template to insert new project
            var template = allProjectsCollection.Template.Data;
            template.Add(new Data {Name = Rels.Template.ProjectsPropertyName, Prompt = "name of project"});
            template.Add(new Data {Name = Rels.Template.ProjectsPropertyTags, Prompt = "Each Tag's name separated by a plus sign"});

            //queries para obter uma lista de projetos onde expression está contido no nome
            allProjectsCollection.Queries.Add(new Query
            {
                Href = MakeUri<ProjectsController>(c => c.GetProjects(page, "")),
                Rel = "search",
                Prompt = "Search for projects with a name that contains the given expression.",
                Data = new List<Data> { new Data { Name = Rels.Search.ContainsName, Prompt = "The keyword to look for inside the names of each project." } }
            });

            
            SetupPaginationLinks(allProjectsCollection, allProjectsFound.Count(), page, previousPageUri(page), nextPageUri(page));

            document.Collection = allProjectsCollection;
            return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
        }
        public ReadDocument Deals(int page = 1) 
        {
            var deals = Enumerable
                            .Range(PAGE_SIZE * (page - 1), PAGE_SIZE)
                            .Select(idx => 
                                new Deal(idx, "Deal " + idx, true, idx * 1000, idx * 100, idx * 1.4f, idx * 5.6f));

            // Collection+JSON => http://amundsen.com/media-types/collection/format/
            var doc = new ReadDocument
            {
                Collection =
                {
                    Href = new Uri(Url.Action(new UrlActionContext 
                        { 
                            Action =  "Deals", 
                            Controller = "Reports", 
                            Protocol = Request.Scheme 
                        })),
                    Version = "1.0"
                }
            };

            foreach (var item in deals.Select(d => 
                        new Item
                        {
                            Data = new List<Data>
                            {
                                new Data { Name = "name", Prompt = "Name", Value = d.Name },
                                new Data { Name = "state", Prompt = "State", Value = d.State.ToString() },
                                new Data { Name = "revenue", Prompt = "Revenue", Value = d.Revenue.ToString() },
                                new Data { Name = "actions", Prompt = "Auctions", Value = d.Auctions.ToString() },
                                new Data { Name = "impressions", Prompt = "Impressions", Value = d.Impressions.ToString() },
                                new Data { Name = "avgClearingCpm", Prompt = "Avg Clearing Cpm", Value = d.AvgClearingCpm.ToString() }
                            },
                            Href = new Uri(Url.Action(new UrlActionContext 
                            { 
                                Action =  "Deals", 
                                Controller = "Reports", 
                                Values = new { id = d.DealID.ToString() },
                                Protocol = Request.Scheme 
                            }))
                        })
                    )
            {
                doc.Collection.Items.Add(item);
            };
            
            // "links" : [
            //   {"href" : "...", "rel" : "first"},
            //   {"href" : "...", "rel" : "previous"},
            //   {"href" : "...", "rel" : "next"},
            //   {"href" : "...", "rel" : "last"}
            // ],                 
            
            doc.Collection.Links.Add(new Link
                {
                    Href = new Uri(Url.Action(new UrlActionContext 
                        { 
                            Action =  "Deals", 
                            Controller = "Reports", 
                            Values = new { page = 1 }, 
                            Protocol = Request.Scheme 
                        })),
                    Rel = "first"   
                });
                
            doc.Collection.Links.Add(new Link
                {
                    Href = new Uri(Url.Action(new UrlActionContext 
                        { 
                            Action =  "Deals", 
                            Controller = "Reports", 
                            Values = new { page = page == 1 ? 1 : page - 1 }, 
                            Protocol = Request.Scheme 
                        })),
                    Rel = "previous"
                });
            doc.Collection.Links.Add(new Link
                {
                    Href = new Uri(Url.Action(new UrlActionContext 
                        { 
                            Action =  "Deals", 
                            Controller = "Reports", 
                            Values = new { page = page == 20 ? 20 : page + 1 }, 
                            Protocol = Request.Scheme 
                         })),
                    Rel = "next"
                });
             doc.Collection.Links.Add(new Link
                {
                    Href = new Uri(Url.Action(new UrlActionContext 
                        { 
                            Action =  "Deals", 
                            Controller = "Reports", 
                            Values = new { page = 20 }, 
                            Protocol = Request.Scheme 
                        })),
                    Rel = "last"
                });
                
            return doc;
        }
        public async Task<HttpResponseMessage> Courses(int id)
        {
            var instructor = await db.Instructors.Where(i => i.ID == id).Include(i => i.Courses).SingleAsync();
            var courses = instructor.Courses;

            var doc = new ReadDocument
            {
                Collection =
                {
                    Href = new Uri(Url.Link<InstructorController>(c => c.Courses(id)) + "/courses"),
                    Version = "1.0"
                }
            };

            foreach (var item in courses.Select(c => new Item
            {
                Data = new List<Data>
                {
                    new Data { Name = "number", Prompt = "Number", Value = c.CourseID.ToString() },
                    new Data { Name = "title", Prompt = "Title", Value = c.Title },
                    new Data { Name = "dept", Prompt = "Department", Value = c.Department.Name }
                },
                Links = new List<Link>
                {
                    new Link
                    {
                        Href = new Uri(string.Format(Url.Link<InstructorController>(x => x.Index()) + "{0}/courses/{1}/students", id, c.CourseID)),
                        Prompt = "Students",
                        Rel = "students"
                    }
                }
            }))
            {
                doc.Collection.Items.Add(item);
            }

            return doc.ToHttpResponseMessage();
        }
        public async Task<HttpResponseMessage> Students(int id, int courseId)
        {
            var course = await db.Courses.Where(c => c.CourseID == courseId).Include(c => c.Enrollments).SingleAsync();
            var enrollments = course.Enrollments;

            var doc = new ReadDocument
            {
                Collection =
                {
                    Href = new Uri(string.Format(Url.Link<InstructorController>(c => c.Index()) + "/courses/{0}/students", courseId)),
                    Version = "1.0"
                }
            };

            foreach (var item in enrollments.Select(e => new Item
            {
                Data = new List<Data>
                {
                    new Data { Name = "full-name", Prompt = "Name", Value = e.Student.FullName },
                    new Data { Name = "grade", Prompt = "Grade", Value = e.Grade.ToString() },
                }
            }))
            {
                doc.Collection.Items.Add(item);
            }

            return doc.ToHttpResponseMessage();
        }
        public async Task<HttpResponseMessage> GetIssues(string projectName, string state = "", string containsName = "", int page = 0)
        {
            var document = new ReadDocument();
            var collectionSelfUri = MakeUri<IssuesController>(c => c.GetIssues(projectName, null, null, 0));

            //root object
            var allIssuesCollection = new Collection{ Version = "1.0", Href = collectionSelfUri };
            IOrderedQueryable<IssueModel> allIssuesFound = null;

            if (state.Length > 0)
            {
                allIssuesFound = Context.Issues.Where(i =>
                    //to handle queries over the collection
                    (state.Length > 0)
                        ? i.ProjectModel.Name.Equals(projectName) && i.State.Equals(state)
                        : i.ProjectModel.Name.Equals(projectName)
                    ).OrderBy(i => i.Id);
            }
            else
            {
                allIssuesFound = Context.Issues.Where(i =>
                    //to handle queries over the collection
                    (containsName.Length > 0)
                        ? i.ProjectModel.Name.Equals(projectName) && i.Title.Contains(containsName)
                        : i.ProjectModel.Name.Equals(projectName)
                    ).OrderBy(i => i.Id);
            }
            var allIssuesConsidered = await allIssuesFound.Skip(PageSize * page).Take(PageSize).ToListAsync();

            //items
            foreach (var issue in allIssuesConsidered)
            {
                var particularIssueUri = MakeUri<IssuesController>(c => c.GetSingleIssue(projectName, issue.Id));
                var item = new Item { Href = particularIssueUri };
                item.Data.Add(new Data { Name = "title", Value = issue.Title, Prompt = "title of issue" });
                item.Data.Add(new Data { Name = "state", Value = issue.State, Prompt = "state of issue" });
                allIssuesCollection.Items.Add(item);
            }

            //template
            var template = allIssuesCollection.Template.Data;
            template.Add(new Data { Name = "title", Prompt = "title of issue" });
            template.Add(new Data { Name = "state", Prompt = "state of issue" });
            template.Add(new Data { Name = "description", Prompt = "description of issue" });
            template.Add(new Data { Name = "tags", Prompt = "Each tag's name, if any, separated by a plus sign." });

            //queries para obter uma lista de issues com um determinado state (open ou close)
            allIssuesCollection.Queries.Add(new Query
            {
                Href = collectionSelfUri,
                Rel = Rels.Query.FilterQueryName,
                Prompt = "Search for issues with a certain state.",
                Data = new List<Data> { new Data { Name = "state", Prompt = "The state to look for."} }
            });
            //queries para procurar por um issue que contenha um determinado nome
            allIssuesCollection.Queries.Add(new Query
            {
                Href = MakeUri<IssuesController>(c => c.GetIssues(projectName, "", "", page)),
                Rel = Rels.Query.SearchQueryName,
                Prompt = "Search for issues that contains the given expression.",
                Data = new List<Data> { new Data { Name = Rels.Search.ContainsName, Prompt = "The keyword to look for inside the names of each issue." } }
            });

            SetupPaginationLinks(allIssuesCollection, Context.Issues.Count(), page, previousPageUri(projectName, state, containsName, page), 
                nextPageUri(projectName, state, containsName, page));

            document.Collection = allIssuesCollection;
            return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
        }
    public async Task<HttpResponseMessage> GetComments(string projectName, int issueId, [FromUri] string before = "",
      [FromUri] string after = "")
    {
      DateTime? beforeDate = null;
      DateTime? afterDate = null;

      if (!string.IsNullOrEmpty(before) && !string.IsNullOrWhiteSpace(before))
      {
        beforeDate = ParseDate(before);
      }
      if (!string.IsNullOrEmpty(after) && !string.IsNullOrWhiteSpace(after))
      {
        afterDate = ParseDate(after);
      }


      var collectionSelfUri = MakeUri<CommentsController>(c => c.GetComments(projectName, issueId, null, null));
      //root object
      var allCommentsCollection = new Collection {Version = "1.0", Href = collectionSelfUri};

      //DbFunctions.TruncateTime(someDateTimeObj) é igual a "someDateTimeObj.Date" mas LINQ não deixa utilizar esta ultima.
      var allCommentsTmp = Context.Comments
        .Where(c => c.IssueModel.Id == issueId
                    && c.ProjectModel.Name.Equals(projectName));


      if (afterDate != null)
      {
        allCommentsTmp =
          allCommentsTmp.Where(c => DbFunctions.TruncateTime(c.CreationDate) > DbFunctions.TruncateTime(afterDate));
      }
      if (beforeDate != null)
      {
        allCommentsTmp =
          allCommentsTmp.Where(c => DbFunctions.TruncateTime(c.CreationDate) < DbFunctions.TruncateTime(beforeDate));
      }

      var allComments = await allCommentsTmp.ToListAsync();
      foreach (var com in allComments)
      {
        var particularCommentUri =
          MakeUri<CommentsController>(c => c.GetSingleComment(projectName, com.IssueModel.Id, com.Id));
        var item = new Item {Href = particularCommentUri};
        item.Data.Add(new Data
        {
          Name = "created_on",
          Value = com.CreationDate.ToString(CultureInfo.InvariantCulture),
          Prompt = "Creation date"
        });
        item.Data.Add(new Data {Name = "content", Value = com.Content, Prompt = "The message"});
        allCommentsCollection.Items.Add(item);
      }

      var template = allCommentsCollection.Template.Data;
      template.Add(new Data {Name = "Content", Prompt = "content of comment"});

      allCommentsCollection.Queries.Add(new Query
      {
        Href = collectionSelfUri,
        Rel = Rels.Query.SearchQueryName,
        Prompt = "Search for comments within a certain date range.",
        Data = new List<Data>
        {
          new Data {Name = Rels.Search.After, Prompt = "Comments created after the given date."},
          new Data {Name = Rels.Search.Before, Prompt = "Comments created before the given date."}
        }
      });

      var document = new ReadDocument {Collection = allCommentsCollection};
      return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
    }
        public async Task<ReadDocument> Courses(int id)
        {
            var courses = await db.CourseInstructors.Where(i => i.InstructorID == id).Include(ci => ci.Course).ThenInclude(c => c.Department).ToListAsync();

            var doc = new ReadDocument
            {
                Collection =
                {
                    Href = new Uri(Url.Action("Courses", "Instructor", new {id}, Request.GetUri().Scheme, null)),
                    Version = "1.0"
                }
            };

            foreach (var item in courses.Select(c => new Item
            {
                Data = new List<Data>
                {
                    new Data { Name = "number", Prompt = "Number", Value = c.CourseID.ToString() },
                    new Data { Name = "title", Prompt = "Title", Value = c.Course.Title },
                    new Data { Name = "dept", Prompt = "Department", Value = c.Course.Department?.Name }
                },
                Links = new List<Link>
                {
                    new Link
                    {
                        Href = new Uri(Url.Action("Students", "Instructor", new { id, courseId = c.CourseID}, Request.GetUri().Scheme, null)),
                        Prompt = "Students",
                        Rel = "students"
                    }
                }
            }))
            {
                doc.Collection.Items.Add(item);
            }

            return doc;
        }
        public async Task<ReadDocument> Students(int id, int courseId)
        {
            var course = await db.Courses.Where(c => c.CourseID == courseId).Include(c => c.Enrollments).ThenInclude(e => e.Student).SingleAsync();
            var enrollments = course.Enrollments;

            var doc = new ReadDocument
            {
                Collection =
                {
                    Href = new Uri(Url.Action("Students", "Instructor", new {id, courseId}, Request.GetUri().Scheme, null)),
                    Version = "1.0"
                }
            };

            foreach (var item in enrollments.Select(e => new Item
            {
                Data = new List<Data>
                {
                    new Data { Name = "full-name", Prompt = "Name", Value = e.Student.FullName },
                    new Data { Name = "grade", Prompt = "Grade", Value = e.Grade.ToString() },
                }
            }))
            {
                doc.Collection.Items.Add(item);
            }

            return doc;
        }