constructorio 1.0.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a44d85b592d503fee64cbf411daf318ab52fcfc9
4
- data.tar.gz: 29aefce25803f2b066488c1550a047ee04ed0071
3
+ metadata.gz: 18db9093fcb9a5bd9ebcb0a13e74e0d828720695
4
+ data.tar.gz: cf0cf3d3c976f8face4928b86bb875c9174c9b64
5
5
  SHA512:
6
- metadata.gz: 736e434f3feae53f9c501764871c7a96529efc39fdd124f557dd8fc55db98fe44cb25f6e03d31222497cb47d78739ce0173d6b861dd74683731c4b9e285f2898
7
- data.tar.gz: 84df4cf7349f73b33f54cd0aa60f14a4f15b72d45630f442f1be4777550abb7b49a40fee1075abc5e41e2c84a6c1c821753b4ca9e801139bf06885045299abd0
6
+ metadata.gz: e7dde5ef1ee84ce2321d9caa2061e55b376ffdb425b4360c66f9b851b8d4bb49b357917fa53112a4f100a86acb19f42017391d783b63fdf6f30ebf6695ff3253
7
+ data.tar.gz: 005611dfe57cf1916995c0d8f16b00fbe1529d090b7bc371abd77f1df898120391421fe777eb0a71ba1aa72b366031cdc55c32d838dab732af18e775c722a206
data/.rock.yml CHANGED
@@ -6,5 +6,3 @@ env:
6
6
  build: |
7
7
  rm -f ./bin/bundle
8
8
  {{ parent }}
9
-
10
- run_web: bin/rails s
@@ -6,10 +6,10 @@ require 'constructorio/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "constructorio"
8
8
  spec.version = ConstructorIO::VERSION
9
- spec.authors = ["Steven Lai"]
10
- spec.email = ["lai.steven@gmail.com"]
9
+ spec.authors = ["Dan McCormick"]
10
+ spec.email = ["dan@constructor.io"]
11
11
  spec.summary = %q{Ruby gem for Constructor.io}
