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

feat: add message validation based on schema #21

Merged
merged 4 commits into from
Jul 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
smoya marked this conversation as resolved.
Show resolved Hide resolved

// 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