Files
baby-nas/internal/importer/samba_test.go
T
darroyo 4ae7335b31 feat: import existing smb.conf and /etc/exports on first boot
Adds auto-detection of pre-existing Samba shares and NFS exports when
nasctl is installed on a host that already has these configs.

New package internal/importer parses smb.conf (INI-style) and
/etc/exports (line-based) and imports them into SQLite.

Imported shares/exports are marked dirty so the user must review
and apply manually before any file is overwritten.

Backup: before the first Apply, each module backs up the original
config to <path>.nasctl.bak.<timestamp> (one time only).

New CLI flag --import-on-boot / NASCTL_IMPORT_ON_BOOT env var
(default false, opt-in).

New API endpoints:
  GET  /api/import/status
  POST /api/import/samba
  POST /api/import/nfs

New DB methods ReplaceSambaShares/ReplaceNFSExports (transactional
replace-all), guarded by import.samba.done / import.nfs.done
settings flags.
2026-07-05 21:45:25 -04:00

167 lines
2.7 KiB
Go

package importer
import (
"testing"
)
func TestParseSambaConf(t *testing.T) {
tests := []struct {
name string
input string
wantLen int
wantErr bool
}{
{
name: "basic share",
input: `[global]
workgroup = WORKGROUP
security = user
[share1]
path = /srv/samba/share1
comment = Test Share
read only = no
guest ok = no
`,
wantLen: 1,
},
{
name: "multiple shares with valid users and groups",
input: `[global]
server string = Test Server
[public]
path = /srv/samba/public
comment = Public Files
read only = yes
guest ok = yes
[data]
path = /srv/samba/data
comment = Data Share
read only = no
writable = yes
guest ok = no
valid users = alice, bob
valid groups = staff
`,
wantLen: 2,
},
{
name: "ignores global section",
input: `[global]
workgroup = WORKGROUP
security = user
server string = test
[global]
printing = cups
[myshare]
path = /srv/samba/myshare
`,
wantLen: 1,
},
{
name: "ignores printers section",
input: `[printers]
comment = All Printers
path = /var/spool/samba
printable = yes
guest ok = yes
[global]
workgroup = WORKGROUP
[myshare]
path = /srv/samba/myshare
`,
wantLen: 1,
},
{
name: "handles comments with semicolon",
input: `; This is a comment
[global]
workgroup = WORKGROUP
[myshare]
path = /srv/samba/myshare
`,
wantLen: 1,
},
{
name: "handles continuation lines",
input: `[myshare]
path = /srv/samba/\
myshare
comment = continued\
line
`,
wantLen: 1,
},
{
name: "handles quoted values",
input: `[myshare]
path = "/srv/samba/myshare"
comment = "Test comment"
`,
wantLen: 1,
},
{
name: "empty input",
input: "",
wantLen: 0,
},
{
name: "skip share without path",
input: `[nopath]
comment = No path here
`,
wantLen: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseSambaConf([]byte(tt.input))
if (err != nil) != tt.wantErr {
t.Errorf("parseSambaConf() error = %v, wantErr %v", err, tt.wantErr)
return
}
if len(got) != tt.wantLen {
t.Errorf("parseSambaConf() got %d shares, want %d", len(got), tt.wantLen)
}
})
}
}
func TestParseBool(t *testing.T) {
tests := []struct {
input string
expected bool
}{
{"yes", true},
{"no", false},
{"true", true},
{"false", false},
{"1", true},
{"0", false},
{"on", true},
{"off", false},
{"YES", true},
{"NO", false},
{"True", true},
{"False", false},
{"", false},
{"maybe", false},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
if got := parseBool(tt.input); got != tt.expected {
t.Errorf("parseBool(%q) = %v, want %v", tt.input, got, tt.expected)
}
})
}
}