From 6cc28e06a645e3e37a79077b1866ca7dca270ecf Mon Sep 17 00:00:00 2001 From: artemave Date: Thu, 23 Jun 2011 16:22:51 +0100 Subject: [PATCH] initial commit --- .gitignore | 4 ++ Gemfile | 4 ++ Rakefile | 10 ++++ cucumber.yml | 3 + db/migrate/20110620161740_add_fixtures.rb | 13 ++++ fake_rest_services.gemspec | 31 ++++++++++ fake_rest_services.rb | 59 +++++++++++++++++++ features/fixtures_via_api.feature | 33 +++++++++++ .../fixtures_via_api_steps.rb | 23 ++++++++ features/support/env.rb | 14 +++++ lib/models/fixture.rb | 29 +++++++++ 11 files changed, 223 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Rakefile create mode 100644 cucumber.yml create mode 100644 db/migrate/20110620161740_add_fixtures.rb create mode 100644 fake_rest_services.gemspec create mode 100755 fake_rest_services.rb create mode 100644 features/fixtures_via_api.feature create mode 100644 features/step_definitions/fixtures_via_api_steps.rb create mode 100644 features/support/env.rb create mode 100644 lib/models/fixture.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4040c6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.gem +.bundle +Gemfile.lock +pkg/* diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..d64b831 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source "http://rubygems.org" + +# Specify your gem's dependencies in fake_rest_services.gemspec +gemspec diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..1f865c4 --- /dev/null +++ b/Rakefile @@ -0,0 +1,10 @@ +require 'fake_rest_services' +require 'rake' +require 'sinatra/activerecord/rake' + +require 'bundler' +Bundler::GemHelper.install_tasks + +task :install do + Rake['db:migrate'].invoke +end diff --git a/cucumber.yml b/cucumber.yml new file mode 100644 index 0000000..0072875 --- /dev/null +++ b/cucumber.yml @@ -0,0 +1,3 @@ +default: --tags ~@long +long: --tags @long +wip: --tags @wip diff --git a/db/migrate/20110620161740_add_fixtures.rb b/db/migrate/20110620161740_add_fixtures.rb new file mode 100644 index 0000000..893398e --- /dev/null +++ b/db/migrate/20110620161740_add_fixtures.rb @@ -0,0 +1,13 @@ +class AddFixtures < ActiveRecord::Migration + def self.up + create_table :fixtures do |t| + t.string :url + t.text :content + end + + end + + def self.down + drop_table :fixtures + end +end diff --git a/fake_rest_services.gemspec b/fake_rest_services.gemspec new file mode 100644 index 0000000..52502be --- /dev/null +++ b/fake_rest_services.gemspec @@ -0,0 +1,31 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) + +Gem::Specification.new do |s| + s.name = "fake_rest_services" + s.version = '0.1' + s.platform = Gem::Platform::RUBY + s.authors = ['Artem Avetisyan', 'Jamal Natour'] + s.email = ['artem.avetisyan@bbc.co.uk', 'jamal.natour@bbc.co.uk'] + s.homepage = "https://github.com/artemave/fake_rest_services" + s.summary = %q{Sinatra webapp that allows mocking GET to any path with arbitrary content} + s.description = %q{TODO: Write a gem description} + + s.rubyforge_project = "fake_rest_services" + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + #s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.executables = ['fake_rest_services.rb'] + s.require_paths = ["."] + + s.add_development_dependency 'cucumber' + s.add_development_dependency 'rspec' + s.add_development_dependency 'rack-test' + s.add_dependency 'sinatra' + s.add_dependency 'thin' + s.add_dependency 'activerecord', '~> 3.0.0' + s.add_dependency 'sinatra-activerecord' + s.add_dependency 'sqlite3' + s.add_dependency 'rake' +end diff --git a/fake_rest_services.rb b/fake_rest_services.rb new file mode 100755 index 0000000..80dfee6 --- /dev/null +++ b/fake_rest_services.rb @@ -0,0 +1,59 @@ +#!/usr/bin/env ruby + +require 'bundler/setup' +require 'sinatra' +require 'sinatra/activerecord' + +ActiveRecord::Base.establish_connection( + adapter: "sqlite3", + database: File.expand_path('../production.db', __FILE__) +) + +require 'models/fixture' + +#get '/dsp/assets/search' do + #team = lookup_team_name params['concept'] + + #case params['story-type'] + #when 'news-story' + ## footballTeams.serviceCalls.teamStories[1] + ## https://api.live.bbc.co.uk/dsp/assets/search?concept=http://www.bbc.co.uk/things/c4285a9a-9865-2343-af3a-8653f7b70734%23id&format=story&story-type=news-story&tagging-type=about&limit=11 + #File.read("#{responses_path}/#{team}/team_stories.json") + ##FakeResponse.lookup('teamStories[1]', concept: params['concept']) + #when 'feature' + ## footballTeams.serviceCalls.teamCommentAnalysis[1] + ## https://api.live.bbc.co.uk/dsp/assets/search?concept=http://www.bbc.co.uk/things/c4285a9a-9865-2343-af3a-8653f7b70734%23id&format=blog&story-type=blog-post&format=story&story-type=feature&tagging-type=about&limit=20 + #File.read("#{responses_path}/#{team}/team_comment_analysis.json") + #else + #puts "wrong call to /dsp/assets/search: params: #{params.inspect}" + #end +#end + +#get %r{/sportsdata/statsapi/football/teamstats/team/(\d+)/clubstats} do |team_id| + #team = lookup_team_name team_id + + ## footballTeams.serviceCalls.clubStats[1] + ## https://api.int.bbc.co.uk/sportsdata/statsapi/football/teamstats/team/138824012/clubstats + #File.read("#{responses_path}/#{team}/club_stats.json") +#end + +#get %r{/sportsdata/statsapi/football/table/competition/(\d*)} do |competition_id| + #File.read("#{responses_path}/competitions/#{competition_id}.json") +#end + +#get /.*/ do + #redirect "#{env['PATH_INFO'] =~ /esp-service/ ? 'http://open' : 'https://api' }.int.bbc.co.uk#{env['REQUEST_URI']}" +#end + +post '/fixtures' do + Fixture.create(url: params['url'], content: params['content']) +end + +get /.*/ do + Fixture.where(url: request.fullpath).last.try(:content) or redirect real_api_url(request) +end + +def real_api_url(request) + "#{request.path_info =~ /esp-service/ ? 'http://open' : 'https://api' }.int.bbc.co.uk#{request.fullpath}" +end + diff --git a/features/fixtures_via_api.feature b/features/fixtures_via_api.feature new file mode 100644 index 0000000..f1b9758 --- /dev/null +++ b/features/fixtures_via_api.feature @@ -0,0 +1,33 @@ +Feature: manage fixtures via api + In order to use fixture data in integration tests + As a developer + I want to mock real api + + Scenario: add new fixture + Given I register "/api/something" as url and "test content" as response content + When I request "/api/something" + Then I should get "test content" in response content + + Scenario: add new fixture with parameters + Given I register "/api/something?p=3&a=5" as url and "test content" as response content + And I register "/api/something?p=4&a=5" as url and "more content" as response content + When I request "/api/something?p=4&a=5" + Then I should get "more content" in response content + + Scenario: add another fixture for the same url + Given I register "/api/something" as url and "test content" as response content + When I register "/api/something" as url and "more content" as response content + And I request "/api/something" + Then I should get "more content" in response content + + Scenario Outline: bypass to real service + Given there is no fixtures for "" + When I request "" + Then it should redirect to "" + + Examples: + | url | real_url | + | /api/something?p=2&a=5 | https://api.int.bbc.co.uk/api/something?p=2&a=5 | + | /api/something | https://api.int.bbc.co.uk/api/something | + | /esp-service/something?p=2&a=5 | http://open.int.bbc.co.uk/esp-service/something?p=2&a=5 | + | /esp-service/something | http://open.int.bbc.co.uk/esp-service/something | diff --git a/features/step_definitions/fixtures_via_api_steps.rb b/features/step_definitions/fixtures_via_api_steps.rb new file mode 100644 index 0000000..d2a7a2f --- /dev/null +++ b/features/step_definitions/fixtures_via_api_steps.rb @@ -0,0 +1,23 @@ +Given /^I register "([^"]*)" as url and "([^"]*)" as response content$/ do |url, content| + n = Fixture.where(url: url, content: content).count + post '/fixtures', { url: url, content: content } + Fixture.where(url: url, content: content).count.should == n + 1 +end + +When /^I request "([^"]*)"$/ do |url| + get url + @last_response = last_response +end + +Then /^I should get "([^"]*)" in response content$/ do |content| + @last_response.body.should == content +end + +Given /^there is no fixtures for "([^"]*)"$/ do |url| + Fixture.where(url: url).destroy_all +end + +Then /^it should redirect to "([^"]*)"$/ do |real_api_url| + follow_redirect! + last_response.header['Location'].should == real_api_url +end diff --git a/features/support/env.rb b/features/support/env.rb new file mode 100644 index 0000000..8d6fd50 --- /dev/null +++ b/features/support/env.rb @@ -0,0 +1,14 @@ +require 'rspec/expectations' +require 'rack/test' +require 'rake' +require 'sinatra/activerecord/rake' +require File.expand_path('../../../fake_api_server', __FILE__) + +set :database, 'sqlite://test.db' +Rake::Task['db:migrate'].invoke + +World(Rack::Test::Methods) + +def app + Sinatra::Application +end diff --git a/lib/models/fixture.rb b/lib/models/fixture.rb new file mode 100644 index 0000000..595843d --- /dev/null +++ b/lib/models/fixture.rb @@ -0,0 +1,29 @@ +class Fixture < ActiveRecord::Base +end + +if $0 == __FILE__ + require 'test/unit' + + class TestFixtureModel < Test::Unit::TestCase + def setup + AddFixtureTable.up + @fixture = Fixture.new + end + + def teardown + AddFixtureTable.down + end + + def test_fixture_attributes_exist + [:url, :content].each do |method| + assert_respond_to @fixture, method, "#{@fixture.class.name} should have instance method called #{method.to_s}" + end + end + + def test_fixture_class_methods_exist + [:create].each do |method| + assert_respond_to Fixture, method, "#{@fixture.class.name} should have class method called #{method.to_s}" + end + end + end +end