pushpad 1.1.0 → 1.2.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
  SHA256:
3
- metadata.gz: dccdac2f6334014fc3b1a7fa42b5cc0644135df02b3e58f9c44f17e7fe00a27e
4
- data.tar.gz: 69c4ea4985bdd6c120445e36c58e8adf0f572874dd7fd3ef929ad90176c84b18
3
+ metadata.gz: 6ca523c6dd48111c5a369889092c80690401158c3f0a14142eb3aee236848062
4
+ data.tar.gz: 637c8461863686d6c3c1f9f666a7df74b2053aed5017318f360054f908b83fbe
5
5
  SHA512:
6
- metadata.gz: b9ab88edcae1bcb44f8e6e1b388d25ee47459c81b6f2c72c9b450a1bf64b08dd874b019d518733a1cb4cf53c7f4f3c8feec7ffc418a144c81cc6b0864c1b67d2
7
- data.tar.gz: 6540c56bb6cbaa46e496098669d081c7c66f35c20e1cc82bb4602510a696179c9fa71ba381dd1693c181fe32adf8a05ef5224ca9a2ea22f16648e35b2eca138b
6
+ metadata.gz: 7aaed7d9218f698803bf1adda9ba1459365b49eaba897903b1cab109aeb9bb825ab40b25119a52cc620d515dd7cce36ad8509d34baacb7b74d58028c26327207
7
+ data.tar.gz: 0e89ea2619f3c6f39c4a073c95d56faa451e672b86ad3d898e681b53c7ecef59af7e2b7b5fd22b3be957ab02cb7fcc98b6c7e4a84b5a328e853f6c5abc8905ac
data/README.md CHANGED
@@ -237,6 +237,29 @@ Pushpad::Subscription.count(project_id: 5, uids: ['user1'], tags: 'sports && tra
237
237
  If `Pushpad.project_id` is defined, the `project_id` option can be
238
238
  omitted.
239
239
 
240
+ ## Getting push subscription data
241
+
242
+ You can retrieve the subscriptions for a given project,
243
+ optionally filtered by `tags` or `uids`:
244
+
245
+ ```ruby
246
+ Pushpad::Subscription.find_all(project_id: 5)
247
+ Pushpad::Subscription.find_all(project_id: 5, uids: ['user1'])
248
+ Pushpad::Subscription.find_all(project_id: 5, tags: ['sports'])
249
+ Pushpad::Subscription.find_all(project_id: 5, tags: 'sports && travel')
250
+ Pushpad::Subscription.find_all(project_id: 5, uids: ['user1'], tags: 'sports && travel')
251
+ ```
252
+
253
+ If `Pushpad.project_id` is defined, the `project_id` option can be
254
+ omitted.
255
+
256
+ The REST API paginates the result set. You can pass a `page` parameter
257
+ to get the full list in multiple requests.
258
+
259
+ ```ruby
260
+ subscriptions = Pushpad::Subscription.find_all(project_id: 5, page: 2)
261
+ ```
262
+
240
263
  ## License
241
264
 
242
265
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -2,51 +2,67 @@ module Pushpad
2
2
  class Subscription
3
3
  class CountError < RuntimeError
4
4
  end
5
-
6
- def self.count(options = {})
7
- CountQuery.new(options).perform
5
+
6
+ class FindError < RuntimeError
8
7
  end
8
+
9
+ attr_reader :id, :endpoint, :p256dh, :auth, :uid, :tags, :last_click_at, :created_at
9
10
 
10
- class CountQuery
11
- attr_reader :options
11
+ def initialize(options)
12
+ @id = options[:id]
13
+ @endpoint = options[:endpoint]
14
+ @p256dh = options[:p256dh]
15
+ @auth = options[:auth]
16
+ @uid = options[:uid]
17
+ @tags = options[:tags]
18
+ @last_click_at = options[:last_click_at] && Time.parse(options[:last_click_at])
19
+ @created_at = options[:created_at] && Time.parse(options[:created_at])
20
+ end
12
21
 
13
- def initialize(options)
14
- @options = options
15
- end
22
+ def self.count(options = {})
23
+ project_id = options[:project_id] || Pushpad.project_id
24
+ raise "You must set project_id" unless project_id
16
25
 
17
- def perform
18
- project_id = options[:project_id] || Pushpad.project_id
19
- raise "You must set project_id" unless project_id
26
+ endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions"
27
+ response = Request.head(endpoint, query_parameters: query_parameters(options))
20
28
 
21
- endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions"
22
- response = Request.head(endpoint, query_parameters: query_parameters)
29
+ unless response.code == "200"
30
+ raise CountError, "Response #{response.code} #{response.message}: #{response.body}"
31
+ end
23
32
 
24
- unless response.code == "200"
25
- raise CountError, "Response #{response.code} #{response.message}: #{response.body}"
26
- end
33
+ response["X-Total-Count"].to_i
34
+ end
35
+
36
+ def self.find_all(options = {})
37
+ project_id = options[:project_id] || Pushpad.project_id
38
+ raise "You must set project_id" unless project_id
27
39
 
28
- response["X-Total-Count"].to_i
29
- end
40
+ query_parameters_with_pagination = query_parameters(options)
41
+ query_parameters_with_pagination << ["page", options[:page]] if options.key?(:page)
30
42
 
31
- private
43
+ response = Request.get("https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions",
44
+ query_parameters: query_parameters_with_pagination)
32
45
 
33
- def query_parameters
34
- [uid_query_parameters, tag_query_parameters].flatten(1)
46
+ unless response.code == "200"
47
+ raise FindError, "Response #{response.code} #{response.message}: #{response.body}"
35
48
  end
36
49
 
37
- def uid_query_parameters
38
- options.fetch(:uids, []).map { |uid| ["uids[]", uid] }
50
+ JSON.parse(response.body, symbolize_names: true).map do |attributes|
51
+ new(attributes)
39
52
  end
53
+ end
40
54
 
41
- def tag_query_parameters
42
- tags = options.fetch(:tags, [])
55
+ private
43
56
 
44
- if tags.is_a?(String)
45
- [["tags", tags]]
46
- else
47
- tags.map { |tag| ["tags[]", tag] }
48
- end
49
- end
57
+ def self.query_parameters(options)
58
+ uids = options.fetch(:uids, [])
59
+ uids_query = uids.map { |uid| ["uids[]", uid] }
60
+
61
+ tags = options.fetch(:tags, [])
62
+ tags_query = tags.is_a?(String) ? [["tags", tags]] : tags.map { |tag| ["tags[]", tag] }
63
+
64
+ [uids_query, tags_query].flatten(1)
50
65
  end
66
+
51
67
  end
52
68
  end
data/pushpad.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "pushpad"
3
- spec.version = '1.1.0'
3
+ spec.version = '1.2.0'
4
4
  spec.authors = ["Pushpad"]
5
5
  spec.email = ["support@pushpad.xyz"]
6
6
  spec.summary = "Web push notifications for Chrome, Firefox, Opera, Edge and Safari using Pushpad."
@@ -13,6 +13,17 @@ module Pushpad
13
13
  stub_request(:head, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
14
14
  to_return(status: 503)
15
15
  end
16
+
17
+ def stub_subscriptions_get(options)
18
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
19
+ with(query: hash_including(options.fetch(:query, {}))).
20
+ to_return(status: 200, body: options[:list].to_json)
21
+ end
22
+
23
+ def stub_failing_subscriptions_get(options)
24
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
25
+ to_return(status: 403)
26
+ end
16
27
 
17
28
  describe ".count" do
18
29
  it "returns value from X-Total-Count header" do
@@ -81,5 +92,110 @@ module Pushpad
81
92
  }.to raise_error(Subscription::CountError)
82
93
  end
83
94
  end
95
+
96
+ describe ".find_all" do
97
+ it "returns subscriptions of project with attributes from json response" do
98
+ attributes = {
99
+ id: 1169,
100
+ endpoint: "https://example.com/push/f7Q1Eyf7EyfAb1",
101
+ p256dh: "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
102
+ auth: "cdKMlhgVeSPzCXZ3V7FtgQ==",
103
+ uid: "exampleUid",
104
+ tags: ["exampleTag1", "exampleTag2"],
105
+ last_click_at: "2023-11-03T10:30:00.000Z",
106
+ created_at: "2016-09-06T10:47:05.494Z"
107
+ }
108
+ stub_subscriptions_get(project_id: 10, list: [attributes])
109
+
110
+ subscriptions = Subscription.find_all(project_id: 10)
111
+
112
+ attributes.delete(:last_click_at)
113
+ attributes.delete(:created_at)
114
+ expect(subscriptions[0]).to have_attributes(attributes)
115
+ expect(subscriptions[0].last_click_at.utc.to_s).to eq(Time.utc(2023, 11, 3, 10, 30, 0.0).to_s)
116
+ expect(subscriptions[0].created_at.utc.to_s).to eq(Time.utc(2016, 9, 6, 10, 47, 5.494).to_s)
117
+ end
118
+
119
+ it "falls back to global project id" do
120
+ attributes = { id: 5 }
121
+ stub_subscriptions_get(project_id: 10, list: [attributes])
122
+
123
+ Pushpad.project_id = 10
124
+ subscriptions = Subscription.find_all
125
+
126
+ expect(subscriptions[0]).to have_attributes(attributes)
127
+ end
128
+
129
+ it "fails with helpful error message when project_id is missing" do
130
+ Pushpad.project_id = nil
131
+
132
+ expect {
133
+ Subscription.find_all
134
+ }.to raise_error(/must set project_id/)
135
+ end
136
+
137
+ it "allows passing page parameter for pagination" do
138
+ attributes = { id: 5 }
139
+ stub_subscriptions_get(project_id: 10, list: [attributes], query: { page: "3" })
140
+
141
+ subscriptions = Subscription.find_all(project_id: 10, page: 3)
142
+
143
+ expect(subscriptions[0]).to have_attributes(attributes)
144
+ end
145
+
146
+ it "fails with FindError if response status code is not 200" do
147
+ stub_failing_subscriptions_get(project_id: 10)
148
+
149
+ expect {
150
+ Subscription.find_all(project_id: 10)
151
+ }.to raise_error(Subscription::FindError)
152
+ end
153
+
154
+ it "allows passing uids" do
155
+ attributes = { id: 5 }
156
+ request = stub_subscriptions_get(project_id: 5, list: [attributes], query: { uids: ["uid0", "uid1"] })
157
+
158
+ Subscription.find_all(project_id: 5, uids: ["uid0", "uid1"])
159
+
160
+ expect(request).to have_been_made.once
161
+ end
162
+
163
+ it "allows passing tags" do
164
+ attributes = { id: 5 }
165
+ request = stub_subscriptions_get(project_id: 5, list: [attributes], query: { tags: ["sports", "travel"] })
166
+
167
+ Subscription.find_all(project_id: 5, tags: ["sports", "travel"])
168
+
169
+ expect(request).to have_been_made.once
170
+ end
171
+
172
+ it "allows passing tags as boolean expression" do
173
+ attributes = { id: 5 }
174
+ request = stub_subscriptions_get(project_id: 5, list: [attributes], query: { tags: "sports || travel" })
175
+
176
+ Subscription.find_all(project_id: 5, tags: "sports || travel")
177
+
178
+ expect(request).to have_been_made.once
179
+ end
180
+
181
+ it "allows passing tags and uids" do
182
+ attributes = { id: 5 }
183
+ request = stub_subscriptions_get(project_id: 5, list: [attributes],
184
+ query: { tags: ["sports", "travel"], uids: ["uid0"] })
185
+
186
+ Subscription.find_all(project_id: 5, tags: ["sports", "travel"], uids: ["uid0"])
187
+
188
+ expect(request).to have_been_made.once
189
+ end
190
+
191
+ it "works properly when there are no results" do
192
+ stub_subscriptions_get(project_id: 5, list: [])
193
+
194
+ subscriptions = Subscription.find_all(project_id: 5)
195
+
196
+ expect(subscriptions).to eq([])
197
+ end
198
+ end
199
+
84
200
  end
85
201
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pushpad
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pushpad
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2024-09-18 00:00:00.000000000 Z
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description:
41
+ description:
42
42
  email:
43
43
  - support@pushpad.xyz
44
44
  executables: []
@@ -66,7 +66,7 @@ homepage: https://pushpad.xyz
66
66
  licenses:
67
67
  - MIT
68
68
  metadata: {}
69
- post_install_message:
69
+ post_install_message:
70
70
  rdoc_options: []
71
71
  require_paths:
72
72
  - lib
@@ -81,8 +81,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  requirements: []
84
- rubygems_version: 3.5.16
85
- signing_key:
84
+ rubygems_version: 3.0.3.1
85
+ signing_key:
86
86
  specification_version: 4
87
87
  summary: Web push notifications for Chrome, Firefox, Opera, Edge and Safari using
88
88
  Pushpad.