- Duplicate part number constraint (PG 23505) - Hard delete, pagination, search filtering - Revision status/labels update, compare, rollback - Project-item association by code, list by project filter - Item file CRUD: create, list, get, delete
122 lines
3.0 KiB
Go
122 lines
3.0 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
)
|
|
|
|
func TestItemFileCreate(t *testing.T) {
|
|
database := mustConnectTestDB(t)
|
|
itemRepo := NewItemRepository(database)
|
|
fileRepo := NewItemFileRepository(database)
|
|
ctx := context.Background()
|
|
|
|
item := &Item{PartNumber: "FILE-001", ItemType: "part", Description: "file test"}
|
|
if err := itemRepo.Create(ctx, item, nil); err != nil {
|
|
t.Fatalf("Create item: %v", err)
|
|
}
|
|
|
|
f := &ItemFile{
|
|
ItemID: item.ID,
|
|
Filename: "drawing.pdf",
|
|
ContentType: "application/pdf",
|
|
Size: 12345,
|
|
ObjectKey: "items/FILE-001/files/abc/drawing.pdf",
|
|
}
|
|
if err := fileRepo.Create(ctx, f); err != nil {
|
|
t.Fatalf("Create file: %v", err)
|
|
}
|
|
if f.ID == "" {
|
|
t.Error("expected file ID to be set")
|
|
}
|
|
if f.CreatedAt.IsZero() {
|
|
t.Error("expected created_at to be set")
|
|
}
|
|
}
|
|
|
|
func TestItemFileListByItem(t *testing.T) {
|
|
database := mustConnectTestDB(t)
|
|
itemRepo := NewItemRepository(database)
|
|
fileRepo := NewItemFileRepository(database)
|
|
ctx := context.Background()
|
|
|
|
item := &Item{PartNumber: "FLIST-001", ItemType: "part", Description: "file list test"}
|
|
itemRepo.Create(ctx, item, nil)
|
|
|
|
for i, name := range []string{"a.pdf", "b.step"} {
|
|
fileRepo.Create(ctx, &ItemFile{
|
|
ItemID: item.ID,
|
|
Filename: name,
|
|
ContentType: "application/octet-stream",
|
|
Size: int64(i * 1000),
|
|
ObjectKey: "items/FLIST-001/files/" + name,
|
|
})
|
|
}
|
|
|
|
files, err := fileRepo.ListByItem(ctx, item.ID)
|
|
if err != nil {
|
|
t.Fatalf("ListByItem: %v", err)
|
|
}
|
|
if len(files) != 2 {
|
|
t.Errorf("expected 2 files, got %d", len(files))
|
|
}
|
|
}
|
|
|
|
func TestItemFileGet(t *testing.T) {
|
|
database := mustConnectTestDB(t)
|
|
itemRepo := NewItemRepository(database)
|
|
fileRepo := NewItemFileRepository(database)
|
|
ctx := context.Background()
|
|
|
|
item := &Item{PartNumber: "FGET-001", ItemType: "part", Description: "file get test"}
|
|
itemRepo.Create(ctx, item, nil)
|
|
|
|
f := &ItemFile{
|
|
ItemID: item.ID,
|
|
Filename: "model.FCStd",
|
|
ContentType: "application/x-freecad",
|
|
Size: 99999,
|
|
ObjectKey: "items/FGET-001/files/xyz/model.FCStd",
|
|
}
|
|
fileRepo.Create(ctx, f)
|
|
|
|
got, err := fileRepo.Get(ctx, f.ID)
|
|
if err != nil {
|
|
t.Fatalf("Get: %v", err)
|
|
}
|
|
if got.Filename != "model.FCStd" {
|
|
t.Errorf("filename: got %q, want %q", got.Filename, "model.FCStd")
|
|
}
|
|
if got.Size != 99999 {
|
|
t.Errorf("size: got %d, want %d", got.Size, 99999)
|
|
}
|
|
}
|
|
|
|
func TestItemFileDelete(t *testing.T) {
|
|
database := mustConnectTestDB(t)
|
|
itemRepo := NewItemRepository(database)
|
|
fileRepo := NewItemFileRepository(database)
|
|
ctx := context.Background()
|
|
|
|
item := &Item{PartNumber: "FDEL-001", ItemType: "part", Description: "file delete test"}
|
|
itemRepo.Create(ctx, item, nil)
|
|
|
|
f := &ItemFile{
|
|
ItemID: item.ID,
|
|
Filename: "temp.bin",
|
|
ContentType: "application/octet-stream",
|
|
Size: 100,
|
|
ObjectKey: "items/FDEL-001/files/tmp/temp.bin",
|
|
}
|
|
fileRepo.Create(ctx, f)
|
|
|
|
if err := fileRepo.Delete(ctx, f.ID); err != nil {
|
|
t.Fatalf("Delete: %v", err)
|
|
}
|
|
|
|
_, err := fileRepo.Get(ctx, f.ID)
|
|
if err == nil {
|
|
t.Error("expected error after delete, got nil")
|
|
}
|
|
}
|