Skip to content
This repository has been archived by the owner on Sep 4, 2023. It is now read-only.

Add homepage #74

Merged
merged 17 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Epsilon.Abstractions/Model/CourseModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ public class CourseModule
public string Name { get; set; } = String.Empty;
public IEnumerable<CourseOutcome> Outcomes { get; set; } = Enumerable.Empty<CourseOutcome>();
}
}
}
20 changes: 20 additions & 0 deletions Epsilon.Abstractions/Model/CoursePage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Epsilon.Abstractions.Model;

public class CoursePage
{
public string Title { get; set; }
public string CreatedAt { get; set; }
public string Url { get; set; }
public string EditingRoles { get; set; }
public string PageId { get; set; }
public string LastEditedBy { get; set; }
public string Published { get; set; }
public string HideFromStudents { get; set; }
public string FrontPage { get; set; }
kn4a-com marked this conversation as resolved.
Show resolved Hide resolved
public string HtmlUrl { get; set; }
public string TodoDate { get; set; }
public string PublishedAt { get; set; }
public string UpdatedAt { get; set; }
public string LockedForUser { get; set; }
public string Body { get; set; }
}
3 changes: 2 additions & 1 deletion Epsilon.Abstractions/Model/ExportData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
public class ExportData
{
public string PersonaHtml { get; set; } = string.Empty;
public IEnumerable<CourseModule> CourseModules { get; set; } = Enumerable.Empty<CourseModule>();
}
}
}
20 changes: 20 additions & 0 deletions Epsilon.Canvas.Abstractions/Model/Page.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Text.Json.Serialization;

namespace Epsilon.Canvas.Abstractions.Model;

public record Page(
[property: JsonPropertyName("title")] string? Title,
[property: JsonPropertyName("created_at")] string? CreatedAt,
[property: JsonPropertyName("url")] string? Url,
[property: JsonPropertyName("editing_roles")] string? EditingRoles,
[property: JsonPropertyName("page_id")] int? PageId,
[property: JsonPropertyName("published")] bool? Published,
[property: JsonPropertyName("hide_from_students")] bool? HideFromStudents,
[property: JsonPropertyName("front_page")] bool? FrontPage,
[property: JsonPropertyName("html_url")] string? HTMLUrl,
[property: JsonPropertyName("todo_date")] DateTime? TodoDate,
[property: JsonPropertyName("publish_at")] DateTime? PublishAt,
[property: JsonPropertyName("updated_at")] DateTime? UpdatedAt,
[property: JsonPropertyName("locked_for_user")] bool? LockedForUser,
[property: JsonPropertyName("body")] string? Body
);
6 changes: 6 additions & 0 deletions Epsilon.Canvas.Abstractions/Service/IFileHttpService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Epsilon.Canvas.Abstractions.Service;

public interface IFileHttpService
{
Task<IEnumerable<byte>?> GetFileByteArray(string url);
}
10 changes: 10 additions & 0 deletions Epsilon.Canvas.Abstractions/Service/IPageHttpService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Epsilon.Canvas.Abstractions.Model;

namespace Epsilon.Canvas.Abstractions.Service;

public interface IPageHttpService
{
Task<string> GetPageByName(int courseId, string pageName);

Task<IEnumerable<Page>?> GetAll(int courseId, IEnumerable<string> include);
}
7 changes: 4 additions & 3 deletions Epsilon.Canvas.Tests/CanvasModuleCollectionFetcherTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ namespace Epsilon.Canvas.Tests
public class CanvasModuleCollectionFetcherTests
{
[Fact]
public async Task GivenAllowedModulesAndCourseId_WhenModuleAndOutcomeServiceAreMocked_ThenReturnsExpectedModuleOutcomeResultCollection()
public async Task
GivenAllowedModulesAndCourseId_WhenModuleAndOutcomeServiceAreMocked_ThenReturnsExpectedModuleOutcomeResultCollection()
{
// Arrange
var courseId = 123;
var allowedModules = new[] { "Module 1", "Module 3" };
var allowedModules = new[] {"Module 1", "Module 3"};
var outcomeServiceMock = new Mock<IOutcomeHttpService>();
var moduleServiceMock = new Mock<IModuleHttpService>();

Expand Down Expand Up @@ -123,4 +124,4 @@ public async Task GivenAllowedModulesAndCourseId_WhenModuleAndOutcomeServiceAreM
Assert.Equal(JsonSerializer.Serialize(expectedResults), JsonSerializer.Serialize(result));
}
}
}
}
12 changes: 6 additions & 6 deletions Epsilon.Canvas.Tests/Epsilon.Canvas.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0"/>
<PackageReference Include="coverlet.collector" Version="3.1.0"/>
<PackageReference Include="Moq" Version="4.18.4"/>
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

Expand Down
15 changes: 9 additions & 6 deletions Epsilon.Canvas.Tests/Services/AssignmentHttpServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,22 @@ public AssignmentHttpServiceTests()
}

