diff --git a/.ruby-version b/.ruby-version index 73462a5..5ae69bd 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.1 +3.2.5 diff --git a/Gemfile.lock b/Gemfile.lock index 57ea43a..f1a7ee5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,21 +2,28 @@ PATH remote: . specs: jurnal_api (0.1.0) - dotenv (= 2.7.5) - faraday (= 0.15.4) - faraday_middleware (= 0.13.1) + dotenv (= 3.1.4) + faraday (= 2.12.0) + faraday-multipart (= 1.0.4) GEM remote: https://rubygems.org/ specs: - activesupport (6.1.3.1) - concurrent-ruby (~> 1.0, >= 1.0.2) + activesupport (7.2.1.1) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - tzinfo (~> 2.0) - zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.2.0) + bigdecimal (3.1.8) byebug (11.1.3) capybara (2.5.0) mime-types (>= 1.16) @@ -25,66 +32,92 @@ GEM rack-test (>= 0.5.4) xpath (~> 2.0) coderay (1.1.3) - concurrent-ruby (1.1.8) - crack (0.4.5) + concurrent-ruby (1.3.4) + connection_pool (2.4.1) + crack (1.0.0) + bigdecimal rexml - diff-lcs (1.4.4) - dotenv (2.7.5) - faraday (0.15.4) - multipart-post (>= 1.2, < 3) - faraday_middleware (0.13.1) - faraday (>= 0.7.4, < 1.0) - hashdiff (1.0.1) - i18n (1.8.10) + diff-lcs (1.5.1) + dotenv (3.1.4) + drb (2.2.1) + faraday (2.12.0) + faraday-net_http (>= 2.0, < 3.4) + json + logger + faraday-multipart (1.0.4) + multipart-post (~> 2) + faraday-net_http (3.3.0) + net-http + hashdiff (1.1.1) + i18n (1.14.6) concurrent-ruby (~> 1.0) - method_source (1.0.0) - mime-types (3.3.1) + json (2.7.2) + logger (1.6.1) + method_source (1.1.0) + mime-types (3.6.0) + logger mime-types-data (~> 3.2015) - mime-types-data (3.2021.0225) - mini_portile2 (2.6.1) - minitest (5.14.4) - multipart-post (2.1.1) - nokogiri (1.12.5) - mini_portile2 (~> 2.6.1) + mime-types-data (3.2024.1001) + minitest (5.25.1) + multipart-post (2.4.1) + net-http (0.4.1) + uri + nokogiri (1.16.7-aarch64-linux) racc (~> 1.4) - pry (0.14.1) + nokogiri (1.16.7-arm-linux) + racc (~> 1.4) + nokogiri (1.16.7-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.7-x86-linux) + racc (~> 1.4) + nokogiri (1.16.7-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.16.7-x86_64-linux) + racc (~> 1.4) + pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (4.0.6) - racc (1.5.2) + public_suffix (6.0.1) + racc (1.8.1) rack (2.2.3) - rack-test (1.1.0) - rack (>= 1.0, < 3) - rake (13.0.3) - rexml (3.2.5) - rspec (3.10.0) - rspec-core (~> 3.10.0) - rspec-expectations (~> 3.10.0) - rspec-mocks (~> 3.10.0) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rack-test (2.1.0) + rack (>= 1.3) + rake (13.2.1) + rexml (3.3.8) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.1) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.2) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-support (3.10.2) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + securerandom (0.3.1) shoulda-context (1.2.2) shoulda-matchers (3.1.1) activesupport (>= 4.0.0) - tzinfo (2.0.4) + tzinfo (2.0.6) concurrent-ruby (~> 1.0) + uri (0.13.1) webmock (3.8.3) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) xpath (2.1.0) nokogiri (~> 1.3) - zeitwerk (2.4.2) PLATFORMS - ruby + aarch64-linux + arm-linux + arm64-darwin + x86-linux + x86_64-darwin + x86_64-linux DEPENDENCIES bundler (~> 2.0) @@ -100,4 +133,4 @@ DEPENDENCIES webmock (= 3.8.3) BUNDLED WITH - 2.0.2 + 2.5.22 diff --git a/jurnal-api.gemspec b/jurnal-api.gemspec index 6683550..bb8a471 100644 --- a/jurnal-api.gemspec +++ b/jurnal-api.gemspec @@ -38,7 +38,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "webmock", "3.8.3" # dependency - spec.add_dependency "faraday", "0.15.4" - spec.add_dependency "faraday_middleware", "0.13.1" - spec.add_dependency "dotenv", "2.7.5" + spec.add_dependency "faraday", "2.12.0" + spec.add_dependency "faraday-multipart", "1.0.4" + spec.add_dependency "dotenv", "3.1.4" end diff --git a/lib/jurnal_api/client.rb b/lib/jurnal_api/client.rb index 0cd4dc2..fe3d10f 100644 --- a/lib/jurnal_api/client.rb +++ b/lib/jurnal_api/client.rb @@ -14,7 +14,9 @@ class Client < API include JurnalApi::Client::SalesOrders include JurnalApi::Client::SalesQuotes include JurnalApi::Client::SalesInvoices + include JurnalApi::Client::TransactionPdfs include JurnalApi::Client::Contacts include JurnalApi::Client::HealthChecks + include JurnalApi::Client::GenerateShortenLink end end diff --git a/lib/jurnal_api/client/generate_shorten_link.rb b/lib/jurnal_api/client/generate_shorten_link.rb new file mode 100644 index 0000000..10d10f8 --- /dev/null +++ b/lib/jurnal_api/client/generate_shorten_link.rb @@ -0,0 +1,16 @@ +module JurnalApi + class Client + # Defines methods related to Core + module GenerateShortenLink + # params: {payment_url: 'https://example.com/payment'} + def generate_shorten_link(params = {}) + self.api_version = 'api/internal' + self.format = nil + + response = post("transactions/generate_shorten_link?payment_url=#{params[:payment_url]}", {}, false, true) + + response + end + end + end +end diff --git a/lib/jurnal_api/client/sales_orders.rb b/lib/jurnal_api/client/sales_orders.rb index c1b8075..8e05e96 100644 --- a/lib/jurnal_api/client/sales_orders.rb +++ b/lib/jurnal_api/client/sales_orders.rb @@ -46,6 +46,14 @@ def sales_order_close(id) def sales_order_receive_payments(id, params = {}) get("sales_orders/#{id}/sales_order_payments", params) end + + def sales_order_templates + get('sales_orders/templates') + end + + def sales_order_delete(id) + delete("sales_orders/#{id}") + end end end end diff --git a/lib/jurnal_api/client/transaction_pdfs.rb b/lib/jurnal_api/client/transaction_pdfs.rb new file mode 100644 index 0000000..24e5847 --- /dev/null +++ b/lib/jurnal_api/client/transaction_pdfs.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module JurnalApi + class Client + # Defines methods related to TransactionPdfs + module TransactionPdfs + def transaction_pdfs_send_email(params = {}) + post('transaction_pdfs/send_email', params) + end + end + end +end diff --git a/lib/jurnal_api/connection.rb b/lib/jurnal_api/connection.rb index a75d7e7..cab147c 100644 --- a/lib/jurnal_api/connection.rb +++ b/lib/jurnal_api/connection.rb @@ -1,4 +1,5 @@ -require 'faraday_middleware' +require 'faraday' +require 'faraday/multipart' Dir[File.expand_path('../../faraday/*.rb', __FILE__)].each{|f| require f} @@ -27,7 +28,7 @@ def connection(raw = false) unless raw case format.to_s.downcase when 'json' - connection.use(FaradayMiddleware::ParseJson, :content_type => /\bjson$/) + connection.use(Faraday::Response::Json, :content_type => /\bjson$/) end end diff --git a/lib/jurnal_api/request.rb b/lib/jurnal_api/request.rb index 314d599..a1a9229 100644 --- a/lib/jurnal_api/request.rb +++ b/lib/jurnal_api/request.rb @@ -38,9 +38,9 @@ def request(method, path, options, raw=false, unformatted=false, no_response_wra case method when :get, :delete - request.url(URI.encode(path), options) + request.url(URI::DEFAULT_PARSER.escape(path), options) when :post, :put, :patch - request.path = URI.encode(path) + request.url(URI::DEFAULT_PARSER.escape(path)) request.body = options unless options.empty? end end diff --git a/spec/jurnal_api/client/generate_shorten_link_spec.rb b/spec/jurnal_api/client/generate_shorten_link_spec.rb new file mode 100644 index 0000000..95c4233 --- /dev/null +++ b/spec/jurnal_api/client/generate_shorten_link_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe JurnalApi::Client::GenerateShortenLink do + let(:client) { JurnalApi::Client.new } + let(:module_endpoint) { 'https://sandbox-api.jurnal.id/core/api/internal' } + + describe '#generate_shorten_link' do + context 'successful' do + let(:payment_url) { 'https://example.com/payment/12345' } + let(:dummy_params) { { payment_url: payment_url } } + let(:dummy_response) do + { + 'url' => 'https://short.ly/abc123' + } + end + + before do + expected_url = "#{module_endpoint}/transactions/generate_shorten_link?payment_url=#{payment_url}" + + @expected_stub = + stub_request(:post, expected_url) + .to_return(status: 200, body: dummy_response.to_json, headers: header_json) + end + + subject { client.generate_shorten_link(dummy_params) } + + it 'should hit the expected stub' do + subject + + expect(@expected_stub).to have_been_requested + end + + it 'should return a json response' do + expect(subject).to eq dummy_response.to_json + end + + it 'should set api_version to api/internal' do + subject + expect(client.api_version).to eq('api/internal') + end + + it 'should set format to nil' do + expect(client).to receive(:format=).with(nil) + subject + end + end + end +end diff --git a/spec/jurnal_api/client/sales_orders_spec.rb b/spec/jurnal_api/client/sales_orders_spec.rb index 15b07a3..b29f684 100644 --- a/spec/jurnal_api/client/sales_orders_spec.rb +++ b/spec/jurnal_api/client/sales_orders_spec.rb @@ -6,6 +6,64 @@ let(:client) { JurnalApi::Client.new } let(:module_endpoint) { 'https://sandbox-api.jurnal.id/core/api/v1/sales_orders' } + describe '#list' do + context 'successful' do + let(:dummy_params) { { page: 1, page_size: 10 } } + let(:dummy_response) do + { + "total_data": 100, + "data": [ + read_file_fixture('responses/sales_orders/create_success.json')['sales_order'] + ] + } + end + + before do + @expected_stub = stub_request(:get, "#{module_endpoint}.json") + .with(query: dummy_params) + .to_return(status: 200, body: dummy_response.to_json, headers: header_json) + end + + subject { client.sales_orders(dummy_params) } + + it 'should hit the expected stub' do + subject + + expect(@expected_stub).to have_been_requested + end + + it 'should return a json response' do + expect(subject).to eq dummy_response + end + end + + context 'without params' do + let(:dummy_response) do + { + "total_data": 100, + "data": [] + } + end + + before do + @expected_stub = stub_request(:get, "#{module_endpoint}.json") + .to_return(status: 200, body: dummy_response.to_json, headers: header_json) + end + + subject { client.sales_orders } + + it 'should hit the expected stub' do + subject + + expect(@expected_stub).to have_been_requested + end + + it 'should return a json response' do + expect(subject).to eq dummy_response + end + end + end + describe '#get' do context 'successful' do let(:dummy_response) { read_file_fixture('responses/sales_orders/create_success.json') } @@ -210,4 +268,122 @@ end end end + + describe '#sales_order_templates' do + before do + expected_url = module_endpoint + '/templates.json' + + @expected_stub = + stub_request(:get, expected_url) + .to_return(status: 200, body: dummy_response.to_json, headers: header_json) + end + + let(:dummy_response) do + { + "total_data": 2, + "data": [ + { + "id": "default-1", + "name": "1", + "image_preview": "https://jurnal-assets-production.jurnal.id/images/templete_preview/invoice_preview/invoice_preview_1.png", + "setting_link": "/company/setting/ondemand_pdf" + }, + { + "id": "default-2", + "name": "2", + "image_preview": "https://jurnal-assets-production.jurnal.id/images/templete_preview/invoice_preview/invoice_preview_2.png" + } + ] + }.to_json + end + + subject { client.sales_order_templates } + + it 'should hit the expected stub' do + subject + + expect(@expected_stub).to have_been_requested + end + + it 'should return a json response' do + expect(subject).to eq dummy_response + end + end + + describe '#sales_order_close' do + context 'successful' do + let(:so_id) { 1234 } + let(:dummy_response) do + { + "status": "success", + "message": "Sales order has been closed successfully" + } + end + + before do + @expected_stub = stub_request(:post, "#{module_endpoint}/#{so_id}/close_order.json") + .to_return(status: 200, body: dummy_response.to_json, headers: header_json) + end + + subject { client.sales_order_close(so_id) } + + it 'should hit the expected stub' do + subject + + expect(@expected_stub).to have_been_requested + end + + it 'should return a json response' do + expect(subject).to eq dummy_response + end + end + end + + describe '#sales_order_delete' do + context 'successful' do + let(:so_id) { 1234 } + let(:dummy_response) do + { + "status": "success", + "message": "Sales order has been deleted successfully" + } + end + + before do + @expected_stub = stub_request(:delete, "#{module_endpoint}/#{so_id}.json") + .to_return(status: 200, body: dummy_response.to_json, headers: header_json) + end + + subject { client.sales_order_delete(so_id) } + + it 'should hit the expected stub' do + subject + + expect(@expected_stub).to have_been_requested + end + + it 'should return a json response' do + expect(subject).to eq dummy_response + end + end + + context 'failed' do + context 'when sales order not found' do + let(:so_id) { 9999 } + + before do + @expected_stub = stub_request(:delete, "#{module_endpoint}/#{so_id}.json") + .to_return(status: 404, body: '{"error": "Sales order not found"}', headers: header_json) + end + + subject { client.sales_order_delete(so_id) } + + it 'should hit the expected stub' do + expect { subject }.to raise_error JurnalApi::NotFound + + expect(@expected_stub).to have_been_requested + end + end + end + end end diff --git a/spec/jurnal_api/client/transaction_pdfs_spec.rb b/spec/jurnal_api/client/transaction_pdfs_spec.rb new file mode 100644 index 0000000..45a53b7 --- /dev/null +++ b/spec/jurnal_api/client/transaction_pdfs_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe JurnalApi::Client::TransactionPdfs do + let(:client) { JurnalApi::Client.new } + let(:module_endpoint) { 'https://sandbox-api.jurnal.id/core/api/v1/transaction_pdfs' } + + describe '#send_email' do + let(:dummy_params) do + { + email: { + transaction_type_id: '3', + email_to: 'dummy@mekari.com', + cc_to: 'gundam@maju.com', + email_from: 'billing@mekari.com', + message: 'message here', + transaction_no: 'BPI/2024/11/00001', + template_id: 'default-1' + } + } + end + let(:dummy_response) do + { + message: 'sent', + sent_total: 1 + } + end + let(:expected_url) { "#{module_endpoint}/send_email.json" } + + before do + @expected_stub = + stub_request(:post, expected_url) + .with(body: dummy_params.to_json) + .to_return(status: 200, body: dummy_response.to_json, headers: header_json) + end + + subject { client.transaction_pdfs_send_email(dummy_params.to_json) } + + it 'should hit the expected stub' do + subject + + expect(@expected_stub).to have_been_requested + end + + it 'should return a json response' do + expect(subject.to_json).to eq dummy_response.to_json + end + end +end