1package handlers
2
3import (
4 "context"
5 "testing"
6
7 "github.com/bnema/archup/internal/application/commands"
8 "github.com/bnema/archup/internal/domain/packages"
9 "github.com/bnema/archup/internal/domain/ports/mocks"
10 "go.uber.org/mock/gomock"
11)
12
13// basePackagesContent is a minimal base.packages fixture used by all tests.
14var basePackagesContent = []byte("base\nlinux-firmware\n")
15
16func TestInstallBaseHandler_Handle_Success(t *testing.T) {
17 ctrl := gomock.NewController(t)
18 defer ctrl.Finish()
19
20 mockFS := mocks.NewMockFileSystem(ctrl)
21 mockExec := mocks.NewMockCommandExecutor(ctrl)
22 mockChrExec := mocks.NewMockChrootExecutor(ctrl)
23 mockLogger := mocks.NewMockLogger(ctrl)
24
25 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
26 mockFS.EXPECT().ReadFile(gomock.Any()).Return(basePackagesContent, nil).AnyTimes()
27 mockExec.EXPECT().Execute(gomock.Any(), "pacstrap", "/mnt", "base", "linux-firmware", "linux-zen", "intel-ucode", "amd-ucode", "vim", "git").Return([]byte{}, nil).AnyTimes()
28 mockExec.EXPECT().Execute(gomock.Any(), "genfstab", "-U", "/mnt").Return([]byte("# fstab"), nil).AnyTimes()
29 mockFS.EXPECT().WriteFile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
30
31 handler := NewInstallBaseHandler(mockFS, mockExec, mockChrExec, mockLogger)
32
33 cmd := commands.InstallBaseCommand{
34 TargetDisk: "/dev/sda",
35 MountPoint: "/mnt",
36 Packages: []string{"vim", "git"},
37 KernelVariant: packages.KernelZen,
38 IncludeMicrocode: true,
39 }
40
41 result, err := handler.Handle(context.Background(), cmd)
42
43 if err != nil {
44 t.Fatalf("expected no error, got %v", err)
45 }
46
47 if !result.Success {
48 t.Error("expected success")
49 }
50
51 if len(result.PackagesInstalled) < 4 {
52 t.Errorf("expected at least 4 packages, got %d", len(result.PackagesInstalled))
53 }
54
55 // Check that linux-zen is in the list
56 found := false
57 for _, pkg := range result.PackagesInstalled {
58 if pkg == "linux-zen" {
59 found = true
60 break
61 }
62 }
63 if !found {
64 t.Error("expected linux-zen kernel to be in packages list")
65 }
66}
67
68func TestInstallBaseHandler_Handle_InvalidKernel(t *testing.T) {
69 ctrl := gomock.NewController(t)
70 defer ctrl.Finish()
71
72 mockFS := mocks.NewMockFileSystem(ctrl)
73 mockExec := mocks.NewMockCommandExecutor(ctrl)
74 mockChrExec := mocks.NewMockChrootExecutor(ctrl)
75 mockLogger := mocks.NewMockLogger(ctrl)
76
77 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
78 mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).Times(1)
79
80 handler := NewInstallBaseHandler(mockFS, mockExec, mockChrExec, mockLogger)
81
82 cmd := commands.InstallBaseCommand{
83 TargetDisk: "/dev/sda",
84 MountPoint: "/mnt",
85 KernelVariant: packages.KernelVariant(999), // Invalid kernel
86 }
87
88 result, err := handler.Handle(context.Background(), cmd)
89
90 if err == nil {
91 t.Error("expected error for invalid kernel")
92 }
93
94 if result.Success {
95 t.Error("expected failure for invalid kernel")
96 }
97}
98
99func TestInstallBaseHandler_Handle_WithCustomPackages(t *testing.T) {
100 ctrl := gomock.NewController(t)
101 defer ctrl.Finish()
102
103 mockFS := mocks.NewMockFileSystem(ctrl)
104 mockExec := mocks.NewMockCommandExecutor(ctrl)
105 mockChrExec := mocks.NewMockChrootExecutor(ctrl)
106 mockLogger := mocks.NewMockLogger(ctrl)
107
108 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
109 mockFS.EXPECT().ReadFile(gomock.Any()).Return(basePackagesContent, nil).AnyTimes()
110 mockExec.EXPECT().Execute(gomock.Any(), "pacstrap", "/mnt", "base", "linux-firmware", "linux", "neovim", "zsh", "tmux").Return([]byte{}, nil).AnyTimes()
111 mockExec.EXPECT().Execute(gomock.Any(), "genfstab", "-U", "/mnt").Return([]byte("# fstab"), nil).AnyTimes()
112 mockFS.EXPECT().WriteFile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
113
114 handler := NewInstallBaseHandler(mockFS, mockExec, mockChrExec, mockLogger)
115
116 customPkgs := []string{"neovim", "zsh", "tmux"}
117 cmd := commands.InstallBaseCommand{
118 TargetDisk: "/dev/sda",
119 MountPoint: "/mnt",
120 Packages: customPkgs,
121 KernelVariant: packages.KernelStable,
122 IncludeMicrocode: false,
123 }
124
125 result, err := handler.Handle(context.Background(), cmd)
126
127 if err != nil {
128 t.Fatalf("expected no error, got %v", err)
129 }
130
131 if !result.Success {
132 t.Error("expected success")
133 }
134
135 // Check that custom packages are included
136 for _, customPkg := range customPkgs {
137 found := false
138 for _, installedPkg := range result.PackagesInstalled {
139 if installedPkg == customPkg {
140 found = true
141 break
142 }
143 }
144 if !found {
145 t.Errorf("expected custom package %s to be installed", customPkg)
146 }
147 }
148}
149
150func TestInstallBaseHandler_Handle_WithEncryption_IncludesCryptsetup(t *testing.T) {
151 ctrl := gomock.NewController(t)
152 defer ctrl.Finish()
153
154 mockFS := mocks.NewMockFileSystem(ctrl)
155 mockExec := mocks.NewMockCommandExecutor(ctrl)
156 mockChrExec := mocks.NewMockChrootExecutor(ctrl)
157 mockLogger := mocks.NewMockLogger(ctrl)
158
159 mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
160 mockFS.EXPECT().ReadFile(gomock.Any()).Return(basePackagesContent, nil).AnyTimes()
161 mockExec.EXPECT().Execute(gomock.Any(), "pacstrap", "/mnt", "base", "linux-firmware", "linux", "cryptsetup").Return([]byte{}, nil).AnyTimes()
162 mockExec.EXPECT().Execute(gomock.Any(), "genfstab", "-U", "/mnt").Return([]byte("# fstab"), nil).AnyTimes()
163 mockFS.EXPECT().WriteFile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
164
165 handler := NewInstallBaseHandler(mockFS, mockExec, mockChrExec, mockLogger)
166
167 cmd := commands.InstallBaseCommand{
168 TargetDisk: "/dev/sda",
169 MountPoint: "/mnt",
170 KernelVariant: packages.KernelStable,
171 IncludeMicrocode: false,
172 Encrypted: true,
173 }
174
175 result, err := handler.Handle(context.Background(), cmd)
176
177 if err != nil {
178 t.Fatalf("expected no error, got %v", err)
179 }
180
181 if !result.Success {
182 t.Error("expected success")
183 }
184
185 // Assert cryptsetup is in PackagesInstalled
186 found := false
187 for _, pkg := range result.PackagesInstalled {
188 if pkg == "cryptsetup" {
189 found = true
190 break
191 }
192 }
193 if !found {
194 t.Error("expected cryptsetup to be in PackagesInstalled for encrypted install")
195 }
196}