Skip to content

Commit

Permalink
🐛 fix: Enhance the webhook test template
Browse files Browse the repository at this point in the history
The webhook scaffold had some oddly indented regions, resulting in the
generated source code having a mix of tabs and spaces, and was generally
looking quite ugly.

The gomega asserions are too chatty; errors, and return values are
checked after first being assigned as variables in scope. This is not
needed, and Gomega checks all of this for us:

Expect(someFunc()).Error().To(HaveOccurred()) checks both the error, but also that the other return values are zero or nil.
Expect(someFunc()).To(ContainSubstring("X")) checks both the return value and verifies that the error is nil.

Fixes #4148

- Indentation
- simplify gomega assertions
  • Loading branch information
mogsie committed Sep 9, 2024
1 parent 571a948 commit d2fdc73
Show file tree
Hide file tree
Showing 19 changed files with 177 additions and 277 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,32 +104,28 @@ var _ = Describe("CronJob Webhook", func() {
Context("When creating or updating CronJob under Validating Webhook", func() {
It("Should deny creation if the name is too long", func() {
obj.ObjectMeta.Name = "this-name-is-way-too-long-and-should-fail-validation-because-it-is-way-too-long"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).To(HaveOccurred(), "Expected name validation to fail for a too-long name")
Expect(warnings).To(BeNil())
Expect(err.Error()).To(ContainSubstring("must be no more than 52 characters"))
Expect(validator.ValidateCreate(ctx, obj)).Error().To(
MatchError(ContainSubstring("must be no more than 52 characters")),
"Expected name validation to fail for a too-long name")
})

It("Should admit creation if the name is valid", func() {
obj.ObjectMeta.Name = "valid-cronjob-name"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).NotTo(HaveOccurred(), "Expected name validation to pass for a valid name")
Expect(warnings).To(BeNil())
Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(),
"Expected name validation to pass for a valid name")
})

It("Should deny creation if the schedule is invalid", func() {
obj.Spec.Schedule = "invalid-cron-schedule"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).To(HaveOccurred(), "Expected spec validation to fail for an invalid schedule")
Expect(warnings).To(BeNil())
Expect(err.Error()).To(ContainSubstring("Expected exactly 5 fields, found 1: invalid-cron-schedule"))
Expect(validator.ValidateCreate(ctx, obj)).Error().To(
MatchError(ContainSubstring("Expected exactly 5 fields, found 1: invalid-cron-schedule")),
"Expected spec validation to fail for an invalid schedule")
})

It("Should admit creation if the schedule is valid", func() {
obj.Spec.Schedule = "*/5 * * * *"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).NotTo(HaveOccurred(), "Expected spec validation to pass for a valid schedule")
Expect(warnings).To(BeNil())
Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(),
"Expected spec validation to pass for a valid schedule")
})

