github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/models/share_test.go (about)

     1  package model
     2  
     3  import (
     4  	"errors"
     5  	"net/http/httptest"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/DATA-DOG/go-sqlmock"
    10  	"github.com/cloudreve/Cloudreve/v3/pkg/cache"
    11  	"github.com/cloudreve/Cloudreve/v3/pkg/conf"
    12  	"github.com/gin-gonic/gin"
    13  	"github.com/jinzhu/gorm"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  func TestShare_Create(t *testing.T) {
    18  	asserts := assert.New(t)
    19  	share := Share{UserID: 1}
    20  
    21  	// 成功
    22  	{
    23  		mock.ExpectBegin()
    24  		mock.ExpectExec("INSERT(.+)").WillReturnResult(sqlmock.NewResult(2, 1))
    25  		mock.ExpectCommit()
    26  		id, err := share.Create()
    27  		asserts.NoError(mock.ExpectationsWereMet())
    28  		asserts.NoError(err)
    29  		asserts.EqualValues(2, id)
    30  	}
    31  
    32  	// 失败
    33  	{
    34  		mock.ExpectBegin()
    35  		mock.ExpectExec("INSERT(.+)").WillReturnError(errors.New("error"))
    36  		mock.ExpectRollback()
    37  		id, err := share.Create()
    38  		asserts.NoError(mock.ExpectationsWereMet())
    39  		asserts.Error(err)
    40  		asserts.EqualValues(0, id)
    41  	}
    42  }
    43  
    44  func TestGetShareByHashID(t *testing.T) {
    45  	asserts := assert.New(t)
    46  	conf.SystemConfig.HashIDSalt = ""
    47  
    48  	// 成功
    49  	{
    50  		mock.ExpectQuery("SELECT(.+)").
    51  			WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
    52  		res := GetShareByHashID("x9T4")
    53  		asserts.NoError(mock.ExpectationsWereMet())
    54  		asserts.NotNil(res)
    55  	}
    56  
    57  	// 查询失败
    58  	{
    59  		mock.ExpectQuery("SELECT(.+)").
    60  			WillReturnError(errors.New("error"))
    61  		res := GetShareByHashID("x9T4")
    62  		asserts.NoError(mock.ExpectationsWereMet())
    63  		asserts.Nil(res)
    64  	}
    65  
    66  	// ID解码失败
    67  	{
    68  		res := GetShareByHashID("empty")
    69  		asserts.Nil(res)
    70  	}
    71  
    72  }
    73  
    74  func TestShare_IsAvailable(t *testing.T) {
    75  	asserts := assert.New(t)
    76  
    77  	// 下载剩余次数为0
    78  	{
    79  		share := Share{}
    80  		asserts.False(share.IsAvailable())
    81  	}
    82  
    83  	// 时效过期
    84  	{
    85  		expires := time.Unix(10, 10)
    86  		share := Share{
    87  			RemainDownloads: -1,
    88  			Expires:         &expires,
    89  		}
    90  		asserts.False(share.IsAvailable())
    91  	}
    92  
    93  	// 源对象为目录,但不存在
    94  	{
    95  		share := Share{
    96  			RemainDownloads: -1,
    97  			SourceID:        2,
    98  			IsDir:           true,
    99  		}
   100  		mock.ExpectQuery("SELECT(.+)").
   101  			WillReturnRows(sqlmock.NewRows([]string{"id"}))
   102  		asserts.False(share.IsAvailable())
   103  		asserts.NoError(mock.ExpectationsWereMet())
   104  	}
   105  
   106  	// 源对象为目录,存在
   107  	{
   108  		share := Share{
   109  			RemainDownloads: -1,
   110  			SourceID:        2,
   111  			IsDir:           false,
   112  		}
   113  		mock.ExpectQuery("SELECT(.+)files(.+)").
   114  			WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(13))
   115  		asserts.True(share.IsAvailable())
   116  		asserts.NoError(mock.ExpectationsWereMet())
   117  	}
   118  
   119  	// 用户被封禁
   120  	{
   121  		share := Share{
   122  			RemainDownloads: -1,
   123  			SourceID:        2,
   124  			IsDir:           true,
   125  			User:            User{Status: Baned},
   126  		}
   127  		asserts.False(share.IsAvailable())
   128  	}
   129  }
   130  
   131  func TestShare_GetCreator(t *testing.T) {
   132  	asserts := assert.New(t)
   133  
   134  	mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
   135  	mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
   136  	share := Share{UserID: 1}
   137  	res := share.Creator()
   138  	asserts.NoError(mock.ExpectationsWereMet())
   139  	asserts.EqualValues(1, res.ID)
   140  }
   141  
   142  func TestShare_Source(t *testing.T) {
   143  	asserts := assert.New(t)
   144  
   145  	// 目录
   146  	{
   147  		share := Share{IsDir: true, SourceID: 3}
   148  		mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(3))
   149  		asserts.EqualValues(3, share.Source().(*Folder).ID)
   150  		asserts.NoError(mock.ExpectationsWereMet())
   151  	}
   152  
   153  	// 文件
   154  	{
   155  		share := Share{IsDir: false, SourceID: 3}
   156  		mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(3))
   157  		asserts.EqualValues(3, share.Source().(*File).ID)
   158  		asserts.NoError(mock.ExpectationsWereMet())
   159  	}
   160  }
   161  
   162  func TestShare_CanBeDownloadBy(t *testing.T) {
   163  	asserts := assert.New(t)
   164  	share := Share{}
   165  
   166  	// 未登录,无权
   167  	{
   168  		user := &User{
   169  			Group: Group{
   170  				OptionsSerialized: GroupOption{
   171  					ShareDownload: false,
   172  				},
   173  			},
   174  		}
   175  		asserts.Error(share.CanBeDownloadBy(user))
   176  	}
   177  
   178  	// 已登录,无权
   179  	{
   180  		user := &User{
   181  			Model: gorm.Model{ID: 1},
   182  			Group: Group{
   183  				OptionsSerialized: GroupOption{
   184  					ShareDownload: false,
   185  				},
   186  			},
   187  		}
   188  		asserts.Error(share.CanBeDownloadBy(user))
   189  	}
   190  
   191  	// 成功
   192  	{
   193  		user := &User{
   194  			Model: gorm.Model{ID: 1},
   195  			Group: Group{
   196  				OptionsSerialized: GroupOption{
   197  					ShareDownload: true,
   198  				},
   199  			},
   200  		}
   201  		asserts.NoError(share.CanBeDownloadBy(user))
   202  	}
   203  }
   204  
   205  func TestShare_WasDownloadedBy(t *testing.T) {
   206  	asserts := assert.New(t)
   207  	share := Share{
   208  		Model: gorm.Model{ID: 1},
   209  	}
   210  
   211  	// 已登录,已下载
   212  	{
   213  		user := User{
   214  			Model: gorm.Model{
   215  				ID: 1,
   216  			},
   217  		}
   218  		r := httptest.NewRecorder()
   219  		c, _ := gin.CreateTestContext(r)
   220  		cache.Set("share_1_1", true, 0)
   221  		asserts.True(share.WasDownloadedBy(&user, c))
   222  	}
   223  }
   224  
   225  func TestShare_DownloadBy(t *testing.T) {
   226  	asserts := assert.New(t)
   227  	share := Share{
   228  		Model: gorm.Model{ID: 1},
   229  	}
   230  	user := User{
   231  		Model: gorm.Model{
   232  			ID: 1,
   233  		},
   234  	}
   235  	cache.Deletes([]string{"1_1"}, "share_")
   236  	r := httptest.NewRecorder()
   237  	c, _ := gin.CreateTestContext(r)
   238  
   239  	mock.ExpectBegin()
   240  	mock.ExpectExec("UPDATE(.+)").WillReturnResult(sqlmock.NewResult(1, 1))
   241  	mock.ExpectCommit()
   242  
   243  	err := share.DownloadBy(&user, c)
   244  	asserts.NoError(mock.ExpectationsWereMet())
   245  	asserts.NoError(err)
   246  	_, ok := cache.Get("share_1_1")
   247  	asserts.True(ok)
   248  }
   249  
   250  func TestShare_Viewed(t *testing.T) {
   251  	asserts := assert.New(t)
   252  	share := Share{}
   253  	mock.ExpectBegin()
   254  	mock.ExpectExec("UPDATE(.+)").
   255  		WillReturnResult(sqlmock.NewResult(1, 1))
   256  	mock.ExpectCommit()
   257  	share.Viewed()
   258  	asserts.NoError(mock.ExpectationsWereMet())
   259  	asserts.EqualValues(1, share.Views)
   260  }
   261  
   262  func TestShare_UpdateAndDelete(t *testing.T) {
   263  	asserts := assert.New(t)
   264  	share := Share{}
   265  
   266  	{
   267  		mock.ExpectBegin()
   268  		mock.ExpectExec("UPDATE(.+)").
   269  			WillReturnResult(sqlmock.NewResult(1, 1))
   270  		mock.ExpectCommit()
   271  		err := share.Update(map[string]interface{}{"id": 1})
   272  		asserts.NoError(mock.ExpectationsWereMet())
   273  		asserts.NoError(err)
   274  	}
   275  
   276  	{
   277  		mock.ExpectBegin()
   278  		mock.ExpectExec("UPDATE(.+)").
   279  			WillReturnResult(sqlmock.NewResult(1, 1))
   280  		mock.ExpectCommit()
   281  		err := share.Delete()
   282  		asserts.NoError(mock.ExpectationsWereMet())
   283  		asserts.NoError(err)
   284  	}
   285  
   286  	{
   287  		mock.ExpectBegin()
   288  		mock.ExpectExec("UPDATE(.+)").
   289  			WillReturnResult(sqlmock.NewResult(1, 1))
   290  		mock.ExpectCommit()
   291  		err := DeleteShareBySourceIDs([]uint{1}, true)
   292  		asserts.NoError(mock.ExpectationsWereMet())
   293  		asserts.NoError(err)
   294  	}
   295  
   296  }
   297  
   298  func TestListShares(t *testing.T) {
   299  	asserts := assert.New(t)
   300  
   301  	mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(2).AddRow(2))
   302  	mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1).AddRow(2))
   303  
   304  	res, total := ListShares(1, 1, 10, "desc", true)
   305  	asserts.NoError(mock.ExpectationsWereMet())
   306  	asserts.Len(res, 2)
   307  	asserts.Equal(2, total)
   308  }
   309  
   310  func TestSearchShares(t *testing.T) {
   311  	asserts := assert.New(t)
   312  
   313  	mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
   314  	mock.ExpectQuery("SELECT(.+)").
   315  		WithArgs("", sqlmock.AnyArg(), "%1%2%").
   316  		WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
   317  	res, total := SearchShares(1, 10, "id", "1 2")
   318  	asserts.NoError(mock.ExpectationsWereMet())
   319  	asserts.Len(res, 1)
   320  	asserts.Equal(1, total)
   321  }