stash/pkg/sqlite/scene_test.go

1747 lines
44 KiB
Go

//go:build integration
// +build integration
package sqlite_test
import (
"database/sql"
"fmt"
"math"
"regexp"
"strconv"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stashapp/stash/pkg/hash/md5"
"github.com/stashapp/stash/pkg/models"
)
func TestSceneFind(t *testing.T) {
withTxn(func(r models.Repository) error {
// assume that the first scene is sceneWithGalleryPath
sqb := r.Scene()
const sceneIdx = 0
sceneID := sceneIDs[sceneIdx]
scene, err := sqb.Find(sceneID)
if err != nil {
t.Errorf("Error finding scene: %s", err.Error())
}
assert.Equal(t, getSceneStringValue(sceneIdx, "Path"), scene.Path)
sceneID = 0
scene, err = sqb.Find(sceneID)
if err != nil {
t.Errorf("Error finding scene: %s", err.Error())
}
assert.Nil(t, scene)
return nil
})
}
func TestSceneFindByPath(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
const sceneIdx = 1
scenePath := getSceneStringValue(sceneIdx, "Path")
scene, err := sqb.FindByPath(scenePath)
if err != nil {
t.Errorf("Error finding scene: %s", err.Error())
}
assert.Equal(t, sceneIDs[sceneIdx], scene.ID)
assert.Equal(t, scenePath, scene.Path)
scenePath = "not exist"
scene, err = sqb.FindByPath(scenePath)
if err != nil {
t.Errorf("Error finding scene: %s", err.Error())
}
assert.Nil(t, scene)
return nil
})
}
func TestSceneCountByPerformerID(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
count, err := sqb.CountByPerformerID(performerIDs[performerIdxWithScene])
if err != nil {
t.Errorf("Error counting scenes: %s", err.Error())
}
assert.Equal(t, 1, count)
count, err = sqb.CountByPerformerID(0)
if err != nil {
t.Errorf("Error counting scenes: %s", err.Error())
}
assert.Equal(t, 0, count)
return nil
})
}
func TestSceneWall(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
const sceneIdx = 2
wallQuery := getSceneStringValue(sceneIdx, "Details")
scenes, err := sqb.Wall(&wallQuery)
if err != nil {
t.Errorf("Error finding scenes: %s", err.Error())
}
assert.Len(t, scenes, 1)
scene := scenes[0]
assert.Equal(t, sceneIDs[sceneIdx], scene.ID)
assert.Equal(t, getSceneStringValue(sceneIdx, "Path"), scene.Path)
wallQuery = "not exist"
scenes, err = sqb.Wall(&wallQuery)
if err != nil {
t.Errorf("Error finding scene: %s", err.Error())
}
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneQueryQ(t *testing.T) {
const sceneIdx = 2
q := getSceneStringValue(sceneIdx, titleField)
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneQueryQ(t, sqb, q, sceneIdx)
return nil
})
}
func queryScene(t *testing.T, sqb models.SceneReader, sceneFilter *models.SceneFilterType, findFilter *models.FindFilterType) []*models.Scene {
t.Helper()
result, err := sqb.Query(models.SceneQueryOptions{
QueryOptions: models.QueryOptions{
FindFilter: findFilter,
},
SceneFilter: sceneFilter,
})
if err != nil {
t.Errorf("Error querying scene: %v", err)
}
scenes, err := result.Resolve()
if err != nil {
t.Errorf("Error resolving scenes: %v", err)
}
return scenes
}
func sceneQueryQ(t *testing.T, sqb models.SceneReader, q string, expectedSceneIdx int) {
filter := models.FindFilterType{
Q: &q,
}
scenes := queryScene(t, sqb, nil, &filter)
assert.Len(t, scenes, 1)
scene := scenes[0]
assert.Equal(t, sceneIDs[expectedSceneIdx], scene.ID)
// no Q should return all results
filter.Q = nil
scenes = queryScene(t, sqb, nil, &filter)
assert.Len(t, scenes, totalScenes)
}
func TestSceneQueryPath(t *testing.T) {
const sceneIdx = 1
scenePath := getSceneStringValue(sceneIdx, "Path")
pathCriterion := models.StringCriterionInput{
Value: scenePath,
Modifier: models.CriterionModifierEquals,
}
verifyScenesPath(t, pathCriterion)
pathCriterion.Modifier = models.CriterionModifierNotEquals
verifyScenesPath(t, pathCriterion)
pathCriterion.Modifier = models.CriterionModifierMatchesRegex
pathCriterion.Value = "scene_.*1_Path"
verifyScenesPath(t, pathCriterion)
pathCriterion.Modifier = models.CriterionModifierNotMatchesRegex
verifyScenesPath(t, pathCriterion)
}
func TestSceneQueryURL(t *testing.T) {
const sceneIdx = 1
scenePath := getSceneStringValue(sceneIdx, urlField)
urlCriterion := models.StringCriterionInput{
Value: scenePath,
Modifier: models.CriterionModifierEquals,
}
filter := models.SceneFilterType{
URL: &urlCriterion,
}
verifyFn := func(s *models.Scene) {
t.Helper()
verifyNullString(t, s.URL, urlCriterion)
}
verifySceneQuery(t, filter, verifyFn)
urlCriterion.Modifier = models.CriterionModifierNotEquals
verifySceneQuery(t, filter, verifyFn)
urlCriterion.Modifier = models.CriterionModifierMatchesRegex
urlCriterion.Value = "scene_.*1_URL"
verifySceneQuery(t, filter, verifyFn)
urlCriterion.Modifier = models.CriterionModifierNotMatchesRegex
verifySceneQuery(t, filter, verifyFn)
urlCriterion.Modifier = models.CriterionModifierIsNull
urlCriterion.Value = ""
verifySceneQuery(t, filter, verifyFn)
urlCriterion.Modifier = models.CriterionModifierNotNull
verifySceneQuery(t, filter, verifyFn)
}
func TestSceneQueryPathOr(t *testing.T) {
const scene1Idx = 1
const scene2Idx = 2
scene1Path := getSceneStringValue(scene1Idx, "Path")
scene2Path := getSceneStringValue(scene2Idx, "Path")
sceneFilter := models.SceneFilterType{
Path: &models.StringCriterionInput{
Value: scene1Path,
Modifier: models.CriterionModifierEquals,
},
Or: &models.SceneFilterType{
Path: &models.StringCriterionInput{
Value: scene2Path,
Modifier: models.CriterionModifierEquals,
},
},
}
withTxn(func(r models.Repository) error {
sqb := r.Scene()
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 2)
assert.Equal(t, scene1Path, scenes[0].Path)
assert.Equal(t, scene2Path, scenes[1].Path)
return nil
})
}
func TestSceneQueryPathAndRating(t *testing.T) {
const sceneIdx = 1
scenePath := getSceneStringValue(sceneIdx, "Path")
sceneRating := getRating(sceneIdx)
sceneFilter := models.SceneFilterType{
Path: &models.StringCriterionInput{
Value: scenePath,
Modifier: models.CriterionModifierEquals,
},
And: &models.SceneFilterType{
Rating: &models.IntCriterionInput{
Value: int(sceneRating.Int64),
Modifier: models.CriterionModifierEquals,
},
},
}
withTxn(func(r models.Repository) error {
sqb := r.Scene()
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
assert.Equal(t, scenePath, scenes[0].Path)
assert.Equal(t, sceneRating.Int64, scenes[0].Rating.Int64)
return nil
})
}
func TestSceneQueryPathNotRating(t *testing.T) {
const sceneIdx = 1
sceneRating := getRating(sceneIdx)
pathCriterion := models.StringCriterionInput{
Value: "scene_.*1_Path",
Modifier: models.CriterionModifierMatchesRegex,
}
ratingCriterion := models.IntCriterionInput{
Value: int(sceneRating.Int64),
Modifier: models.CriterionModifierEquals,
}
sceneFilter := models.SceneFilterType{
Path: &pathCriterion,
Not: &models.SceneFilterType{
Rating: &ratingCriterion,
},
}
withTxn(func(r models.Repository) error {
sqb := r.Scene()
scenes := queryScene(t, sqb, &sceneFilter, nil)
for _, scene := range scenes {
verifyString(t, scene.Path, pathCriterion)
ratingCriterion.Modifier = models.CriterionModifierNotEquals
verifyInt64(t, scene.Rating, ratingCriterion)
}
return nil
})
}
func TestSceneIllegalQuery(t *testing.T) {
assert := assert.New(t)
const sceneIdx = 1
subFilter := models.SceneFilterType{
Path: &models.StringCriterionInput{
Value: getSceneStringValue(sceneIdx, "Path"),
Modifier: models.CriterionModifierEquals,
},
}
sceneFilter := &models.SceneFilterType{
And: &subFilter,
Or: &subFilter,
}
withTxn(func(r models.Repository) error {
sqb := r.Scene()
queryOptions := models.SceneQueryOptions{
SceneFilter: sceneFilter,
}
_, err := sqb.Query(queryOptions)
assert.NotNil(err)
sceneFilter.Or = nil
sceneFilter.Not = &subFilter
_, err = sqb.Query(queryOptions)
assert.NotNil(err)
sceneFilter.And = nil
sceneFilter.Or = &subFilter
_, err = sqb.Query(queryOptions)
assert.NotNil(err)
return nil
})
}
func verifySceneQuery(t *testing.T, filter models.SceneFilterType, verifyFn func(s *models.Scene)) {
withTxn(func(r models.Repository) error {
t.Helper()
sqb := r.Scene()
scenes := queryScene(t, sqb, &filter, nil)
// assume it should find at least one
assert.Greater(t, len(scenes), 0)
for _, scene := range scenes {
verifyFn(scene)
}
return nil
})
}
func verifyScenesPath(t *testing.T, pathCriterion models.StringCriterionInput) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneFilter := models.SceneFilterType{
Path: &pathCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
for _, scene := range scenes {
verifyString(t, scene.Path, pathCriterion)
}
return nil
})
}
func verifyNullString(t *testing.T, value sql.NullString, criterion models.StringCriterionInput) {
t.Helper()
assert := assert.New(t)
if criterion.Modifier == models.CriterionModifierIsNull {
if value.Valid && value.String == "" {
// correct
return
}
assert.False(value.Valid, "expect is null values to be null")
}
if criterion.Modifier == models.CriterionModifierNotNull {
assert.True(value.Valid, "expect is null values to be null")
assert.Greater(len(value.String), 0)
}
if criterion.Modifier == models.CriterionModifierEquals {
assert.Equal(criterion.Value, value.String)
}
if criterion.Modifier == models.CriterionModifierNotEquals {
assert.NotEqual(criterion.Value, value.String)
}
if criterion.Modifier == models.CriterionModifierMatchesRegex {
assert.True(value.Valid)
assert.Regexp(regexp.MustCompile(criterion.Value), value)
}
if criterion.Modifier == models.CriterionModifierNotMatchesRegex {
if !value.Valid {
// correct
return
}
assert.NotRegexp(regexp.MustCompile(criterion.Value), value)
}
}
func verifyString(t *testing.T, value string, criterion models.StringCriterionInput) {
t.Helper()
assert := assert.New(t)
if criterion.Modifier == models.CriterionModifierEquals {
assert.Equal(criterion.Value, value)
}
if criterion.Modifier == models.CriterionModifierNotEquals {
assert.NotEqual(criterion.Value, value)
}
if criterion.Modifier == models.CriterionModifierMatchesRegex {
assert.Regexp(regexp.MustCompile(criterion.Value), value)
}
if criterion.Modifier == models.CriterionModifierNotMatchesRegex {
assert.NotRegexp(regexp.MustCompile(criterion.Value), value)
}
}
func TestSceneQueryRating(t *testing.T) {
const rating = 3
ratingCriterion := models.IntCriterionInput{
Value: rating,
Modifier: models.CriterionModifierEquals,
}
verifyScenesRating(t, ratingCriterion)
ratingCriterion.Modifier = models.CriterionModifierNotEquals
verifyScenesRating(t, ratingCriterion)
ratingCriterion.Modifier = models.CriterionModifierGreaterThan
verifyScenesRating(t, ratingCriterion)
ratingCriterion.Modifier = models.CriterionModifierLessThan
verifyScenesRating(t, ratingCriterion)
ratingCriterion.Modifier = models.CriterionModifierIsNull
verifyScenesRating(t, ratingCriterion)
ratingCriterion.Modifier = models.CriterionModifierNotNull
verifyScenesRating(t, ratingCriterion)
}
func verifyScenesRating(t *testing.T, ratingCriterion models.IntCriterionInput) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneFilter := models.SceneFilterType{
Rating: &ratingCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
for _, scene := range scenes {
verifyInt64(t, scene.Rating, ratingCriterion)
}
return nil
})
}
func verifyInt64(t *testing.T, value sql.NullInt64, criterion models.IntCriterionInput) {
t.Helper()
assert := assert.New(t)
if criterion.Modifier == models.CriterionModifierIsNull {
assert.False(value.Valid, "expect is null values to be null")
}
if criterion.Modifier == models.CriterionModifierNotNull {
assert.True(value.Valid, "expect is null values to be null")
}
if criterion.Modifier == models.CriterionModifierEquals {
assert.Equal(int64(criterion.Value), value.Int64)
}
if criterion.Modifier == models.CriterionModifierNotEquals {
assert.NotEqual(int64(criterion.Value), value.Int64)
}
if criterion.Modifier == models.CriterionModifierGreaterThan {
assert.True(value.Int64 > int64(criterion.Value))
}
if criterion.Modifier == models.CriterionModifierLessThan {
assert.True(value.Int64 < int64(criterion.Value))
}
}
func TestSceneQueryOCounter(t *testing.T) {
const oCounter = 1
oCounterCriterion := models.IntCriterionInput{
Value: oCounter,
Modifier: models.CriterionModifierEquals,
}
verifyScenesOCounter(t, oCounterCriterion)
oCounterCriterion.Modifier = models.CriterionModifierNotEquals
verifyScenesOCounter(t, oCounterCriterion)
oCounterCriterion.Modifier = models.CriterionModifierGreaterThan
verifyScenesOCounter(t, oCounterCriterion)
oCounterCriterion.Modifier = models.CriterionModifierLessThan
verifyScenesOCounter(t, oCounterCriterion)
}
func verifyScenesOCounter(t *testing.T, oCounterCriterion models.IntCriterionInput) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneFilter := models.SceneFilterType{
OCounter: &oCounterCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
for _, scene := range scenes {
verifyInt(t, scene.OCounter, oCounterCriterion)
}
return nil
})
}
func verifyInt(t *testing.T, value int, criterion models.IntCriterionInput) {
t.Helper()
assert := assert.New(t)
if criterion.Modifier == models.CriterionModifierEquals {
assert.Equal(criterion.Value, value)
}
if criterion.Modifier == models.CriterionModifierNotEquals {
assert.NotEqual(criterion.Value, value)
}
if criterion.Modifier == models.CriterionModifierGreaterThan {
assert.Greater(value, criterion.Value)
}
if criterion.Modifier == models.CriterionModifierLessThan {
assert.Less(value, criterion.Value)
}
}
func TestSceneQueryDuration(t *testing.T) {
duration := 200.432
durationCriterion := models.IntCriterionInput{
Value: int(duration),
Modifier: models.CriterionModifierEquals,
}
verifyScenesDuration(t, durationCriterion)
durationCriterion.Modifier = models.CriterionModifierNotEquals
verifyScenesDuration(t, durationCriterion)
durationCriterion.Modifier = models.CriterionModifierGreaterThan
verifyScenesDuration(t, durationCriterion)
durationCriterion.Modifier = models.CriterionModifierLessThan
verifyScenesDuration(t, durationCriterion)
durationCriterion.Modifier = models.CriterionModifierIsNull
verifyScenesDuration(t, durationCriterion)
durationCriterion.Modifier = models.CriterionModifierNotNull
verifyScenesDuration(t, durationCriterion)
}
func verifyScenesDuration(t *testing.T, durationCriterion models.IntCriterionInput) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneFilter := models.SceneFilterType{
Duration: &durationCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
for _, scene := range scenes {
if durationCriterion.Modifier == models.CriterionModifierEquals {
assert.True(t, scene.Duration.Float64 >= float64(durationCriterion.Value) && scene.Duration.Float64 < float64(durationCriterion.Value+1))
} else if durationCriterion.Modifier == models.CriterionModifierNotEquals {
assert.True(t, scene.Duration.Float64 < float64(durationCriterion.Value) || scene.Duration.Float64 >= float64(durationCriterion.Value+1))
} else {
verifyFloat64(t, scene.Duration, durationCriterion)
}
}
return nil
})
}
func verifyFloat64(t *testing.T, value sql.NullFloat64, criterion models.IntCriterionInput) {
assert := assert.New(t)
if criterion.Modifier == models.CriterionModifierIsNull {
assert.False(value.Valid, "expect is null values to be null")
}
if criterion.Modifier == models.CriterionModifierNotNull {
assert.True(value.Valid, "expect is null values to be null")
}
if criterion.Modifier == models.CriterionModifierEquals {
assert.Equal(float64(criterion.Value), value.Float64)
}
if criterion.Modifier == models.CriterionModifierNotEquals {
assert.NotEqual(float64(criterion.Value), value.Float64)
}
if criterion.Modifier == models.CriterionModifierGreaterThan {
assert.True(value.Float64 > float64(criterion.Value))
}
if criterion.Modifier == models.CriterionModifierLessThan {
assert.True(value.Float64 < float64(criterion.Value))
}
}
func TestSceneQueryResolution(t *testing.T) {
verifyScenesResolution(t, models.ResolutionEnumLow)
verifyScenesResolution(t, models.ResolutionEnumStandard)
verifyScenesResolution(t, models.ResolutionEnumStandardHd)
verifyScenesResolution(t, models.ResolutionEnumFullHd)
verifyScenesResolution(t, models.ResolutionEnumFourK)
verifyScenesResolution(t, models.ResolutionEnum("unknown"))
}
func verifyScenesResolution(t *testing.T, resolution models.ResolutionEnum) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneFilter := models.SceneFilterType{
Resolution: &models.ResolutionCriterionInput{
Value: resolution,
Modifier: models.CriterionModifierEquals,
},
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
for _, scene := range scenes {
verifySceneResolution(t, scene.Height, resolution)
}
return nil
})
}
func verifySceneResolution(t *testing.T, height sql.NullInt64, resolution models.ResolutionEnum) {
assert := assert.New(t)
h := height.Int64
switch resolution {
case models.ResolutionEnumLow:
assert.True(h < 480)
case models.ResolutionEnumStandard:
assert.True(h >= 480 && h < 720)
case models.ResolutionEnumStandardHd:
assert.True(h >= 720 && h < 1080)
case models.ResolutionEnumFullHd:
assert.True(h >= 1080 && h < 2160)
case models.ResolutionEnumFourK:
assert.True(h >= 2160)
}
}
func TestAllResolutionsHaveResolutionRange(t *testing.T) {
for _, resolution := range models.AllResolutionEnum {
assert.NotZero(t, resolution.GetMinResolution(), "Define resolution range for %s in extension_resolution.go", resolution)
assert.NotZero(t, resolution.GetMaxResolution(), "Define resolution range for %s in extension_resolution.go", resolution)
}
}
func TestSceneQueryResolutionModifiers(t *testing.T) {
if err := withRollbackTxn(func(r models.Repository) error {
qb := r.Scene()
sceneNoResolution, _ := createScene(qb, 0, 0)
firstScene540P, _ := createScene(qb, 960, 540)
secondScene540P, _ := createScene(qb, 1280, 719)
firstScene720P, _ := createScene(qb, 1280, 720)
secondScene720P, _ := createScene(qb, 1280, 721)
thirdScene720P, _ := createScene(qb, 1920, 1079)
scene1080P, _ := createScene(qb, 1920, 1080)
scenesEqualTo720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierEquals)
scenesNotEqualTo720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierNotEquals)
scenesGreaterThan720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierGreaterThan)
scenesLessThan720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierLessThan)
assert.Subset(t, scenesEqualTo720P, []*models.Scene{firstScene720P, secondScene720P, thirdScene720P})
assert.NotSubset(t, scenesEqualTo720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P, scene1080P})
assert.Subset(t, scenesNotEqualTo720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P, scene1080P})
assert.NotSubset(t, scenesNotEqualTo720P, []*models.Scene{firstScene720P, secondScene720P, thirdScene720P})
assert.Subset(t, scenesGreaterThan720P, []*models.Scene{scene1080P})
assert.NotSubset(t, scenesGreaterThan720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P, firstScene720P, secondScene720P, thirdScene720P})
assert.Subset(t, scenesLessThan720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P})
assert.NotSubset(t, scenesLessThan720P, []*models.Scene{scene1080P, firstScene720P, secondScene720P, thirdScene720P})
return nil
}); err != nil {
t.Error(err.Error())
}
}
func queryScenes(t *testing.T, queryBuilder models.SceneReaderWriter, resolution models.ResolutionEnum, modifier models.CriterionModifier) []*models.Scene {
sceneFilter := models.SceneFilterType{
Resolution: &models.ResolutionCriterionInput{
Value: resolution,
Modifier: modifier,
},
}
return queryScene(t, queryBuilder, &sceneFilter, nil)
}
func createScene(queryBuilder models.SceneReaderWriter, width int64, height int64) (*models.Scene, error) {
name := fmt.Sprintf("TestSceneQueryResolutionModifiers %d %d", width, height)
scene := models.Scene{
Path: name,
Width: sql.NullInt64{
Int64: width,
Valid: true,
},
Height: sql.NullInt64{
Int64: height,
Valid: true,
},
Checksum: sql.NullString{String: md5.FromString(name), Valid: true},
}
return queryBuilder.Create(scene)
}
func TestSceneQueryHasMarkers(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
hasMarkers := "true"
sceneFilter := models.SceneFilterType{
HasMarkers: &hasMarkers,
}
q := getSceneStringValue(sceneIdxWithMarkers, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes := queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdxWithMarkers], scenes[0].ID)
hasMarkers = "false"
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
findFilter.Q = nil
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.NotEqual(t, 0, len(scenes))
// ensure non of the ids equal the one with gallery
for _, scene := range scenes {
assert.NotEqual(t, sceneIDs[sceneIdxWithMarkers], scene.ID)
}
return nil
})
}
func TestSceneQueryIsMissingGallery(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
isMissing := "galleries"
sceneFilter := models.SceneFilterType{
IsMissing: &isMissing,
}
q := getSceneStringValue(sceneIdxWithGallery, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes := queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
findFilter.Q = nil
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
// ensure non of the ids equal the one with gallery
for _, scene := range scenes {
assert.NotEqual(t, sceneIDs[sceneIdxWithGallery], scene.ID)
}
return nil
})
}
func TestSceneQueryIsMissingStudio(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
isMissing := "studio"
sceneFilter := models.SceneFilterType{
IsMissing: &isMissing,
}
q := getSceneStringValue(sceneIdxWithStudio, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes := queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
findFilter.Q = nil
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
// ensure non of the ids equal the one with studio
for _, scene := range scenes {
assert.NotEqual(t, sceneIDs[sceneIdxWithStudio], scene.ID)
}
return nil
})
}
func TestSceneQueryIsMissingMovies(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
isMissing := "movie"
sceneFilter := models.SceneFilterType{
IsMissing: &isMissing,
}
q := getSceneStringValue(sceneIdxWithMovie, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes := queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
findFilter.Q = nil
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
// ensure non of the ids equal the one with movies
for _, scene := range scenes {
assert.NotEqual(t, sceneIDs[sceneIdxWithMovie], scene.ID)
}
return nil
})
}
func TestSceneQueryIsMissingPerformers(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
isMissing := "performers"
sceneFilter := models.SceneFilterType{
IsMissing: &isMissing,
}
q := getSceneStringValue(sceneIdxWithPerformer, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes := queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
findFilter.Q = nil
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.True(t, len(scenes) > 0)
// ensure non of the ids equal the one with movies
for _, scene := range scenes {
assert.NotEqual(t, sceneIDs[sceneIdxWithPerformer], scene.ID)
}
return nil
})
}
func TestSceneQueryIsMissingDate(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
isMissing := "date"
sceneFilter := models.SceneFilterType{
IsMissing: &isMissing,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
// three in four scenes have no date
assert.Len(t, scenes, int(math.Ceil(float64(totalScenes)/4*3)))
// ensure date is null, empty or "0001-01-01"
for _, scene := range scenes {
assert.True(t, !scene.Date.Valid || scene.Date.String == "" || scene.Date.String == "0001-01-01")
}
return nil
})
}
func TestSceneQueryIsMissingTags(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
isMissing := "tags"
sceneFilter := models.SceneFilterType{
IsMissing: &isMissing,
}
q := getSceneStringValue(sceneIdxWithTwoTags, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes := queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
findFilter.Q = nil
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.True(t, len(scenes) > 0)
return nil
})
}
func TestSceneQueryIsMissingRating(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
isMissing := "rating"
sceneFilter := models.SceneFilterType{
IsMissing: &isMissing,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.True(t, len(scenes) > 0)
// ensure date is null, empty or "0001-01-01"
for _, scene := range scenes {
assert.True(t, !scene.Rating.Valid)
}
return nil
})
}
func TestSceneQueryPerformers(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
performerCriterion := models.MultiCriterionInput{
Value: []string{
strconv.Itoa(performerIDs[performerIdxWithScene]),
strconv.Itoa(performerIDs[performerIdx1WithScene]),
},
Modifier: models.CriterionModifierIncludes,
}
sceneFilter := models.SceneFilterType{
Performers: &performerCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 2)
// ensure ids are correct
for _, scene := range scenes {
assert.True(t, scene.ID == sceneIDs[sceneIdxWithPerformer] || scene.ID == sceneIDs[sceneIdxWithTwoPerformers])
}
performerCriterion = models.MultiCriterionInput{
Value: []string{
strconv.Itoa(performerIDs[performerIdx1WithScene]),
strconv.Itoa(performerIDs[performerIdx2WithScene]),
},
Modifier: models.CriterionModifierIncludesAll,
}
scenes = queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdxWithTwoPerformers], scenes[0].ID)
performerCriterion = models.MultiCriterionInput{
Value: []string{
strconv.Itoa(performerIDs[performerIdx1WithScene]),
},
Modifier: models.CriterionModifierExcludes,
}
q := getSceneStringValue(sceneIdxWithTwoPerformers, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneQueryTags(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
tagCriterion := models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(tagIDs[tagIdxWithScene]),
strconv.Itoa(tagIDs[tagIdx1WithScene]),
},
Modifier: models.CriterionModifierIncludes,
}
sceneFilter := models.SceneFilterType{
Tags: &tagCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 2)
// ensure ids are correct
for _, scene := range scenes {
assert.True(t, scene.ID == sceneIDs[sceneIdxWithTag] || scene.ID == sceneIDs[sceneIdxWithTwoTags])
}
tagCriterion = models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(tagIDs[tagIdx1WithScene]),
strconv.Itoa(tagIDs[tagIdx2WithScene]),
},
Modifier: models.CriterionModifierIncludesAll,
}
scenes = queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdxWithTwoTags], scenes[0].ID)
tagCriterion = models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(tagIDs[tagIdx1WithScene]),
},
Modifier: models.CriterionModifierExcludes,
}
q := getSceneStringValue(sceneIdxWithTwoTags, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneQueryPerformerTags(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
tagCriterion := models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(tagIDs[tagIdxWithPerformer]),
strconv.Itoa(tagIDs[tagIdx1WithPerformer]),
},
Modifier: models.CriterionModifierIncludes,
}
sceneFilter := models.SceneFilterType{
PerformerTags: &tagCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 2)
// ensure ids are correct
for _, scene := range scenes {
assert.True(t, scene.ID == sceneIDs[sceneIdxWithPerformerTag] || scene.ID == sceneIDs[sceneIdxWithPerformerTwoTags])
}
tagCriterion = models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(tagIDs[tagIdx1WithPerformer]),
strconv.Itoa(tagIDs[tagIdx2WithPerformer]),
},
Modifier: models.CriterionModifierIncludesAll,
}
scenes = queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdxWithPerformerTwoTags], scenes[0].ID)
tagCriterion = models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(tagIDs[tagIdx1WithPerformer]),
},
Modifier: models.CriterionModifierExcludes,
}
q := getSceneStringValue(sceneIdxWithPerformerTwoTags, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
tagCriterion = models.HierarchicalMultiCriterionInput{
Modifier: models.CriterionModifierIsNull,
}
q = getSceneStringValue(sceneIdx1WithPerformer, titleField)
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdx1WithPerformer], scenes[0].ID)
q = getSceneStringValue(sceneIdxWithPerformerTag, titleField)
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
tagCriterion.Modifier = models.CriterionModifierNotNull
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdxWithPerformerTag], scenes[0].ID)
q = getSceneStringValue(sceneIdx1WithPerformer, titleField)
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneQueryStudio(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
studioCriterion := models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(studioIDs[studioIdxWithScene]),
},
Modifier: models.CriterionModifierIncludes,
}
sceneFilter := models.SceneFilterType{
Studios: &studioCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
// ensure id is correct
assert.Equal(t, sceneIDs[sceneIdxWithStudio], scenes[0].ID)
studioCriterion = models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(studioIDs[studioIdxWithScene]),
},
Modifier: models.CriterionModifierExcludes,
}
q := getSceneStringValue(sceneIdxWithStudio, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneQueryStudioDepth(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
depth := 2
studioCriterion := models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(studioIDs[studioIdxWithGrandChild]),
},
Modifier: models.CriterionModifierIncludes,
Depth: &depth,
}
sceneFilter := models.SceneFilterType{
Studios: &studioCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
depth = 1
scenes = queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 0)
studioCriterion.Value = []string{strconv.Itoa(studioIDs[studioIdxWithParentAndChild])}
scenes = queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
// ensure id is correct
assert.Equal(t, sceneIDs[sceneIdxWithGrandChildStudio], scenes[0].ID)
depth = 2
studioCriterion = models.HierarchicalMultiCriterionInput{
Value: []string{
strconv.Itoa(studioIDs[studioIdxWithGrandChild]),
},
Modifier: models.CriterionModifierExcludes,
Depth: &depth,
}
q := getSceneStringValue(sceneIdxWithGrandChildStudio, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
depth = 1
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 1)
studioCriterion.Value = []string{strconv.Itoa(studioIDs[studioIdxWithParentAndChild])}
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneQueryMovies(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
movieCriterion := models.MultiCriterionInput{
Value: []string{
strconv.Itoa(movieIDs[movieIdxWithScene]),
},
Modifier: models.CriterionModifierIncludes,
}
sceneFilter := models.SceneFilterType{
Movies: &movieCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Len(t, scenes, 1)
// ensure id is correct
assert.Equal(t, sceneIDs[sceneIdxWithMovie], scenes[0].ID)
movieCriterion = models.MultiCriterionInput{
Value: []string{
strconv.Itoa(movieIDs[movieIdxWithScene]),
},
Modifier: models.CriterionModifierExcludes,
}
q := getSceneStringValue(sceneIdxWithMovie, titleField)
findFilter := models.FindFilterType{
Q: &q,
}
scenes = queryScene(t, sqb, &sceneFilter, &findFilter)
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneQuerySorting(t *testing.T) {
sort := titleField
direction := models.SortDirectionEnumAsc
findFilter := models.FindFilterType{
Sort: &sort,
Direction: &direction,
}
withTxn(func(r models.Repository) error {
sqb := r.Scene()
scenes := queryScene(t, sqb, nil, &findFilter)
// scenes should be in same order as indexes
firstScene := scenes[0]
lastScene := scenes[len(scenes)-1]
assert.Equal(t, sceneIDs[0], firstScene.ID)
assert.Equal(t, sceneIDs[sceneIdxWithSpacedName], lastScene.ID)
// sort in descending order
direction = models.SortDirectionEnumDesc
scenes = queryScene(t, sqb, nil, &findFilter)
firstScene = scenes[0]
lastScene = scenes[len(scenes)-1]
assert.Equal(t, sceneIDs[sceneIdxWithSpacedName], firstScene.ID)
assert.Equal(t, sceneIDs[0], lastScene.ID)
return nil
})
}
func TestSceneQueryPagination(t *testing.T) {
perPage := 1
findFilter := models.FindFilterType{
PerPage: &perPage,
}
withTxn(func(r models.Repository) error {
sqb := r.Scene()
scenes := queryScene(t, sqb, nil, &findFilter)
assert.Len(t, scenes, 1)
firstID := scenes[0].ID
page := 2
findFilter.Page = &page
scenes = queryScene(t, sqb, nil, &findFilter)
assert.Len(t, scenes, 1)
secondID := scenes[0].ID
assert.NotEqual(t, firstID, secondID)
perPage = 2
page = 1
scenes = queryScene(t, sqb, nil, &findFilter)
assert.Len(t, scenes, 2)
assert.Equal(t, firstID, scenes[0].ID)
assert.Equal(t, secondID, scenes[1].ID)
return nil
})
}
func TestSceneQueryTagCount(t *testing.T) {
const tagCount = 1
tagCountCriterion := models.IntCriterionInput{
Value: tagCount,
Modifier: models.CriterionModifierEquals,
}
verifyScenesTagCount(t, tagCountCriterion)
tagCountCriterion.Modifier = models.CriterionModifierNotEquals
verifyScenesTagCount(t, tagCountCriterion)
tagCountCriterion.Modifier = models.CriterionModifierGreaterThan
verifyScenesTagCount(t, tagCountCriterion)
tagCountCriterion.Modifier = models.CriterionModifierLessThan
verifyScenesTagCount(t, tagCountCriterion)
}
func verifyScenesTagCount(t *testing.T, tagCountCriterion models.IntCriterionInput) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneFilter := models.SceneFilterType{
TagCount: &tagCountCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Greater(t, len(scenes), 0)
for _, scene := range scenes {
ids, err := sqb.GetTagIDs(scene.ID)
if err != nil {
return err
}
verifyInt(t, len(ids), tagCountCriterion)
}
return nil
})
}
func TestSceneQueryPerformerCount(t *testing.T) {
const performerCount = 1
performerCountCriterion := models.IntCriterionInput{
Value: performerCount,
Modifier: models.CriterionModifierEquals,
}
verifyScenesPerformerCount(t, performerCountCriterion)
performerCountCriterion.Modifier = models.CriterionModifierNotEquals
verifyScenesPerformerCount(t, performerCountCriterion)
performerCountCriterion.Modifier = models.CriterionModifierGreaterThan
verifyScenesPerformerCount(t, performerCountCriterion)
performerCountCriterion.Modifier = models.CriterionModifierLessThan
verifyScenesPerformerCount(t, performerCountCriterion)
}
func verifyScenesPerformerCount(t *testing.T, performerCountCriterion models.IntCriterionInput) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneFilter := models.SceneFilterType{
PerformerCount: &performerCountCriterion,
}
scenes := queryScene(t, sqb, &sceneFilter, nil)
assert.Greater(t, len(scenes), 0)
for _, scene := range scenes {
ids, err := sqb.GetPerformerIDs(scene.ID)
if err != nil {
return err
}
verifyInt(t, len(ids), performerCountCriterion)
}
return nil
})
}
func TestSceneCountByTagID(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneCount, err := sqb.CountByTagID(tagIDs[tagIdxWithScene])
if err != nil {
t.Errorf("error calling CountByTagID: %s", err.Error())
}
assert.Equal(t, 1, sceneCount)
sceneCount, err = sqb.CountByTagID(0)
if err != nil {
t.Errorf("error calling CountByTagID: %s", err.Error())
}
assert.Equal(t, 0, sceneCount)
return nil
})
}
func TestSceneCountByMovieID(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneCount, err := sqb.CountByMovieID(movieIDs[movieIdxWithScene])
if err != nil {
t.Errorf("error calling CountByMovieID: %s", err.Error())
}
assert.Equal(t, 1, sceneCount)
sceneCount, err = sqb.CountByMovieID(0)
if err != nil {
t.Errorf("error calling CountByMovieID: %s", err.Error())
}
assert.Equal(t, 0, sceneCount)
return nil
})
}
func TestSceneCountByStudioID(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
sceneCount, err := sqb.CountByStudioID(studioIDs[studioIdxWithScene])
if err != nil {
t.Errorf("error calling CountByStudioID: %s", err.Error())
}
assert.Equal(t, 1, sceneCount)
sceneCount, err = sqb.CountByStudioID(0)
if err != nil {
t.Errorf("error calling CountByStudioID: %s", err.Error())
}
assert.Equal(t, 0, sceneCount)
return nil
})
}
func TestFindByMovieID(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
scenes, err := sqb.FindByMovieID(movieIDs[movieIdxWithScene])
if err != nil {
t.Errorf("error calling FindByMovieID: %s", err.Error())
}
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdxWithMovie], scenes[0].ID)
scenes, err = sqb.FindByMovieID(0)
if err != nil {
t.Errorf("error calling FindByMovieID: %s", err.Error())
}
assert.Len(t, scenes, 0)
return nil
})
}
func TestFindByPerformerID(t *testing.T) {
withTxn(func(r models.Repository) error {
sqb := r.Scene()
scenes, err := sqb.FindByPerformerID(performerIDs[performerIdxWithScene])
if err != nil {
t.Errorf("error calling FindByPerformerID: %s", err.Error())
}
assert.Len(t, scenes, 1)
assert.Equal(t, sceneIDs[sceneIdxWithPerformer], scenes[0].ID)
scenes, err = sqb.FindByPerformerID(0)
if err != nil {
t.Errorf("error calling FindByPerformerID: %s", err.Error())
}
assert.Len(t, scenes, 0)
return nil
})
}
func TestSceneUpdateSceneCover(t *testing.T) {
if err := withTxn(func(r models.Repository) error {
qb := r.Scene()
// create performer to test against
const name = "TestSceneUpdateSceneCover"
scene := models.Scene{
Path: name,
Checksum: sql.NullString{String: md5.FromString(name), Valid: true},
}
created, err := qb.Create(scene)
if err != nil {
return fmt.Errorf("Error creating scene: %s", err.Error())
}
image := []byte("image")
err = qb.UpdateCover(created.ID, image)
if err != nil {
return fmt.Errorf("Error updating scene cover: %s", err.Error())
}
// ensure image set
storedImage, err := qb.GetCover(created.ID)
if err != nil {
return fmt.Errorf("Error getting image: %s", err.Error())
}
assert.Equal(t, storedImage, image)
// set nil image
err = qb.UpdateCover(created.ID, nil)
if err == nil {
return fmt.Errorf("Expected error setting nil image")
}
return nil
}); err != nil {
t.Error(err.Error())
}
}
func TestSceneDestroySceneCover(t *testing.T) {
if err := withTxn(func(r models.Repository) error {
qb := r.Scene()
// create performer to test against
const name = "TestSceneDestroySceneCover"
scene := models.Scene{
Path: name,
Checksum: sql.NullString{String: md5.FromString(name), Valid: true},
}
created, err := qb.Create(scene)
if err != nil {
return fmt.Errorf("Error creating scene: %s", err.Error())
}
image := []byte("image")
err = qb.UpdateCover(created.ID, image)
if err != nil {
return fmt.Errorf("Error updating scene image: %s", err.Error())
}
err = qb.DestroyCover(created.ID)
if err != nil {
return fmt.Errorf("Error destroying scene cover: %s", err.Error())
}
// image should be nil
storedImage, err := qb.GetCover(created.ID)
if err != nil {
return fmt.Errorf("Error getting image: %s", err.Error())
}
assert.Nil(t, storedImage)
return nil
}); err != nil {
t.Error(err.Error())
}
}
func TestSceneStashIDs(t *testing.T) {
if err := withTxn(func(r models.Repository) error {
qb := r.Scene()
// create scene to test against
const name = "TestSceneStashIDs"
scene := models.Scene{
Path: name,
Checksum: sql.NullString{String: md5.FromString(name), Valid: true},
}
created, err := qb.Create(scene)
if err != nil {
return fmt.Errorf("Error creating scene: %s", err.Error())
}
testStashIDReaderWriter(t, qb, created.ID)
return nil
}); err != nil {
t.Error(err.Error())
}
}
func TestSceneQueryQTrim(t *testing.T) {
if err := withTxn(func(r models.Repository) error {
qb := r.Scene()
expectedID := sceneIDs[sceneIdxWithSpacedName]
type test struct {
query string
id int
count int
}
tests := []test{
{query: " zzz yyy ", id: expectedID, count: 1},
{query: " \"zzz yyy xxx\" ", id: expectedID, count: 1},
{query: "zzz", id: expectedID, count: 1},
{query: "\" zzz yyy \"", count: 0},
{query: "\"zzz yyy\"", count: 0},
{query: "\" zzz yyy\"", count: 0},
{query: "\"zzz yyy \"", count: 0},
}
for _, tst := range tests {
f := models.FindFilterType{
Q: &tst.query,
}
scenes := queryScene(t, qb, nil, &f)
assert.Len(t, scenes, tst.count)
if len(scenes) > 0 {
assert.Equal(t, tst.id, scenes[0].ID)
}
}
findFilter := models.FindFilterType{}
scenes := queryScene(t, qb, nil, &findFilter)
assert.NotEqual(t, 0, len(scenes))
return nil
}); err != nil {
t.Error(err.Error())
}
}
// TODO Update
// TODO IncrementOCounter
// TODO DecrementOCounter
// TODO ResetOCounter
// TODO Destroy
// TODO FindByChecksum
// TODO Count
// TODO SizeCount
// TODO All