keepcon 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a7a0fa69cc80ff684b2fa24dad62197c43797c5f
4
+ data.tar.gz: ce37f8ea76108fda5ef7f2f4f41094d50523330e
5
+ SHA512:
6
+ metadata.gz: 33da2e6573ffbe5a42816e663a356f8bdd244f11006c6d1e5391ff6c315d9f1fc13d3cbf1f538c5888473b7cc371d9392bdaeab7d3f7cb7d6302c08e6cfe52d5
7
+ data.tar.gz: c9337e9353beb7ca87c8b8c91ca65c16bc3f39f3ef9a8aa716034cbba3bdefe38fda7fa68ab292e00667d468a3040cad945762bdc40389006b778d4ac2316870
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ Style/Documentation:
2
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1
7
+ - 2.2
8
+ - ruby-head
9
+ git:
10
+ depth: 1
11
+ script:
12
+ - bundle exec rspec
13
+ - bundle exec rubocop
14
+ addons:
15
+ code_climate:
16
+ repo_token: 217146fc082e87b5e4b2352141a8832d0da78d66a9d22cb0b5189344648e821e
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Love Mondays Ltda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Keepcon
2
+
3
+
4
+ [![Build Status](https://travis-ci.org/LoveMondays/keepcon.svg)](https://travis-ci.org/LoveMondays/keepcon)
5
+ [![Code Climate](https://codeclimate.com/github/LoveMondays/keepcon/badges/gpa.svg)](https://codeclimate.com/github/LoveMondays/keepcon)
6
+ [![Test Coverage](https://codeclimate.com/github/LoveMondays/keepcon/badges/coverage.svg)](https://codeclimate.com/github/LoveMondays/keepcon)
7
+ [![Dependency Status](https://gemnasium.com/LoveMondays/keepcon.svg)](https://gemnasium.com/LoveMondays/keepcon)
8
+
9
+ This is a Ruby wrapper for the [Keepcon](http://keepcon.com) API.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'keepcon'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install keepcon
26
+
27
+ ## Usage
28
+
29
+ TODO: Write usage instructions here
30
+
31
+ ## Development
32
+
33
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
34
+
35
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it ( https://github.com/LoveMondays/keepcon/fork )
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ require 'bundler/gem_tasks'
5
+
6
+ begin
7
+ Bundler.setup(:default, :development)
8
+ Bundler::GemHelper.install_tasks
9
+ rescue Bundler::BundlerError => e
10
+ $stderr.puts e.message
11
+ $stderr.puts 'Run `bundle install` to install missing gems'
12
+ exit e.status_code
13
+ end
14
+
15
+ require 'rake'
16
+ require 'rspec/core'
17
+ require 'rspec/core/rake_task'
18
+ require 'rubocop/rake_task'
19
+
20
+ RSpec::Core::RakeTask.new(:spec)
21
+
22
+ desc 'Run RuboCop'
23
+ RuboCop::RakeTask.new(:style)
24
+
25
+ task default: [:spec, :style]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'keepcon'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require 'pry'
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/keepcon.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'keepcon/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'keepcon'
8
+ spec.version = Keepcon::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["Shane O'Grady"]
11
+ spec.email = ['shane@ogrady.ie']
12
+
13
+ spec.summary = 'Ruby wrapper for the Keepcon XML API'
14
+ spec.homepage = 'https://github.com/LoveMondays/keepcon'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|features)/)
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'retryable-rb'
23
+ spec.add_dependency 'faraday'
24
+ spec.add_dependency 'activesupport'
25
+ spec.add_dependency 'actionview'
26
+ spec.add_dependency 'gyoku'
27
+
28
+ spec.add_development_dependency 'bundler'
29
+ spec.add_development_dependency 'rake'
30
+ spec.add_development_dependency 'rspec'
31
+ spec.add_development_dependency 'factory_girl'
32
+ spec.add_development_dependency 'rubocop'
33
+ spec.add_development_dependency 'vcr'
34
+ spec.add_development_dependency 'webmock'
35
+ spec.add_development_dependency 'codeclimate-test-reporter'
36
+ end
@@ -0,0 +1,47 @@
1
+ module Keepcon
2
+ class Client
3
+ attr_accessor :user, :config
4
+ attr_writer :password
5
+
6
+ def initialize
7
+ self.config = {}
8
+ config['urls'] = YAML.load_file(urls_config_path)
9
+ config['client'] = YAML.load_file(client_config_path)
10
+ yield self if block_given?
11
+ end
12
+
13
+ def content_request(data, mode = :sync)
14
+ fail ArgumentError, 'The data can not be empty' unless data.present?
15
+
16
+ request(:put, config['urls']['content']['request'][mode.to_s], data, mode)
17
+ end
18
+
19
+ private
20
+
21
+ def request(method, path, data, mode = :sync)
22
+ connection(mode).send(method, path, data.to_s, headers)
23
+ end
24
+
25
+ def connection(mode = :sync)
26
+ Faraday.new(url: config['urls']['keepcon'][mode.to_s]).tap do |c|
27
+ c.basic_auth(user, @password)
28
+ end
29
+ end
30
+
31
+ def urls_config_path
32
+ File.expand_path('../config/urls.yml', __FILE__)
33
+ end
34
+
35
+ def client_config_path
36
+ File.expand_path('../config/client.yml', __FILE__)
37
+ end
38
+
39
+ def headers
40
+ { 'User-Agent' => user_agent }
41
+ end
42
+
43
+ def user_agent
44
+ config['client']['request']['headers']['user_agent'] % { user: user }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ request:
2
+ headers:
3
+ user_agent: 'Keepcon Client API REST v1.0 - Context Name: [%{user}]'
@@ -0,0 +1,9 @@
1
+ keepcon:
2
+ sync: 'http://sync.keepcon.com'
3
+ async: 'http://service.keepcon.com'
4
+ content:
5
+ request:
6
+ sync: '/synchronic/moderate'
7
+ async: '/input/contentSet'
8
+ response:
9
+ async: '/output/contentSet?contextName=%{context_name}'
@@ -0,0 +1,39 @@
1
+ module Keepcon
2
+ class Context
3
+ attr_accessor :user
4
+ attr_writer :password
5
+
6
+ def initialize(params = {})
7
+ @mappings = {}
8
+ map(params[:mappings])
9
+ params.except(:mappings).each { |k, v| send("#{k}=", v) }
10
+ end
11
+
12
+ def map(hash)
13
+ return unless hash.present?
14
+ hash.each { |k, v| add_mapping(k, v) }
15
+ end
16
+
17
+ def translate(attribute)
18
+ @mappings[attribute].try(:to)
19
+ end
20
+
21
+ def attribute_names
22
+ @mappings.keys
23
+ end
24
+
25
+ def client
26
+ @client ||= Client.new do |config|
27
+ config.user = user
28
+ config.password = @password
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def add_mapping(from, to)
35
+ mapping = Mapping.new(from: from, to: to)
36
+ @mappings[mapping.from] = mapping
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ module Keepcon
2
+ class Entity
3
+ class Response
4
+ attr_accessor :status, :body
5
+
6
+ def initialize(http_response)
7
+ self.body = http_response.body
8
+ self.status = http_response.status
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,62 @@
1
+ require 'gyoku'
2
+ require 'action_view'
3
+
4
+ require 'keepcon/entity/response'
5
+
6
+ module Keepcon
7
+ class Entity
8
+ include ActionView::Helpers::TagHelper
9
+
10
+ attr_accessor :context, :instance
11
+
12
+ def initialize(params = {})
13
+ params.each { |k, v| send("#{k}=", v) }
14
+ end
15
+
16
+ def translate
17
+ translation = context.attribute_names.map do |attr_name|
18
+ [context.translate(attr_name), instance.send(attr_name)]
19
+ end
20
+ Hash[translation]
21
+ end
22
+
23
+ def to_xml
24
+ Gyoku.xml(xml_hash)
25
+ end
26
+
27
+ def send_data(mode = :sync)
28
+ parse_response(context.client.content_request(to_xml, mode))
29
+ end
30
+
31
+ private
32
+
33
+ def parse_response(response)
34
+ Response.new(response)
35
+ end
36
+
37
+ def xml_hash
38
+ {
39
+ import: {
40
+ contenttype: context.user,
41
+ contents: {
42
+ content: [
43
+ { :@id => instance.id }.merge(translate_to_xml_hash)
44
+ ]
45
+ }
46
+ }
47
+ }
48
+ end
49
+
50
+ def translate_to_xml_hash
51
+ translation = translate.map do |k, v|
52
+ case
53
+ when k == :datetime then [k, { content!: (v.to_f * 1_000).to_i }]
54
+ when k == :author then [k, { :@type => :author, :content! => v }]
55
+ when v.is_a?(Fixnum) then [k, { content!: v }]
56
+ else ["#{k}!", { content!: cdata_section(v) }]
57
+ end
58
+ end
59
+ Hash[translation]
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,35 @@
1
+ module Keepcon
2
+ module Integration
3
+ def send_to_keepcon(context, mode = :sync)
4
+ keepcon_entity(context).send_data(mode)
5
+ end
6
+
7
+ def keepcon_entity(context)
8
+ Entity.new(context: context, instance: self)
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+
15
+ module ClassMethods
16
+ def keepcon_integration(context_name, mappings = {})
17
+ unless (context = find_context(context_name))
18
+ fail 'The context does not exist'
19
+ end
20
+
21
+ context.map(mappings)
22
+
23
+ define_method("send_#{context_name}_to_keepcon") do |mode = :sync|
24
+ send_to_keepcon(context, mode)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def find_context(context)
31
+ Keepcon.contexts[context]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module Keepcon
2
+ class Mapping
3
+ attr_accessor :from, :to
4
+
5
+ def initialize(params = {})
6
+ params.each { |k, v| send("#{k}=", v) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module Keepcon
2
+ class Rails
3
+ class << self
4
+ def setup!
5
+ add_integration(ActiveRecord::Base) if defined?(ActiveRecord::Base)
6
+ end
7
+
8
+ private
9
+
10
+ def add_integration(klass)
11
+ klass.send(:include, Integration) unless klass.include?(Integration)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ module Keepcon
3
+ VERSION = '0.1.1'
4
+ end
data/lib/keepcon.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'yaml'
2
+ require 'faraday'
3
+ require 'active_support'
4
+ require 'active_support/core_ext/object'
5
+
6
+ require 'keepcon/client'
7
+ require 'keepcon/context'
8
+ require 'keepcon/entity'
9
+ require 'keepcon/integration'
10
+ require 'keepcon/mapping'
11
+ require 'keepcon/rails'
12
+ require 'keepcon/version'
13
+
14
+ module Keepcon
15
+ mattr_accessor :contexts
16
+ self.contexts = {}
17
+
18
+ Rails.setup!
19
+
20
+ class << self
21
+ def setup
22
+ yield self
23
+ end
24
+
25
+ def add_context(name, params)
26
+ contexts[name] = Context.new(params)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon::Client do
4
+ let(:client) do
5
+ described_class.new do |config|
6
+ config.user = 'user'
7
+ config.password = 'password'
8
+ end
9
+ end
10
+
11
+ describe '.new' do
12
+ it 'passes the self to the block' do
13
+ described_class.new do |config|
14
+ expect(config.class).to eq(described_class)
15
+ end
16
+ end
17
+ end
18
+
19
+ describe '#content_request' do
20
+ subject { client.content_request(data, mode) }
21
+
22
+ let(:adapter) do
23
+ Faraday::Adapter::Test::Stubs.new do |stub|
24
+ stub.put('/synchronic/moderate', 'data', headers) do |_env|
25
+ [200, {}, 'sync']
26
+ end
27
+ stub.put('/input/contentSet', 'data', headers) do |_env|
28
+ [200, {}, 'async']
29
+ end
30
+ end
31
+ end
32
+ let(:headers) do
33
+ {
34
+ 'User-Agent' => 'Keepcon Client API REST v1.0 - Context Name: [user]',
35
+ 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA=='
36
+ }
37
+ end
38
+ let!(:faraday) { Faraday.new { |f| f.adapter :test, adapter } }
39
+
40
+ before do
41
+ allow(Faraday).to receive(:new).and_return(faraday)
42
+ end
43
+
44
+ context 'with empty data' do
45
+ let(:data) { '' }
46
+ let(:mode) { :sync }
47
+
48
+ it { expect { subject }.to raise_error(ArgumentError) }
49
+ end
50
+
51
+ context 'with any data' do
52
+ let(:data) { 'data' }
53
+
54
+ context 'sync request' do
55
+ let(:mode) { :sync }
56
+
57
+ it { expect(subject.status).to eq(200) }
58
+ it { expect(subject.body).to eq('sync') }
59
+ end
60
+
61
+ context 'async request' do
62
+ let(:mode) { :async }
63
+
64
+ it { expect(subject.status).to eq(200) }
65
+ it { expect(subject.body).to eq('async') }
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon::Context do
4
+ describe '#new' do
5
+ subject { described_class.new(attributes) }
6
+
7
+ let(:attributes) { attributes_for(:context, mappings: { a: :b }) }
8
+
9
+ it { expect(subject.user).to eq(attributes[:user]) }
10
+ it { expect(subject.translate(:a)).to eq(:b) }
11
+ end
12
+
13
+ describe '#map & #translate' do
14
+ let(:attributes) { { a: :b, c: :d } }
15
+
16
+ before { subject.map(attributes) }
17
+
18
+ it { expect(subject.translate(:a)).to eq(:b) }
19
+ it { expect(subject.translate(:c)).to eq(:d) }
20
+ end
21
+
22
+ describe '#attribute_names' do
23
+ subject { context.attribute_names }
24
+
25
+ let(:context) { build(:context, mappings: { a: :b, c: :d }) }
26
+
27
+ it { expect(subject).to match_array([:a, :c]) }
28
+ end
29
+
30
+ describe '#client' do
31
+ subject { context.client }
32
+
33
+ let(:context) { build(:context) }
34
+
35
+ it { expect(subject.class).to eq(Keepcon::Client) }
36
+ it { expect(subject.user).to eq(context.user) }
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon::Entity::Response do
4
+ describe '.new' do
5
+ subject { described_class.new(response) }
6
+
7
+ let(:response) { Faraday::Response.new.finish(status: 200, body: 'ok') }
8
+
9
+ it { expect(subject.status).to eq(200) }
10
+ it { expect(subject.body).to eq('ok') }
11
+ end
12
+ end
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon::Entity do
4
+ let(:dummy_class) do
5
+ Class.new do
6
+ define_method(:id) { 1 }
7
+ define_method(:a) { 1 }
8
+ define_method(:b) { 'b' }
9
+ define_method(:created_at) { Time.utc('2015-01-01') }
10
+ end
11
+ end
12
+
13
+ describe '#new' do
14
+ subject { described_class.new(attributes) }
15
+
16
+ let(:context) { build(:context) }
17
+ let(:instance) { Object.new }
18
+ let(:attributes) do
19
+ attributes_for(:entity, context: context, instance: instance)
20
+ end
21
+
22
+ it { expect(subject.context).to eq(attributes[:context]) }
23
+ it { expect(subject.instance).to eq(attributes[:instance]) }
24
+ end
25
+
26
+ describe '#translate' do
27
+ subject { entity.translate }
28
+
29
+ let(:entity) { build(:entity, context: context, instance: instance) }
30
+ let(:context) { build(:context, mappings: { a: :x, b: :y }) }
31
+ let(:instance) { dummy_class.new }
32
+
33
+ it { expect(subject).to match_array(x: 1, y: 'b') }
34
+ it { expect(subject.class).to eq(Hash) }
35
+ end
36
+
37
+ describe '#to_xml' do
38
+ subject { entity.to_xml }
39
+
40
+ let(:entity) { build(:entity, context: context, instance: instance) }
41
+ let(:instance) { dummy_class.new }
42
+
43
+ context 'when the attribute is mapped to author' do
44
+ let(:context) { build(:context, mappings: { a: :author }) }
45
+
46
+ it 'generates the correct xml' do
47
+ is_expected.to eq(<<-"END".gsub(/(\s*\n|^\s*)/, '').strip)
48
+ <import>
49
+ <contenttype>#{context.user}</contenttype>
50
+ <contents>
51
+ <content id="1">
52
+ <author type="author">1</author>
53
+ </content>
54
+ </contents>
55
+ </import>
56
+ END
57
+ end
58
+ end
59
+
60
+ context 'when the attribute is mapped to datetime' do
61
+ let(:context) { build(:context, mappings: { created_at: :datetime }) }
62
+
63
+ it 'generates the correct xml' do
64
+ is_expected.to eq(<<-"END".gsub(/(\s*\n|^\s*)/, '').strip)
65
+ <import>
66
+ <contenttype>#{context.user}</contenttype>
67
+ <contents>
68
+ <content id="1">
69
+ <datetime>1420070400000</datetime>
70
+ </content>
71
+ </contents>
72
+ </import>
73
+ END
74
+ end
75
+ end
76
+
77
+ context 'with other mappings' do
78
+ let(:context) { build(:context, mappings: { a: :x, b: :y }) }
79
+
80
+ it 'generates the correct xml' do
81
+ is_expected.to eq(<<-"END".gsub(/(\s*\n|^\s*)/, '').strip)
82
+ <import>
83
+ <contenttype>#{context.user}</contenttype>
84
+ <contents>
85
+ <content id="1">
86
+ <x>1</x>
87
+ <y><![CDATA[b]]></y>
88
+ </content>
89
+ </contents>
90
+ </import>
91
+ END
92
+ end
93
+ end
94
+ end
95
+
96
+ describe '#send_data' do
97
+ subject { entity.send_data(mode) }
98
+
99
+ let(:entity) { build(:entity, context: context, instance: instance) }
100
+ let(:instance) { dummy_class.new }
101
+ let(:context) { build(:context, mappings: { a: :x, b: :y }) }
102
+ let(:response) { Keepcon::Entity::Response.new(http_response) }
103
+ let(:http_response) { Faraday::Response.new.finish(status: 200) }
104
+
105
+ before do
106
+ allow(context.client).to receive(:content_request)
107
+ .with(entity.to_xml, mode).and_return(response)
108
+ subject
109
+ end
110
+
111
+ context 'sync request' do
112
+ let(:mode) { :sync }
113
+
114
+ it 'calls the #content_request with the corresponding xml' do
115
+ expect(context.client).to have_received(:content_request).once
116
+ end
117
+
118
+ it { expect(subject.status).to be 200 }
119
+ end
120
+
121
+ context 'async request' do
122
+ let(:mode) { :async }
123
+
124
+ it 'calls the #content_request with the corresponding xml' do
125
+ expect(context.client).to have_received(:content_request).once
126
+ end
127
+
128
+ it { expect(subject.status).to be 200 }
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,8 @@
1
+ FactoryGirl.define do
2
+ factory :context, class: Keepcon::Context do
3
+ user
4
+ password
5
+
6
+ initialize_with { new(attributes) }
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :entity, class: Keepcon::Entity do
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :mapping, class: Keepcon::Mapping do
3
+ end
4
+ end
@@ -0,0 +1,9 @@
1
+ FactoryGirl.define do
2
+ sequence :user do |n|
3
+ "user_#{n}"
4
+ end
5
+
6
+ sequence :password do |n|
7
+ "password_#{n}"
8
+ end
9
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon::Integration do
4
+ subject { instance }
5
+
6
+ let(:dummy_class) do
7
+ Class.new do
8
+ include Keepcon::Integration
9
+
10
+ define_method(:id) { 1 }
11
+ define_method(:a) { 1 }
12
+ end
13
+ end
14
+ let(:instance) { dummy_class.new }
15
+ let(:added_context) { Keepcon.contexts[:user] }
16
+
17
+ before { Keepcon.add_context(:user, user: 'user', password: 'password') }
18
+
19
+ describe '.keepcon_integration' do
20
+ context 'when context do not exists' do
21
+ subject { dummy_class.keepcon_integration(:test) }
22
+
23
+ it { expect { subject }.to raise_error }
24
+ end
25
+
26
+ context 'when context exists' do
27
+ subject { dummy_class.keepcon_integration(:user, a: :b) }
28
+
29
+ before { subject }
30
+
31
+ it { expect(added_context.translate(:a)).to eq(:b) }
32
+ it { expect(instance.respond_to?(:send_user_to_keepcon)).to be true }
33
+ end
34
+ end
35
+
36
+ context 'with some integration defined' do
37
+ before { dummy_class.keepcon_integration(:user, a: :b) }
38
+
39
+ describe '#send_to_keepcon' do
40
+ subject { instance.send_to_keepcon(added_context, mode) }
41
+
42
+ let(:entity) do
43
+ Keepcon::Entity.new(context: added_context, instance: instance)
44
+ end
45
+
46
+ before { allow(instance).to receive(:keepcon_entity).and_return(entity) }
47
+
48
+ context 'sync request' do
49
+ let(:mode) { :sync }
50
+
51
+ it 'calls send_data on the entity' do
52
+ expect(entity).to receive(:send_data).with(:sync).once
53
+ subject
54
+ end
55
+ end
56
+
57
+ context 'async request' do
58
+ let(:mode) { :async }
59
+
60
+ it 'calls send_data on the entity' do
61
+ expect(entity).to receive(:send_data).with(:async).once
62
+ subject
63
+ end
64
+ end
65
+ end
66
+
67
+ describe '#keepcon_entity' do
68
+ subject { instance.keepcon_entity(added_context) }
69
+
70
+ it { expect(subject.context).to eq(added_context) }
71
+ it { expect(subject.instance).to eq(instance) }
72
+ end
73
+
74
+ describe '#send_context_to_keepcon' do
75
+ subject { instance.send_user_to_keepcon(mode) }
76
+
77
+ context 'sync request' do
78
+ let(:mode) { :sync }
79
+
80
+ it 'calls #send_to_keepcon with the context' do
81
+ expect(instance).to receive(:send_to_keepcon)
82
+ .with(added_context, :sync)
83
+ subject
84
+ end
85
+ end
86
+
87
+ context 'async request' do
88
+ let(:mode) { :async }
89
+
90
+ it 'calls #send_to_keepcon with the context' do
91
+ expect(instance).to receive(:send_to_keepcon)
92
+ .with(added_context, :async)
93
+ subject
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon do
4
+ it 'has a version number' do
5
+ expect(Keepcon::VERSION).not_to be nil
6
+ end
7
+
8
+ describe '.add_context' do
9
+ subject { described_class.add_context(:user_name, params) }
10
+
11
+ let(:params) { { user: 'UserName', password: 'password' } }
12
+ let(:added_context) { described_class.contexts[:user_name] }
13
+
14
+ before { subject }
15
+
16
+ it { expect(described_class.contexts.length).to eq(1) }
17
+ it { expect(added_context.user).to eq(params[:user]) }
18
+ end
19
+
20
+ describe '.setup' do
21
+ it 'passes the Keepcon module to the block' do
22
+ described_class.setup do |config|
23
+ expect(config).to eq(described_class)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon::Mapping do
4
+ describe '#new' do
5
+ subject { described_class.new(attributes) }
6
+
7
+ let(:attributes) { attributes_for(:mapping, from: :a, to: :b) }
8
+
9
+ it { expect(subject.from).to eq(attributes[:from]) }
10
+ it { expect(subject.to).to eq(attributes[:to]) }
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Keepcon::Rails do
4
+ describe '.setup!' do
5
+ before do
6
+ ActiveRecord = Class.new
7
+ ActiveRecord::Base = Class.new(ActiveRecord)
8
+ end
9
+
10
+ it 'includes Integration on ActiveModel::Model' do
11
+ expect(ActiveRecord::Base.include?(Keepcon::Integration)).to be false
12
+ described_class.setup!
13
+ expect(ActiveRecord::Base.include?(Keepcon::Integration)).to be true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'codeclimate-test-reporter'
3
+ CodeClimate::TestReporter.start
4
+
5
+ require 'rspec'
6
+ require 'keepcon'
7
+ Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
8
+
9
+ require_relative 'vcr_setup'
10
+
11
+ RSpec.configure do |config|
12
+ config.after(:example) { Keepcon.contexts.clear }
13
+ end
@@ -0,0 +1,7 @@
1
+ require 'factory_girl'
2
+
3
+ RSpec.configure do |config|
4
+ config.include FactoryGirl::Syntax::Methods
5
+
6
+ FactoryGirl.find_definitions
7
+ end
data/spec/vcr_setup.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'vcr'
2
+
3
+ VCR.configure do |config|
4
+ config.cassette_library_dir = 'spec/cassettes'
5
+ config.hook_into :webmock
6
+ config.ignore_hosts 'codeclimate.com'
7
+ end
metadata ADDED
@@ -0,0 +1,280 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keepcon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Shane O'Grady
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: retryable-rb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: actionview
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: gyoku
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: factory_girl
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: vcr
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: webmock
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: codeclimate-test-reporter
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ description:
196
+ email:
197
+ - shane@ogrady.ie
198
+ executables:
199
+ - console
200
+ - setup
201
+ extensions: []
202
+ extra_rdoc_files: []
203
+ files:
204
+ - ".gitignore"
205
+ - ".rspec"
206
+ - ".rubocop.yml"
207
+ - ".travis.yml"
208
+ - Gemfile
209
+ - LICENSE.txt
210
+ - README.md
211
+ - Rakefile
212
+ - bin/console
213
+ - bin/setup
214
+ - keepcon.gemspec
215
+ - lib/keepcon.rb
216
+ - lib/keepcon/client.rb
217
+ - lib/keepcon/config/client.yml
218
+ - lib/keepcon/config/urls.yml
219
+ - lib/keepcon/context.rb
220
+ - lib/keepcon/entity.rb
221
+ - lib/keepcon/entity/response.rb
222
+ - lib/keepcon/integration.rb
223
+ - lib/keepcon/mapping.rb
224
+ - lib/keepcon/rails.rb
225
+ - lib/keepcon/version.rb
226
+ - spec/client_spec.rb
227
+ - spec/context_spec.rb
228
+ - spec/entity/response_spec.rb
229
+ - spec/entity_spec.rb
230
+ - spec/factories/contexts.rb
231
+ - spec/factories/entities.rb
232
+ - spec/factories/mapping.rb
233
+ - spec/factories/sequences.rb
234
+ - spec/integration_spec.rb
235
+ - spec/keepcon_spec.rb
236
+ - spec/mapping_spec.rb
237
+ - spec/rails_spec.rb
238
+ - spec/spec_helper.rb
239
+ - spec/support/factory_girl.rb
240
+ - spec/vcr_setup.rb
241
+ homepage: https://github.com/LoveMondays/keepcon
242
+ licenses:
243
+ - MIT
244
+ metadata: {}
245
+ post_install_message:
246
+ rdoc_options: []
247
+ require_paths:
248
+ - lib
249
+ required_ruby_version: !ruby/object:Gem::Requirement
250
+ requirements:
251
+ - - ">="
252
+ - !ruby/object:Gem::Version
253
+ version: '0'
254
+ required_rubygems_version: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: '0'
259
+ requirements: []
260
+ rubyforge_project:
261
+ rubygems_version: 2.4.5
262
+ signing_key:
263
+ specification_version: 4
264
+ summary: Ruby wrapper for the Keepcon XML API
265
+ test_files:
266
+ - spec/client_spec.rb
267
+ - spec/context_spec.rb
268
+ - spec/entity/response_spec.rb
269
+ - spec/entity_spec.rb
270
+ - spec/factories/contexts.rb
271
+ - spec/factories/entities.rb
272
+ - spec/factories/mapping.rb
273
+ - spec/factories/sequences.rb
274
+ - spec/integration_spec.rb
275
+ - spec/keepcon_spec.rb
276
+ - spec/mapping_spec.rb
277
+ - spec/rails_spec.rb
278
+ - spec/spec_helper.rb
279
+ - spec/support/factory_girl.rb
280
+ - spec/vcr_setup.rb