Skip to content

Commit

Permalink
Surface assessment tags on Archetype resource
Browse files Browse the repository at this point in the history
Signed-off-by: Sam Lucidi <[email protected]>
  • Loading branch information
mansam committed Oct 3, 2023
1 parent 2c86e5f commit 9a2a94c
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 12 deletions.
34 changes: 30 additions & 4 deletions api/archetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,24 @@ func (h ArchetypeHandler) Get(ctx *gin.Context) {
return
}

resolver, err := assessment.NewQuestionnaireResolver(h.DB(ctx))
questionnaires, err := assessment.NewQuestionnaireResolver(h.DB(ctx))
if err != nil {
_ = ctx.Error(err)
return
}

tags, err := assessment.NewTagResolver(h.DB(ctx))
if err != nil {
_ = ctx.Error(err)
}

resolver := assessment.NewArchetypeResolver(m, tags)

r := Archetype{}
r.With(m)
r.WithApplications(applications)
r.Assessed = resolver.Assessed(m.Assessments)
r.WithAssessmentTags(resolver.AssessmentTags())
r.Assessed = questionnaires.Assessed(m.Assessments)
h.Respond(ctx, http.StatusOK, r)
}

Expand All @@ -93,11 +101,15 @@ func (h ArchetypeHandler) List(ctx *gin.Context) {
return
}

resolver, err := assessment.NewQuestionnaireResolver(h.DB(ctx))
questionnaires, err := assessment.NewQuestionnaireResolver(h.DB(ctx))
if err != nil {
_ = ctx.Error(err)
return
}
tags, err := assessment.NewTagResolver(h.DB(ctx))
if err != nil {
_ = ctx.Error(err)
}

membership := assessment.NewMembershipResolver(h.DB(ctx))
resources := []Archetype{}
Expand All @@ -109,9 +121,11 @@ func (h ArchetypeHandler) List(ctx *gin.Context) {
_ = ctx.Error(err)
return
}
resolver := assessment.NewArchetypeResolver(m, tags)
r.With(m)
r.WithApplications(applications)
r.Assessed = resolver.Assessed(m.Assessments)
r.WithAssessmentTags(resolver.AssessmentTags())
r.Assessed = questionnaires.Assessed(m.Assessments)
resources = append(resources, r)
}

