caruby-small 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ .DS_Store
2
+ *~
3
+ *.pdf
4
+ *.tmproj
5
+ .project
6
+ .loadpath
7
+ .yardoc
8
+ /.bundle
9
+ *.gem
10
+ *.tar*
11
+ /ext
12
+ /doc/api
13
+ **log
14
+ /test/config
15
+ /test/results
16
+ /embed/gems
17
+ /embed/staging
18
+ /embed/target
19
+ /embed/classes
20
+ /embed/lib/*.jar
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source :rubygems
2
+ gemspec
3
+
4
+ group :development do
5
+ # Uncomment the following lines if there are local gem changes. Change the path option
6
+ # to your workspace location. Commit the changed Gemfile and Gemfile.lock to a git branch
7
+ # named 'local' rather than to the master branch. Do not check in the local change.
8
+ gem 'caruby-core', :path => File.dirname(__FILE__) + '/../core'
9
+ gem 'caruby-tissue', :path => File.dirname(__FILE__) + '/../tissue'
10
+ gem 'jinx', :path => File.dirname(__FILE__) + '/../../jinx/core'
11
+ gem 'jinx-migrate', :path => File.dirname(__FILE__) + '/../../jinx/migrate'
12
+ gem 'jinx-json', :path => File.dirname(__FILE__) + '/../../jinx/json'
13
+ gem 'caruby-small', :path => File.dirname(__FILE__)
14
+ end
15
+
16
+ group :test do
17
+ gem 'rspec', '>= 2.6'
18
+ gem 'sinatra', '=1.2.6'
19
+ gem 'rack-test', :require => 'rack/test'
20
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,106 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ caruby-small (1.1.2)
5
+ bundler
6
+ caruby-tissue (>= 2.1.4)
7
+ jruby-openssl
8
+ rack
9
+ sinatra
10
+ sinatra-authorization
11
+
12
+ PATH
13
+ remote: /Users/loneyf/workspace/caruby/core
14
+ specs:
15
+ caruby-core (2.1.3)
16
+ bundler
17
+ jinx (~> 2.1.1)
18
+ jinx-json (~> 2.1.1)
19
+ jinx-migrate (>= 2.1.1)
20
+ rdbi
21
+
22
+ PATH
23
+ remote: /Users/loneyf/workspace/caruby/tissue
24
+ specs:
25
+ caruby-tissue (2.1.5)
26
+ bundler
27
+ caruby-core (>= 2.1.1)
28
+ uom (>= 1.2.2)
29
+
30
+ PATH
31
+ remote: /Users/loneyf/workspace/jinx/core
32
+ specs:
33
+ jinx (2.1.3)
34
+ bundler
35
+
36
+ PATH
37
+ remote: /Users/loneyf/workspace/jinx/json
38
+ specs:
39
+ jinx-json (2.1.2)
40
+ bundler
41
+ jinx
42
+ json_pure
43
+
44
+ PATH
45
+ remote: /Users/loneyf/workspace/jinx/migrate
46
+ specs:
47
+ jinx-migrate (2.1.2)
48
+ bundler
49
+ fastercsv
50
+ rack
51
+
52
+ GEM
53
+ remote: http://rubygems.org/
54
+ specs:
55
+ bouncy-castle-java (1.5.0146.1)
56
+ diff-lcs (1.1.3)
57
+ epoxy (0.3.1)
58
+ extensional (1.3.1)
59
+ fastercsv (1.5.5)
60
+ jruby-openssl (0.7.7)
61
+ bouncy-castle-java (>= 1.5.0146.1)
62
+ json_pure (1.7.3)
63
+ methlab (0.1.0)
64
+ rack (1.4.1)
65
+ rack-test (0.6.1)
66
+ rack (>= 1.0)
67
+ rake (0.9.2.2)
68
+ rdbi (0.9.1)
69
+ epoxy (>= 0.3.1)
70
+ methlab (>= 0.0.9)
71
+ typelib
72
+ rspec (2.10.0)
73
+ rspec-core (~> 2.10.0)
74
+ rspec-expectations (~> 2.10.0)
75
+ rspec-mocks (~> 2.10.0)
76
+ rspec-core (2.10.1)
77
+ rspec-expectations (2.10.0)
78
+ diff-lcs (~> 1.1.3)
79
+ rspec-mocks (2.10.1)
80
+ sinatra (1.2.6)
81
+ rack (~> 1.1)
82
+ tilt (>= 1.2.2, < 2.0)
83
+ sinatra-authorization (1.0.0)
84
+ sinatra (>= 0.9.1.1)
85
+ tilt (1.3.3)
86
+ typelib (0.1.0)
87
+ uom (1.2.2)
88
+ extensional
89
+ yard (0.8.2.1)
90
+
91
+ PLATFORMS
92
+ java
93
+ ruby
94
+
95
+ DEPENDENCIES
96
+ caruby-core!
97
+ caruby-small!
98
+ caruby-tissue!
99
+ jinx!
100
+ jinx-json!
101
+ jinx-migrate!
102
+ rack-test
103
+ rake
104
+ rspec (>= 2.6)
105
+ sinatra (= 1.2.6)
106
+ yard
data/History.md ADDED
@@ -0,0 +1,9 @@
1
+ This history lists major release themes. See the git commits for change details.
2
+
3
+ 1.1.2 / 2012-06-18
4
+ ------------------
5
+ * Add authorization.
6
+
7
+ 1.1.1 / 2012-06-12
8
+ ------------------
9
+ * Initial release.
data/LEGAL ADDED
@@ -0,0 +1,5 @@
1
+ LEGAL NOTICE INFORMATION
2
+ ------------------------
3
+
4
+ All the files in this distribution are covered under either the MIT
5
+ license (see the file LICENSE).
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Oregon Health & Science University
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ ca<small>Small</small>: A caTissue web service and application micro-framework
2
+ ==============================================================================
3
+ **Home**: [http://caruby.rubyforge.org/casmall.html](http://caruby.rubyforge.org/casmall.html)
4
+ **Git**: [http://github.com/caruby/small](http://github.com/caruby/small)
5
+ **Author**: OHSU Knight Cancer Institute
6
+ **Copyright**: 2012
7
+ **License**: MIT License
8
+
9
+ Synopsis
10
+ --------
11
+ caSmall is a framework for deploying a caTissue RESTful web service and custom web applications.
12
+ This project features a web service. The companion [Scat](http://github.com/caruby/scat) project
13
+ is a light-weight web application.
14
+
15
+ Feature List
16
+ ------------
17
+ 1. Search, create and update caTissue objects.
18
+
19
+ 2. Leverages the [caRuby](http://caruby.rubyforge.org) declarative API.
20
+
21
+ Installing
22
+ ----------
23
+ caSmall is installed on a server as a JRuby gem:
24
+ sudo jgem install caruby-small
25
+
26
+ Usage
27
+ -----
28
+ Examples:
29
+
30
+ * Fetch the specimen with identifier 212:
31
+
32
+ GET `myserver:9060/casmall/specimen/212`
33
+
34
+ * Fetch the specimen collection group with SPN <tt>SPN-41873</tt>:
35
+
36
+ GET `myserver:9060/casmall/SpecimenCollectionGroup?surgicalPathologyNumber=SPN-41873`
37
+
38
+ * Fetch specimens based on a submitted JSON criterion template:
39
+
40
+ POST `myserver:9060/casmall/query`
41
+
42
+ * Create a specimen from a submitted JSON object:
43
+
44
+ POST `myserver:9060/casmall/`
45
+
46
+ * Update a specimen from a submitted JSON object:
47
+
48
+ PUT `myserver:9060/casmall/`
49
+
50
+ The JSON payload is described in the Jinx [JSON](http://github.com/jinx/json) project.
51
+
52
+ Copyright
53
+ ---------
54
+ caSmall &copy; 2012 by [Oregon Health & Science University](http://www.ohsu.edu/xd/health/services/cancer).
55
+ caSmall is licensed under the MIT license. Please see the LICENSE and LEGAL files for more information.
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'fileutils'
2
+ require File.expand_path('version', File.dirname(__FILE__) + '/lib/casmall')
3
+
4
+ desc "Default: run all tests"
5
+ task :default => :test
6
+
7
+ # the gem name
8
+ GEM = 'caruby-small'
9
+ GEM_VERSION = CaSmall::VERSION
10
+
11
+ WINDOWS = (Config::CONFIG['host_os'] =~ /mingw|win32|cygwin/ ? true : false) rescue false
12
+ SUDO = WINDOWS ? '' : 'sudo'
13
+
14
+ desc 'Builds the gem'
15
+ task :gem do
16
+ sh "jgem build #{GEM}.gemspec"
17
+ end
18
+
19
+ desc 'Installs the gem'
20
+ task :install => :gem do
21
+ sh "#{SUDO} jgem install #{GEM}-#{GEM_VERSION}.gem"
22
+ end
23
+
24
+ desc 'Documents the API'
25
+ task :doc do
26
+ FileUtils.rm_rf 'doc/api'
27
+ sh "yardoc"
28
+ end
29
+
30
+ desc 'Runs the specs'
31
+ task :spec do
32
+ Dir['spec/**/*_spec.rb'].each { |f| sh "rspec #{f}" rescue nil }
33
+ end
34
+
35
+ desc 'Runs the tests'
36
+ task :test => :spec
data/bin/casmall ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env jruby
2
+ #
3
+ # casmall: Start a caTissue web service
4
+ #
5
+
6
+ require 'casmall'
7
+ rackup --env production File.dirname(__FILE__) + '../config.ru'
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ require 'date'
5
+ require File.expand_path('version', File.dirname(__FILE__) + '/lib/casmall')
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'caruby-small'
9
+ s.summary = 'caSmall web service'
10
+ s.description = s.summary + '. See the Git README for more information.'
11
+ s.version = CaSmall::VERSION
12
+ s.date = Date.today
13
+ s.author = "OHSU"
14
+ s.email = "loneyf@ohsu.edu"
15
+ s.require_path = 'lib'
16
+ s.bindir = 'bin'
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files spec`.split("\n")
19
+ s.executables = `git ls-files bin`.split("\n").map { |f| File.basename(f) }
20
+ s.add_runtime_dependency 'bundler'
21
+ s.add_runtime_dependency 'rack'
22
+ s.add_runtime_dependency 'sinatra'
23
+ s.add_runtime_dependency 'sinatra-authorization'
24
+ s.add_runtime_dependency 'jruby-openssl'
25
+ s.add_runtime_dependency 'caruby-tissue', '>= 2.1.5'
26
+ s.add_development_dependency 'yard'
27
+ s.add_development_dependency 'rake'
28
+ s.has_rdoc = 'yard'
29
+ s.license = 'MIT'
30
+ end
data/config.ru ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require
4
+
5
+ require 'casmall'
6
+ require 'jinx/helpers/log'
7
+
8
+ # the logger
9
+ use Rack::CommonLogger, Jinx.logger(:app => 'CaSmall', :debug => true)
10
+
11
+ # start the application
12
+ run CaSmall::App.new(CaTissue)
@@ -0,0 +1,80 @@
1
+ require 'sinatra/authorization'
2
+
3
+ module CaSmall
4
+ module Authorization
5
+ include Sinatra::Authorization
6
+
7
+ # Runs the given block in an HTTP basic authorization context.
8
+ # The session status is set to the result of performing the given block.
9
+ #
10
+ # @yield perform the caTissue operation and return a status message
11
+ def protect!(&block)
12
+ login_required
13
+ CaTissue::Database.current.open(session[:email], session[:password], &block)
14
+ end
15
+
16
+ # @return [CaTissue::User] the user who is submitting this edit
17
+ # @raise [ArgumentError] if there is no such caTissue user
18
+ def current_user
19
+ # The caTissue login name is the user's email address.
20
+ email = session[:email]
21
+ raise ScatError.new("The caTissue login is not available in this web session.") unless email
22
+ # the current caTissue User
23
+ user = CaTissue::User.new(:email_address => email)
24
+ # the cached caTissue User id
25
+ user_id = session[:user_id]
26
+ if user_id then
27
+ user.identifier = user_id
28
+ else
29
+ # Fetch the User and cache the id.
30
+ raise ScatError.new("User not found: #{user.email_address}") unless user.find
31
+ session[:user_id] = user.identifier
32
+ end
33
+ user
34
+ end
35
+
36
+ # Fix +Sinatra::Authorization.authorization_realm+ per the
37
+ # (https://github.com/sr/sinatra-authorization)[https://github.com/sr/sinatra-authorization]
38
+ # patch.
39
+ def authorization_realm
40
+ settings.authorization_realm
41
+ end
42
+
43
+ private
44
+
45
+ # Obtains the HTML Basic authorization username and password.
46
+ # Formats the caTissue login name as _username_+@+_domain_,
47
+ # where _domain_ is the domain portion of the system +hostname+.
48
+ #
49
+ # @param [String] the caTissue login name, with or without the +@+_domain_ suffix
50
+ # @param [String] the caTissue password
51
+ # @return [Boolean] the authorization result
52
+ def authorize(username, password)
53
+ email = session[:email] = infer_email_address(username)
54
+ session[:password] = password
55
+ # Try to start a session.
56
+ begin
57
+ CaTissue::Database.current.open(email, password) {}
58
+ logger.debug { "Scat captured the caTissue login name #{email} and password." }
59
+ true
60
+ rescue Exception => e
61
+ logger.debug { "Scat caTissue login #{email.qp} with password #{password.qp} is invalid." }
62
+ session[:status] = "caTissue login was unsuccessful - #{e.message}"
63
+ false
64
+ end
65
+ end
66
+
67
+ # @param [String] the username, with or without the +@+_domain_ suffix
68
+ # @param [String] the email address
69
+ def infer_email_address(username)
70
+ if username.index('@') then
71
+ username
72
+ else
73
+ # The email domain is the last two components of the hostname, e.g.
74
+ # the prod01.cluster.galena.edu domain is galena.edu.
75
+ domain = `hostname`.chomp[/[^.]+\.[^.]+$/]
76
+ domain.empty? ? username : [username, domain].join('@')
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,3 @@
1
+ module CaSmall
2
+ VERSION = '1.1.2'
3
+ end
@@ -0,0 +1,66 @@
1
+ require 'json'
2
+
3
+ module CaSmall
4
+ # The WebService processes catissuews requests.
5
+ class WebService
6
+ # @param [Module] mod the application domain module, e.g. +CaTissue+.
7
+ def initialize(mod)
8
+ @context = mod
9
+ end
10
+
11
+ # @param [String] name the search target class name, singular or plural
12
+ # @param [{String=>String}] params the attribute => value search arguments
13
+ # @return [String, nil] the JSON content of the matching object(s), or nil if no match
14
+ def find(name, params)
15
+ # the caTissue class to find
16
+ tgt = name.singularize
17
+ logger.info { "caSmall finding #{name.qp} #{params.qp}..." }
18
+ klass = @context.const_get(tgt.camelize)
19
+ # the attribute => value hash
20
+ vh = {}
21
+ # Convert the parameters into attribute => value entries.
22
+ params.each do |k, v|
23
+ pa = k.to_sym
24
+ # the standard property
25
+ prop = klass.property(pa)
26
+ # Convert a numeric attribute string argument to an integer.
27
+ v = v.to_i if prop.type < Java::JavaLang::Number
28
+ vh[pa] = v
29
+ end
30
+ # the search template
31
+ tmpl = klass.new(vh)
32
+ # the search result
33
+ result = tgt == name ? tmpl.find : tmpl.query
34
+ # convert the search result, if any, to JSON
35
+ if result then
36
+ logger.info { "caSmall found #{result.qp}." }
37
+ result.to_json
38
+ end
39
+ end
40
+
41
+ # @param [String] json the JSON representation of the query template
42
+ # @param [String, nil] path the optional query attribute path
43
+ # @return [String, nil] the JSON content of the matching objects, or nil if no match
44
+ def query(json, path=nil)
45
+ path_a = path ? path.split('/').map { |s| s.to_sym } : Array::EMPTY_ARRAY
46
+ # Bump the default nesting, since a query result can be deeply nested.
47
+ JSON[json].query(*path_a).to_json(:max_nesting => 100)
48
+ end
49
+
50
+ # @param [String] json the JSON representation of the object to create
51
+ # @return [String] the created object's identifier as a JSON string
52
+ def create(json)
53
+ JSON[json].create.identifier.to_json
54
+ end
55
+
56
+ # @param [String] json the JSON representation of the object to update
57
+ def update(json)
58
+ obj = JSON[json]
59
+ if obj.identifier.nil? then
60
+ obj.find or raise NotFoundError.new("Object to update was not found in the database: #{obj}")
61
+ end
62
+ obj.update
63
+ true.to_json
64
+ end
65
+ end
66
+ end
data/lib/casmall.rb ADDED
@@ -0,0 +1,52 @@
1
+ require 'sinatra'
2
+ require 'catissue'
3
+ require 'casmall/authorization'
4
+ require 'casmall/web_service'
5
+
6
+ module CaSmall
7
+ class App < Sinatra::Base
8
+ include Authorization
9
+
10
+ set :root, File.dirname(__FILE__) + '/..'
11
+
12
+ if development? then
13
+ # Don't generate fancy HTML for stack traces.
14
+ disable :show_exceptions
15
+ # Allow errors to get out of the app so Cucumber can display them.
16
+ enable :raise_errors
17
+ end
18
+
19
+ # The authorization page name.
20
+ set :authorization_realm, 'Please enter your username and caTissue password'
21
+
22
+ enable :sessions
23
+
24
+ def initialize(mod, *args)
25
+ super(*args)
26
+ #the request handler.
27
+ @ws = CaSmall::WebService.new(mod)
28
+ end
29
+
30
+ # Match on the class/id or class?attribute=value[&attribute=value ...].
31
+ get %r{/(\w+)(?:/(\d+))?} do |name, id|
32
+ # The value hash is either the id argument or the URL parameters.
33
+ vh = id ? {'identifier' => id} : params.delete_if { |k, v| k == 'captures' }
34
+ # delegate to the web service
35
+ @ws.find(name, vh)
36
+ end
37
+
38
+ # Match on +query+ with request parameters.
39
+ post %r{/query(?:/([\w/]+))?} do |path|
40
+ @ws.query(params[:json], path)
41
+ end
42
+
43
+ post '/' do
44
+ @ws.create(params[:json])
45
+ end
46
+
47
+ put '/' do
48
+ @ws.update(params[:json])
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,33 @@
1
+ require 'spec/spec_helper'
2
+
3
+ module CaSmall
4
+ describe 'Create' do
5
+ include RackTest
6
+
7
+ before(:all) do
8
+ @reg = seed.registration
9
+ end
10
+
11
+ subject { @reg }
12
+
13
+ it 'should create a new registration' do
14
+ post '/', :json => subject.to_json
15
+ last_response.should be_ok
16
+ id_s = last_response.body
17
+ id_s.should match /^\d+$/
18
+ fetched = subject.class.new(:identifier => id_s.to_i).find
19
+ fetched.should_not be nil
20
+ scgs = fetched.specimen_collection_groups
21
+ scgs.size.should be 1
22
+ scgs.first.specimens.size.should be 1
23
+ end
24
+
25
+ it 'should create an annotation' do
26
+ pnt = @reg.participant
27
+ lab = CaTissue::Participant::Clinical::LabAnnotation.new
28
+ lab.merge_attributes(:lab_test_name => 'Test Lab', :participant => pnt)
29
+ post '/', :json => lab.to_json
30
+ last_response.should be_ok
31
+ end
32
+ end
33
+ end
data/spec/find_spec.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'uri'
2
+ require 'spec/spec_helper'
3
+
4
+ module CaSmall
5
+ describe 'Find' do
6
+ include RackTest
7
+
8
+ it "should find an existing Site by name" do
9
+ site = CaTissue::Site.default_site
10
+ get "/site?name=#{URI.escape(site.name)}"
11
+ last_response.should be_ok
12
+ fetched = JSON[last_response.body]
13
+ fetched.identifier.should_not be_nil
14
+ site.content_matches?(fetched).should be true
15
+ end
16
+
17
+ it "should find an existing Participant" do
18
+ pnt = CaTissue::Participant.new(:last_name => Jinx::UID.generate.to_s).create
19
+ get "/participant/#{pnt.id}"
20
+ last_response.should be_ok
21
+ fetched = JSON[last_response.body]
22
+ fetched.identifier.should_not be_nil
23
+ pnt.content_matches?(fetched).should be true
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec/spec_helper'
2
+
3
+ module CaSmall
4
+ describe 'Query' do
5
+ include RackTest
6
+
7
+ it 'should query an existing Site' do
8
+ site = CaTissue::Site.default_site
9
+ post "/query", :json => site.to_json
10
+ last_response.should be_ok
11
+ fetched = JSON[last_response.body]
12
+ fetched.size.should be 1
13
+ site.content_matches?(fetched.first).should be true
14
+ end
15
+
16
+ it 'should query a Site -> coordinator path' do
17
+ site = CaTissue::Site.default_site
18
+ post '/query/coordinator', :json => site.to_json
19
+ last_response.should be_ok
20
+ fetched = JSON[last_response.body]
21
+ fetched.size.should be 1
22
+ end
23
+
24
+ it 'should query registration specimens' do
25
+ reg = seed.registration.create
26
+ pnt = reg.participant
27
+ spc = pnt.specimens.first
28
+ tmpl = reg.copy(:identifier)
29
+ post '/query/specimen_collection_groups/specimens', :json => tmpl.to_json
30
+ last_response.should be_ok
31
+ fetched = JSON[last_response.body]
32
+ fetched.size.should be 1
33
+ fetched.first.content_matches?(spc).should be true
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ Bundler.require(:test, :development)
4
+
5
+ require 'casmall'
6
+
7
+ module CaSmall::Test
8
+ RESULTS = File.dirname(__FILE__) + '/../test/results'
9
+ end
10
+
11
+ # Open the logger.
12
+ Jinx::Log.instance.open(CaSmall::Test::RESULTS + '/log/casmall.log', :debug => true)
13
+
14
+ Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
@@ -0,0 +1,16 @@
1
+ require 'rack/test'
2
+ require Bundler.environment.specs.detect { |s| s.name == 'caruby-tissue' }.full_gem_path + '/test/helpers/seed'
3
+
4
+ def app
5
+ CaSmall::App.new(CaTissue)
6
+ end
7
+
8
+ module CaSmall
9
+ module RackTest
10
+ include Rack::Test::Methods
11
+
12
+ def seed
13
+ CaTissue::TestCase::Seed.new.uniquify
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec/spec_helper'
2
+
3
+ module CaSmall
4
+ describe 'Update' do
5
+ include RackTest
6
+
7
+ before(:all) do
8
+ @spc = seed.specimen.create
9
+ end
10
+
11
+ subject { @spc }
12
+
13
+ it 'should update a specimen quantity' do
14
+ qty = subject.available_quantity /= 2
15
+ put '/', :json => subject.to_json
16
+ last_response.should be_ok
17
+ fetched = subject.copy(:identifier).find
18
+ fetched.available_quantity.should be_within(0.00001).of(qty)
19
+ end
20
+
21
+ it 'should add a specimen annotation' do
22
+ pst = CaTissue::Specimen::Pathology::ProstateSpecimenPathologyAnnotation.new
23
+ pst.merge_attributes(:specimen => subject)
24
+ grd = CaTissue::Specimen::Pathology::SpecimenHistologicGrade.new
25
+ grd.merge_attributes(:grade => 3, :specimen_base_solid_tissue_pathology_annotation => pst)
26
+ put '/', :json => subject.to_json
27
+ last_response.should be_ok
28
+ # TODO - Uncomment when annotation query supported
29
+ # fetched = subject.copy(:identifier).find
30
+ # fpst = fetched.pathology.prostate_specimen_pathology_annotations.first
31
+ # fpst.should_not be nil
32
+ # fgrd = fpst.histologic_grades.first
33
+ # fgrd.should_not be nil
34
+ # fgrd.grade.should be grd.grade
35
+ end
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: caruby-small
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.1.2
6
+ platform: ruby
7
+ authors:
8
+ - OHSU
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-07-17 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ version_requirements: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ requirement: *id001
24
+ prerelease: false
25
+ type: :runtime
26
+ - !ruby/object:Gem::Dependency
27
+ name: rack
28
+ version_requirements: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ requirement: *id002
35
+ prerelease: false
36
+ type: :runtime
37
+ - !ruby/object:Gem::Dependency
38
+ name: sinatra
39
+ version_requirements: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ requirement: *id003
46
+ prerelease: false
47
+ type: :runtime
48
+ - !ruby/object:Gem::Dependency
49
+ name: sinatra-authorization
50
+ version_requirements: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ requirement: *id004
57
+ prerelease: false
58
+ type: :runtime
59
+ - !ruby/object:Gem::Dependency
60
+ name: jruby-openssl
61
+ version_requirements: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ requirement: *id005
68
+ prerelease: false
69
+ type: :runtime
70
+ - !ruby/object:Gem::Dependency
71
+ name: caruby-tissue
72
+ version_requirements: &id006 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 2.1.5
78
+ requirement: *id006
79
+ prerelease: false
80
+ type: :runtime
81
+ - !ruby/object:Gem::Dependency
82
+ name: yard
83
+ version_requirements: &id007 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ requirement: *id007
90
+ prerelease: false
91
+ type: :development
92
+ - !ruby/object:Gem::Dependency
93
+ name: rake
94
+ version_requirements: &id008 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ requirement: *id008
101
+ prerelease: false
102
+ type: :development
103
+ description: caSmall web service. See the Git README for more information.
104
+ email: loneyf@ohsu.edu
105
+ executables:
106
+ - casmall
107
+ extensions: []
108
+
109
+ extra_rdoc_files: []
110
+
111
+ files:
112
+ - .gitignore
113
+ - Gemfile
114
+ - Gemfile.lock
115
+ - History.md
116
+ - LEGAL
117
+ - LICENSE
118
+ - README.md
119
+ - Rakefile
120
+ - bin/casmall
121
+ - caruby-small.gemspec
122
+ - config.ru
123
+ - lib/casmall.rb
124
+ - lib/casmall/authorization.rb
125
+ - lib/casmall/version.rb
126
+ - lib/casmall/web_service.rb
127
+ - spec/create_spec.rb
128
+ - spec/find_spec.rb
129
+ - spec/query_spec.rb
130
+ - spec/spec_helper.rb
131
+ - spec/support/rack_test.rb
132
+ - spec/update_spec.rb
133
+ homepage:
134
+ licenses:
135
+ - MIT
136
+ post_install_message:
137
+ rdoc_options: []
138
+
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: "0"
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: "0"
153
+ requirements: []
154
+
155
+ rubyforge_project:
156
+ rubygems_version: 1.8.15
157
+ signing_key:
158
+ specification_version: 3
159
+ summary: caSmall web service
160
+ test_files:
161
+ - spec/create_spec.rb
162
+ - spec/find_spec.rb
163
+ - spec/query_spec.rb
164
+ - spec/spec_helper.rb
165
+ - spec/support/rack_test.rb
166
+ - spec/update_spec.rb
167
+ has_rdoc: yard