Skip to content

Commit

Permalink
Add a table for compliance results
Browse files Browse the repository at this point in the history
This commit adds the basic schema we've outlined in
#84 (comment)
Future patches might include additional columns we need, depending on
how this is used.

Fixes #31
  • Loading branch information
rhmdnd committed Aug 5, 2022
1 parent 7d9500a commit a68f6e7
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 6 deletions.
1 change: 1 addition & 0 deletions migrations/000009_create_results_table.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS results;
15 changes: 15 additions & 0 deletions migrations/000009_create_results_table.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS results (
id uuid PRIMARY KEY,
name VARCHAR(255),
outcome VARCHAR(255),
instruction TEXT,
rationale TEXT,
control_id UUID,
metadata_id UUID,
subject_id UUID,
assessment_id UUID,
CONSTRAINT fk_results_control_id FOREIGN KEY (control_id) REFERENCES controls (id),
CONSTRAINT fk_results_metadata_id FOREIGN KEY (metadata_id) REFERENCES metadata (id),
CONSTRAINT fk_results_subject_id FOREIGN KEY (subject_id) REFERENCES subjects (id),
CONSTRAINT fk_results_assessment_id FOREIGN KEY (assessment_id) REFERENCES assessments (id)
);
128 changes: 123 additions & 5 deletions tests/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ func TestMigration(t *testing.T) { // nolint:paralleltest // database tests shou
// Upgrade the database and make sure all upgrades apply cleanly.
err = m.Up()
version, dirty, _ = m.Version()
expectedVersion = uint(8)
expectedVersion = uint(9)
assert.Equal(t, expectedVersion, version, "Database version mismatch: want %d but got %d", expectedVersion, version)
assert.Equal(t, false, dirty, "Database state mismatch: want %t but got %t", false, dirty)
assert.Equal(t, err, nil, "Error upgrading the database: %s", err)
Expand Down Expand Up @@ -456,30 +456,148 @@ func TestAssessmentMigration(t *testing.T) { // nolint:paralleltest // database
assert.False(t, result, "Table exist: %s", tableName)
}

func TestResultMigration(t *testing.T) { // nolint:paralleltest // database tests should run serially
m := getMigrationHelper(t)
gormDB := getGormHelper()
tableName := "results"

if err := m.Migrate(8); err != nil {
t.Fatalf("Unable to upgrade database: %s", err)
}

// Ensure the metadata table doesn't exist before the upgrade
result := gormDB.Migrator().HasTable(tableName)
assert.False(t, result, "Table exists prior to migration: %s", tableName)

// Ensure the table exists after running the migration
if err := m.Migrate(9); err != nil {
t.Fatalf("Unable to upgrade database: %s", err)
}

result = gormDB.Migrator().HasTable(tableName)
assert.True(t, result, "Table doesn't exist: %s", tableName)

// Check to make sure it has the expected columns
type results struct{}
columns := []string{
"id", "name", "outcome", "instruction",
"rationale", "control_id", "metadata_id", "subject_id",
"assessment_id",
}
for _, s := range columns {
result = gormDB.Migrator().HasColumn(&results{}, s)
assert.True(t, result, "Column doesn't exist: %s", s)
}

constraintName := "fk_results_control_id"
result = gormDB.Migrator().HasConstraint(&results{}, constraintName)
assert.True(t, result, "Table doesn't have constraint: %s", constraintName)

constraintName = "fk_results_metadata_id"
result = gormDB.Migrator().HasConstraint(&results{}, constraintName)
assert.True(t, result, "Table doesn't have constraint: %s", constraintName)

constraintName = "fk_results_subject_id"
result = gormDB.Migrator().HasConstraint(&results{}, constraintName)
assert.True(t, result, "Table doesn't have constraint: %s", constraintName)

constraintName = "fk_results_assessment_id"
result = gormDB.Migrator().HasConstraint(&results{}, constraintName)
assert.True(t, result, "Table doesn't have constraint: %s", constraintName)

// Ensure the table is removed on downgrade
if err := m.Migrate(8); err != nil {
t.Fatalf("Unable to upgrade database: %s", err)
}
result = gormDB.Migrator().HasTable(tableName)
assert.False(t, result, "Table exists after downgrade: %s", tableName)
}

func TestInsertAssessmentSucceeds(t *testing.T) { // nolint:paralleltest // database tests should run serially
m := getMigrationHelper(t)
gormDB := getGormHelper()

if err := m.Migrate(4); err != nil {
t.Fatalf("Unable to upgrade database: %s", err)
}

id := getUUIDString()
metadataID, err := insertMetadata()
if err != nil {
t.Fatalf("Unable to create metadata: %s", err)
}
name := getUUIDString()

assessment := Assessments{ID: id, Name: name, MetadataID: metadataID}
assessment := Assessment{ID: id, Name: name, MetadataID: metadataID}
err = gormDB.Create(&assessment).Error
assert.Nil(t, err)

a := Assessments{}
a := Assessment{}
gormDB.First(&a, "id = ?", id)

e := Assessment{ID: id, Name: name, MetadataID: metadataID}
assert.Equal(t, e.ID, a.ID, "expected %s got %s", e.ID, a.ID)
assert.Equal(t, e.Name, a.Name, "expected %s got %s", e.Name, a.Name)
assert.Equal(t, e.MetadataID, a.MetadataID, "expected %s got %s", e.MetadataID, a.MetadataID)
}

func TestInsertResultSucceeds(t *testing.T) { // nolint:paralleltest // database tests should run serially
m := getMigrationHelper(t)
gormDB := getGormHelper()

if err := m.Migrate(9); err != nil {
t.Fatalf("Unable to upgrade database: %s", err)
}

metadataID, err := insertMetadata()
if err != nil {
t.Fatalf("Unable to create necessary metadata: %s", err)
}
subjectID, err := insertSubject()
if err != nil {
t.Fatalf("Unable to create necessary subject: %s", err)
}
controlID, err := insertControl()
if err != nil {
t.Fatalf("Unable to create necessary control: %s", err)
}
assessmentID, err := insertAssessment()
if err != nil {
t.Fatalf("Unable to create necessary assessment: %s", err)
}

id := getUUIDString()
name := getUUIDString()
outcome := getUUIDString()
instruction := strings.Repeat(getUUIDString(), 100)
rationale := getUUIDString()

r := Result{
ID: id, Name: name, ControlID: controlID,
Outcome: outcome, Instruction: instruction,
Rationale: rationale, MetadataID: metadataID,
SubjectID: subjectID, AssessmentID: assessmentID,
}

err = gormDB.Create(&r).Error
assert.Nil(t, err)

a := Result{}
gormDB.First(&a, "id = ?", id)

e := Assessments{ID: id, Name: name, MetadataID: metadataID}
e := Result{
ID: id, Name: name, ControlID: controlID,
Outcome: outcome, Instruction: instruction,
Rationale: rationale, MetadataID: metadataID,
SubjectID: subjectID, AssessmentID: assessmentID,
}

assert.Equal(t, e.ID, a.ID, "expected %s got %s", e.ID, a.ID)
assert.Equal(t, e.Name, a.Name, "expected %s got %s", e.Name, a.Name)
assert.Equal(t, e.ControlID, a.ControlID, "expected %s got %s", e.ControlID, a.ControlID)
assert.Equal(t, e.Outcome, a.Outcome, "expected %s got %s", e.Outcome, a.Outcome)
assert.Equal(t, e.Instruction, a.Instruction, "expected %s got %s", e.Instruction, a.Instruction)
assert.Equal(t, e.Rationale, a.Rationale, "expected %s got %s", e.Rationale, a.Rationale)
assert.Equal(t, e.MetadataID, a.MetadataID, "expected %s got %s", e.MetadataID, a.MetadataID)
assert.Equal(t, e.SubjectID, a.SubjectID, "expected %s got %s", e.SubjectID, a.SubjectID)
assert.Equal(t, e.AssessmentID, a.AssessmentID, "expected %s got %s", e.AssessmentID, a.AssessmentID)
}
133 changes: 132 additions & 1 deletion tests/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,29 @@ import (
"gorm.io/gorm"
)

type Assessments struct {
type Catalog struct {
ID string
Name string
MetadataID string
Content string
}

type Profile struct {
ID string
Name string
MetadataID string
CatalogID string
}

type Control struct {
ID string
Name string
Severity string
ProfileID string
MetadataID string
}

type Assessment struct {
ID string
Name string
MetadataID string
Expand All @@ -37,6 +59,18 @@ type Subject struct {
MetadataID sql.NullString
}

type Result struct {
ID string
Name string
Outcome string
Instruction string
Rationale string
ControlID string
MetadataID string
SubjectID string
AssessmentID string
}

func getDatabaseConnection(t *testing.T) *sql.DB {
t.Helper()
// Generlize this so that it can be used to connect to any Postgres
Expand Down Expand Up @@ -127,3 +161,100 @@ func insertMetadata() (string, error) {

return id, nil
}

func insertSubject() (string, error) {
gormDB := getGormHelper()

id := getUUIDString()
name := getUUIDString()
subjectTypeStr := getUUIDString()

s := Subject{ID: id, Name: name, Type: subjectTypeStr}
if err := gormDB.Create(&s).Error; err != nil {
return "", err
}

return id, nil
}

func insertControl() (string, error) {
gormDB := getGormHelper()

id := getUUIDString()
name := getUUIDString()
metadataID, err := insertMetadata()
if err != nil {
return "", err
}
profileID, err := insertProfile()
if err != nil {
return "", err
}
severity := getUUIDString()

c := Control{ID: id, Name: name, Severity: severity, ProfileID: profileID, MetadataID: metadataID}
if err := gormDB.Create(&c).Error; err != nil {
return "", err
}

return id, nil
}

func insertProfile() (string, error) {
gormDB := getGormHelper()

id := getUUIDString()
name := getUUIDString()
metadataID, err := insertMetadata()
if err != nil {
return "", err
}
catalogID, err := insertCatalog()
if err != nil {
return "", err
}

p := Profile{ID: id, Name: name, MetadataID: metadataID, CatalogID: catalogID}
if err := gormDB.Create(&p).Error; err != nil {
return "", err
}

return id, nil
}

func insertCatalog() (string, error) {
gormDB := getGormHelper()

id := getUUIDString()
name := getUUIDString()
metadataID, err := insertMetadata()
if err != nil {
return "", err
}
content := getUUIDString()

c := Catalog{ID: id, Name: name, MetadataID: metadataID, Content: content}
if err := gormDB.Create(&c).Error; err != nil {
return "", err
}

return id, nil
}

func insertAssessment() (string, error) {
gormDB := getGormHelper()

id := getUUIDString()
name := getUUIDString()
metadataID, err := insertMetadata()
if err != nil {
return "", err
}

c := Assessment{ID: id, Name: name, MetadataID: metadataID}
if err := gormDB.Create(&c).Error; err != nil {
return "", err
}

return id, nil
}

0 comments on commit a68f6e7

Please sign in to comment.