package reset import ( "database/sql" "fmt" "io/ioutil" "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/require" "src.dualinventive.com/go/cp3000-interface/internal/storage" "src.dualinventive.com/go/dinet" "src.dualinventive.com/go/dinet/rpc" ) func createTestObj(t *testing.T) (*Reset, *dinet.TestTransport) { msgProxyConn, err := dinet.NewConn(dinet.TransportTest) require.Nil(t, err) require.Nil(t, msgProxyConn.Connect("")) reset, err := New("testdata/private.cert", "testdata/private.key", "testdata/wsdl.wsdl", "myusername", "mypassword", msgProxyConn) require.Nil(t, err) return reset, msgProxyConn.(*dinet.TestTransport) } func updateWSDLURL(t *testing.T, r *Reset, location string) { require.NotNil(t, r) require.NotNil(t, r.vodafoneM2MSoapClient) require.NotNil(t, r.vodafoneM2MSoapClient.Definitions) for _, s := range r.vodafoneM2MSoapClient.Definitions.Services { for _, p := range s.Ports { for _, a := range p.SoapAddresses { a.Location = location } } } } func TestResetSMS(t *testing.T) { r, msgProxyConn := createTestObj(t) device := &storage.Device{ ID: 10, TelephoneNR: "+31612345678", SMSOperator: sql.NullInt64{ Int64: 0, Valid: false, }, } errChan := make(chan error) go func() { errChan <- r.Reset(device) }() // receive the request to the messaging proxy msg := <-msgProxyConn.Read require.Equal(t, rpc.CurrentDinetrpc, msg.Dinetrpc) require.Equal(t, rpc.ClassMethodMessageSms, msg.ClassMethod) require.Equal(t, rpc.MsgTypeRequest, msg.Type) var recvParam []rpc.MessageSms err := msg.Params.Unmarshal(&recvParam) require.Nil(t, err) require.Equal(t, []rpc.MessageSms{{Destinations: []string{"+31612345678"}, Message: resetCommand}}, recvParam) // write the response back to the cp3000-interface msg.Type = rpc.MsgTypeReply msg.Params = nil msgProxyConn.Write <- msg // reset was ok require.Nil(t, <-errChan) } func TestResetSMSSendFailed(t *testing.T) { r, msgProxyConn := createTestObj(t) // close the messaging proxy connection to force an error err := msgProxyConn.Close() require.Nil(t, err) device := &storage.Device{ ID: 10, TelephoneNR: "+31612345678", SMSOperator: sql.NullInt64{ Int64: 0, Valid: false, }, } // reset was not ok require.Equal(t, dinet.ErrDisconnected, r.Reset(device)) } func TestResetSMSMessagingProxyFailed(t *testing.T) { r, msgProxyConn := createTestObj(t) device := &storage.Device{ ID: 10, TelephoneNR: "+31612345678", SMSOperator: sql.NullInt64{ Int64: 0, Valid: false, }, } errChan := make(chan error) go func() { errChan <- r.Reset(device) }() // receive the request to the messaging proxy msg := <-msgProxyConn.Read require.Equal(t, rpc.CurrentDinetrpc, msg.Dinetrpc) require.Equal(t, rpc.ClassMethodMessageSms, msg.ClassMethod) require.Equal(t, rpc.MsgTypeRequest, msg.Type) var recvParam []rpc.MessageSms err := msg.Params.Unmarshal(&recvParam) require.Nil(t, err) require.Equal(t, []rpc.MessageSms{{Destinations: []string{"+31612345678"}, Message: resetCommand}}, recvParam) // write the error response back to the cp3000-interface msg.Type = rpc.MsgTypeReply msg.Params = nil msg.Error = rpc.GetError(rpc.EBackendCp3000CommError) msgProxyConn.Write <- msg // reset was not ok require.Equal(t, rpc.GetError(rpc.EBackendCp3000CommError), <-errChan) } func TestResetSMSRecvFailed(t *testing.T) { r, msgProxyConn := createTestObj(t) device := &storage.Device{ ID: 10, TelephoneNR: "+31612345678", SMSOperator: sql.NullInt64{ Int64: 0, Valid: false, }, } errChan := make(chan error) go func() { errChan <- r.Reset(device) }() // receive the request to the messaging proxy msg := <-msgProxyConn.Read require.Equal(t, rpc.CurrentDinetrpc, msg.Dinetrpc) require.Equal(t, rpc.ClassMethodMessageSms, msg.ClassMethod) require.Equal(t, rpc.MsgTypeRequest, msg.Type) var recvParam []rpc.MessageSms err := msg.Params.Unmarshal(&recvParam) require.Nil(t, err) require.Equal(t, []rpc.MessageSms{{Destinations: []string{"+31612345678"}, Message: resetCommand}}, recvParam) // close the messaging proxy connection to force a recv error err = msgProxyConn.Close() require.Nil(t, err) // reset was not ok require.Equal(t, dinet.ErrDisconnected, <-errChan) } func TestResetVodafoneM2M(t *testing.T) { r, _ := createTestObj(t) device := &storage.Device{ IMSI: "310150123456789", SMSOperator: sql.NullInt64{ Int64: 22, Valid: true, }, } requestChan := make(chan *http.Request) responseChan := make(chan http.ResponseWriter) send := make(chan bool) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestChan <- r responseChan <- w <-send })) defer ts.Close() // Change all the URLs in the WSDL file updateWSDLURL(t, r, ts.URL) errChan := make(chan error) go func() { errChan <- r.Reset(device) }() // Receive the request data request := <-requestChan requestData, err := ioutil.ReadAll(request.Body) // First this check, because when ioutil returns an error we didn't close the body require.Nil(t, request.Body.Close()) require.Nil(t, err) // Write a response back resp := <-responseChan fmt.Fprintln(resp, ` 000 00 `) send <- true // Receive the expected data dat, err := ioutil.ReadFile("testdata/xmlrequest.xml") require.Nil(t, err) // Compare the expected data and the requested data require.Equal(t, dat, requestData) // Expect no error require.Nil(t, <-errChan) } func TestResetVodafoneM2MFailed(t *testing.T) { r, _ := createTestObj(t) device := &storage.Device{ IMSI: "310150123456789", SMSOperator: sql.NullInt64{ Int64: 22, Valid: true, }, } requestChan := make(chan *http.Request) responseChan := make(chan http.ResponseWriter) send := make(chan bool) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestChan <- r responseChan <- w <-send })) defer ts.Close() // Change all the URLs in the WSDL file updateWSDLURL(t, r, ts.URL) errChan := make(chan error) go func() { errChan <- r.Reset(device) }() // Receive the request data request := <-requestChan requestData, err := ioutil.ReadAll(request.Body) // First this check, because when ioutil returns an error we didn't close the body require.Nil(t, request.Body.Close()) require.Nil(t, err) // Write a response back resp := <-responseChan fmt.Fprintln(resp, ` 100 15 `) send <- true // Receive the expected data dat, err := ioutil.ReadFile("testdata/xmlrequest.xml") require.Nil(t, err) // Compare the expected data and the requested data require.Equal(t, dat, requestData) // Expect error require.Equal(t, SoapReturnValue{MajorReturnCode: "100", MinorReturnCode: "15"}, <-errChan) }