- Priority 1: Test NewSendEmailTask + NewSendPushTask (5 tests) - Priority 2: Test customHTTPErrorHandler — all 15+ branches (21 tests) - Priority 3: Extract Enqueuer interface + payload builders in worker pkg (5 tests) - Priority 4: Extract ClassifyFile/ComputeRelPath in migrate-encrypt (6 tests) - Priority 5: Define Handler interfaces, refactor to accept them, mock-based tests (14 tests) - Fix .gitignore: /worker instead of worker to stop ignoring internal/worker/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
765 lines
30 KiB
Go
765 lines
30 KiB
Go
package services
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
|
"github.com/treytartt/honeydue-api/internal/models"
|
|
"github.com/treytartt/honeydue-api/internal/repositories"
|
|
"github.com/treytartt/honeydue-api/internal/testutil"
|
|
)
|
|
|
|
func setupDocumentService(t *testing.T) (*DocumentService, *repositories.DocumentRepository, *repositories.ResidenceRepository) {
|
|
db := testutil.SetupTestDB(t)
|
|
testutil.SeedLookupData(t, db)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
return service, documentRepo, residenceRepo
|
|
}
|
|
|
|
// === CreateDocument ===
|
|
|
|
func TestDocumentService_CreateDocument(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
req := &requests.CreateDocumentRequest{
|
|
ResidenceID: residence.ID,
|
|
Title: "Furnace Manual",
|
|
Description: "Installation manual for the furnace",
|
|
DocumentType: models.DocumentTypeManual,
|
|
FileURL: "https://example.com/manual.pdf",
|
|
FileName: "manual.pdf",
|
|
}
|
|
|
|
resp, err := service.CreateDocument(req, user.ID)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, resp)
|
|
assert.Equal(t, "Furnace Manual", resp.Title)
|
|
assert.Equal(t, models.DocumentTypeManual, resp.DocumentType)
|
|
}
|
|
|
|
func TestDocumentService_CreateDocument_DefaultType(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
req := &requests.CreateDocumentRequest{
|
|
ResidenceID: residence.ID,
|
|
Title: "Some Document",
|
|
// DocumentType not set — should default to "general"
|
|
}
|
|
|
|
resp, err := service.CreateDocument(req, user.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, models.DocumentTypeGeneral, resp.DocumentType)
|
|
}
|
|
|
|
func TestDocumentService_CreateDocument_WithImages(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
req := &requests.CreateDocumentRequest{
|
|
ResidenceID: residence.ID,
|
|
Title: "Receipt with photos",
|
|
ImageURLs: []string{"https://example.com/img1.jpg", "https://example.com/img2.jpg"},
|
|
}
|
|
|
|
resp, err := service.CreateDocument(req, user.ID)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, resp)
|
|
assert.Equal(t, "Receipt with photos", resp.Title)
|
|
}
|
|
|
|
func TestDocumentService_CreateDocument_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
|
|
req := &requests.CreateDocumentRequest{
|
|
ResidenceID: residence.ID,
|
|
Title: "Unauthorized Doc",
|
|
}
|
|
|
|
_, err := service.CreateDocument(req, other.ID)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.residence_access_denied")
|
|
}
|
|
|
|
// === GetDocument ===
|
|
|
|
func TestDocumentService_GetDocument(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Test Doc")
|
|
|
|
resp, err := service.GetDocument(doc.ID, user.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, doc.ID, resp.ID)
|
|
assert.Equal(t, "Test Doc", resp.Title)
|
|
}
|
|
|
|
func TestDocumentService_GetDocument_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
|
|
_, err := service.GetDocument(9999, user.ID)
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_not_found")
|
|
}
|
|
|
|
func TestDocumentService_GetDocument_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Private Doc")
|
|
|
|
_, err := service.GetDocument(doc.ID, other.ID)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.document_access_denied")
|
|
}
|
|
|
|
// === UpdateDocument ===
|
|
|
|
func TestDocumentService_UpdateDocument(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Original Title")
|
|
|
|
newTitle := "Updated Title"
|
|
newDesc := "Updated description"
|
|
req := &requests.UpdateDocumentRequest{
|
|
Title: &newTitle,
|
|
Description: &newDesc,
|
|
}
|
|
|
|
resp, err := service.UpdateDocument(doc.ID, user.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Updated Title", resp.Title)
|
|
assert.Equal(t, "Updated description", resp.Description)
|
|
}
|
|
|
|
func TestDocumentService_UpdateDocument_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
|
|
newTitle := "Won't Work"
|
|
req := &requests.UpdateDocumentRequest{Title: &newTitle}
|
|
|
|
_, err := service.UpdateDocument(9999, user.ID, req)
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_not_found")
|
|
}
|
|
|
|
func TestDocumentService_UpdateDocument_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Private Doc")
|
|
|
|
newTitle := "Hacked"
|
|
req := &requests.UpdateDocumentRequest{Title: &newTitle}
|
|
|
|
_, err := service.UpdateDocument(doc.ID, other.ID, req)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.document_access_denied")
|
|
}
|
|
|
|
func TestDocumentService_UpdateDocument_ChangeType(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "My Receipt")
|
|
|
|
newType := models.DocumentTypeWarranty
|
|
req := &requests.UpdateDocumentRequest{DocumentType: &newType}
|
|
|
|
resp, err := service.UpdateDocument(doc.ID, user.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, models.DocumentTypeWarranty, resp.DocumentType)
|
|
}
|
|
|
|
// === DeleteDocument ===
|
|
|
|
func TestDocumentService_DeleteDocument(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "To Delete")
|
|
|
|
err := service.DeleteDocument(doc.ID, user.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Should not be found after deletion
|
|
_, err = service.GetDocument(doc.ID, user.ID)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestDocumentService_DeleteDocument_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
|
|
err := service.DeleteDocument(9999, user.ID)
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_not_found")
|
|
}
|
|
|
|
func TestDocumentService_DeleteDocument_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Private Doc")
|
|
|
|
err := service.DeleteDocument(doc.ID, other.ID)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.document_access_denied")
|
|
}
|
|
|
|
// === ListDocuments ===
|
|
|
|
func TestDocumentService_ListDocuments(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Doc 1")
|
|
testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Doc 2")
|
|
|
|
resp, err := service.ListDocuments(user.ID, nil)
|
|
require.NoError(t, err)
|
|
assert.Len(t, resp, 2)
|
|
}
|
|
|
|
func TestDocumentService_ListDocuments_NoResidences(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "loner", "loner@test.com", "Password123")
|
|
|
|
resp, err := service.ListDocuments(user.ID, nil)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, resp)
|
|
}
|
|
|
|
func TestDocumentService_ListDocuments_FilterByResidence(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence1 := testutil.CreateTestResidence(t, db, user.ID, "House 1")
|
|
residence2 := testutil.CreateTestResidence(t, db, user.ID, "House 2")
|
|
testutil.CreateTestDocument(t, db, residence1.ID, user.ID, "Doc A")
|
|
testutil.CreateTestDocument(t, db, residence2.ID, user.ID, "Doc B")
|
|
|
|
filter := &repositories.DocumentFilter{ResidenceID: &residence1.ID}
|
|
resp, err := service.ListDocuments(user.ID, filter)
|
|
require.NoError(t, err)
|
|
assert.Len(t, resp, 1)
|
|
assert.Equal(t, "Doc A", resp[0].Title)
|
|
}
|
|
|
|
func TestDocumentService_ListDocuments_FilterByResidence_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Owner House")
|
|
// other has their own residence so they have at least one
|
|
testutil.CreateTestResidence(t, db, other.ID, "Other House")
|
|
|
|
filter := &repositories.DocumentFilter{ResidenceID: &residence.ID}
|
|
_, err := service.ListDocuments(other.ID, filter)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.residence_access_denied")
|
|
}
|
|
|
|
// === ListWarranties ===
|
|
|
|
func TestDocumentService_ListWarranties(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
// Create a warranty doc directly
|
|
warrantyDoc := &models.Document{
|
|
ResidenceID: residence.ID,
|
|
CreatedByID: user.ID,
|
|
Title: "HVAC Warranty",
|
|
DocumentType: "warranty",
|
|
FileURL: "https://example.com/warranty.pdf",
|
|
}
|
|
err := db.Create(warrantyDoc).Error
|
|
require.NoError(t, err)
|
|
|
|
// Create a general doc
|
|
testutil.CreateTestDocument(t, db, residence.ID, user.ID, "General Doc")
|
|
|
|
resp, err := service.ListWarranties(user.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, resp, 1)
|
|
assert.Equal(t, "HVAC Warranty", resp[0].Title)
|
|
}
|
|
|
|
func TestDocumentService_ListWarranties_NoResidences(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "loner", "loner@test.com", "Password123")
|
|
|
|
resp, err := service.ListWarranties(user.ID)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, resp)
|
|
}
|
|
|
|
// === DeactivateDocument ===
|
|
|
|
func TestDocumentService_DeactivateDocument(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "To Deactivate")
|
|
|
|
resp, err := service.DeactivateDocument(doc.ID, user.ID)
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.IsActive)
|
|
}
|
|
|
|
func TestDocumentService_DeactivateDocument_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
|
|
_, err := service.DeactivateDocument(9999, user.ID)
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_not_found")
|
|
}
|
|
|
|
func TestDocumentService_DeactivateDocument_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Private Doc")
|
|
|
|
_, err := service.DeactivateDocument(doc.ID, other.ID)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.document_access_denied")
|
|
}
|
|
|
|
// === UploadDocumentImage ===
|
|
|
|
func TestDocumentService_UploadDocumentImage(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Test Doc")
|
|
|
|
resp, err := service.UploadDocumentImage(doc.ID, user.ID, "https://example.com/photo.jpg", "Front view")
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, resp)
|
|
}
|
|
|
|
func TestDocumentService_UploadDocumentImage_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
|
|
_, err := service.UploadDocumentImage(9999, user.ID, "https://example.com/photo.jpg", "")
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_not_found")
|
|
}
|
|
|
|
func TestDocumentService_UploadDocumentImage_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Private Doc")
|
|
|
|
_, err := service.UploadDocumentImage(doc.ID, other.ID, "https://example.com/photo.jpg", "")
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.document_access_denied")
|
|
}
|
|
|
|
// === DeleteDocumentImage ===
|
|
|
|
func TestDocumentService_DeleteDocumentImage(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Test Doc")
|
|
|
|
// Create an image
|
|
img := &models.DocumentImage{
|
|
DocumentID: doc.ID,
|
|
ImageURL: "https://example.com/photo.jpg",
|
|
}
|
|
err := db.Create(img).Error
|
|
require.NoError(t, err)
|
|
|
|
resp, err := service.DeleteDocumentImage(doc.ID, img.ID, user.ID)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, resp)
|
|
}
|
|
|
|
func TestDocumentService_DeleteDocumentImage_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Test Doc")
|
|
|
|
_, err := service.DeleteDocumentImage(doc.ID, 9999, user.ID)
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_image_not_found")
|
|
}
|
|
|
|
func TestDocumentService_DeleteDocumentImage_WrongDocument(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc1 := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Doc 1")
|
|
doc2 := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Doc 2")
|
|
|
|
// Create an image on doc1
|
|
img := &models.DocumentImage{
|
|
DocumentID: doc1.ID,
|
|
ImageURL: "https://example.com/photo.jpg",
|
|
}
|
|
err := db.Create(img).Error
|
|
require.NoError(t, err)
|
|
|
|
// Try to delete the image specifying doc2
|
|
_, err = service.DeleteDocumentImage(doc2.ID, img.ID, user.ID)
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_image_not_found")
|
|
}
|
|
|
|
func TestDocumentService_DeleteDocumentImage_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Private Doc")
|
|
|
|
img := &models.DocumentImage{
|
|
DocumentID: doc.ID,
|
|
ImageURL: "https://example.com/photo.jpg",
|
|
}
|
|
err := db.Create(img).Error
|
|
require.NoError(t, err)
|
|
|
|
_, err = service.DeleteDocumentImage(doc.ID, img.ID, other.ID)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.document_access_denied")
|
|
}
|
|
|
|
// === SharedUser access ===
|
|
|
|
func TestDocumentService_GetDocument_SharedUserHasAccess(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
shared := testutil.CreateTestUser(t, db, "shared", "shared@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
residenceRepo.AddUser(residence.ID, shared.ID)
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Shared Doc")
|
|
|
|
resp, err := service.GetDocument(doc.ID, shared.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Shared Doc", resp.Title)
|
|
}
|
|
|
|
// === ActivateDocument ===
|
|
|
|
func TestDocumentService_ActivateDocument(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "To Activate")
|
|
|
|
// Deactivate first
|
|
_, err := service.DeactivateDocument(doc.ID, user.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Now activate
|
|
resp, err := service.ActivateDocument(doc.ID, user.ID)
|
|
require.NoError(t, err)
|
|
assert.True(t, resp.IsActive)
|
|
}
|
|
|
|
func TestDocumentService_ActivateDocument_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
|
|
_, err := service.ActivateDocument(9999, user.ID)
|
|
testutil.AssertAppError(t, err, http.StatusNotFound, "error.document_not_found")
|
|
}
|
|
|
|
func TestDocumentService_ActivateDocument_AccessDenied(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
other := testutil.CreateTestUser(t, db, "other", "other@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Private Doc")
|
|
|
|
_, err := service.ActivateDocument(doc.ID, other.ID)
|
|
testutil.AssertAppError(t, err, http.StatusForbidden, "error.document_access_denied")
|
|
}
|
|
|
|
// === CreateDocument — with empty image URL in array (should skip) ===
|
|
|
|
func TestDocumentService_CreateDocument_WithEmptyImageURL(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
req := &requests.CreateDocumentRequest{
|
|
ResidenceID: residence.ID,
|
|
Title: "Doc with empty images",
|
|
ImageURLs: []string{"", "https://example.com/img.jpg", ""},
|
|
}
|
|
|
|
resp, err := service.CreateDocument(req, user.ID)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, resp)
|
|
}
|
|
|
|
// === UpdateDocument — all optional fields ===
|
|
|
|
func TestDocumentService_UpdateDocument_AllFields(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, user.ID, "Original")
|
|
|
|
newTitle := "Updated"
|
|
newDesc := "New description"
|
|
newType := models.DocumentTypeWarranty
|
|
newFileURL := "https://example.com/new.pdf"
|
|
newFileName := "new.pdf"
|
|
newMimeType := "application/pdf"
|
|
newVendor := "HVAC Corp"
|
|
newSerial := "SN12345"
|
|
newModel := "Model X"
|
|
size := int64(1024)
|
|
|
|
req := &requests.UpdateDocumentRequest{
|
|
Title: &newTitle,
|
|
Description: &newDesc,
|
|
DocumentType: &newType,
|
|
FileURL: &newFileURL,
|
|
FileName: &newFileName,
|
|
FileSize: &size,
|
|
MimeType: &newMimeType,
|
|
Vendor: &newVendor,
|
|
SerialNumber: &newSerial,
|
|
ModelNumber: &newModel,
|
|
}
|
|
|
|
resp, err := service.UpdateDocument(doc.ID, user.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Updated", resp.Title)
|
|
assert.Equal(t, "New description", resp.Description)
|
|
assert.Equal(t, models.DocumentTypeWarranty, resp.DocumentType)
|
|
}
|
|
|
|
// === ListDocuments — filter by document type ===
|
|
|
|
func TestDocumentService_ListDocuments_FilterByType(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
// Create a warranty doc
|
|
warrantyDoc := &models.Document{
|
|
ResidenceID: residence.ID,
|
|
CreatedByID: user.ID,
|
|
Title: "Warranty Doc",
|
|
DocumentType: models.DocumentTypeWarranty,
|
|
FileURL: "https://example.com/w.pdf",
|
|
}
|
|
err := db.Create(warrantyDoc).Error
|
|
require.NoError(t, err)
|
|
|
|
// Create a general doc
|
|
testutil.CreateTestDocument(t, db, residence.ID, user.ID, "General Doc")
|
|
|
|
filter := &repositories.DocumentFilter{DocumentType: string(models.DocumentTypeWarranty)}
|
|
resp, err := service.ListDocuments(user.ID, filter)
|
|
require.NoError(t, err)
|
|
assert.Len(t, resp, 1)
|
|
assert.Equal(t, "Warranty Doc", resp[0].Title)
|
|
}
|
|
|
|
// === Shared user can update/delete documents ===
|
|
|
|
func TestDocumentService_SharedUser_CanUpdate(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
shared := testutil.CreateTestUser(t, db, "shared", "shared@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
residenceRepo.AddUser(residence.ID, shared.ID)
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Shared Doc")
|
|
|
|
newTitle := "Updated by shared user"
|
|
req := &requests.UpdateDocumentRequest{Title: &newTitle}
|
|
resp, err := service.UpdateDocument(doc.ID, shared.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Updated by shared user", resp.Title)
|
|
}
|
|
|
|
func TestDocumentService_SharedUser_CanDelete(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
documentRepo := repositories.NewDocumentRepository(db)
|
|
residenceRepo := repositories.NewResidenceRepository(db)
|
|
service := NewDocumentService(documentRepo, residenceRepo)
|
|
|
|
owner := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
|
shared := testutil.CreateTestUser(t, db, "shared", "shared@test.com", "Password123")
|
|
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
|
|
residenceRepo.AddUser(residence.ID, shared.ID)
|
|
doc := testutil.CreateTestDocument(t, db, residence.ID, owner.ID, "Shared Doc")
|
|
|
|
err := service.DeleteDocument(doc.ID, shared.ID)
|
|
require.NoError(t, err)
|
|
}
|