mirror of
https://github.com/frappe/lms.git
synced 2026-04-19 22:52:29 +03:00
test: course package export and import
This commit is contained in:
@@ -184,11 +184,8 @@ const exportCourse = async () => {
|
||||
}
|
||||
|
||||
const blob = await response.blob()
|
||||
|
||||
// Extract filename from header if present
|
||||
const disposition = response.headers.get('Content-Disposition')
|
||||
let filename = 'course.zip'
|
||||
|
||||
if (disposition && disposition.includes('filename=')) {
|
||||
filename = disposition.split('filename=')[1].replace(/"/g, '')
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ const uploadFile = (e: Event) => {
|
||||
|
||||
const importZip = () => {
|
||||
if (!zip.value) return
|
||||
call('lms.lms.api.import_course_as_zip', {
|
||||
call('lms.lms.api.import_course_from_zip', {
|
||||
zip_file_path: zip.value.file_url,
|
||||
})
|
||||
.then((data: any) => {
|
||||
|
||||
@@ -2375,6 +2375,6 @@ def export_course_as_zip(course_name: str):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def import_course_as_zip(zip_file_path):
|
||||
def import_course_from_zip(zip_file_path: str):
|
||||
frappe.only_for(["Moderator", "Course Creator"])
|
||||
return import_course_zip(zip_file_path)
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import zipfile
|
||||
|
||||
import frappe
|
||||
|
||||
from lms.lms.api import get_certified_participants, get_course_assessment_progress
|
||||
from lms.lms.api import (
|
||||
export_course_as_zip,
|
||||
get_certified_participants,
|
||||
get_course_assessment_progress,
|
||||
import_course_from_zip,
|
||||
)
|
||||
from lms.lms.test_helpers import BaseTestUtils
|
||||
|
||||
|
||||
@@ -83,3 +93,73 @@ class TestLMSAPI(BaseTestUtils):
|
||||
)
|
||||
self.assertEqual(result.is_correct, 1 if index % 2 == 0 else 0)
|
||||
self.assertEqual(result.marks, 5 if index % 2 == 0 else 0)
|
||||
|
||||
def test_export_course_as_zip(self):
|
||||
latest_file = self.get_latest_zip_file()
|
||||
self.assertTrue(latest_file)
|
||||
self.assertTrue(latest_file.endswith(".zip"))
|
||||
expected_name_pattern = re.escape(self.course.name) + r"_\d{8}_\d{6}_[a-f0-9]{8}\.zip"
|
||||
self.assertRegex(latest_file, expected_name_pattern)
|
||||
with zipfile.ZipFile(latest_file, "r") as zip_ref:
|
||||
expected_files = [
|
||||
"course.json",
|
||||
"instructors.json",
|
||||
]
|
||||
for expected_file in expected_files:
|
||||
self.assertIn(expected_file, zip_ref.namelist())
|
||||
chapter_files = [
|
||||
f for f in zip_ref.namelist() if f.startswith("chapters/") and f.endswith(".json")
|
||||
]
|
||||
self.assertEqual(len(chapter_files), 3)
|
||||
lesson_files = [f for f in zip_ref.namelist() if f.startswith("lessons/") and f.endswith(".json")]
|
||||
self.assertEqual(len(lesson_files), 12)
|
||||
assessment_files = [
|
||||
f
|
||||
for f in zip_ref.namelist()
|
||||
if f.startswith("assessments/") and f.endswith(".json") and len(f.split("/")) == 2
|
||||
]
|
||||
self.assertEqual(len(assessment_files), 3)
|
||||
|
||||
def get_latest_zip_file(self):
|
||||
export_course_as_zip(self.course.name)
|
||||
site_path = frappe.get_site_path("private", "files")
|
||||
zip_files = glob.glob(os.path.join(site_path, f"{self.course.name}_*.zip"))
|
||||
latest_file = max(zip_files, key=os.path.getctime) if zip_files else None
|
||||
return latest_file
|
||||
|
||||
def test_import_course_from_zip(self):
|
||||
imported_course = self.get_imported_course()
|
||||
self.assertEqual(imported_course.title, self.course.title)
|
||||
self.assertEqual(imported_course.category, self.course.category)
|
||||
# self.assertEqual(imported_course.lessons, self.course.lessons)
|
||||
self.assertEqual(len(imported_course.instructors), len(self.course.instructors))
|
||||
self.assertEqual(imported_course.instructors[0].instructor, self.course.instructors[0].instructor)
|
||||
imported_first_chapter = frappe.get_doc("Course Chapter", self.course.chapters[0].chapter)
|
||||
original_first_chapter = frappe.get_doc("Course Chapter", self.course.chapters[0].chapter)
|
||||
self.assertEqual(imported_first_chapter.title, original_first_chapter.title)
|
||||
imported_first_lesson = frappe.get_doc("Course Lesson", imported_first_chapter.lessons[0].lesson)
|
||||
original_first_lesson = frappe.get_doc("Course Lesson", original_first_chapter.lessons[0].lesson)
|
||||
self.assertEqual(imported_first_lesson.title, original_first_lesson.title)
|
||||
self.assertEqual(imported_first_lesson.content, original_first_lesson.content)
|
||||
self.cleanup_imported_course(imported_course.name)
|
||||
|
||||
def get_imported_course(self):
|
||||
latest_file = self.get_latest_zip_file()
|
||||
self.assertTrue(latest_file)
|
||||
zip_file_path = f"/{latest_file.lstrip(frappe.get_site_path())}"
|
||||
imported_course_name = import_course_from_zip(zip_file_path)
|
||||
imported_course = frappe.get_doc("LMS Course", imported_course_name)
|
||||
return imported_course
|
||||
|
||||
def cleanup_imported_course(self, course_name):
|
||||
self.cleanup_items.append(("LMS Course", course_name))
|
||||
self.cleanup_imported_assessment("LMS Quiz", self.quiz)
|
||||
self.cleanup_imported_assessment("LMS Assignment", self.assignment)
|
||||
self.cleanup_imported_assessment("LMS Programming Exercise", self.programming_exercise)
|
||||
|
||||
def cleanup_imported_assessment(self, doctype, doc):
|
||||
imported_assessment = frappe.db.get_value(
|
||||
doctype, {"title": doc.title, "name": ["!=", doc.name]}, "name"
|
||||
)
|
||||
if imported_assessment:
|
||||
self.cleanup_items.append((doctype, imported_assessment))
|
||||
|
||||
Reference in New Issue
Block a user