1package handlers
2
3import (
4 "context"
5 "testing"
6
7 "github.com/bnema/archup/internal/application/commands"
8 "github.com/bnema/archup/internal/domain/ports/mocks"
9 "go.uber.org/mock/gomock"
10)
11
12func TestPreflightHandler_Handle(t *testing.T) {
13 ctrl := gomock.NewController(t)
14 defer ctrl.Finish()
15
16 mockFS := mocks.NewMockFileSystem(ctrl)
17 mockExec := mocks.NewMockCommandExecutor(ctrl)
18 mockLogger := mocks.NewMockLogger(ctrl)
19
20 // Expect basic logging calls
21 mockLogger.EXPECT().Info(gomock.Any()).AnyTimes()
22 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
23 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
24 mockLogger.EXPECT().Warn(gomock.Any()).AnyTimes()
25 mockLogger.EXPECT().Warn(gomock.Any(), gomock.Any()).AnyTimes()
26 mockLogger.EXPECT().Error(gomock.Any(), gomock.Any()).AnyTimes()
27 mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
28
29 // Mock filesystem and executor responses
30 mockFS.EXPECT().Exists(gomock.Any()).DoAndReturn(func(path string) (bool, error) {
31 switch path {
32 case "/etc/arch-release":
33 return true, nil
34 case "/sys/firmware/efi/efivars":
35 return true, nil
36 default:
37 return false, nil
38 }
39 }).AnyTimes()
40 mockExec.EXPECT().Execute(gomock.Any(), "id", "-u").Return([]byte("0\n"), nil).Times(1)
41 mockExec.EXPECT().Execute(gomock.Any(), "uname", "-m").Return([]byte("x86_64\n"), nil).Times(1)
42 mockExec.EXPECT().Execute(gomock.Any(), "bootctl", "status").Return([]byte("Secure Boot: disabled"), nil).Times(2)
43 mockExec.EXPECT().Execute(gomock.Any(), "ping", "-c", "1", "archlinux.org").Return([]byte{}, nil).Times(1)
44 mockExec.EXPECT().Execute(gomock.Any(), "grep", "model name", "/proc/cpuinfo").Return([]byte("model name : Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz\n"), nil).Times(1)
45
46 handler := NewPreflightHandler(mockFS, mockExec, mockLogger)
47 result, err := handler.Handle(context.Background(), commands.PreflightCommand{})
48
49 if err != nil {
50 t.Fatalf("expected no error, got %v", err)
51 }
52
53 if !result.ChecksPassed {
54 t.Error("expected checks to pass")
55 }
56
57 if result.SystemInfo.Architecture != "x86_64" {
58 t.Errorf("expected architecture x86_64, got %s", result.SystemInfo.Architecture)
59 }
60
61 if !result.SystemInfo.IsUEFI {
62 t.Error("expected UEFI boot to be detected")
63 }
64}
65
66func TestPreflightHandler_NotRoot(t *testing.T) {
67 ctrl := gomock.NewController(t)
68 defer ctrl.Finish()
69
70 mockFS := mocks.NewMockFileSystem(ctrl)
71 mockExec := mocks.NewMockCommandExecutor(ctrl)
72 mockLogger := mocks.NewMockLogger(ctrl)
73
74 mockLogger.EXPECT().Info(gomock.Any()).AnyTimes()
75 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
76 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
77 mockLogger.EXPECT().Warn(gomock.Any()).AnyTimes()
78 mockLogger.EXPECT().Warn(gomock.Any(), gomock.Any()).AnyTimes()
79 mockLogger.EXPECT().Error(gomock.Any(), gomock.Any()).AnyTimes()
80 mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
81 mockFS.EXPECT().Exists(gomock.Any()).DoAndReturn(func(path string) (bool, error) {
82 switch path {
83 case "/etc/arch-release":
84 return true, nil
85 default:
86 return false, nil
87 }
88 }).AnyTimes()
89 mockExec.EXPECT().Execute(gomock.Any(), "id", "-u").Return([]byte("1000\n"), nil).Times(1)
90 mockExec.EXPECT().Execute(gomock.Any(), "bootctl", "status").Return([]byte("Secure Boot: disabled"), nil).AnyTimes()
91 mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
92 mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
93
94 handler := NewPreflightHandler(mockFS, mockExec, mockLogger)
95 result, err := handler.Handle(context.Background(), commands.PreflightCommand{})
96
97 if err != nil {
98 t.Fatalf("expected no error, got %v", err)
99 }
100
101 if result.ChecksPassed {
102 t.Error("expected checks to fail when not running as root")
103 }
104
105 if len(result.CriticalErrors) == 0 {
106 t.Error("expected critical errors to be recorded")
107 }
108}