github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/wopi/wopi_test.go (about)

     1  package wopi
     2  
     3  import (
     4  	"database/sql"
     5  	"errors"
     6  	"github.com/DATA-DOG/go-sqlmock"
     7  	model "github.com/cloudreve/Cloudreve/v3/models"
     8  	"github.com/cloudreve/Cloudreve/v3/pkg/cache"
     9  	"github.com/cloudreve/Cloudreve/v3/pkg/mocks/cachemock"
    10  	"github.com/cloudreve/Cloudreve/v3/pkg/mocks/requestmock"
    11  	"github.com/cloudreve/Cloudreve/v3/pkg/request"
    12  	"github.com/jinzhu/gorm"
    13  	"github.com/stretchr/testify/assert"
    14  	testMock "github.com/stretchr/testify/mock"
    15  	"net/url"
    16  	"testing"
    17  )
    18  
    19  var mock sqlmock.Sqlmock
    20  
    21  // TestMain 初始化数据库Mock
    22  func TestMain(m *testing.M) {
    23  	var db *sql.DB
    24  	var err error
    25  	db, mock, err = sqlmock.New()
    26  	if err != nil {
    27  		panic("An error was not expected when opening a stub database connection")
    28  	}
    29  	model.DB, _ = gorm.Open("mysql", db)
    30  	defer db.Close()
    31  	m.Run()
    32  }
    33  
    34  func TestNewSession(t *testing.T) {
    35  	a := assert.New(t)
    36  	endpoint, _ := url.Parse("http://localhost:8001/hosting/discovery")
    37  	client := &client{
    38  		cache: cache.NewMemoStore(),
    39  		config: config{
    40  			discoveryEndpoint: endpoint,
    41  		},
    42  	}
    43  
    44  	// Discovery failed
    45  	{
    46  		expectedErr := errors.New("error")
    47  		mockHttp := &requestmock.RequestMock{}
    48  		client.http = mockHttp
    49  		mockHttp.On(
    50  			"Request",
    51  			"GET",
    52  			endpoint.String(),
    53  			testMock.Anything,
    54  			testMock.Anything,
    55  		).Return(&request.Response{
    56  			Err: expectedErr,
    57  		})
    58  		res, err := client.NewSession(0, &model.File{}, ActionPreview)
    59  		a.Nil(res)
    60  		a.ErrorIs(err, expectedErr)
    61  		mockHttp.AssertExpectations(t)
    62  	}
    63  
    64  	// not supported ext
    65  	{
    66  		client.discovery = &WopiDiscovery{}
    67  		client.actions = make(map[string]map[string]Action)
    68  		res, err := client.NewSession(0, &model.File{}, ActionPreview)
    69  		a.Nil(res)
    70  		a.ErrorIs(err, ErrActionNotSupported)
    71  	}
    72  
    73  	// preferred action not supported
    74  	{
    75  		client.discovery = &WopiDiscovery{}
    76  		client.actions = map[string]map[string]Action{
    77  			".doc": {},
    78  		}
    79  		res, err := client.NewSession(0, &model.File{Name: "1.doc"}, ActionPreview)
    80  		a.Nil(res)
    81  		a.ErrorIs(err, ErrActionNotSupported)
    82  	}
    83  
    84  	// src url cannot be parsed
    85  	{
    86  		client.discovery = &WopiDiscovery{}
    87  		client.actions = map[string]map[string]Action{
    88  			".doc": {
    89  				string(ActionPreviewFallback): Action{
    90  					Urlsrc: string([]byte{0x7f}),
    91  				},
    92  			},
    93  		}
    94  		res, err := client.NewSession(0, &model.File{Name: "1.doc"}, ActionEdit)
    95  		a.Nil(res)
    96  		a.ErrorContains(err, "invalid control character in URL")
    97  	}
    98  
    99  	// all pass - default placeholder
   100  	{
   101  		client.discovery = &WopiDiscovery{}
   102  		client.actions = map[string]map[string]Action{
   103  			".doc": {
   104  				string(ActionPreviewFallback): Action{
   105  					Urlsrc: "https://doc.com/doc",
   106  				},
   107  			},
   108  		}
   109  		res, err := client.NewSession(0, &model.File{Name: "1.doc"}, ActionEdit)
   110  		a.NotNil(res)
   111  		a.NoError(err)
   112  		resUrl := res.ActionURL.String()
   113  		a.Contains(resUrl, wopiSrcParamDefault)
   114  	}
   115  
   116  	// all pass - with placeholders
   117  	{
   118  		client.discovery = &WopiDiscovery{}
   119  		client.actions = map[string]map[string]Action{
   120  			".doc": {
   121  				string(ActionPreviewFallback): Action{
   122  					Urlsrc: "https://doc.com/doc?origin=preserved&<dc=DC_LLCC&><notsuported=DISABLE_ASYNC&><src=WOPI_SOURCE&>",
   123  				},
   124  			},
   125  		}
   126  		res, err := client.NewSession(0, &model.File{Name: "1.doc"}, ActionEdit)
   127  		a.NotNil(res)
   128  		a.NoError(err)
   129  		resUrl := res.ActionURL.String()
   130  		a.Contains(resUrl, "origin=preserved")
   131  		a.Contains(resUrl, "dc=lng")
   132  		a.Contains(resUrl, "src=")
   133  		a.NotContains(resUrl, "notsuported")
   134  	}
   135  
   136  	// cache operation failed
   137  	{
   138  		mockCache := &cachemock.CacheClientMock{}
   139  		expectedErr := errors.New("error")
   140  		client.cache = mockCache
   141  		client.discovery = &WopiDiscovery{}
   142  		client.actions = map[string]map[string]Action{
   143  			".doc": {
   144  				string(ActionPreviewFallback): Action{
   145  					Urlsrc: "https://doc.com/doc",
   146  				},
   147  			},
   148  		}
   149  		mockCache.On("Set", testMock.Anything, testMock.Anything, testMock.Anything).Return(expectedErr)
   150  		res, err := client.NewSession(0, &model.File{Name: "1.doc"}, ActionEdit)
   151  		a.Nil(res)
   152  		a.ErrorIs(err, expectedErr)
   153  	}
   154  }
   155  
   156  func TestInit(t *testing.T) {
   157  	a := assert.New(t)
   158  
   159  	// not enabled
   160  	{
   161  		a.Nil(Default)
   162  		Default = &client{}
   163  		Init()
   164  		a.Nil(Default)
   165  	}
   166  
   167  	// throw error
   168  	{
   169  		a.Nil(Default)
   170  		cache.Set("setting_wopi_enabled", "1", 0)
   171  		cache.Set("setting_wopi_endpoint", string([]byte{0x7f}), 0)
   172  		Init()
   173  		a.Nil(Default)
   174  	}
   175  
   176  	// all pass
   177  	{
   178  		a.Nil(Default)
   179  		cache.Set("setting_wopi_enabled", "1", 0)
   180  		cache.Set("setting_wopi_endpoint", "", 0)
   181  		Init()
   182  		a.NotNil(Default)
   183  	}
   184  }