Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

require "elastic_graph/constants"
require "elastic_graph/datastore_core/index_definition"
require "elastic_graph/json_ingestion/schema_definition/api_extension"
require "elastic_graph/support/hash_util"
require "stringio"
require_relative "implementation_shared_examples"
Expand All @@ -16,6 +17,12 @@ module ElasticGraph
class DatastoreCore
module IndexDefinition
RSpec.describe RolloverIndexTemplate, :uses_datastore, :builds_indexer do
# Documents indexed by these specs are validated against the JSON schemas, so the schemas
# defined in this file all include the JSON ingestion schema definition extension.
def build_datastore_core(**options, &block)
super(schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension], **options, &block)
end

# Use different index names than any other tests use, because most tests expect a specific index
# configuration (based on `config/schema.graphql`) and we do not want to mess with it here.
let(:index_prefix) { unique_index_name }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# frozen_string_literal: true

require "elastic_graph/graphql/datastore_search_router"
require "elastic_graph/json_ingestion/schema_definition/api_extension"
require "elastic_graph/schema_definition/schema_elements/type_namer"
require "elastic_graph/spec_support/builds_admin"
require "graphql"
Expand Down Expand Up @@ -91,6 +92,9 @@ def self.with_both_casing_forms(&block)
schema_element_name_form: :camelCase,
derived_type_name_formats: derived_type_name_formats,
enum_value_overrides_by_type: enum_value_overrides_by_type,
# The camelCase schema definition below is derived from the repository's main test schema,
# which uses the JSON ingestion schema definition DSL, so it requires this extension.
schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension],
schema_definition: ->(schema) do
# standard:disable Security/Eval -- it's ok here in a test.
schema.as_active_instance { eval(camel_case_schema_def) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require_relative "datastore_query_integration_support"
require "elastic_graph/errors"
require "elastic_graph/graphql/datastore_search_router"
require "elastic_graph/json_ingestion/schema_definition/api_extension"

module ElasticGraph
class GraphQL
Expand Down Expand Up @@ -85,7 +86,7 @@ def msearch(body:, **args, &block)

context "when the indexed type has nested `default_sort_fields`" do
let(:graphql) do
build_graphql(schema_definition: lambda do |schema|
build_graphql(schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension], schema_definition: lambda do |schema|
schema.object_type "Money" do |t|
t.field "currency", "String!"
t.field "amount_cents", "Int!"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# frozen_string_literal: true

require "elastic_graph/graphql/resolvers/nested_relationships"
require "elastic_graph/json_ingestion/schema_definition/api_extension"

module ElasticGraph
class GraphQL
Expand All @@ -16,7 +17,7 @@ module Resolvers
# is implemented via a filter on `id` (the search routing field)
context "when the field being resolved is a relay connection field", :expect_search_routing do
let(:graphql) do
build_graphql(schema_definition: lambda do |schema|
build_graphql(schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension], schema_definition: lambda do |schema|
schema.object_type "Component" do |t|
t.field "id", "ID!"
t.field "name", "String!"
Expand Down Expand Up @@ -62,7 +63,7 @@ module Resolvers

describe "a relates_to_many/relates_to_one bidirectional relationship with an array foreign key from the one to the many" do
let(:graphql) do
build_graphql(schema_definition: lambda do |schema|
build_graphql(schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension], schema_definition: lambda do |schema|
schema.object_type "Money" do |t|
t.field "currency", "String!"
t.field "amount_cents", "Int"
Expand Down Expand Up @@ -241,7 +242,7 @@ module Resolvers

describe "a relates_to_many/relates_to_one bidirectional relationship with a scalar foreign key from the many to the one" do
let(:graphql) do
build_graphql(schema_definition: lambda do |schema|
build_graphql(schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension], schema_definition: lambda do |schema|
schema.object_type "ElectricalPart" do |t|
t.field "id", "ID!"
t.field "name", "String!"
Expand Down Expand Up @@ -381,7 +382,7 @@ module Resolvers

describe "a relates_to_many/relates_to_many bidirectional relationship with an array foreign key from a many to a many" do
let(:graphql) do
build_graphql(schema_definition: lambda do |schema|
build_graphql(schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension], schema_definition: lambda do |schema|
schema.object_type "Component" do |t|
t.field "id", "ID!"
t.field "name", "String!"
Expand Down Expand Up @@ -573,7 +574,7 @@ module Resolvers

describe "a relates_to_one/relates_to_one bidirectional relationship with a scalar foreign key from a one to a one" do
let(:graphql) do
build_graphql(schema_definition: lambda do |schema|
build_graphql(schema_definition_extension_modules: [JSONIngestion::SchemaDefinition::APIExtension], schema_definition: lambda do |schema|
schema.object_type "Manufacturer" do |t|
t.field "id", "ID!"
t.field "name", "String"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,6 @@ def resolve(field:, object:, args:, context:)

schema.scalar_type "Operands" do |t|
t.mapping type: nil
t.json_schema type: "null"
end

schema.object_type "Widget" do |t|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module Resolvers
self.schema_artifacts = generate_schema_artifacts do |schema|
schema.scalar_type "MyInt" do |t|
t.mapping type: "integer"
t.json_schema type: "integer"
end

schema.object_type "PersonIdentifiers" do |t|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ module ScalarCoercionAdapters
RSpec.describe "NoOp" do
include_context("scalar coercion adapter support", "SomeCustomScalar", schema_definition: ->(schema) do
schema.scalar_type "SomeCustomScalar" do |t|
t.json_schema type: "null"
t.mapping type: nil
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,6 @@ def search_index_definitions_from(type_name: "TheType")
schema = define_schema do |s|
s.scalar_type "CustomScalar" do |t|
t.mapping type: "keyword"
t.json_schema type: "string"
end
end

Expand All @@ -967,7 +966,6 @@ def search_index_definitions_from(type_name: "TheType")
schema = define_schema do |s|
s.scalar_type "CustomScalar" do |t|
t.mapping type: "keyword"
t.json_schema type: "string"
t.grouping_missing_value_placeholder "MISSING"
end
end
Expand All @@ -980,7 +978,6 @@ def search_index_definitions_from(type_name: "TheType")
schema = define_schema do |s|
s.scalar_type "CustomScalar" do |t|
t.mapping type: "keyword"
t.json_schema type: "string"
t.grouping_missing_value_placeholder nil
end
end
Expand All @@ -1007,7 +1004,6 @@ def search_index_definitions_from(type_name: "TheType")
t.field "name", "String"
t.field "count", "Int"
t.field "price", "Float"
t.field "big_number", "JsonSafeLong"
t.index "things"
end
end
Expand All @@ -1016,7 +1012,6 @@ def search_index_definitions_from(type_name: "TheType")
expect(schema.type_named("String").grouping_missing_value_placeholder).to eq MISSING_STRING_PLACEHOLDER_VALUE
expect(schema.type_named("Int").grouping_missing_value_placeholder).to eq MISSING_NUMERIC_PLACEHOLDER
expect(schema.type_named("Float").grouping_missing_value_placeholder).to eq MISSING_NUMERIC_PLACEHOLDER
expect(schema.type_named("JsonSafeLong").grouping_missing_value_placeholder).to eq MISSING_NUMERIC_PLACEHOLDER
end

it "returns nil for object types" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class GraphQL
define_schema do |schema|
schema.scalar_type "_FieldSet" do |t|
t.mapping type: "keyword"
t.json_schema type: "string"
end

schema.object_type "Widget" do |t|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ def build_health_checker(health_check:, latest: {}, index_definitions: nil, sche
clients_by_name: datastore_clients_by_name,
clock: class_double(::Time, now: now),
schema_definition: schema_definition,
schema_definition_extension_modules: [],
index_definitions: index_definitions,
extension_settings: {"health_check" => health_check_settings}.compact
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def process(http_method, url, with_configured_path_segment:, body: nil, cluster_

def build_graphql_for_path(http_path_segment)
config = {http_path_segment: http_path_segment}.compact
schema_artifacts = generate_schema_artifacts do |schema|
schema_artifacts = generate_schema_artifacts(extension_modules: []) do |schema|
schema.register_graphql_extension(EnvoyExtension, defined_at: "elastic_graph/health_check/envoy_extension", **config)
schema.object_type "Widget" do |t|
t.field "id", "ID"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#
# frozen_string_literal: true

require "elastic_graph/json_ingestion/schema_definition/api_extension"
require "elastic_graph/spec_support/schema_definition_helpers"

module ElasticGraph
Expand All @@ -15,7 +16,12 @@ class Indexer

def build_indexer_with_multiple_schema_versions(schema_versions:)
results_by_version = schema_versions.to_h do |json_schema_version, prior_def|
results = define_schema(schema_element_name_form: :snake_case, json_schema_version: json_schema_version, &prior_def)
results = define_schema(
schema_element_name_form: :snake_case,
json_schema_version: json_schema_version,
extension_modules: [JSONIngestion::SchemaDefinition::APIExtension],
&prior_def
)
[json_schema_version, results]
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# frozen_string_literal: true

require "elastic_graph/indexer/record_preparer"
require "elastic_graph/json_ingestion/schema_definition/api_extension"
require "elastic_graph/spec_support/schema_definition_helpers"
require "support/multiple_version_support"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2024 - 2026 Block, Inc.
#
# Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.
#
# frozen_string_literal: true

require "elastic_graph/json_ingestion/schema_definition/api_extension"
require "elastic_graph/spec_support/schema_definition_helpers"

# Extends the shared "SchemaDefinitionHelpers" context to automatically apply this gem's
# `APIExtension` to every defined schema, since every spec in this gem exercises behavior
# provided by that extension. Additional extension modules can still be passed via
# `extension_modules:` and will be applied alongside it.
::RSpec.shared_context "JSONIngestionSchemaDefinitionHelpers" do
include_context "SchemaDefinitionHelpers"

def define_schema_with_schema_elements(schema_elements, extension_modules: [], output: nil, **options, &block)
super(
schema_elements,
extension_modules: [::ElasticGraph::JSONIngestion::SchemaDefinition::APIExtension] | extension_modules,
output: output || log_device,
**options,
&block
)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
# frozen_string_literal: true

require "elastic_graph/json_ingestion/schema_definition/indexing/json_schema_with_metadata"
require "elastic_graph/spec_support/schema_definition_helpers"
require "support/json_ingestion_schema_definition_helpers"

module ElasticGraph
module JSONIngestion::SchemaDefinition
module Indexing
::RSpec.describe JSONSchemaWithMetadata do
include_context "SchemaDefinitionHelpers"
include_context "JSONIngestionSchemaDefinitionHelpers"

it "ignores derived indexed types that do not show up in the JSON schema" do
v1_json_schema = dump_versioned_json_schema do |schema|
Expand Down Expand Up @@ -1056,7 +1056,6 @@ def metadata_for(json_schema, type, field)
def define_schema(&schema_definition)
super(
schema_element_name_form: "snake_case",
extension_modules: [APIExtension],
&schema_definition
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
require "elastic_graph/json_ingestion/schema_definition/indexing/field"
require "elastic_graph/json_ingestion/schema_definition/indexing/field_reference"
require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/object"
require "elastic_graph/spec_support/schema_definition_helpers"
require "support/json_ingestion_schema_definition_helpers"
require "support/json_schema_matcher"

module ElasticGraph
module JSONIngestion::SchemaDefinition
::RSpec.describe "JSON schema indexing wrappers" do
include_context "SchemaDefinitionHelpers"
include_context "JSONIngestionSchemaDefinitionHelpers"

# `FieldReference#resolve` is a lazy reference: the referenced type need not exist when a field is
# defined, only when artifacts are dumped. These two specs drive both outcomes (resolves / never
Expand Down Expand Up @@ -45,7 +45,11 @@ module JSONIngestion::SchemaDefinition
})
end

it "raises a clear error (rather than blowing up internally) for a field whose type never resolves" do
# `:dont_validate_graphql_schema` matters here: with `VALIDATE_GRAPHQL_SCHEMAS=1` (as on CI), the
# eager SDL validation would raise this error during GraphQL schema generation, before the JSON
# schema generation path exercises the wrapped `FieldReference#resolve` nil return that this
# example exists to cover.
it "raises a clear error (rather than blowing up internally) for a field whose type never resolves", :dont_validate_graphql_schema do
# When a field references a type that is never defined, the wrapped `FieldReference#resolve`
# returns `nil`. The schema definition machinery relies on that `nil` to detect the unresolvable
# type and surface a helpful error instead of crashing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
# frozen_string_literal: true

require "elastic_graph/json_ingestion/schema_definition/indexing/json_schema_field_metadata"
require "elastic_graph/spec_support/schema_definition_helpers"
require "support/json_ingestion_schema_definition_helpers"

module ElasticGraph
module JSONIngestion::SchemaDefinition
::RSpec.describe "JSON schema field metadata generation" do
include_context "SchemaDefinitionHelpers"
include_context "JSONIngestionSchemaDefinitionHelpers"

it "generates no field metadata for built-in scalar and enum types" do
metadata_by_type_and_field_name = dump_metadata
Expand Down Expand Up @@ -143,7 +143,6 @@ def dump_metadata(&schema_definition)
def define_schema(&schema_definition)
super(
schema_element_name_form: "snake_case",
extension_modules: [APIExtension],
&schema_definition
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

require "elastic_graph/constants"
require "elastic_graph/json_ingestion/schema_definition/json_schema_pruner"
require "elastic_graph/spec_support/schema_definition_helpers"
require "support/json_ingestion_schema_definition_helpers"

module ElasticGraph
module JSONIngestion::SchemaDefinition
RSpec.describe JSONSchemaPruner do
include_context "SchemaDefinitionHelpers"
include_context "JSONIngestionSchemaDefinitionHelpers"

describe ".prune" do
subject { described_class.prune(schema) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@

require "elastic_graph/constants"
require "elastic_graph/errors"
require "elastic_graph/json_ingestion/schema_definition/api_extension"
require "elastic_graph/spec_support/schema_definition_helpers"
require "support/json_ingestion_schema_definition_helpers"
require "support/json_schema_matcher"

module ElasticGraph
module JSONIngestion::SchemaDefinition
::RSpec.describe "JSON schema generation" do
include_context "SchemaDefinitionHelpers"
include_context "JSONIngestionSchemaDefinitionHelpers"
json_schema_id = {"allOf" => [{"$ref" => "#/$defs/ID"}, {"maxLength" => DEFAULT_MAX_KEYWORD_LENGTH}]}
json_schema_float = {"$ref" => "#/$defs/Float"}
json_schema_integer = {"$ref" => "#/$defs/Int"}
Expand Down Expand Up @@ -113,10 +112,7 @@ module JSONIngestion::SchemaDefinition
it "configures built-in scalar JSON schema before user schema blocks are evaluated" do
json_schema_options_in_schema_block = nil

define_schema(
schema_element_name_form: "snake_case",
extension_modules: [JSONIngestion::SchemaDefinition::APIExtension]
) do |s|
define_schema(schema_element_name_form: "snake_case") do |s|
json_schema_options_in_schema_block = s.state.scalar_types_by_name.fetch("String").json_schema_options.dup

s.object_type "Widget" do |t|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@

require "elastic_graph/constants"
require "elastic_graph/errors"
require "elastic_graph/json_ingestion/schema_definition/api_extension"
require "elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension"
require "elastic_graph/spec_support/schema_definition_helpers"
require "support/json_ingestion_schema_definition_helpers"

module ElasticGraph
module JSONIngestion
module SchemaDefinition
module SchemaElements
RSpec.describe ScalarTypeExtension do
include_context "SchemaDefinitionHelpers"
include_context "JSONIngestionSchemaDefinitionHelpers"

it "requires custom scalar types to declare their JSON schema representation" do
expect {
Expand Down
Loading
Loading