github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/services/remotecluster/sendprofileImage_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package remotecluster
     5  
     6  import (
     7  	"bytes"
     8  	"image"
     9  	"image/color"
    10  	"image/png"
    11  	"io"
    12  	"io/ioutil"
    13  	"net/http"
    14  	"net/http/httptest"
    15  	"sync"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/masterhung0112/hk_server/v5/model"
    23  )
    24  
    25  const (
    26  	imageWidth  = 128
    27  	imageHeight = 128
    28  )
    29  
    30  func TestService_sendProfileImageToRemote(t *testing.T) {
    31  	hadPing := disablePing
    32  	disablePing = true
    33  	defer func() { disablePing = hadPing }()
    34  
    35  	shouldError := &flag{}
    36  
    37  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    38  		defer io.Copy(ioutil.Discard, r.Body)
    39  
    40  		if shouldError.get() {
    41  			w.WriteHeader(http.StatusInternalServerError)
    42  			resp := make(map[string]string)
    43  			resp[model.STATUS] = model.STATUS_FAIL
    44  			w.Write([]byte(model.MapToJson(resp)))
    45  			return
    46  		}
    47  
    48  		status := model.STATUS_OK
    49  		defer func(s *string) {
    50  			if *s != model.STATUS_OK {
    51  				w.WriteHeader(http.StatusInternalServerError)
    52  			}
    53  			resp := make(map[string]string)
    54  			resp[model.STATUS] = *s
    55  			w.Write([]byte(model.MapToJson(resp)))
    56  		}(&status)
    57  
    58  		if err := r.ParseMultipartForm(1024 * 1024); err != nil {
    59  			status = model.STATUS_FAIL
    60  			assert.Fail(t, "connect parse multipart form", err)
    61  			return
    62  		}
    63  		m := r.MultipartForm
    64  		if m == nil {
    65  			status = model.STATUS_FAIL
    66  			assert.Fail(t, "multipart form missing")
    67  			return
    68  		}
    69  
    70  		imageArray, ok := m.File["image"]
    71  		if !ok || len(imageArray) != 1 {
    72  			status = model.STATUS_FAIL
    73  			assert.Fail(t, "image missing")
    74  			return
    75  		}
    76  
    77  		imageData := imageArray[0]
    78  		file, err := imageData.Open()
    79  		if err != nil {
    80  			status = model.STATUS_FAIL
    81  			assert.Fail(t, "cannot open multipart form file")
    82  			return
    83  		}
    84  		defer file.Close()
    85  
    86  		img, err := png.Decode(file)
    87  		if err != nil || imageWidth != img.Bounds().Max.X || imageHeight != img.Bounds().Max.Y {
    88  			status = model.STATUS_FAIL
    89  			assert.Fail(t, "cannot decode png", err)
    90  			return
    91  		}
    92  	}))
    93  	defer ts.Close()
    94  
    95  	rc := makeRemoteCluster("remote_test_profile_image", ts.URL, TestTopics)
    96  
    97  	user := &model.User{
    98  		Id:       model.NewId(),
    99  		RemoteId: model.NewString(rc.RemoteId),
   100  	}
   101  
   102  	provider := testImageProvider{}
   103  
   104  	mockServer := newMockServer(t, makeRemoteClusters(NumRemotes, ts.URL))
   105  	mockServer.SetUser(user)
   106  	service, err := NewRemoteClusterService(mockServer)
   107  	require.NoError(t, err)
   108  
   109  	err = service.Start()
   110  	require.NoError(t, err)
   111  	defer service.Shutdown()
   112  
   113  	t.Run("Server response 200", func(t *testing.T) {
   114  		shouldError.set(false)
   115  
   116  		resultFunc := func(userId string, rc *model.RemoteCluster, resp *Response, err error) {
   117  			assert.Equal(t, user.Id, userId, "user ids should match")
   118  			assert.NoError(t, err)
   119  			assert.True(t, resp.IsSuccess())
   120  		}
   121  
   122  		task := sendProfileImageTask{
   123  			rc:       rc,
   124  			userID:   user.Id,
   125  			provider: provider,
   126  			f:        resultFunc,
   127  		}
   128  
   129  		err := service.sendProfileImageToRemote(time.Second*15, task)
   130  		assert.NoError(t, err, "request should not error")
   131  	})
   132  
   133  	t.Run("Server response 500", func(t *testing.T) {
   134  		shouldError.set(true)
   135  
   136  		resultFunc := func(userId string, rc *model.RemoteCluster, resp *Response, err error) {
   137  			assert.Equal(t, user.Id, userId, "user ids should match")
   138  			assert.False(t, resp.IsSuccess())
   139  		}
   140  
   141  		task := sendProfileImageTask{
   142  			rc:       rc,
   143  			userID:   user.Id,
   144  			provider: provider,
   145  			f:        resultFunc,
   146  		}
   147  
   148  		err := service.sendProfileImageToRemote(time.Second*15, task)
   149  		assert.Error(t, err, "request should error")
   150  	})
   151  }
   152  
   153  type testImageProvider struct {
   154  }
   155  
   156  func (tip testImageProvider) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) {
   157  	img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{imageWidth, imageHeight}})
   158  	red := color.RGBA{255, 50, 50, 0xff}
   159  
   160  	for x := 0; x < imageWidth; x++ {
   161  		for y := 0; y < imageHeight; y++ {
   162  			img.Set(x, y, red)
   163  		}
   164  	}
   165  
   166  	buf := &bytes.Buffer{}
   167  	png.Encode(buf, img)
   168  
   169  	return buf.Bytes(), true, nil
   170  }
   171  
   172  type flag struct {
   173  	mux sync.RWMutex
   174  	b   bool
   175  }
   176  
   177  func (f *flag) get() bool {
   178  	f.mux.RLock()
   179  	defer f.mux.RUnlock()
   180  	return f.b
   181  }
   182  
   183  func (f *flag) set(b bool) {
   184  	f.mux.Lock()
   185  	defer f.mux.Unlock()
   186  	f.b = b
   187  }