From 95f192a71f85428baa943fb9be138d0286122492 Mon Sep 17 00:00:00 2001 From: Iphytech Date: Thu, 20 Jul 2023 11:27:07 +0100 Subject: [PATCH 1/2] added workflow script and TZS mobile money --- .env.example | 3 + .github/pull_request_template.md | 39 ++++++++++ .github/workflows/change-review.yml | 52 ++++++++++++++ .github/workflows/ruby-publish.yml | 65 +++++++++++++++++ .gitignore | 5 +- Gemfile.lock | 11 +++ flutterwave_sdk.gemspec | 8 +++ .../flutterwave_objects/card.rb | 12 ++-- .../flutterwave_objects/mobile_money.rb | 13 ++-- spec/flutterwave_card_spec.rb | 22 +++--- spec/flutterwave_momo_tzs_spec.rb | 72 +++++++++++++++++++ 11 files changed, 279 insertions(+), 23 deletions(-) create mode 100644 .env.example create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/change-review.yml create mode 100644 .github/workflows/ruby-publish.yml create mode 100644 spec/flutterwave_momo_tzs_spec.rb diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b962b39 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +TEST_SECRET_KEY= +TEST_PUBLIC_KEY= +TEST_ENCRYPTION_KEY= diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..2e89937 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,39 @@ + + +#### Description + + +#### Related Issue + + + + + +#### Motivation and Context + + +#### How Has This Been Tested? + + + + +#### Types of changes + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] Refactor (non-breaking change which improves implementation) +- [ ] Performance (non-breaking change which improves performance. Please add associated performance test and results) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Non-functional change (xml comments/documentation/etc) + +#### Checklist: + + +- [ ] My code follows the code style of this project. +- [ ] I have read the **CONTRIBUTING** [document](https://github.com/QuantConnect/Lean/blob/master/CONTRIBUTING.md). +- [ ] I have added tests to cover my changes. +- [ ] All new and existing tests passed. +- [ ] My branch follows the naming convention `bug--` or `feature--` + + +@Flutterwave/Corvus97 What do you think about these updates? diff --git a/.github/workflows/change-review.yml b/.github/workflows/change-review.yml new file mode 100644 index 0000000..4005905 --- /dev/null +++ b/.github/workflows/change-review.yml @@ -0,0 +1,52 @@ +name: Review changes on Dev (Commits/PRs) +on: + push: + branches: ["dev"] + pull_request: + types: + - opened + +jobs: + code-check: + runs-on: ubuntu-latest + + strategy: + matrix: + ruby-version: ["3.1", "3.0", "2.7"] + + steps: + - name: checkout code + uses: actions/checkout@v2 + + - name: setup ruby environment + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + ruby-version: ${{ matrix.ruby-version }} + + - name: install ruby dependencies + run: | + gem install bundler + bundle install --jobs 4 --retry 3 + + - name: run unit tests and coverage scan + env: + PUBLIC_KEY: ${{ secrets.PUBLIC_KEY }} + ENCRYPTION_KEY: ${{ secrets.ENCRYPTION_KEY }} + RAVE_SECRET_KEY: ${{ secrets.SECRET_KEY }} + run: | + bundle exec rspec --format progress --format json --out coverage/coverage.json + + - name: upload coverage report to codecov + uses: codecov/codecov-action@v2 + with: + file: coverage/coverage.json + + - name: push build status to slack + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + fields: repo,message,commit,author,action,eventName,ref,workflow,job,took,pullRequest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + if: always() diff --git a/.github/workflows/ruby-publish.yml b/.github/workflows/ruby-publish.yml new file mode 100644 index 0000000..991fda9 --- /dev/null +++ b/.github/workflows/ruby-publish.yml @@ -0,0 +1,65 @@ +name: Publish changes to Rubygems + +on: + release: + types: [created] + +jobs: + check-readme-and-changelog: + runs-on: ubuntu-latest + env: + OS: ubuntu-latest + ruby-version: "3.1" + steps: + - name: checkout code + uses: actions/checkout@v2 + + - name: check for changes in readme and changelog files + run: | + if ! git diff --quiet HEAD~ HEAD -- README.md CHANGELOG.md; then + echo "README and/or CHANGELOG have been modified. Proceeding with deployment." + else + echo "README and/or CHANGELOG have not been modified. Terminating deployment." + exit 1 + fi + + - name: push build status to Slack + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + fields: repo,message,commit,author,action,eventName,ref,workflow,job,took,pullRequest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + if: always() + + publish: + needs: check-readme-and-changelog + runs-on: ubuntu-latest + env: + OS: ubuntu-latest + ruby-version: "3.1" + steps: + - name: checkout code + uses: actions/checkout@v2 + + - name: Setup ruby environment + uses: actions/setup-ruby@v1 + with: + ruby-version: "3.1" + + - name: install ruby dependencies + run: bundle install + + - name: Publish gems to Rubygems + env: + GEM_HOST_API_KEY: ${{secrets.GEM_HOST_API_KEY}} + run: gem push gems/*.gem + + - name: push build status to Slack + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + fields: repo,message,commit,author,action,eventName,ref,workflow,job,took,pullRequest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + if: always() diff --git a/.gitignore b/.gitignore index 8a2870f..b7516cc 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ /tmp/ .env +/sample_code +sample_code/ +sample_code # rspec failure tracking .rspec_status @@ -33,4 +36,4 @@ virtual_account_number_test.rb bills_test.rb preauth_test.rb rspec_results.html -flutterwave_sdk-0.1.0.gem \ No newline at end of file +flutterwave_sdk-0.1.0.gem diff --git a/Gemfile.lock b/Gemfile.lock index 7b0bea3..49273f1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,11 +2,20 @@ PATH remote: . specs: flutterwave_sdk (0.1.1) + httparty (~> 0.16.3) GEM remote: https://rubygems.org/ specs: diff-lcs (1.3) + dotenv (2.8.1) + httparty (0.16.4) + mime-types (~> 3.0) + multi_xml (>= 0.5.2) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2023.0218.1) + multi_xml (0.6.0) rake (12.3.3) rspec (3.9.0) rspec-core (~> 3.9.0) @@ -26,6 +35,8 @@ PLATFORMS ruby DEPENDENCIES + bundler (~> 2.1.4) + dotenv (~> 2.8.1) flutterwave_sdk! rake (~> 12.0) rspec (~> 3.0) diff --git a/flutterwave_sdk.gemspec b/flutterwave_sdk.gemspec index d164758..c2b1b7f 100644 --- a/flutterwave_sdk.gemspec +++ b/flutterwave_sdk.gemspec @@ -25,4 +25,12 @@ spec.date = '2020-05-10' spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] + + spec.add_development_dependency "bundler", "~> 2.1.4" + #add dotenv + spec.add_development_dependency "dotenv", "~> 2.8.1" + + # Dependencies + spec.required_ruby_version = ">= 2.5.3" + spec.add_runtime_dependency 'httparty', '~> 0.16.3' end diff --git a/lib/flutterwave_sdk/flutterwave_objects/card.rb b/lib/flutterwave_sdk/flutterwave_objects/card.rb index 44d3ffc..6fd658d 100644 --- a/lib/flutterwave_sdk/flutterwave_objects/card.rb +++ b/lib/flutterwave_sdk/flutterwave_objects/card.rb @@ -3,12 +3,12 @@ class Card < CardBase - # method to initiate card charge + # method to initiate card charge def initiate_charge(data) base_url = flutterwave_object.base_url encryption_key = flutterwave_object.encryption_key public_key = flutterwave_object.public_key - + # only update the payload with the transaction reference if it isn't already added to the payload if !data.key?("tx_ref") data.merge!({"tx_ref" => Util.transaction_reference_generator}) @@ -29,13 +29,13 @@ def initiate_charge(data) type = "card" payload = payload.to_json - response = post_request("#{base_url}#{BASE_ENDPOINTS::CHARGE_ENDPOINT}?type=#{type}", payload) - + response = post_request("#{base_url}#{BASE_ENDPOINTS::CHARGE_ENDPOINT}?type=#{type}", payload) + return response end - def validate_charge(flw_ref, otp) + def validate_charge(flw_ref, otp) base_url = flutterwave_object.base_url payload = { "otp" => otp, @@ -52,4 +52,4 @@ def verify_charge(id) response = get_request("#{base_url}/transactions/#{id}/verify") return response end -end \ No newline at end of file +end diff --git a/lib/flutterwave_sdk/flutterwave_objects/mobile_money.rb b/lib/flutterwave_sdk/flutterwave_objects/mobile_money.rb index a0c283b..b817765 100644 --- a/lib/flutterwave_sdk/flutterwave_objects/mobile_money.rb +++ b/lib/flutterwave_sdk/flutterwave_objects/mobile_money.rb @@ -3,13 +3,13 @@ class MobileMoney < Base def initiate_charge(data) - base_url = flutterwave_object.base_url - + base_url = flutterwave_object.base_url + # only update the payload with the transaction reference if it isn't already added to the payload if !data.key?("tx_ref") data.merge!({"tx_ref" => Util.transaction_reference_generator}) end - # check the currency to determine the type and the required parameters + # check the currency to determine the type and the required parameters if data["currency"] == "KES" required_parameters = [ "amount", "email", "phone_number", "tx_ref", "currency"] type = "mpesa" @@ -22,12 +22,15 @@ def initiate_charge(data) elsif data["currency"] == "ZMW" required_parameters = ["amount", "email", "phone_number","tx_ref", "currency"] type = "mobile_money_zambia" - elsif data["currency"] == "RWF" + elsif data["currency"] == "RWF" required_parameters = ["amount", "email", "phone_number","tx_ref", "currency"] type = "mobile_money_rwanda" elsif data["currency"] == "XAF" || data["currency"] == "XOF" required_parameters = ["amount", "email", "phone_number", "tx_ref", "currency"] type = "mobile_money_franco" + elsif data["currency"] == "TZS" + required_parameters = ["amount", "email", "phone_number", "tx_ref", "currency"] + type = "mobile_money_tanzania" else return "pass a valid currency" end @@ -36,7 +39,7 @@ def initiate_charge(data) type = type payload = data.to_json - response = post_request("#{base_url}#{BASE_ENDPOINTS::CHARGE_ENDPOINT}?type=#{type}", payload) + response = post_request("#{base_url}#{BASE_ENDPOINTS::CHARGE_ENDPOINT}?type=#{type}", payload) return response end diff --git a/spec/flutterwave_card_spec.rb b/spec/flutterwave_card_spec.rb index 6d1b580..6827bb4 100644 --- a/spec/flutterwave_card_spec.rb +++ b/spec/flutterwave_card_spec.rb @@ -11,29 +11,29 @@ payload = { "type" => "card", - "card_number" => "5531886652142950", - "cvv" => "564", + "card_number" => "4187427415564246", + "cvv" => "828", "expiry_month" => "09", - "expiry_year" => "22", + "expiry_year" => "32", "currency" => "NGN", "amount" => "10", "email" => "developers@flutterwavego.com", "fullname" => "Ifunanya ikemma", - "tx_ref" => "Sample_RBRef218", + "tx_ref" => "MC-" + Date.today.to_s, "redirect_url" => "https://webhook.site/3ed41e38-2c79-4c79-b455-97398730866c" } -pin_payload = { +pin_payload = { "type" => "card", - "card_number" => "5531886652142950", - "cvv" => "564", + "card_number" => "4187427415564246", + "cvv" => "828", "expiry_month" => "09", - "expiry_year" => "22", + "expiry_year" => "32", "currency" => "NGN", "amount" => "10", "email" => "developers@flutterwavego.com", "fullname" => "Ifunanya ikemma", - "tx_ref" => "Sample_RBRef015", + "tx_ref" => "MC-" + Date.today.to_s, "redirect_url" => "https://webhook.site/3ed41e38-2c79-4c79-b455-97398730866c", "authorization": { "mode": "pin", @@ -46,12 +46,12 @@ # "card_number" => "5531886652142950", "cvv" => "564", "expiry_month" => "09", - "expiry_year" => "22", + "expiry_year" => "32", "currency" => "NGN", "amount" => "10", "email" => "developers@flutterwavego.com", "fullname" => "Ifunanya ikemma", - "tx_ref" => "MC-3243e-if-16", + "tx_ref" => "MC-" + Date.today.to_s, "redirect_url" => "https://webhook.site/3ed41e38-2c79-4c79-b455-97398730866c" } diff --git a/spec/flutterwave_momo_tzs_spec.rb b/spec/flutterwave_momo_tzs_spec.rb new file mode 100644 index 0000000..dde34d9 --- /dev/null +++ b/spec/flutterwave_momo_tzs_spec.rb @@ -0,0 +1,72 @@ +require 'dotenv' +require 'spec_helper' +require "flutterwave_sdk/flutterwave_objects/mobile_money" +require "flutterwave_sdk/flutterwave_objects/transactions" + +Dotenv.load + +test_public_key = ENV['TEST_PUBLIC_KEY'] +test_secret_key = ENV['TEST_SECRET_KEY'] +test_encryption_key = ENV['TEST_ENCRYPTION_KEY'] + +payload = { + "tx_ref" => "MC-" + + Date.today.to_s, + "amount" => "100", + "currency" => "TZS", + "email" => "ifunanyaikemma@gmail.com", + "phone_number" => "0782835136", + "fullname" => "Yolande Aglae Colbert", + "network" => "Halopesa", +} + +incomplete_payload = { + "tx_ref" => "MC-158523sdsdsd", + "amount" => "100", + "currency" => "TZS", + "email" => "ifunanyaikemma@gmail.com", +} + +RSpec.describe MobileMoney do + flutterwave = Flutterwave.new(test_public_key, test_secret_key, test_encryption_key) + mobile_money = MobileMoney.new(flutterwave) + transactions = Transactions.new(flutterwave) + mobile_money_charge = mobile_money.initiate_charge(payload) + + + context "when a merchant tries to charge a customers via mobile money" do + it "should return a mobile money object" do + expect(mobile_money.nil?).to eq(false) + end + + it 'should raise Error if the mobile money payload is incomplete' do + begin + incomplete_mobile_money_response = mobile_money.initiate_charge(incomplete_payload) + rescue => e + expect(e.instance_of? IncompleteParameterError).to eq true + end + end + + it 'should successfully generate payment link for the charge' do + payload_response = mobile_money_charge + expect(payload_response["status"]).to eq("success") + end + + it 'should successfully return processor response ' do + payload_response = mobile_money_charge + expect(payload_response["data"]["processor_response"]).to eq("Transaction in progress") + end + + it 'should successfully return the auth model' do + payload_response = mobile_money_charge + expect(payload_response["data"]["auth_model"]).to eq("MOBILEMONEY") + end + + it 'should successfully verify fees for mobile money payments' do + currency = "TZS" + amount = "100" + verify_fee_response = transactions.transaction_fee(currency, amount) + expect(verify_fee_response["data"]["fee"]).to eq(1.4) + end + + end +end From 4f89bfa091a24762b0dd4904c4a90c0e11182cc3 Mon Sep 17 00:00:00 2001 From: Iphytech Date: Thu, 20 Jul 2023 11:32:13 +0100 Subject: [PATCH 2/2] edit changelog --- changelog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/changelog.md b/changelog.md index 2a33a76..b9ffaa9 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,14 @@ # Changelog +## [0.1.1] - 2023-07-20 +### Added +- Test suite for mobile money TZS transactions. +- Workflow scripts for review and publish + +### Fixed +- Fix test suite for card. + + ## [0.1.1] - 2022-06-02 ### Added - Test suite for mobile money transactions.