Expand Down Expand Up @@ -331,6 +345,7 @@ type Archetype struct {
Comments string `json:"comments" yaml:"comments"`
Tags []Ref `json:"tags" yaml:"tags"`
CriteriaTags []Ref `json:"criteriaTags" yaml:"criteriaTags"`
AssessmentTags []Ref `json:"assessmentTags" yaml:"assessmentTags"`
Stakeholders []Ref `json:"stakeholders" yaml:"stakeholders"`
StakeholderGroups []Ref `json:"stakeholderGroups" yaml:"stakeholderGroups"`
Applications []Ref `json:"applications" yaml:"applications"`
Expand All @@ -346,6 +361,7 @@ func (r *Archetype) With(m *model.Archetype) {
r.Name = m.Name
r.Description = m.Description
r.Comments = m.Comments
r.AssessmentTags = []Ref{}
r.Tags = []Ref{}
for _, t := range m.Tags {
r.Tags = append(r.Tags, r.ref(t.ID, &t))
Expand Down Expand Up @@ -383,6 +399,16 @@ func (r *Archetype) WithApplications(apps []model.Application) {
}
}

//
// WithAssessmentTags updates the Archetype resource with tags inherited from assessments.
func (r *Archetype) WithAssessmentTags(tags []model.Tag) {
for _, t := range tags {
ref := Ref{}
ref.With(t.ID, t.Name)
r.AssessmentTags = append(r.AssessmentTags, ref)
}
}

//
// Model builds a model from the resource.
func (r *Archetype) Model() (m *model.Archetype) {
Expand Down
38 changes: 38 additions & 0 deletions assessment/archetype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package assessment

import "github.com/konveyor/tackle2-hub/model"

//
// NewArchetypeResolver creates a new ArchetypeResolver.
func NewArchetypeResolver(archetype *model.Archetype, tags *TagResolver) (a *ArchetypeResolver) {
a = &ArchetypeResolver{
archetype: archetype,
tagResolver: tags,
}
return
}

//
// ArchetypeResolver wraps an Archetype model
// with assessment-related functionality.
type ArchetypeResolver struct {
archetype *model.Archetype
tagResolver *TagResolver
}

//
// AssessmentTags returns the list of tags that the archetype should
// inherit from the answers given to its assessments.
func (r *ArchetypeResolver) AssessmentTags() (tags []model.Tag) {
seenTags := make(map[uint]bool)
for _, assessment := range r.archetype.Assessments {
aTags := r.tagResolver.Assessment(&assessment)
for _, t := range aTags {
if _, found := seenTags[t.ID]; !found {
seenTags[t.ID] = true
tags = append(tags, t)
}
}
}
return
}
4 changes: 2 additions & 2 deletions assessment/membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (r *MembershipResolver) Archetypes(m *model.Application) (archetypes []mode

matches := []model.Archetype{}
for _, a := range r.archetypes {
if appTags.Superset(r.tagSets[a.ID]) {
if appTags.Superset(r.tagSets[a.ID], false) {
matches = append(matches, a)
}
}
Expand All @@ -69,7 +69,7 @@ loop:
}
a1tags := r.tagSets[a1.ID]
a2tags := r.tagSets[a2.ID]
if a1tags.Subset(a2tags) {
if a1tags.Subset(a2tags, true) {
continue loop
}
}
Expand Down
2 changes: 1 addition & 1 deletion assessment/questionnaire.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ loop:
answered.Add(a.QuestionnaireID)
}
}
assessed = answered.Superset(r.requiredQuestionnaires)
assessed = answered.Superset(r.requiredQuestionnaires, false)

return
}
15 changes: 10 additions & 5 deletions assessment/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ func (r Set) Size() int {

//
// Add a member to the set.
func (r Set) Add(member uint) {
r.members[member] = true
func (r Set) Add(members ...uint) {
for _, member := range members {
r.members[member] = true
}
}

//
Expand All @@ -35,7 +37,10 @@ func (r Set) Contains(element uint) bool {

//
// Superset tests whether every element of other is in the set.
func (r Set) Superset(other Set) bool {
func (r Set) Superset(other Set, strict bool) bool {
if strict && r.Size() <= other.Size() {
return false
}
for m := range other.members {
if !r.Contains(m) {
return false
Expand All @@ -46,8 +51,8 @@ func (r Set) Superset(other Set) bool {

//
// Subset tests whether every element of this set is in the other.
func (r Set) Subset(other Set) bool {
return other.Superset(r)
func (r Set) Subset(other Set, strict bool) bool {
return other.Superset(r, strict)
}

//
Expand Down
46 changes: 46 additions & 0 deletions assessment/set_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package assessment

import (
"github.com/onsi/gomega"
"testing"
)

func TestSet_Superset(t *testing.T) {
g := gomega.NewGomegaWithT(t)

a := NewSet()
b := NewSet()
a.Add(1, 2, 3, 4)
b.Add(1, 2, 3, 4)

g.Expect(a.Superset(b, false)).To(gomega.BeTrue())
g.Expect(b.Superset(a, false)).To(gomega.BeTrue())
g.Expect(a.Superset(b, true)).To(gomega.BeFalse())
g.Expect(b.Superset(a, true)).To(gomega.BeFalse())

a.Add(5)
g.Expect(a.Superset(b, false)).To(gomega.BeTrue())
g.Expect(a.Superset(b, true)).To(gomega.BeTrue())
g.Expect(b.Superset(a, false)).To(gomega.BeFalse())
g.Expect(b.Superset(a, true)).To(gomega.BeFalse())
}

func TestSet_Subset(t *testing.T) {
g := gomega.NewGomegaWithT(t)

a := NewSet()
b := NewSet()
a.Add(1, 2, 3, 4)
b.Add(1, 2, 3, 4)

g.Expect(a.Subset(b, false)).To(gomega.BeTrue())
g.Expect(b.Subset(a, false)).To(gomega.BeTrue())
g.Expect(a.Subset(b, true)).To(gomega.BeFalse())
g.Expect(b.Subset(a, true)).To(gomega.BeFalse())

b.Add(5)
g.Expect(a.Subset(b, false)).To(gomega.BeTrue())
g.Expect(a.Subset(b, true)).To(gomega.BeTrue())
g.Expect(b.Subset(a, false)).To(gomega.BeFalse())
g.Expect(b.Subset(a, true)).To(gomega.BeFalse())
}

0 comments on commit 9a2a94c

Please sign in to comment.