skryukov / skooma

Skooma is a Ruby library for validating API implementations against OpenAPI documents.
MIT License
140 stars 5 forks source link

JSONSkooma::Error: Cannot get key db from String in #25

Closed ursm closed 5 months ago

ursm commented 5 months ago

Hello,

I recently updated skooma to 0.3.1 (0.3.0 did the same) and now my tests that POST in multipart/form-data are failing.

  1) validate via file happy case
     Failure/Error: expect(response).to conform_schema(201)

     JSONSkooma::Error:
       Cannot get key db from String in 
     # /home/ursm/.local/share/mise/installs/ruby/3.3.0/lib/ruby/3.3.0/delegate.rb:89:in `bind_call'
     # /home/ursm/.local/share/mise/installs/ruby/3.3.0/lib/ruby/3.3.0/delegate.rb:89:in `method_missing'
     # /home/ursm/.local/share/mise/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/json_skooma-0.2.3/lib/json_skooma/json_node.rb:30:in `[]'
     # /home/ursm/.local/share/mise/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/skooma-0.3.0/lib/skooma/keywords/oas_3_1/dialect/discriminator.rb:14:in `evaluate'
     # /home/ursm/.local/share/mise/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/json_skooma-0.2.3/lib/json_skooma/json_schema.rb:41:in `block (2 levels) in evaluate'
(snip)

The schema uses a property called db as discriminator, but skooma does not seem to have access to it. https://github.com/ddbj/ddbj-repository/blob/ac23cbb67979c946024a4d2448b1342f465d6c59/schema/openapi.yml#L1378

In this situation, I checked the __getobj__ of JSONSkooma::JSONNode and it contains the multipart/form-data body as a string before parsing.

"------------XnJLe9ZIbbGUYtzPQJ16u1\r\ncontent-disposition: form-data; name=\"db\"\r\n\r\nMetaboBank\r\n------------XnJLe9ZIbbGUYtzPQJ16u1\r\ncontent-disposition: form-data; name=\"IDF[file]\"; filename=\"myidf.txt\"\r\ncontent-type: text/plain\r\ncontent-length: 0\r\n\r\n\r\n------------XnJLe9ZIbbGUYtzPQJ16u1\r\ncontent-disposition: form-data; name=\"SDRF[file]\"; filename=\"mysdrf.txt\"\r\ncontent-type: text/plain\r\ncontent-length: 0\r\n\r\n\r\n------------XnJLe9ZIbbGUYtzPQJ16u1\r\ncontent-disposition: form-data; name=\"RawDataFile[path]\"\r\n\r\nfoo\r\n------------XnJLe9ZIbbGUYtzPQJ16u1\r\ncontent-disposition: form-data; name=\"ProcessedDataFile[path]\"\r\n\r\nfoo\r\n------------XnJLe9ZIbbGUYtzPQJ16u1\r\ncontent-disposition: form-data; name=\"ProcessedDataFile[destination]\"\r\n\r\ndest\r\n------------XnJLe9ZIbbGUYtzPQJ16u1--\r\n"

If you can tell me if I am missing something, I would appreciate it. Thanks.

EDIT:

I tried specifying the Content-Type as follows, but there was no change.

    post '/api/validations/via-file', params: {
      db:   'MetaboBank',
      IDF:  {file: file_fixture_upload('metabobank/valid/MTBKS231.idf.txt')},
      SDRF: {file: file_fixture_upload('metabobank/valid/MTBKS231.sdrf.txt')}
    }, headers: {
      'Content-Type' => 'multipart/form-data'
    }
skryukov commented 5 months ago

Hey, @ursm, thanks for the issue!

Skooma comes with only application/json parser out of the box, to parse multipart/form-data (or xml, etc) we need to register a new parser. You can find an example multipart/form-data parser in this comment: https://github.com/skryukov/skooma/issues/16#issuecomment-2044271205 The bad news is that I tried it on ddbj/api and test failed 😅

ursm commented 5 months ago

Hey, @skryukov, thanks for the reply.

I see, I understand it well. I was able to make skooma recognize the parsed body with the code you gave me. I think the rest of the errors are a problem with my schema, so I will try and work on it. Thanks again for letting me know and for trying to run the test!