exponent-server-sdk 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 937bd4d5dcc76c2a2f25ffb7add009d83c70f9b5
4
- data.tar.gz: 2548e5f9f910985944b64556f650e8eea7f40730
3
+ metadata.gz: 88ec6ffe5bd4602818f88d05b6ce235631cd4951
4
+ data.tar.gz: b5cf4200640d97ca8136dbe2788c60b1a28d1531
5
5
  SHA512:
6
- metadata.gz: 27e84460a044e4ffa79ac433ef2e1c77a19bd6048232b837ce4443374332e0a7bb3154e198b7987c910ed6d2e79b35637f7946d4036ef981b041f9ddb8c23317
7
- data.tar.gz: 0b0b4926c5a3a426192cc29f754cb7564106a4f695041ab7f89e45dcb7fa02a316d3e74be8f7aaae5068051b79eb42515ed5b39e0ec0620cceaedb941554dd14
6
+ metadata.gz: 51937e0397c547c37f7a6da6dc0b94897cf578ef47ca4271f5ee2b15c216cea04a9071893cd45e2a3ca2f729feffa60bc1b0c893640fdd72a15d4e8605caa04f
7
+ data.tar.gz: 15b4e65065e9526a407b9f274f7bb9d56427cd2ee7dd842962d1be4f0ff9812f3e65d9f6c4e6bad8b9ef45047543a6ee401ef7a0698deece9cb0de44da90ffec
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *.log
19
+ .ruby-version
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.0
4
+ - 2.3.0
5
+ - 2.2.0
6
+ - 2.1.0
7
+ - 2.0.0
data/README.md CHANGED
@@ -1,17 +1,50 @@
1
1
  # Exponent Server SDK Ruby