12
- spec.description = %q{Ruby gem for Constructor.io's autocomplete service. Enables Rails models to send updates to the Constructor.io API automatically, and provides a view helper to add autocomplete on any input.}
12
+ spec.description = %q{Ruby gem for Constructor.io's autocomplete service.}
13
13
  spec.homepage = "http://constructor.io"
14
14
  spec.license = "MIT"
15
15
 
@@ -18,13 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "activerecord"
22
21
  spec.add_dependency 'faraday', '~> 0.9', '>= 0.9.0'
23
- spec.add_dependency "activesupport", ">= 3.2"
24
22
  spec.add_development_dependency "bundler", "~> 1.7"
25
23
  spec.add_development_dependency "rake", "~> 10.0"
26
24
  spec.add_development_dependency 'pry', '~> 0.10', '>= 0.10.1'
27
- spec.add_development_dependency 'sqlite3', '~> 1.3', '>= 1.3.10'
28
25
  spec.add_development_dependency 'mocha', '~> 1.1', '>= 1.1.0'
29
- spec.add_development_dependency "minitest", "~> 5.5.1"
26
+ spec.add_development_dependency 'minitest', '~> 5.5', '>= 5.5.1'
30
27
  end
@@ -0,0 +1,58 @@
1
+ require 'json'
2
+
3
+ module ConstructorIO
4
+ class Client
5
+ def add(params)
6
+ call_api("item", "post", params)
7
+ end
8
+
9
+ def remove(params)
10
+ call_api("item", "delete", params)
11
+ end
12
+
13
+ def modify(params)
14
+ call_api("item", "put", params)
15
+ end
16
+
17
+ def track_search(params)
18
+ call_api("search", "post", params)
19
+ end
20
+
21
+ def track_click_through(params)
22
+ call_api("click_through", "post", params)
23
+ end
24
+
25
+ def track_conversion(params)
26
+ call_api("conversion", "post", params)
27
+ end
28
+
29
+ def verify
30
+ call_api("verify", "get")
31
+ end
32
+
33
+ private
34
+
35
+ def call_api(path, method, params)
36
+ api_token = ConstructorIO.configuration.api_token
37
+ api_url = ConstructorIO.configuration.api_url || "https://ac.constructor.io/"
38
+ autocomplete_key = ConstructorIO.configuration.autocomplete_key
39
+ @http_client ||= Faraday.new(url: api_url)
40
+ @http_client.basic_auth(api_token, '')
41
+
42
+ send_request(path, method, @http_client, params, autocomplete_key)
43
+ end
44
+
45
+ def send_request(path, method, http_client, params, autocomplete_key)
46
+ response = http_client.send(method) do |request|
47
+ request.url "/v1/#{path}?autocomplete_key=#{autocomplete_key}"
48
+ request.headers['Content-Type'] = 'application/json'
49
+ request.body = params.to_json
50
+ end
51
+ if response.status.to_s =~ /^2/
52
+ return nil
53
+ else
54
+ return response.status
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,3 +1,3 @@
1
1
  module ConstructorIO
2
- VERSION = "1.0.4"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/constructorio.rb CHANGED
@@ -1,25 +1,15 @@
1
1
  require 'constructorio/version'
2
2
  require 'constructorio/configuration'
3
- require 'constructorio/helper'
4
- require 'constructorio/fields'
5
- require 'active_record'
3
+ require 'constructorio/client'
6
4
  require 'faraday'
7
- require 'active_support/core_ext/string/output_safety'
8
-
9
- require 'constructorio/railtie' if defined?(Rails)
10
5
 
11
6
  begin
12
7
  require 'pry'
13
8
  rescue LoadError
14
9
  end
15
10
 
16
- class MissingItemName < StandardError; end
17
-
18
11
  module ConstructorIO
19
-
20
- class << self
21
- attr_accessor :configuration
22
- end
12
+ attr_accessor :configuration
23
13
 
24
14
  def self.configuration
25
15
  @configuration ||= Configuration.new
@@ -28,95 +18,4 @@ module ConstructorIO
28
18
  def self.configure
29
19
  yield(configuration)
30
20
  end
31
-
32
- # This injects the methods on the included hook
33
- def self.included base
34
- base.send :include, InstanceMethods
35
- base.extend ClassMethods
36
- end
37
-
38
- module ClassMethods
39
- # "fields" is expected to be an array of strings or an array of hashes, like:
40
- # "product_name", "description"
41
- # - or -
42
- # { 'attribute' => 'product_name', 'metadata' => { metadata_one => ->{ something_dynamic }} }
43
- def constructorio_autocomplete(fields, autocomplete_key = ConstructorIO.configuration.autocomplete_key)
44
- # All fields require an attribute
45
- field_names = fields.map { |f| f.is_a?(String) ? f : f['attribute'] }
46
- raise MissingItemName if field_names.include? nil
47
-
48
- field_names.each do |field|
49
- ConstructorIO::Fields.instance.add(self.model_name, field)
50
- end
51
-
52
- # transform the data
53
- transformed = {}
54
- fields.each do |field|
55
- if field.is_a?(String)
56
- transformed[field] = {}
57
- else
58
- transformed[field['attribute']] = field['metadata']
59
- end
60
- end
61
-
62
- after_save do |record|
63
- updated_fields = record.changed.select { |c| field_names.include? c }
64
- updated_fields.each do |field|
65
- record.send(:constructorio_add_record, record[field.to_sym], transformed[field], autocomplete_key)
66
- end
67
- end
68
-
69
- before_destroy do |record|
70
- field_names.each do |field|
71
- record.send(:constructorio_delete_record, record[field.to_sym], transformed[field], autocomplete_key)
72
- end
73
- end
74
- end
75
- end
76
-
77
- module InstanceMethods
78
- def constructorio_add_record(value, metadata = {}, autocomplete_key)
79
- constructorio_call_api("post", value, metadata, autocomplete_key)
80
- end
81
-
82
- def constructorio_delete_record(value, metadata = {}, autocomplete_key)
83
- constructorio_call_api("delete", value, metadata, autocomplete_key)
84
- end
85
-
86
- private
87
-
88
- def constructorio_make_request_body(value, metadata)
89
- request_body = { "item_name" => "#{value}" }
90
- unless metadata.empty?
91
- metadata.each do |k, v|
92
- v = instance_exec(&v) if v.is_a? Proc
93
- request_body[k] = v
94
- end
95
- end
96
- request_body
97
- end
98
-
99
- def constructorio_call_api(method, value, metadata, autocomplete_key)
100
- api_token = ConstructorIO.configuration.api_token
101
- api_url = ConstructorIO.configuration.api_url || "https://ac.constructor.io/"
102
- @http_client ||= Faraday.new(url: api_url)
103
- @http_client.basic_auth(api_token, '')
104
-
105
- request_body = constructorio_make_request_body(value, metadata)
106
- constructorio_send_request(method, @http_client, request_body, autocomplete_key)
107
- end
108
-
109
- def constructorio_send_request(method, http_client, request_body, autocomplete_key)
110
- response = http_client.send(method) do |request|
111
- request.url "/v1/item?autocomplete_key=#{autocomplete_key}"
112
- request.headers['Content-Type'] = 'application/json'
113
- request.body = request_body.to_json
114
- end
115
- if response.status.to_s =~ /^2/
116
- return nil
117
- else
118
- return response.status
119
- end
120
- end
121
- end
122
21
  end
@@ -1,106 +1,50 @@
1
1
  require_relative 'test_helper'
2
2
 
3
3
  class ConstructorIOTest < MiniTest::Test
4
- def test_add_record_makes_request
5
- person = Person.new(
6
- first_name: "Steven",
7
- last_name: "Lai",
8
- address: "New York"
4
+ def test_add_record_calls_post
5
+ c = ConstructorIO::Client.new
6
+ c.expects(:call_api).with(
7
+ "item",
8
+ "post",
9
+ { item_name: "power drill" }
9
10
  )
10
11
 
11
- person.stubs(:constructorio_send_request)
12
-
13
- person.expects(:constructorio_make_request_body)
14
- assert person.save
15
- end
16
-
17
- def test_add_simple_record_makes_request
18
- person = PersonSimple.new(
19
- first_name: "Steven",
20
- last_name: "Lai",
21
- address: "New York"
22
- )
23
-
24
- person.stubs(:constructorio_send_request)
25
-
26
- person.expects(:constructorio_make_request_body)
27
- assert person.save
28
- end
29
-
30
- def test_add_record_accepts_procs
31
- person = Person.new(
32
- first_name: "Steven",
33
- last_name: "Lai",
34
- address: "New York"
35
- )
36
-
37
- person.expects(:constructorio_send_request).with(
38
- 'post',
39
- instance_of(Faraday::Connection),
40
- {'item_name' => 'Steven', 'test_metadata' => 'test_values', 'test_proc' => 'NEW YORK'},
41
- 'person_autocomplete_key'
42
- )
43
- assert person.save
44
- end
45
-
46
- def test_add_simple_record_accepts_procs
47
- person = PersonSimple.new(
48
- first_name: "Steven",
49
- last_name: "Lai",
50
- address: "New York"
51
- )
52
-
53
- person.expects(:constructorio_send_request).with(
54
- 'post',
55
- instance_of(Faraday::Connection),
56
- {'item_name' => 'Steven'},
57
- 'example_autocomplete_key'
58
- )
59
- assert person.save
12
+ c.add( { item_name: "power drill" } )
60
13
  end
61
14
 
62
15
  def test_add_record_sends_request
63
- person = Person.new(
64
- first_name: "Steven",
65
- last_name: "Lai",
66
- address: "New York"
16
+ c = ConstructorIO::Client.new
17
+ c.expects(:send_request).with(
18
+ "item",
19
+ "post",
20
+ instance_of(Faraday::Connection),
21
+ { item_name: "power drill" },
22
+ "example_autocomplete_key"
67
23
  )
68
24
 
69
- person.expects(:constructorio_send_request)
70
- assert person.save
25
+ c.add( { item_name: "power drill" } )
71
26
  end
72
27
 
73
- def test_delete_record_makes_request
74
- Person.any_instance.stubs(:constructorio_call_api)
75
- person = Person.create(
76
- first_name: "Ronald",
77
- last_name: "McDonald",
78
- address: "Disneyland"
28
+ def test_remove_record_calls_delete
29
+ c = ConstructorIO::Client.new
30
+ c.expects(:call_api).with(
31
+ "item",
32
+ "delete",
33
+ { item_name: "power drill" }
79
34
  )
80
35
 
81
- person.expects(:constructorio_call_api).with("delete", "Ronald", has_entry('test_proc', instance_of(Proc)),"person_autocomplete_key")
82
- person.destroy
36
+ c.remove( { item_name: "power drill" } )
83
37
  end
84
38
 
85
- def test_add_record_without_key_uses_default_key
86
- person = PersonNoKey.new(
87
- first_name: "Steven",
88
- last_name: "Lai",
89
- address: "New York"
39
+ def test_modify_record_calls_put
40
+ c = ConstructorIO::Client.new
41
+ c.expects(:call_api).with(
42
+ "item",
43
+ "put",
44
+ { item_name: "power drill" }
90
45
  )
91
46
 
92
- person.expects(:constructorio_call_api).with("post", "Lai", anything, ConstructorIO.configuration.autocomplete_key)
93
- assert person.save
47
+ c.modify( { item_name: "power drill" } )
94
48
  end
95
49
 
96
- def test_fields_are_tracked
97
- Person.any_instance.expects(:constructorio_call_api).with("post", "Ronald", anything, "person_autocomplete_key")
98
- person = Person.create(
99
- first_name: "Ronald",
100
- last_name: "McDonald",
101
- address: "Disneyland"
102
- )
103
-
104
- assert_equal ConstructorIO::Fields.instance.list('Person'), ["first_name"]
105
- end
106
50
  end
data/test/test_helper.rb CHANGED
@@ -3,49 +3,8 @@ require 'minitest/unit'
3
3
  require 'mocha/mini_test'
4
4
  require_relative '../lib/constructorio'
5
5
 
6
-
7
- ActiveRecord::Base.establish_connection(
8
- adapter: 'sqlite3',
9
- database: ':memory:'
10
- )
11
-
12
- ActiveRecord::Schema.define do
13
- create_table :people, force: true do |t|
14
- t.string :first_name
15
- t.string :last_name
16
- t.string :address
17
- end
18
- end
19
-
20
6
  ConstructorIO.configure do |config|
21
7
  config.api_token = "example_api_token"
22
8
  config.autocomplete_key = "example_autocomplete_key"
23
9
  config.api_url = "http://example.constructor.io"
24
10
  end
25
-
26
- class Person < ActiveRecord::Base
27
- include ConstructorIO
28
- constructorio_autocomplete [{
29
- 'attribute' => 'first_name',
30
- 'metadata' => {
31
- 'test_metadata' => 'test_values',
32
- 'test_proc' => ->{ self.address.upcase }
33
- }
34
- }], "person_autocomplete_key"
35
- end
36
-
37
- class PersonSimple < ActiveRecord::Base
38
- self.table_name = 'people'
39
- include ConstructorIO
40
- constructorio_autocomplete [ 'first_name' ]
41
- end
42
-
43
- class PersonNoKey < ActiveRecord::Base
44
- self.table_name = 'people'
45
- include ConstructorIO
46
- constructorio_autocomplete [{'attribute' => 'last_name'}]
47
- end
48
-
49
- class FakeView
50
- include ConstructorIO::Helper
51
- end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: constructorio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Steven Lai
7
+ - Dan McCormick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-16 00:00:00.000000000 Z
11
+ date: 2015-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activerecord
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
13
  - !ruby/object:Gem::Dependency
28
14
  name: faraday
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -44,20 +30,6 @@ dependencies:
44
30
  - - ">="
45
31
  - !ruby/object:Gem::Version
46
32
  version: 0.9.0
47
- - !ruby/object:Gem::Dependency
48
- name: activesupport
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '3.2'
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '3.2'
61
33
  - !ruby/object:Gem::Dependency
62
34
  name: bundler
63
35
  requirement: !ruby/object:Gem::Requirement
@@ -106,26 +78,6 @@ dependencies:
106
78
  - - ">="
107
79
  - !ruby/object:Gem::Version
108
80
  version: 0.10.1
109
- - !ruby/object:Gem::Dependency
110
- name: sqlite3
111
- requirement: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - "~>"
114
- - !ruby/object:Gem::Version
115
- version: '1.3'
116
- - - ">="
117
- - !ruby/object:Gem::Version
118
- version: 1.3.10
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - "~>"
124
- - !ruby/object:Gem::Version
125
- version: '1.3'
126
- - - ">="
127
- - !ruby/object:Gem::Version
128
- version: 1.3.10
129
81
  - !ruby/object:Gem::Dependency
130
82
  name: mocha
131
83
  requirement: !ruby/object:Gem::Requirement
@@ -151,6 +103,9 @@ dependencies:
151
103
  requirement: !ruby/object:Gem::Requirement
152
104
  requirements:
153
105
  - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '5.5'
108
+ - - ">="
154
109
  - !ruby/object:Gem::Version
155
110
  version: 5.5.1
156
111
  type: :development
@@ -158,13 +113,14 @@ dependencies:
158
113
  version_requirements: !ruby/object:Gem::Requirement
159
114
  requirements:
160
115
  - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '5.5'
118
+ - - ">="
161
119
  - !ruby/object:Gem::Version
162
120
  version: 5.5.1
163
- description: Ruby gem for Constructor.io's autocomplete service. Enables Rails models
164
- to send updates to the Constructor.io API automatically, and provides a view helper
165
- to add autocomplete on any input.
121
+ description: Ruby gem for Constructor.io's autocomplete service.
166
122
  email:
167
- - lai.steven@gmail.com
123
+ - dan@constructor.io
168
124
  executables: []
169
125
  extensions: []
170
126
  extra_rdoc_files: []
@@ -178,16 +134,12 @@ files:
178
134
  - Rakefile
179
135
  - constructorio.gemspec
180
136
  - lib/constructorio.rb
137
+ - lib/constructorio/client.rb
181
138
  - lib/constructorio/configuration.rb
182
- - lib/constructorio/fields.rb
183
- - lib/constructorio/helper.rb
184
- - lib/constructorio/railtie.rb
185
- - lib/constructorio/tasks/import.rake
186
139
  - lib/constructorio/version.rb
187
140
  - test/configuration_test.rb
188
141
  - test/constructorio_test.rb
189
142
  - test/test_helper.rb
190
- - test/view_helper_test.rb
191
143
  homepage: http://constructor.io
192
144
  licenses:
193
145
  - MIT
@@ -216,4 +168,3 @@ test_files:
216
168
  - test/configuration_test.rb
217
169
  - test/constructorio_test.rb
218
170
  - test/test_helper.rb
219
- - test/view_helper_test.rb
@@ -1,27 +0,0 @@
1
- require 'singleton'
2
-
3
- module ConstructorIO
4
- class Fields
5
- include Singleton
6
-
7
- attr_accessor :set
8
-
9
- def initialize
10
- @set = {}
11
- end
12
-
13
- def add(model_name, field)
14
- @set[model_name] ||= {}
15
- @set[model_name][field] = 1
16
- end
17
-
18
- def list(model_name)
19
- if @set[model_name].is_a?(Hash)
20
- @set[model_name].keys
21
- else
22
- []
23
- end
24
- end
25
- end
26
- end
27
-
@@ -1,11 +0,0 @@
1
- # usage: <%= autocomplete :dom_id => "search" %>
2
-
3
- module ConstructorIO
4
- module Helper
5
- def constructorio_autocomplete(options = {})
6
- result = %Q|<script type="text/javascript" src="//cnstrc.com/js/ac.js"></script>\n|
7
- result += %Q|<script>$(document).ready(function(){ $('##{options[:dom_id]}').constructorAutocomplete({ key: '#{ConstructorIO.configuration.autocomplete_key}' }); })</script>|
8
- return result.html_safe
9
- end
10
- end
11
- end
@@ -1,15 +0,0 @@
1
- require 'rails'
2
-
3
- module ConstructorIO
4
- class Railtie < Rails::Railtie
5
- initializer 'constructorio.action_view' do
6
- ActiveSupport.on_load(:action_view) do
7
- include ConstructorIO::Helper
8
- end
9
- end
10
-
11
- rake_tasks do
12
- Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].each { |f| load f }
13
- end
14
- end
15
- end
@@ -1,25 +0,0 @@
1
- namespace :constructorio do
2
- import_model_desc = <<-DESC.gsub(/ /, '')
3
- Import data from your model (pass name as CLASS environment variable).
4
-
5
- $ rake environment constructorio:import:model CLASS='MyModel'
6
- DESC
7
-
8
- task :import => 'import:model'
9
-
10
- namespace :import do
11
- desc import_model_desc
12
-
13
- task :model do
14
- klass = eval(ENV['CLASS'].to_s)
15
- fields = ConstructorIO::Fields.instance.list(klass.model_name)
16
- if fields.any?
17
- klass.all.each do |record|
18
- fields.each do |field|
19
- klass.add_record(record[field.to_sym], ConstructorIO.configuration.autocomplete_key)
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,11 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- class ViewHelperTest < MiniTest::Test
4
- def setup
5
- @fakeview = FakeView.new
6
- end
7
-
8
- def test_autocomplete_html
9
- assert_equal @fakeview.constructorio_autocomplete(dom_id: 'a'), "<script type=\"text/javascript\" src=\"//cnstrc.com/js/ac.js\"></script>\n<script>$(document).ready(function(){ $('#a').constructorAutocomplete({ key: 'example_autocomplete_key' }); })</script>"
10
- end
11
- end