bianchi 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57689540f35b1837b227a23ec9b9badd237e5e1bda6b7f0b5c3d64443b404fd9
4
- data.tar.gz: b963e56598337607ef36f0d4ebb514c9a83e354c3dc65d55d3ad299c856668b3
3
+ metadata.gz: 9d0a4841767acc10455e325dee277cf81119914192754b2da010b99626850986
4
+ data.tar.gz: 544c49afaa014e0163d86730b5338ead295ddd1f02bf6364aaa480d4a1da38f2
5
5
  SHA512:
6
- metadata.gz: 9272b56f5a057de49f9695cc615afcf05fbdcb14db6f31f582bf8d6b421b4dc8787ba5fbbcab87a120aaf4fd0519fad88c66f842423984915dbf271de3076207
7
- data.tar.gz: ce5f129f37e80ff25fa642af17ae8d5f31b467f580419a7b053afe941979f6e09cf9183668a9443aea262c2d933f41a1656401098e6ef6d8d8ac26ed890b2d22
6
+ metadata.gz: 993ad14fd38daaf4ee9cf0d55f2450111675195d778c92c4663edff75f8f657cbcb816837bb41ec3ad75b7256e0a6e800b051808c46a0224f3d54cfea16f22e7
7
+ data.tar.gz: 183c4fbd9c4113c4bf6fcc399e119f1e4f54f5a39b24a220dca9ce8c8fdec81195f0c802e002b36f2e2998b3fd1bfe8b0aa081ac3e88b30d823d5f78a2037e3e
@@ -0,0 +1,45 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - '*'
7
+ pull_request:
8
+ branches:
9
+ - main
10
+
11
+ jobs:
12
+ rubocop:
13
+ runs-on: ubuntu-latest
14
+
15
+ services:
16
+ redis:
17
+ image: redis
18
+ ports:
19
+ - 6379:6379
20
+ options: --entrypoint redis-server
21
+
22
+ steps:
23
+ - name: Checkout code
24
+ uses: actions/checkout@v4.1.1
25
+
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@v1.171.0
28
+ with:
29
+ ruby-version: 3.0
30
+
31
+ - name: Install dependencies
32
+ run: |
33
+ gem install bundler
34
+ bundle install
35
+
36
+ - name: Run RuboCop
37
+ run: bundle exec rubocop
38
+
39
+ - name: Start Redis
40
+ run: docker ps -a
41
+
42
+ - name: Run RSpec tests
43
+ env:
44
+ REDIS_URL: redis://localhost:6379
45
+ run: bundle exec rspec
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ .byebug_history
data/.rubocop.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  AllCops:
2
2
  NewCops: enable
3
3
  TargetRubyVersion: 3.0
4
+ SuggestExtensions: false
4
5
 
5
6
  Style/StringLiterals:
6
7
  Enabled: true
@@ -18,3 +19,4 @@ Metrics/MethodLength:
18
19
 
19
20
 
20
21
 
22
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "cSpell.words": [
3
+ "appsnmobile"
4
+ ]
5
+ }
data/Gemfile CHANGED
@@ -9,6 +9,6 @@ gem "rake", "~> 13.0"
9
9
 
10
10
  gem "rspec", "~> 3.0"
11
11
 
12
- gem "rubocop", "~> 0.80"
12
+ gem "rubocop", "~> 1.60", ">= 1.60.2"
13
13
 
14
14
  gem "byebug"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bianchi (0.1.0)
4
+ bianchi (0.1.2)
5
5
  activesupport
6
6
  json
7
7
  redis
@@ -32,10 +32,11 @@ GEM
32
32
  i18n (1.14.1)
33
33
  concurrent-ruby (~> 1.0)
34
34
  json (2.7.1)
35
+ language_server-protocol (3.17.0.3)
35
36
  minitest (5.21.2)
36
37
  mutex_m (0.2.0)
37
38
  parallel (1.24.0)
38
- parser (3.3.0.2)
39
+ parser (3.3.0.5)
39
40
  ast (~> 2.4.1)
