# Testing CORS Headers With RSpec and Rack in Rails

I’ve not found any blog post or article about how to easily test CORS support implemented in a Rack middleware (e.g. using the rack-cors gem) with RSpec in Rails. So, after figured out I decided to write some small tips I learned from it.

I assume you have a fairly updated Rails app, I tested it with Rails 4.2.x, with RSpec tests support, and you want to add support for CORS headers.

## Install rack-cors gem

it’s better to follow the gem instructions (you’ll find the most updated instructions there) than a blog post, but anyway here’s how I did it:

Add this to your Gemfile:

Add this to your config/application.rb:

These are the common options, tune it to your needs. Here we’re allowing requests from any domain for the get, post, patch and options methods. options is a special method used for preflight requests.

That’s it. CORS is now active in this Rails app. Every time we send a request with the CORS headers, we’ll receive the CORS response headers.

## How to test it with cURL

With cURL, it’s easy to test CORS. Let’s see the most common scenarios:

#### Sending the Origin header:

• -H: Header to include in the request.
• -I: Fetch the HTTP header only.

We should receive: Access-Control-Allow-Origin: *.

#### Sending the preflight options method:

Send a options request with Origin: *, Access-Control-Request-Method: get and Access-Control-Request-Headers: test. * -X: Specifies a custom request method

We should receive Access-Control-Allow-Origin: *, Access-Control-Allow-Methods: get, post, patch, options, and Access-Control-Allow-Headers: test.

## How to test it with RSpec

Support CORS is a bit tricky to test with RSpec, because we don’t have a real server (like Webrick, Unicorn or Puma) between the code and the client. This usually is not a problem but it does affect in this particular case, and the rfc3875 explains why. The server translate the custom HTTP request headers in this way:

• Convert to upper case.
• Replace - with _
• Prepend HTTP_.

Because we don’t have the server to do it for us, we must do it manually. For example, the Origin becomes HTTP_ORIGIN and Http-Access-Control-Request-Method becomes HTTP_ACCESS_CONTROL_REQUEST_METHOD. Let’s see some example tests:

#### Sending the preflight options method:

Note: You must use integration tests to be able the test through rack. A controller test doesn’t trigger rack, it’s like an unit test for the controller.

Don’t forget to uppercase, replace - and prepend HTTP_ to all your custom HTTP headers when testing!