github.com/status-im/status-go@v1.1.0/server/server_test.go (about)

     1  package server
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"encoding/base64"
     7  	"encoding/pem"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"net/url"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/stretchr/testify/require"
    16  	"github.com/stretchr/testify/suite"
    17  
    18  	"github.com/status-im/status-go/images"
    19  	"github.com/status-im/status-go/protocol/common"
    20  	"github.com/status-im/status-go/server/servertest"
    21  )
    22  
    23  const (
    24  	waitTime            = 50 * time.Millisecond
    25  	customPortForTests  = 1337
    26  	defaultPortForTests = 80
    27  )
    28  
    29  var (
    30  	baseURL                = "https://127.0.0.1"
    31  	baseURLWithCustomPort  = fmt.Sprintf("%s:%d", baseURL, customPortForTests)
    32  	baseURLWithDefaultPort = fmt.Sprintf("%s:%d", baseURL, defaultPortForTests)
    33  )
    34  
    35  func TestServerURLSuite(t *testing.T) {
    36  	suite.Run(t, new(ServerURLSuite))
    37  }
    38  
    39  type ServerURLSuite struct {
    40  	suite.Suite
    41  	servertest.TestKeyComponents
    42  	servertest.TestLoggerComponents
    43  
    44  	server       *MediaServer
    45  	serverForQR  *MediaServer
    46  	serverNoPort *MediaServer
    47  	testStart    time.Time
    48  }
    49  
    50  func (s *ServerURLSuite) SetupTest() {
    51  	s.SetupKeyComponents(s.T())
    52  	s.SetupLoggerComponents()
    53  
    54  	mediaServer, err := NewMediaServer(nil, nil, nil, nil)
    55  	s.Require().NoError(err)
    56  
    57  	s.serverForQR = mediaServer
    58  
    59  	err = s.serverForQR.Start()
    60  	s.Require().NoError(err)
    61  
    62  	s.server = &MediaServer{Server: Server{
    63  		hostname:   LocalHostIP.String(),
    64  		portManger: newPortManager(s.Logger, nil),
    65  	}}
    66  	err = s.server.SetPort(customPortForTests)
    67  	s.Require().NoError(err)
    68  
    69  	s.serverNoPort = &MediaServer{Server: Server{
    70  		hostname:   LocalHostIP.String(),
    71  		portManger: newPortManager(s.Logger, nil),
    72  	}}
    73  	go func() {
    74  		time.Sleep(waitTime)
    75  		s.serverNoPort.port = defaultPortForTests
    76  	}()
    77  
    78  	s.testStart = time.Now()
    79  }
    80  
    81  // testNoPort takes two strings and compares expects them both to be equal
    82  // then compares ServerURLSuite.testStart to the current time
    83  // the difference must be greater than waitTime.
    84  // This is caused by the ServerURLSuite.SetupTest waiting waitTime before unlocking the portWait sync.Mutex
    85  func (s *ServerURLSuite) testNoPort(expected string, actual string) {
    86  	s.Require().Equal(expected, actual)
    87  	s.Require().Greater(time.Since(s.testStart), waitTime)
    88  }
    89  
    90  func (s *ServerURLSuite) TestServer_MakeBaseURL() {
    91  	s.Require().Equal(baseURLWithCustomPort, s.server.MakeBaseURL().String())
    92  	s.testNoPort(baseURLWithDefaultPort, s.serverNoPort.MakeBaseURL().String())
    93  }
    94  
    95  func (s *ServerURLSuite) TestServer_MakeImageServerURL() {
    96  	s.Require().Equal(baseURLWithCustomPort+"/messages/", s.server.MakeImageServerURL())
    97  	s.testNoPort(baseURLWithDefaultPort+"/messages/", s.serverNoPort.MakeImageServerURL())
    98  }
    99  
   100  func (s *ServerURLSuite) TestServer_MakeImageURL() {
   101  	s.Require().Equal(
   102  		baseURLWithCustomPort+"/messages/images?messageId=0x10aded70ffee",
   103  		s.server.MakeImageURL("0x10aded70ffee"))
   104  
   105  	s.testNoPort(
   106  		baseURLWithDefaultPort+"/messages/images?messageId=0x10aded70ffee",
   107  		s.serverNoPort.MakeImageURL("0x10aded70ffee"))
   108  }
   109  
   110  func (s *ServerURLSuite) TestServer_MakeLinkPreviewThumbnailURL() {
   111  	s.Require().Equal(
   112  		baseURLWithCustomPort+"/link-preview/thumbnail?message-id=99&url=https%3A%2F%2Fgithub.com",
   113  		s.server.MakeLinkPreviewThumbnailURL("99", "https://github.com"))
   114  
   115  	s.testNoPort(
   116  		baseURLWithDefaultPort+"/link-preview/thumbnail?message-id=99&url=https%3A%2F%2Fgithub.com",
   117  		s.serverNoPort.MakeLinkPreviewThumbnailURL("99", "https://github.com"))
   118  }
   119  
   120  func (s *ServerURLSuite) TestServer_MakeStatusLinkPreviewThumbnailURL() {
   121  	s.Require().Equal(
   122  		baseURLWithCustomPort+"/status-link-preview/thumbnail?image-id=contact-icon&message-id=99&url=https%3A%2F%2Fstatus.app",
   123  		s.server.MakeStatusLinkPreviewThumbnailURL("99", "https://status.app", common.MediaServerContactIcon))
   124  
   125  	s.testNoPort(
   126  		baseURLWithDefaultPort+"/status-link-preview/thumbnail?image-id=contact-icon&message-id=99&url=https%3A%2F%2Fstatus.app",
   127  		s.serverNoPort.MakeStatusLinkPreviewThumbnailURL("99", "https://status.app", common.MediaServerContactIcon))
   128  }
   129  
   130  func (s *ServerURLSuite) TestServer_MakeAudioURL() {
   131  	s.Require().Equal(
   132  		baseURLWithCustomPort+"/messages/audio?messageId=0xde1e7ebee71e",
   133  		s.server.MakeAudioURL("0xde1e7ebee71e"))
   134  	s.testNoPort(
   135  		baseURLWithDefaultPort+"/messages/audio?messageId=0xde1e7ebee71e",
   136  		s.serverNoPort.MakeAudioURL("0xde1e7ebee71e"))
   137  }
   138  
   139  func (s *ServerURLSuite) TestServer_MakeStickerURL() {
   140  	s.Require().Equal(
   141  		baseURLWithCustomPort+"/ipfs?hash=0xdeadbeef4ac0",
   142  		s.server.MakeStickerURL("0xdeadbeef4ac0"))
   143  	s.testNoPort(
   144  		baseURLWithDefaultPort+"/ipfs?hash=0xdeadbeef4ac0",
   145  		s.serverNoPort.MakeStickerURL("0xdeadbeef4ac0"))
   146  }
   147  
   148  // TestQRCodeGeneration tests if we provide all the correct parameters to the media server
   149  // do we get a valid QR code or not as part of the response payload.
   150  // we have stored a generated QR code in tests folder, and we compare their bytes.
   151  func (s *ServerURLSuite) TestQRCodeGeneration() {
   152  
   153  	qrURL := "https://github.com/status-im/status-go/pull/3154"
   154  	generatedURL := base64.StdEncoding.EncodeToString([]byte(qrURL))
   155  	generatedURL = s.serverForQR.MakeQRURL(generatedURL, "false", "2", "200", "", "")
   156  
   157  	u, err := url.Parse(generatedURL)
   158  	if err != nil {
   159  		s.Require().NoError(err)
   160  	}
   161  
   162  	if u.Scheme == "" || u.Host == "" {
   163  		s.Require().Failf("generatedURL is not a valid URL: %s", generatedURL)
   164  	}
   165  
   166  	serverCert := s.serverForQR.cert
   167  	serverCertBytes := serverCert.Certificate[0]
   168  
   169  	certPem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: serverCertBytes})
   170  
   171  	rootCAs, err := x509.SystemCertPool()
   172  	if err != nil {
   173  		s.Require().NoError(err)
   174  	}
   175  
   176  	_ = rootCAs.AppendCertsFromPEM(certPem)
   177  	tr := &http.Transport{
   178  		TLSClientConfig: &tls.Config{
   179  			MinVersion: tls.VersionTLS12,
   180  			RootCAs:    rootCAs,
   181  		},
   182  	}
   183  
   184  	client := &http.Client{Transport: tr}
   185  
   186  	req, err := http.NewRequest(http.MethodGet, generatedURL, nil)
   187  	if err != nil {
   188  		s.Require().NoError(err)
   189  	}
   190  
   191  	resp, err := client.Do(req)
   192  	if err != nil {
   193  		s.Require().NoError(err)
   194  	}
   195  
   196  	defer func() {
   197  		_ = resp.Body.Close()
   198  	}()
   199  
   200  	if resp.StatusCode != http.StatusOK {
   201  		s.Require().Failf("Unexpected response status code: %d", fmt.Sprint(resp.StatusCode))
   202  	}
   203  
   204  	payload, err := ioutil.ReadAll(resp.Body)
   205  	if err != nil {
   206  		s.Require().NoError(err)
   207  	}
   208  
   209  	s.Require().NotEmpty(payload)
   210  
   211  	expectedPayload, err := images.Asset("_assets/tests/qr/defaultQR.png")
   212  	require.Equal(s.T(), payload, expectedPayload)
   213  	s.Require().NoError(err)
   214  
   215  	//(siddarthkay) un-comment code block below to generate the file in tests folder
   216  	//f, err := os.Create("image.png")
   217  	//if err != nil {
   218  	//	s.Require().NoError(err)
   219  	//
   220  	//}
   221  	//defer f.Close()
   222  	//_, err = f.Write(payload)
   223  	//
   224  	//if err != nil {
   225  	//	s.Require().NoError(err)
   226  	//}
   227  }