[Fact]
public async Task GivenCourseIdAndIncludeSubmissionAndRubricAssessment_WhenCanvasAssignmentsAreRetrieved_ThenAssignmentsAreReturned()
public async Task
GivenCourseIdAndIncludeSubmissionAndRubricAssessment_WhenCanvasAssignmentsAreRetrieved_ThenAssignmentsAreReturned()
{
// Arrange
var courseId = 123;
var include = new[] { "submission", "rubric_assessment" };
var include = new[] {"submission", "rubric_assessment"};
var assignments = new[]
{
new Assignment(1, "Assignment 1", new("https://example.com/1"), null),
new Assignment(2, "Assignment 2", new("https://example.com/2"), new Submission(null, null, null, null)),
new Assignment(3, "Assignment 3", new("https://example.com/3"), new Submission(null, null, new RubricAssessment(8.5, 1, Enumerable.Empty<RubricRating>()), null)),
new Assignment(3, "Assignment 3", new("https://example.com/3"),
new Submission(null, null, new RubricAssessment(8.5, 1, Enumerable.Empty<RubricRating>()), null)),
};
_paginatorHttpServiceMock.Setup(x => x.GetAllPages<IEnumerable<Assignment>>(HttpMethod.Get, $"v1/courses/{courseId}/assignments?include[]=submission&include[]=rubric_assessment"))
.ReturnsAsync(new[] { assignments });
_paginatorHttpServiceMock.Setup(x => x.GetAllPages<IEnumerable<Assignment>>(HttpMethod.Get,
$"v1/courses/{courseId}/assignments?include[]=submission&include[]=rubric_assessment"))
.ReturnsAsync(new[] {assignments});

// Act
var result = await _assignmentHttpService.GetAll(courseId, include);
Expand All @@ -49,4 +52,4 @@ public async Task GivenCourseIdAndIncludeSubmissionAndRubricAssessment_WhenCanva
Assert.Equal(assignments, result);
}
}
}
}
9 changes: 5 additions & 4 deletions Epsilon.Canvas/CanvasModuleCollectionFetcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ IOutcomeHttpService outcomeService
_outcomeService = outcomeService;
}

public async IAsyncEnumerable<ModuleOutcomeResultCollection> GetAll(int courseId, IEnumerable<string>? allowedModules)
public async IAsyncEnumerable<ModuleOutcomeResultCollection> GetAll(int courseId,
IEnumerable<string>? allowedModules)
{
var response = await _outcomeService.GetResults(courseId, new[] { "outcomes", "alignments" });
var modules = await _moduleService.GetAll(courseId, new[] { "items" });
var response = await _outcomeService.GetResults(courseId, new[] {"outcomes", "alignments"});
var modules = await _moduleService.GetAll(courseId, new[] {"items"});

Debug.Assert(response != null, nameof(response) + " != null");
Debug.Assert(modules != null, nameof(modules) + " != null");
Expand All @@ -41,7 +42,7 @@ public async IAsyncEnumerable<ModuleOutcomeResultCollection> GetAll(int courseId

yield return new ModuleOutcomeResultCollection(module, new OutcomeResultCollection(
response.OutcomeResults.Where(r => ids.Contains(r.Link.Alignment)),
response.Links with { Alignments = response.Links.Alignments.Where(a => ids.Contains(a.Id)) }
response.Links with {Alignments = response.Links.Alignments.Where(a => ids.Contains(a.Id))}
));
}
}
Expand Down
7 changes: 5 additions & 2 deletions Epsilon.Canvas/CanvasServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@ public static IServiceCollection AddCanvas(this IServiceCollection services, ICo
var settings = provider.GetRequiredService<IOptions<CanvasSettings>>().Value;

client.BaseAddress = settings.ApiUrl;
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", settings.AccessToken);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", settings.AccessToken);
});

services.AddHttpClient<IPaginatorHttpService, PaginatorHttpService>(CanvasHttpClient);
services.AddHttpClient<IModuleHttpService, ModuleHttpService>(CanvasHttpClient);
services.AddHttpClient<IAssignmentHttpService, AssignmentHttpService>(CanvasHttpClient);
services.AddHttpClient<IOutcomeHttpService, OutcomeHttpService>(CanvasHttpClient);
services.AddHttpClient<ISubmissionHttpService, SubmissionHttpService>(CanvasHttpClient);
services.AddHttpClient<IPageHttpService, PageHttpService>(CanvasHttpClient);
services.AddHttpClient<IFileHttpService, FileHttpService>(CanvasHttpClient);

services.AddScoped<ILinkHeaderConverter, LinkHeaderConverter>();

services.AddScoped<ICanvasModuleCollectionFetcher, CanvasModuleCollectionFetcher>();

