Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/prod 2146 #98

Closed
wants to merge 4 commits into from
Closed
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.DS_Store
coverage.txt
.vscode
.vscode
.idea
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Changes from upstream and other notes:
* Fixes [#81](https://github.com/qri-io/jsonschema/issues/81)
* I have looked at [*76](https://github.com/qri-io/jsonschema/issues/76) / [#80](https://github.com/qri-io/jsonschema/issues/80). My opinion, after reading the code, is that the global schema registry (which is the source of these concurrency issues) only gets involved when you have "$ref" elements. Since we only run this against schemas we write / generate, and I can guarantee that we don't generate "$ref" elements, this shouldn't be an issue for us, and we should be able to use this library across goroutines without additional synchronization
* [#91](https://github.com/qri-io/jsonschema/issues/91) may still be an issue, but I don't understand from reading it exactly what the problem is
* Fixes [#53](https://github.com/qri-io/jsonschema/issues/53) by adding a ValidateReader method that takes an io.Reader


# jsonschema
[![Qri](https://img.shields.io/badge/made%20by-qri-magenta.svg?style=flat-square)](https://qri.io)
[![GoDoc](https://godoc.org/github.com/qri-io/jsonschema?status.svg)](http://godoc.org/github.com/qri-io/jsonschema)
Expand Down
4 changes: 2 additions & 2 deletions keywords_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ func (ap *AdditionalProperties) ValidateKeyword(ctx context.Context, currentStat
continue
}
if ap.schemaType == schemaTypeFalse {
currentState.AddError(data, "additional properties are not allowed")
currentState.AddError(data, "additional properties are not allowed: "+key)
return
}
currentState.SetEvaluatedKey(key)
Expand Down Expand Up @@ -669,7 +669,7 @@ func (up *UnevaluatedProperties) ValidateKeyword(ctx context.Context, currentSta
continue
}
if up.schemaType == schemaTypeFalse {
currentState.AddError(data, "unevaluated properties are not allowed")
currentState.AddError(data, "unevaluated properties are not allowed: "+key)
return
}
subState.DescendInstanceFromState(currentState, key)
Expand Down
41 changes: 41 additions & 0 deletions modo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package jsonschema

import (
"context"
"encoding/json"
"io"
"io/fs"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestLoadingGeneratedSchemas(t *testing.T) {
t.Parallel()

filesystem := os.DirFS("testdata")
_ = fs.WalkDir(filesystem, "modo", func(path string, d fs.DirEntry, err error) error {
require.NoError(t, err)
if d.IsDir() {
return nil
}

t.Run(path, func(t *testing.T) {
assert.NotEqual(t, "", d.Name())
f, err := filesystem.Open(path)
require.NoError(t, err)
data, err := io.ReadAll(f)
require.NoError(t, err)

var s Schema
err = json.Unmarshal(data, &s)
require.NoError(t, err)

_, err = s.ValidateBytes(context.Background(), []byte(`{}`))
require.NoError(t, err)
})
return nil
})
}
12 changes: 12 additions & 0 deletions schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"net/url"
"sort"
"strings"
Expand Down Expand Up @@ -331,6 +332,17 @@ func (s *Schema) ValidateBytes(ctx context.Context, data []byte) ([]KeyError, er
return *vs.Errs, nil
}

// ValidateReader performs schema validation against a stream of json
// byte data
func (s *Schema) ValidateReader(ctx context.Context, data io.Reader) ([]KeyError, error) {
var doc interface{}
if err := json.NewDecoder(data).Decode(&doc); err != nil {
return nil, fmt.Errorf("error parsing JSON bytes: %w", err)
}
vs := s.Validate(ctx, doc)
return *vs.Errs, nil
}

// TopLevelType returns a string representing the schema's top-level type.
func (s *Schema) TopLevelType() string {
if t, ok := s.keywords["type"].(*Type); ok {
Expand Down
1 change: 1 addition & 0 deletions testdata/modo/app_session-session.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"device_identifier":{"description":"mobile device/app identifier","type":"string"},"ip_address":{"description":"ip address of the session","type":"string"},"payment_frame_size":{"required":["height","width"],"type":"object","properties":{"height":{"type":"number"},"unit":{"type":"string","default":"pixel"},"width":{"type":"number"}},"additionalProperties":false}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/bank_direct_details-payment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","required":["debitor_account_number","debitor_account_type","debitor_bank_id_code"],"type":"object","properties":{"bank_network":{"description":"The network by which the payment will be cleared. Such as SEPA or ACH.","type":"string"},"country":{"description":"ISO-3166 Alpha-2 Country Code","type":"string"},"creditor_account_number":{"description":"Account number at a given bank for the recipient of funds, likely an IBAN if outside the U.S. and Canada. This is an optional field and would override any previously configured merchant account information","type":"string"},"creditor_bank_id_code":{"description":"Bank identifier of the bank in which funds will be credited, sometimes referred to as a routing number in the US or BIC elsewhere. This is an optional field and would override any previously configured merchant account information","type":"string"},"debitor_account_number":{"description":"Account number at a given bank for the source of funds, likely an IBAN if outside the U.S. and Canada.","type":"string"},"debitor_account_type":{"description":"Account number at a given bank for the source of funds, likely an IBAN if outside the U.S. and Canada.","type":"string"},"debitor_bank_id_code":{"description":"Bank identifier of the bank in which funds will be debited, sometimes referred to as a routing number in the US or BIC elsewhere.","type":"string"},"payment_information":{"description":"a description or note for the bank direct payment being made","type":"string"}},"additionalProperties":false}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"bank_response_reason":{"description":"the response/reason from the acquirer bank","type":"string"},"payment_method":{"type":"string"},"psp_name":{"description":"Name of the payment service provider","type":"string"},"response_time":{"description":"The delta (in seconds) between when Modo sends a request to psp and receives the response","type":"number"},"status_code":{"description":"The status code returned during the processing of the payment","type":"string"},"status_message":{"description":"The status message (human readable) returned during the processing of the payment","type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/card_details-payment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","description":"A credit, debit or prepaid card issued on a network (like Visa or Mastercard) by one or more banks.","required":["card_number","expiration_date"],"type":"object","properties":{"brand":{"description":"The brand of the card","type":"string"},"card_number":{"type":"string"},"card_type":{"description":"type of card being used (credit, debit, pre-paid)","type":"string"},"country":{"description":"ISO-3166 Alpha-2 Country Code","type":"string"},"expiration_date":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/card_psp_response-paymentResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"acquirer_response_code":{"description":"the raw acquirer response code to the authorization request","type":"string"},"address_verification_response_code":{"description":"This is the AVs response code","type":"string"},"authorization_id":{"description":"id assigned by the acquirer for the authorization","type":"string"},"available_balance":{"type":"object","properties":{"currency":{"type":"object","properties":{"currency_code":{"type":"object","properties":{"isocode":{"type":"string"}},"additionalProperties":false},"decimal_places":{"type":"integer"},"name":{"type":"string"},"separator":{"type":"string"},"symbol":{"type":"string"}},"additionalProperties":false},"value":{"type":"integer"}},"additionalProperties":false},"card_verification_response_code":{"description":"This is the CVV2 response code","type":"string"},"international_card_flag":{"description":"This flag indicates if this transaction was made with a international card","type":"boolean"},"network_unique_id":{"description":"Global or domestic network id assigned to the transaction","type":"string"},"payment_method":{"type":"string"},"prepaid_card_flag":{"description":"This flag indicates if this transaction was made with a pre-paid card","type":"boolean"},"psp_name":{"description":"Name of the payment service provider","type":"string"},"response_time":{"description":"The delta (in seconds) between when Modo sends a request to psp and receives the response","type":"number"},"status_code":{"description":"The status code returned during the processing of the payment","type":"string"},"status_message":{"description":"The status message (human readable) returned during the processing of the payment","type":"string"}},"additionalProperties":false}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","description":"Verification details for a card","type":"object","properties":{"card_verification_code":{"description":"Plaintext card verification code","type":"string"},"device_fingerprint_ref":{"description":"A fingerprint of the device used for card verification (necessary for 3DS scenarios)","type":"string"},"emv_data":{"description":"data sent in specific to chip card transactions","type":"string"},"pin_block":{"description":"card pin block","type":"string"},"track_1":{"description":"1st track on the card magstripe","type":"string"},"track_2":{"description":"2nd track on the card magstripe","type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_airfare-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"agency_invoice_number":{"type":"string"},"agency_plan_name":{"type":"string"},"airline_code":{"type":"string"},"airline_designator_code":{"type":"string"},"cabin_class":{"type":"string"},"customer_reference_identifier":{"type":"string"},"itinerary":{"type":"array","items":{"type":"object","properties":{"arrival_time":{"type":"string","format":"date-time"},"departure_time":{"type":"string","format":"date-time"},"destination_airport_city":{"type":"string"},"destination_airport_code":{"type":"string"},"flight_number":{"type":"string"},"origin_airport_city":{"type":"string"},"origin_airport_code":{"type":"string"},"seat_assignment":{"type":"string"}},"additionalProperties":false}},"ticket_number":{"type":"string"},"travel_agency_code":{"type":"string"},"travel_agency_name":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_cashback-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"product_id":{"type":"string"},"your_product_reference":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_fuel-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"fuel_grade":{"type":"string"},"product_id":{"type":"string"},"service_level":{"type":"string"},"unit_of_measure":{"type":"string"},"your_product_reference":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_invoice-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"customer_identifier":{"type":"string"},"invoice_date":{"type":"string","format":"date"},"invoice_identifier":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_product-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"SKU":{"type":"string"},"manufacturer":{"type":"string"},"model":{"type":"string"},"serial_number":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_shipping-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"shipping_date":{"type":"string"},"shipping_method":{"type":"string"},"your_shipping_reference":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_subscription-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"description":{"type":"string"},"frequency":{"type":"string"},"subscription_name":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/line_item_details_tax-order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"product_id":{"type":"string"},"your_product_reference":{"type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/offline_session-session.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"application_name":{"description":"the name of the system requesting checkout.","type":"string"},"ip_address":{"description":"originating IP address of the session","type":"string"},"system_id":{"description":"the identifier of the system requesting the checkout.","type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/ps_adyen_details-paymentService.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","description":"The payment service uses this field for payment specific","type":"object","properties":{"ps_payment_options":{"description":"Sometimes a payment_service has a reference or optional value for a payment associated with optional services that you may want to take advantage of (fraud flags, purchase financing, installment plans). Use this to communicate those options to the payment_service.\n// ","type":"object","properties":{"option_type":{"description":"The type of payments option","type":"string"},"option_value":{"description":"The actual option value","type":"string"}},"additionalProperties":false},"settlement_splits":{"type":"array","items":{"type":"object","properties":{"account":{"description":"If split_type is MarketPlace, the account_id for the accountholder's settlement account must be provided","type":"string"},"amount":{"type":"object","properties":{"currency":{"type":"object","properties":{"currency_code":{"type":"object","properties":{"isocode":{"type":"string"}},"additionalProperties":false},"decimal_places":{"type":"integer"},"name":{"type":"string"},"separator":{"type":"string"},"symbol":{"type":"string"}},"additionalProperties":false},"value":{"type":"integer"}},"additionalProperties":false},"reference":{"description":"The reference of this split. Used to link other operations (e.g. captures and refunds) to this split.","type":"string"},"split_type":{"type":"string"}},"additionalProperties":false}}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/terminal_session-session.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"ip_address":{"description":"IP address of the session","type":"string"},"lane":{"description":"your lane identifier","type":"string"},"register":{"description":"your register identifier","type":"string"},"terminal_id":{"description":"your terminal identifier","type":"string"}},"additionalProperties":false}
1 change: 1 addition & 0 deletions testdata/modo/web_session-session.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2019-09/schema","type":"object","properties":{"browser":{"type":"object","properties":{"accept_header":{"type":"string"},"user_agent":{"type":"string"}},"additionalProperties":false},"cookie":{"type":"string"},"ip_address":{"description":"ip address of the session","type":"string"},"payment_frame_size":{"required":["height","width"],"type":"object","properties":{"height":{"type":"number"},"unit":{"type":"string","default":"pixel"},"width":{"type":"number"}},"additionalProperties":false}},"additionalProperties":false}