package tmobile import ( "context" "fmt" "strings" "sync" "testing" "time" "github.com/pkg/errors" ) func TestSMSClient_Start(t *testing.T) { t.Skip() clSucc := MockClientAccTokResSucc{wasSet: make(chan string, 1)} smsc := NewSMSClient(&clSucc, nil) ctx, cancel := context.WithCancel(context.Background()) go smsc.Start(ctx) t.Log("Waiting for FIRST access token to be set") select { case gotAt := <-clSucc.wasSet: if gotAt != fmt.Sprintf("%s%d", mockAccessTokenResponse.AccessToken, 0) { t.Errorf("expected access token %s, got %s", mockAccessTokenResponse.AccessToken, gotAt) close(clSucc.wasSet) cancel() return } t.Log("First access token set") case <-time.After(time.Second): t.Error("Access token was not set, cancelling test") close(clSucc.wasSet) cancel() return } time.Sleep(time.Second) t.Log("Waiting for REFRESHED access token to be set") select { case gotAt := <-clSucc.wasSet: if gotAt != fmt.Sprintf("%s%d", mockAccessTokenResponse.AccessToken, 1) { t.Errorf("expected access token %s, got %s", mockAccessTokenResponse.AccessToken, gotAt) cancel() close(clSucc.wasSet) return } t.Log("Refreshed access token set") case <-time.After(time.Second): t.Error("Access token was not set, cancelling test") cancel() close(clSucc.wasSet) return } t.Log("Waiting for CANCELLATION") cancel() doneChan := ctx.Done() if _, ok := <-doneChan; ok { t.Error("Context was not cancelled") close(clSucc.wasSet) return } else { t.Log("Context was cancelled") } time.Sleep(time.Second) if len(clSucc.wasSet) != 0 { t.Error("Access token was set after cancellation") close(clSucc.wasSet) return } t.Log("Success test finished") clFail := MockClientAccTokResFail{wasSet: make(chan struct{}, 3)} smsc = NewSMSClient(&clFail, nil) ctx, cancel = context.WithCancel(context.Background()) go smsc.Start(ctx) time.Sleep(time.Millisecond * 100) if len(clFail.wasSet) <= 2 { t.Errorf("Access token was not set after failure: len(chan) = %d", len(clFail.wasSet)) cancel() close(clFail.wasSet) return } cancel() t.Log("Test finished") } var mockSmsRequest = &SendSMSRequest{ ICCID: "12345678901234567890", MessageText: "Hello world", await: true, } var mockCtx = context.Background() func TestSMSClient_SendSMS(t *testing.T) { t.Skip() cl := MockClientSendSMSResSucc{wasSet: make(chan SmsDetailsStatus, 3)} smsc := NewSMSClient(&cl, nil) t.Log("sending succ SMS") r, err := smsc.SendSMS(mockCtx, mockSmsRequest) if err != nil { t.Errorf("SendSMS failed: %v", err) close(cl.wasSet) return } if r.Status != Delivered { t.Errorf("SendSMS returned status %s, expected %s", r.Status, Delivered) close(cl.wasSet) return } t.Log("getting succ SMS statuses") for i := 0; i < 3; i++ { select { case status := <-cl.wasSet: t.Logf("sms status was set: %s", status) case <-time.After(time.Second): t.Error("sms was not set") return } } } func TestSMSClient_SendSMS_FailOnSend(t *testing.T) { t.Skip() cl := MockClientSendSMSResFail{wasSet: make(chan struct{}, 1)} smsc := NewSMSClient(&cl, nil) t.Log("sending fail SMS") out, err := smsc.SendSMS(mockCtx, mockSmsRequest) if !strings.HasPrefix(err.Error(), "failed to send SMS") { t.Error("SendSMS should have failed") close(cl.wasSet) return } if out != nil { t.Error("SendSMS should have returned nil") close(cl.wasSet) return } t.Log("getting SendSMS failure") select { case <-cl.wasSet: t.Log("SendSMS was called") case <-time.After(time.Second): t.Error("SendSMS was not called") return } } func TestSMSClient_SendSMSFailOnDetailsStatus(t *testing.T) { t.Skip() for _, curType := range smsStatusFailTypes { cl := MockClientSendSMSDetailsFailWithBadStatus{wasSet: make(chan SmsDetailsStatus, len(curType)), toFail: curType} smsc := NewSMSClient(&cl, nil) t.Logf("sending fail SMS with type %s", curType[len(curType)-1]) r, err := smsc.SendSMS(mockCtx, mockSmsRequest) if err == nil { t.Errorf("SendDetails should have failed: %v", err) close(cl.wasSet) return } if r == nil { t.Error("SendDetails should have returned non-nil") close(cl.wasSet) return } t.Log("getting succ SMS statuses") for i := 0; i < len(curType); i++ { select { case status := <-cl.wasSet: t.Logf("sms status was set: %s", status) case <-time.After(time.Second): t.Error("sms was not set") return } } } } func TestSMSClient_SendSMSFailOnDetails(t *testing.T) { // TODO fix the timing of this test, skipping for now t.Skip() cl := &MockClientSendSMSDetailsFailRes{wasSet: make(chan struct{}, 1)} smsc := NewSMSClient(cl, nil) r, err := smsc.SendSMS(mockCtx, mockSmsRequest) if !strings.HasPrefix(err.Error(), "failed to get sms details") { t.Errorf("SendDetails should have failed: %v", err) close(cl.wasSet) return } if r != nil { t.Errorf("SendDetails should have returned nil: %v", r) close(cl.wasSet) return } select { case <-cl.wasSet: t.Log("SendDetails was called") case <-time.After(time.Second): t.Error("SendDetails was not called") } } func TestNewSMSClient_SendSMSAwaitExpire(t *testing.T) { t.Skip() cl := &MockClientSendSMSExpire{} smsc := NewSMSClient(cl, nil) r, err := smsc.SendSMS(mockCtx, mockSmsRequest) if !errors.Is(err, ErrTimeoutSendingMessage) { t.Errorf("SendSMS should have failed: %v", err) return } if r != nil { t.Errorf("SendSMS should have returned nil: %v", r) return } } type MockWrapperFail struct { SMSClientWrapper wasSet chan struct{} } func (mw *MockWrapperFail) SendSMS(ctx context.Context, req *SendSMSRequest) (*SMSDetailsResponse, error) { mw.wasSet <- struct{}{} return nil, ErrTimeoutSendingMessage } type MockWrapper struct { SMSClientWrapper wasSet chan struct{} } func (mw *MockWrapper) SendSMS(ctx context.Context, req *SendSMSRequest) (*SMSDetailsResponse, error) { mw.wasSet <- struct{}{} return mockSmsDetailsResponse, nil } func TestWrapperIntegrationTest(t *testing.T) { t.Skip() tg, err := InitTokenGen( "PRIVATE KEY", "ID", "PASSWORD", ) if err != nil { t.Error(err) } tmobc, err := NewTMobileClient( Endpoint, tg, time.Minute*2) client := NewSMSClient(tmobc, nil) iccids := []string{"8901882000784161105", "8901882000784163135", "8901882000784161071", "8901882000784164976", "8901882000784163135", "8901882000787584451", "8901882000784166427", "8901882000784163671", "8901882000784163945", "8901882000784167342", "8901882000784166625"} wg := sync.WaitGroup{} // Running test 10 times in a row to see if we get any failures for _, iccid := range iccids { wg.Add(1) go func(iccid string) { msg := SendSMSRequest{ ICCID: iccid, MessageText: "newer_test", await: true, } ctx, cancel := context.WithTimeout(context.Background(), time.Second*45) defer cancel() _, err := client.SendSMS(ctx, &msg) if err != nil { t.Error(err) } wg.Done() }(iccid) } wg.Wait() } // Want to benchmark and record the memory and cpu usage of having different ways to check if the sms was delivered func BenchmarkSMSWrapper(b *testing.B) { sim := newTMboileSimulator() wrap := NewSMSClient(&sim, nil) tt := sync.WaitGroup{} for x := 0; x < 1000; x++ { tt.Add(1) go func() { wrap.SendSMS(context.Background(), &SendSMSRequest{ MessageText: ".", await: true, }) tt.Done() }() } tt.Wait() }