# frozen_string_literal: true RSpec::Matchers.define :require_graphql_authorizations do |*expected| match do |klass| permissions = if klass.respond_to?(:required_permissions) klass.required_permissions else [klass.to_graphql.metadata[:authorize]] end expect(permissions).to eq(expected) end end RSpec::Matchers.define :have_graphql_fields do |*expected| def expected_field_names Array.wrap(expected).map { |name| GraphqlHelpers.fieldnamerize(name) } end @allow_extra = false chain :only do @allow_extra = false end chain :at_least do @allow_extra = true end match do |kls| if @allow_extra expect(kls.fields.keys).to include(*expected_field_names) else expect(kls.fields.keys).to contain_exactly(*expected_field_names) end end failure_message do |kls| missing = expected_field_names - kls.fields.keys extra = kls.fields.keys - expected_field_names message = [] message << "is missing fields: <#{missing.inspect}>" if missing.any? message << "contained unexpected fields: <#{extra.inspect}>" if extra.any? && !@allow_extra message.join("\n") end end RSpec::Matchers.define :include_graphql_fields do |*expected| expected_field_names = expected.map { |name| GraphqlHelpers.fieldnamerize(name) } match do |kls| expect(kls.fields.keys).to include(*expected_field_names) end failure_message do |kls| missing = expected_field_names - kls.fields.keys "is missing fields: <#{missing.inspect}>" if missing.any? end end RSpec::Matchers.define :have_graphql_field do |field_name, args = {}| match do |kls| field = kls.fields[GraphqlHelpers.fieldnamerize(field_name)] expect(field).to be_present args.each do |argument, value| expect(field.send(argument)).to eq(value) end end end RSpec::Matchers.define :have_graphql_mutation do |mutation_class| match do |mutation_type| field = mutation_type.fields[GraphqlHelpers.fieldnamerize(mutation_class.graphql_name)] expect(field).to be_present expect(field.resolver).to eq(mutation_class) end end # note: connection arguments do not have to be named, they will be inferred. RSpec::Matchers.define :have_graphql_arguments do |*expected| include GraphqlHelpers def expected_names(field) @names ||= Array.wrap(expected).map { |name| GraphqlHelpers.fieldnamerize(name) } if field.type.try(:ancestors)&.include?(GraphQL::Types::Relay::BaseConnection) @names | %w(after before first last) else @names end end match do |field| names = expected_names(field) expect(field.arguments.keys).to contain_exactly(*names) end failure_message do |field| names = expected_names(field) "expected that #{field.name} would have the following fields: #{names.inspect}, but it has #{field.arguments.keys.inspect}." end end RSpec::Matchers.define :have_graphql_type do |expected| match do |field| expect(field.type).to eq(expected) end end RSpec::Matchers.define :have_non_null_graphql_type do |expected| match do |field| expect(field.type.to_graphql).to eq(!expected.to_graphql) end end RSpec::Matchers.define :have_graphql_resolver do |expected| match do |field| case expected when Method expect(field.to_graphql.metadata[:type_class].resolve_proc).to eq(expected) else expect(field.to_graphql.metadata[:type_class].resolver).to eq(expected) end end end RSpec::Matchers.define :have_graphql_extension do |expected| match do |field| expect(field.to_graphql.metadata[:type_class].extensions).to include(expected) end end RSpec::Matchers.define :expose_permissions_using do |expected| match do |type| permission_field = type.fields['userPermissions'] expect(permission_field).not_to be_nil expect(permission_field.type).to be_non_null expect(permission_field.type.of_type.graphql_name).to eq(expected.graphql_name) end end