summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--config.ru5
-rw-r--r--datasets.rb127
-rw-r--r--test.rb46
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
diff --git a/test.rb b/test.rb
new file mode 100644
index 0000000..9d24a42
--- /dev/null
+++ b/test.rb
@@ -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