Skip to content

Commit d99f1ad

Browse files
committed
docs: fix bookstore example
The bookstore example serves as a helpful reference, so it should be working.
1 parent eb3b92e commit d99f1ad

File tree

2 files changed

+116
-50
lines changed

2 files changed

+116
-50
lines changed

examples/resource-definitions/bookstore.yaml

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ contact:
55
name: "API support"
66
email: "aepsupport@aep.dev"
77
resources:
8-
# example of a simple resource
9-
- &publisher
10-
kind: "publisher"
8+
publisher: &publisher
9+
singular: "publisher"
1110
plural: "publishers"
1211
schema:
12+
type: object
1313
properties:
1414
description:
1515
type: string
@@ -23,40 +23,40 @@ resources:
2323
supports_filter: true
2424
supports_skip: true
2525
apply: {}
26-
# example of a child resource
27-
- &book
28-
kind: "book"
26+
book: &book
27+
singular: "book"
2928
plural: "books"
30-
# the parents should specify the parents of the resource. It takes in the
31-
# kind.
3229
parents:
3330
- *publisher
34-
properties:
31+
schema:
32+
type: object
3533
required: ["author", "edition", "isbn", "price", "published"]
36-
isbn:
37-
type: array
38-
items:
39-
type: string
40-
x-aep-field-number: 1
41-
price:
42-
type: number
43-
x-aep-field-number: 2
44-
published:
45-
type: boolean
46-
x-aep-field-number: 3
47-
edition:
48-
type: integer
49-
x-aep-field-number: 4
50-
author:
51-
type: array
52-
items:
53-
properties:
54-
firstName:
55-
type: string
56-
x-aep-field-number: 1
57-
lastName:
58-
type: string
59-
x-aep-field-number: 2
34+
properties:
35+
isbn:
36+
type: array
37+
items:
38+
type: string
39+
x-aep-field-number: 1
40+
price:
41+
type: number
42+
x-aep-field-number: 2
43+
published:
44+
type: boolean
45+
x-aep-field-number: 3
46+
edition:
47+
type: integer
48+
x-aep-field-number: 4
49+
author:
50+
type: array
51+
items:
52+
type: object
53+
properties:
54+
firstName:
55+
type: string
56+
x-aep-field-number: 1
57+
lastName:
58+
type: string
59+
x-aep-field-number: 2
6060
methods:
6161
create: {}
6262
read: {}
@@ -67,7 +67,7 @@ resources:
6767
apply: {}
6868
custom_methods:
6969
- name: "archive"
70-
method_type: POST
70+
method: "POST"
7171
request:
7272
type: object
7373
properties: {}
@@ -76,34 +76,30 @@ resources:
7676
properties:
7777
success:
7878
type: boolean
79-
# other example resources that might be interesting to add:
80-
# authors, which could be a reference for book
81-
# authors could have a reference to publishers too
82-
# example of a child resource, with a redudant type name.
83-
# aepc will remove the redundant component in the path pattern
84-
- &book-edition
85-
kind: "book-edition"
79+
book-edition:
80+
singular: "book-edition"
8681
plural: "book-editions"
87-
# the parents should specify the parents of the resource. It takes in the
88-
# kind.
8982
parents:
9083
- *book
91-
properties:
84+
schema:
85+
type: object
9286
required: ["displayname"]
93-
displayname:
94-
type: string
95-
x-aep-field-number: 1
87+
properties:
88+
displayname:
89+
type: string
90+
x-aep-field-number: 1
9691
methods:
9792
create: {}
9893
read: {}
9994
list: {}
10095
delete: {}
101-
- kind: "isbn"
96+
isbn:
97+
singular: "isbn"
10298
plural: "isbns"
99+
schema:
100+
type: object
103101
properties: {}
104102
methods:
105103
read: {}
106104
list: {}
107105
create: {}
108-
# blocked on https://github.com/aep-dev/api-linter/issues/97
109-
# non_client_settable_id: true

pkg/api/api_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package api
22

33
import (
4+
"encoding/json"
5+
"os"
6+
"path/filepath"
47
"testing"
58

69
"github.com/aep-dev/aep-lib-go/pkg/openapi"
710
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
"gopkg.in/yaml.v3"
813
)
914

