Files
cameradar/cameradar_test.go
T
Brendan Le Glaunec e81eeb0c4d feat: v6 rewrite
2026-01-27 22:11:17 +01:00

231 lines
5.1 KiB
Go

package cameradar_test
import (
"context"
"errors"
"sync"
"testing"
"github.com/Ullaakut/cameradar/v6"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNew(t *testing.T) {
tests := []struct {
name string
scanner cameradar.StreamScanner
attacker cameradar.StreamAttacker
wantErr require.ErrorAssertionFunc
wantMsg string
}{
{
name: "missing scanner",
scanner: nil,
attacker: &fakeAttacker{},
wantErr: require.Error,
wantMsg: "stream scanner is required",
},
{
name: "missing attacker",
scanner: &fakeScanner{},
attacker: nil,
wantErr: require.Error,
wantMsg: "stream attacker is required",
},
{
name: "valid",
scanner: &fakeScanner{},
attacker: &fakeAttacker{},
wantErr: require.NoError,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
app, err := cameradar.New(test.scanner, test.attacker, []string{"target"}, []string{"554"}, &recordingReporter{})
test.wantErr(t, err)
if test.wantMsg != "" {
assert.ErrorContains(t, err, test.wantMsg)
}
if err == nil {
require.NotNil(t, app)
}
})
}
}
func TestApp_Run(t *testing.T) {
ctx := t.Context()
streams := []cameradar.Stream{{Port: 554}}
attacked := []cameradar.Stream{{Port: 8554}}
tests := []struct {
name string
scanner *fakeScanner
attacker *fakeAttacker
wantErrContains string
wantErrorCalls int
wantDoneCalls int
wantSummaryErr string
wantSummary []cameradar.Stream
}{
{
name: "success",
scanner: &fakeScanner{
streams: streams,
},
attacker: &fakeAttacker{
streams: attacked,
},
wantDoneCalls: 1,
wantSummary: attacked,
wantSummaryErr: "",
},
{
name: "scan error",
scanner: &fakeScanner{
streams: streams,
err: errors.New("scan failed"),
},
attacker: &fakeAttacker{},
wantErrContains: "discovering devices",
wantErrorCalls: 1,
wantSummary: streams,
wantSummaryErr: "discovering devices",
},
{
name: "attack error",
scanner: &fakeScanner{
streams: streams,
},
attacker: &fakeAttacker{
err: errors.New("attack failed"),
},
wantErrContains: "attacking devices",
wantDoneCalls: 1,
wantSummary: streams,
wantSummaryErr: "attacking devices",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
reporter := &recordingReporter{}
scanner := test.scanner
attacker := test.attacker
app, err := cameradar.New(scanner, attacker, []string{"target"}, []string{"554"}, reporter)
require.NoError(t, err)
err = app.Run(ctx)
if test.wantErrContains != "" {
require.Error(t, err)
assert.ErrorContains(t, err, test.wantErrContains)
} else {
require.NoError(t, err)
}
assert.Equal(t, 1, scanner.calls)
assert.Same(t, ctx, scanner.gotCtx)
if test.wantErrContains == "discovering devices" {
assert.Equal(t, 0, attacker.calls)
} else {
assert.Equal(t, 1, attacker.calls)
assert.Equal(t, streams, attacker.gotStreams)
}
assert.Equal(t, 1, reporter.startCalls)
assert.Equal(t, test.wantDoneCalls, reporter.doneCalls)
assert.Equal(t, test.wantErrorCalls, reporter.errorCalls)
require.Equal(t, 1, reporter.summaryCalls)
assert.Equal(t, test.wantSummary, reporter.summaryStreams)
if test.wantSummaryErr == "" {
assert.NoError(t, reporter.summaryErr)
} else {
require.Error(t, reporter.summaryErr)
assert.ErrorContains(t, reporter.summaryErr, test.wantSummaryErr)
}
})
}
}
type fakeScanner struct {
streams []cameradar.Stream
err error
calls int
gotCtx context.Context
gotTargets []string
gotPorts []string
}
func (f *fakeScanner) Scan(ctx context.Context) ([]cameradar.Stream, error) {
f.calls++
f.gotCtx = ctx
return f.streams, f.err
}
type fakeAttacker struct {
streams []cameradar.Stream
err error
calls int
gotStreams []cameradar.Stream
}
func (f *fakeAttacker) Attack(_ context.Context, streams []cameradar.Stream) ([]cameradar.Stream, error) {
f.calls++
f.gotStreams = append([]cameradar.Stream(nil), streams...)
if f.err != nil {
return streams, f.err
}
if f.streams != nil {
return f.streams, nil
}
return streams, nil
}
type recordingReporter struct {
mu sync.Mutex
startCalls int
doneCalls int
errorCalls int
summaryCalls int
summaryStreams []cameradar.Stream
summaryErr error
}
func (r *recordingReporter) Start(cameradar.Step, string) {
r.mu.Lock()
defer r.mu.Unlock()
r.startCalls++
}
func (r *recordingReporter) Done(cameradar.Step, string) {
r.mu.Lock()
defer r.mu.Unlock()
r.doneCalls++
}
func (r *recordingReporter) Progress(cameradar.Step, string) {}
func (r *recordingReporter) Debug(cameradar.Step, string) {}
func (r *recordingReporter) Error(cameradar.Step, error) {
r.mu.Lock()
defer r.mu.Unlock()
r.errorCalls++
}
func (r *recordingReporter) Summary(streams []cameradar.Stream, err error) {
r.mu.Lock()
defer r.mu.Unlock()
r.summaryCalls++
r.summaryStreams = append([]cameradar.Stream(nil), streams...)
r.summaryErr = err
}
func (r *recordingReporter) Close() {}