40
41
  racc
41
42
  racc (1.7.3)
@@ -60,15 +61,17 @@ GEM
60
61
  diff-lcs (>= 1.2.0, < 2.0)
61
62
  rspec-support (~> 3.12.0)
62
63
  rspec-support (3.12.1)
63
- rubocop (0.93.1)
64
+ rubocop (1.60.2)
65
+ json (~> 2.3)
66
+ language_server-protocol (>= 3.17.0)
64
67
  parallel (~> 1.10)
65
- parser (>= 2.7.1.5)
68
+ parser (>= 3.3.0.2)
66
69
  rainbow (>= 2.2.2, < 4.0)
67
- regexp_parser (>= 1.8)
68
- rexml
69
- rubocop-ast (>= 0.6.0)
70
+ regexp_parser (>= 1.8, < 3.0)
71
+ rexml (>= 3.2.5, < 4.0)
72
+ rubocop-ast (>= 1.30.0, < 2.0)
70
73
  ruby-progressbar (~> 1.7)
71
- unicode-display_width (>= 1.4.0, < 2.0)
74
+ unicode-display_width (>= 2.4.0, < 3.0)
72
75
  rubocop-ast (1.30.0)
73
76
  parser (>= 3.2.1.0)
74
77
  ruby-progressbar (1.13.0)
@@ -76,9 +79,10 @@ GEM
76
79
  thor (1.3.0)
77
80
  tzinfo (2.0.6)
78
81
  concurrent-ruby (~> 1.0)
79
- unicode-display_width (1.8.0)
82
+ unicode-display_width (2.5.0)
80
83
 
81
84
  PLATFORMS
85
+ arm64-darwin-22
82
86
  x86_64-darwin-23
83
87
 
84
88
  DEPENDENCIES
@@ -86,7 +90,7 @@ DEPENDENCIES
86
90
  byebug
87
91
  rake (~> 13.0)
88
92
  rspec (~> 3.0)
89
- rubocop (~> 0.80)
93
+ rubocop (~> 1.60, >= 1.60.2)
90
94
 
91
95
  BUNDLED WITH
92
96
  2.2.3
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # Bianchi
2
2
  A DSL (Domain-Specific Language) and a minimalist framework in Ruby, tailored for USSD development. Structured around a menu page approach, Bianchi offers a comprehensive suite of methods and generators, streamlining the process of building USSD applications efficiently and easily.
3
+ A basic test run with bianchi can be found here https://github.com/SydDaps/sinatra_bianchi_example
3
4
 
4
5
  ## Installation
5
- Add `gem 'bianchi', '~> 0.1.0'` to your gem file and run `bundle install`
6
+ Add `gem 'bianchi', '~> 0.1.1'` to your gem file and run `bundle install`
6
7
 
7
- Bianchi relies on Redis and requires the `REDIS_URL` environment variable to be set, pointing to your Redis instance. Ensure Redis is installed, running, and that REDIS_URL is correctly configured before using Bianchi.
8
+ Bianchi relies on Redis and requires the `REDIS_URL` environment variable to be set, pointing to your Redis instance. Ensure Redis is installed, and running, and that REDIS_URL is correctly configured before using Bianchi.
8
9
 
9
10
  ## Getting Started
10
11
 
@@ -14,7 +15,7 @@ To initialize a new USSD project, generate a project directory using Bianchi's c
14
15
  bundle exec bianchi setup -p provider_name
