From b467f2ca61e46ee5937c657c35fa2641f4c0363f Mon Sep 17 00:00:00 2001
From: viktorstrate <viktorstrate@gmail.com>
Date: Sat, 6 Nov 2021 12:23:47 +0100
Subject: [PATCH] Add failing test for #198

---
 api/go.mod                        |  1 +
 api/go.sum                        |  6 +++
 api/graphql/resolvers/user.go     |  2 +-
 api/scanner/cleanup_media.go      |  2 +-
 api/scanner/cleanup_media_test.go | 81 +++++++++++++++++++++++++++++++
 api/scanner/scanner_test.go       | 12 +----
 api/scanner/scanner_user.go       |  2 +-
 api/test_utils/scanner_helpers.go | 36 ++++++++++++++
 8 files changed, 128 insertions(+), 14 deletions(-)
 create mode 100644 api/scanner/cleanup_media_test.go
 create mode 100644 api/test_utils/scanner_helpers.go

diff --git a/api/go.mod b/api/go.mod
index d433f0e..cbd64d2 100644
--- a/api/go.mod
+++ b/api/go.mod
@@ -19,6 +19,7 @@ require (
 	github.com/joho/godotenv v1.3.0
 	github.com/mattn/go-sqlite3 v1.14.6 // indirect
 	github.com/mitchellh/mapstructure v1.4.1 // indirect
+	github.com/otiai10/copy v1.6.0 // indirect
 	github.com/pkg/errors v0.9.1
 	github.com/sabhiram/go-gitignore v0.0.0-20201211210132-54b8a0bf510f
 	github.com/stretchr/objx v0.3.0 // indirect
diff --git a/api/go.sum b/api/go.sum
index 7331992..108be1c 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -437,6 +437,12 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
 github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
 github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI=
 github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ=
+github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E=
+github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
+github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
+github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
+github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
 github.com/pact-foundation/pact-go v1.0.4 h1:OYkFijGHoZAYbOIb1LWXrwKQbMMRUv1oQ89blD2Mh2Q=
 github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
diff --git a/api/graphql/resolvers/user.go b/api/graphql/resolvers/user.go
index 2c52d4e..24f222b 100644
--- a/api/graphql/resolvers/user.go
+++ b/api/graphql/resolvers/user.go
@@ -343,7 +343,7 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
 		}
 
 		// Reload faces as media might have been deleted
