http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/core/collection.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/core/collection.rb b/sdks/other/ruby/lib/usergrid/core/collection.rb new file mode 100644 index 0000000..02ac9fd --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/core/collection.rb @@ -0,0 +1,121 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Usergrid + class Collection < Entity + include Enumerable + + attr_accessor :iterator_follows_cursor + + def initialize(url, api_url, options={}, response=nil) + super url, api_url, options, response + @iterator_follows_cursor = false + end + + def collection + self + end + + def entities + get unless response + response.entities + end + + def [](k) + entities[k] + end + + def []=(k,v) + raise "unsupported operation" + end + + # does not save entities! just fields (eg. 'name') + def save + super save + end + + def each(&block) + entities.each &block + while cursor + next_page + entities.each &block + end if iterator_follows_cursor + end + + # use in conjunction with each() like: collection.follow_cursor.each {|e| } + def follow_cursor + my_clone = self.clone + my_clone.iterator_follows_cursor = true + my_clone + end + + def create_entity(data) + self.post data + end + alias_method :create_entities, :create_entity + + # options: 'reversed', 'start', 'cursor', 'limit', 'permission' + def update_query(updates, query=nil, options={}) + options = options.symbolize_keys + query_params = query ? options.merge({ql: query}) : options + self.put(updates, {params: query_params }) + self + end + + # options: 'reversed', 'start', 'cursor', 'limit', 'permission' + def delete_query(query=nil, options={}) + options = options.symbolize_keys + query_params = query ? options.merge({ql: query}) : options + self.delete({params: query_params }) + self + end + + # options: 'reversed', 'start', 'cursor', 'limit', 'permission' + def query(query=nil, options={}) + options = options.symbolize_keys + query_params = query ? options.merge({ql: query}) : options + self.get({params: query_params }) + self + end + + def size + entities.size + end + + def empty? + entities.empty? + end + + def cursor + response.data['cursor'] + end + + def next_page + query(nil, query_params.merge({cursor: cursor})) + end + + protected + + def query_params + params = {} + if response.data['params'] + response.data['params'].each do |k,v| + params[k] = v[0] + end + end + params + end + end +end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/core/entity.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/core/entity.rb b/sdks/other/ruby/lib/usergrid/core/entity.rb new file mode 100644 index 0000000..1539b58 --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/core/entity.rb @@ -0,0 +1,80 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# also allows hash or dot notation for entity properties +module Usergrid + class Entity < Resource + + def initialize(url, api_url, options={}, response=nil, index=nil) + super url, api_url, options, response + @index = index + end + + def data + get unless response + @index ? response.entities_data[@index] : response.entity_data + end + + def data? + !!response + end + + def resource + Resource.new url, api_url, options + end + + def [](k) + data[k] + end + + def []=(k,v) + data[k] = v + end + + def collection + Collection.new url[0..url[0..-2].rindex('/')-1], api_url, options + end + + def save + self.put data + end + + def to_s + "resource: #{url}\ndata: #{data}" + end + + def to_json(*args) + data.except(RESERVED).to_json *args + end + alias :encode :to_json + alias :dump :to_json + + private + + def method_missing(method, *args, &block) + if data.respond_to?(method) + data.send(method, *args, &block) + elsif method[-1] == '=' && args.size == 1 + data[method[0..-2]] = args[0] + else + super method, args, block + end + end + + def respond_to?(method) + super.respond_to?(method) || data.respond_to?(method) + end + end +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/core/management.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/core/management.rb b/sdks/other/ruby/lib/usergrid/core/management.rb new file mode 100644 index 0000000..b8f3e06 --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/core/management.rb @@ -0,0 +1,57 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Usergrid + class Management < Resource + + def initialize(url, options={}) + management = url.split('/')[-1] + if management == 'management' + api_url = url[0..url.index(management)-2] + else + api_url = url + url = concat_urls(api_url, 'management') + end + super url, api_url, options + end + + def create_organization(organization, username, name, email, password) + data = { organization: organization, + username: username, + name: name, + email: email, + password: password } + self['organizations'].post data + end + + def organizations + self[__method__].get + end + + def organization(organization) + url = self["organizations/#{organization}"].url + Organization.new url, options + end + + def users + self['users'].get + end + + def user(name_or_uuid) + self["users/#{name_or_uuid}"].get + end + + end +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/core/organization.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/core/organization.rb b/sdks/other/ruby/lib/usergrid/core/organization.rb new file mode 100644 index 0000000..9df485a --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/core/organization.rb @@ -0,0 +1,74 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'uri' +module Usergrid + class Organization < Resource + + def initialize(url, options={}) + org_name = url.split('/')[-1] + api_url = url[0..url.index('management')-2] + super url, api_url, options + end + + def name + URI(url).path.split('/').last + end + + def create_application(name) + self['applications'].post({ name: name }) + application name + end + + def applications(query=nil) + resource = self[__method__] + response = query ? resource.query(query) : resource.get + response.data['data'].collect do |k| + application concat_urls(api_url, k) + end + end + + def application(name_or_uuid) + Usergrid::Application.new concat_urls(api_url, "#{name}/#{name_or_uuid}"), options + end + + def users(query=nil) + self[__method__].query(query) + end + + def user(user) + management.user(user) + end + + def feed(query=nil) + self[__method__].query(query) + end + + def credentials + self[__method__].get + end + + def generate_credentials + self['credentials'].post nil + end + + def login_credentials(client_id, client_secret) + resource = api_resource 'management' + response = resource['token'].post grant_type: 'client_credentials', client_id: client_id, client_secret: client_secret + self.auth_token = response.data['access_token'] + end + + end +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/core/resource.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/core/resource.rb b/sdks/other/ruby/lib/usergrid/core/resource.rb new file mode 100644 index 0000000..1f96f90 --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/core/resource.rb @@ -0,0 +1,157 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'rest_client' + +module Usergrid + class Resource < RestClient::Resource + + RESERVED = %w( created modified metadata uri ) + DEFAULT_API_URL = 'https://api.usergrid.com' + TYPE_HEADERS = { content_type: :json, accept: :json } + + attr_reader :current_user, :api_url, :response + + def initialize(resource_url=DEFAULT_API_URL, api_url=nil, options={}, response=nil) + options[:headers] = TYPE_HEADERS.merge options[:headers] || {} + @api_url = api_url || resource_url + self.response = response + super resource_url, options, &method(:handle_response) + end + + # gets user token and automatically set auth header for future requests + # precondition: resource must already be set to the correct context (application or management) + def login(username, password) + response = self['token'].post grant_type: 'password', username: username, password: password + self.auth_token = response.data['access_token'] + user_uuid = response.data['user']['uuid'] + @current_user = self["/users/#{user_uuid}"].get.entity + response + end + + # remove auth header for future requests + # only affects self and derivative resources + def logout + self.auth_token = nil + @current_user = nil + end + + def logged_in? + !!auth_token + end + + def management + Usergrid::Management.new api_url, options + end + + # application defaults to sandbox if none provided + def application(organization, application='sandbox') + Usergrid::Application.new concat_urls(api_url, "#{organization}/#{application}"), options + end + + # options: 'reversed', 'start', 'cursor', 'limit', 'permission' + def query(query=nil, options={}) + options = options.merge({ql: query}) if query + get({params: options}) + end + + # options: 'reversed', 'start', 'cursor', 'limit', 'permission' + def update_query(updates, query=nil, options={}) + options = options.merge({ql: query}) if query + put(updates, {params: options}) + end + + # options: 'reversed', 'start', 'cursor', 'limit', 'permission' + def delete_query(query=nil, options={}) + options = options.merge({ql: query}) if query + delete({params: options}) + end + + def entity + get unless response + response.entity + end + + def entities + get unless response + response.entities + end + + def collection + get unless response + Collection.new url, api_url, options, response + end + + # overridden to ensure sub resources are instances of this class + def [](suburl, &new_block) + case + when block_given? then Resource.new(concat_urls(url, suburl), api_url, options, &new_block) + when block then Resource.new(concat_urls(url, suburl), api_url, options, &block) + else + Resource.new(concat_urls(url, suburl), api_url, options) + end + end + + def api_resource(suburl) + Resource.new(concat_urls(api_url, suburl), api_url, options) + end + + def get(additional_headers={}, &block) + self.response = super additional_headers, &block + end + + def post(payload, additional_headers={}, &block) + payload = MultiJson.dump(payload) unless payload.is_a? String + self.response = super payload, additional_headers, &block + end + + def put(payload, additional_headers={}, &block) + payload = MultiJson.dump(payload) unless payload.is_a? String + self.response = super payload, additional_headers, &block + end + + def auth_token=(auth_token) + if auth_token + @options[:headers].merge!({ Authorization: "Bearer #{auth_token}" }) + else + @options[:headers].delete :Authorization if @options + end + end + + def auth_token + begin + @options[:headers][:Authorization].gsub 'Bearer ', '' + rescue + nil + end + end + + protected + + def response=(response) + @response = response + end + + # add verbose debugging of response body + def handle_response(response, request, result, &block) + LOG.debug "response.body = #{response}" + response = response.return!(request, result, &block) + response.resource = self + self.response = response + response + end + + end +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/extensions/hash.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/extensions/hash.rb b/sdks/other/ruby/lib/usergrid/extensions/hash.rb new file mode 100644 index 0000000..5a1cd30 --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/extensions/hash.rb @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +class Hash + + # not recursive + def symbolize_keys + inject({}) do |options, (key, value)| + options[(key.to_sym rescue key) || key] = value + options + end + end + + def except(*keys) + dup.except! *keys + end + + def except!(*keys) + keys.each { |key| key.is_a?(Array) ? except!(*key) : delete(key) } + self + end + + # recursive + def add_dot_notation!(_hash=self) + _hash.each do |k,v| + getter = k.to_sym; setter = "#{k}=".to_sym + _hash.define_singleton_method getter, lambda { _hash[k] } unless _hash.respond_to? getter + _hash.define_singleton_method setter, lambda { |v| _hash[k] = v } unless _hash.respond_to? setter + add_dot_notation!(v) if v.is_a? Hash + v.each { |e| add_dot_notation!(e) if e.is_a? Hash } if v.is_a? Array + end + end +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/extensions/response.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/extensions/response.rb b/sdks/other/ruby/lib/usergrid/extensions/response.rb new file mode 100644 index 0000000..ee2ffbf --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/extensions/response.rb @@ -0,0 +1,96 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module RestClient + module Response + + def resource=(resource) + @resource = resource + end + + def resource + @resource + end + + def data + @data = MultiJson.load(self).add_dot_notation! unless @data + @data + end + + def collection + resource.collection + end + + def multiple_entities? + entities_data = data['entities'] || data['data'] || data['messages'] || data['list'] + entities_data.is_a? Array + end + + def entities_data + return @entities_data if @entities_data + entities_data = data['entities'] || data['data'] || data['messages'] || data['list'] + raise "unable to determine entities from: #{data}" unless entities_data.is_a?(Array) + entities_data.each do |e| + e['uri'] = concat_urls(data['uri'], e['uuid']) if e.is_a?(Hash) && e['uuid'] + end + @entities_data = entities_data + end + + def entities + return @entities if @entities + index = -1 + @entities = entities_data.collect do |e| + if e.is_a? Array + e + else + Usergrid::Entity.new e['uri'], resource.api_url, resource.options, self, index+=1 + end + end + end + + def entity_data + if multiple_entities? + entities_data.first + elsif data['data'] + d = data['data'] + d['uri'] = @resource.url + d + elsif data['organization'] + d = data['organization'] + d['uri'] = @resource.url + d + else + entities_data.first + end + end + + def entity + Usergrid::Entity.new(entity_data['uri'], resource.api_url, resource.options, self) if entity_data + end + + protected + + def concat_urls(url, suburl) # :nodoc: + url = url.to_s + suburl = suburl.to_s + if url.slice(-1, 1) == '/' or suburl.slice(0, 1) == '/' + url + suburl + else + "#{url}/#{suburl}" + end + end + + end +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid/version.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid/version.rb b/sdks/other/ruby/lib/usergrid/version.rb new file mode 100644 index 0000000..951b017 --- /dev/null +++ b/sdks/other/ruby/lib/usergrid/version.rb @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Usergrid + VERSION = '0.9.2' +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/lib/usergrid_iron.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/lib/usergrid_iron.rb b/sdks/other/ruby/lib/usergrid_iron.rb new file mode 100644 index 0000000..7bd209c --- /dev/null +++ b/sdks/other/ruby/lib/usergrid_iron.rb @@ -0,0 +1,43 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'logger' +require 'multi_json' + + +module Usergrid + + LOG = Logger.new(STDOUT) + + USERGRID_PATH = File.join File.dirname(__FILE__), 'usergrid' + + def self.usergrid_path *path + File.join USERGRID_PATH, *path + end + + require usergrid_path('version') + + require usergrid_path('extensions', 'hash') + require usergrid_path('extensions', 'response') + + require usergrid_path('core', 'resource') + require usergrid_path('core', 'management') + require usergrid_path('core', 'organization') + require usergrid_path('core', 'application') + require usergrid_path('core', 'entity') + require usergrid_path('core', 'collection') + + #autoload :Management, usergrid_path('core', 'management') +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/spec_helper.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/spec_helper.rb b/sdks/other/ruby/spec/spec_helper.rb new file mode 100644 index 0000000..88f5b43 --- /dev/null +++ b/sdks/other/ruby/spec/spec_helper.rb @@ -0,0 +1,89 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'simplecov' + +require 'rspec' +require 'yaml' +require 'securerandom' +require_relative '../lib/usergrid_iron' + +LOG = Logger.new(STDOUT) +RestClient.log=LOG + +SimpleCov.at_exit do + SimpleCov.result.format! + #index = File.join(SimpleCov.coverage_path, 'index.html') + #`open #{index}` if File.exists?(index) +end +SimpleCov.start + +SPEC_SETTINGS = YAML::load_file(File.join File.dirname(__FILE__), 'spec_settings.yaml') + +def login_management + management = Usergrid::Resource.new(SPEC_SETTINGS[:api_url]).management + management.login SPEC_SETTINGS[:organization][:username], SPEC_SETTINGS[:organization][:password] + management +end + +# ensure we are correctly setup (management login & organization) +management = login_management + +begin + management.create_organization(SPEC_SETTINGS[:organization][:name], + SPEC_SETTINGS[:organization][:username], + SPEC_SETTINGS[:organization][:username], + "#{SPEC_SETTINGS[:organization][:username]}@email.com", + SPEC_SETTINGS[:organization][:password]) + LOG.info "created organization with user #{SPEC_SETTINGS[:organization][:username]}@email.com" +rescue + if MultiJson.load($!.response)['error'] == "duplicate_unique_property_exists" + LOG.debug "test organization exists" + else + raise $! + end +end + +def create_random_application + management = login_management + organization = management.organization SPEC_SETTINGS[:organization][:name] + + app_name = "_test_app_#{SecureRandom.hex}" + organization.create_application app_name + management.application SPEC_SETTINGS[:organization][:name], app_name +end + +def delete_application(application) + management = login_management + application.auth_token = management.auth_token + # application.delete rescue nil # not implemented on server yet +end + +def create_random_user(application, login=false) + random = SecureRandom.hex + user_hash = {username: "username_#{random}", + password: random, + email: "#{random}@email.com", + name: "#{random} name" } + entity = application['users'].post(user_hash).entity + application.login user_hash[:username], user_hash[:password] if login + entity +end + +RSpec.configure do |config| + config.filter_run focus: true + config.run_all_when_everything_filtered = true + config.treat_symbols_as_metadata_keys_with_true_values = true +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/spec_settings.yaml ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/spec_settings.yaml b/sdks/other/ruby/spec/spec_settings.yaml new file mode 100644 index 0000000..7f82f40 --- /dev/null +++ b/sdks/other/ruby/spec/spec_settings.yaml @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +:api_url: http://localhost:8080 +:management: + :username: test + :password: test +:organization: + :name: test-organization + :username: test + :password: test +:application: + :name: test-app + :username: test-app-user + :password: test http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/usergrid/core/application_spec.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/usergrid/core/application_spec.rb b/sdks/other/ruby/spec/usergrid/core/application_spec.rb new file mode 100644 index 0000000..f2b479e --- /dev/null +++ b/sdks/other/ruby/spec/usergrid/core/application_spec.rb @@ -0,0 +1,342 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +describe Usergrid::Application do + + before :all do + @application = create_random_application + @user = create_random_user @application, true + end + + after :all do + @user.delete + delete_application @application + end + + it "should be able to create a user using deprecated syntax" do + random = SecureRandom.hex + response = @application.create_user "username_#{random}", 'password' + response.entity.uuid.should_not be_nil + end + + it "should be able to create, login, and delete a user" do + random = SecureRandom.hex + application = Usergrid::Application.new @application.url # create application resource that's not logged in + response = application.create_user username: "username_#{random}", password: 'password' + entity = response.entity + application.login "username_#{random}", 'password' + begin + response.code.should eq 200 + response.entities.size.should eq 1 + entity.uuid.should_not be_nil + response = application["users/#{entity.uuid}"].get + response.code.should eq 200 + ensure + entity.delete + # deleted user shouldn't be able to access anything now + expect { application["users/#{entity.uuid}"].get }.to raise_error(RestClient::Unauthorized) + # use original application - logged in under existing user + expect { @application["users/#{entity.uuid}"].get }.to raise_error(RestClient::ResourceNotFound) + end + end + + it "should be able to retrieve users" do + entity1 = create_random_user @application + entity2 = create_random_user @application + begin + response = @application.users + response.entities.size.should be >= 2 + match1 = match2 = false + response.entities.each do |e| + match1 ||= e.username == entity1.username + match2 ||= e.username == entity2.username + end + match1.should be_true + match2.should be_true + ensure + entity1.delete + entity2.delete + end + response = @application.users + response.code.should eq 200 + response.entities.should be_an Array + end + + it "should be able to query users" do + entity1 = create_random_user @application + entity2 = create_random_user @application + begin + response = @application.users "select * where username = \'#{entity1.username}\'" + response.entities.size.should eq 1 + response.entity.username.should eq entity1.username + ensure + entity1.delete + entity2.delete + end + end + + it "should be able to update a user" do + entity = create_random_user @application + begin + updates = { email: 'testus...@email.com', city: 'santa clarita' } + response = @application.put updates + updates.each {|k,v| response.entity[k.to_s].should eq v } + ensure + entity.delete + end + end + + it "should be able to retrieve the logged in user" do + user = @application.current_user + user.uuid.should_not be_nil + end + + it "should be able to add and retrieve activities" do + user = @application.current_user + activity = { + verb: "post", + content: "testy, testy", + actor: { + uuid: user.uuid, + email: user.email, + username: user.username, + displayName: user.username, + image: { + height: 80, + width: 80, + url: user.picture + }}} + response = @application['activities'].post activity + activity_path = response.entity['metadata']['path'] + response.code.should eq 200 + + begin + entity = @application.activities.entity + activity.add_dot_notation! + entity.verb.should eq activity.verb + entity.content.should eq activity.content + entity.actor.uuid.should eq activity.actor.uuid + ensure + @application[activity_path].delete + end + end + + it "should be able to retrieve a user's feed" do + response = @application.current_user.resource['feed'].get + response.code.should eq 200 + response.entities.should be_an Array + end + + it "should be able to follow a user" do + follower = create_random_user @application + begin + me = @application.current_user + @application["users/#{follower.uuid}/following/users/#{me.uuid}"].post "{}" + + response = @application["users/#{follower.uuid}/following"].get + response.entities.size.should == 1 + response.entity.uuid.should eq me.uuid + + response = @application.current_user.resource['followers'].get + response.entities.size.should be > 0 + ensure + follower.delete + end + end + + it "should be able to create and retrieve groups" do + response = @application.groups + size = response.entities.size + random = SecureRandom.hex + @application.create_entity :groups, path: "test-#{random}" + response = @application.groups + response.entities.size.should eq size+1 + end + + it "should be able to create and retrieve devices" do + response = @application.devices + size = response.entities.size + random = SecureRandom.hex + @application.create_entity :devices, path: "test-#{random}" + response = @application.devices + response.entities.size.should eq size+1 + end + + it "should be able to create and retrieve assets" do + response = @application.assets + size = response.entities.size + random = SecureRandom.hex + @application.create_entity :assets, path: "test-#{random}", owner: @application.current_user.uuid + response = @application.assets + response.entities.size.should eq size+1 + end + + it "should be able to create and retrieve folders" do + response = @application.folders + size = response.entities.size + random = SecureRandom.hex + @application.create_entity :folders, path: "test-#{random}", owner: @application.current_user.uuid + response = @application.folders + response.entities.size.should eq size+1 + end + + # can't reliably test this - counters are batched on server + #it "should be able to create and retrieve events and retrieve counters" do + # # clear events + # {} while @application.events.entities.size > 0 + # + # events_in = [] + # events_in << {timestamp: 0, category: 'test', counters: { test: 1 }} + # events_in << {timestamp: 0, category: 'testme', counters: { testme: 1 }} + # events_in << {timestamp: 0, counters: { test: 1 }} + # events_in.each {|e| @application.create_entity :events, e } + # + # events_out = [] + # events_out << @application.events.entity + # events_out << @application.events.entity + # events_out << @application.events.entity + # + # (0..2).each do |i| + # events_in[i][:category].should eq events_out[i]['category'] + # end + # + # response = @application.events + # response.entities.size.should eq 0 + # + # # get and test counters + # counter_names = @application.counter_names + # counter_names.should include 'test' + # counter_names.should include 'testme' + # + # response = @application.counter 'test' + # counter = response.data.counters.first + # counter.name.should eq 'test' + # counter.values.last.first.value.should be > 0 + #end + + it "should be able to create, retrieve, and delete roles" do + size = @application.roles.collection.size + + role_name = "test-#{SecureRandom.hex}" + @application.create_entity :role, name: role_name, title: 'title', inactivity: 0 + roles = @application.roles.collection + roles.size.should eq size+1 + role = roles.detect {|r| r.name == role_name } + role.should_not be_nil + + role.delete + @application.roles.collection.size.should eq size + end + + it "should be able to add/remove permissions from a user" do + user = create_random_user @application + permission = 'post:/users/*' + user.resource['permissions'].post permission: permission + + permissions = user.resource['permissions'].get.data.data + permissions.size.should eq 1 + permissions.first.should eq permission + + user.resource['permissions'].delete({params: { permission: permission }}) + + permissions = user.resource['permissions'].get.collection.entities + permissions.size.should eq 0 + end + + it "should be able to add/remove a user from a roles" do + user = create_random_user @application + + roles = user.resource['roles'].get.entities + size = roles.size + + @application["roles/admin/users/#{user.uuid}"].post nil + + roles = user.resource['roles'].get.entities + roles.size.should == size+1 + + @application["roles/admin/users/#{user.uuid}"].delete + + roles = user.resource['roles'].get.entities + roles.size.should == size + end + + it "should be able to create a new collection and access it" do + entities = (1..4).collect { |i| { name: "test_#{i}" } } + @application.create_entities 'tests', entities + response = @application['tests'].get + collection = response.collection + collection.size.should eq 4 + end + + it "should be able to create a new collection via create_ method and access it" do + entities = (1..4).collect { |i| { name: "test_#{i}" } } + @application.create_moretests entities + response = @application['tests'].get + collection = response.collection + collection.size.should eq 4 + end + + it "should be able to access a collection without calling get" do + entities = (1..4).collect { |i| { name: "test_#{i}" } } + @application.create_entities 'tests', entities + collection = @application['tests'].collection + collection.size.should eq 4 + end + + it "should be able to access entities without calling get" do + entities = (1..4).collect { |i| { name: "test_#{i}" } } + @application.create_entities 'tests', entities + entities = @application['tests'].entities + entities.size.should eq 4 + end + + it "should be able to query using dot notation" do + entities = (1..4).collect { |i| { name: "test_#{i}" } } + @application.create_btests entities + entities = @application.btests("name = 'test_1'").entities + entities.size.should eq 1 + end + + describe "grant_type: client_credentials" do + + before(:each) do + @app = create_random_application + end + + context "invalid credentials" do + it "should not be able to get access token with invalid credentials" do + expect { @app.login_credentials "invalid_client_id", "invalid_client_secret" }.to raise_exception RestClient::BadRequest + end + + it "should not be able to get access token with empty credentials" do + expect { @app.login_credentials "", "" }.to raise_exception RestClient::BadRequest + end + end + + context "valid credentials" do + it "should be able to get access token with valid credentials" do + app_info = JSON.parse @app.get + + management = login_management + app = management.application app_info["organization"], app_info["applicationName"] + app_credentials = JSON.parse app.credentials + app.login_credentials app_credentials["credentials"]["client_id"], app_credentials["credentials"]["client_secret"] + + expect(app.auth_token).to_not be_empty + expect(app.auth_token).to be_instance_of String + end + end + end +end \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/usergrid/core/collection_spec.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/usergrid/core/collection_spec.rb b/sdks/other/ruby/spec/usergrid/core/collection_spec.rb new file mode 100644 index 0000000..9ab07c3 --- /dev/null +++ b/sdks/other/ruby/spec/usergrid/core/collection_spec.rb @@ -0,0 +1,125 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +describe Usergrid::Collection do + + before :all do + @application = create_random_application + @user = create_random_user @application, true + + @collection = @application['tests'].collection + @entity_data = (1..25).collect do |i| + { name: "name_#{i}", value: "value_#{i+1}" } + end + (1..3).each {|i| @entity_data[i]['three'] = 3} + @collection.create_entities @entity_data + end + + after :all do + @user.delete + delete_application @application + end + + it "should be able to do a simple query" do + @collection.query "select * where name = \'#{@entity_data[0][:name]}\'" + @collection.size.should eq 1 + end + + it "should be able to select data elements" do + @collection.query "select name, value where name = \'#{@entity_data[0][:name]}\'" + @collection.size.should eq 1 + # note: not Usergrid::Entity objects: it is an Array for this kind of query + values = @collection.entities.first + values[0].should eq @entity_data[0][:name] + values[1].should eq @entity_data[0][:value] + end + + it "should be able to select redefined data elements" do + @collection.query "select { test1: name, test2 : value } where name = \'#{@entity_data[0][:name]}\'" + @collection.size.should eq 1 + # note: not Usergrid::Entity objects: it is a Hash for this kind of query + values = @collection.entities.first + values.test1.should eq @entity_data[0][:name] + values.test2.should eq @entity_data[0][:value] + end + + it "should be able to find an entity" do + @collection.query + entity = @collection.detect { |e| e.name == @entity_data[5][:name] } + entity.should_not be_nil + entity.name.should eq @entity_data[5][:name] + end + + it "should be able to respect query reversal and limits" do + @collection.query nil, reversed: true, start: 5, cursor: nil, limit: 2, permission: nil + @collection.size.should eq 2 + @collection[0].name.should eq @entity_data[@entity_data.size-1][:name] + @collection[1].name.should eq @entity_data[@entity_data.size-2][:name] + end + + it "should be able to select the start by uuid" do + @collection.query + uuid = @collection[4].uuid + @collection.query nil, reversed: false, start: uuid, cursor: nil, limit: 3, permission: nil + @collection.size.should eq 3 + @collection.first.uuid.should eq uuid + @collection[2].name.should eq @entity_data[6][:name] + end + + it "should be able to page forward by cursor" do + @collection.query 'select * where three = 3', limit: 2 + @collection.next_page + @collection.size.should eq 1 + @collection[0].name.should eq @entity_data[3][:name] + end + + it "should be able to update based on a query" do + @collection.update_query({new_field: 'new_value'}, "select * where name = \'#{@entity_data[4][:name]}\'") + @collection.query + entity = @collection.detect { |e| e['new_field'] == 'new_value' } + entity.should_not be_nil + entity.name.should eq @entity_data[4][:name] + end + + it "should be able to delete based on a query" do + @collection.delete_query "select * where name = \'#{@entity_data[5][:name]}\'" + @collection.query + entity = @collection.detect { |e| e['name'] == "#{@entity_data[5][:name]}" } + entity.should be_nil + @entity_data.delete @entity_data[5] + end + + it "should be able to iterate within the page" do + @collection.query + @collection.cursor.should_not be_nil + count = 0 + page_size = @collection.count + @collection.each {|e| count += 1 } + count.should eq page_size + end + + it "should be able to iterate over pages" do + @collection.query + @collection.cursor.should_not be_nil + count = 0 + seen = Set.new + @collection.follow_cursor.each do |e| + seen.add?(e.uuid).should_not be_nil + count += 1 + end + count.should eq @entity_data.size + end + +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/usergrid/core/entity_spec.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/usergrid/core/entity_spec.rb b/sdks/other/ruby/spec/usergrid/core/entity_spec.rb new file mode 100644 index 0000000..887fa91 --- /dev/null +++ b/sdks/other/ruby/spec/usergrid/core/entity_spec.rb @@ -0,0 +1,91 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +describe Usergrid::Entity do + + before :all do + @application = create_random_application + @user = create_random_user @application, true + end + + after :all do + @user.delete + delete_application @application + end + + it "should be able to retrieve its collection" do + collection = @user.collection + collection.should_not be_nil + u = collection.detect {|u| u.uuid == @user.uuid } + u.uuid.should eq @user.uuid + end + + it "should be able to reload its data" do + old_name = @user.name + @user.name = 'new name' + @user.name.should eq 'new name' + @user.get + @user.name.should eq old_name + end + + it "should be able to save" do + @user.name = 'new name' + @user.save + @user.name.should eq 'new name' + end + + it "should be able to print itself" do + p = @user.to_s + p.start_with?('resource').should be_true + end + + it "should know if it has data" do + @user.data?.should be_true + empty = Usergrid::Entity.new 'url', 'url' + empty.data?.should be_false + end + + it "should return nil if empty result" do + @application['foobars'].get.entity.should be_nil + end + + it "should not serialize reserved attributes" do + dump = MultiJson.dump @user + hash = MultiJson.load dump + Usergrid::Resource::RESERVED.each { |a| hash.should_not have_key(a) } + end + + it "should be able to delete itself" do + user = create_random_user @application + name = user.name + user.delete + u = @application['users'].entities.detect {|e| e.name == "#{name}"} + u.should be_nil + end + + it "should be able to update and delete by query" do + dog = (@application.create_dog name: 'Vex').entity + + @application['dogs'].update_query({foo: 'bar'}, "select * where name = \'#{dog.name}\'") + dog.get + dog.foo.should eq('bar') + + @application['dogs'].delete_query "select * where name = \'#{dog.name}\'" + + dog = @application['dogs'].entities.detect {|e| e.name == "#{dog.name}"} + dog.should be_nil + end + +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/usergrid/core/management_spec.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/usergrid/core/management_spec.rb b/sdks/other/ruby/spec/usergrid/core/management_spec.rb new file mode 100644 index 0000000..f53d572 --- /dev/null +++ b/sdks/other/ruby/spec/usergrid/core/management_spec.rb @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +describe Usergrid::Management do + + before :all do + @base_resource = Usergrid::Resource.new(SPEC_SETTINGS[:api_url]) + @management = @base_resource.management + @management.login SPEC_SETTINGS[:management][:username], SPEC_SETTINGS[:management][:password] + end + + it "should be able to create an organization" do + # can't delete an org or a user, so we create new random ones and leave them + random = SecureRandom.hex + org_name = "test_org_#{random}" + user_name = "test_admin_#{random}" + response = @management.create_organization("#{org_name}", + "#{user_name}", + "#{user_name}", + "#{user_name}@email.com", + "#{random}") + response.code.should eq 200 + #@base_resource["users/#{user_name}"].delete + end + + # this is broken on the server + #it "should be able to get organizations" do + # response = @management.organizations + #end + + it "should be able to get an organization" do + organization = @management.organization SPEC_SETTINGS[:organization][:name] + organization.should be_a Usergrid::Organization + org_ent = organization.get.entity + org_ent.uuid.should_not be_nil + org_ent.name.should eq SPEC_SETTINGS[:organization][:name] + end + +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/usergrid/core/organization_spec.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/usergrid/core/organization_spec.rb b/sdks/other/ruby/spec/usergrid/core/organization_spec.rb new file mode 100644 index 0000000..93092fc --- /dev/null +++ b/sdks/other/ruby/spec/usergrid/core/organization_spec.rb @@ -0,0 +1,113 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +describe Usergrid::Organization do + + before :each do + @management = Usergrid::Resource.new(SPEC_SETTINGS[:api_url]).management + @management.login SPEC_SETTINGS[:organization][:username], SPEC_SETTINGS[:organization][:password] + @organization = @management.organization SPEC_SETTINGS[:organization][:name] + end + + it "should be able to create (and delete) an application" do + app_name = "test_app_#{SecureRandom.hex}" + app = @organization.create_application app_name + app.should be_an Usergrid::Application + + response = @organization["applications/#{app_name}"].delete + response.code.should eq 200 + end + + it "should be able to get applications" do + response = @organization.applications + response.should be_an Array + if response.size > 0 + app = response.first + app.should be_an Usergrid::Application + end + end + + it "should be able to get users" do + response = @organization.users + response.code.should eq 200 + response.entities.should be_an Array + response.entities[0].uuid.should_not be_nil + end + + it "should be able to get a user" do + response = @organization.user(SPEC_SETTINGS[:organization][:username]) + response.code.should eq 200 + response.entity.uuid.should_not be_nil + end + + it "should be able to get an application" do + app_name = "test_app_#{SecureRandom.hex}" + @organization.create_application app_name + begin + app = @organization.application app_name + app.should be_an Usergrid::Application + ensure + @organization["applications/#{app_name}"].delete + end + end + + it "should be able to get feed" do + response = @organization.feed + entities = response.entities + entities.size.should be > 0 + entities.first.uuid.should_not be_nil + end + + it "should be able to get credentials" do + response = @organization.credentials + response.code.should eq 200 + response.data.credentials.client_id.should_not be_nil + response.data.credentials.client_secret.should_not be_nil + end + + it "should be able to generate credentials" do + response = @organization.generate_credentials + response.code.should eq 200 + response.data.credentials.client_id.should_not be_nil + response.data.credentials.client_secret.should_not be_nil + end + + describe "grant_type: client_credentials" do + context "invalid credentials" do + before :each do + @organization.logout + end + + it "should not be able to get access token with invalid credentials" do + expect { @organization.login_credentials "invalid_client_id", "invalid_client_secret" }.to raise_exception RestClient::BadRequest + end + + it "should not be able to get access token with empty credentials" do + expect { @organization.login_credentials "", "" }.to raise_exception RestClient::BadRequest + end + end + + context "valid crendentials" do + it "should be able to get access token with valid credentials" do + org_credentials = JSON.parse @organization.credentials + @organization.logout + @organization.login_credentials org_credentials["credentials"]["client_id"], org_credentials["credentials"]["client_secret"] + + expect(@organization.auth_token).to_not be_empty + expect(@organization.auth_token).to be_instance_of String + end + end + end +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/usergrid/core/resource_spec.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/usergrid/core/resource_spec.rb b/sdks/other/ruby/spec/usergrid/core/resource_spec.rb new file mode 100644 index 0000000..82a1ace --- /dev/null +++ b/sdks/other/ruby/spec/usergrid/core/resource_spec.rb @@ -0,0 +1,63 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +describe Usergrid::Resource do + + before :all do + @resource = Usergrid::Resource.new SPEC_SETTINGS[:api_url] + end + + it "should succeed on status check" do + response = @resource['/status'].get + + response.code.should eq 200 + response.data.should be_a Hash + end + + it "should fail with a 400 when no auth given" do + expect { @resource['management'].get }.to raise_error(RestClient::BadRequest) { |exception| + exception.response.code.should eq 400 + } + end + + it "should fail with a 401 when lacking auth" do + app_endpoint = "#{SPEC_SETTINGS[:organization][:name]}/#{SPEC_SETTINGS[:application][:name]}" + expect { @resource[app_endpoint].get }.to raise_error(RestClient::Unauthorized) { |exception| + exception.response.code.should eq 401 + } + end + + it "should be able to login" do + resource = @resource['management'] + response = resource.login SPEC_SETTINGS[:management][:username], SPEC_SETTINGS[:management][:password] + + response.code.should eq 200 + resource.auth_token.should_not be_nil + response.data['access_token'].should eq resource.auth_token + resource.options[:headers][:Authorization].should eq "Bearer #{resource.auth_token}" + resource.logged_in?.should be_true + end + + it "should be able to log out" do + resource = @resource['management'] + resource.login SPEC_SETTINGS[:management][:username], SPEC_SETTINGS[:management][:password] + resource.logged_in?.should be_true + + resource.logout + resource.options[:headers][:Authorization].should be_nil + resource.logged_in?.should be_false + end + +end \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/spec/usergrid/extensions/hash_spec.rb ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/spec/usergrid/extensions/hash_spec.rb b/sdks/other/ruby/spec/usergrid/extensions/hash_spec.rb new file mode 100644 index 0000000..9dbecdb --- /dev/null +++ b/sdks/other/ruby/spec/usergrid/extensions/hash_spec.rb @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative '../../../lib/usergrid/extensions/hash' + +describe Hash do + + it "should add dot notation recursively" do + h = { test1: 'test1', test2: { test2a: 'test2a' }, test3: [ { test3a: 'test3a' }] } + expect { h.test1 }.to raise_error + h.add_dot_notation! + h.test1.should eq 'test1' + h.test2.test2a.should eq 'test2a' + h.test3.first.test3a.should eq 'test3a' + h.test1 = 'testx' + h.test1.should eq 'testx' + end + + it "should symbolize keys at top level" do + h = { 'test1' => 'test1', 'test2' => { 'test2a' => 'test2a' }, 'test3' => [ { 'test3a' => 'test3a' }] } + h['test1'].should eq 'test1' + h = h.symbolize_keys + h['test1'].should be_nil + h[:test1].should eq 'test1' + h[:test2][:test2a].should be_nil + h[:test3].first['test3a'].should eq 'test3a' + end +end \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ruby/usergrid_iron.gemspec ---------------------------------------------------------------------- diff --git a/sdks/other/ruby/usergrid_iron.gemspec b/sdks/other/ruby/usergrid_iron.gemspec new file mode 100644 index 0000000..f9bc46e --- /dev/null +++ b/sdks/other/ruby/usergrid_iron.gemspec @@ -0,0 +1,41 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# -*- encoding: utf-8 -*- +require File.expand_path('../lib/usergrid/version', __FILE__) + +Gem::Specification.new do |gem| + gem.authors = ["Scott Ganyo"] + gem.email = ["sc...@ganyo.com"] + gem.description = %q{Low-level gem to access Usergrid / Apigee App Services} + gem.summary = %q{Usergrid_iron enables simple, low-level Ruby access to Apigee's App Services + (aka Usergrid) REST API with minimal dependencies.} + gem.homepage = "https://github.com/scottganyo/usergrid_iron" + + gem.files = `git ls-files`.split($\) + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(spec|spec|features)/}) + gem.name = "usergrid_iron" + gem.require_paths = ["lib"] + gem.version = Usergrid::VERSION + + gem.add_dependency 'rest-client' + gem.add_dependency 'multi_json' + + gem.add_development_dependency 'rake' + gem.add_development_dependency 'rspec' + gem.add_development_dependency 'simplecov' +end http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/perl/Build.PL ---------------------------------------------------------------------- diff --git a/sdks/perl/Build.PL b/sdks/perl/Build.PL deleted file mode 100644 index 71bcf10..0000000 --- a/sdks/perl/Build.PL +++ /dev/null @@ -1,46 +0,0 @@ - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -use 5.006; -use strict; -use warnings FATAL => 'all'; -use Module::Build; - -my $builder = Module::Build->new( - module_name => 'Usergrid::Client', - license => 'Apache_2_0', - abstract => 'Client API for Apache Usergrid', - dist_author => 'Anuradha Weeraman <anura...@cpan.org>', - dist_version_from => 'lib/Usergrid/Client.pm', - release_status => 'stable', - configure_requires => { - 'Module::Build' => 0, - }, - build_requires => { - 'Test::More' => 0, - }, - requires => { - 'Moose' => 0, - 'JSON' => 0, - 'REST::Client' => 0, - 'URI::Template' => 0, - 'Log::Log4perl' => 0, - 'namespace::autoclean' => 0 - }, - add_to_cleanup => [ 'Usergrid-Client-*' ] -); - -$builder->create_build_script(); http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/perl/LICENSE ---------------------------------------------------------------------- diff --git a/sdks/perl/LICENSE b/sdks/perl/LICENSE deleted file mode 100644 index e06d208..0000000 --- a/sdks/perl/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/perl/MANIFEST ---------------------------------------------------------------------- diff --git a/sdks/perl/MANIFEST b/sdks/perl/MANIFEST deleted file mode 100644 index 4169300..0000000 --- a/sdks/perl/MANIFEST +++ /dev/null @@ -1,23 +0,0 @@ -.travis.yml -Build.PL -examples/books.pl -lib/Usergrid/Client.pm -lib/Usergrid/Collection.pm -lib/Usergrid/Entity.pm -lib/Usergrid/Request.pm -LICENSE -Makefile.PL -MANIFEST This list of files -META.json -META.yml -README.md -t/01_init.t -t/02_login.t -t/03_update.t -t/04_collection.t -t/05_query.t -t/06_batch_update.t -t/07_batch_delete.t -t/08_connections.t -t/09_paging.t -t/10_auto_paging.t http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/perl/Makefile.PL ---------------------------------------------------------------------- diff --git a/sdks/perl/Makefile.PL b/sdks/perl/Makefile.PL deleted file mode 100644 index 6ab9874..0000000 --- a/sdks/perl/Makefile.PL +++ /dev/null @@ -1,41 +0,0 @@ - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -use strict; -use warnings; - -use 5.008; - -use ExtUtils::MakeMaker; - -WriteMakefile( - LICENSE => 'apache', - AUTHOR => 'Anuradha Weeraman <anura...@cpan.org', - ABSTRACT => 'Client API for Apache Usergrid', - NAME => 'Usergrid::Client', - VERSION_FROM => 'lib/Usergrid/Client.pm', - PREREQ_PM => { - 'Moose' => 0, - 'JSON' => 0, - 'REST::Client' => 0, - 'URI::Template' => 0, - 'Log::Log4perl' => 0, - 'namespace::autoclean' => 0 - }, - BUILD_REQUIRES => { - 'Test::More' => '0.98' - } -);