15
16
  ```
16
17
 
17
- Replace `provider_name` with your desired provider. Currently supported providers include: africa_is_talking.
18
+ Replace `provider_name` with your desired provider. Currently supported providers include: africastalking.
18
19
 
19
20
  This command creates a `ussd/engine.rb` file in the project root directory. Here's a sample content of `ussd/engine.rb`:
20
21
 
@@ -22,7 +23,7 @@ This command creates a `ussd/engine.rb` file in the project root directory. Here
22
23
  module USSD
23
24
  class Engine
24
25
  def self.start(params)
25
- Bianchi::USSD::Engine.start(params, provider: :africa_is_talking) do
26
+ Bianchi::USSD::Engine.start(params, provider: :africastalking) do
26
27
  # e.g menu :main, options
27
28
  end
28
29
  end
@@ -52,11 +53,9 @@ This creates a `ussd/main_menu/page_1` file in the project root directory. Here'
52
53
  module USSD
53
54
  module MainMenu
54
55
  class Page1 < Bianchi::USSD::Page
55
- def request
56
- end
56
+ def request; end
57
57
 
58
- def response
59
- end
58
+ def response; end
60
59
  end
61
60
  end
62
61
  end
@@ -183,8 +182,8 @@ Here's an example of how you can retrieve the provider prompt data in your USSD
183
182
  module USSD
184
183
  class Engine
185
184
  def self.start(params)
186
- Bianchi::USSD::Engine.start(params, provider: :africa_is_talking) do
187
- menu :main, options
185
+ Bianchi::USSD::Engine.start(params, provider: :africastalking) do
186
+ menu :main, initial: true
188
187
  menu :greetings
189
188
  menu :repeat
190
189
  end
data/bianchi.gemspec CHANGED
@@ -8,7 +8,10 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Dapilah Sydney"]
9
9
  spec.email = ["dapilah.sydney@gmail.com"]
10
10
 
11
- spec.summary = "Write a short summary, because RubyGems requires one."
11
+ spec.summary = <<~MSG
12
+ A DSL (Domain-Specific Language) and a minimalist framework in Ruby, tailored for USSD development.
13
+ MSG
14
+
12
15
  spec.homepage = "https://github.com/SydDaps/Bianchi"
13
16
  spec.license = "MIT"
14
17
  spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
@@ -34,4 +37,5 @@ Gem::Specification.new do |spec|
34
37
  spec.add_dependency "json"
35
38
  spec.add_dependency "redis"
36
39
  spec.add_dependency "thor"
40
+ spec.metadata["rubygems_mfa_required"] = "true"
37
41
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Metrics/ParameterLists
3
4
  module Bianchi
4
5
  module Cli
5
6
  class Main < Thor
@@ -19,7 +20,7 @@ module Bianchi
19
20
  desc "setup", "sets up a new ussd project"
20
21
  long_desc <<-LONG_DESC
21
22
  Usage: bianchi setup optional(-p|--provider)
22
- \x5 Providers: [:africa_is_talking]
23
+ \x5 Providers: [:africa_is_talking, :appsnmobile]
23
24
  \x5 Example: `bianchi setup`
24
25
  \x5 Example: `bianchi setup -p :africa_is_talking`
25
26
 
@@ -27,7 +28,7 @@ module Bianchi
27
28
  method_option :provider, aliases: "-p", type: :string, desc: "Set up ussd project for provider"
28
29
  def setup
29
30
  @provider = options[:provider]
30
- unless %w[africastalking none].include? @provider
31
+ unless %w[africastalking none appsnmobile].include? @provider
31
32
  say("Error: provider #{@provider} is not yet configured.", :yellow)
32
33
  exit(1)
33
34
  end
@@ -62,3 +63,4 @@ module Bianchi
62
63
  end
63
64
  end
64
65
  end
66
+ # rubocop:enable Metrics/ParameterLists
@@ -110,10 +110,7 @@ module Bianchi
110
110
  "#{constant_name} is supposed to be defined to process #{session.menu.name} menu #{page_number}"
111
111
  end
112
112
 
113
- page.new(session).tap do |p|
114
- p.ensure_methods_defined(%i[request response])
115
- p.send(action)
116
- end
113
+ page.call(session, action)
117
114
  end
118
115
  end
119
116
  end
@@ -6,5 +6,7 @@ module Bianchi
6
6
  class PageLoadError < StandardError; end
7
7
  class MethodNameError < StandardError; end
8
8
  class ProviderError < StandardError; end
9
+ class ProviderError < StandardError; end
10
+ class DispatchRenderException < StandardError; end
9
11
  end
10
12
  end
@@ -11,6 +11,15 @@ module Bianchi
11
11
  @session = session
12
12
  end
13
13
 
14
+ def self.call(session, action)
15
+ new(session).tap do |p|
16
+ p.ensure_methods_defined(%i[request response])
17
+ p.send(action)
18
+ rescue DispatchRenderException
19
+ p
20
+ end
21
+ end
22
+
14
23
  def render(body, options = {})
15
24
  raise ArgumentError, "render body expected to be a string" unless body.is_a? String
16
25
 
@@ -22,6 +31,8 @@ module Bianchi
22
31
  s.page_number = self.class.name.split("::").last
23
32
  s.store.track_session
24
33
  end
34
+
35
+ raise DispatchRenderException
25
36
  end
26
37
 
27
38
  def load_page(page_number, menu_name)
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Style/MissingRespondToMissing
3
4
  module Bianchi
4
5
  module USSD
5
6
  module PageDelegators
@@ -100,3 +101,4 @@ module Bianchi
100
101
  end
101
102
  end
102
103
  end
104
+ # rubocop:enable Style/MissingRespondToMissing
@@ -4,11 +4,13 @@ module Bianchi
4
4
  module USSD
5
5
  module ProviderConfigurations
6
6
  include ProviderParsers::Africastalking
7
+ include ProviderParsers::Appsnmobile
7
8
 
8
9
  def parse_params(params)
9
10
  provider_parsers = {
10
11
  none: proc { params },
11
- africastalking: proc { africastalking_params_parser(params) }
12
+ africastalking: proc { africastalking_params_parser(params) },
13
+ appsnmobile: proc { appsnmobile_params_parser(params) }
12
14
  }.with_indifferent_access
13
15
 
14
16
  parser = provider_parsers[@provider]
@@ -21,7 +23,8 @@ module Bianchi
21
23
  def parser_prompt_data(prompt_data)
22
24
  provider_parsers = {
23
25
  none: proc { prompt_data },
24
- africastalking: proc { africastalking_prompt_data_parser(prompt_data) }
26
+ africastalking: proc { africastalking_prompt_data_parser(prompt_data) },
27
+ appsnmobile: proc { appsnmobile_prompt_data_parser(prompt_data) }
25
28
  }.with_indifferent_access
26
29
 
27
30
  parser = provider_parsers[@provider]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bianchi
2
4
  module USSD
3
5
  module ProviderParsers
@@ -25,4 +27,4 @@ module Bianchi
25
27
  end
26
28
  end
27
29
  end
28
- end
30
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bianchi
4
+ module USSD
5
+ module ProviderParsers
6
+ module Appsnmobile
7
+ def appsnmobile_params_parser(params)
8
+ required_params = %w[session_id msisdn msg_type ussd_body nw_code service_code]
9
+ left_required_params = required_params - params.keys.map(&:to_s)
10
+
11
+ unless left_required_params.empty?
12
+ raise ArgumentError, "#{left_required_params} required in params to start engine for provider #{@provider}"
13
+ end
14
+
15
+ {
16
+ session_id: params["session_id"],
17
+ mobile_number: params["msisdn"],
18
+ activity_state: return_activity_state(params["msg_type"]),
19
+ input_body: params["ussd_body"],
20
+ nw_code: params["nw_code"],
21
+ service_code: params["service_code"]
22
+ }
23
+ end
24
+
25
+ def appsnmobile_prompt_data_parser(prompt_data)
26
+ msg_type = prompt_data["activity_state"] == :await ? "1" : "2"
27
+
28
+ {
29
+ session_id: prompt_data["session_id"],
30
+ msisdn: prompt_data["mobile_number"],
31
+ msg_type: msg_type,
32
+ ussd_body: prompt_data["body"],
33
+ nw_code: prompt_data["nw_code"],
34
+ service_code: prompt_data["service_code"]
35
+ }.to_json
36
+ end
37
+
38
+ def return_activity_state(msg_type)
39
+ case msg_type
40
+ when "0"
41
+ "initial"
42
+ when "1"
43
+ "subsequent"
44
+ else
45
+ raise ArgumentError, "#{@provider} sent in an unknown message type or msg_type"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -6,7 +6,13 @@ module Bianchi
6
6
  attr_reader :session
7
7
 
8
8
  def initialize(session)
9
- @redis = Redis.new(url: ENV.fetch("REDIS_URL", nil))
9
+ redis_url = ENV.fetch("REDIS_URL", nil)
10
+ unless redis_url.present?
11
+ raise ArgumentError,
12
+ "environment variable REDIS_URL required to track engine session."
13
+ end
14
+
15
+ @redis = Redis.new(url: redis_url)
10
16
  @session = session
11
17
  end
12
18
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bianchi
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
data/lib/bianchi.rb CHANGED
@@ -7,6 +7,7 @@ require "thor"
7
7
 
8
8
  require_relative "bianchi/version"
9
9
  require_relative "bianchi/ussd/provider_parsers/africastalking"
10
+ require_relative "bianchi/ussd/provider_parsers/appsnmobile"
10
11
  require_relative "bianchi/ussd/provider_configurations"
11
12
  require_relative "bianchi/ussd/engine"
12
13
  require_relative "bianchi/ussd/menu"
@@ -14,7 +15,7 @@ require_relative "bianchi/ussd/session"
14
15
  require_relative "bianchi/ussd/page_delegators"
15
16
  require_relative "bianchi/ussd/page"
16
17
  require_relative "bianchi/ussd/store"
17
- require_relative "bianchi/ussd/errors"
18
+ require_relative "bianchi/ussd/exceptions"
18
19
 
19
20
  # cli
20
21
  require "bianchi/cli/main"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bianchi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dapilah Sydney
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-28 00:00:00.000000000 Z
11
+ date: 2024-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -74,9 +74,11 @@ executables:
74
74
  extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
+ - ".github/workflows/ci.yml"
77
78
  - ".gitignore"
78
79
  - ".rspec"
79
80
  - ".rubocop.yml"
81
+ - ".vscode/settings.json"
80
82
  - CODE_OF_CONDUCT.md
81
83
  - Gemfile
82
84
  - Gemfile.lock
@@ -93,12 +95,13 @@ files:
93
95
  - lib/bianchi/cli/templates/engine.erb
94
96
  - lib/bianchi/cli/templates/page.erb
95
97
  - lib/bianchi/ussd/engine.rb
96
- - lib/bianchi/ussd/errors.rb
98
+ - lib/bianchi/ussd/exceptions.rb
97
99
  - lib/bianchi/ussd/menu.rb
98
100
  - lib/bianchi/ussd/page.rb
99
101
  - lib/bianchi/ussd/page_delegators.rb
100
102
  - lib/bianchi/ussd/provider_configurations.rb
101
103
  - lib/bianchi/ussd/provider_parsers/africastalking.rb
104
+ - lib/bianchi/ussd/provider_parsers/appsnmobile.rb
102
105
  - lib/bianchi/ussd/session.rb
103
106
  - lib/bianchi/ussd/store.rb
104
107
  - lib/bianchi/version.rb
@@ -112,6 +115,7 @@ metadata:
112
115
  homepage_uri: https://github.com/SydDaps/Bianchi
113
116
  source_code_uri: https://github.com/SydDaps/Bianchi
114
117
  changelog_uri: https://rubygems.org/
118
+ rubygems_mfa_required: 'true'
115
119
  post_install_message:
116
120
  rdoc_options: []
117
121
  require_paths:
@@ -130,5 +134,6 @@ requirements: []
130
134
  rubygems_version: 3.2.3
131
135
  signing_key:
132
136
  specification_version: 4
133
- summary: Write a short summary, because RubyGems requires one.
137
+ summary: A DSL (Domain-Specific Language) and a minimalist framework in Ruby, tailored
138
+ for USSD development.
134
139
  test_files: []