diff options
author | Christoph Helma <helma@in-silico.de> | 2009-07-21 18:24:36 +0200 |
---|---|---|
committer | Christoph Helma <helma@in-silico.de> | 2009-07-21 18:24:36 +0200 |
commit | 678a9667e25c5ca20338938474e39a3cdefa7c3e (patch) | |
tree | 7ac1d9d1ee838ea54dcfb35392bde1e17164b78a |
Initial import of opentox-dataset
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | config.ru | 5 | ||||
-rw-r--r-- | datasets.rb | 127 | ||||
-rw-r--r-- | test.rb | 46 |
4 files changed, 181 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..872da93 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +api_key.rb +*.sqlite3 +tmp/* diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..4202e2b --- /dev/null +++ b/config.ru @@ -0,0 +1,5 @@ +require 'rubygems' +require 'sinatra' +require 'datasets.rb' + +run Sinatra::Application diff --git a/datasets.rb b/datasets.rb new file mode 100644 index 0000000..2b5a43a --- /dev/null +++ b/datasets.rb @@ -0,0 +1,127 @@ +## SETUP +[ 'rubygems', 'sinatra', 'rest_client', 'sinatra/url_for', 'datamapper', 'dm-more', 'do_sqlite3', 'builder', 'api_key' ].each do |lib| + require lib +end + +# reload + +## MODELS + +class Dataset + include DataMapper::Resource + property :id, Serial + property :name, String, :unique => true + has n, :associations +end + +class Association + include DataMapper::Resource + property :id, Serial + property :compound_uri, Text + property :feature_uri, Text + belongs_to :dataset +end + +# automatically create the tables +configure :test do + DataMapper.setup(:default, 'sqlite3::memory:') + [Dataset, Association].each do |model| + model.auto_migrate! + end +end + +@db = "datasets.sqlite3" +configure :development, :production do + DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/#{@db}") + unless FileTest.exists?("#{@db}") + [Dataset, Association].each do |model| + model.auto_migrate! + end + end + puts @db +end + +# configure services +COMPOUNDS_SERVICE_URI = "http://webservices.in-silico.ch/compounds/" +FEATURES_SERVICE_URI = "http://webservices.in-silico.ch/features/" + +## Authentification +helpers do + + def protected! + response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth") and \ + throw(:halt, [401, "Not authorized\n"]) and \ + return unless authorized? + end + + def authorized? + @auth ||= Rack::Auth::Basic::Request.new(request.env) + @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ['api', API_KEY] + end + +end + +## REST API +get '/' do + Dataset.all.collect{ |d| url_for("/", :full) + d.id.to_s }.join("\n") +end + +get '/:id' do + begin + dataset = Dataset.get(params[:id]) + builder do |xml| + xml.instruct! + xml.dataset do + xml.uri url_for("/", :full) + dataset.id.to_s + xml.name dataset.name + dataset.associations.each do |a| + xml.association do + xml.compound a.compound_uri + xml.feature a.feature_uri + end + end + end + end + rescue + status 404 + "Cannot find dataset with ID #{params[:id]}." + end +end + +put '/:id' do + begin + dataset = Dataset.get params[:id] + compound_uri = RestClient.post COMPOUNDS_SERVICE_URI, :name => params[:compound_name] + feature_uri = RestClient.post FEATURES_SERVICE_URI, :name => params[:feature_name], :value => params[:feature_value] + Association.create(:compound_uri => compound_uri.to_s, :feature_uri => feature_uri.to_s, :dataset_id => dataset.id) + url_for("/", :full) + dataset.id.to_s + rescue + status 500 + "Failed to update dataset #{params[:id]}." + end +end + +post '/' do + protected! + begin + dataset = Dataset.create :name => params[:dataset_name] + url_for("/", :full) + dataset.id.to_s + rescue + status 500 + "Failed to create new dataset." + end +end + +delete '/:id' do + # dangerous, because other datasets might refer to it + protected! + begin + dataset = Dataset.get(params[:id]) + dataset.associations.each { |a| a.destroy } + dataset.destroy + "Successfully deleted dataset #{params[:id]}." + rescue + status 500 + "Can not delete dataset #{params[:id]}." + end +end @@ -0,0 +1,46 @@ +ENV['RACK_ENV'] = 'test' +require 'datasets' +require 'test/unit' +require 'rack/test' + + +class DatasetsTest < Test::Unit::TestCase + include Rack::Test::Methods + + def app + Sinatra::Application + end + + def test_index + get '/' + assert last_response.ok? + end + + def test_create_dataset + authorize "api", API_KEY + post '/', :dataset_name => "Test dataset" + assert last_response.ok? + assert_equal "http://example.org/1", last_response.body.chomp + end + + def test_create_dataset_and_insert_data + authorize "api", API_KEY + post '/', :dataset_name => "Test dataset" + puts last_response.body + put '/1', :feature_name => "New feature", :feature_value => "inactive", :compound_name => 'Benzene' + puts last_response.body + put '/1', :feature_name => "New feature", :feature_value => "active", :compound_name => 'Dioxin' + get '/1' + puts last_response.body.chomp + assert last_response.ok? + end + + def test_unauthorized_create + post '/', :dataset_name => "Test dataset", :feature_name => "Test feature", :file => File.new('tests/example.tab') + assert !last_response.ok? + end + + def test_post_to_existing_dataset + end + +end |