jsonapi-rb / jsonapi-rspec

RSpec matchers for JSON:API spec
https://rubygems.org/gems/jsonapi-rspec
MIT License
123 stars 24 forks source link

Inconsistentcy, have_jsonapi_attributes should not allow symbols #17

Closed nattfodd closed 4 years ago

nattfodd commented 4 years ago

FastJsonapi serializer returns keys as symbols with MySerializer.new(data).serializable_hash, including :attributes. It's pretty unobvious that you can say expect(data).to have_jsonapi_attributes(:foo, :bar) but your data object should be { 'attributes' => { foo: 1, bar: 2 } } with "attribute" key being precisely a string.

https://github.com/jsonapi-rb/jsonapi-rspec/blob/c68657cbe786c026dfb60162d32a7486c442eb53/lib/jsonapi/rspec/attributes.rb#L18

stas commented 4 years ago

@nattfodd thanks for reporting this... but could you please explain or provide an example what exactly is the problem here? I'm not sure I understand where's the inconsistency?

Are you trying to say that have_jsonapi_attributes allows symbols and the other matchers do not?!

nattfodd commented 4 years ago

Here is an example:

class ProductSerializer
  include FastJsonapi::ObjectSerializer

  attributes :title, :price
end

describe ProductSerializer do
  let(:product) { FactoryBot.create(:product) }

  it 'has title & price attributes' do
    data = ProductSerializer.new(product).serializable_json[:data]
    expect(data).to have_jsonapi_attributes(:title, :price) # fails
    expect(data.with_indifferent_access).to have_jsonapi_attributes(:title, :price) # works
    expect(data).to have_jsonapi_attributes('title', 'price') # also works
  end
end

The first expectation expect(data).to have_jsonapi_attributes(:title, :price) is basically taken from README. FastJsonapi::ObjectSerializer returns data with keys as symbols as well. While the have_jsonapi_attributes matcher expects them to be strings.

stas commented 4 years ago

Thanks @nattfodd, makes sense now. Patches welcome btw :upside_down_face:

stas commented 4 years ago

@nattfodd please give the latest version a test, there's a new option to configure the matchers to be indifferent to symbols/strings.

stas commented 4 years ago

@nattfodd I'm closing this as part of 56226ed

Since the JSON:API requires a valid JSON document which means string keys, the marchers will always try to do the conversion where spec enforces it: https://github.com/jsonapi-rb/jsonapi-rspec#on-matcher-arguments