Initial Alma assignments reporter
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
func TestInferAssignmentDate(t *testing.T) {
|
||||
now := time.Date(2026, 3, 28, 10, 0, 0, 0, time.UTC)
|
||||
got := inferAssignmentDate("Jan 20", now)
|
||||
want := time.Date(2026, 1, 20, 0, 0, 0, 0, time.UTC)
|
||||
if !got.Equal(want) {
|
||||
t.Fatalf("got %s want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInferAssignmentDateRollsBackYear(t *testing.T) {
|
||||
now := time.Date(2026, 3, 28, 10, 0, 0, 0, time.UTC)
|
||||
got := inferAssignmentDate("Dec 15", now)
|
||||
want := time.Date(2025, 12, 15, 0, 0, 0, 0, time.UTC)
|
||||
if !got.Equal(want) {
|
||||
t.Fatalf("got %s want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInferUpcomingDateRollsForwardYear(t *testing.T) {
|
||||
now := time.Date(2026, 12, 28, 10, 0, 0, 0, time.UTC)
|
||||
got := inferUpcomingDate("Jan 03", now)
|
||||
want := time.Date(2027, 1, 3, 0, 0, 0, 0, time.UTC)
|
||||
if !got.Equal(want) {
|
||||
t.Fatalf("got %s want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterUpcomingAssignments(t *testing.T) {
|
||||
now := time.Date(2026, 3, 28, 10, 0, 0, 0, time.UTC)
|
||||
assignments := []Assignment{
|
||||
{DueDate: time.Date(2026, 3, 29, 0, 0, 0, 0, time.UTC), Title: "Soon"},
|
||||
{DueDate: time.Date(2026, 4, 20, 0, 0, 0, 0, time.UTC), Title: "Later"},
|
||||
}
|
||||
got := filterUpcomingAssignments(assignments, now, 14)
|
||||
if len(got) != 1 || got[0].Title != "Soon" {
|
||||
t.Fatalf("unexpected filtered assignments: %#v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDedupeAssignments(t *testing.T) {
|
||||
assignment := Assignment{
|
||||
DueDate: time.Date(2026, 4, 1, 0, 0, 0, 0, time.UTC),
|
||||
Title: "Preparedness",
|
||||
Link: "https://example.invalid/a",
|
||||
}
|
||||
got := dedupeAssignments([]Assignment{assignment, assignment})
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("got %d items", len(got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractLikeLiveMissingTable(t *testing.T) {
|
||||
doc := mustParseHTML(`
|
||||
<table class="pure-table pure-table-horizontal missing-assignments">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Mar<br>25</td>
|
||||
<td>
|
||||
<small><a href="/class/1">US History</a></small>
|
||||
<a data-alma-modal="StudentAssignmentDetailsModal" href="/assignment/1">HW: Timeline Events</a>
|
||||
</td>
|
||||
<td><i title="Missing"></i></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>`)
|
||||
|
||||
table := findNode(doc, func(n *html.Node) bool {
|
||||
return n.Type == html.ElementNode && n.Data == "table" && hasClass(n, "missing-assignments")
|
||||
})
|
||||
if table == nil {
|
||||
t.Fatal("missing table not found")
|
||||
}
|
||||
row := findNode(table, func(n *html.Node) bool { return n.Type == html.ElementNode && n.Data == "tr" })
|
||||
cells := directChildrenByTag(row, "td")
|
||||
if got := nodeText(cells[0]); got != "Mar 25" {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
link := findNode(cells[1], func(n *html.Node) bool {
|
||||
return n.Type == html.ElementNode && n.Data == "a" && attr(n, "data-alma-modal") != ""
|
||||
})
|
||||
if got := nodeText(link); got != "HW: Timeline Events" {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseHTML(text string) *html.Node {
|
||||
doc, err := html.Parse(strings.NewReader(text))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return doc
|
||||
}
|
||||
Reference in New Issue
Block a user