pushpop-product-hunt 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f590d2284f5f7fec629133a55725070e7f3d21b4
4
+ data.tar.gz: c5d751a55023d8011c3fa2d7266678cb7fd072aa
5
+ SHA512:
6
+ metadata.gz: d33cc2c7b46cb7edaa92c3d5592f47e33af91031947b23d0fac25af106845feca9e121e5a900eed8f9b709685052ec7c91dccae4aacc2592b87fc96ad7666778
7
+ data.tar.gz: 52cf34a62b6db21b7c85c17ff89394f2e76dde5cb2023c51265cc5535c7d6a36b40ee59432cbc2b169b044f446394e7472a857a6c1d54cb6ea468434930a06a8
@@ -0,0 +1 @@
1
+ Gemfile.lock
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+
4
+ rvm:
5
+ - 2.1.1
6
+
7
+ script:
8
+ - bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'pushpop'
4
+
5
+ group :development, :test do
6
+ gem 'rake'
7
+ gem 'rspec'
8
+ gem 'webmock'
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Author Josh Dzielak
2
+ Copyright (c) 2014 Keen Labs
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,244 @@
1
+ # pushpop-product-hunt
2
+
3
+ Product Hunt plugin for [Pushpop](https://github.com/pushpop-project/pushpop).
4
+
5
+ - [Installation](#installation)
6
+ - [Usage](#usage)
7
+ - [Post Functions](#[post]-functions)
8
+ - [User Functions](#user-functions)
9
+ - [Collection Functions](#collection-functions)
10
+ - [Nested Resources](#nested-resources)
11
+ - [Pagination, Sorting, Ordering](#pagination-sorting-ordering)
12
+ - [Todo](#todo)
13
+ - [Contributing](#contributing)
14
+
15
+ ## Installation
16
+
17
+ Add `pushpop-product-hunt` to your Gemfile:
18
+
19
+ ```ruby
20
+ gem 'pushpop-product-hunt'
21
+ ```
22
+
23
+ or install it as a gem
24
+
25
+ ```bash
26
+ $ gem install pushpop-product-hunt
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ The product hunt plugin gives you an easy interface for pulling information out of Product Hunt. We've wrapped pretty much all of [Product Hunt's API](https://api.producthunt.com/v1/docs), so nearly everything is available to you.
32
+
33
+ Here's a quick preview of something a product hunt job could do
34
+
35
+ ``` ruby
36
+ job 'alert me if Keen is on product hunt' do
37
+ product_hunt do
38
+ posts('https://keen.io')
39
+ end
40
+
41
+ step do |response|
42
+ if response['posts'].length > 0
43
+ response['posts']
44
+ else
45
+ false
46
+ end
47
+ end
48
+
49
+ sendgrid do |posts|
50
+ # Send the email
51
+ end
52
+ end
53
+ ```
54
+
55
+ In order to query the Product Hunt API, you will need to put an [application token](https://www.producthunt.com/v1/oauth/applications) in the `PRODUCT_HUNT_TOKEN` environment variable.
56
+
57
+ ### Post Functions
58
+
59
+ **day([date])**
60
+
61
+ This requests all posts for a given day. By default, it will request posts from the current day.
62
+
63
+ Optionally, you can pass in a date specifier. Passing a number will get posts `N` days ago. Passing a string will attempt to parse that into a date, and request posts for that date.
64
+
65
+ ``` ruby
66
+ product_hunt do
67
+ day # Get today's posts
68
+ end
69
+
70
+ product_hunt do
71
+ day 3 # Get posts from 3 days ago
72
+ end
73
+
74
+ product_hunt do
75
+ day '2014-07-04' # Get posts from July 4th, 2014.
76
+ end
77
+ ```
78
+
79
+ **posts([url])**
80
+
81
+ This will get the most recent page of posts.
82
+
83
+ You can optionally pass in a URL to this function to filter to only posts that match that URL.
84
+
85
+ ``` ruby
86
+ product_hunt do
87
+ posts # Get all posts
88
+ end
89
+
90
+ product_hunt do
91
+ posts 'https://keen.io' # Get posts on keen.io
92
+ end
93
+ ```
94
+
95
+ **post(id)**
96
+
97
+ Gets a single post with the given ID
98
+
99
+ ``` ruby
100
+ product_hunt do
101
+ post 1234 # Gets post 1234
102
+ end
103
+ ```
104
+
105
+ ### User Functions
106
+
107
+ **users()**
108
+
109
+ Gets all users
110
+
111
+ ``` ruby
112
+ product_hunt do
113
+ users # Get all users
114
+ end
115
+ ```
116
+
117
+ **user(id)**
118
+
119
+ Gets a user with the specified ID.
120
+
121
+ ``` ruby
122
+ product_hunt do
123
+ user 4321 # Get user 4321
124
+ end
125
+ ```
126
+
127
+ ### Collection Functions
128
+
129
+ **collections()**
130
+
131
+ Get all collections
132
+
133
+ ``` ruby
134
+ product_hunt do
135
+ collections # Get all collections
136
+ end
137
+ ```
138
+
139
+ **featured_collections()**
140
+
141
+ Gets all of the featured collections.
142
+
143
+ ``` ruby
144
+ product_hunt do
145
+ featured_collections # Get all featured collections
146
+ end
147
+ ```
148
+
149
+ **collections(id)**
150
+
151
+ Gets the collection with the specified ID.
152
+
153
+ ``` ruby
154
+ product_hunt do
155
+ collection 6789 # Get collection 6789
156
+ end
157
+ ```
158
+
159
+ ### Nested Resources
160
+
161
+ You can sometimes filter your results to only get resources _owned_ by another resource. In order to do that, you would ask for the parent resource first (ie: `user 10`), and then the child resource list (ie: `collections`).
162
+
163
+ #### Posts created by a user
164
+
165
+ ``` ruby
166
+ product_hunt do
167
+ user 10
168
+ posts # Gets posts created by user 10
169
+ end
170
+ ```
171
+
172
+ #### Collections created by a user
173
+
174
+ ``` ruby
175
+ product_hunt do
176
+ user 10
177
+ collections # Gets collections created by user 10
178
+ end
179
+ ```
180
+
181
+ #### Collections that contain a post
182
+
183
+ ``` ruby
184
+ product_hunt do
185
+ post 35
186
+ collections # Gets collections that contain post 35
187
+ end
188
+ ```
189
+
190
+ ### Pagination, Sorting Ordering
191
+
192
+ Certain Product Hunt endpoints support pagination, sorting, and ordering. These functions allow you to customize your requests with those options.
193
+
194
+ **per_page(count)**
195
+ *available on posts, users, and collections.*
196
+
197
+ Sets the number of resources you should receive from any of the LIST functions
198
+
199
+ ``` ruby
200
+ product_hunt do
201
+ posts
202
+ per_page 100
203
+ end
204
+ ```
205
+
206
+ **newer_than(id)**
207
+ *available on posts, users, and collections.*
208
+
209
+ Filters your results to resources with an ID *higher* than the ID.
210
+
211
+ ``` ruby
212
+ product_hunt do
213
+ posts
214
+ newer_than 1234
215
+ end
216
+ ```
217
+
218
+ **older_than(id)**
219
+ *available on posts, users, and collections.*
220
+
221
+ Filters your results to resources with an ID *lower* than the ID.
222
+
223
+ ``` ruby
224
+ product_hunt do
225
+ posts
226
+ older_than 4321
227
+ end
228
+ ```
229
+
230
+ **sort(field, [direction])**
231
+ *available on collections*
232
+
233
+ Sorts your results by a certain field. By default, results will be sorted ascending. Pass `'desc'` as the second parameter to sort descending.
234
+
235
+ ``` ruby
236
+ product_hunt do
237
+ collections
238
+ sort_by 'created_at', 'desc'
239
+ end
240
+ ```
241
+
242
+ ## Contributing
243
+
244
+ Code and documentation issues and pull requests are definitely welcome!
@@ -0,0 +1,16 @@
1
+ $stdout.sync = true
2
+
3
+ $: << File.join(File.dirname(__FILE__), './lib')
4
+
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+ desc 'Run Rspec unit tests'
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.pattern = 'spec/**/*_spec.rb'
10
+ end
11
+
12
+ task default: :spec
13
+ rescue LoadError
14
+ end
15
+
16
+
@@ -0,0 +1,112 @@
1
+ require 'pushpop'
2
+ require 'pushpop-product-hunt/client'
3
+ require 'date'
4
+
5
+ module Pushpop
6
+ module ProductHunt
7
+ class Step < Pushpop::Step
8
+
9
+ PLUGIN_NAME = 'product_hunt'
10
+
11
+ Pushpop::Job.register_plugin(PLUGIN_NAME, self)
12
+
13
+ ## SETUP FUNCTIONS ##
14
+
15
+ def run(last_response=nil, step_responses=nil)
16
+ client.reset()
17
+
18
+ ret = self.configure(last_response, step_responses)
19
+
20
+ resp = client.get()
21
+
22
+ if resp
23
+ resp
24
+ else
25
+ ret
26
+ end
27
+ end
28
+
29
+ def configure(last_response=nil, step_responses=nil)
30
+ self.instance_exec(last_response, step_responses, &block)
31
+ end
32
+
33
+ def client
34
+ if @client
35
+ @client
36
+ else
37
+ if ENV['PRODUCT_HUNT_TOKEN'].nil? || ENV['PRODUCT_HUNT_TOKEN'].empty?
38
+ raise 'You have to set the PRODUCT_HUNT_TOKEN'
39
+ else
40
+ @client = Pushpop::ProductHunt::Client.new(ENV['PRODUCT_HUNT_TOKEN'])
41
+ end
42
+ end
43
+ end
44
+
45
+ ## QUERYING FUNCTIONS ##
46
+
47
+ def day(date = nil)
48
+ client.type('posts')
49
+
50
+ if date.is_a? String
51
+ # Parse the date, and then reoutput it to get a consistent format
52
+ client.option('day', Date.parse(date).to_s)
53
+ elsif date.is_a? Date
54
+ client.option('day', date.to_s)
55
+ elsif date.is_a? Numeric
56
+ client.option('days_ago', date)
57
+ elsif !date.nil?
58
+ raise 'Unknown date format'
59
+ end
60
+ end
61
+
62
+ def posts(url = nil)
63
+ client.identifier('all')
64
+ client.type('posts')
65
+
66
+ unless url.nil?
67
+ client.option('search[url]' => url)
68
+ end
69
+ end
70
+
71
+ def post(id)
72
+ client.post(id)
73
+ end
74
+
75
+ def users
76
+ client.type('users')
77
+ end
78
+
79
+ def user(id)
80
+ client.user(id)
81
+ end
82
+
83
+ def collections
84
+ client.type('collections')
85
+ end
86
+
87
+ def featured_collections
88
+ collections
89
+ client.option('search[featured]' => true)
90
+ end
91
+
92
+ # Options Functions
93
+
94
+ def per_page(count)
95
+ client.option('per_page', count)
96
+ end
97
+
98
+ def older_than(max)
99
+ client.option('older', max)
100
+ end
101
+
102
+ def newer_than(min)
103
+ client.option('newer', min)
104
+ end
105
+
106
+ def sort(field, direction = 'asc')
107
+ client.option('sort_by', field)
108
+ client.option('order', direction)
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,155 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ module Pushpop
5
+ module ProductHunt
6
+ class Client
7
+ include HTTParty
8
+
9
+ API_VERSION = 'v1'
10
+ base_uri 'https://api.producthunt.com'
11
+
12
+ USER_SCOPABLE_ENDPOINTS = [
13
+ 'posts',
14
+ 'collections'
15
+ ]
16
+ POST_SCOPABLE_ENDPOINTS = [
17
+ 'collections'
18
+ ]
19
+
20
+ PAGINATING_ENDPOINTS = [
21
+ 'posts',
22
+ 'users',
23
+ 'collections'
24
+ ]
25
+ SORTABLE_ENDPOINTS = [
26
+ 'collections'
27
+ ]
28
+ ORDERABLE_ENDPOINTS = [
29
+ 'users',
30
+ 'collections'
31
+ ]
32
+
33
+ attr_accessor :_user
34
+ attr_accessor :_post
35
+ attr_accessor :_options
36
+
37
+ def initialize(token)
38
+ @api_token = token
39
+ self._options = {}
40
+ end
41
+
42
+ def get
43
+ url = construct_url
44
+
45
+ if url
46
+ self.class.headers({
47
+ 'Accept' => 'application/json',
48
+ 'Content-Type' => 'application/json',
49
+ 'Authorization' => "Bearer #{@api_token}"
50
+ })
51
+
52
+ response = self.class.get(url)
53
+
54
+ if response.code == 200
55
+ JSON.parse(response.body)
56
+ else
57
+ raise "Something went wrong with the Product Hunt request, returned status code #{response.code}"
58
+ end
59
+ else
60
+ false
61
+ end
62
+ end
63
+
64
+ def reset
65
+ self._user = nil
66
+ self._post = nil
67
+ self._options = {}
68
+ end
69
+
70
+ def construct_url
71
+ return false unless @type
72
+
73
+ url = "/#{API_VERSION}/#{@type}"
74
+
75
+ if @identifier
76
+ url = "#{url}/#{@identifier}"
77
+
78
+ if @subtype
79
+ url = "#{url}/#{@subtype}"
80
+ end
81
+ end
82
+
83
+ url = "#{url}?"
84
+ escaper = Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
85
+ self._options.each { |key, value|
86
+ case key
87
+ when 'older', 'newer', 'per_page'
88
+ next unless PAGINATING_ENDPOINTS.include?(@subtype || @type)
89
+ when 'sort_by'
90
+ next unless SORTABLE_ENDPOINTS.include?(@subtype || @type)
91
+ when 'order'
92
+ next unless ORDERABLE_ENDPOINTS.include?(@subtype || @type)
93
+ next unless ['asc', 'desc'].include?(value)
94
+ end
95
+
96
+ url = "#{url}#{URI.escape(key, escaper)}=#{URI.escape(value, escaper)}&"
97
+ }
98
+
99
+ url
100
+ end
101
+
102
+ def type(type)
103
+ @type = type
104
+ set_contextual_identifier
105
+ end
106
+
107
+ def subtype(type)
108
+ @subtype = type
109
+ end
110
+
111
+ def identifier(id)
112
+ @identifier = id
113
+ end
114
+
115
+ def user(id)
116
+ self._user = id
117
+ type('users')
118
+ identifier(id)
119
+ end
120
+
121
+ def post(id)
122
+ self._post = id
123
+ type('posts')
124
+ identifier(id)
125
+ end
126
+
127
+ def option(key, value)
128
+ self._options[key] = value
129
+ end
130
+
131
+ # If the user sets a specific post ID or user ID prior to calling
132
+ # one of the list functions like #collections, we should scope
133
+ # that call to only return items that are related
134
+ def set_contextual_identifier
135
+ # Let's prioritize user identifiers over posts identifiers
136
+ if self._user && USER_SCOPABLE_ENDPOINTS.include?(@type)
137
+ @subtype = @type
138
+ @type = 'users'
139
+ @identifier = self._user
140
+
141
+ true
142
+ elsif self._post && POST_SCOPABLE_ENDPOINTS.include?(@type)
143
+ @subtype = @type
144
+ @type = 'posts'
145
+ @identifier = self._post
146
+
147
+ true
148
+ else
149
+ false
150
+ end
151
+ end
152
+
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+
6
+ s.name = "pushpop-product-hunt"
7
+ s.version = '0.1'
8
+ s.authors = ["Joe Wegner"]
9
+ s.email = "joe@keen.io"
10
+ s.homepage = "https://github.com/pushpop-project/pushpop-product-hunt"
11
+ s.summary = "A Pushpop Plugin for triggering based on Product Hunt data"
12
+
13
+ s.add_dependency "pushpop"
14
+ s.add_dependency "hunting_season"
15
+ s.add_dependency 'httparty'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
22
+
@@ -0,0 +1,174 @@
1
+ require 'spec_helper'
2
+ require 'webmock/rspec'
3
+
4
+ describe Pushpop::ProductHunt::Client do
5
+
6
+ before(:each) do
7
+ stub_request(:get, /.*api\.producthunt\.com.*/)
8
+ end
9
+
10
+ describe 'internal functions' do
11
+ client = nil
12
+ before(:each) do
13
+ client = Pushpop::ProductHunt::Client.new('12345')
14
+ end
15
+
16
+ it 'resets state values' do
17
+ client.user(123)
18
+ client.post(321)
19
+ client.option('number', 456)
20
+
21
+ client.reset
22
+
23
+ expect(client._user).to be_nil
24
+ expect(client._post).to be_nil
25
+ expect(client._options).to eq({})
26
+ end
27
+
28
+ describe '#set_contextual_identifier' do
29
+ it 'scopes user queries' do
30
+ client.user(10)
31
+ client.type('posts')
32
+
33
+ expect(client.instance_variable_get('@type')).to eq('users')
34
+ expect(client.instance_variable_get('@identifier')).to eq(10)
35
+ expect(client.instance_variable_get('@subtype')).to eq('posts')
36
+ end
37
+
38
+ it 'scopes post queries' do
39
+ client.post(10)
40
+ client.type('collections')
41
+
42
+ expect(client.instance_variable_get('@type')).to eq('posts')
43
+ expect(client.instance_variable_get('@identifier')).to eq(10)
44
+ expect(client.instance_variable_get('@subtype')).to eq('collections')
45
+ end
46
+
47
+ it 'doesnt scope thins that arent defined as scopable' do
48
+ client.user(10)
49
+ client.type('comments')
50
+
51
+ expect(client.instance_variable_get('@type')).to eq('comments')
52
+ end
53
+ end
54
+
55
+ describe '#construct_url' do
56
+ before(:each) do
57
+ client.reset
58
+ end
59
+
60
+ it 'builds URLs with types' do
61
+ client.type 'post'
62
+
63
+ expect(client.construct_url).to include('/post')
64
+ end
65
+
66
+ it 'builds URLs with identifiers' do
67
+ client.type 'post'
68
+ client.identifier 10
69
+
70
+ expect(client.construct_url).to include('/post/10')
71
+ end
72
+
73
+ it 'builds URLs with subtypes' do
74
+ client.type 'user'
75
+ client.identifier 10
76
+ client.subtype 'posts'
77
+
78
+ expect(client.construct_url).to include('/user/10/posts')
79
+ end
80
+
81
+ it 'puts options in the URL' do
82
+ client.type 'post'
83
+ client.option 'some', 'thing'
84
+
85
+ expect(client.construct_url).to include('some=thing')
86
+ end
87
+
88
+ it 'doesnt add options that are blocked from an endpoint' do
89
+ client.type 'bad'
90
+ client.option 'order', 'asc'
91
+
92
+ expect(client.construct_url).not_to include('order=asc')
93
+ end
94
+ end
95
+ end
96
+
97
+ describe 'query building functions' do
98
+ client = nil
99
+ before(:each) do
100
+ client = Pushpop::ProductHunt::Client.new('12345')
101
+ end
102
+
103
+ describe 'type' do
104
+ it 'sets the type of resource to request' do
105
+ client.type('test')
106
+ expect(client.instance_variable_get('@type')).to eq('test')
107
+ end
108
+
109
+ it 'will set contextual identifiers' do
110
+ expect(client).to receive(:set_contextual_identifier)
111
+ client.type('test')
112
+ end
113
+ end
114
+
115
+ describe 'subtype' do
116
+ it 'sets the subtype to request' do
117
+ client.subtype('test')
118
+ expect(client.instance_variable_get('@subtype')).to eq('test')
119
+ end
120
+ end
121
+
122
+ describe 'identifier' do
123
+ it 'sets the resource identifier to request' do
124
+ client.identifier(10)
125
+ expect(client.instance_variable_get('@identifier')).to eq(10)
126
+ end
127
+ end
128
+
129
+ describe 'user' do
130
+ it 'sets the user context' do
131
+ client.user(10)
132
+ expect(client._user).to eq(10)
133
+ end
134
+
135
+ it 'sets the resource type to users' do
136
+ client.user(10)
137
+ expect(client.instance_variable_get('@type')).to eq('users')
138
+ end
139
+
140
+ it 'sets the resource identifier to the user id' do
141
+ client.user(10)
142
+ expect(client.instance_variable_get('@identifier')).to eq(10)
143
+ end
144
+ end
145
+
146
+ describe 'post' do
147
+ it 'sets the post context' do
148
+ client.post(10)
149
+ expect(client._post).to eq(10)
150
+ end
151
+
152
+ it 'sets the resource type to posts' do
153
+ client.post(10)
154
+ expect(client.instance_variable_get('@type')).to eq('posts')
155
+ end
156
+
157
+ it 'sets the resource identifier to the post id' do
158
+ client.post(10)
159
+ expect(client.instance_variable_get('@identifier')).to eq(10)
160
+ end
161
+ end
162
+
163
+ describe 'option' do
164
+ before(:each) do
165
+ client.reset
166
+ end
167
+
168
+ it 'sets keys and values' do
169
+ client.option('test', 'tester')
170
+ expect(client._options['test']).to eq('tester')
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,269 @@
1
+ require 'spec_helper'
2
+ require 'date'
3
+ require 'webmock/rspec'
4
+ require 'json'
5
+
6
+ ENV['PRODUCT_HUNT_TOKEN'] = '12345'
7
+
8
+ describe Pushpop::ProductHunt::Step do
9
+
10
+ before(:each) do
11
+ stub_request(:get, /.*api\.producthunt\.com.*/).
12
+ to_return(:body => JSON.generate({:success => true}))
13
+ end
14
+
15
+ describe 'internal functions' do
16
+ it 'has a ProductHunt::Client' do
17
+ step = Pushpop::ProductHunt::Step.new
18
+
19
+ expect(step.client).to be_a(Pushpop::ProductHunt::Client)
20
+ end
21
+
22
+ it 'resets the client' do
23
+ step = Pushpop::ProductHunt::Step.new do
24
+ #nothing
25
+ end
26
+
27
+ expect(step.client).to receive(:reset)
28
+ step.run
29
+ end
30
+ end
31
+
32
+
33
+ describe '#day' do
34
+ it 'queries for posts by day' do
35
+ step = Pushpop::ProductHunt::Step.new do
36
+ day
37
+ end
38
+
39
+ expect(step.client).to receive(:type).with('posts')
40
+
41
+ step.run
42
+ end
43
+
44
+ it 'queries for posts on a recent date' do
45
+ step = Pushpop::ProductHunt::Step.new do
46
+ day(3)
47
+ end
48
+
49
+ expect(step.client).to receive(:option).with('days_ago', 3)
50
+
51
+ step.run
52
+ end
53
+
54
+ it 'queries for posts for a specific date string' do
55
+ step = Pushpop::ProductHunt::Step.new do
56
+ day('15th May, 2015')
57
+ end
58
+
59
+ expect(step.client).to receive(:option).with('day', '2015-05-15')
60
+
61
+ step.run
62
+ end
63
+
64
+ it 'queries for posts for a Date object' do
65
+ step = Pushpop::ProductHunt::Step.new do
66
+ day(Date.parse('2015-05-15'))
67
+ end
68
+
69
+ expect(step.client).to receive(:option).with('day', '2015-05-15')
70
+
71
+ step.run
72
+ end
73
+ end
74
+
75
+ describe '#posts' do
76
+ it 'queries for all posts' do
77
+ step = Pushpop::ProductHunt::Step.new do
78
+ posts
79
+ end
80
+
81
+ expect(step.client).to receive(:type).with('posts')
82
+ expect(step.client).to receive(:identifier).with('all')
83
+
84
+ step.run
85
+ end
86
+
87
+ it 'queries for posts with a specific URL' do
88
+ step = Pushpop::ProductHunt::Step.new do
89
+ posts 'https://www.example.com'
90
+ end
91
+
92
+ expect(step.client).to receive(:option).with('search[url]' => 'https://www.example.com')
93
+
94
+ step.run
95
+ end
96
+
97
+ it 'queries for posts owned by a user' do
98
+ step = Pushpop::ProductHunt::Step.new do
99
+ user(10)
100
+ posts
101
+ end
102
+
103
+ step.run
104
+
105
+ expect(step.client.instance_variable_get('@type')).to eq('users')
106
+ expect(step.client.instance_variable_get('@identifier')).to eq(10)
107
+ expect(step.client.instance_variable_get('@subtype')).to eq('posts')
108
+ end
109
+ end
110
+
111
+ describe '#post' do
112
+ it 'queries for a post by id' do
113
+ step = Pushpop::ProductHunt::Step.new do
114
+ post 10
115
+ end
116
+
117
+ expect(step.client).to receive(:post).with(10)
118
+
119
+ step.run
120
+ end
121
+
122
+ it 'sets the current post context' do
123
+ step = Pushpop::ProductHunt::Step.new do
124
+ post 10
125
+ end
126
+
127
+ step.run
128
+ expect(step.client._post).to eq(10)
129
+ end
130
+ end
131
+
132
+ describe '#users' do
133
+ it 'gets a list of users' do
134
+ step = Pushpop::ProductHunt::Step.new do
135
+ users
136
+ end
137
+
138
+ expect(step.client).to receive(:type).with('users')
139
+
140
+ step.run
141
+ end
142
+ end
143
+
144
+ describe '#user' do
145
+ it 'gets a single user' do
146
+ step = Pushpop::ProductHunt::Step.new do
147
+ user 10
148
+ end
149
+
150
+ expect(step.client).to receive(:user).with(10)
151
+
152
+ step.run
153
+ end
154
+
155
+ it 'sets the current user context' do
156
+ step = Pushpop::ProductHunt::Step.new do
157
+ user 10
158
+ end
159
+
160
+ step.run
161
+ expect(step.client._user).to eq(10)
162
+ end
163
+ end
164
+
165
+ describe '#collections' do
166
+ it 'gets all collections' do
167
+ step = Pushpop::ProductHunt::Step.new do
168
+ collections
169
+ end
170
+
171
+ expect(step.client).to receive(:type).with('collections')
172
+
173
+ step.run
174
+ end
175
+
176
+ it 'queries for collections created by a user' do
177
+ step = Pushpop::ProductHunt::Step.new do
178
+ user(10)
179
+ collections
180
+ end
181
+
182
+ step.run
183
+
184
+ expect(step.client.instance_variable_get('@type')).to eq('users')
185
+ expect(step.client.instance_variable_get('@identifier')).to eq(10)
186
+ expect(step.client.instance_variable_get('@subtype')).to eq('collections')
187
+ end
188
+
189
+ it 'queries for collections containing a post' do
190
+ step = Pushpop::ProductHunt::Step.new do
191
+ post(10)
192
+ collections
193
+ end
194
+
195
+ step.run
196
+
197
+ expect(step.client.instance_variable_get('@type')).to eq('posts')
198
+ expect(step.client.instance_variable_get('@identifier')).to eq(10)
199
+ expect(step.client.instance_variable_get('@subtype')).to eq('collections')
200
+ end
201
+ end
202
+
203
+ describe '#featured_collections' do
204
+ it 'gets the featured collections' do
205
+ step = Pushpop::ProductHunt::Step.new do
206
+ featured_collections
207
+ end
208
+
209
+ expect(step.client).to receive(:type).with('collections')
210
+ expect(step.client).to receive(:option).with('search[featured]' => true)
211
+
212
+ step.run
213
+ end
214
+ end
215
+
216
+ describe 'options functions' do
217
+ it 'sets the per page value' do
218
+ step = Pushpop::ProductHunt::Step.new do
219
+ per_page 100
220
+ end
221
+
222
+ expect(step.client).to receive(:option).with('per_page', 100)
223
+
224
+ step.run
225
+ end
226
+
227
+ it 'sets the minimum id' do
228
+ step = Pushpop::ProductHunt::Step.new do
229
+ newer_than 54321
230
+ end
231
+
232
+ expect(step.client).to receive(:option).with('newer', 54321)
233
+
234
+ step.run
235
+ end
236
+
237
+ it 'sets the maximum id' do
238
+ step = Pushpop::ProductHunt::Step.new do
239
+ older_than 98765
240
+ end
241
+
242
+ expect(step.client).to receive(:option).with('older', 98765)
243
+
244
+ step.run
245
+ end
246
+
247
+ it 'sets the sort and defaults to asc' do
248
+ step = Pushpop::ProductHunt::Step.new do
249
+ sort 'created_at'
250
+ end
251
+
252
+ expect(step.client).to receive(:option).with('sort_by', 'created_at')
253
+ expect(step.client).to receive(:option).with('order', 'asc')
254
+
255
+ step.run
256
+ end
257
+
258
+ it 'can be overridden to order by desc' do
259
+ step = Pushpop::ProductHunt::Step.new do
260
+ sort 'created_at', 'desc'
261
+ end
262
+
263
+ expect(step.client).to receive(:option).with('sort_by', 'created_at')
264
+ expect(step.client).to receive(:option).with('order', 'desc')
265
+
266
+ step.run
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,11 @@
1
+ $: << File.join(File.dirname(__FILE__), '../lib')
2
+
3
+ require 'pushpop'
4
+ require 'pushpop-product-hunt'
5
+
6
+ RSpec.configure do |config|
7
+ config.before :each do
8
+ Pushpop.jobs.clear
9
+ end
10
+ end
11
+
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pushpop-product-hunt
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Joe Wegner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pushpop
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: hunting_season
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: httparty
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
+ description:
56
+ email: joe@keen.io
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - .gitignore
62
+ - .travis.yml
63
+ - Gemfile
64
+ - LICENSE
65
+ - README.md
66
+ - Rakefile
67
+ - lib/pushpop-product-hunt.rb
68
+ - lib/pushpop-product-hunt/client.rb
69
+ - pushpop-plugin.gemspec
70
+ - spec/lib/client_spec.rb
71
+ - spec/pushpop-product-hunt_spec.rb
72
+ - spec/spec_helper.rb
73
+ homepage: https://github.com/pushpop-project/pushpop-product-hunt
74
+ licenses: []
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.0.14
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: A Pushpop Plugin for triggering based on Product Hunt data
96
+ test_files:
97
+ - spec/lib/client_spec.rb
98
+ - spec/pushpop-product-hunt_spec.rb
99
+ - spec/spec_helper.rb