Skip to content

Commit

Permalink
DEVX-7520: Adding Users (#282)
Browse files Browse the repository at this point in the history
* Adding Users tests

* Implementing Users class

* Implementing Users#list method

* Implementing Users#find method

* Implementing Users#create method

* Implementing Users#update method

* Implementing Users#delete method

* Fixing JWT issues

* Adding User code comments
  • Loading branch information
superchilled authored Aug 9, 2023
1 parent c9097d2 commit f9dfa72
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 4 deletions.
7 changes: 7 additions & 0 deletions lib/vonage/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ def tfa
@tfa ||= T.let(TFA.new(config), T.nilable(Vonage::TFA))
end

# @return [Users]
#
sig { returns(T.nilable(Vonage::Users)) }
def users
@users ||= T.let(Users.new(config), T.nilable(Vonage::Users))
end

# @return [Verify]
#
sig { returns(T.nilable(Vonage::Verify)) }
Expand Down
156 changes: 156 additions & 0 deletions lib/vonage/users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# typed: strict
# frozen_string_literal: true

module Vonage
class Users < Namespace
extend T::Sig
self.authentication = BearerToken

self.request_body = JSON

# Get a list of Users associated with the Vonage Application.
#
# @param [optional, Integer] :page_size
# Specifies the number of records to be returned in the response.
#
# @param [optional, String] :order
# Specifies the order in which the records should be returned.
# Must be one of `asc`, `ASC`, `desc`, or `DESC`
#
# @param [optional, String] :cursor
# Specficy a cursor point from which to start returning results, for example the values of the `next` or `prev`
# `_links` contained in a response.
#
# @param [optional, String] :name
# Specify a user name with which to filter results
#
# @return [ListResponse]
#
# @see https://developer.vonage.com/en/api/application.v2#getUsers
#
def list(**params)
request('/v1/users', params: params, response_class: ListResponse)
end

# Get a specified User associated with the Vonage Application.
#
# @param [required, String] :id
# The unique ID or name for the user.
#
# @return [Vonage::Response]
#
# @see https://developer.vonage.com/en/api/application.v2#getUser
#
def find(id:)
request("/v1/users/#{id}")
end

# Create a new User associated with the Vonage Application.
#
# @param [optional, String] :name
# A unique name for the user. If not provided, a name will be auto-generated.
#
# @param [optional, String] :display_name
# A string to be displayed as user name. It does not need to be unique.
#
# @param [optional, String] :image_url
# A publicly accessible URL to an image file for an image to be associated with the user.
#
# @param [optional, Hash] :properties A hash defining properties for the User.
# @option properties [Hash] :custom_data A hash of custom data as key/value pairs.
#
# @param [optional, Hash] :channels A hash defining details of various channels.
# @option channels [Array] :pstn An array containing a Hash which defines data for the pstn channel.
# @option pstn [Integer] :number The pstn number.
# @option channels [Array] :sip An array containing a Hash which defines data for the sip channel.
# @option sip [String] :uri The sip uri.
# @option sip [String] :username The sip username.
# @option sip [String] :password The sip password.
# @option channels [Array] :vbc An array containing a Hash which defines data for the vbc channel.
# @option vbc [String] :extension The vbc extension.
# @option channels [Array] :websocket An array containing a Hash which defines data for the websocket channel.
# @option websocket [String] :uri The websocket uri.
# @option websocket [String] :content-type The websocket audio type. Must be one of: `audio/l16;rate=8000`, `audio/l16;rate=16000`.
# @option websocket [Hash] :headers A hash of custom websocket headers provided as key/value pairs.
# @option channels [Array] :sms An array containing a Hash which defines data for the sms channel.
# @option sms [Integer] :number The sms number.
# @option channels [Array] :mms An array containing a Hash which defines data for the mms channel.
# @option mms [Integer] :number The mms number.
# @option channels [Array] :whatsapp An array containing a Hash which defines data for the whatsapp channel.
# @option whatsapp [Integer] :number The whatsapp number.
# @option channels [Array] :viber An array containing a Hash which defines data for the sms channel.
# @option viber [Integer] :number The viber number.
# @option channels [Array] :messenger An array containing a Hash which defines data for the messenger channel.
# @option messenger [Integer] :id The messenger id.
#
# @return [Vonage::Response]
#
# @see https://developer.vonage.com/en/api/application.v2#createUser
#
def create(**params)
request('/v1/users', params: params, type: Post)
end

# Update an existing User associated with the Vonage Application.
#
# @param [required, String] :id
# The unique ID or name for the user to be updated.
#
# @param [optional, String] :name
# A unique name for the user.
#
# @param [optional, String] :display_name
# A string to be displayed as user name. It does not need to be unique.
#
# @param [optional, String] :image_url
# A publicly accessible URL to an image file for an image to be associated with the user.
#
# @param [optional, Hash] :properties A hash defining properties for the User.
# @option properties [Hash] :custom_data A hash of custom data as key/value pairs.
#
# @param [optional, Hash] :channels A hash defining details of various channels.
# @option channels [Array] :pstn An array containing a Hash which defines data for the pstn channel.
# @option pstn [Integer] :number The pstn number.
# @option channels [Array] :sip An array containing a Hash which defines data for the sip channel.
# @option sip [String] :uri The sip uri.
# @option sip [String] :username The sip username.
# @option sip [String] :password The sip password.
# @option channels [Array] :vbc An array containing a Hash which defines data for the vbc channel.
# @option vbc [String] :extension The vbc extension.
# @option channels [Array] :websocket An array containing a Hash which defines data for the websocket channel.
# @option websocket [String] :uri The websocket uri.
# @option websocket [String] :content-type The websocket audio type. Must be one of: `audio/l16;rate=8000`, `audio/l16;rate=16000`.
# @option websocket [Hash] :headers A hash of custom websocket headers provided as key/value pairs.
# @option channels [Array] :sms An array containing a Hash which defines data for the sms channel.
# @option sms [Integer] :number The sms number.
# @option channels [Array] :mms An array containing a Hash which defines data for the mms channel.
# @option mms [Integer] :number The mms number.
# @option channels [Array] :whatsapp An array containing a Hash which defines data for the whatsapp channel.
# @option whatsapp [Integer] :number The whatsapp number.
# @option channels [Array] :viber An array containing a Hash which defines data for the sms channel.
# @option viber [Integer] :number The viber number.
# @option channels [Array] :messenger An array containing a Hash which defines data for the messenger channel.
# @option messenger [Integer] :id The messenger id.
#
# @return [Vonage::Response]
#
# @see https://developer.vonage.com/en/api/application.v2#createUser
#
def update(id:, **params)
request("/v1/users/#{id}", params: params, type: Patch)
end

# Delete a specified User associated with the Vonage Application.
#
# @param [required, String] :id
# The unique ID or name for the user.
#
# @return [Vonage::Response]
#
# @see https://developer.vonage.com/en/api/application.v2#deleteUser
#
def delete(id:)
request("/v1/users/#{id}", type: Delete)
end
end
end
11 changes: 11 additions & 0 deletions lib/vonage/users/list_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# typed: true

class Vonage::Users::ListResponse < Vonage::Response
include Enumerable

def each
return enum_for(:each) unless block_given?

@entity._embedded.users.each { |item| yield item }
end
end
2 changes: 1 addition & 1 deletion lib/vonage/verify2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Verify2 < Namespace
# @option opts [String] :client_ref Reference to be included in callbacks
# @option opts [Boolean] If used, must be set to `false`. Will bypass a network block for a single Verify V2 request
#
# @return Vomage::Response
# @return Vonage::Response
# @see https://developer.vonage.com/en/api/verify.v2#newRequest
#
def start_verification(brand:, workflow:, **opts)
Expand Down
4 changes: 4 additions & 0 deletions test/vonage/client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ def test_tfa_method
assert_kind_of Vonage::TFA, client.tfa
end

def test_users_method
assert_kind_of Vonage::Users, client.users
end

def test_verify_method
assert_kind_of Vonage::Verify, client.verify
end
Expand Down
2 changes: 1 addition & 1 deletion test/vonage/jwt_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def uuid_pattern
end

def sample_token
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1OTUyNTM2MTMsImp0aSI6ImU1QmxGeDVOek5ydCIsImV4cCI6MTU5NTI1NDUxMywic3ViIjoiU3ViamVjdCIsImFwcGxpY2F0aW9uX2lkIjoieHh4eHh4eHgteHh4eC14eHh4LXh4eHgteHh4eHh4eHh4eHh4In0.Jv1flw0dzDEskyEHaK1appNUEHF2zBRJw0VWjQ8ri-MzsWguPu8ofoGVfWDTemF2xj87ukgfg8a3kTOjA0rZfCMUG4vJiGrWPJvCab7ECvy0_-vJgsDSzrG7I5MsBpbJnc1iyxv1kRu_U-EcbOceaM77yqisRLFSmwkEYuLFAOMuFeBOHZTbHYLhWYvzCOZXIU0IxDNQfGw-wXxXSMcv8aAPvhJe7bYZeRUpX8Pw0y2Qz0PxE7tB2ven_6-F_5FuOl2ARGU90GpzLho77aV5KQAKsaShwA4oqH5ETJF5JUDc9MYky-7Hbu2BmC3AqnpxGNnu7g4M6nnM-g63_5WFFg'
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1OTUyNTM2MTMsImp0aSI6ImU1QmxGeDVOek5ydCIsImV4cCI6MTU5NTI1NDUxMywiYXBwbGljYXRpb25faWQiOiJ4eHh4eHh4eC14eHh4LXh4eHgteHh4eC14eHh4eHh4eHh4eHgifQ.DurSM2It4XstunZd_PykqDW1EceX5pCCB3s1ER2_ljMkLZbNuMcMv3GvCnTdtNKhizMEjrH8PXyVSjENdKMjUscyyMISNzLKQMYM1vsHOIIeFQY0M90D2wEaAvHf7fUtPPbBPsOUsl3zMDCrpikDSvEnMXOlxNTkc7_xxCWjv1dQI5Fu7_6VE8xEXgLi0jCv3rEaA61CYlzGwVRFkAH9kkettJa3tl7ZyHNqgR4TM-9DmuPomNQ8ARgff3ab0NalVZougF4cgxQvvMqIOWhXfxkmU-OCAs86wVGDkapJ8TJt_NuUKcVAMfhnf9eLR3USVMnsz2oTRWcezKrJM63mQQ"
end

def decode(token)
Expand Down
6 changes: 5 additions & 1 deletion test/vonage/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def meetings_host
def vonage_host
"api-eu.vonage.com"
end

def request(body: nil, query: nil, headers: {}, auth: nil)
headers['Authorization'] = auth || authorization
headers['Content-Type'] = 'application/json' if body
Expand All @@ -115,6 +115,10 @@ def secrets_response
{ body: '{"_embedded": {"secrets":[]}}', headers: response_headers }
end

def users_response
{ body: '{"_embedded": {"users":[]}}', headers: response_headers }
end

def numbers_response
{ body: '{"numbers":[]}', headers: response_headers }
end
Expand Down
92 changes: 92 additions & 0 deletions test/vonage/users_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# typed: false
require_relative './test'

class Vonage::UsersTest < Vonage::Test
def users
Vonage::Users.new(config)
end

def users_uri
'https://api.nexmo.com/v1/users'
end

def user_uri
'https://api.nexmo.com/v1/users/' + user_id
end

def test_list_method
stub_request(:get, users_uri).with(request).to_return(users_response)

response = users.list

assert_kind_of Vonage::Users::ListResponse, response
response.each{|resp| assert_kind_of Vonage::Response, resp }
end

def test_list_method_with_optional_params
stub_request(:get, users_uri + '?order=asc').with(request).to_return(users_response)

response = users.list(order: 'asc')

assert_kind_of Vonage::Users::ListResponse, response
response.each{|resp| assert_kind_of Vonage::Response, resp }
end

def test_find_method
stub_request(:get, user_uri).with(request).to_return(response)

assert_kind_of Vonage::Response, users.find(id: user_id)
end

def test_find_method_without_id
assert_raises ArgumentError do
users.find
end
end

def test_create_method
stub_request(:post, users_uri).with(request).to_return(response)

assert_kind_of Vonage::Response, users.create
end

def test_create_method_with_optional_params
params = {name: 'USR-1234'}

stub_request(:post, users_uri).with(request(body: params)).to_return(response)

assert_kind_of Vonage::Response, users.create(**params)
end

def test_update_method
stub_request(:patch, user_uri).to_return(response)

assert_kind_of Vonage::Response, users.update(id: user_id)
end

def test_update_method_with_optional_params
params = {display_name: 'Foo'}

stub_request(:patch, user_uri).with(request(body: params)).to_return(response)

assert_kind_of Vonage::Response, users.update(id: user_id, **params)
end

def test_update_method_without_id
assert_raises ArgumentError do
users.update
end
end

def test_delete_method
stub_request(:delete, user_uri).with(request).to_return(status: 204)

assert_kind_of Vonage::Response, users.delete(id: user_id)
end

def test_delete_method_without_id
assert_raises ArgumentError do
users.delete
end
end
end
2 changes: 1 addition & 1 deletion vonage.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Gem::Specification.new do |s|
s.summary = 'This is the Ruby Server SDK for Vonage APIs. To use it you\'ll need a Vonage account. Sign up for free at https://www.vonage.com'
s.files = Dir.glob('lib/**/*.rb') + %w(LICENSE.txt README.md vonage.gemspec)
s.required_ruby_version = '>= 2.5.0'
s.add_dependency('vonage-jwt', '~> 0.1.0')
s.add_dependency('vonage-jwt', '~> 0.1.3')
s.add_dependency('zeitwerk', '~> 2', '>= 2.2')
s.add_dependency('sorbet-runtime', '~> 0.5')
s.add_dependency('multipart-post', '~> 2.0')
Expand Down

0 comments on commit f9dfa72

Please sign in to comment.