func TestListenerEventChan(t *testing.T) {
	contracts, err := cutils.SetupAllTestContracts()
	if err != nil {
		t.Fatalf("Unable to setup the contracts: err: %v", err)
	}
	watchers := []model.ContractWatchers{
		watcher.NewCivilTCRContractWatchers(contracts.CivilTcrAddr),
		watcher.NewNewsroomContractWatchers(contracts.NewsroomAddr),
	}
	listener := setupListener(t, contracts.Client, watchers)
	defer listener.Stop(true)  
	quitChan := make(chan interface{})
	eventRecv := make(chan bool)
	go func(quit <-chan interface{}, recv chan<- bool) {
		for {
			select {
			case event := <-listener.EventRecvChan:
				if event.EventType() != "Application" {
					t.Errorf("Eventtype is not correct: %v", event.EventType())
				}
				recv <- true
			case <-quit:
				return
			}
		}
	}(quitChan, eventRecv)
	tempPayload := &contract.CivilTCRContractApplication{
		ListingAddress: contracts.CivilTcrAddr,
		Deposit:        big.NewInt(1000),
		AppEndDate:     big.NewInt(1653860896),
		Data:           "DATA",
		Applicant:      contracts.CivilTcrAddr,
		Raw: types.Log{
			Address:     contracts.CivilTcrAddr,
			Topics:      []common.Hash{},
			Data:        []byte{},
			BlockNumber: 8888888,
		},
	}
	newEvent, _ := model.NewEventFromContractEvent("Application", "CivilTCRContract", contracts.CivilTcrAddr, tempPayload,
		ctime.CurrentEpochSecsInInt64(), model.Filterer)
	listener.EventRecvChan <- newEvent
	select {
	case <-eventRecv:
		close(quitChan)
	case <-time.After(5 * time.Second):
		t.Errorf("Event not received, should have been received by goroutine")
		close(quitChan)
	}
}
TestListenerEventChan mainly tests the EventRecvChan to ensure it can
pass along a Event object
package listener_test
import (
	"errors"
	"math/big"
	"runtime"
	"testing"
	"time"
	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	ctime "github.com/joincivil/go-common/pkg/time"
	"github.com/joincivil/civil-events-crawler/pkg/contractspecs"
	cutils "github.com/joincivil/civil-events-crawler/pkg/contractutils"
	"github.com/joincivil/civil-events-crawler/pkg/generated/watcher"
	"github.com/joincivil/civil-events-crawler/pkg/listener"
	"github.com/joincivil/civil-events-crawler/pkg/model"
	"github.com/joincivil/civil-events-crawler/pkg/utils"
	"github.com/joincivil/go-common/pkg/generated/contract"
)
func TestListener(t *testing.T) {
	contracts, err := cutils.SetupAllTestContracts()
	if err != nil {
		t.Fatalf("Unable to setup the contracts: %v", err)
	}
	watchers := []model.ContractWatchers{
		watcher.NewCivilTCRContractWatchers(contracts.CivilTcrAddr),
		watcher.NewNewsroomContractWatchers(contracts.NewsroomAddr),
	}
	contractspecs.EnableListener[contractspecs.EnableAllListenersKey] = true
	listener := setupListener(t, contracts.Client, watchers)
	defer listener.Stop(true)  
}
func TestListenerStop(t *testing.T) {
	contracts, err := cutils.SetupAllTestContracts()
	if err != nil {
		t.Fatalf("Unable to setup the contracts: %v", err)
	}
	watchers := []model.ContractWatchers{
		watcher.NewCivilTCRContractWatchers(contracts.CivilTcrAddr),
		watcher.NewNewsroomContractWatchers(contracts.NewsroomAddr),
	}
	contractspecs.EnableListener[contractspecs.EnableAllListenersKey] = true
	listener := setupListener(t, contracts.Client, watchers)
	initialNumRoutines := runtime.NumGoroutine()
	listener.Stop(true)  
	if initialNumRoutines <= runtime.NumGoroutine() {
		t.Errorf("Number of goroutines has not gone down since listener.Stop")
	}
}
type testErrorWatcher struct{}
func (t *testErrorWatcher) ContractName() string {
	return "TestErrorContract"
}
func (t *testErrorWatcher) ContractAddress() common.Address {
	return common.HexToAddress("0xf86a8a467666c752fa99bb7ca954d269ab6136bf")
}
func (t *testErrorWatcher) StopWatchers(unsub bool) error {
	return nil
}
func (t *testErrorWatcher) StartWatchers(client bind.ContractBackend,
	eventRecvChan chan *model.Event, errs chan error) ([]utils.WatcherSubscription, error) {
	return nil, errors.New("This is an error starting watchers")
}
func TestListenerEmptyWatchers(t *testing.T) {
	contracts, err := cutils.SetupAllTestContracts()
	if err != nil {
		t.Fatalf("Unable to setup the contracts: %v", err)
	}
	watchers := []model.ContractWatchers{
		&testErrorWatcher{},
	}
	contractspecs.EnableListener[contractspecs.EnableAllListenersKey] = true
	listener := listener.NewEventListener(contracts.Client, watchers)
	if listener == nil {
		t.Fatal("Listener should not be nil")
	}
	subs, err := listener.Start()
	if err == nil {
		t.Errorf("Listener should have failed with no watchers: %v", err)
	}
	if len(subs) > 0 {
		t.Error("Listener should have had no watchers")
	}
}
func TestListenerDisableWatchers(t *testing.T) {
	contracts, err := cutils.SetupAllTestContracts()
	if err != nil {
		t.Fatalf("Unable to setup the contracts: %v", err)
	}
	watchers := []model.ContractWatchers{
		watcher.NewCivilTCRContractWatchers(contracts.CivilTcrAddr),
	}
	contractspecs.EnableListener[contractspecs.EnableAllListenersKey] = true
	listener := listener.NewEventListener(contracts.Client, watchers)
	if listener == nil {
		t.Fatal("Listener should not be nil")
	}
	contractspecs.EnableListener = map[string]bool{}
	_, err = listener.Start()
	if err != nil {
		t.Errorf("Listener not should have failed with no watchers")
	}
}
func TestListenerEnableWatchers(t *testing.T) {
	contracts, err := cutils.SetupAllTestContracts()
	if err != nil {
		t.Fatalf("Unable to setup the contracts: %v", err)
	}
	watchers := []model.ContractWatchers{
		watcher.NewCivilTCRContractWatchers(contracts.CivilTcrAddr),
	}
	listener := listener.NewEventListener(contracts.Client, watchers)
	if listener == nil {
		t.Fatal("Listener should not be nil")
	}
	contractspecs.EnableListener = map[string]bool{
		contractspecs.FlagKey("CivilTCRContract", "ApplicationWhitelisted"): true,
	}
	subs, err := listener.Start()
	if err != nil || len(subs) == 0 {
		t.Errorf("Listener should have enabled a watcher: %v", err)
	}
}