package main import ( "io" "log" "os" "sync" "testing" "github.com/probakowski/go-satel" "github.com/stretchr/testify/assert" ) func TestSatelEventTypeFiltering(t *testing.T) { testEvents := make(chan satel.Event) receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} go func() { wg.Add(1) for e := range FilterByType(testEvents, []satel.ChangeType{satel.ArmedPartition, satel.PartitionFireAlarm}) { receivedEvents = append(receivedEvents, e) } wg.Done() }() testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} testEvents <- satel.Event{Type: satel.DoorOpened, Index: 2, Value: true} testEvents <- satel.Event{Type: satel.PartitionAlarm, Index: 3, Value: true} testEvents <- satel.Event{Type: satel.PartitionFireAlarm, Index: 4, Value: true} testEvents <- satel.Event{Type: satel.TroublePart1, Index: 5, Value: true} testEvents <- satel.Event{Type: satel.ZoneTamper, Index: 6, Value: true} close(testEvents) wg.Wait() assert.Len(t, receivedEvents, 2) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}) assert.Contains(t, receivedEvents, satel.Event{Type: satel.PartitionFireAlarm, Index: 4, Value: true}) } func TestSatelEventTypeFiltering_NoAllowedEventTypesMeansAllAreAllowed(t *testing.T) { testEvents := make(chan satel.Event) receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} go func() { wg.Add(1) for e := range FilterByType(testEvents, []satel.ChangeType{}) { receivedEvents = append(receivedEvents, e) } wg.Done() }() for index, ct := range SUPPORTED_CHANGE_TYPES { testEvents <- satel.Event{Type: ct, Index: index, Value: true} } close(testEvents) wg.Wait() assert.Len(t, receivedEvents, len(SUPPORTED_CHANGE_TYPES)) for index, ct := range SUPPORTED_CHANGE_TYPES { assert.Contains(t, receivedEvents, satel.Event{Type: ct, Index: index, Value: true}) } } func TestSatelIndexFiltering(t *testing.T) { testEvents := make(chan satel.Event) receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} go func() { wg.Add(1) for e := range FilterByIndex(testEvents, []int{1, 3}) { receivedEvents = append(receivedEvents, e) } wg.Done() }() testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} testEvents <- satel.Event{Type: satel.DoorOpened, Index: 2, Value: true} testEvents <- satel.Event{Type: satel.PartitionAlarm, Index: 3, Value: true} testEvents <- satel.Event{Type: satel.PartitionFireAlarm, Index: 4, Value: true} testEvents <- satel.Event{Type: satel.TroublePart1, Index: 5, Value: true} testEvents <- satel.Event{Type: satel.ZoneTamper, Index: 6, Value: true} close(testEvents) wg.Wait() assert.Len(t, receivedEvents, 2) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}) assert.Contains(t, receivedEvents, satel.Event{Type: satel.PartitionAlarm, Index: 3, Value: true}) } func TestSatelIndexFiltering_NoAllowedEventTypesMeansAllAreAllowed(t *testing.T) { testEvents := make(chan satel.Event) receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} myReasonableMaxIndex := 100 // I wanted to use math.MaxInt at first, but it's kind of a waste of time here go func() { wg.Add(1) for e := range FilterByIndex(testEvents, []int{}) { receivedEvents = append(receivedEvents, e) } wg.Done() }() for i := 0; i < myReasonableMaxIndex; i++ { testEvents <- satel.Event{Type: satel.ArmedPartition, Index: i, Value: true} } close(testEvents) wg.Wait() assert.Len(t, receivedEvents, myReasonableMaxIndex) for i := 0; i < myReasonableMaxIndex; i++ { assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: i, Value: true}) } } func TestSatelLastSeenFiltering(t *testing.T) { f, err := os.CreateTemp("", "TestSatelLastSeenFiltering") assert.NoError(t, err) tempFileName := f.Name() assert.NoError(t, f.Close()) defer os.Remove(f.Name()) testEvents := make(chan satel.Event) receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} fakeLog := log.New(io.Discard, "", log.Ltime) ds := MakeDataStore(fakeLog, tempFileName) go func() { wg.Add(1) for e := range FilterByLastSeen(testEvents, &ds, fakeLog) { receivedEvents = append(receivedEvents, e) } wg.Done() }() testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} close(testEvents) wg.Wait() assert.Len(t, receivedEvents, 3) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true}) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false}) } func TestSatelLastSeenFilteringWithPersistence(t *testing.T) { f, err := os.CreateTemp("", "TestSatelLastSeenFilteringWithPersistence") assert.NoError(t, err) tempFileName := f.Name() assert.NoError(t, f.Close()) defer os.Remove(f.Name()) testEvents := make(chan satel.Event) receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} fakeLog := log.New(io.Discard, "", log.Ltime) ds := MakeDataStore(fakeLog, tempFileName) go func() { wg.Add(1) for e := range FilterByLastSeen(testEvents, &ds, fakeLog) { receivedEvents = append(receivedEvents, e) } wg.Done() }() testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} close(testEvents) wg.Wait() assert.Len(t, receivedEvents, 3) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true}) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false}) testEvents = make(chan satel.Event) receivedEvents = make([]satel.Event, 0) ds = MakeDataStore(fakeLog, tempFileName) go func() { wg.Add(1) for e := range FilterByLastSeen(testEvents, &ds, fakeLog) { receivedEvents = append(receivedEvents, e) } wg.Done() }() receivedEvents = make([]satel.Event, 0) testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} close(testEvents) wg.Wait() assert.Len(t, receivedEvents, 1) assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}) }