return services;
Expand Down
2 changes: 1 addition & 1 deletion Epsilon.Canvas/Epsilon.Canvas.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
</ItemGroup>
Expand Down
21 changes: 21 additions & 0 deletions Epsilon.Canvas/Service/FileHttpService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Net;
using System.Net.Http.Json;
using Epsilon.Abstractions.Http;
using Epsilon.Canvas.Abstractions.Converter;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Service;
using HtmlAgilityPack;

namespace Epsilon.Canvas.Service;

public class FileHttpService : HttpService, IFileHttpService
{
public FileHttpService(HttpClient client) : base(client)
{
}

public async Task<IEnumerable<byte>?> GetFileByteArray(string url)
{
return await Client.GetByteArrayAsync(url);
}
}
36 changes: 36 additions & 0 deletions Epsilon.Canvas/Service/PageHttpService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Net;
using System.Net.Http.Json;
using Epsilon.Abstractions.Http;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Service;

namespace Epsilon.Canvas.Service;

public class PageHttpService : HttpService, IPageHttpService
{
public PageHttpService(HttpClient client) : base(client)
{
}

public async Task<string?> GetPageByName(int courseId, string pageName)
{
using var request = new HttpRequestMessage(HttpMethod.Get, $"v1/courses/{courseId}/{pageName}");
using var response = await Client.SendAsync(request);

if (response.StatusCode == HttpStatusCode.OK)
return (await response.Content.ReadFromJsonAsync<Page>()).Body;

return null;
}

public async Task<IEnumerable<Page>?> GetAll(int courseId, IEnumerable<string> include)
{
using var request = new HttpRequestMessage(HttpMethod.Get, $"v1/courses/{courseId}/pages");
using var response = await Client.SendAsync(request);

if (response.StatusCode == HttpStatusCode.OK)
return await response.Content.ReadFromJsonAsync<IEnumerable<Page>>();

return null;
}
}
4 changes: 3 additions & 1 deletion Epsilon.Cli/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ private async Task ExecuteAsync()

var stream = await exporter.Export(formattedItems, format);

await using var fileStream = new FileStream($"{_exportOptions.FormattedOutputName}.{exporter.FileExtension}", FileMode.Create, FileAccess.Write);
await using var fileStream =
new FileStream($"{_exportOptions.FormattedOutputName}.{exporter.FileExtension}", FileMode.Create,
FileAccess.Write);

stream.Position = 0; // Reset position to zero to prepare for copy
await stream.CopyToAsync(fileStream);
Expand Down
46 changes: 23 additions & 23 deletions Epsilon.Tests/Epsilon.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2"/>
<PackageReference Include="Moq" Version="4.18.4"/>
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Epsilon.Abstractions\Epsilon.Abstractions.csproj" />
<ProjectReference Include="..\Epsilon\Epsilon.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Epsilon.Abstractions\Epsilon.Abstractions.csproj"/>
<ProjectReference Include="..\Epsilon\Epsilon.csproj"/>
</ItemGroup>

</Project>
5 changes: 3 additions & 2 deletions Epsilon.Tests/ExportDataPackagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace Epsilon.Tests
public class ExportDataPackagerTests
{
[Fact]
public async Task GivenListOfModuleOutcomeResultCollection_WhenRequiringOpenLearningOutcomeStructure_ThenOutcomeStructureShouldBeTransformed()
public async Task
GivenListOfModuleOutcomeResultCollection_WhenRequiringOpenLearningOutcomeStructure_ThenOutcomeStructureShouldBeTransformed()
{
// Arrange
var module = new Module(1, "Module 1", 3, new List<ModuleItem>
Expand Down Expand Up @@ -91,4 +92,4 @@ public async Task GivenListOfModuleOutcomeResultCollection_WhenRequiringOpenLear
Assert.Equal(JsonSerializer.Serialize(expectedData), JsonSerializer.Serialize(result));
}
}
}
}
10 changes: 7 additions & 3 deletions Epsilon.Tests/Exporters/WordModuleExporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ public async Task GivenExportData_WhenExportToWord_ThenFileShouldContainExportDa
Description = "Short Description",
Assignments = new List<CourseAssignment>
{
new CourseAssignment { Name = "Assignment 1", Url = "https://assignment1.com/", Score = "Good" },
new CourseAssignment { Name = "Assignment 2", Url = "https://assignment2.com/", Score = "Outstanding" },
new CourseAssignment
{Name = "Assignment 1", Url = "https://assignment1.com/", Score = "Good"},
new CourseAssignment
{
Name = "Assignment 2", Url = "https://assignment2.com/", Score = "Outstanding"
},
}
}
}
Expand All @@ -52,4 +56,4 @@ public async Task GivenExportData_WhenExportToWord_ThenFileShouldContainExportDa
Assert.Contains("Assignment 2", content);
}
}
}
}
1 change: 0 additions & 1 deletion Epsilon/Epsilon.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="DocumentFormat.OpenXml" Version="2.18.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>

</Project>
Loading