Skip to content

Commit

Permalink
Forgot document group review model
Browse files Browse the repository at this point in the history
  • Loading branch information
jfreda committed Mar 27, 2024
1 parent d76bc91 commit 740581f
Show file tree
Hide file tree
Showing 2 changed files with 386 additions and 0 deletions.
159 changes: 159 additions & 0 deletions pkg/models/document_group_review.go
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
}
227 changes: 227 additions & 0 deletions pkg/models/document_group_review_test.go
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)
})
})
}

0 comments on commit 740581f

Please sign in to comment.