It("Should deny update if both name and spec are invalid", func() {
Expand All @@ -141,9 +137,8 @@ var _ = Describe("CronJob Webhook", func() {
obj.Spec.Schedule = "invalid-cron-schedule"

By("validating an update")
warnings, err := validator.ValidateUpdate(ctx, oldObj, obj)
Expect(err).To(HaveOccurred(), "Expected validation to fail for both name and spec")
Expect(warnings).To(BeNil())
Expect(validator.ValidateUpdate(ctx, oldObj, obj)).Error().To(HaveOccurred(),
"Expected validation to fail for both name and spec")
})

It("Should admit update if both name and spec are valid", func() {
Expand All @@ -155,9 +150,8 @@ var _ = Describe("CronJob Webhook", func() {
obj.Spec.Schedule = "0 0 * * *"

By("validating an update")
warnings, err := validator.ValidateUpdate(ctx, oldObj, obj)
Expect(err).NotTo(HaveOccurred(), "Expected validation to pass for a valid update")
Expect(warnings).To(BeNil())
Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil(),
"Expected validation to pass for a valid update")
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,32 +104,28 @@ var _ = Describe("CronJob Webhook", func() {
Context("When creating or updating CronJob under Validating Webhook", func() {
It("Should deny creation if the name is too long", func() {
obj.ObjectMeta.Name = "this-name-is-way-too-long-and-should-fail-validation-because-it-is-way-too-long"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).To(HaveOccurred(), "Expected name validation to fail for a too-long name")
Expect(warnings).To(BeNil())
Expect(err.Error()).To(ContainSubstring("must be no more than 52 characters"))
Expect(validator.ValidateCreate(ctx, obj)).Error().To(
MatchError(ContainSubstring("must be no more than 52 characters")),
"Expected name validation to fail for a too-long name")
})

It("Should admit creation if the name is valid", func() {
obj.ObjectMeta.Name = "valid-cronjob-name"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).NotTo(HaveOccurred(), "Expected name validation to pass for a valid name")
Expect(warnings).To(BeNil())
Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(),
"Expected name validation to pass for a valid name")
})

It("Should deny creation if the schedule is invalid", func() {
obj.Spec.Schedule = "invalid-cron-schedule"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).To(HaveOccurred(), "Expected spec validation to fail for an invalid schedule")
Expect(warnings).To(BeNil())
Expect(err.Error()).To(ContainSubstring("Expected exactly 5 fields, found 1: invalid-cron-schedule"))
Expect(validator.ValidateCreate(ctx, obj)).Error().To(
MatchError(ContainSubstring("Expected exactly 5 fields, found 1: invalid-cron-schedule")),
"Expected spec validation to fail for an invalid schedule")
})

It("Should admit creation if the schedule is valid", func() {
obj.Spec.Schedule = "*/5 * * * *"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).NotTo(HaveOccurred(), "Expected spec validation to pass for a valid schedule")
Expect(warnings).To(BeNil())
Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(),
"Expected spec validation to pass for a valid schedule")
})

It("Should deny update if both name and spec are invalid", func() {
Expand All @@ -141,9 +137,8 @@ var _ = Describe("CronJob Webhook", func() {
obj.Spec.Schedule = "invalid-cron-schedule"

By("validating an update")
warnings, err := validator.ValidateUpdate(ctx, oldObj, obj)
Expect(err).To(HaveOccurred(), "Expected validation to fail for both name and spec")
Expect(warnings).To(BeNil())
Expect(validator.ValidateUpdate(ctx, oldObj, obj)).Error().To(HaveOccurred(),
"Expected validation to fail for both name and spec")
})

It("Should admit update if both name and spec are valid", func() {
Expand All @@ -155,9 +150,8 @@ var _ = Describe("CronJob Webhook", func() {
obj.Spec.Schedule = "0 0 * * *"

By("validating an update")
warnings, err := validator.ValidateUpdate(ctx, oldObj, obj)
Expect(err).NotTo(HaveOccurred(), "Expected validation to pass for a valid update")
Expect(warnings).To(BeNil())
Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil(),
"Expected validation to pass for a valid update")
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ var _ = Describe("CronJob Webhook", func() {
// Example:
// It("Should apply defaults when a required field is empty", func() {
// By("simulating a scenario where defaults should be applied")
// obj.SomeFieldWithDefault = ""
// err := obj.Default(ctx)
// Expect(err).NotTo(HaveOccurred())
// obj.SomeFieldWithDefault = ""
// Expect(obj.Default(ctx)).To(Succeed())
// Expect(obj.SomeFieldWithDefault).To(Equal("default_value"))
// })
})
Expand All @@ -54,40 +53,33 @@ var _ = Describe("CronJob Webhook", func() {
// TODO (user): Add logic for validating webhooks
// Example:
// It("Should deny creation if a required field is missing", func() {
// By("simulating an invalid creation scenario")
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = ""
// warnings, err := obj.ValidateCreate(ctx)
// Expect(err).To(HaveOccurred())
// Expect(warnings).To(BeNil())
// Expect(obj.ValidateCreate(ctx)).Error().To(HaveOccurred())
// })
//
// It("Should admit creation if all required fields are present", func() {
// By("simulating an invalid creation scenario")
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = "valid_value"
// warnings, err := obj.ValidateCreate(ctx)
// Expect(err).NotTo(HaveOccurred())
// Expect(warnings).To(BeNil())
// Expect(obj.ValidateCreate(ctx)).To(BeNil())
// })
//
// It("Should validate updates correctly", func() {
// By("simulating a valid update scenario")
// oldObj := &Captain{SomeRequiredField: "valid_value"}
// obj.SomeRequiredField = "updated_value"
// warnings, err := obj.ValidateUpdate(ctx, oldObj)
// Expect(err).NotTo(HaveOccurred())
// Expect(warnings).To(BeNil())
// oldObj := &Captain{SomeRequiredField: "valid_value"}
// obj.SomeRequiredField = "updated_value"
// Expect(obj.ValidateUpdate(ctx, oldObj)).To(BeNil())
// })
})

Context("When creating CronJob under Conversion Webhook", func() {
It("Should convert the object correctly", func() {
// TODO (user): Add logic to convert the object to the desired version and verify the conversion
// Example:
// convertedObj := &CronJob{}
// err := obj.ConvertTo(convertedObj)
// Expect(err).NotTo(HaveOccurred())
// Expect(convertedObj).ToNot(BeNil())
})
// TODO (user): Add logic to convert the object to the desired version and verify the conversion
// Example:
// It("Should convert the object correctly", func() {
// convertedObj := &CronJob{}
// Expect(obj.ConvertTo(convertedObj)).To(Succeed())
// Expect(convertedObj).ToNot(BeNil())
// })
})

})
59 changes: 23 additions & 36 deletions hack/docs/internal/cronjob-tutorial/webhook_implementation.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,8 @@ const webhookTestCreateDefaultingFragment = `// TODO (user): Add logic for defau
// Example:
// It("Should apply defaults when a required field is empty", func() {
// By("simulating a scenario where defaults should be applied")
// obj.SomeFieldWithDefault = ""
// err := obj.Default(ctx)
// Expect(err).NotTo(HaveOccurred())
// obj.SomeFieldWithDefault = ""
// Expect(obj.Default(ctx)).To(Succeed())
// Expect(obj.SomeFieldWithDefault).To(Equal("default_value"))
// })`

Expand Down Expand Up @@ -231,58 +230,48 @@ const webhookTestCreateDefaultingReplaceFragment = `It("Should apply defaults wh
const webhookTestingValidatingTodoFragment = `// TODO (user): Add logic for validating webhooks
// Example:
// It("Should deny creation if a required field is missing", func() {
// By("simulating an invalid creation scenario")
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = ""
// warnings, err := obj.ValidateCreate(ctx)
// Expect(err).To(HaveOccurred())
// Expect(warnings).To(BeNil())
// Expect(obj.ValidateCreate(ctx)).Error().To(HaveOccurred())
// })
//
// It("Should admit creation if all required fields are present", func() {
// By("simulating an invalid creation scenario")
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = "valid_value"
// warnings, err := obj.ValidateCreate(ctx)
// Expect(err).NotTo(HaveOccurred())
// Expect(warnings).To(BeNil())
// Expect(obj.ValidateCreate(ctx)).To(BeNil())
// })
//
// It("Should validate updates correctly", func() {
// By("simulating a valid update scenario")
// oldObj := &Captain{SomeRequiredField: "valid_value"}
// obj.SomeRequiredField = "updated_value"
// warnings, err := obj.ValidateUpdate(ctx, oldObj)
// Expect(err).NotTo(HaveOccurred())
// Expect(warnings).To(BeNil())
// oldObj := &Captain{SomeRequiredField: "valid_value"}
// obj.SomeRequiredField = "updated_value"
// Expect(obj.ValidateUpdate(ctx, oldObj)).To(BeNil())
// })`

const webhookTestingValidatingExampleFragment = `It("Should deny creation if the name is too long", func() {
obj.ObjectMeta.Name = "this-name-is-way-too-long-and-should-fail-validation-because-it-is-way-too-long"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).To(HaveOccurred(), "Expected name validation to fail for a too-long name")
Expect(warnings).To(BeNil())
Expect(err.Error()).To(ContainSubstring("must be no more than 52 characters"))
Expect(validator.ValidateCreate(ctx, obj)).Error().To(
MatchError(ContainSubstring("must be no more than 52 characters")),
"Expected name validation to fail for a too-long name")
})
It("Should admit creation if the name is valid", func() {
obj.ObjectMeta.Name = "valid-cronjob-name"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).NotTo(HaveOccurred(), "Expected name validation to pass for a valid name")
Expect(warnings).To(BeNil())
Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(),
"Expected name validation to pass for a valid name")
})
It("Should deny creation if the schedule is invalid", func() {
obj.Spec.Schedule = "invalid-cron-schedule"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).To(HaveOccurred(), "Expected spec validation to fail for an invalid schedule")
Expect(warnings).To(BeNil())
Expect(err.Error()).To(ContainSubstring("Expected exactly 5 fields, found 1: invalid-cron-schedule"))
Expect(validator.ValidateCreate(ctx, obj)).Error().To(
MatchError(ContainSubstring("Expected exactly 5 fields, found 1: invalid-cron-schedule")),
"Expected spec validation to fail for an invalid schedule")
})
It("Should admit creation if the schedule is valid", func() {
obj.Spec.Schedule = "*/5 * * * *"
warnings, err := validator.ValidateCreate(ctx, obj)
Expect(err).NotTo(HaveOccurred(), "Expected spec validation to pass for a valid schedule")
Expect(warnings).To(BeNil())
Expect(validator.ValidateCreate(ctx, obj)).To(BeNil(),
"Expected spec validation to pass for a valid schedule")
})
It("Should deny update if both name and spec are invalid", func() {
Expand All @@ -294,9 +283,8 @@ const webhookTestingValidatingExampleFragment = `It("Should deny creation if the
obj.Spec.Schedule = "invalid-cron-schedule"
By("validating an update")
warnings, err := validator.ValidateUpdate(ctx, oldObj, obj)
Expect(err).To(HaveOccurred(), "Expected validation to fail for both name and spec")
Expect(warnings).To(BeNil())
Expect(validator.ValidateUpdate(ctx, oldObj, obj)).Error().To(HaveOccurred(),
"Expected validation to fail for both name and spec")
})
It("Should admit update if both name and spec are valid", func() {
Expand All @@ -308,9 +296,8 @@ const webhookTestingValidatingExampleFragment = `It("Should deny creation if the
obj.Spec.Schedule = "0 0 * * *"
By("validating an update")
warnings, err := validator.ValidateUpdate(ctx, oldObj, obj)
Expect(err).NotTo(HaveOccurred(), "Expected validation to pass for a valid update")
Expect(warnings).To(BeNil())
Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil(),
"Expected validation to pass for a valid update")
})`

const webhookTestsBeforeEachOriginal = `obj = &CronJob{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ var _ = Describe("{{ .Resource.Kind }} Webhook", func() {
BeforeEach(func() {
obj = &{{ .Resource.Kind }}{}
Expect(obj).NotTo(BeNil(), "Expected obj to be initialized")
// TODO (user): Add any setup logic common to all tests
})
Expand All @@ -103,14 +103,13 @@ var _ = Describe("{{ .Resource.Kind }} Webhook", func() {

const conversionWebhookTestTemplate = `
Context("When creating {{ .Resource.Kind }} under Conversion Webhook", func() {
It("Should convert the object correctly", func() {
// TODO (user): Add logic to convert the object to the desired version and verify the conversion
// Example:
// convertedObj := &{{ .Resource.Kind }}{}
// err := obj.ConvertTo(convertedObj)
// Expect(err).NotTo(HaveOccurred())
// Expect(convertedObj).ToNot(BeNil())
})
// TODO (user): Add logic to convert the object to the desired version and verify the conversion
// Example:
// It("Should convert the object correctly", func() {
// convertedObj := &{{ .Resource.Kind }}{}
// Expect(obj.ConvertTo(convertedObj)).To(Succeed())
// Expect(convertedObj).ToNot(BeNil())
// })
})
`

Expand All @@ -119,28 +118,22 @@ Context("When creating or updating {{ .Resource.Kind }} under Validating Webhook
// TODO (user): Add logic for validating webhooks
// Example:
// It("Should deny creation if a required field is missing", func() {
// By("simulating an invalid creation scenario")
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = ""
// warnings, err := obj.ValidateCreate(ctx)
// Expect(err).To(HaveOccurred())
// Expect(warnings).To(BeNil())
// Expect(obj.ValidateCreate(ctx)).Error().To(HaveOccurred())
// })
//
// It("Should admit creation if all required fields are present", func() {
// By("simulating an invalid creation scenario")
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = "valid_value"
// warnings, err := obj.ValidateCreate(ctx)
// Expect(err).NotTo(HaveOccurred())
// Expect(warnings).To(BeNil())
// Expect(obj.ValidateCreate(ctx)).To(BeNil())
// })
//
// It("Should validate updates correctly", func() {
// By("simulating a valid update scenario")
// oldObj := &Captain{SomeRequiredField: "valid_value"}
// obj.SomeRequiredField = "updated_value"
// warnings, err := obj.ValidateUpdate(ctx, oldObj)
// Expect(err).NotTo(HaveOccurred())
// Expect(warnings).To(BeNil())
// oldObj := &Captain{SomeRequiredField: "valid_value"}
// obj.SomeRequiredField = "updated_value"
// Expect(obj.ValidateUpdate(ctx, oldObj)).To(BeNil())
// })
})
`
Expand All @@ -151,9 +144,8 @@ Context("When creating {{ .Resource.Kind }} under Defaulting Webhook", func() {
// Example:
// It("Should apply defaults when a required field is empty", func() {
// By("simulating a scenario where defaults should be applied")
// obj.SomeFieldWithDefault = ""
// err := obj.Default(ctx)
// Expect(err).NotTo(HaveOccurred())
// obj.SomeFieldWithDefault = ""
// Expect(obj.Default(ctx)).To(Succeed())
// Expect(obj.SomeFieldWithDefault).To(Equal("default_value"))
// })
})
Expand Down
Loading

0 comments on commit d2fdc73

Please sign in to comment.