diff --git a/internal/resource/convert_test.go b/internal/resource/convert_test.go new file mode 100644 index 0000000..f52e518 --- /dev/null +++ b/internal/resource/convert_test.go @@ -0,0 +1,70 @@ +package resource_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/opdev/productctl/internal/resource" +) + +var _ = Describe("Convert", func() { + type FooOriginal struct { + IntKey int `json:"int_key"` + StringKey string `json:"string_key"` + } + + type FooLike struct { + MyInt int `json:"int_key"` + MyString string `json:"string_key"` + } + + When("converting between types through the JSONConvert roundtrip", func() { + When("like struct markers are used", func() { + var ( + original FooOriginal + similar FooLike + ) + + BeforeEach(func() { + original = FooOriginal{ + IntKey: 10, + StringKey: "ten", + } + + similar = FooLike{} + }) + + It("should round trip successfully", func() { + var err error + similar, err = resource.JSONConvert[FooLike](original) + Expect(err).ToNot(HaveOccurred()) + Expect(similar.MyInt).ToNot(BeZero()) + Expect(original.IntKey).To(Equal(similar.MyInt)) + Expect(similar.MyString).ToNot(BeEmpty()) + Expect(original.StringKey).To(Equal(similar.MyString)) + }) + }) + + When("unlike types are used", func() { + var in string + BeforeEach(func() { + in = "foo" + }) + It("should throw an error", func() { + var err error + _, err = resource.JSONConvert[struct{}](in) + Expect(err).To(HaveOccurred()) + }) + }) + When("the input type cannot be marshaled", func() { + var in func() + BeforeEach(func() { + in = func() {} + }) + It("should throw an error", func() { + _, err := resource.JSONConvert[string](in) + Expect(err).To(HaveOccurred()) + }) + }) + }) +}) diff --git a/internal/resource/io_test.go b/internal/resource/io_test.go new file mode 100644 index 0000000..ece59fd --- /dev/null +++ b/internal/resource/io_test.go @@ -0,0 +1,59 @@ +package resource_test + +import ( + "bytes" + "io" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/opdev/productctl/internal/resource" +) + +var _ = Describe("IO", func() { + When("provided a reader", func() { + var fixture io.Reader + When("it contains a product listing", func() { + BeforeEach(func() { + fixture = bytes.NewBufferString(`--- +kind: ProductListing +spec: + descriptions: + long: This can contain long form content about your product. + short: A brief synopsis + name: Test Product 1 + type: container stack +with: + components: + - certification_status: Started + container: + distribution_method: rhcc + hosted_registry: false + os_content_type: Red Hat Universal Base Image (UBI) + type: container + name: test-component + project_status: active + type: Containers`) + }) + + It("should marshal correctly", func() { + listing, err := resource.ReadProductListing(fixture) + Expect(err).ToNot(HaveOccurred()) + Expect(listing.Kind).To(Equal("ProductListing")) + Expect(listing.HasComponents()).To(BeTrue()) + Expect(listing.Spec.Name).To(Equal("Test Product 1")) + Expect(listing.With.Components[0].Name).To(Equal("test-component")) + }) + }) + + When("it does not contain a product listing", func() { + BeforeEach(func() { + fixture = bytes.NewBufferString("package resource") + }) + It("should not marshal correctly", func() { + _, err := resource.ReadProductListing(fixture) + Expect(err).To(HaveOccurred()) + }) + }) + }) +}) diff --git a/internal/resource/productlisting_test.go b/internal/resource/productlisting_test.go new file mode 100644 index 0000000..39e7c44 --- /dev/null +++ b/internal/resource/productlisting_test.go @@ -0,0 +1,37 @@ +package resource_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/opdev/productctl/internal/genpyxis" + "github.com/opdev/productctl/internal/resource" +) + +var _ = Describe("Productlisting", func() { + DescribeTable( + "when using boolean helper methods for product listing state", + func(actual, expected bool) { + Expect(actual).To(Equal(expected)) + }, + Entry("name is present", (&resource.ProductListing{Name: "foo"}).HasName(), true), + Entry("name is missing", (&resource.ProductListing{}).HasName(), false), + Entry("ID is present", (&resource.ProductListing{ID: "123"}).HasID(), true), + Entry("ID is missing", (&resource.ProductListing{}).HasID(), false), + ) + When("converting a ContactInfoProvider into a corresponding product listing contact list", func() { + var provider *genpyxis.ProductListingSupportedFieldsContactsContactsItems + BeforeEach(func() { + provider = &genpyxis.ProductListingSupportedFieldsContactsContactsItems{ + Email_address: "user@example.com", + Type: "testcontact", + } + }) + It("should map the Email Address and Type to the right places", func() { + contacts := resource.ContactsFrom([]*genpyxis.ProductListingSupportedFieldsContactsContactsItems{provider}) + Expect(contacts).To(HaveLen(1)) + Expect(contacts[0].EmailAddress).To(Equal(provider.GetEmail_address())) + Expect(contacts[0].Type).To(Equal(provider.GetType())) + }) + }) +}) diff --git a/internal/resource/resource.go b/internal/resource/resource.go index 1b0c4e0..7caf211 100644 --- a/internal/resource/resource.go +++ b/internal/resource/resource.go @@ -44,6 +44,7 @@ func (d *ProductListingDeclaration) Sanitize() { d.With.Components[i].ProjectStatus = "active" d.With.Components[i].CreationDate = nil d.With.Components[i].LastUpdateDate = nil + d.With.Components[i].CertificationDate = nil } } diff --git a/internal/resource/resource_suite_test.go b/internal/resource/resource_suite_test.go new file mode 100644 index 0000000..67535c5 --- /dev/null +++ b/internal/resource/resource_suite_test.go @@ -0,0 +1,13 @@ +package resource_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestResource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Resource Suite") +} diff --git a/internal/resource/resource_test.go b/internal/resource/resource_test.go new file mode 100644 index 0000000..26a057a --- /dev/null +++ b/internal/resource/resource_test.go @@ -0,0 +1,87 @@ +package resource_test + +import ( + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/opdev/productctl/internal/resource" +) + +var _ = Describe("Resource", func() { + When("working with product listing declarations", func() { + var declaration *resource.ProductListingDeclaration + + When("sanitizing the declaration", func() { + BeforeEach(func() { + new := resource.NewProductListing() + new.Spec = resource.ProductListing{ + ID: "abc123", + Name: "test-fixture", + OrgID: 1234, + LastUpdateDate: &time.Time{}, + Type: resource.ProductListingTypeContainerStack, + CreationDate: &time.Time{}, + } + new.With = resource.Inclusions{ + Components: []*resource.Component{ + { + ID: "c123", + CertificationDate: &time.Time{}, + Name: "cname", + OrgID: 1234, + ProjectStatus: "unset", + Type: resource.ComponentTypeContainer, + CreationDate: &time.Time{}, + LastUpdateDate: &time.Time{}, + }, + }, + } + + declaration = &new + }) + + JustBeforeEach(func() { + declaration.Sanitize() + }) + It("should unset created, update, etc. dates", func() { + Expect(declaration.Spec.LastUpdateDate).To(BeNil()) + Expect(declaration.Spec.CreationDate).To(BeNil()) + for _, c := range declaration.With.Components { + Expect(c.LastUpdateDate).To(BeNil()) + Expect(c.CertificationDate).To(BeNil()) + } + }) + It("should unset the top-level ID and all component IDs", func() { + Expect(declaration.Spec.ID).To(BeEmpty()) + Expect(declaration.Spec.OrgID).To(BeZero()) + for _, c := range declaration.With.Components { + Expect(c.ID).To(BeEmpty()) + Expect(c.OrgID).To(BeZero()) + } + }) + It("should reset the component statuses", func() { + for _, c := range declaration.With.Components { + Expect(c.ProjectStatus).To(Equal(resource.ProjectStatusActive)) + } + }) + It("should leave component information intact", func() { + Expect(declaration.Spec.Name).To(Equal("test-fixture")) + Expect(declaration.Spec.Type).To(Equal(resource.ProductListingTypeContainerStack)) + for _, c := range declaration.With.Components { + Expect(c.Name).To(Equal("cname")) + } + }) + }) + + When("the declaration has components", func() { + BeforeEach(func() { + declaration.With = resource.Inclusions{Components: []*resource.Component{{ID: "id"}}} + }) + It("should return a corresponding boolean from the helper function", func() { + Expect(declaration.HasComponents()).To(BeTrue()) + }) + }) + }) +})