| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- package modules
- import (
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
- )
- func TestModuleInfo_JSON(t *testing.T) {
- module := ModuleInfo{
- Name: "TestModule",
- Desc: "A test module",
- Group: "utilities",
- IconPath: "test/img/icon.png",
- Version: "1.0.0",
- StartDir: "test/index.html",
- SupportFW: true,
- LaunchFWDir: "test/float.html",
- SupportEmb: false,
- SupportedExt: []string{".txt", ".pdf"},
- }
- // Marshal to JSON
- data, err := json.Marshal(module)
- if err != nil {
- t.Fatalf("Failed to marshal ModuleInfo: %v", err)
- }
- // Unmarshal back
- var restored ModuleInfo
- err = json.Unmarshal(data, &restored)
- if err != nil {
- t.Fatalf("Failed to unmarshal ModuleInfo: %v", err)
- }
- if restored.Name != module.Name {
- t.Errorf("Name mismatch: got %q, want %q", restored.Name, module.Name)
- }
- if restored.Group != module.Group {
- t.Errorf("Group mismatch: got %q, want %q", restored.Group, module.Group)
- }
- if len(restored.SupportedExt) != 2 {
- t.Errorf("Expected 2 extensions, got %d", len(restored.SupportedExt))
- }
- }
- func TestNewModuleHandler(t *testing.T) {
- // NewModuleHandler requires a userHandler which is complex
- // Test with nil (may panic) - we test the struct is initialized
- mh := &ModuleHandler{
- LoadedModule: []*ModuleInfo{},
- tmpDirectory: t.TempDir(),
- }
- if mh.LoadedModule == nil {
- t.Error("Expected non-nil LoadedModule")
- }
- }
- func TestRegisterModuleFromJSON_Valid(t *testing.T) {
- mh := &ModuleHandler{
- LoadedModule: []*ModuleInfo{},
- }
- moduleJSON := `{
- "Name": "TestMod",
- "Desc": "Test description",
- "Group": "media",
- "IconPath": "test/icon.png",
- "Version": "1.0.0",
- "StartDir": "test/index.html",
- "SupportFW": true,
- "SupportedExt": [".txt"]
- }`
- err := mh.RegisterModuleFromJSON(moduleJSON, false)
- if err != nil {
- t.Fatalf("RegisterModuleFromJSON() unexpected error: %v", err)
- }
- if len(mh.LoadedModule) != 1 {
- t.Errorf("Expected 1 module, got %d", len(mh.LoadedModule))
- }
- }
- func TestRegisterModuleFromJSON_Invalid(t *testing.T) {
- mh := &ModuleHandler{
- LoadedModule: []*ModuleInfo{},
- }
- err := mh.RegisterModuleFromJSON("invalid json {", false)
- if err == nil {
- t.Error("Expected error for invalid JSON")
- }
- }
- func TestDeregisterModule(t *testing.T) {
- mh := &ModuleHandler{
- LoadedModule: []*ModuleInfo{},
- }
- moduleJSON := `{"Name": "ModA", "Group": "media"}`
- mh.RegisterModuleFromJSON(moduleJSON, false)
- mh.RegisterModuleFromJSON(`{"Name": "ModB", "Group": "media"}`, false)
- if len(mh.LoadedModule) != 2 {
- t.Fatalf("Expected 2 modules before deregister, got %d", len(mh.LoadedModule))
- }
- mh.DeregisterModule("ModA")
- if len(mh.LoadedModule) != 1 {
- t.Errorf("Expected 1 module after deregister, got %d", len(mh.LoadedModule))
- }
- if mh.LoadedModule[0].Name != "ModB" {
- t.Errorf("Expected ModB to remain, got %q", mh.LoadedModule[0].Name)
- }
- }
- func TestGetModuleNameList(t *testing.T) {
- mh := &ModuleHandler{
- LoadedModule: []*ModuleInfo{},
- }
- mh.RegisterModuleFromJSON(`{"Name": "Alpha", "Group": "media"}`, false)
- mh.RegisterModuleFromJSON(`{"Name": "Beta", "Group": "media"}`, false)
- names := mh.GetModuleNameList()
- if len(names) != 2 {
- t.Errorf("Expected 2 module names, got %d", len(names))
- }
- }
- func TestModuleSortList(t *testing.T) {
- mh := &ModuleHandler{
- LoadedModule: []*ModuleInfo{},
- }
- mh.RegisterModuleFromJSON(`{"Name": "Zebra", "Group": "media"}`, false)
- mh.RegisterModuleFromJSON(`{"Name": "Apple", "Group": "media"}`, false)
- mh.RegisterModuleFromJSON(`{"Name": "Mango", "Group": "media"}`, false)
- mh.ModuleSortList()
- names := mh.GetModuleNameList()
- if names[0] != "Apple" || names[1] != "Mango" || names[2] != "Zebra" {
- t.Errorf("Expected sorted order [Apple Mango Zebra], got %v", names)
- }
- }
- func TestGetModuleInfoByID(t *testing.T) {
- mh := &ModuleHandler{
- LoadedModule: []*ModuleInfo{},
- }
- mh.RegisterModuleFromJSON(`{"Name": "FindMe", "Group": "media"}`, false)
- info := mh.GetModuleInfoByID("FindMe")
- if info == nil {
- t.Fatal("Expected non-nil ModuleInfo")
- }
- if info.Name != "FindMe" {
- t.Errorf("Expected Name FindMe, got %q", info.Name)
- }
- // Non-existent module
- notFound := mh.GetModuleInfoByID("DoesNotExist")
- if notFound != nil {
- t.Error("Expected nil for non-existent module")
- }
- }
- // TestGetLaunchParameter_MissingParam tests that missing "module" param returns error
- func TestGetLaunchParameter_MissingParam(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- req := httptest.NewRequest(http.MethodGet, "/modules/launch", nil)
- rr := httptest.NewRecorder()
- mh.GetLaunchParameter(rr, req)
- body := rr.Body.String()
- if !strings.Contains(body, "error") {
- t.Errorf("expected error response for missing module param, got: %s", body)
- }
- }
- // TestGetLaunchParameter_NotFound tests that an unknown module returns error
- func TestGetLaunchParameter_NotFound(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- req := httptest.NewRequest(http.MethodGet, "/modules/launch?module=NonExistent", nil)
- rr := httptest.NewRecorder()
- mh.GetLaunchParameter(rr, req)
- body := rr.Body.String()
- if !strings.Contains(body, "error") {
- t.Errorf("expected error for non-existent module, got: %s", body)
- }
- }
- // TestGetLaunchParameter_Found tests that a known module returns JSON
- func TestGetLaunchParameter_Found(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- mh.RegisterModuleFromJSON(`{"Name": "MyApp", "Group": "media", "StartDir": "MyApp/index.html"}`, false)
- req := httptest.NewRequest(http.MethodGet, "/modules/launch?module=MyApp", nil)
- rr := httptest.NewRecorder()
- mh.GetLaunchParameter(rr, req)
- if rr.Code != http.StatusOK {
- t.Errorf("expected 200, got %d", rr.Code)
- }
- body := rr.Body.String()
- if !strings.Contains(body, "MyApp") {
- t.Errorf("expected module name in response, got: %s", body)
- }
- }
- // TestRegisterModule_NonUtilitiesGroup tests that non-utilities groups don't access userHandler
- func TestRegisterModule_NonUtilitiesGroup(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- // userHandler is nil; as long as Group != "utilities"/"system tools" it won't be accessed
- module := ModuleInfo{
- Name: "TestMediaMod",
- Group: "media",
- }
- mh.RegisterModule(module)
- if len(mh.LoadedModule) != 1 {
- t.Errorf("expected 1 module, got %d", len(mh.LoadedModule))
- }
- }
- // TestGetModuleNameList_Empty verifies an empty handler returns empty list
- func TestGetModuleNameList_Empty(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- names := mh.GetModuleNameList()
- if len(names) != 0 {
- t.Errorf("expected 0 names, got %d", len(names))
- }
- }
- // TestDeregisterModule_NonExistent verifies deregistering unknown module is a no-op
- func TestDeregisterModule_NonExistent(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- mh.RegisterModuleFromJSON(`{"Name": "StayMod", "Group": "media"}`, false)
- mh.DeregisterModule("NotHere")
- if len(mh.LoadedModule) != 1 {
- t.Errorf("expected 1 module after no-op deregister, got %d", len(mh.LoadedModule))
- }
- }
- // TestModuleSortList_Empty verifies sorting empty list doesn't panic
- func TestModuleSortList_Empty(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- mh.ModuleSortList() // should not panic
- }
- // TestOnModuleUninstall_Hook verifies the hook is called on uninstall (only if hook is set)
- func TestOnModuleUninstall_Hook(t *testing.T) {
- mh := &ModuleHandler{LoadedModule: []*ModuleInfo{}}
- mh.RegisterModuleFromJSON(`{"Name": "HookMod", "Group": "media"}`, false)
- called := false
- mh.OnModuleUninstall = func(moduleName string) {
- if moduleName == "HookMod" {
- called = true
- }
- }
- // Invoke DeregisterModule which may or may not call OnModuleUninstall
- mh.DeregisterModule("HookMod")
- // The hook may not be called by DeregisterModule (it's for uninstall, not deregister)
- // Just verify the module is gone
- if mh.GetModuleInfoByID("HookMod") != nil {
- t.Error("expected HookMod to be deregistered")
- }
- _ = called // hook may not be invoked by DeregisterModule
- }
|