-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
386 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
package models | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
validation "github.com/go-ozzo/ozzo-validation/v4" | ||
"gorm.io/gorm" | ||
"gorm.io/gorm/clause" | ||
) | ||
|
||
type DocumentGroupReview struct { | ||
CreatedAt time.Time | ||
UpdatedAt time.Time | ||
DeletedAt gorm.DeletedAt `gorm:"index"` | ||
|
||
DocumentID uint `gorm:"primaryKey"` | ||
Document Document | ||
GroupID uint `gorm:"primaryKey"` | ||
Group Group | ||
} | ||
|
||
// DocumentReviews is a slice of document reviews. | ||
type DocumentGroupReviews []DocumentGroupReview | ||
|
||
// BeforeSave is a hook to find or create associations before saving. | ||
func (d *DocumentGroupReview) BeforeSave(tx *gorm.DB) error { | ||
// Validate required fields. | ||
if err := validation.ValidateStruct(&d.Document, | ||
validation.Field( | ||
&d.Document.GoogleFileID, validation.Required), | ||
); err != nil { | ||
return err | ||
} | ||
if err := validation.ValidateStruct(&d.Group, | ||
validation.Field( | ||
&d.Group.EmailAddress, validation.Required), | ||
); err != nil { | ||
return err | ||
} | ||
|
||
if err := d.getAssociations(tx); err != nil { | ||
return fmt.Errorf("error getting associations: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Find finds all document group reviews with the provided query, and assigns | ||
// them to the receiver. | ||
func (d *DocumentGroupReviews) Find(db *gorm.DB, dr DocumentGroupReview) error { | ||
// Validate required fields. | ||
if err := validation.ValidateStruct(&dr.Document, | ||
validation.Field( | ||
&dr.Document.GoogleFileID, | ||
validation.When(dr.Group.EmailAddress == "", | ||
validation.Required.Error( | ||
"at least a Document's GoogleFileID or Group's EmailAddress is required"), | ||
), | ||
), | ||
); err != nil { | ||
return err | ||
} | ||
if err := validation.ValidateStruct(&dr.Group, | ||
validation.Field( | ||
&dr.Group.EmailAddress, | ||
validation.When(dr.Document.GoogleFileID == "", | ||
validation.Required.Error( | ||
"at least a Document's GoogleFileID or Group's EmailAddress is required"), | ||
), | ||
), | ||
); err != nil { | ||
return err | ||
} | ||
|
||
// Get document. | ||
if dr.Document.GoogleFileID != "" { | ||
if err := dr.Document.Get(db); err != nil { | ||
return fmt.Errorf("error getting document: %w", err) | ||
} | ||
dr.DocumentID = dr.Document.ID | ||
} | ||
|
||
// Get group. | ||
if dr.Group.EmailAddress != "" { | ||
if err := dr.Group.Get(db); err != nil { | ||
return fmt.Errorf("error getting group: %w", err) | ||
} | ||
dr.GroupID = dr.Group.ID | ||
} | ||
|
||
return db. | ||
Where(DocumentGroupReview{ | ||
DocumentID: dr.DocumentID, | ||
GroupID: dr.GroupID, | ||
}). | ||
Preload(clause.Associations). | ||
Find(&d). | ||
Error | ||
} | ||
|
||
// Get gets the document group review from database db, and assigns it to the | ||
// receiver. | ||
func (d *DocumentGroupReview) Get(db *gorm.DB) error { | ||
// Validate required fields. | ||
if err := validation.ValidateStruct(&d.Document, | ||
validation.Field(&d.Document.GoogleFileID, validation.Required), | ||
); err != nil { | ||
return err | ||
} | ||
if err := validation.ValidateStruct(&d.Group, | ||
validation.Field(&d.Group.EmailAddress, validation.Required), | ||
); err != nil { | ||
return err | ||
} | ||
|
||
if err := d.getAssociations(db); err != nil { | ||
return fmt.Errorf("error getting associations: %w", err) | ||
} | ||
|
||
return db. | ||
Where(DocumentGroupReview{ | ||
DocumentID: d.DocumentID, | ||
GroupID: d.GroupID, | ||
}). | ||
Preload(clause.Associations). | ||
First(&d). | ||
Error | ||
} | ||
|
||
// Update updates the document review in database db. | ||
func (d *DocumentGroupReview) Update(db *gorm.DB) error { | ||
if err := d.getAssociations(db); err != nil { | ||
return fmt.Errorf("error getting associations: %w", err) | ||
} | ||
|
||
return db. | ||
Model(&d). | ||
Omit(clause.Associations). | ||
Updates(*d). | ||
Error | ||
} | ||
|
||
// getAssociations gets associations. | ||
func (d *DocumentGroupReview) getAssociations(db *gorm.DB) error { | ||
// Get document. | ||
if err := d.Document.Get(db); err != nil { | ||
return fmt.Errorf("error getting document: %w", err) | ||
} | ||
d.DocumentID = d.Document.ID | ||
|
||
// Get group. | ||
if err := d.Group.Get(db); err != nil { | ||
return fmt.Errorf("error getting group: %w", err) | ||
} | ||
d.GroupID = d.Group.ID | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
package models | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestDocumentGroupReviewModel(t *testing.T) { | ||
dsn := os.Getenv("HERMES_TEST_POSTGRESQL_DSN") | ||
if dsn == "" { | ||
t.Skip("HERMES_TEST_POSTGRESQL_DSN environment variable isn't set") | ||
} | ||
|
||
t.Run("Create and Get", func(t *testing.T) { | ||
db, tearDownTest := setupTest(t, dsn) | ||
defer tearDownTest(t) | ||
|
||
t.Run("Create a document type", func(t *testing.T) { | ||
_, require := assert.New(t), require.New(t) | ||
dt := DocumentType{ | ||
Name: "DT1", | ||
LongName: "DocumentType1", | ||
} | ||
err := dt.FirstOrCreate(db) | ||
require.NoError(err) | ||
}) | ||
|
||
t.Run("Create a product", func(t *testing.T) { | ||
_, require := assert.New(t), require.New(t) | ||
p := Product{ | ||
Name: "Product1", | ||
Abbreviation: "P1", | ||
} | ||
err := p.FirstOrCreate(db) | ||
require.NoError(err) | ||
}) | ||
|
||
t.Run("Get the review before we create the document", func(t *testing.T) { | ||
_, require := assert.New(t), require.New(t) | ||
dr := DocumentGroupReview{ | ||
Document: Document{ | ||
GoogleFileID: "fileID1", | ||
}, | ||
Group: Group{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
} | ||
err := dr.Get(db) | ||
require.Error(err) | ||
}) | ||
|
||
var d Document | ||
t.Run("Create a document", func(t *testing.T) { | ||
assert, require := assert.New(t), require.New(t) | ||
d = Document{ | ||
GoogleFileID: "fileID1", | ||
ApproverGroups: []*Group{ | ||
{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
}, | ||
DocumentType: DocumentType{ | ||
Name: "DT1", | ||
}, | ||
Product: Product{ | ||
Name: "Product1", | ||
}, | ||
} | ||
err := d.Create(db) | ||
require.NoError(err) | ||
assert.EqualValues(1, d.ID) | ||
}) | ||
|
||
t.Run("Get the review", func(t *testing.T) { | ||
assert, require := assert.New(t), require.New(t) | ||
dr := DocumentGroupReview{ | ||
Document: Document{ | ||
GoogleFileID: "fileID1", | ||
}, | ||
Group: Group{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
} | ||
err := dr.Get(db) | ||
require.NoError(err) | ||
assert.EqualValues(1, dr.DocumentID) | ||
assert.Equal("fileID1", dr.Document.GoogleFileID) | ||
assert.EqualValues(2, dr.GroupID) | ||
assert.Equal("[email protected]", dr.Group.EmailAddress) | ||
}) | ||
}) | ||
|
||
t.Run("Find", func(t *testing.T) { | ||
db, tearDownTest := setupTest(t, dsn) | ||
defer tearDownTest(t) | ||
|
||
t.Run("Create a document type", func(t *testing.T) { | ||
_, require := assert.New(t), require.New(t) | ||
dt := DocumentType{ | ||
Name: "DT1", | ||
LongName: "DocumentType1", | ||
} | ||
err := dt.FirstOrCreate(db) | ||
require.NoError(err) | ||
}) | ||
|
||
t.Run("Create a product", func(t *testing.T) { | ||
_, require := assert.New(t), require.New(t) | ||
p := Product{ | ||
Name: "Product1", | ||
Abbreviation: "P1", | ||
} | ||
err := p.FirstOrCreate(db) | ||
require.NoError(err) | ||
}) | ||
|
||
var d1, d2, d3 Document | ||
t.Run("Create first document", func(t *testing.T) { | ||
assert, require := assert.New(t), require.New(t) | ||
d1 = Document{ | ||
GoogleFileID: "fileID1", | ||
ApproverGroups: []*Group{ | ||
{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
}, | ||
DocumentType: DocumentType{ | ||
Name: "DT1", | ||
}, | ||
Product: Product{ | ||
Name: "Product1", | ||
}, | ||
} | ||
err := d1.Create(db) | ||
require.NoError(err) | ||
assert.EqualValues(1, d1.ID) | ||
}) | ||
|
||
t.Run("Create second document", func(t *testing.T) { | ||
assert, require := assert.New(t), require.New(t) | ||
d2 = Document{ | ||
GoogleFileID: "fileID2", | ||
ApproverGroups: []*Group{ | ||
{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
}, | ||
DocumentType: DocumentType{ | ||
Name: "DT1", | ||
}, | ||
Product: Product{ | ||
Name: "Product1", | ||
}, | ||
} | ||
err := d2.Create(db) | ||
require.NoError(err) | ||
assert.EqualValues(2, d2.ID) | ||
}) | ||
|
||
t.Run("Create third document", func(t *testing.T) { | ||
assert, require := assert.New(t), require.New(t) | ||
d3 = Document{ | ||
GoogleFileID: "fileID3", | ||
ApproverGroups: []*Group{ | ||
{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
}, | ||
DocumentType: DocumentType{ | ||
Name: "DT1", | ||
}, | ||
Product: Product{ | ||
Name: "Product1", | ||
}, | ||
} | ||
err := d3.Create(db) | ||
require.NoError(err) | ||
assert.EqualValues(3, d3.ID) | ||
}) | ||
|
||
t.Run("Find reviews without any search fields", func(t *testing.T) { | ||
_, require := assert.New(t), require.New(t) | ||
var revs DocumentGroupReviews | ||
err := revs.Find(db, DocumentGroupReview{}) | ||
require.Error(err) | ||
}) | ||
|
||
t.Run("Find all reviews for a document", func(t *testing.T) { | ||
assert, require := assert.New(t), require.New(t) | ||
var revs DocumentGroupReviews | ||
err := revs.Find(db, DocumentGroupReview{ | ||
Document: Document{ | ||
GoogleFileID: "fileID1", | ||
}, | ||
}) | ||
require.NoError(err) | ||
require.Len(revs, 2) | ||
assert.Equal("[email protected]", revs[0].Group.EmailAddress) | ||
assert.Equal("[email protected]", revs[1].Group.EmailAddress) | ||
}) | ||
|
||
t.Run("Find all reviews for a group", func(t *testing.T) { | ||
assert, require := assert.New(t), require.New(t) | ||
var revs DocumentGroupReviews | ||
err := revs.Find(db, DocumentGroupReview{ | ||
Group: Group{ | ||
EmailAddress: "[email protected]", | ||
}, | ||
}) | ||
require.NoError(err) | ||
require.Len(revs, 2) | ||
assert.Equal("fileID1", revs[0].Document.GoogleFileID) | ||
assert.Equal("fileID3", revs[1].Document.GoogleFileID) | ||
assert.Equal("[email protected]", revs[0].Group.EmailAddress) | ||
assert.Equal("[email protected]", revs[1].Group.EmailAddress) | ||
}) | ||
}) | ||
} |