-		if face_detection.GlobalFaceDetector == nil {
+		if face_detection.GlobalFaceDetector != nil {
 			if err := face_detection.GlobalFaceDetector.ReloadFacesFromDatabase(r.Database); err != nil {
 				return nil, err
 			}
diff --git a/api/scanner/cleanup_media.go b/api/scanner/cleanup_media.go
index 9492672..de2250d 100644
--- a/api/scanner/cleanup_media.go
+++ b/api/scanner/cleanup_media.go
@@ -126,7 +126,7 @@ func deleteOldUserAlbums(db *gorm.DB, scannedAlbums []*models.Album, user *model
 	}
 
 	// Reload faces after deleting albums
-	if face_detection.GlobalFaceDetector == nil {
+	if face_detection.GlobalFaceDetector != nil {
 		if err := face_detection.GlobalFaceDetector.ReloadFacesFromDatabase(db); err != nil {
 			deleteErrors = append(deleteErrors, err)
 		}
diff --git a/api/scanner/cleanup_media_test.go b/api/scanner/cleanup_media_test.go
new file mode 100644
index 0000000..7df7b1e
--- /dev/null
+++ b/api/scanner/cleanup_media_test.go
@@ -0,0 +1,81 @@
+package scanner_test
+
+import (
+	"os"
+	"path"
+	"testing"
+
+	"github.com/otiai10/copy"
+	"github.com/photoview/photoview/api/graphql/models"
+	"github.com/photoview/photoview/api/test_utils"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestCleanupMedia(t *testing.T) {
+	test_utils.FilesystemTest(t)
+	db := test_utils.DatabaseTest(t)
+
+	test_dir := t.TempDir()
+	copy.Copy("./test_data", test_dir)
+
+	countAllMedia := func() int {
+		var all_media []*models.Media
+		if !assert.NoError(t, db.Find(&all_media).Error) {
+			return -1
+		}
+		return len(all_media)
+	}
+
+	countAllMediaURLs := func() int {
+		var all_media_urls []*models.MediaURL
+		if !assert.NoError(t, db.Find(&all_media_urls).Error) {
+			return -1
+		}
+		return len(all_media_urls)
+	}
+
+	pass := "1234"
+	user1, err := models.RegisterUser(db, "user1", &pass, true)
+	if !assert.NoError(t, err) {
+		return
+	}
+
+	user2, err := models.RegisterUser(db, "user2", &pass, true)
+	if !assert.NoError(t, err) {
+		return
+	}
+
+	root_album := models.Album{
+		Title: "root album",
+		Path:  test_dir,
+	}
+
+	if !assert.NoError(t, db.Save(&root_album).Error) {
+		return
+	}
+
+	err = db.Model(user1).Association("Albums").Append(&root_album)
+	if !assert.NoError(t, err) {
+		return
+	}
+	err = db.Model(user2).Association("Albums").Append(&root_album)
+	if !assert.NoError(t, err) {
+		return
+	}
+
+	test_utils.RunScannerOnUser(t, db, user1)
+	assert.Equal(t, 9, countAllMedia())
+	assert.Equal(t, 18, countAllMediaURLs())
+
+	// move faces directory
+	assert.NoError(t, os.Rename(path.Join(test_dir, "faces"), path.Join(test_dir, "faces_moved")))
+	test_utils.RunScannerAll(t, db)
+	assert.Equal(t, 9, countAllMedia())
+	assert.Equal(t, 18, countAllMediaURLs())
+
+	// remove faces_moved directory
+	assert.NoError(t, os.RemoveAll(path.Join(test_dir, "faces_moved")))
+	test_utils.RunScannerAll(t, db)
+	assert.Equal(t, 3, countAllMedia())
+	assert.Equal(t, 6, countAllMediaURLs())
+}
diff --git a/api/scanner/scanner_test.go b/api/scanner/scanner_test.go
index 4ccd45d..e4d66ec 100644
--- a/api/scanner/scanner_test.go
+++ b/api/scanner/scanner_test.go
@@ -6,7 +6,6 @@ import (
 	"time"
 
 	"github.com/photoview/photoview/api/graphql/models"
-	"github.com/photoview/photoview/api/scanner"
 	"github.com/photoview/photoview/api/scanner/face_detection"
 	"github.com/photoview/photoview/api/test_utils"
 	"github.com/stretchr/testify/assert"
@@ -40,20 +39,11 @@ func TestFullScan(t *testing.T) {
 		return
 	}
 
-	if !assert.NoError(t, scanner.InitializeScannerQueue(db)) {
-		return
-	}
-
 	if !assert.NoError(t, face_detection.InitializeFaceDetector(db)) {
 		return
 	}
 
-	if !assert.NoError(t, scanner.AddUserToQueue(user)) {
-		return
-	}
-
-	// wait for all jobs to finish
-	scanner.CloseScannerQueue()
+	test_utils.RunScannerOnUser(t, db, user)
 
 	var all_media []*models.Media
 	if !assert.NoError(t, db.Find(&all_media).Error) {
diff --git a/api/scanner/scanner_user.go b/api/scanner/scanner_user.go
index ab0d1e1..63be22a 100644
--- a/api/scanner/scanner_user.go
+++ b/api/scanner/scanner_user.go
@@ -23,7 +23,7 @@ func getPhotoviewIgnore(ignorePath string) ([]string, error) {
 	// Open .photoviewignore file, if exists
 	photoviewIgnoreFile, err := os.Open(path.Join(ignorePath, ".photoviewignore"))
 	if err != nil {
-		if err == os.ErrNotExist {
+		if os.IsNotExist(err) {
 			return photoviewIgnore, nil
 		}
 		return photoviewIgnore, err
diff --git a/api/test_utils/scanner_helpers.go b/api/test_utils/scanner_helpers.go
new file mode 100644
index 0000000..b143fc6
--- /dev/null
+++ b/api/test_utils/scanner_helpers.go
@@ -0,0 +1,36 @@
+package test_utils
+
+import (
+	"testing"
+
+	"github.com/photoview/photoview/api/graphql/models"
+	"github.com/photoview/photoview/api/scanner"
+	"github.com/stretchr/testify/assert"
+	"gorm.io/gorm"
+)
+
+func RunScannerOnUser(t *testing.T, db *gorm.DB, user *models.User) {
+	if !assert.NoError(t, scanner.InitializeScannerQueue(db)) {
+		return
+	}
+
+	if !assert.NoError(t, scanner.AddUserToQueue(user)) {
+		return
+	}
+
+	// wait for all jobs to finish
+	scanner.CloseScannerQueue()
+}
+
+func RunScannerAll(t *testing.T, db *gorm.DB) {
+	if !assert.NoError(t, scanner.InitializeScannerQueue(db)) {
+		return
+	}
+
+	if !assert.NoError(t, scanner.AddAllToQueue()) {
+		return
+	}
+
+	// wait for all jobs to finish
+	scanner.CloseScannerQueue()
+}
