Updates from July, 2021 Toggle Comment Threads | Keyboard Shortcuts

  • ThomasPowell 7:34 am on July 13, 2021 Permalink | Reply
    Tags: factory_bot, factory_girl, , , , trait   

    Referencing one trait from another trait in factory_bot 

    Sometimes you want to DRY up traits by referencing one trait from another trait in factory_bot. I tried searching on “inheriting traits” (that’s just for one factory inheriting traits from another and was in a factory_bot issue in GitHub). I accidentally stumbled upon the answer in a slightly unrelated StackOverflow question about calling a trait from another trait with params in factory_girl.

    Ultimately, you use the trait name from the first trait as a method invocation in the referencing trait:

    FactoryBot.define do
      factory :user do
        role
        trait :with_supervisor do
          # complex set up might go
          # here
          after(:create) do |user|
            supervisor { create(:user) }
          end
        end
        trait :with_organization do
          with_supervisor # invoke the other trait first
          organization
        end
      end
    end
    
     
  • ThomasPowell 8:48 pm on July 6, 2021 Permalink | Reply
    Tags: ,   

    RAW_POST_DATA in rspec rails for Rails 5.2 and beyond 

    The last time I was trying to specify RAW_POST_DATA in rspec was probably Rails 3 or 4, but I ran into a situation trying to test an edge case for error handling where I wanted that same functionality. I quickly found this issue [Unable to POST raw request body], but didn’t immediately figure out what wasn’t being set correctly.

    In this case the test setup I was using was setting multipart/form-data instead of application/xml on the content types:

    {:HTTP_ACCEPT=>"application/xml", :HTTP_CONTENT_TYPE=>"multipart/form-data", :CONTENT_TYPE=>"multipart/form-data"}
    

    Because of this, the Rails controller tests that rspec hooks into was trying to break following malformed xml down to parameters:

                <test>
                  <data&nbsp;
                  <![CDATA[THIS|IS|SENSITIVE|BUT|MALFORMED]]>
                  </data>
                </test>
    
     Minitest::Assertion:
       Expected response to be a <400: bad_request>, but was a <422: Unprocessable Entity>
       Response body: <errors>
           <error>["<test>\n  <data", "nbsp;\n  <!"] are not permitted parameters</error>
       </errors>
    

    I finally noticed that the mime-type might be involved. In this code, Content-Type was also an issue, so:

    • Removed HTTP_CONTENT_TYPE from the headers
    • Set CONTENT_TYPE header to 'application/xml' instead of 'multipart/form-data' to prevent automatic params parsing in this case.
    • Passed as: :xml into the test to get the 'mime-type' correct.

    Ultimately, if your code hasn’t boxed you in, then the as: :xml and passing raw data as a parameter should work:

    post things_path, params: raw_xml_data, headers: non_form_data_headers, as: :xml
    
    ## replacement for the following:
    # @request.env['RAW_POST_DATA'] = raw_xml_data
    # post things_path
    
     
  • ThomasPowell 9:18 pm on July 5, 2021 Permalink | Reply
    Tags: , , tr, translate   

    String#tr in ruby (like tr in Linux) complete with figuring out slashes. 

    It seems like I’ve seen quite a few programming puzzles in the last few weeks that involved translating mistyped input in which the hands were shifted (right) on the keyboard. My first thought was the tr utility in *nix operating systems, but didn’t immediately go looking for or notice that ruby has a tr method on string. However, after doing a trivial implementation involving keyboard rows like the following, I stumbled on the tr method.

      # initial array of characters/strings to shift back to the left with [index-1]
      KEYBOARD_ROWS= [
        '`1234567890-=',
        'qwertyuiop[]\\', # need to escape the backslash or else debugging pain
        "asdfghjkl;'", # double-quotes here because single quote embedded
        'zxcvbnm,./',
        '[email protected]#\$%^&*()_+',
        'QWERTYUIOP{}|',
        'ASDFGHJKL:"',
        'ZXCVBNM<>?'
      ].join
    

    Attempting to rewrite this for .tr presented a few challenges, however. If you are substituting for \, -, or ~, you have to escape the characters. You also have to escape them from their string representation, which makes for some head-spinning levels of escaping (zsh users who run shell commands through kubectl might be familiar with this pain as well):

    # puts '\\~-'.tr('\\', 'a') # doesn't match because \ is passed to tr and not escaped
    a~-
    # puts '\\~-'.tr('\\\\', 'a') # now \\ is passed to tr, which is
    a~-
    # puts '\\~-'.tr("\\\\\\", 'a') # with double quotes, you need an extra pair, for 6 total.
    a~-
    # puts '\\~-'.tr('\\~', 'b') # the escaping backslash needs to be doubled
    \b-
    # puts '\\~-'.tr("\\\~", 'b') # the escaping backslash needs to be tripled
    \b-
    # puts '\\~-'.tr('\\-', 'c') # the escaping backslash needs to be doubled
    \~c
    # puts '\\~-'.tr("\\\-", 'c') # the escaping backslash needs to be tripled
    \~c
    

    So if you’re going to use translate to “shift” hands back to the left, the two arguments to tr, SHIFTED_KEYBOARD_ROWS and UNSHIFTED_KEYBOARD_ROWS would have to be defined with the following escaping:

      SHIFTED_KEYBOARD_ROWS =
        [
          '1234567890\\-=',
          'wertyuiop[]\\\\', # 4x backslash = backslash
          "sdfghjkl;'",
          'xcvbnm,./',
          '[email protected]#\$%\^&*()_+',
          'WERTYUIOP{}|',
          'SDFGHJKL:"',
          'XCVBNM<>?'
      ].join
    
      UNSHIFTED_KEYBOARD_ROWS= [
        '`1234567890\-',
        'qwertyuiop[]', # need to escape the backslash or else debugging pain
        'asdfghjkl;',
        'zxcvbnm,.',
        '[email protected]#\$%\^&*()_',
        'QWERTYUIOP{}',
        'ASDFGHJKL:',
        'ZXCVBNM<>?'
      ].join
    
      def self.translate(string)
        string.tr(SHIFTED_KEYBOARD_ROWS, UNSHIFTED_KEYBOARD_ROWS)
      end
    
     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
%d bloggers like this: