Adopt SummerCMS v0.1.1 admin features
Datepickers on native time.Time / lagoon.Date fields, file uploads on materials, readings and class sessions managed from the course form (course_id made nullable).
This commit is contained in:
@@ -113,7 +113,7 @@ func TestAdminCRUDAgainstDatabase(t *testing.T) {
|
||||
}
|
||||
|
||||
sessionID := createdID(t, adminSend(t, h, http.MethodPost, "/jz/bm/class_sessions", token, map[string]any{
|
||||
"course": courseID, "meeting": meetingID, "starts_at": "2030-10-05 08:00", "ends_at": "2030-10-05 09:30", "room": "", "is_online": true,
|
||||
"course": courseID, "meeting": meetingID, "starts_at": "2030-10-05T06:00:00Z", "ends_at": "2030-10-05T07:30:00Z", "room": "", "is_online": true,
|
||||
}))
|
||||
var stored time.Time
|
||||
gdb.Raw(`SELECT starts_at FROM jz_bm_class_sessions WHERE id = ?`, sessionID).Scan(&stored)
|
||||
@@ -122,11 +122,11 @@ func TestAdminCRUDAgainstDatabase(t *testing.T) {
|
||||
}
|
||||
var session models.ClassSession
|
||||
gdb.Take(&session, sessionID)
|
||||
if session.CourseID != courseID || session.MeetingID == nil || *session.MeetingID != meetingID || session.Room != nil || !session.IsOnline {
|
||||
if session.CourseID == nil || *session.CourseID != courseID || session.MeetingID == nil || *session.MeetingID != meetingID || session.Room != nil || !session.IsOnline {
|
||||
t.Errorf("session = %+v", session)
|
||||
}
|
||||
rec := adminSend(t, h, http.MethodPost, "/jz/bm/class_sessions", token, map[string]any{
|
||||
"course": courseID, "starts_at": "2030-10-05 10:00", "ends_at": "wtorek",
|
||||
"course": courseID, "starts_at": "2030-10-05T08:00:00Z", "ends_at": "2030-10-05T07:00:00Z",
|
||||
})
|
||||
if rec.Code != http.StatusUnprocessableEntity || !strings.Contains(rec.Body.String(), "ends_at") {
|
||||
t.Errorf("bad ends_at = %d %s", rec.Code, rec.Body.String())
|
||||
@@ -140,7 +140,7 @@ func TestAdminCRUDAgainstDatabase(t *testing.T) {
|
||||
|
||||
tagID := createdID(t, adminSend(t, h, http.MethodPost, "/jz/bm/tags", token, map[string]any{"name": "Geopolityka", "slug": "geopolityka"}))
|
||||
materialID := createdID(t, adminSend(t, h, http.MethodPost, "/jz/bm/materials", token, map[string]any{
|
||||
"title": "Notatka", "type": "notatka", "course": courseID, "tags": []uint{tagID}, "published_at": "", "body": "# Treść",
|
||||
"title": "Notatka", "type": "notatka", "course": courseID, "tags": []uint{tagID}, "published_at": nil, "body": "# Treść",
|
||||
}))
|
||||
var material models.Material
|
||||
gdb.Preload("Tags").Take(&material, materialID)
|
||||
@@ -148,13 +148,13 @@ func TestAdminCRUDAgainstDatabase(t *testing.T) {
|
||||
t.Errorf("material = %+v", material)
|
||||
}
|
||||
rec = adminSend(t, h, http.MethodPut, "/jz/bm/materials/"+strconv.Itoa(int(materialID)), token, map[string]any{
|
||||
"title": "Notatka", "type": "notatka", "published_at": "2026-01-15 12:00",
|
||||
"title": "Notatka", "type": "notatka", "published_at": "2026-01-15T11:00:00Z",
|
||||
})
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("publish = %d %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
gdb.Take(&material, materialID)
|
||||
if material.PublishedAt == nil || *material.PublishedAt != "2026-01-15T12:00:00+01:00" {
|
||||
if material.PublishedAt == nil || !material.PublishedAt.Equal(time.Date(2026, 1, 15, 11, 0, 0, 0, time.UTC)) {
|
||||
t.Errorf("published_at = %v", material.PublishedAt)
|
||||
}
|
||||
|
||||
@@ -183,3 +183,64 @@ func adminToken2(t *testing.T, gdb *gorm.DB, h http.Handler) string {
|
||||
}
|
||||
return body.Data.AccessToken
|
||||
}
|
||||
|
||||
// TestCourseRelationManagersOnUnsavedCourse creates a reading and a class
|
||||
// session from the course form before the course exists: they wait without
|
||||
// a course, stay out of the student API, and get the course on its first
|
||||
// save with the same form session key.
|
||||
func TestCourseRelationManagersOnUnsavedCourse(t *testing.T) {
|
||||
app, plugins, gdb := migrated(t)
|
||||
h, err := surf.Assemble(app, plugins)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
token := adminToken(t, gdb, h, `{"jz.bm.access_courses":1}`)
|
||||
key := strings.Repeat("k", 40)
|
||||
send := func(method, path string, body any) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
raw, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req := httptest.NewRequest(method, adminAPI+path, bytes.NewReader(raw))
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
req.Header.Set("Accept-Language", "en")
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("X-Session-Key", key)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
return rec
|
||||
}
|
||||
|
||||
readingID := createdID(t, send(http.MethodPost, "/jz/bm/courses/0/relations/readings/records", map[string]any{
|
||||
"title": "Lektura w toku", "is_required": true,
|
||||
}))
|
||||
sessionID := createdID(t, send(http.MethodPost, "/jz/bm/courses/0/relations/sessions/records", map[string]any{
|
||||
"starts_at": "2030-10-05T06:00:00Z", "ends_at": "2030-10-05T07:30:00Z", "room": "237",
|
||||
}))
|
||||
if rec := send(http.MethodPost, "/jz/bm/courses/0/relations/sessions/records", map[string]any{
|
||||
"starts_at": "2030-10-05T08:00:00Z", "ends_at": "2030-10-05T07:00:00Z",
|
||||
}); rec.Code != http.StatusUnprocessableEntity || !strings.Contains(rec.Body.String(), "ends_at") {
|
||||
t.Errorf("session ending before it starts = %d %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
|
||||
var pending models.ClassSession
|
||||
gdb.Take(&pending, sessionID)
|
||||
if pending.CourseID != nil {
|
||||
t.Fatalf("pending session has course %d", *pending.CourseID)
|
||||
}
|
||||
|
||||
courseID := createdID(t, send(http.MethodPost, "/jz/bm/courses", map[string]any{
|
||||
"name": "Przedmiot z lekturami", "form": "wyklad", "semester": 1,
|
||||
}))
|
||||
var reading models.Reading
|
||||
gdb.Take(&reading, readingID)
|
||||
var session models.ClassSession
|
||||
gdb.Take(&session, sessionID)
|
||||
if reading.CourseID == nil || *reading.CourseID != courseID || session.CourseID == nil || *session.CourseID != courseID {
|
||||
t.Errorf("after save: reading course %v, session course %v, want %d", reading.CourseID, session.CourseID, courseID)
|
||||
}
|
||||
if !session.StartsAt.Equal(time.Date(2030, 10, 5, 6, 0, 0, 0, time.UTC)) {
|
||||
t.Errorf("session starts_at = %v", session.StartsAt)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user