1015
var basicOpenAPI = &openapi.OpenAPI{
@@ -568,3 +573,68 @@ func TestGetAPI(t *testing.T) {
568573
})
569574
}
570575
}
576+
577+
func TestParseBookstoreYAMLDirectly(t *testing.T) {
578+
// Construct the path relative to the test file's location
579+
yamlPath := filepath.Join("..", "..", "examples", "resource-definitions", "bookstore.yaml")
580+
581+
// Read the YAML file
582+
yamlData, err := os.ReadFile(yamlPath)
583+
require.NoError(t, err, "Failed to read bookstore.yaml")
584+
require.NotEmpty(t, yamlData, "bookstore.yaml is empty")
585+
586+
// Unmarshal YAML into a generic interface{}
587+
var genericYamlData interface{}
588+
err = yaml.Unmarshal(yamlData, &genericYamlData)
589+
require.NoError(t, err, "Failed to unmarshal YAML into generic interface")
590+
591+
// Marshal the generic interface{} to JSON
592+
jsonData, err := json.Marshal(genericYamlData)
593+
require.NoError(t, err, "Failed to marshal generic interface to JSON")
594+
require.NotEmpty(t, jsonData, "Resulting JSON data is empty")
595+
596+
// Attempt to unmarshal the JSON directly into api.API
597+
var apiResult API
598+
err = json.Unmarshal(jsonData, &apiResult)
599+
require.NoError(t, err, "Failed to unmarshal JSON into api.API struct")
600+
601+
// Assert basic fields that might match (like Name, ServerURL, Contact)
602+
assert.Equal(t, "bookstore.example.com", apiResult.Name, "API Name should be populated if field names match")
603+
assert.Equal(t, "http://localhost:8081", apiResult.ServerURL, "API ServerURL should be populated based on json tag")
604+
if assert.NotNil(t, apiResult.Contact, "Contact might be populated if fields match") {
605+
assert.Equal(t, "API support", apiResult.Contact.Name)
606+
assert.Equal(t, "aepsupport@aep.dev", apiResult.Contact.Email)
607+
}
608+
609+
// Assert that Resources map IS populated correctly
610+
assert.NotEmpty(t, apiResult.Resources, "Resources map should be populated")
611+
assert.Contains(t, apiResult.Resources, "publisher", "Resources map should contain 'publisher'")
612+
assert.Contains(t, apiResult.Resources, "book", "Resources map should contain 'book'")
613+
assert.Contains(t, apiResult.Resources, "book-edition", "Resources map should contain 'book-edition'")
614+
assert.Contains(t, apiResult.Resources, "isbn", "Resources map should contain 'isbn'")
615+
616+
// Check some details of a resource
617+
publisherResource := apiResult.Resources["publisher"]
618+
assert.NotNil(t, publisherResource, "'publisher' resource should not be nil")
619+
assert.Equal(t, "publisher", publisherResource.Singular)
620+
assert.Equal(t, "publishers", publisherResource.Plural)
621+
assert.NotNil(t, publisherResource.Schema, "'publisher' resource schema should not be nil")
622+
assert.Equal(t, "object", publisherResource.Schema.Type)
623+
assert.Contains(t, publisherResource.Schema.Properties, "description")
624+
assert.Equal(t, "string", publisherResource.Schema.Properties["description"].Type)
625+
assert.NotNil(t, publisherResource.Methods.List, "'publisher' should have List method")
626+
assert.True(t, publisherResource.Methods.List.SupportsFilter)
627+
628+
// Check book resource details, including custom method
629+
bookResource := apiResult.Resources["book"]
630+
assert.NotNil(t, bookResource, "'book' resource should not be nil")
631+
assert.Equal(t, "book", bookResource.Singular)
632+
assert.Equal(t, "books", bookResource.Plural)
633+
assert.NotNil(t, bookResource.Schema, "'book' resource schema should not be nil")
634+
assert.Contains(t, bookResource.Schema.Properties, "isbn")
635+
assert.Equal(t, "array", bookResource.Schema.Properties["isbn"].Type)
636+
assert.NotNil(t, bookResource.Methods.List, "'book' should have List method")
637+
assert.True(t, bookResource.Methods.List.HasUnreachableResources)
638+
assert.Len(t, bookResource.CustomMethods, 1, "'book' should have 1 custom method")
639+
assert.Equal(t, "archive", bookResource.CustomMethods[0].Name)
640+
}

0 commit comments

Comments
 (0)