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

Commit

Permalink
Feat/58 unit testing poc (#73)
Browse files Browse the repository at this point in the history
* Release v1.0.0 (#41)

* Change formats type to `string` and split with comma separator

* Use root configuration instead of configuration section

* Fix exceptions not properly displaying in the console

* Add all module item types according to documentation

* Update application demo GIF

* Create code-analysis.yml

* Remove comments and enable additional queries

* Removed push from code-analysis.yml workflow

* Typo code-analysis.yml

* Added support for a Word export option

* Added footer Epsilon Credits

* Created helper class with reformat functions

* Reformat code

* Improved helper functions, Found that they can be added to records :-)

* Reformat files

* string interpolation

* Feature/cleanup (#40)

* Remove obsolete Epsilon.Http.Abstractions project

* Fix invalid serializable implementation

* Disable unused method return value hint

* Change exception to more appropriate one

* Update Grade score description

* Prevent null grades from exporting

* Reduce cognitive complexity to acceptable level

* Move logging call

* Reduce nesting

* Move project name and repository uri to constants

* Fix nullability warnings

* Remove unused class

* Use ?: operator and move constants to top level of class

* Reduce loop complexity

* Use project name constant in output name export option

* Update README.md application demo gif

* Add supported formats to README.md

Co-authored-by: Jelle Maas <typiqally@gmail.com>

* POC Open XML SDK

* Update

* Add KPI format and structure

* Added module names to document

* Testing the build and structure of exel files.

* Testing release deployment script.

* Delete file

* POC for excel export

* Code reformat

* Abstracted format logic from exporters to main logic

* Remove typo

* Remove unused variable

* Headers added

* Code cleanup

* Merge

* Removal nullability warnings

* Removal nullability warnings

* Removal tasks/awaits because they dont have nay use atm.

* Removal tasks/awaits because they dont have nay use atm.

* Add exporters return type

* Added memoryStream return type for ConsoleModuleExporter

* Remove unused ExportOptions from ConsoleModuleExporter

* Clean up old merge files

* Update continuous-integration.yml

* Add tests for HttpService, Exporter and ExportDataPackager

* Update continuous-integration.yml

* 'Var' is everything

* Update continuous-integration.yml

* Created unit test for CanvasModuleCollectionFetcher GetAll method

* Renamed unit test

* Bugfix

* Merged feat/42 into feat/58

* Refactored ExcelModuleExporter tests to WordModuleExporter tests

---------

Co-authored-by: Neal Geilen <info@nealgeilen.nl>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven Hansen <76601644+1SvenHansen@users.noreply.github.com>
  • Loading branch information
4 people committed May 26, 2023
1 parent 879b927 commit f5baae5
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 1 deletion.
126 changes: 126 additions & 0 deletions Epsilon.Canvas.Tests/CanvasModuleCollectionFetcherTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using Epsilon.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Service;
using Microsoft.Extensions.Logging;
using Moq;
using System.Text.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Epsilon.Canvas.Abstractions;

namespace Epsilon.Canvas.Tests
{
public class CanvasModuleCollectionFetcherTests
{
[Fact]
public async Task GivenAllowedModulesAndCourseId_WhenModuleAndOutcomeServiceAreMocked_ThenReturnsExpectedModuleOutcomeResultCollection()
{
// Arrange
var courseId = 123;
var allowedModules = new[] { "Module 1", "Module 3" };
var outcomeServiceMock = new Mock<IOutcomeHttpService>();
var moduleServiceMock = new Mock<IModuleHttpService>();

var expectedResults = new List<ModuleOutcomeResultCollection>
{
new ModuleOutcomeResultCollection(
new Module(1, "Module 1", 3, new List<ModuleItem>
{
new ModuleItem(1, "Module 1 Item 1", ModuleItemType.Page, 1),
new ModuleItem(2, "Module 1 Item 2", ModuleItemType.Assignment, 2),
new ModuleItem(3, "Module 1 Item 3", ModuleItemType.Quiz, 3)
}),
new OutcomeResultCollection(
new List<OutcomeResult> { },
new OutcomeResultCollectionLink(
new List<Outcome>
{
new Outcome(1, "Outcome 1", "Outcome 1 EN Short Description NL Long Description"),
new Outcome(2, "Outcome 2", "Outcome 2 EN Short Description NL Long Description")
},
new List<Alignment> { }
)
)
),
new ModuleOutcomeResultCollection(
new Module(3, "Module 3", 2, new List<ModuleItem>
{
new ModuleItem(4, "Module 3 Item 1", ModuleItemType.Assignment, 4),
new ModuleItem(5, "Module 3 Item 2", ModuleItemType.Assignment, 5)
}),
new OutcomeResultCollection(
new List<OutcomeResult> { },
new OutcomeResultCollectionLink(
new List<Outcome>
{
new Outcome(1, "Outcome 1", "Outcome 1 EN Short Description NL Long Description"),
new Outcome(2, "Outcome 2", "Outcome 2 EN Short Description NL Long Description")
},
new List<Alignment> { }
)
)
)
};

outcomeServiceMock
.Setup(s => s.GetResults(It.IsAny<int>(), It.IsAny<string[]>()))
.ReturnsAsync(new OutcomeResultCollection(
new List<OutcomeResult>
{
new OutcomeResult(false, 3, new OutcomeResultLink("user1", "1", "1", "2")),
new OutcomeResult(true, 4.5, new OutcomeResultLink("user2", "2", "2", "3")),
new OutcomeResult(false, null, new OutcomeResultLink("user1", "1", "1", "3")),
},
new OutcomeResultCollectionLink(
new List<Outcome>
{
new Outcome(1, "Outcome 1", "Outcome 1 EN Short Description NL Long Description"),
new Outcome(2, "Outcome 2", "Outcome 2 EN Short Description NL Long Description"),
},
new List<Alignment>
{
new Alignment("1", "Alignment 1", new Uri("https://alignment1.com")),
new Alignment("2", "Alignment 2", new Uri("https://alignment2.com")),
new Alignment("3", "Alignment 3", new Uri("https://alignment3.com")),
}
)
));

moduleServiceMock
.Setup(s => s.GetAll(It.IsAny<int>(), It.IsAny<string[]>()))
.ReturnsAsync(new List<Module>
{
new Module(1, "Module 1", 3, new List<ModuleItem>
{
new ModuleItem(1, "Module 1 Item 1", ModuleItemType.Page, 1),
new ModuleItem(2, "Module 1 Item 2", ModuleItemType.Assignment, 2),
new ModuleItem(3, "Module 1 Item 3", ModuleItemType.Quiz, 3)
}),
new Module(2, "Module 2", 0, new List<ModuleItem>()),
new Module(3, "Module 3", 2, new List<ModuleItem>
{
new ModuleItem(4, "Module 3 Item 1", ModuleItemType.Assignment, 4),
new ModuleItem(5, "Module 3 Item 2", ModuleItemType.Assignment, 5)
}),
});

var canvasModuleCollectionFetcher = new CanvasModuleCollectionFetcher(
Mock.Of<ILogger<CanvasModuleCollectionFetcher>>(), moduleServiceMock.Object, outcomeServiceMock.Object
);

// Act
var result = new List<ModuleOutcomeResultCollection>();
await foreach (var item in canvasModuleCollectionFetcher.GetAll(courseId, allowedModules))
{
result.Add(item);
}

// Assert
Assert.Equal(JsonSerializer.Serialize(expectedResults), JsonSerializer.Serialize(result));
}
}
}
94 changes: 94 additions & 0 deletions Epsilon.Tests/ExportDataPackagerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using Epsilon.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Export;
using Moq;
using System.Text.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Epsilon.Tests
{
public class ExportDataPackagerTests
{
[Fact]
public async Task GivenListOfModuleOutcomeResultCollection_WhenRequiringOpenLearningOutcomeStructure_ThenOutcomeStructureShouldBeTransformed()
{
// Arrange
var module = new Module(1, "Module 1", 3, new List<ModuleItem>
{
new ModuleItem(1, "Module 1 Item 1", ModuleItemType.Page, 1),
new ModuleItem(2, "Module 1 Item 2", ModuleItemType.Assignment, 2),
new ModuleItem(3, "Module 1 Item 3", ModuleItemType.Quiz, 3)
});

var outcomes = new List<Outcome>
{
new Outcome(1, "Outcome 1", "Outcome 1 EN Short Description NL Long Description"),
new Outcome(2, "Outcome 2", "Outcome 2 EN Short Description NL Long Description"),
};

var alignments = new List<Alignment>
{
new Alignment("1", "Alignment 1", new Uri("https://alignment1.com")),
new Alignment("2", "Alignment 2", new Uri("https://alignment2.com")),
};

var outcomeResults = new List<OutcomeResult>
{
new OutcomeResult(false, 3, new OutcomeResultLink("user1", "1", "1", "2")),
new OutcomeResult(true, 4.5, new OutcomeResultLink("user2", "2", "2", "3")),
new OutcomeResult(false, null, new OutcomeResultLink("user1", "1", "1", "3")),
};

var links = new OutcomeResultCollectionLink(outcomes, alignments);

var collection = new OutcomeResultCollection(outcomeResults, links);

var moduleOutcomeResultCollection = new ModuleOutcomeResultCollection(module, collection);

var data = new List<ModuleOutcomeResultCollection>
{
moduleOutcomeResultCollection
}.ToAsyncEnumerable();

var expectedData = new ExportData
{
CourseModules = new List<CourseModule>
{
new CourseModule
{
Name = "Module 1",
Outcomes = new List<CourseOutcome>
{
new CourseOutcome
{
Name = "Outcome 1",
Description = "Short Description",
Assignments = new List<CourseAssignment>
{
new CourseAssignment
{
Name = "Alignment 2",
Url = "https://alignment2.com/",
Score = "Satisfactory"
}
}
}
}
}
}
};

var exportDataPackager = new ExportDataPackager();

// Act
var result = await exportDataPackager.GetExportData(data);

// Assert
Assert.Equal(JsonSerializer.Serialize(expectedData), JsonSerializer.Serialize(result));
}
}
}
55 changes: 55 additions & 0 deletions Epsilon.Tests/Exporters/WordModuleExporterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Epsilon.Abstractions.Model;
using Epsilon.Export;
using Epsilon.Export.Exporters;
using Microsoft.Extensions.Options;
using DocumentFormat.OpenXml.Packaging;

namespace Epsilon.Tests.Exporters
{
public class WordModuleExporterTests
{
[Fact]
public async Task GivenExportData_WhenExportToWord_ThenFileShouldContainExportData()
{
// Arrange
var data = new ExportData
{
CourseModules = new List<CourseModule>
{
new CourseModule
{
Name = "Module 1",
Outcomes = new List<CourseOutcome>
{
new CourseOutcome
{
Name = "Outcome 1",
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" },
}
}
}
}
}
};

var moduleExporter = new WordModuleExporter();

// Act
using var stream = await moduleExporter.Export(data, "word");
using var document = WordprocessingDocument.Open(stream, false);

var content = document?.MainDocumentPart?.Document?.Body?.InnerText;

// Assert
Assert.Contains("Module 1", content);
Assert.Contains("Outcome 1", content);
Assert.Contains("Short Description", content);
Assert.Contains("Assignment 1", content);
Assert.Contains("Assignment 2", content);
}
}
}
1 change: 1 addition & 0 deletions Epsilon.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Xunit;
2 changes: 1 addition & 1 deletion Epsilon.sln
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ Global
{194C4770-0BCD-4EC2-BC7C-5D672A3B6557}.Release|Any CPU.ActiveCfg = Release|Any CPU
{194C4770-0BCD-4EC2-BC7C-5D672A3B6557}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
EndGlobal

0 comments on commit f5baae5

Please sign in to comment.