pushpad 1.1.0 → 1.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dccdac2f6334014fc3b1a7fa42b5cc0644135df02b3e58f9c44f17e7fe00a27e
4
- data.tar.gz: 69c4ea4985bdd6c120445e36c58e8adf0f572874dd7fd3ef929ad90176c84b18
3
+ metadata.gz: 328e31a9039907c359c8a9eeb0e560a71027163f2fbc05d4f899ef94dd21fad2
4
+ data.tar.gz: 334cc8c408c1b8c0c7a2bb9dcd982919c4f223cd36076869691d251ce932fdfb
5
5
  SHA512:
6
- metadata.gz: b9ab88edcae1bcb44f8e6e1b388d25ee47459c81b6f2c72c9b450a1bf64b08dd874b019d518733a1cb4cf53c7f4f3c8feec7ffc418a144c81cc6b0864c1b67d2
7
- data.tar.gz: 6540c56bb6cbaa46e496098669d081c7c66f35c20e1cc82bb4602510a696179c9fa71ba381dd1693c181fe32adf8a05ef5224ca9a2ea22f16648e35b2eca138b
6
+ metadata.gz: 1126ed9f343b6e9b57dfae141dd8a7c46c2234c459f10d906b3051e8932699851d986f53d8721ae32b3fa8bdb654011e594334d3c699dfaf74f80ee2bf072f6c
7
+ data.tar.gz: 9e0cdb926a5b27b306c74dfd24c556447001087eb6d62fb00d24d462bcbcf160920e39abf932c7bfac3bcb51f281367a074bd7121ce70e2bb628a4d24b7041fd
data/README.md CHANGED
@@ -237,6 +237,83 @@ 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
+
263
+ You can also retrieve the data of a specific subscription if you already know its id:
264
+
265
+ ```ruby
266
+ Pushpad::Subscription.find 123
267
+ Pushpad::Subscription.find 123, project_id: 456
268
+ ```
269
+
270
+ ## Updating push subscription data
271
+
272
+ Usually you add data, like user IDs and tags, to the push subscriptions using the [JavaScript SDK](https://pushpad.xyz/docs/javascript_sdk_reference) in the frontend.
273
+
274
+ However you can also update the subscription data from your server:
275
+
276
+ ```ruby
277
+ Pushpad::Subscription.find_all(uids: ['user1']).each do |subscription|
278
+ # update the user ID associated to the push subscription
279
+ subscription.update uid: 'myuser1'
280
+
281
+ # update the tags associated to the push subscription
282
+ tags = subscription.tags
283
+ tags << 'another_tag'
284
+ subscription.update tags: tags
285
+ end
286
+ ```
287
+
288
+ ## Importing push subscriptions
289
+
290
+ If you need to [import](https://pushpad.xyz/docs/import) some existing push subscriptions (from another service to Pushpad, or from your backups) or if you simply need to create some test data, you can use this method:
291
+
292
+ ```ruby
293
+ attributes = {
294
+ endpoint: "https://example.com/push/f7Q1Eyf7EyfAb1",
295
+ p256dh: "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
296
+ auth: "cdKMlhgVeSPzCXZ3V7FtgQ==",
297
+ uid: "exampleUid",
298
+ tags: ["exampleTag1", "exampleTag2"]
299
+ }
300
+
301
+ subscription = Pushpad::Subscription.create(attributes, project_id: 5)
302
+ ```
303
+
304
+ Please note that this is not the standard way to collect subscriptions on Pushpad: usually you subscribe the users to the notifications using the [JavaScript SDK](https://pushpad.xyz/docs/javascript_sdk_reference) in the frontend.
305
+
306
+ ## Deleting push subscriptions
307
+
308
+ Usually you unsubscribe a user from push notifications using the [JavaScript SDK](https://pushpad.xyz/docs/javascript_sdk_reference) in the frontend (recommended).
309
+
310
+ However you can also delete the subscriptions using this library. Be careful, the subscriptions are permanently deleted!
311
+
312
+ ```ruby
313
+ subscription = Pushpad::Subscription.find 123
314
+ subscription.delete
315
+ ```
316
+
240
317
  ## License
241
318
 
242
319
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -19,6 +19,12 @@ module Pushpad
19
19
  end
20
20
  end
21
21
 
22
+ def patch(endpoint, body, options = {})
23
+ perform(Net::HTTP::Patch, endpoint, options) do |request|
24
+ request.body = body
25
+ end
26
+ end
27
+
22
28
  def delete(endpoint, options = {})
23
29
  perform(Net::HTTP::Delete, endpoint, options)
24
30
  end
@@ -1,52 +1,137 @@
1
1
  module Pushpad
2
2
  class Subscription
3
+ class CreateError < RuntimeError
4
+ end
5
+
6
+ class UpdateError < RuntimeError
7
+ end
8
+
3
9
  class CountError < RuntimeError
4
10
  end
5
-
6
- def self.count(options = {})
7
- CountQuery.new(options).perform
11
+
12
+ class FindError < RuntimeError
13
+ end
14
+
15
+ class DeleteError < RuntimeError
8
16
  end
17
+
18
+ attr_reader :id, :endpoint, :p256dh, :auth, :uid, :tags, :last_click_at, :created_at
9
19
 
10
- class CountQuery
11
- attr_reader :options
20
+ def initialize(options)
21
+ @id = options[:id]
22
+ @endpoint = options[:endpoint]
23
+ @p256dh = options[:p256dh]
24
+ @auth = options[:auth]
25
+ @uid = options[:uid]
26
+ @tags = options[:tags]
27
+ @last_click_at = options[:last_click_at] && Time.parse(options[:last_click_at])
28
+ @created_at = options[:created_at] && Time.parse(options[:created_at])
29
+ end
30
+
31
+ def self.create(attributes, options = {})
32
+ project_id = options[:project_id] || Pushpad.project_id
33
+ raise "You must set project_id" unless project_id
34
+
35
+ endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions"
36
+ response = Request.post(endpoint, attributes.to_json)
12
37
 
13
- def initialize(options)
14
- @options = options
38
+ unless response.code == "201"
39
+ raise CreateError, "Response #{response.code} #{response.message}: #{response.body}"
15
40
  end
41
+
42
+ new(JSON.parse(response.body, symbolize_names: true))
43
+ end
16
44
 
17
- def perform
18
- project_id = options[:project_id] || Pushpad.project_id
19
- raise "You must set project_id" unless project_id
45
+ def self.count(options = {})
46
+ project_id = options[:project_id] || Pushpad.project_id
47
+ raise "You must set project_id" unless project_id
20
48
 
21
- endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions"
22
- response = Request.head(endpoint, query_parameters: query_parameters)
49
+ endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions"
50
+ response = Request.head(endpoint, query_parameters: query_parameters(options))
23
51
 
24
- unless response.code == "200"
25
- raise CountError, "Response #{response.code} #{response.message}: #{response.body}"
26
- end
52
+ unless response.code == "200"
53
+ raise CountError, "Response #{response.code} #{response.message}: #{response.body}"
54
+ end
55
+
56
+ response["X-Total-Count"].to_i
57
+ end
58
+
59
+ def self.find(id, options = {})
60
+ project_id = options[:project_id] || Pushpad.project_id
61
+ raise "You must set project_id" unless project_id
62
+
63
+ response = Request.get("https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions/#{id}")
27
64
 
28
- response["X-Total-Count"].to_i
65
+ unless response.code == "200"
66
+ raise FindError, "Response #{response.code} #{response.message}: #{response.body}"
29
67
  end
30
68
 
31
- private
69
+ new(JSON.parse(response.body, symbolize_names: true))
70
+ end
71
+
72
+ def self.find_all(options = {})
73
+ project_id = options[:project_id] || Pushpad.project_id
74
+ raise "You must set project_id" unless project_id
75
+
76
+ query_parameters_with_pagination = query_parameters(options)
77
+ query_parameters_with_pagination << ["page", options[:page]] if options.key?(:page)
78
+
79
+ response = Request.get("https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions",
80
+ query_parameters: query_parameters_with_pagination)
32
81
 
33
- def query_parameters
34
- [uid_query_parameters, tag_query_parameters].flatten(1)
82
+ unless response.code == "200"
83
+ raise FindError, "Response #{response.code} #{response.message}: #{response.body}"
35
84
  end
36
85
 
37
- def uid_query_parameters
38
- options.fetch(:uids, []).map { |uid| ["uids[]", uid] }
86
+ JSON.parse(response.body, symbolize_names: true).map do |attributes|
87
+ new(attributes)
39
88
  end
89
+ end
90
+
91
+ def update(attributes, options = {})
92
+ project_id = options[:project_id] || Pushpad.project_id
93
+ raise "You must set project_id" unless project_id
94
+
95
+ raise "You must set id" unless id
96
+
97
+ endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions/#{id}"
98
+ response = Request.patch(endpoint, attributes.to_json)
40
99
 
41
- def tag_query_parameters
42
- tags = options.fetch(:tags, [])
100
+ unless response.code == "200"
101
+ raise UpdateError, "Response #{response.code} #{response.message}: #{response.body}"
102
+ end
103
+
104
+ attributes = JSON.parse(response.body, symbolize_names: true)
105
+ @uid = attributes[:uid]
106
+ @tags = attributes[:tags]
107
+
108
+ self
109
+ end
110
+
111
+ def delete(options = {})
112
+ project_id = options[:project_id] || Pushpad.project_id
113
+ raise "You must set project_id" unless project_id
114
+
115
+ raise "You must set id" unless id
116
+
117
+ response = Request.delete("https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions/#{id}")
43
118
 
44
- if tags.is_a?(String)
45
- [["tags", tags]]
46
- else
47
- tags.map { |tag| ["tags[]", tag] }
48
- end
119
+ unless response.code == "204"
120
+ raise DeleteError, "Response #{response.code} #{response.message}: #{response.body}"
49
121
  end
50
122
  end
123
+
124
+ private
125
+
126
+ def self.query_parameters(options)
127
+ uids = options.fetch(:uids, [])
128
+ uids_query = uids.map { |uid| ["uids[]", uid] }
129
+
130
+ tags = options.fetch(:tags, [])
131
+ tags_query = tags.is_a?(String) ? [["tags", tags]] : tags.map { |tag| ["tags[]", tag] }
132
+
133
+ [uids_query, tags_query].flatten(1)
134
+ end
135
+
51
136
  end
52
137
  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.3.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."
@@ -2,6 +2,16 @@ require "spec_helper"
2
2
 
3
3
  module Pushpad
4
4
  describe Subscription do
5
+ def stub_subscription_get(options)
6
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions/#{options[:id]}").
7
+ to_return(status: 200, body: options[:attributes].to_json)
8
+ end
9
+
10
+ def stub_failing_subscription_get(options)
11
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions/#{options[:id]}").
12
+ to_return(status: 404)
13
+ end
14
+
5
15
  def stub_subscriptions_head(options)
6
16
  stub_request(:head, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
7
17
  with(query: hash_including(options.fetch(:query, {}))).
@@ -13,6 +23,74 @@ module Pushpad
13
23
  stub_request(:head, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
14
24
  to_return(status: 503)
15
25
  end
26
+
27
+ def stub_subscriptions_get(options)
28
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
29
+ with(query: hash_including(options.fetch(:query, {}))).
30
+ to_return(status: 200, body: options[:list].to_json)
31
+ end
32
+
33
+ def stub_failing_subscriptions_get(options)
34
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
35
+ to_return(status: 403)
36
+ end
37
+
38
+ def stub_subscriptions_post(project_id, attributes = {})
39
+ stub_request(:post, "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions").
40
+ with(body: hash_including(attributes)).
41
+ to_return(status: 201, body: attributes.to_json)
42
+ end
43
+
44
+ def stub_failing_subscriptions_post(project_id)
45
+ stub_request(:post, "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions").
46
+ to_return(status: 403)
47
+ end
48
+
49
+ def stub_subscription_patch(project_id, id, attributes = {})
50
+ stub_request(:patch, "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions/#{id}").
51
+ with(body: hash_including(attributes)).
52
+ to_return(status: 200, body: attributes.to_json)
53
+ end
54
+
55
+ def stub_failing_subscription_patch(project_id, id)
56
+ stub_request(:patch, "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions/#{id}").
57
+ to_return(status: 422)
58
+ end
59
+
60
+ def stub_subscription_delete(project_id, id)
61
+ stub_request(:delete, "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions/#{id}").
62
+ to_return(status: 204)
63
+ end
64
+
65
+ def stub_failing_subscription_delete(project_id, id)
66
+ stub_request(:delete, "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions/#{id}").
67
+ to_return(status: 403)
68
+ end
69
+
70
+ describe ".create" do
71
+ it "creates a new subscription with the given attributes and returns it" do
72
+ attributes = {
73
+ endpoint: "https://example.com/push/f7Q1Eyf7EyfAb1",
74
+ p256dh: "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
75
+ auth: "cdKMlhgVeSPzCXZ3V7FtgQ==",
76
+ uid: "exampleUid",
77
+ tags: ["exampleTag1", "exampleTag2"]
78
+ }
79
+ stub_subscriptions_post(5, attributes)
80
+
81
+ subscription = Subscription.create(attributes, project_id: 5)
82
+ expect(subscription).to have_attributes(attributes)
83
+ end
84
+
85
+ it "fails with CreateError if response status code is not 201" do
86
+ attributes = { endpoint: "https://example.com/push/123" }
87
+ stub_failing_subscriptions_post(5)
88
+
89
+ expect {
90
+ Subscription.create(attributes, project_id: 5)
91
+ }.to raise_error(Subscription::CreateError)
92
+ end
93
+ end
16
94
 
17
95
  describe ".count" do
18
96
  it "returns value from X-Total-Count header" do
@@ -81,5 +159,214 @@ module Pushpad
81
159
  }.to raise_error(Subscription::CountError)
82
160
  end
83
161
  end
162
+
163
+ describe ".find" do
164
+ it "returns subscription with attributes from json response" do
165
+ attributes = {
166
+ id: 5,
167
+ endpoint: "https://example.com/push/f7Q1Eyf7EyfAb1",
168
+ p256dh: "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
169
+ auth: "cdKMlhgVeSPzCXZ3V7FtgQ==",
170
+ uid: "exampleUid",
171
+ tags: ["exampleTag1", "exampleTag2"],
172
+ last_click_at: "2023-11-03T10:30:00.000Z",
173
+ created_at: "2016-09-06T10:47:05.494Z"
174
+ }
175
+ stub_subscription_get(id: 5, project_id: 10, attributes: attributes)
176
+
177
+ subscription = Subscription.find(5, project_id: 10)
178
+
179
+ attributes.delete(:last_click_at)
180
+ attributes.delete(:created_at)
181
+ expect(subscription).to have_attributes(attributes)
182
+ expect(subscription.last_click_at.utc.to_s).to eq(Time.utc(2023, 11, 3, 10, 30, 0.0).to_s)
183
+ expect(subscription.created_at.utc.to_s).to eq(Time.utc(2016, 9, 6, 10, 47, 5.494).to_s)
184
+ end
185
+
186
+ it "fails with FindError if response status code is not 200" do
187
+ stub_failing_subscription_get(id: 5, project_id: 10)
188
+
189
+ expect {
190
+ Subscription.find(5, project_id: 10)
191
+ }.to raise_error(Subscription::FindError)
192
+ end
193
+
194
+ it "fails with helpful error message when project_id is missing" do
195
+ Pushpad.project_id = nil
196
+
197
+ expect {
198
+ Subscription.find 5
199
+ }.to raise_error(/must set project_id/)
200
+ end
201
+ end
202
+
203
+ describe ".find_all" do
204
+ it "returns subscriptions of project with attributes from json response" do
205
+ attributes = {
206
+ id: 1169,
207
+ endpoint: "https://example.com/push/f7Q1Eyf7EyfAb1",
208
+ p256dh: "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
209
+ auth: "cdKMlhgVeSPzCXZ3V7FtgQ==",
210
+ uid: "exampleUid",
211
+ tags: ["exampleTag1", "exampleTag2"],
212
+ last_click_at: "2023-11-03T10:30:00.000Z",
213
+ created_at: "2016-09-06T10:47:05.494Z"
214
+ }
215
+ stub_subscriptions_get(project_id: 10, list: [attributes])
216
+
217
+ subscriptions = Subscription.find_all(project_id: 10)
218
+
219
+ attributes.delete(:last_click_at)
220
+ attributes.delete(:created_at)
221
+ expect(subscriptions[0]).to have_attributes(attributes)
222
+ expect(subscriptions[0].last_click_at.utc.to_s).to eq(Time.utc(2023, 11, 3, 10, 30, 0.0).to_s)
223
+ expect(subscriptions[0].created_at.utc.to_s).to eq(Time.utc(2016, 9, 6, 10, 47, 5.494).to_s)
224
+ end
225
+
226
+ it "falls back to global project id" do
227
+ attributes = { id: 5 }
228
+ stub_subscriptions_get(project_id: 10, list: [attributes])
229
+
230
+ Pushpad.project_id = 10
231
+ subscriptions = Subscription.find_all
232
+
233
+ expect(subscriptions[0]).to have_attributes(attributes)
234
+ end
235
+
236
+ it "fails with helpful error message when project_id is missing" do
237
+ Pushpad.project_id = nil
238
+
239
+ expect {
240
+ Subscription.find_all
241
+ }.to raise_error(/must set project_id/)
242
+ end
243
+
244
+ it "allows passing page parameter for pagination" do
245
+ attributes = { id: 5 }
246
+ stub_subscriptions_get(project_id: 10, list: [attributes], query: { page: "3" })
247
+
248
+ subscriptions = Subscription.find_all(project_id: 10, page: 3)
249
+
250
+ expect(subscriptions[0]).to have_attributes(attributes)
251
+ end
252
+
253
+ it "fails with FindError if response status code is not 200" do
254
+ stub_failing_subscriptions_get(project_id: 10)
255
+
256
+ expect {
257
+ Subscription.find_all(project_id: 10)
258
+ }.to raise_error(Subscription::FindError)
259
+ end
260
+
261
+ it "allows passing uids" do
262
+ attributes = { id: 5 }
263
+ request = stub_subscriptions_get(project_id: 5, list: [attributes], query: { uids: ["uid0", "uid1"] })
264
+
265
+ Subscription.find_all(project_id: 5, uids: ["uid0", "uid1"])
266
+
267
+ expect(request).to have_been_made.once
268
+ end
269
+
270
+ it "allows passing tags" do
271
+ attributes = { id: 5 }
272
+ request = stub_subscriptions_get(project_id: 5, list: [attributes], query: { tags: ["sports", "travel"] })
273
+
274
+ Subscription.find_all(project_id: 5, tags: ["sports", "travel"])
275
+
276
+ expect(request).to have_been_made.once
277
+ end
278
+
279
+ it "allows passing tags as boolean expression" do
280
+ attributes = { id: 5 }
281
+ request = stub_subscriptions_get(project_id: 5, list: [attributes], query: { tags: "sports || travel" })
282
+
283
+ Subscription.find_all(project_id: 5, tags: "sports || travel")
284
+
285
+ expect(request).to have_been_made.once
286
+ end
287
+
288
+ it "allows passing tags and uids" do
289
+ attributes = { id: 5 }
290
+ request = stub_subscriptions_get(project_id: 5, list: [attributes],
291
+ query: { tags: ["sports", "travel"], uids: ["uid0"] })
292
+
293
+ Subscription.find_all(project_id: 5, tags: ["sports", "travel"], uids: ["uid0"])
294
+
295
+ expect(request).to have_been_made.once
296
+ end
297
+
298
+ it "works properly when there are no results" do
299
+ stub_subscriptions_get(project_id: 5, list: [])
300
+
301
+ subscriptions = Subscription.find_all(project_id: 5)
302
+
303
+ expect(subscriptions).to eq([])
304
+ end
305
+ end
306
+
307
+ describe "#update" do
308
+ it "updates a subscription with the given attributes and returns it" do
309
+ attributes = {
310
+ uid: "exampleUid",
311
+ tags: ["exampleTag1", "exampleTag2"]
312
+ }
313
+ stub_subscription_patch(5, 123, attributes)
314
+
315
+ subscription = Subscription.new(id: 123)
316
+ subscription.update attributes, project_id: 5
317
+ expect(subscription).to have_attributes(attributes)
318
+ end
319
+
320
+ it "fails with UpdateError if response status code is not 200" do
321
+ attributes = { uid: "exampleUid" }
322
+ stub_failing_subscription_patch(5, 123)
323
+
324
+ subscription = Subscription.new(id: 123)
325
+
326
+ expect {
327
+ subscription.update attributes, project_id: 5
328
+ }.to raise_error(Subscription::UpdateError)
329
+ end
330
+
331
+ it "fails with helpful error message when project_id is missing" do
332
+ Pushpad.project_id = nil
333
+
334
+ expect {
335
+ Subscription.new(id: 123).update({})
336
+ }.to raise_error(/must set project_id/)
337
+ end
338
+
339
+ it "fails with helpful error message when id is missing" do
340
+ Pushpad.project_id = 5
341
+
342
+ expect {
343
+ Subscription.new(id: nil).update({})
344
+ }.to raise_error(/must set id/)
345
+ end
346
+ end
347
+
348
+ describe "#delete" do
349
+ it "deletes a subscription" do
350
+ Pushpad.project_id = 5
351
+ stub_subscription_delete(5, 123)
352
+
353
+ subscription = Subscription.new(id: 123)
354
+
355
+ res = subscription.delete
356
+ expect(res).to be_nil
357
+ end
358
+
359
+ it "fails with DeleteError if response status code is not 204" do
360
+ Pushpad.project_id = 5
361
+ stub_failing_subscription_delete(5, 123)
362
+
363
+ subscription = Subscription.new(id: 123)
364
+
365
+ expect {
366
+ subscription.delete
367
+ }.to raise_error(Subscription::DeleteError)
368
+ end
369
+ end
370
+
84
371
  end
85
372
  end
metadata CHANGED
@@ -1,14 +1,14 @@
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.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pushpad
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-18 00:00:00.000000000 Z
11
+ date: 2024-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -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.