0

I'm interviewing for a front-end developer job and have been given a coding test to build a simple front-end interface. I've been given the server, which has been written in Ruby (2.1.3) and has 3 endpoints which I am to make use of in my front-end client. I have no experience whatsoever with Ruby but I followed their instructions for setting up the server and it seems to work - I get responses from all the endpoints. The problem is that I'm not getting any response from my client app, which is in a different "domain" (actually, they're both just different ports of localhost). It seems that they are not setting the "Access-Control-Allow-Origin" headers on the API, but I don't want to go back to them asking how to fix this because I'm afraid it will reflect poorly on my test.

Below is the server file structure and I've also included the contents of a few files which seem to be relevant. If anyone wants to see other files, please just comment. I'm sure this is simple for anyone who knows Ruby but I haven't the foggiest clue.

D:.
¦   .gitkeep
¦   client.rb
¦   config.ru
¦   foo.sqlite3
¦   Gemfile
¦   Gemfile.lock
¦   Rakefile
¦   README.md
¦
+---app
¦   +---controllers
¦   ¦       api_controller.rb
¦   ¦       application_controller.rb
¦   ¦       not_found_controller.rb
¦   ¦       payments_controller.rb
¦   ¦
¦   +---models
¦   ¦       payment.rb
¦   ¦
¦   +---views
¦           booking.html
¦           confirmation.html
¦
+---config
¦       boot.rb
¦       dispatcher.rb
¦
+---db
¦   ¦   schema.rb
¦   ¦   seeds.rb
¦   ¦
¦   +---migrate
¦           20150331094122_create_payments.rb
¦
+---lib
¦       my_application.rb
¦
+---log
¦       development.log
¦       test.log
¦
+---public
¦   ¦   404.html
¦   ¦   500.html
¦   ¦
¦   +---css
¦           style.css
¦
+---script
¦       console
¦       server
¦
+---spec
¦   ¦   spec_helper.rb
¦   ¦
¦   +---acceptance
¦   ¦       api_endpoint_spec.rb
¦   ¦       not_found_spec.rb
¦   ¦
¦   +---models
¦           payment_spec.rb
¦
+---vendor
    +---libs
            foobar_goodies

boot.rb

ENV['RACK_ENV'] ||= 'development'

# Bundler
require 'bundler/setup'
Bundler.require :default, ENV['RACK_ENV'].to_sym

require_relative '../lib/my_application.rb'

root_path = MyApplication.root
lib_path = File.join(MyApplication.root, 'lib')
app_path = File.join(MyApplication.root, 'app')
[root_path, lib_path, app_path].each { |path| $LOAD_PATH.unshift(path) }

ENV['PEERTRANSFER_ROOT'] = root_path

require 'config/dispatcher'
require 'sinatra/activerecord'

set :database, { adapter: "sqlite3", database: "foo.sqlite3" }

require 'app/models/payment'

my_application.rb

module MyApplication
  class << self
    def root
      File.dirname(__FILE__) + '/..'
    end

    def views_path
      root + '/app/views'
    end

    def public_folder
      root + '/public'
    end
  end
end

dispatcher.rb

require 'controllers/application_controller'
require 'controllers/not_found_controller'

require 'controllers/api_controller'
require 'controllers/payments_controller'

module MyApplication
  class Dispatcher
    def call(env)
      path_info = env['PATH_INFO']

      app = case path_info
        when %r{^/api} then ApiController.new
        when %r{^/payment} then PaymentsController.new
        else NotFoundController.new
      end

      app.call(env)
    end
  end
end

application_controller.rb

class ApplicationController < Sinatra::Base
  set :views, MyApplication.views_path
  set :public_folder, MyApplication.public_folder

  not_found do
    html_path = File.join(settings.public_folder, '404.html')
    File.read(html_path)
  end

  error do
    raise request.env['sinatra.error'] if self.class.test?

    File.read(File.join(settings.public_folder, '500.html'))
  end
end

api_endpoint_spec.rb

require 'spec_helper'
require 'models/payment'

describe 'API Endpoint' do
  it 'responds with a JSON welcoming message' do
    get '/api'

    expect(last_response.status).to eq(200)
    expect(last_response.body).to eq('{"message":"Hello Developer"}')
  end

  it 'returns all the stored payments' do
    Payment.all.map(&:delete)
    Payment.new(reference: 'any reference', amount: 10000).save

    get '/api/bookings'

    expect(last_response.status).to eq(200)
    expect(last_response.body).to eq("{\"bookings\":[{\"reference\":\"any reference\",\"amount\":10000,\"country_from\":null,\"sender_full_name\":null,\"sender_address\":null,\"school\":null,\"currency_from\":null,\"student_id\":null,\"email\":null}]}")
  end

  def app
    MyApplication::Dispatcher.new
  end
end
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
T Nguyen
  • 3,309
  • 2
  • 31
  • 48
  • 1
    As I mentioned, I'm not a Ruby developer at all. I did search SO regarding Ruby but none of the responses made any sense to me. Even the question you linked to makes no sense to me, not to mention that it seems to be about Sinatra which also means nothing to me. I need it spelled out for me, what command needs to go in what file in what line. If you don't want to help, no one is forcing you, but there's no reason to be condescending and rude. – T Nguyen Feb 25 '17 at 10:33

1 Answers1

2

Sinatra is a simple and lightweight web server. The general idea is that you write response routes like this:

get '/api' do
 "Hello world"
end

When you make a HTTP GET request to yoursite.com/api you will get a "Hello world" as response.

Now to add the header you want, this should do the trick:

get '/api' do
  response['Access-Control-Allow-Origin'] = '*'
  "Hello world"
end
Esa Mäkinen
  • 160
  • 8