diff --git a/Gemfile.lock b/Gemfile.lock index 6ba659f..f50a52e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,5 +1,5 @@ GIT - remote: git://github.com/pivotal/sinclair.git + remote: https://github.com/pivotal/sinclair.git revision: b8c88158d000e75c6b8296a96e2dfe6da82ed823 specs: sinclair (0.2.0) @@ -219,7 +219,7 @@ GEM http_parser.rb (~> 0.6.0) multi_json puma (2.16.0) - rack (1.6.4) + rack (1.6.13) rack-cors (0.4.0) rack-test (0.6.3) rack (>= 1.0) diff --git a/vendor/cache/ffi-1.9.14.gem b/vendor/cache/ffi-1.9.14.gem new file mode 100644 index 0000000..4d0db22 Binary files /dev/null and b/vendor/cache/ffi-1.9.14.gem differ diff --git a/vendor/cache/rack-1.6.13.gem b/vendor/cache/rack-1.6.13.gem new file mode 100644 index 0000000..cea335c Binary files /dev/null and b/vendor/cache/rack-1.6.13.gem differ diff --git a/vendor/cache/rack-1.6.4.gem b/vendor/cache/rack-1.6.4.gem deleted file mode 100644 index 6d06fed..0000000 Binary files a/vendor/cache/rack-1.6.4.gem and /dev/null differ diff --git a/vendor/cache/rubyzip-1.2.0.gem b/vendor/cache/rubyzip-1.2.0.gem new file mode 100644 index 0000000..021092a Binary files /dev/null and b/vendor/cache/rubyzip-1.2.0.gem differ diff --git a/vendor/cache/selenium-webdriver-2.53.4.gem b/vendor/cache/selenium-webdriver-2.53.4.gem new file mode 100644 index 0000000..c5620eb Binary files /dev/null and b/vendor/cache/selenium-webdriver-2.53.4.gem differ diff --git a/vendor/cache/sinclair-b8c88158d000/.bundlecache b/vendor/cache/sinclair-b8c88158d000/.bundlecache new file mode 100644 index 0000000..e69de29 diff --git a/vendor/cache/sinclair-b8c88158d000/.gitignore b/vendor/cache/sinclair-b8c88158d000/.gitignore new file mode 100644 index 0000000..9106b2a --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/.gitignore @@ -0,0 +1,8 @@ +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ diff --git a/vendor/cache/sinclair-b8c88158d000/.rspec b/vendor/cache/sinclair-b8c88158d000/.rspec new file mode 100644 index 0000000..8c18f1a --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/.rspec @@ -0,0 +1,2 @@ +--format documentation +--color diff --git a/vendor/cache/sinclair-b8c88158d000/.ruby-version b/vendor/cache/sinclair-b8c88158d000/.ruby-version new file mode 100644 index 0000000..276cbf9 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/.ruby-version @@ -0,0 +1 @@ +2.3.0 diff --git a/vendor/cache/sinclair-b8c88158d000/.travis.yml b/vendor/cache/sinclair-b8c88158d000/.travis.yml new file mode 100644 index 0000000..eb6b0b7 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/.travis.yml @@ -0,0 +1,9 @@ +language: ruby +rvm: + - 2.1.5 + +before_install: gem install bundler + +addons: + code_climate: + repo_token: 8072f0a2d484fa3f658829f9c44ebbd4c10647800cb3a2fa0f3f7337be585050 diff --git a/vendor/cache/sinclair-b8c88158d000/Gemfile b/vendor/cache/sinclair-b8c88158d000/Gemfile new file mode 100644 index 0000000..9ee599f --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in sinclair.gemspec +gemspec diff --git a/vendor/cache/sinclair-b8c88158d000/LICENSE.txt b/vendor/cache/sinclair-b8c88158d000/LICENSE.txt new file mode 100644 index 0000000..bfb4cf5 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 TODO: Write your name + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/cache/sinclair-b8c88158d000/README.md b/vendor/cache/sinclair-b8c88158d000/README.md new file mode 100644 index 0000000..2728d51 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/README.md @@ -0,0 +1,75 @@ +# Sinclair + +[![Build Status](https://travis-ci.org/pivotal/sinclair.svg)](https://travis-ci.org/pivotal/sinclair) +[![Code Climate](https://codeclimate.com/github/pivotal/sinclair/badges/gpa.svg)](https://codeclimate.com/github/pivotal/sinclair) +[![Test Coverage](https://codeclimate.com/github/pivotal/sinclair/badges/coverage.svg)](https://codeclimate.com/github/pivotal/sinclair/coverage) + +![Sinclair the Dinosaur](http://www.monsterbashnews.com/Morepics/SinclairOilLogo.jpg) + +Sinclair is a gem that makes using the OpenAir API tolerable. + +## Usage + +### Basic Usage + +Create the API client using your connection parameters: + +``` +client = Sinclair::OpenAirApiClient.new( + username: 'Username', password: 'Password', company: 'Company', client: 'Client', key: 'APIKEY' +) +``` + +Create an XML ERB template containing your OpenAir request: + +``` + + + <%= name %> + + + +``` + +Make the request: + +``` +template = File.read('your template file') +customers = client.send_request(template: template, model: 'Customer', locals: { name: 'Foo' }) +``` + +Note that `model` should be the type of data returned by the API. In the above example, we are requesting `Customer` data, so the `model` would be `Customer`. The return value includes all of the XML response data that is nested under `model`. + +By default, Sinclair will make a `Read` request. To change the type of request, supply a `method` argument: + +``` +customers = client.send_request(template: template, model: 'Customer', method: 'Add') +``` + +Sinclair will always return an array of items regardless of the number of items returned. + +### Pagination + +Sinclair will attempt to make additional requests if the number of items returned is equal to the limit supplied in the request. When this happens, Sinclair will add an `offset` parameter to the locals used to render the template. You will need to change your request template to include the `offset`. + +``` + + + <%= name %> + + +``` + +### Debugging + +If you want to see the actual requests Sinclair is making, you can supply a logger which Sinclair will use to log both the requests and responses seen from OpenAir: + +``` +client.logger = Logger.new(STDOUT) +client.logger.level = Logger::DEBUG +``` + +## License + +The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). + diff --git a/vendor/cache/sinclair-b8c88158d000/Rakefile b/vendor/cache/sinclair-b8c88158d000/Rakefile new file mode 100644 index 0000000..b7e9ed5 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/Rakefile @@ -0,0 +1,6 @@ +require "bundler/gem_tasks" +require "rspec/core/rake_task" + +RSpec::Core::RakeTask.new(:spec) + +task :default => :spec diff --git a/vendor/cache/sinclair-b8c88158d000/bin/console b/vendor/cache/sinclair-b8c88158d000/bin/console new file mode 100755 index 0000000..96c5852 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/bin/console @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "sinclair" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start diff --git a/vendor/cache/sinclair-b8c88158d000/bin/setup b/vendor/cache/sinclair-b8c88158d000/bin/setup new file mode 100755 index 0000000..b65ed50 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/bin/setup @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +bundle install + +# Do any other automated setup that you need to do here diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair.rb new file mode 100644 index 0000000..dd2535b --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair.rb @@ -0,0 +1,12 @@ +require 'sinclair/version' +require 'sinclair/request' +require 'sinclair/open_air_api_client' +require 'sinclair/errors/open_air_authentication_failure' +require 'sinclair/errors/open_air_response_error' +require 'sinclair/errors/open_air_invalid_data' +require 'sinclair/errors/open_air_response_timeout' +require 'sinclair/errors/open_air_response_unrecognized' +require 'sinclair/errors/open_air_user_locked' + +module Sinclair +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_authentication_failure.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_authentication_failure.rb new file mode 100644 index 0000000..7535f71 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_authentication_failure.rb @@ -0,0 +1,4 @@ +module Sinclair + class OpenAirAuthenticationFailure < StandardError + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_invalid_data.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_invalid_data.rb new file mode 100644 index 0000000..3eaebce --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_invalid_data.rb @@ -0,0 +1,13 @@ +module Sinclair + class OpenAirInvalidData < StandardError + attr_reader :errors + + def initialize(errors) + @errors = errors + end + + def message + errors.join(', ') + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_error.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_error.rb new file mode 100644 index 0000000..d791693 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_error.rb @@ -0,0 +1,13 @@ +module Sinclair + class OpenAirResponseError < StandardError + attr_reader :status + + def initialize(status) + @status = status + end + + def message + "Error making OpenAir request. Got status #{@status}." + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_timeout.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_timeout.rb new file mode 100644 index 0000000..6600d6f --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_timeout.rb @@ -0,0 +1,4 @@ +module Sinclair + class OpenAirResponseTimeout < StandardError + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_unrecognized.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_unrecognized.rb new file mode 100644 index 0000000..4ec8392 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_response_unrecognized.rb @@ -0,0 +1,13 @@ +module Sinclair + class OpenAirResponseUnrecognized < StandardError + attr_reader :response + + def initialize(response) + @response = response + end + + def message + "Unknown OpenAir response: #{response}" + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_user_locked.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_user_locked.rb new file mode 100644 index 0000000..969ef9d --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/errors/open_air_user_locked.rb @@ -0,0 +1,4 @@ +module Sinclair + class OpenAirUserLocked < StandardError + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/open_air_api_client.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/open_air_api_client.rb new file mode 100644 index 0000000..4402517 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/open_air_api_client.rb @@ -0,0 +1,134 @@ +require 'nori' +require 'faraday' +require 'nokogiri' + +module Sinclair + class OpenAirApiClient + attr_accessor :logger, :last_request, :last_response + + def initialize(username:, password:, company:, client:, key:, url: 'https://www.openair.com', limit: '1000', timeout: 180, open_timeout: 120) + @username = username + @password = password + @company = company + @client = client + @key = key + @url = url + @limit = limit + @timeout = timeout + @open_timeout = open_timeout + end + + def send_request(template: , model: , method: 'Read', locals: {}) + response = {} + response[model] = [] + + while true + page = process_page(template: template, method: method, model: model, locals: {offset: response[model].length}.merge(locals)) + break unless page[model] + returned_models = page.keys + returned_models.each do |m| + response[m] ? response[m] += page[m] : response[m] = page[m] + end + break if page[model].length < @limit.to_i + end + response + end + + private + + def process_page(template:, method:, model:, locals: {}) + response = make_request(locals, template) + + log_request unless logger.nil? + + check_auth_status(response) + + read = response['response'][method] + read = [read] unless read.is_a?(Array) + + check_response_status(read, model) + map_response_by_model(read) + end + + def make_request(locals, template) + response = get_response(template, locals) + self.last_response = response.body + Nori.new(advanced_typecasting: false).parse(response.body) + end + + def invalid_read_status(status) + status != 0 && status != 601 + end + + def map_response_by_model(response) + result = {} + returned_models = find_returned_models(response) + returned_models.each { |m| result[m] = [] } + + response.each do |r| + model = returned_models.find{|m| r.keys.include?(m)} + result[model] << r[model] + end + + result.map do |model, items| + result[model] = items.flatten.compact + end + + result + end + + def find_returned_models(response) + response.map do |r| + r.keys[0] + end.compact.uniq + end + + def check_auth_status(response) + raise Sinclair::OpenAirResponseUnrecognized.new(response) if response['response']['Auth'].nil? + + auth_status = response['response']['Auth']['@status'].to_i + raise Sinclair::OpenAirUserLocked if auth_status == 416 + raise Sinclair::OpenAirAuthenticationFailure if auth_status != 0 + end + + def check_response_status(read, model) + statuses = read.map { |r| r['@status'].to_i } + if statuses.any? { |s| s == 1002 } + errors = read.select{|r| r['@status'].to_i == 1002}.map{|r| r[model]['errors']} + raise Sinclair::OpenAirInvalidData.new(errors) + elsif statuses.any? { |s| invalid_read_status(s) } + raise Sinclair::OpenAirResponseError.new(statuses.find { |s| invalid_read_status(s) }) + end + end + + def get_response(template, locals = {}) + options = {request: {timeout: @timeout, open_timeout: @open_timeout}} + begin + locals = locals.merge(username: @username, password: @password, company: @company, client: @client, key: @key, limit: @limit) + Faraday.new(@url, options).post('/api.pl') do |request| + request.body = Sinclair::Request.new(template).render(locals) + request.headers.merge!({'Accept-Encoding' => 'identity'}) + self.last_request = request.body + end + rescue Faraday::TimeoutError + raise Sinclair::OpenAirResponseTimeout + end + end + + def log_request + logger.debug('#' * 80) + logger.debug('# REQUEST') + logger.debug('#' * 80) + logger.debug(last_request) + + logger.debug('#' * 80) + logger.debug('# RESPONSE') + logger.debug('#' * 80) + logger.debug(last_response) + end + + def wrap_response(response) + response.is_a?(Array) ? response : [response] + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/request.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/request.rb new file mode 100644 index 0000000..d7928b7 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/request.rb @@ -0,0 +1,24 @@ +require 'erb' +require 'ostruct' + +module Sinclair + class Request + def initialize(body) + @body = body + @header = File.read(File.expand_path('../templates/request_header.xml.erb', __FILE__)) + end + + def render(locals) + templates = [@body, @header] + templates.inject(nil) do |prev, temp| + _render(temp, locals) { prev } + end + end + + private + + def _render(temp, locals) + ERB.new(temp).result(OpenStruct.new(locals).instance_eval { binding }).strip + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/templates/request_header.xml.erb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/templates/request_header.xml.erb new file mode 100644 index 0000000..030dcf3 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/templates/request_header.xml.erb @@ -0,0 +1,11 @@ + + + + + <%= company %> + <%= username %> + <%= password %> + + + <%= yield %> + diff --git a/vendor/cache/sinclair-b8c88158d000/lib/sinclair/version.rb b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/version.rb new file mode 100644 index 0000000..6bcf2c9 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/lib/sinclair/version.rb @@ -0,0 +1,3 @@ +module Sinclair + VERSION = '0.2.0' +end diff --git a/vendor/cache/sinclair-b8c88158d000/sinclair.gemspec b/vendor/cache/sinclair-b8c88158d000/sinclair.gemspec new file mode 100644 index 0000000..affb530 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/sinclair.gemspec @@ -0,0 +1,46 @@ +# -*- encoding: utf-8 -*- +# stub: sinclair 0.2.0 ruby lib + +Gem::Specification.new do |s| + s.name = "sinclair".freeze + s.version = "0.2.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Pivotal IAD".freeze] + s.bindir = "exe".freeze + s.date = "2024-02-29" + s.description = "Sinclair is a gem that makes using the OpenAir API tolerable.".freeze + s.email = ["iad-dev@pivotal.io".freeze] + s.files = [".gitignore".freeze, ".rspec".freeze, ".ruby-version".freeze, ".travis.yml".freeze, "Gemfile".freeze, "LICENSE.txt".freeze, "README.md".freeze, "Rakefile".freeze, "bin/console".freeze, "bin/setup".freeze, "lib/sinclair.rb".freeze, "lib/sinclair/errors/open_air_authentication_failure.rb".freeze, "lib/sinclair/errors/open_air_invalid_data.rb".freeze, "lib/sinclair/errors/open_air_response_error.rb".freeze, "lib/sinclair/errors/open_air_response_timeout.rb".freeze, "lib/sinclair/errors/open_air_response_unrecognized.rb".freeze, "lib/sinclair/errors/open_air_user_locked.rb".freeze, "lib/sinclair/open_air_api_client.rb".freeze, "lib/sinclair/request.rb".freeze, "lib/sinclair/templates/request_header.xml.erb".freeze, "lib/sinclair/version.rb".freeze, "sinclair.gemspec".freeze] + s.homepage = "http://github.com/pivotal/sinclair".freeze + s.licenses = ["MIT".freeze] + s.rubygems_version = "3.3.26".freeze + s.summary = "Sinclair is a gem that makes using the OpenAir API tolerable.".freeze + + s.installed_by_version = "3.3.26" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 4 + end + + if s.respond_to? :add_runtime_dependency then + s.add_runtime_dependency(%q.freeze, ["~> 2.6.0"]) + s.add_runtime_dependency(%q.freeze, ["~> 0.9.0"]) + s.add_runtime_dependency(%q.freeze, ["~> 1.6.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.10"]) + s.add_development_dependency(%q.freeze, ["~> 10.0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + else + s.add_dependency(%q.freeze, ["~> 2.6.0"]) + s.add_dependency(%q.freeze, ["~> 0.9.0"]) + s.add_dependency(%q.freeze, ["~> 1.6.0"]) + s.add_dependency(%q.freeze, ["~> 1.10"]) + s.add_dependency(%q.freeze, ["~> 10.0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/add_request.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/add_request.xml new file mode 100644 index 0000000..4b75837 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/add_request.xml @@ -0,0 +1,35 @@ + + + + + Company + Username + Password + + + + + 1234 + + + + + + 9 + 28 + 2015 + + + + + + + + 10 + 2 + 2015 + + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/add_response.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/add_response.xml new file mode 100644 index 0000000..dc48b4d --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/add_response.xml @@ -0,0 +1,32 @@ + + + + + + O + 1234 + + 6375 + + + + + + 12 + 01 + 2013 + + + + + + + + 11 + 25 + 2013 + + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_1002.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_1002.xml new file mode 100644 index 0000000..78bada8 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_1002.xml @@ -0,0 +1,27 @@ + + + + + + 1111 + Submit failed + + The timesheet is terrible + + + + + 1111 + Submit failed + + + + + + 1111 + Submit failed + + The timesheet is really bad + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_123.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_123.xml new file mode 100644 index 0000000..5996385 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_123.xml @@ -0,0 +1,4 @@ + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_416.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_416.xml new file mode 100644 index 0000000..d15e93d --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_416.xml @@ -0,0 +1,4 @@ + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_601.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_601.xml new file mode 100644 index 0000000..b0949bd --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_601.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_602.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_602.xml new file mode 100644 index 0000000..03c4268 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_602.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_no_auth_status.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_no_auth_status.xml new file mode 100644 index 0000000..2ce045d --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/error_no_auth_status.xml @@ -0,0 +1,4 @@ + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/multiple_commands_request.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/multiple_commands_request.xml new file mode 100644 index 0000000..d5fe5ce --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/multiple_commands_request.xml @@ -0,0 +1,20 @@ + + + + + Company + Username + Password + + + + + 1 + + + + + 2 + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/multiple_commands_response.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/multiple_commands_response.xml new file mode 100644 index 0000000..2da87a9 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/multiple_commands_response.xml @@ -0,0 +1,16 @@ + + + + + + 1 + Customer 1 + + + + + 2 + Customer 2 + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_model_response.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_model_response.xml new file mode 100644 index 0000000..eba4515 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_model_response.xml @@ -0,0 +1,20 @@ + + + + + + fail + + + success? + + + unknown + + + + + 123 + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_request_1.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_request_1.xml new file mode 100644 index 0000000..03e347d --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_request_1.xml @@ -0,0 +1,12 @@ + + + + + Company + Username + Password + + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_request_2.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_request_2.xml new file mode 100644 index 0000000..3a5dfd6 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_request_2.xml @@ -0,0 +1,12 @@ + + + + + Company + Username + Password + + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_response_1.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_response_1.xml new file mode 100644 index 0000000..32e7a36 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_response_1.xml @@ -0,0 +1,26 @@ + + + + + + 1 + Client 1 + + + 4 + Client 2 + + + 5 + Client 3 + + + 6 + Client 4 + + + 7 + Client 5 + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_response_2.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_response_2.xml new file mode 100644 index 0000000..b412a44 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_multiple_response_2.xml @@ -0,0 +1,14 @@ + + + + + + 10 + Fancy Client + + + 40 + Blah Client + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_single_request.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_single_request.xml new file mode 100644 index 0000000..03e347d --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_single_request.xml @@ -0,0 +1,12 @@ + + + + + Company + Username + Password + + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_single_response.xml b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_single_response.xml new file mode 100644 index 0000000..fd6a8a7 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/fixtures/read_single_response.xml @@ -0,0 +1,10 @@ + + + + + + 1 + Client 1 + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/open_air_api_client_spec.rb b/vendor/cache/sinclair-b8c88158d000/spec/open_air_api_client_spec.rb new file mode 100644 index 0000000..77f5225 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/open_air_api_client_spec.rb @@ -0,0 +1,206 @@ +require 'spec_helper' + +describe Sinclair::OpenAirApiClient do + subject { Sinclair::OpenAirApiClient.new(username: 'Username', password: 'Password', company: 'Company', client: 'Client', key: 'APIKEY', limit: '5') } + let(:template) { IO.read("#{ File.expand_path('../templates', __FILE__) }/#{ template_name }") } + + describe '#send_request' do + let!(:template_name) { 'single_command.xml.erb' } + + it 'saves the last request and response' do + stub_xml_request( + request: 'read_single_request', + response: 'read_single_response' + ) + + subject.send_request(template: template, model: 'Customer') + expect(subject.last_request).not_to be_nil + expect(subject.last_response).not_to be_nil + end + + context 'when reading multiple models in a single response' do + let!(:template_name) { 'single_command.xml.erb' } + + before do + stub_xml_request( + request: 'read_single_request', + response: 'read_multiple_model_response' + ) + end + + it 'returns a hash with a key for each model type' do + response = subject.send_request(template: template, model: 'Thing1') + expect(response.keys).to match_array(['Thing1', 'Thing2']) + end + + end + + context 'when the response is empty' do + let!(:template_name) { 'single_command.xml.erb' } + + before do + stub_xml_request( + request: 'read_single_request', + response: 'error_601' + ) + end + + it 'returns an empty array' do + response = subject.send_request(template: template, model: 'Customer') + expect(response['Customer']).to be_empty + end + end + + context 'when the request contains one command' do + let!(:template_name) { 'single_command.xml.erb' } + + context 'when the response contains one item' do + before do + stub_xml_request( + request: 'read_single_request', + response: 'read_single_response' + ) + end + + it 'returns an array of one item' do + response = subject.send_request(template: template, model: 'Customer') + expect(response['Customer'].map { |client| client['name'] }).to match_array(['Client 1']) + end + end + + context 'when the response contains multiple items' do + before do + stub_xml_request( + request: 'read_multiple_request_1', + response: 'read_multiple_response_1' + ) + + stub_xml_request( + request: 'read_multiple_request_2', + response: 'read_multiple_response_2' + ) + end + + it 'makes multiple requests when the number of responses is greater than the limit' do + response = subject.send_request(template: template, model: 'Customer') + names = response['Customer'].map { |client| client['name'] } + + expect(names).to match_array(['Blah Client', 'Client 1', 'Client 2', 'Client 3', 'Client 4', 'Client 5', 'Fancy Client']) + end + end + end + + context 'when the request contains multiple commands' do + let!(:template_name) { 'multiple_commands.xml.erb' } + + before do + stub_xml_request( + request: 'multiple_commands_request', + response: 'multiple_commands_response' + ) + end + + it 'returns an array of all items' do + response = subject.send_request(template: template, model: 'Customer', locals: {customer_ids: [1, 2]}) + expect(response['Customer'].map { |client| client['name'] }).to match_array(['Customer 1', 'Customer 2']) + end + end + + context 'when an error occurs' do + let!(:template_name) { 'single_command.xml.erb' } + + it 'raises a OpenAirResponseUnrecognized error when the response is malformed' do + stub_xml_request( + request: 'read_single_request', + response: 'error_no_auth_status' + ) + + expect { + subject.send_request(template: template, model: 'Client') + }.to raise_error(Sinclair::OpenAirResponseUnrecognized) + end + + it 'raises a OpenAirUserLocked error when the response status is 416' do + stub_xml_request( + request: 'read_single_request', + response: 'error_416' + ) + + expect { + subject.send_request(template: template, model: 'Client') + }.to raise_error(Sinclair::OpenAirUserLocked) + end + + it 'raises a OpenAirAuthenticationFailure error when the response status not zero' do + stub_xml_request( + request: 'read_single_request', + response: 'error_123' + ) + + expect { + subject.send_request(template: template, model: 'Client') + }.to raise_error(Sinclair::OpenAirAuthenticationFailure) + end + + it 'raises a OpenAirResponseTimeout error when OpenAir times out' do + allow_any_instance_of(Faraday::Connection).to receive(:post).and_raise(Faraday::TimeoutError) + + expect { + subject.send_request(template: template, model: 'Client') + }.to raise_error(Sinclair::OpenAirResponseTimeout) + end + + it 'raises a OpenAirResponseError when the read status is not zero' do + stub_xml_request( + request: 'read_single_request', + response: 'error_602' + ) + + begin + subject.send_request(template: template, model: 'Client') + rescue Sinclair::OpenAirResponseError => e + expect(e.status).to eq(602) + expect(e.message).to eq('Error making OpenAir request. Got status 602.') + end + end + + it 'does not raise an error when the read status is 601' do + stub_xml_request( + request: 'read_single_request', + response: 'error_601' + ) + + expect { + subject.send_request(template: template, model: 'Client') + }.not_to raise_error + end + + it 'raises an OpenAirInvalidData error when the response status is 1002' do + stub_xml_request( + request: 'read_single_request', + response: 'error_1002' + ) + + expect { + subject.send_request(template: template, model: 'Timesheet', method: 'Submit') + }.to raise_error(Sinclair::OpenAirInvalidData, 'The timesheet is terrible, The timesheet is really bad') + end + end + + context 'when the request is an "add" request' do + let!(:template_name) { 'add_command.xml.erb' } + + before do + stub_xml_request( + request: 'add_request', + response: 'add_response' + ) + end + + it 'creates a timesheet' do + response = subject.send_request(template: template, model: 'Timesheet', method: 'Add', locals: {start_date: Date.new(2015, 9, 28), end_date: Date.new(2015, 10, 2), user_id: '1234'}) + expect(response['Timesheet'].map { |timesheet| timesheet['userid'] }).to eq(['1234']) + end + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/spec/open_air_api_errors_spec.rb b/vendor/cache/sinclair-b8c88158d000/spec/open_air_api_errors_spec.rb new file mode 100644 index 0000000..f1bdc86 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/open_air_api_errors_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe 'OpenAir Exceptions' do + describe Sinclair::OpenAirResponseError do + it 'includes a status code' do + e = Sinclair::OpenAirResponseError.new(1003) + expect(e.status).to eq(1003) + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/spec/request_spec.rb b/vendor/cache/sinclair-b8c88158d000/spec/request_spec.rb new file mode 100644 index 0000000..6f2c417 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/request_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe Sinclair::Request do + subject { Sinclair::Request.new('<%= foo %>') } + + describe '#render' do + let(:output) { ignore_whitespace(subject.render(foo: 'Sinclair')) } + + it 'renders the request header' do + expect(output).to include(ignore_whitespace('')) + end + + it 'renders the request body' do + expect(output).to include(ignore_whitespace('Sinclair')) + end + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/spec/sinclair_spec.rb b/vendor/cache/sinclair-b8c88158d000/spec/sinclair_spec.rb new file mode 100644 index 0000000..b35d21f --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/sinclair_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Sinclair do + it 'has a version number' do + expect(Sinclair::VERSION).not_to be nil + end +end diff --git a/vendor/cache/sinclair-b8c88158d000/spec/spec_helper.rb b/vendor/cache/sinclair-b8c88158d000/spec/spec_helper.rb new file mode 100644 index 0000000..1ca4638 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/spec_helper.rb @@ -0,0 +1,27 @@ +$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) + +require 'codeclimate-test-reporter' +CodeClimate::TestReporter.start + +require 'sinclair' +require 'webmock' + +WebMock.disable_net_connect!(allow_localhost: true, allow: 'codeclimate.com') +WebMock.enable! + +def ignore_whitespace(str) + str.gsub(/\s/, '') +end + +def xml_fixture_for(file) + File.read(File.join('spec', 'fixtures', "#{file}.xml")) +end + +def stub_xml_request(options = {}) + request = ignore_whitespace(xml_fixture_for(options[:request])) + response = xml_fixture_for(options[:response]) + + WebMock.stub_request(:post, 'https://www.openair.com/api.pl').with do |r| + ignore_whitespace(r.body) == request + end.to_return(status: 200, body: response) +end diff --git a/vendor/cache/sinclair-b8c88158d000/spec/templates/add_command.xml.erb b/vendor/cache/sinclair-b8c88158d000/spec/templates/add_command.xml.erb new file mode 100644 index 0000000..11c567c --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/templates/add_command.xml.erb @@ -0,0 +1,25 @@ + + + <%= user_id %> + + + + + + <%= start_date.month %> + <%= start_date.day %> + <%= start_date.year %> + + + + + + + + <%= end_date.month %> + <%= end_date.day %> + <%= end_date.year %> + + + + diff --git a/vendor/cache/sinclair-b8c88158d000/spec/templates/multiple_commands.xml.erb b/vendor/cache/sinclair-b8c88158d000/spec/templates/multiple_commands.xml.erb new file mode 100644 index 0000000..c38c5e3 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/templates/multiple_commands.xml.erb @@ -0,0 +1,7 @@ +<% customer_ids.each do |customer_id| %> + + + <%= customer_id %> + + +<% end %> diff --git a/vendor/cache/sinclair-b8c88158d000/spec/templates/single_command.xml.erb b/vendor/cache/sinclair-b8c88158d000/spec/templates/single_command.xml.erb new file mode 100644 index 0000000..3034da1 --- /dev/null +++ b/vendor/cache/sinclair-b8c88158d000/spec/templates/single_command.xml.erb @@ -0,0 +1,2 @@ + + diff --git a/vendor/cache/timecop-0.8.1.gem b/vendor/cache/timecop-0.8.1.gem new file mode 100644 index 0000000..a284330 Binary files /dev/null and b/vendor/cache/timecop-0.8.1.gem differ diff --git a/vendor/cache/websocket-1.2.3.gem b/vendor/cache/websocket-1.2.3.gem new file mode 100644 index 0000000..b83730b Binary files /dev/null and b/vendor/cache/websocket-1.2.3.gem differ