pushpop-product-hunt 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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