-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#1592, Customer API controller to open phone.systems UI according to …
…provisioned service (#1600)
- Loading branch information
1 parent
f9a75d1
commit 2b8a943
Showing
9 changed files
with
312 additions
and
0 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
app/controllers/api/rest/customer/v1/phone_systems_sessions_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# frozen_string_literal: true | ||
|
||
module Api | ||
module Rest | ||
module Customer | ||
module V1 | ||
PhoneSystemsSessionsController = Class.new(Api::Rest::Customer::V1::BaseController) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# frozen_string_literal: true | ||
|
||
class PhoneSystemsSessionForm < ApplicationForm | ||
attr_reader :uuid | ||
attr_accessor :customer | ||
attr_accessor :api_access | ||
|
||
attribute :service | ||
attribute :phone_systems_url | ||
|
||
def persisted? | ||
false | ||
end | ||
|
||
validate do | ||
errors.add(:base, 'service not found') if service_relation.nil? || customer_id_from_current_service != customer_id_from_session | ||
|
||
if service_relation && api_access.account_ids.any? && api_access.account_ids.exclude?(service_relation.account_id) | ||
errors.add(:service, 'Account of current Service is not related to current API Access') | ||
end | ||
end | ||
|
||
private | ||
|
||
def _save | ||
self.phone_systems_url = Billing::Provisioning::PhoneSystems::SessionCreationService.call!(service_relation) | ||
|
||
@uuid = SecureRandom.uuid | ||
rescue Billing::Provisioning::Errors::Error => e | ||
errors.add(:base, 'failed to create Phone Systems session') | ||
end | ||
|
||
def service_relation | ||
Billing::Service.find_by(uuid: service) | ||
end | ||
|
||
def customer_id_from_current_service | ||
return if service_relation.nil? | ||
|
||
service_relation.account.contractor_id | ||
end | ||
|
||
def customer_id_from_session | ||
customer.id | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
app/models/billing/provisioning/phone_systems/session_creation_service.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# frozen_string_literal: true | ||
|
||
module Billing | ||
module Provisioning | ||
class PhoneSystems | ||
class SessionCreationService | ||
def initialize(service) | ||
@service = service | ||
@service_variables = service.type.variables.merge(service.variables) | ||
@api_client = PhoneSystemsApiClient.new(@service_variables) | ||
end | ||
|
||
def self.call!(service) | ||
new(service).call! | ||
end | ||
|
||
def call! | ||
url = '' | ||
payload = { | ||
data: { | ||
type: 'sessions', | ||
relationships: { | ||
customer: { | ||
data: { | ||
type: 'customers', | ||
id: @service.id | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
response = @api_client.create_session(payload) | ||
@api_client.process_response(response, 'created the "Customer sessions" on the phone.systems server') do |response_body| | ||
url = response_body.dig('data', 'attributes', 'uri') | ||
end | ||
|
||
url | ||
end | ||
end | ||
end | ||
end | ||
end |
30 changes: 30 additions & 0 deletions
30
app/resources/api/rest/customer/v1/phone_systems_session_resource.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# frozen_string_literal: true | ||
|
||
module Api | ||
module Rest | ||
module Customer | ||
module V1 | ||
class PhoneSystemsSessionResource < Api::Rest::Customer::V1::BaseResource | ||
exclude_links [:self] | ||
model_name 'PhoneSystemsSessionForm' | ||
|
||
attribute :service | ||
attribute :phone_systems_url | ||
|
||
before_replace_fields do | ||
_model.customer = context[:current_customer].customer | ||
_model.api_access = context[:current_customer] | ||
end | ||
|
||
def self.creatable_fields(_context) | ||
[:service] | ||
end | ||
|
||
def fetchable_fields | ||
[:phone_systems_url] | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
spec/acceptance/rest/customer/api/v1/phone_systems_sessions_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rspec_api_documentation/dsl' | ||
|
||
RSpec.resource 'Phone Systems session', document: :customer_v1 do | ||
header 'Accept', 'application/vnd.api+json' | ||
header 'Content-Type', 'application/vnd.api+json' | ||
header 'Authorization', :auth_token | ||
|
||
let(:api_access) { create :api_access } | ||
let(:customer) { api_access.customer } | ||
let!(:account) { create(:account, contractor: customer) } | ||
include_context :customer_v1_cookie_helpers | ||
include_context :stub_request_to_create_phone_systems_session | ||
let(:service_id) { service_relation.id } | ||
let(:auth_token) { build_customer_token(api_access.id, expiration: 1.minute.from_now) } | ||
let(:type) { 'phone-systems-sessions' } | ||
|
||
post '/api/rest/customer/v1/phone-systems-sessions' do | ||
parameter :type, scope: :data, required: true | ||
jsonapi_attribute :service | ||
|
||
let(:service) { service_relation.uuid } | ||
let(:service_type_attrs) do | ||
{ | ||
variables: { | ||
endpoint: phone_systems_base_url, | ||
username: 'test', | ||
password: 'test', | ||
# Attributes for Customer on the phone.systems side | ||
attributes: { | ||
name: 'John Johnson', | ||
language: 'EN', | ||
trm_mode: 'operator', | ||
capacity_limit: 10, | ||
sip_account_limit: 5 | ||
} | ||
} | ||
} | ||
end | ||
let(:service_type) { FactoryBot.create(:service_type, service_type_attrs) } | ||
let(:service_relation_attrs) { { type: service_type, account:, variables: { attributes: { name: 'John Doe' } } } } | ||
let(:service_relation) { FactoryBot.create(:service, service_relation_attrs) } | ||
|
||
before { stub_request_to_create_phone_systems_session } | ||
|
||
example_request 'create new phone.systems session' do | ||
expect(status).to eq(201) | ||
expect(stub_request_to_create_phone_systems_session).to have_been_requested | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe PhoneSystemsSessionForm do | ||
subject { form.save } | ||
|
||
include_context :stub_request_to_create_phone_systems_session | ||
|
||
let(:customer) { create(:customer) } | ||
let(:account) { create(:account, contractor: customer) } | ||
let(:service_type_attrs) { { variables: { endpoint: phone_systems_base_url } } } | ||
let(:service_type) { FactoryBot.create(:service_type, service_type_attrs) } | ||
let(:service_attrs) { { type: service_type, account: } } | ||
let(:service) { FactoryBot.create(:service, service_attrs) } | ||
let(:api_access_attrs) { { account_ids: [account.id], customer: } } | ||
let(:api_access) { create :api_access, api_access_attrs } | ||
let(:form_attributes) { { service: service.uuid } } | ||
let(:form) do | ||
f = described_class.new(form_attributes) | ||
f.customer = service.account.contractor | ||
f.api_access = api_access | ||
f | ||
end | ||
|
||
context 'when valid data' do | ||
before { stub_request_to_create_phone_systems_session } | ||
|
||
it 'should create session on the phone.systems side and URL should be received' do | ||
subject | ||
|
||
expect(form.errors.messages).to eq({}) | ||
expect(form.phone_systems_url).to eq phone_systems_redirect_url | ||
expect(stub_request_to_create_phone_systems_session).to have_been_requested | ||
end | ||
end | ||
|
||
context 'when service not found' do | ||
let(:form_attributes) { { service: SecureRandom.uuid } } | ||
|
||
it 'should return validation error message' do | ||
subject | ||
|
||
expect(form.errors.messages).to eq base: ['service not found'] | ||
end | ||
end | ||
|
||
context 'when service from another Customer' do | ||
let!(:another_customer) { create(:customer) } | ||
let!(:another_account) { create(:account, contractor: another_customer) } | ||
let(:api_access_attrs) { { account_ids: [another_account.id], customer: another_customer } } | ||
let(:form_attributes) { { service: service.uuid } } | ||
|
||
let(:form) do | ||
f = described_class.new(form_attributes) | ||
f.customer = another_customer | ||
f.api_access = api_access | ||
f | ||
end | ||
|
||
it 'should return validation error message' do | ||
subject | ||
|
||
expect(form.errors.messages).to match_array( | ||
base: ['service not found'], | ||
service: ['Account of current Service is not related to current API Access'] | ||
) | ||
end | ||
end | ||
|
||
context 'when current API Access with account_ids = []' do | ||
let(:api_access_attrs) { super().merge account_ids: [] } | ||
|
||
before { stub_request_to_create_phone_systems_session } | ||
|
||
it 'should create session on the phone.systems side and URL should be received' do | ||
subject | ||
|
||
expect(form.errors.messages).to eq({}) | ||
expect(form.phone_systems_url).to eq phone_systems_redirect_url | ||
expect(stub_request_to_create_phone_systems_session).to have_been_requested | ||
end | ||
end | ||
|
||
context 'when Account of Service is NOT included in list of allowed account IDs ' do | ||
let(:second_account) { create(:account, contractor: customer, name: 'Second Account') } | ||
let(:api_access_attrs) { super().merge account_ids: [account.id] } | ||
let(:service_attrs) { super().merge account: second_account } | ||
|
||
it 'should return validation error' do | ||
subject | ||
|
||
expect(form.errors.messages).to eq service: ['Account of current Service is not related to current API Access'] | ||
end | ||
end | ||
end |
29 changes: 29 additions & 0 deletions
29
spec/support/contexts/stub_request_to_create_phone_systems_session.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.shared_context :stub_request_to_create_phone_systems_session do | ||
let(:phone_systems_base_url) { 'https://api.telecom.center' } | ||
let(:phone_systems_query_params) { { token: 'asdf.asdf.asdf', redirect_to: :phone_systems, from: :rspec } } | ||
let(:phone_systems_redirect_url) { "https://sandbox.phone.systems/auth#{phone_systems_query_params.to_query}" } | ||
# the Customer ID from Phone Systems and The service ID from Yeti WEB should be the same | ||
let(:service_id) { service.id } | ||
let(:response_from_phone_systems) do | ||
{ | ||
data: { | ||
id: 99, | ||
type: :sessions, | ||
attributes: { | ||
uri: phone_systems_redirect_url | ||
} | ||
} | ||
} | ||
end | ||
let(:stub_request_to_create_phone_systems_session) do | ||
stub_request(:post, "#{phone_systems_base_url}/api/rest/public/operator/sessions") | ||
.with( | ||
body: { data: { type: 'sessions', relationships: { customer: { data: { type: :customers, id: service_id } } } } }.to_json | ||
) | ||
.to_return( | ||
status: 200, body: response_from_phone_systems.to_json, headers: {} | ||
) | ||
end | ||
end |