snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
17
test/schema/README.md
Normal file
17
test/schema/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Schema Tests
|
||||
|
||||
This test works by validating cases of the payload against a schema.
|
||||
To add a case, place a file in the `${schemaName}.schema.test.${success|failure}` folder.
|
||||
A success case should validate, a failure case should throw a validation error.
|
||||
|
||||
## Handling of "$ref"
|
||||
|
||||
To allow testing definitions on their own, and reduce the size of individual cases,
|
||||
every `"$ref"` in the schema will be replaced with `"const"` before validation.
|
||||
This means that a case only has to define the pointer as a string. Example:
|
||||
|
||||
```yaml
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
hooks:
|
||||
- "#/definitions/selfServiceSessionRevokerHook"
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
userinfo:
|
||||
given_name:
|
||||
essential: true
|
||||
someInvalidProperty: 'invalid' # Invalid property
|
||||
nickname: null
|
||||
email:
|
||||
essential: InvalidValueForEssential
|
||||
email_verified:
|
||||
essentials: true # key typo
|
||||
picture: null
|
||||
http://example/info/claims/groups: null
|
||||
id_token:
|
||||
auth_time:
|
||||
essential: true
|
||||
acr:
|
||||
values: ['urn:mace:incommon:iap:silver']
|
||||
sub:
|
||||
value: '248289761001'
|
||||
@@ -0,0 +1,5 @@
|
||||
valid:
|
||||
email:
|
||||
body:
|
||||
plaintext: "https://some-url"
|
||||
subject: "https://some-url"
|
||||
@@ -0,0 +1,4 @@
|
||||
invalid:
|
||||
another-courier:
|
||||
valid:
|
||||
email:
|
||||
@@ -0,0 +1,4 @@
|
||||
body:
|
||||
plaintext: "http://call-something"
|
||||
html: "malformed uri"
|
||||
subject: "something"
|
||||
@@ -0,0 +1,5 @@
|
||||
sms:
|
||||
request_config:
|
||||
url: "malformed uri"
|
||||
method: POST
|
||||
body: "malformed uri"
|
||||
@@ -0,0 +1,81 @@
|
||||
selfservice:
|
||||
|
||||
strategies:
|
||||
password:
|
||||
enabled: 0
|
||||
oidc:
|
||||
enabled: 0
|
||||
config:
|
||||
providers:
|
||||
- foo
|
||||
|
||||
logout:
|
||||
redirect_to: 0
|
||||
|
||||
profile:
|
||||
lifespan: 10
|
||||
|
||||
login:
|
||||
lifespan: 10
|
||||
before: foo
|
||||
after: foo
|
||||
|
||||
registration:
|
||||
lifespan: 10
|
||||
before:
|
||||
- foo
|
||||
after: foo
|
||||
|
||||
dsn: foo
|
||||
|
||||
courier:
|
||||
template_override_path: foo
|
||||
smtp:
|
||||
connection_uri: 0
|
||||
from_address: 0
|
||||
message_retries: invalid-value
|
||||
|
||||
serve:
|
||||
admin:
|
||||
host: 0
|
||||
port: foo
|
||||
public:
|
||||
host: 0
|
||||
port: foo
|
||||
|
||||
urls:
|
||||
self:
|
||||
public: 1
|
||||
admin: 1
|
||||
mfa_ui: 1
|
||||
login_ui: 1
|
||||
settings_ui: 1
|
||||
default_return_to: 1
|
||||
registration_ui: 1
|
||||
error_ui: 1
|
||||
allowed_return_urls:
|
||||
- 1
|
||||
- 1
|
||||
|
||||
log:
|
||||
level: 1
|
||||
format: 1
|
||||
|
||||
identity:
|
||||
traits:
|
||||
default_schema_id: 1123
|
||||
schemas:
|
||||
- id: 1
|
||||
url: 1
|
||||
|
||||
secrets:
|
||||
session:
|
||||
- 1
|
||||
|
||||
hashers:
|
||||
argon2:
|
||||
memory: foo
|
||||
iterations: foo
|
||||
parallelism: foo
|
||||
salt_length: foo
|
||||
key_length: foo
|
||||
@@ -0,0 +1 @@
|
||||
version: x1.0.0
|
||||
@@ -0,0 +1,20 @@
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
|
||||
dsn: foo
|
||||
|
||||
identity:
|
||||
schemas:
|
||||
- id: default
|
||||
url: https://example.com
|
||||
|
||||
courier:
|
||||
template_override_path: foo
|
||||
smtp:
|
||||
connection_uri: smtps://foo:bar@my-mailserver:1234/
|
||||
from_address: no-reply@ory.kratos.sh
|
||||
templates:
|
||||
recovery: "#/definitions/courierTemplates"
|
||||
verification:
|
||||
valid:
|
||||
email: "#/definitions/emailCourierTemplate"
|
||||
@@ -0,0 +1,12 @@
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
flows:
|
||||
recovery:
|
||||
enabled: true
|
||||
|
||||
dsn: foo
|
||||
|
||||
identity:
|
||||
schemas:
|
||||
- id: default
|
||||
url: https://example.com
|
||||
@@ -0,0 +1,12 @@
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
flows:
|
||||
verification:
|
||||
enabled: true
|
||||
|
||||
dsn: foo
|
||||
|
||||
identity:
|
||||
schemas:
|
||||
- id: default
|
||||
url: https://example.com
|
||||
@@ -0,0 +1,11 @@
|
||||
id: 1
|
||||
provider: unknown
|
||||
client_id: 1
|
||||
client_secret: 1
|
||||
issuer_url: not an URL
|
||||
auth_url: not an URL
|
||||
token_url: not an URL
|
||||
mapper_url: not an URL
|
||||
scope:
|
||||
- 1
|
||||
microsoft_tenant: 1
|
||||
@@ -0,0 +1,6 @@
|
||||
id: foo
|
||||
provider: github
|
||||
client_id: asdf
|
||||
client_secret: asdf
|
||||
mapper_url: file://./mapper_file
|
||||
apple_private_key_id: org
|
||||
@@ -0,0 +1,10 @@
|
||||
id: foo
|
||||
provider: apple
|
||||
client_id: foo
|
||||
team_id: foo
|
||||
private_key: foo
|
||||
mapper_url: https://example.com
|
||||
scope:
|
||||
- foo
|
||||
- bar
|
||||
requested_claims: "#/definitions/OIDCClaims"
|
||||
@@ -0,0 +1,6 @@
|
||||
id: foo
|
||||
provider: github
|
||||
client_id: asdf
|
||||
client_secret: asdf
|
||||
mapper_url: file://./mapper_file
|
||||
private_key: org
|
||||
@@ -0,0 +1,10 @@
|
||||
id: foo
|
||||
provider: apple
|
||||
client_id: foo
|
||||
apple_team_id: foo
|
||||
apple_private_key_id: foo
|
||||
mapper_url: https://example.com
|
||||
scope:
|
||||
- foo
|
||||
- bar
|
||||
requested_claims: "#/definitions/OIDCClaims"
|
||||
@@ -0,0 +1,6 @@
|
||||
id: foo
|
||||
provider: github
|
||||
client_id: asdf
|
||||
client_secret: asdf
|
||||
mapper_url: file://./mapper_file
|
||||
team_id: org
|
||||
@@ -0,0 +1,10 @@
|
||||
id: foo
|
||||
provider: apple
|
||||
client_id: foo
|
||||
apple_private_key_id: foo
|
||||
apple_private_key: foo
|
||||
mapper_url: https://example.com
|
||||
scope:
|
||||
- foo
|
||||
- bar
|
||||
requested_claims: "#/definitions/OIDCClaims"
|
||||
@@ -0,0 +1,6 @@
|
||||
id: foo
|
||||
provider: github
|
||||
client_id: asdf
|
||||
client_secret: asdf
|
||||
mapper_url: file://./mapper_file
|
||||
microsoft_tenant: org
|
||||
@@ -0,0 +1,5 @@
|
||||
id: foo
|
||||
provider: microsoft
|
||||
client_id: asdf
|
||||
client_secret: asdf
|
||||
mapper_url: file://./mapper_file
|
||||
@@ -0,0 +1,18 @@
|
||||
userinfo:
|
||||
given_name:
|
||||
essential: true
|
||||
nickname: null
|
||||
email:
|
||||
essential: true
|
||||
email_verified:
|
||||
essential: true
|
||||
picture: null
|
||||
http://example/info/claims/groups: null
|
||||
id_token:
|
||||
auth_time:
|
||||
essential: true
|
||||
acr:
|
||||
values: ['urn:mace:incommon:iap:silver']
|
||||
sub:
|
||||
essential: true
|
||||
value: 248289761001
|
||||
@@ -0,0 +1,4 @@
|
||||
invalid:
|
||||
email: "#/definitions/emailCourierTemplate"
|
||||
valid:
|
||||
email: "#/definitions/emailCourierTemplate"
|
||||
@@ -0,0 +1 @@
|
||||
/dashboard
|
||||
@@ -0,0 +1 @@
|
||||
https://my-app.com/dashboard
|
||||
@@ -0,0 +1,4 @@
|
||||
body:
|
||||
plaintext: "base64://"
|
||||
html: "base64://"
|
||||
subject: "http://"
|
||||
@@ -0,0 +1 @@
|
||||
subject: "http://"
|
||||
@@ -0,0 +1,3 @@
|
||||
body:
|
||||
plaintext: "base64://"
|
||||
html: "base64://"
|
||||
@@ -0,0 +1,19 @@
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
|
||||
dsn: foo
|
||||
|
||||
identity:
|
||||
schemas:
|
||||
- id: default
|
||||
url: https://example.com
|
||||
|
||||
courier:
|
||||
message_retries: 50
|
||||
smtp:
|
||||
connection_uri: smtps://foo:bar@my-mailserver:1234/
|
||||
from_address: no-reply@ory.kratos.sh
|
||||
channels:
|
||||
- id: sms
|
||||
type: http
|
||||
request_config: "#/definitions/httpRequestConfig"
|
||||
@@ -0,0 +1,18 @@
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
|
||||
dsn: foo
|
||||
|
||||
identity:
|
||||
schemas:
|
||||
- id: default
|
||||
url: https://example.com
|
||||
|
||||
courier:
|
||||
template_override_path: foo
|
||||
smtp:
|
||||
connection_uri: smtps://foo:bar@my-mailserver:1234/
|
||||
from_address: no-reply@ory.kratos.sh
|
||||
templates:
|
||||
recovery: "#/definitions/courierTemplates"
|
||||
verification: "#/definitions/courierTemplates"
|
||||
109
test/schema/fixtures/config.schema.test.success/root.full.yml
Normal file
109
test/schema/fixtures/config.schema.test.success/root.full.yml
Normal file
@@ -0,0 +1,109 @@
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
|
||||
allowed_return_urls:
|
||||
- https://foo.bar
|
||||
- /dashboard
|
||||
|
||||
flows:
|
||||
settings:
|
||||
ui_url: /settings
|
||||
lifespan: 1h5s
|
||||
privileged_session_max_age: 1h
|
||||
after: "#/definitions/selfServiceAfterSettings"
|
||||
|
||||
logout:
|
||||
after:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
|
||||
registration:
|
||||
ui_url: /registration
|
||||
lifespan: 1h
|
||||
after: "#/definitions/selfServiceAfterRegistration"
|
||||
|
||||
login:
|
||||
ui_url: /login
|
||||
lifespan: 1h
|
||||
after: "#/definitions/selfServiceAfterLogin"
|
||||
|
||||
verification:
|
||||
enabled: true
|
||||
ui_url: /verification
|
||||
lifespan: 1h
|
||||
after: "#/definitions/selfServiceAfterVerification"
|
||||
|
||||
recovery:
|
||||
enabled: true
|
||||
ui_url: /recovery
|
||||
lifespan: 1h
|
||||
after: "#/definitions/selfServiceAfterRecovery"
|
||||
|
||||
error:
|
||||
ui_url: /error
|
||||
|
||||
methods:
|
||||
profile:
|
||||
enabled: true
|
||||
link:
|
||||
enabled: true
|
||||
password:
|
||||
enabled: true
|
||||
totp:
|
||||
enabled: true
|
||||
config:
|
||||
issuer: "foobar"
|
||||
oidc:
|
||||
enabled: true
|
||||
config:
|
||||
providers:
|
||||
- "#/definitions/selfServiceOIDCProvider"
|
||||
|
||||
dsn: foo
|
||||
|
||||
courier:
|
||||
template_override_path: foo
|
||||
smtp:
|
||||
connection_uri: smtps://foo:bar@my-mailserver:1234/
|
||||
from_address: no-reply@ory.kratos.sh
|
||||
|
||||
serve:
|
||||
admin:
|
||||
host: foo
|
||||
port: 4434
|
||||
public:
|
||||
host: foo
|
||||
port: 4433
|
||||
|
||||
log:
|
||||
level: trace
|
||||
format: json
|
||||
|
||||
identity:
|
||||
default_schema_id: foo
|
||||
schemas:
|
||||
- id: foo
|
||||
url: https://example.com
|
||||
|
||||
secrets:
|
||||
default:
|
||||
- default secret with a lot of chars
|
||||
cookie:
|
||||
- cookie secret with a lot of chars
|
||||
cipher:
|
||||
- secret-thirty-two-character-long
|
||||
|
||||
ciphers:
|
||||
algorithm: xchacha20-poly1305
|
||||
|
||||
hashers:
|
||||
argon2:
|
||||
memory: 128MB
|
||||
iterations: 1
|
||||
parallelism: 1
|
||||
salt_length: 16
|
||||
key_length: 16
|
||||
dedicated_memory: 1GB
|
||||
expected_deviation: 500ms
|
||||
expected_duration: 500ms
|
||||
|
||||
version: v1.0.0
|
||||
@@ -0,0 +1,17 @@
|
||||
serve:
|
||||
public:
|
||||
base_url: "#/definitions/baseUrl"
|
||||
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
|
||||
dsn: foo
|
||||
|
||||
identity:
|
||||
schemas:
|
||||
- id: default
|
||||
url: https://example.com
|
||||
|
||||
session:
|
||||
cookie:
|
||||
domain: foobar
|
||||
@@ -0,0 +1,9 @@
|
||||
selfservice:
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
|
||||
dsn: foo
|
||||
|
||||
identity:
|
||||
schemas:
|
||||
- id: default
|
||||
url: https://example.com
|
||||
@@ -0,0 +1,2 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
hooks: "#/definitions/selfServiceAfterDefaultLoginMethodHooks"
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,2 @@
|
||||
- "#/definitions/selfServiceSessionRevokerHook"
|
||||
- "#/definitions/selfServiceRequireVerifiedAddressHook"
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1,4 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
password: "#/definitions/selfServiceAfterDefaultLoginMethod"
|
||||
webauthn: "#/definitions/selfServiceAfterDefaultLoginMethod"
|
||||
oidc: "#/definitions/selfServiceAfterOIDCLoginMethod"
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,3 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
hooks:
|
||||
- "#/definitions/selfServiceSessionRevokerHook"
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,4 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
password: "#/definitions/selfServiceAfterRegistrationMethod"
|
||||
webauthn: "#/definitions/selfServiceAfterRegistrationMethod"
|
||||
oidc: "#/definitions/selfServiceAfterRegistrationMethod"
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,3 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
hooks:
|
||||
- "#/definitions/selfServiceSessionIssuerHook"
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,3 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
password: "#/definitions/selfServiceAfterSettingsAuthMethod"
|
||||
profile: "#/definitions/selfServiceAfterSettingsProfileMethod"
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,4 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
hooks:
|
||||
- "#/definitions/selfServiceWebHook"
|
||||
- "#/definitions/selfServiceSessionRevokerHook"
|
||||
@@ -0,0 +1,3 @@
|
||||
default_browser_return_url: "#/definitions/defaultReturnTo"
|
||||
hooks:
|
||||
- "#/definitions/selfServiceWebHook"
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,11 @@
|
||||
id: foo
|
||||
provider: apple
|
||||
client_id: foo
|
||||
apple_team_id: foo
|
||||
apple_private_key_id: foo
|
||||
apple_private_key: foo
|
||||
mapper_url: https://example.com
|
||||
scope:
|
||||
- foo
|
||||
- bar
|
||||
requested_claims: "#/definitions/OIDCClaims"
|
||||
@@ -0,0 +1,12 @@
|
||||
id: foo
|
||||
provider: github
|
||||
client_id: foo
|
||||
client_secret: foo
|
||||
issuer_url: https://example.com
|
||||
auth_url: https://example.com
|
||||
token_url: https://example.com
|
||||
mapper_url: https://example.com
|
||||
scope:
|
||||
- foo
|
||||
- bar
|
||||
requested_claims: "#/definitions/OIDCClaims"
|
||||
@@ -0,0 +1,13 @@
|
||||
id: foo
|
||||
provider: microsoft
|
||||
client_id: foo
|
||||
client_secret: foo
|
||||
issuer_url: https://example.com
|
||||
auth_url: https://example.com
|
||||
token_url: https://example.com
|
||||
mapper_url: https://example.com
|
||||
scope:
|
||||
- foo
|
||||
- bar
|
||||
microsoft_tenant: org
|
||||
requested_claims: "#/definitions/OIDCClaims"
|
||||
@@ -0,0 +1,5 @@
|
||||
id: foo
|
||||
provider: github
|
||||
client_id: foo
|
||||
client_secret: foo
|
||||
mapper_url: https://example.com
|
||||
@@ -0,0 +1 @@
|
||||
hook: session
|
||||
@@ -0,0 +1 @@
|
||||
hook: revoke_active_sessions
|
||||
@@ -0,0 +1,7 @@
|
||||
hook: web_hook
|
||||
config:
|
||||
url: https://foo/bar
|
||||
method: POST
|
||||
body: base64://asdf
|
||||
response:
|
||||
ignore: false
|
||||
@@ -0,0 +1,5 @@
|
||||
type: api_key
|
||||
config:
|
||||
name: foo
|
||||
value: bar
|
||||
in: header
|
||||
@@ -0,0 +1,4 @@
|
||||
type: basic_auth
|
||||
config:
|
||||
user: foo
|
||||
password: bar
|
||||
153
test/schema/schema_test.go
Normal file
153
test/schema/schema_test.go
Normal file
@@ -0,0 +1,153 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/ory/jsonschema/v3"
|
||||
_ "github.com/ory/jsonschema/v3/fileloader"
|
||||
)
|
||||
|
||||
type schema struct {
|
||||
name string
|
||||
raw string
|
||||
s *jsonschema.Schema
|
||||
}
|
||||
|
||||
type schemas []schema
|
||||
|
||||
type result int
|
||||
|
||||
const (
|
||||
success result = iota
|
||||
failure
|
||||
)
|
||||
|
||||
func (r result) String() string {
|
||||
return []string{"success", "failure"}[r]
|
||||
}
|
||||
|
||||
func (s schema) validate(t *testing.T, path string) error {
|
||||
t.Helper()
|
||||
if s.s == nil {
|
||||
compiler := jsonschema.NewCompiler()
|
||||
if err := compiler.AddResource(s.name, strings.NewReader(s.raw)); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
sx, err := compiler.Compile(context.Background(), s.name)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
s.s = sx
|
||||
}
|
||||
|
||||
var doc io.Reader
|
||||
y, err := os.ReadFile(path) // #nosec G304 test code
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
j, err := yaml.YAMLToJSON(y)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
doc = bytes.NewBuffer(j)
|
||||
|
||||
if err := s.s.Validate(doc); err != nil {
|
||||
return errors.Errorf("there were validation errors: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ss *schemas) getByName(n string) (*schema, error) {
|
||||
for _, s := range *ss {
|
||||
if s.name == n {
|
||||
return &s, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("could not find schema with name %s", n)
|
||||
}
|
||||
|
||||
func TestSchemas(t *testing.T) {
|
||||
t.Run("test embedx/config.schema.json", SchemaTestRunner("../../embedx", "config"))
|
||||
}
|
||||
|
||||
func SchemaTestRunner(spath string, sname string) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
sb, err := os.ReadFile(fmt.Sprintf("%s/%s.schema.json", spath, sname))
|
||||
require.NoError(t, err)
|
||||
|
||||
// To test refs independently and reduce test case size we replace every "$ref" with "const".
|
||||
// That way refs will not be resolved but we still make sure that they are pointing to the right definition.
|
||||
// Changing a definition will result in just changing test cases for that definition.
|
||||
s := strings.ReplaceAll(string(sb), `"$ref":`, `"const":`)
|
||||
schemas := schemas{{
|
||||
name: "root",
|
||||
raw: s,
|
||||
}}
|
||||
def := gjson.Get(s, "definitions")
|
||||
if def.Exists() {
|
||||
require.True(t, def.IsObject())
|
||||
def.ForEach(func(key, value gjson.Result) bool {
|
||||
require.Equal(t, gjson.String, key.Type)
|
||||
schemas = append(schemas, schema{
|
||||
name: key.String(),
|
||||
raw: value.Raw,
|
||||
})
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
RunCases(t, schemas, fmt.Sprintf("./fixtures/%s.schema.test.success", sname), success)
|
||||
RunCases(t, schemas, fmt.Sprintf("./fixtures/%s.schema.test.failure", sname), failure)
|
||||
}
|
||||
}
|
||||
|
||||
func RunCases(t *testing.T, ss schemas, dir string, expected result) {
|
||||
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
require.NoError(t, err)
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
parts := strings.Split(info.Name(), ".")
|
||||
require.Equal(t, 3, len(parts))
|
||||
sName, tc := parts[0], parts[1]
|
||||
|
||||
s, err := ss.getByName(sName)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run(fmt.Sprintf("case=schema %s test case %s expects %s", sName, tc, expected), func(t *testing.T) {
|
||||
err := s.validate(t, path)
|
||||
if expected == success {
|
||||
assert.NoError(t, err, "path: %s", path)
|
||||
} else {
|
||||
assert.Error(t, err, "path: %s", path)
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
Reference in New Issue
Block a user