2
+ [![Build Status](https://travis-ci.org/expo/exponent-server-sdk-ruby.svg?branch=master)](https://travis-ci.org/expo/exponent-server-sdk-ruby)
2
3
 
3
4
  Use to send push notifications to Exponent Experiences from a Ruby server.
4
5
 
6
+ If you have problems with the code in this repository, please file issues & bug reports at https://github.com/expo/expo. Thanks!
7
+
5
8
  ## Installation
6
9
 
7
10
  Add this line to your application's Gemfile:
8
11
 
9
- gem 'exponent-server-sdk'
12
+ ```ruby
13
+ gem 'exponent-server-sdk'
14
+ ```
10
15
 
11
16
  And then execute:
12
17
 
13
- $ bundle
18
+ ```shell
19
+ $ bundle
20
+ ```
14
21
 
15
22
  Or install it yourself as:
16
23
 
17
- $ gem install exponent-server-sdk
24
+ ```shell
25
+ $ gem install exponent-server-sdk
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### Client
31
+
32
+ The push client is the preferred way. This hits the latest version of the api.
33
+
34
+ ```ruby
35
+ exponent = Exponent::Push::Client.new
36
+
37
+ messages = [{
38
+ to: "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
39
+ sound: "default",
40
+ body: "Hello world!"
41
+ }, {
42
+ to: "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
43
+ badge: 1,
44
+ body: "You've got mail"
45
+ }]
46
+
47
+ exponent.publish messages
48
+ ```
49
+
50
+ The complete format of the messages can be found [here.](https://docs.expo.io/versions/v16.0.0/guides/push-notifications.html#http2-api)
data/Rakefile CHANGED
@@ -1 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*-test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -4,22 +4,23 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'exponent-server-sdk/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "exponent-server-sdk"
7
+ spec.name = 'exponent-server-sdk'
8
8
  spec.version = Exponent::VERSION
9
- spec.authors = ["Jesse Ruder"]
10
- spec.email = ["jesse@sixfivezero.net"]
9
+ spec.authors = ['Jesse Ruder', 'Pablo Gomez']
10
+ spec.email = ['jesse@sixfivezero.net', 'pablonahuelgomez@gmail.com']
11
11
  spec.summary = %q{Exponent Server SDK}
12
12
  spec.description = %q{Exponent Server SDK}
13
- spec.homepage = ""
14
- spec.license = "MIT"
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency "httparty"
21
+ spec.add_dependency 'typhoeus'
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.5"
24
- spec.add_development_dependency "rake"
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'minitest'
25
26
  end
@@ -1,32 +1,111 @@
1
1
  require 'exponent-server-sdk/version'
2
-
3
- require 'httparty'
2
+ require 'typhoeus'
3
+ require 'json'
4
4
 
5
5
  module Exponent
6
+ def self.is_exponent_push_token?(token)
7
+ token.start_with?('ExponentPushToken')
8
+ end
9
+
6
10
  module Push
7
- def self.is_exponent_push_token?(token)
8
- token.start_with?('ExponentPushToken')
9
- end
11
+ Error = Class.new(StandardError)
10
12
 
11
13
  class Client
12
- def publish options
13
- data = options.delete(:data)
14
- response = HTTParty.post('https://exp.host/--/api/notify/' + ERB::Util.url_encode([options].to_json),
15
- :body => data.to_json,
16
- :headers => {
17
- 'Content-Type' => 'application/json'
18
- }
14
+
15
+ def initialize(new_http_client = nil)
16
+ @http_client = new_http_client || Typhoeus
17
+ end
18
+
19
+ def publish(messages)
20
+ handle_response(push_notifications(messages))
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :http_client
26
+
27
+ def handle_response(response)
28
+ case response.code.to_s
29
+ when /(^4|^5)/
30
+ raise Error, build_error_from_failure(parse_json(response))
31
+ else
32
+ handle_success(parse_json(response))
33
+ end
34
+ end
35
+
36
+ def parse_json(response)
37
+ JSON.parse(response.body)
38
+ end
39
+
40
+ def build_error_from_failure(response)
41
+ build_error_with_handling(response) do
42
+ extract_error_from_response(response)
43
+ end
44
+ end
45
+
46
+ def extract_error_from_response(response)
47
+ error = response.fetch('errors').first { unknown_error_format(response) }
48
+ "#{error.fetch('code')} -> #{error.fetch('message')}"
49
+ end
50
+
51
+ def build_error_with_handling(response)
52
+ yield(response)
53
+ rescue KeyError
54
+ unknown_error_format(response)
55
+ end
56
+
57
+ def push_notifications(messages)
58
+ http_client.post(
59
+ push_url,
60
+ body: messages.to_json,
61
+ headers: headers
19
62
  )
63
+ end
20
64
 
21
- case response.code
22
- when 400
23
- raise Exponent::Push::Errors::InvalidPushTokenError
65
+ def push_url
66
+ 'https://exp.host/--/api/v2/push/send'
67
+ end
68
+
69
+ def headers
70
+ {
71
+ 'Content-Type' => 'application/json',
72
+ 'Accept' => 'application/json',
73
+ 'Accept-Encoding' => 'gzip, deflate'
74
+ }
75
+ end
76
+
77
+ def handle_success(response)
78
+ data = extract_data(response)
79
+ if data.fetch('status') == 'ok'
80
+ data
81
+ else
82
+ raise Error, build_error_from_success(response)
24
83
  end
25
84
  end
26
- end
27
85
 
28
- module Errors
29
- class InvalidPushTokenError < StandardError
86
+ def build_error_from_success(response)
87
+ build_error_with_handling(response) do
88
+ extract_error_from_success(response)
89
+ end
90
+ end
91
+
92
+ def extract_error_from_success(response)
93
+ data = extract_data(response)
94
+ message = data.fetch('message')
95
+
96
+ if data['details']
97
+ "#{data.fetch('details').fetch('error')} -> #{message}"
98
+ else
99
+ "#{data.fetch('status')} -> #{message}"
100
+ end
101
+ end
102
+
103
+ def extract_data(response)
104
+ response.fetch('data').first
105
+ end
106
+
107
+ def unknown_error_format(response)
108
+ "Unknown error format: #{response}"
30
109
  end
31
110
  end
32
111
  end
@@ -1,3 +1,3 @@
1
1
  module Exponent
2
- VERSION = "0.0.2"
2
+ VERSION = '0.0.3'
3
3
  end
@@ -0,0 +1,130 @@
1
+ require 'minitest/autorun'
2
+ require 'exponent-server-sdk'
3
+
4
+ class ExponentServerSdkTest < Minitest::Test
5
+ def setup
6
+ @mock = MiniTest::Mock.new
7
+ @response_mock = MiniTest::Mock.new
8
+ @exponent = Exponent::Push::Client.new(@mock)
9
+ end
10
+
11
+ def test_publish_with_success
12
+ @response_mock.expect(:code, 200)
13
+ @response_mock.expect(:body, success_body.to_json)
14
+
15
+ @mock.expect(:post, @response_mock, client_args)
16
+
17
+ @exponent.publish(messages)
18
+
19
+ @mock.verify
20
+ end
21
+
22
+ def test_publish_with_error
23
+ @response_mock.expect(:code, 400)
24
+ @response_mock.expect(:body, error_body.to_json)
25
+ message = 'INTERNAL_SERVER_ERROR -> An unknown error occurred.'
26
+
27
+ @mock.expect(:post, @response_mock, client_args)
28
+
29
+ exception = assert_raises Exponent::Push::Error do
30
+ @exponent.publish(messages)
31
+ end
32
+
33
+ assert_equal(message, exception.message)
34
+
35
+ @mock.verify
36
+ end
37
+
38
+ def test_publish_with_success_and_errors
39
+ @response_mock.expect(:code, 200)
40
+ @response_mock.expect(:body, success_with_error_body.to_json)
41
+ message = 'DeviceNotRegistered -> "ExponentPushToken[42]" is not a registered push notification recipient'
42
+
43
+ @mock.expect(:post, @response_mock, client_args)
44
+
45
+ exception = assert_raises Exponent::Push::Error do
46
+ @exponent.publish(messages)
47
+ end
48
+
49
+ assert_equal(message, exception.message)
50
+
51
+ @mock.verify
52
+ end
53
+
54
+ def test_publish_with_success_and_apn_error
55
+ @response_mock.expect(:code, 200)
56
+ @response_mock.expect(:body, success_with_apn_error_body.to_json)
57
+ message = 'error -> Could not find APNs credentials for you (your_app). Check whether you are trying to send a notification to a detached app.'
58
+
59
+ @mock.expect(:post, @response_mock, client_args)
60
+
61
+ exception = assert_raises Exponent::Push::Error do
62
+ @exponent.publish(messages)
63
+ end
64
+
65
+ assert_equal(message, exception.message)
66
+
67
+ @mock.verify
68
+ end
69
+
70
+ private
71
+
72
+ def success_body
73
+ { 'data' => [{ 'status' => 'ok' }] }
74
+ end
75
+
76
+ def error_body
77
+ {
78
+ 'errors' => [{
79
+ 'code' => 'INTERNAL_SERVER_ERROR',
80
+ 'message' => 'An unknown error occurred.'
81
+ }]
82
+ }
83
+ end
84
+
85
+ def success_with_error_body
86
+ {
87
+ 'data' => [{
88
+ 'status' => 'error',
89
+ 'message' => '"ExponentPushToken[42]" is not a registered push notification recipient',
90
+ 'details' => { 'error' => 'DeviceNotRegistered' }
91
+ }]
92
+ }
93
+ end
94
+
95
+ def success_with_apn_error_body
96
+ {
97
+ 'data' => [{
98
+ 'status' => 'error',
99
+ 'message' =>
100
+ 'Could not find APNs credentials for you (your_app). Check whether you are trying to send a notification to a detached app.'
101
+ }]
102
+ }
103
+ end
104
+
105
+ def client_args
106
+ [
107
+ 'https://exp.host/--/api/v2/push/send',
108
+ {
109
+ body: messages.to_json,
110
+ headers: {
111
+ 'Content-Type' => 'application/json',
112
+ 'Accept' => 'application/json',
113
+ 'Accept-Encoding' => 'gzip, deflate'
114
+ }
115
+ }
116
+ ]
117
+ end
118
+
119
+ def messages
120
+ [{
121
+ to: 'ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]',
122
+ sound: 'default',
123
+ body: 'Hello world!'
124
+ }, {
125
+ to: 'ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]',
126
+ badge: 1,
127
+ body: "You've got mail"
128
+ }]
129
+ end
130
+ end
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exponent-server-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesse Ruder
8
+ - Pablo Gomez
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2016-06-20 00:00:00.000000000 Z
12
+ date: 2018-02-13 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: httparty
15
+ name: typhoeus
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
18
  - - ">="
@@ -28,16 +29,16 @@ dependencies:
28
29
  name: bundler
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - "~>"
32
+ - - ">="
32
33
  - !ruby/object:Gem::Version
33
- version: '1.5'
34
+ version: '0'
34
35
  type: :development
35
36
  prerelease: false
36
37
  version_requirements: !ruby/object:Gem::Requirement
37
38
  requirements:
38
- - - "~>"
39
+ - - ">="
39
40
  - !ruby/object:Gem::Version
40
- version: '1.5'
41
+ version: '0'
41
42
  - !ruby/object:Gem::Dependency
42
43
  name: rake
43
44
  requirement: !ruby/object:Gem::Requirement
@@ -52,14 +53,30 @@ dependencies:
52
53
  - - ">="
53
54
  - !ruby/object:Gem::Version
54
55
  version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: minitest
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
55
70
  description: Exponent Server SDK
56
71
  email:
57
72
  - jesse@sixfivezero.net
73
+ - pablonahuelgomez@gmail.com
58
74
  executables: []
59
75
  extensions: []
60
76
  extra_rdoc_files: []
61
77
  files:
62
78
  - ".gitignore"
79
+ - ".travis.yml"
63
80
  - Gemfile
64
81
  - LICENSE.txt
65
82
  - README.md
@@ -68,6 +85,7 @@ files:
68
85
  - lib/exponent-server-sdk.rb
69
86
  - lib/exponent-server-sdk/version.rb
70
87
  - manual-testing.txt
88
+ - test/exponent-server-sdk-test.rb
71
89
  homepage: ''
72
90
  licenses:
73
91
  - MIT
@@ -88,8 +106,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
106
  version: '0'
89
107
  requirements: []
90
108
  rubyforge_project:
91
- rubygems_version: 2.4.6
109
+ rubygems_version: 2.6.11
92
110
  signing_key:
93
111
  specification_version: 4
94
112
  summary: Exponent Server SDK
95
- test_files: []
113
+ test_files:
114
+ - test/exponent-server-sdk-test.rb