Skip to content
This repository has been archived by the owner on Apr 11, 2024. It is now read-only.

Commit

Permalink
feat: add message validation based on schema (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
smoya authored Jul 26, 2021
1 parent cd5268b commit 5d5b36a
Show file tree
Hide file tree
Showing 18 changed files with 1,010 additions and 182 deletions.
6 changes: 6 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,9 @@ linters-settings:
forbidigo:
forbid:
- fmt.Print.* # usually just used for debugging purpose

issues:
exclude-rules:
- path: _test.go
linters:
- funlen
16 changes: 12 additions & 4 deletions asyncapi/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,22 @@ type Message interface {
Payload() Schema
}

// FalsifiableSchema is a variadic type used for some Schema fields.
// For example, additionalProperties value can be either `false` or a Schema.
type FalsifiableSchema interface {
IsFalse() bool
IsSchema() bool
Schema() Schema
}

// Schema is an object that allows the definition of input and output data types.
// These types can be objects, but also primitives and arrays.
// This object is a superset of the JSON Schema Specification Draft 07.
type Schema interface {
Extendable
ID() string
AdditionalItems() Schema
AdditionalProperties() Schema // TODO (boolean | Schema)
AdditionalItems() FalsifiableSchema
AdditionalProperties() FalsifiableSchema // TODO (boolean | Schema)
AllOf() []Schema
AnyOf() []Schema
CircularProps() []string
Expand Down Expand Up @@ -121,14 +129,14 @@ type Schema interface {
MinProperties() *float64
MultipleOf() *float64
Not() Schema
OneOf() Schema
OneOf() []Schema
Pattern() string
PatternProperties() map[string]Schema
Properties() map[string]Schema
Property(name string) Schema
PropertyNames() Schema
ReadOnly() bool
Required() string // TODO string[]
Required() []string
Then() Schema
Title() string
Type() []string // TODO // string | string[]
Expand Down
120 changes: 68 additions & 52 deletions asyncapi/v2/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestDecodeFromFile(t *testing.T) {
}
}

//nolint:misspell,funlen
//nolint:misspell
func TestDecodeFromPlainText(t *testing.T) {
raw := []byte(`
asyncapi: '2.0.0'
Expand All @@ -78,22 +78,35 @@ channels:
summary: Inform about environmental lighting conditions for a particular streetlight.
operationId: onLightMeasured
message:
name: LightMeasured
payload:
type: object
properties:
id:
type: integer
minimum: 0
description: Id of the streetlight.
lumens:
type: integer
minimum: 0
description: Light intensity measured in lumens.
sentAt:
type: string
format: date-time
description: Date and time when the message was sent.`)
oneOf:
- $ref: '#/components/messages/lightMeasured'
- $ref: '#/components/messages/lightMeasured2'
components:
messages:
lightMeasured:
name: LightMeasured
payload:
$ref: "#/components/schemas/lightMeasuredPayload"
lightMeasured2:
name: LightMeasured
payload:
$ref: "#/components/schemas/lightMeasuredPayload"
schemas:
lightMeasuredPayload:
type: object
properties:
id:
type: integer
minimum: 0
description: Id of the streetlight.
lumens:
type: integer
minimum: 0
description: Light intensity measured in lumens.
sentAt:
type: string
format: date-time
description: Date and time when the message was sent.`)

doc := new(Document)
require.NoError(t, Decode(raw, doc))
Expand All @@ -116,15 +129,15 @@ channels:

assert.Len(t, doc.ApplicationPublishableChannels(), 1)
assert.Len(t, doc.ApplicationPublishOperations(), 1)
assert.Len(t, doc.ApplicationPublishableMessages(), 1)
assert.Len(t, doc.ApplicationPublishableMessages(), 2)

assert.Empty(t, doc.ApplicationSubscribableChannels())
assert.Empty(t, doc.ApplicationSubscribeOperations())
assert.Empty(t, doc.ApplicationSubscribableMessages())

assert.Len(t, doc.ClientSubscribableChannels(), 1)
assert.Len(t, doc.ClientSubscribeOperations(), 1)
assert.Len(t, doc.ClientSubscribableMessages(), 1)
assert.Len(t, doc.ClientSubscribableMessages(), 2)

assert.Empty(t, doc.ClientPublishableChannels())
assert.Empty(t, doc.ClientPublishOperations())
Expand All @@ -149,40 +162,43 @@ channels:
assert.Equal(t, "onLightMeasured", operations[0].ID())

messages := operations[0].Messages()
require.Len(t, messages, 1)

assert.Equal(t, "LightMeasured", messages[0].Name())
assert.False(t, messages[0].HasSummary())
assert.False(t, messages[0].HasDescription())
assert.False(t, messages[0].HasTitle())
assert.Empty(t, messages[0].ContentType())

payload := messages[0].Payload()
require.NotNil(t, payload)

assert.Equal(t, []string{"object"}, payload.Type())
properties := payload.Properties()
require.Len(t, properties, 3)

expectedProperties := map[string]asyncapi.Schema{
"id": &Schema{
DescriptionField: "Id of the streetlight.",
MinimumField: refFloat64(0),
TypeField: "integer",
},
"lumens": &Schema{
DescriptionField: "Light intensity measured in lumens.",
MinimumField: refFloat64(0),
TypeField: "integer",
},
"sentAt": &Schema{
DescriptionField: "Date and time when the message was sent.",
FormatField: "date-time",
TypeField: "string",
},
}
require.Len(t, messages, 2)

for i := 0; i < 2; i++ {
msg := messages[i]
assert.Equal(t, "LightMeasured", msg.Name())
assert.False(t, msg.HasSummary())
assert.False(t, msg.HasDescription())
assert.False(t, msg.HasTitle())
assert.Empty(t, msg.ContentType())

payload := msg.Payload()
require.NotNil(t, payload)

assert.Equal(t, []string{"object"}, payload.Type())
properties := payload.Properties()
require.Len(t, properties, 3)

expectedProperties := map[string]asyncapi.Schema{
"id": &Schema{
DescriptionField: "Id of the streetlight.",
MinimumField: refFloat64(0),
TypeField: "integer",
},
"lumens": &Schema{
DescriptionField: "Light intensity measured in lumens.",
MinimumField: refFloat64(0),
TypeField: "integer",
},
"sentAt": &Schema{
DescriptionField: "Date and time when the message was sent.",
FormatField: "date-time",
TypeField: "string",
},
}

assert.Equal(t, expectedProperties, properties)
assert.Equal(t, expectedProperties, properties)
}
}

func refFloat64(v float64) *float64 {
Expand Down
Loading

0 comments on commit 5d5b36a

Please sign in to comment.