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 }