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)
}