sms_aero 0.0.11 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -6
  3. data/CHANGELOG.md +15 -10
  4. data/README.md +25 -30
  5. data/lib/sms_aero.rb +119 -34
  6. data/lib/sms_aero/birthday.rb +12 -0
  7. data/lib/sms_aero/callable.rb +6 -0
  8. data/lib/sms_aero/channel.rb +15 -0
  9. data/lib/sms_aero/digital.rb +7 -0
  10. data/lib/sms_aero/filled_string.rb +11 -0
  11. data/lib/sms_aero/future.rb +16 -0
  12. data/lib/sms_aero/group.rb +11 -0
  13. data/lib/sms_aero/optional.rb +15 -0
  14. data/lib/sms_aero/phone.rb +11 -0
  15. data/lib/sms_aero/response.rb +30 -0
  16. data/lib/sms_aero/response/with_balance.rb +5 -0
  17. data/lib/sms_aero/response/with_groups.rb +5 -0
  18. data/lib/sms_aero/response/with_id.rb +9 -0
  19. data/lib/sms_aero/response/with_senders.rb +5 -0
  20. data/lib/sms_aero/response/with_statuses.rb +5 -0
  21. data/lib/sms_aero/response/with_tariff.rb +5 -0
  22. data/lib/sms_aero/tariff.rb +8 -0
  23. data/sms_aero.gemspec +2 -4
  24. data/spec/{sms_aero/types → models}/birthday_spec.rb +2 -2
  25. data/spec/{sms_aero/types → models}/channel_spec.rb +2 -2
  26. data/spec/{sms_aero/types → models}/digital_spec.rb +1 -1
  27. data/spec/{sms_aero/types → models}/future_spec.rb +5 -5
  28. data/spec/{sms_aero/types → models}/phone_spec.rb +1 -1
  29. data/spec/{sms_aero/operations → operations}/add_blacklist_spec.rb +19 -3
  30. data/spec/{sms_aero/operations → operations}/add_group_spec.rb +4 -4
  31. data/spec/{sms_aero/operations → operations}/add_phone_spec.rb +39 -76
  32. data/spec/{sms_aero/operations → operations}/check_balance_spec.rb +2 -4
  33. data/spec/{sms_aero/operations → operations}/check_groups_spec.rb +0 -0
  34. data/spec/{sms_aero/operations → operations}/check_senders_spec.rb +5 -5
  35. data/spec/{sms_aero/operations → operations}/check_sending_spec.rb +3 -3
  36. data/spec/{sms_aero/operations → operations}/check_sign_spec.rb +2 -2
  37. data/spec/{sms_aero/operations → operations}/check_status_spec.rb +3 -3
  38. data/spec/{sms_aero/operations → operations}/check_tariff_spec.rb +1 -1
  39. data/spec/{sms_aero/operations → operations}/delete_group_spec.rb +3 -3
  40. data/spec/{sms_aero/operations → operations}/delete_phone_spec.rb +4 -4
  41. data/spec/{sms_aero/operations → operations}/send_sms_spec.rb +49 -11
  42. data/spec/spec_helper.rb +4 -1
  43. data/spec/support/en.yml +8 -0
  44. metadata +61 -101
  45. data/lib/sms_aero/models/answer.rb +0 -8
  46. data/lib/sms_aero/models/sms.rb +0 -16
  47. data/lib/sms_aero/models/tariff.rb +0 -8
  48. data/lib/sms_aero/operations/add_blacklist.rb +0 -11
  49. data/lib/sms_aero/operations/add_group.rb +0 -11
  50. data/lib/sms_aero/operations/add_phone.rb +0 -17
  51. data/lib/sms_aero/operations/check_balance.rb +0 -11
  52. data/lib/sms_aero/operations/check_groups.rb +0 -12
  53. data/lib/sms_aero/operations/check_senders.rb +0 -15
  54. data/lib/sms_aero/operations/check_sending.rb +0 -11
  55. data/lib/sms_aero/operations/check_sign.rb +0 -15
  56. data/lib/sms_aero/operations/check_status.rb +0 -11
  57. data/lib/sms_aero/operations/check_tariff.rb +0 -12
  58. data/lib/sms_aero/operations/delete_group.rb +0 -11
  59. data/lib/sms_aero/operations/delete_phone.rb +0 -12
  60. data/lib/sms_aero/operations/hlr.rb +0 -36
  61. data/lib/sms_aero/operations/send_sms.rb +0 -22
  62. data/lib/sms_aero/operations/send_to_group.rb +0 -15
  63. data/lib/sms_aero/types/birthday.rb +0 -20
  64. data/lib/sms_aero/types/channel.rb +0 -4
  65. data/lib/sms_aero/types/digital.rb +0 -8
  66. data/lib/sms_aero/types/filled_string.rb +0 -3
  67. data/lib/sms_aero/types/future.rb +0 -16
  68. data/lib/sms_aero/types/password.rb +0 -6
  69. data/lib/sms_aero/types/phone.rb +0 -12
  70. data/lib/sms_aero/types/sign_status.rb +0 -9
  71. data/spec/sms_aero/operations/hlr_spec.rb +0 -96
  72. data/spec/sms_aero/operations/send_to_group_spec.rb +0 -185
  73. data/spec/sms_aero/types/sign_status_spec.rb +0 -19
@@ -1,8 +0,0 @@
1
- class SmsAero
2
- class Answer < Evil::Struct
3
- attribute :reason, default: proc { nil }
4
- attribute :result,
5
- Types::FilledString.constructor(&:strip),
6
- default: proc { "accepted" }
7
- end
8
- end
@@ -1,16 +0,0 @@
1
- # Describes an SMS that can be send to either a phone or a group
2
- class SmsAero
3
- class Sms < Evil::Struct
4
- attribute :from, Types::FilledString
5
- attribute :text, Types::FilledString
6
- attribute :date, Types::Future, optional: true
7
- attribute :digital, Types::Digital, optional: true
8
- attribute :type, Types::Channel, default: -> (*) do
9
- if digital == 1
10
- Dry::Initializer::UNDEFINED
11
- else
12
- 2
13
- end
14
- end
15
- end
16
- end
@@ -1,8 +0,0 @@
1
- class SmsAero
2
- class Tariff < Evil::Struct
3
- attributes type: Types::Coercible::Float, optional: true do
4
- attribute :"Direct channel", as: :direct
5
- attribute :"Digital channel", as: :digital
6
- end
7
- end
8
- end
@@ -1,11 +0,0 @@
1
- class SmsAero
2
- operation :add_blacklist do
3
- documentation "https://smsaero.ru/api/description/#balcklist"
4
-
5
- path { "addblacklist" }
6
-
7
- query do
8
- attribute :phone, Types::Phone
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- class SmsAero
2
- operation :add_group do
3
- documentation "https://smsaero.ru/api/description/#groups"
4
-
5
- path { "addgroup" }
6
-
7
- query do
8
- attribute :group, Types::FilledString
9
- end
10
- end
11
- end
@@ -1,17 +0,0 @@
1
- class SmsAero
2
- operation :add_phone do
3
- documentation "https://smsaero.ru/api/description/#contacts"
4
-
5
- path { "addphone" }
6
-
7
- query do
8
- attribute :phone, Types::Phone
9
- attribute :group, Types::FilledString, optional: true
10
- attribute :lname, Types::FilledString, optional: true
11
- attribute :fname, Types::FilledString, optional: true
12
- attribute :sname, Types::FilledString, optional: true
13
- attribute :param, Types::FilledString, optional: true
14
- attribute :bday, Types::Birthday, optional: true
15
- end
16
- end
17
- end
@@ -1,11 +0,0 @@
1
- class SmsAero
2
- operation :check_balance do
3
- documentation "https://smsaero.ru/api/description/#get-balance"
4
-
5
- path { "balance" }
6
-
7
- response :success, 200, format: :json, model: Answer do
8
- attribute :balance, Types::Coercible::Float
9
- end
10
- end
11
- end
@@ -1,12 +0,0 @@
1
- class SmsAero
2
- operation :check_groups do
3
- documentation "https://smsaero.ru/api/description/#groups"
4
-
5
- path { "checkgroup" }
6
-
7
- response :success, 200, format: :json do
8
- attribute :result, Types::FilledString
9
- attribute :reason, Types::Hash, as: :channels
10
- end
11
- end
12
- end
@@ -1,15 +0,0 @@
1
- class SmsAero
2
- operation :check_senders do
3
- documentation "https://smsaero.ru/api/description/#signs"
4
-
5
- path { "senders" }
6
-
7
- query do
8
- attribute :sign, Types::FilledString
9
- end
10
-
11
- response :success, 200, format: :json, model: Answer do
12
- attribute :data, Types::Array.member(Types::FilledString)
13
- end
14
- end
15
- end
@@ -1,11 +0,0 @@
1
- class SmsAero
2
- operation :check_sending do
3
- documentation "https://smsaero.ru/api/description/#check-status"
4
-
5
- path { "checksending" }
6
-
7
- query do
8
- attribute :id, Types::Coercible::String.constrained(filled: true)
9
- end
10
- end
11
- end
@@ -1,15 +0,0 @@
1
- class SmsAero
2
- operation :check_sign do
3
- documentation "https://smsaero.ru/api/description/#signs"
4
-
5
- path { "sign" }
6
-
7
- query do
8
- attribute :sign, Types::FilledString
9
- end
10
-
11
- response :success, 200, format: :json do
12
- attribute :data, Types::Array.member(Types::SignStatus), as: :statuses
13
- end
14
- end
15
- end
@@ -1,11 +0,0 @@
1
- class SmsAero
2
- operation :check_status do
3
- documentation "https://smsaero.ru/api/description/#check-status"
4
-
5
- path { "status" }
6
-
7
- query do
8
- attribute :id, Types::Coercible::String.constrained(filled: true)
9
- end
10
- end
11
- end
@@ -1,12 +0,0 @@
1
- class SmsAero
2
- operation :check_tariff do
3
- documentation "https://smsaero.ru/api/description/#get-balance"
4
-
5
- path { "checktarif" }
6
-
7
- response :success, 200, format: :json do
8
- attribute :result, Types::FilledString
9
- attribute :reason, Tariff, as: :tariff
10
- end
11
- end
12
- end
@@ -1,11 +0,0 @@
1
- class SmsAero
2
- operation :delete_group do
3
- documentation "https://smsaero.ru/api/description/#groups"
4
-
5
- path { "delgroup" }
6
-
7
- query do
8
- attribute :group, Types::FilledString
9
- end
10
- end
11
- end
@@ -1,12 +0,0 @@
1
- class SmsAero
2
- operation :delete_phone do
3
- documentation "https://smsaero.ru/api/description/#contacts"
4
-
5
- path { "delphone" }
6
-
7
- query do
8
- attribute :phone, Types::Phone
9
- attribute :group, Types::FilledString, optional: true
10
- end
11
- end
12
- end
@@ -1,36 +0,0 @@
1
- class SmsAero
2
- HLR_STATUSES = {
3
- 1 => :available,
4
- 2 => :unavailable,
5
- 3 => :nonexistent
6
- }.freeze
7
-
8
- operation :hlr do
9
- documentation "https://smsaero.ru/api/description/#hlr"
10
-
11
- path { "hlr" }
12
-
13
- query { attribute :phone, Types::Phone }
14
-
15
- response :success, 200, format: :json, model: Answer do
16
- attribute :id, proc(&:to_s)
17
- attribute :success, default: proc { id != "" }
18
- end
19
-
20
- response :failure, 200, format: :json, model: Answer do
21
- attribute :success, default: proc { false }
22
- end
23
- end
24
-
25
- operation :hlr_status do
26
- documentation "https://smsaero.ru/api/description/#hlr"
27
-
28
- path { "hlrStatus" }
29
-
30
- query { attribute :id, Types::Coercible::String.constrained(filled: true) }
31
-
32
- response :success, 200, format: :json, model: Answer do
33
- attribute :status, -> (s) { HLR_STATUSES[s.to_i] }
34
- end
35
- end
36
- end
@@ -1,22 +0,0 @@
1
- class SmsAero
2
- operation :send_sms do |settings|
3
- documentation "https://smsaero.ru/api/description/#send-sms"
4
-
5
- path do |test: false, **|
6
- settings.test || test ? "testsend" : "send"
7
- end
8
-
9
- query model: Sms do
10
- attribute :to, Types::Phone
11
- end
12
-
13
- response :success, 200, format: :json, model: Answer do
14
- attribute :id, proc(&:to_s)
15
- attribute :success, default: proc { id != "" }
16
- end
17
-
18
- response :failure, 200, format: :json, model: Answer do
19
- attribute :success, default: proc { false }
20
- end
21
- end
22
- end
@@ -1,15 +0,0 @@
1
- class SmsAero
2
- operation :send_to_group do
3
- documentation "https://smsaero.ru/api/description/#send-sms"
4
-
5
- path { "sendtogroup" }
6
-
7
- query model: Sms do
8
- attribute :group, Types::FilledString, default: proc { "all" }
9
- end
10
-
11
- response :success, 200, format: :json, model: Answer do
12
- attribute :id, Types::Coercible::String, optional: true
13
- end
14
- end
15
- end
@@ -1,20 +0,0 @@
1
- module SmsAero::Types
2
- # Describes a user's birthday in year-month-date format
3
- # Accepts dates, times, datetimes, and strings parceable to dates
4
- #
5
- # @example
6
- # SmsAero::Types::Birthday["1901-12-9"] # => "1901-12-09"
7
- # SmsAero::Types::Birthday[Time.new(1901, 12, 9, 10, 12)] # => "1901-12-09"
8
- #
9
- Birthday = Strict::String
10
- .constrained(format: /\A\d{4}-\d{2}-\d{2}\z/)
11
- .constructor do |value|
12
- begin
13
- date = value.to_date if value.respond_to? :to_date
14
- date ||= ::Date.parse(value.to_s)
15
- date.strftime "%Y-%m-%d"
16
- rescue StandardError
17
- raise TypeError, "#{value.inspect} cannot be coerced to date"
18
- end
19
- end
20
- end
@@ -1,4 +0,0 @@
1
- module SmsAero::Types
2
- # Describes acceptable channel codes
3
- Channel = Coercible::Int.constrained included_in: [1, 2, 3, 4, 6]
4
- end
@@ -1,8 +0,0 @@
1
- module SmsAero::Types
2
- # Converts any value to either 1 or 0 flag for digital sending channel
3
- #
4
- # @example
5
- # SmsAero::Types::Digital[true] # => 1
6
- #
7
- Digital = Strict::Int.constructor { |value| value ? 1 : 0 }
8
- end
@@ -1,3 +0,0 @@
1
- module SmsAero::Types
2
- FilledString = Coercible::String.constrained(filled: true)
3
- end
@@ -1,16 +0,0 @@
1
- module SmsAero::Types
2
- # Describes coercible Unix time in future
3
- Future = Strict::Int.constructor do |value|
4
- begin
5
- error = TypeError.new "#{value.inspect} is not a valid time in future"
6
-
7
- time = value.to_time if value.respond_to? :to_time
8
- time ||= ::Time.parse(value.to_s) unless value.is_a? Numeric
9
- number = time.to_i
10
-
11
- number > ::Time.now.to_i ? number : raise(error)
12
- rescue StandardError
13
- raise error
14
- end
15
- end
16
- end
@@ -1,6 +0,0 @@
1
- module SmsAero::Types
2
- Password = \
3
- Strict::String.constructor do |value|
4
- OpenSSL::Digest::MD5.new.hexdigest(value)
5
- end
6
- end
@@ -1,12 +0,0 @@
1
- module SmsAero::Types
2
- # Describes a valid phone containing digits without lead zeros
3
- #
4
- # @example
5
- # SmsAero::Types::Phone["07 (123) 134-12-08"] # => "71231341208"
6
- # SmsAero::Types::Phone["008"] # raises #<Dry::Types::ConstraintError ...>
7
- #
8
- Phone = Strict::String.constrained(format: /\A\d{11,13}\z/)
9
- .constructor do |value|
10
- value.to_s.scan(/\d/).join[/[^0].*/].to_s
11
- end
12
- end
@@ -1,9 +0,0 @@
1
- module SmsAero::Types
2
- # Describes statuses of the sign
3
- SignStatus = Strict::String.constrained included_in: %w(
4
- accepted
5
- approved
6
- rejected
7
- pending
8
- )
9
- end
@@ -1,96 +0,0 @@
1
- describe SmsAero do
2
- let(:settings) { { user: "LOGIN", password: "PASSWORD" } }
3
- let(:client) { described_class.new(settings) }
4
-
5
- before { stub_request(:any, //).to_return(body: answer.to_json) }
6
-
7
- describe "#hlr" do
8
- let(:params) { { phone: "+7(002)034-5678" } }
9
- let(:answer) { { result: "accepted", id: 123 } }
10
- let(:url) do
11
- "https://gate.smsaero.ru/hlr?answer=json&user=LOGIN&" \
12
- "password=319f4d26e3c536b5dd871bb2c52e3178&phone=70020345678"
13
- end
14
-
15
- subject { client.hlr params }
16
-
17
- it "sends a request" do
18
- subject
19
- expect(a_request(:post, url)).to have_been_made
20
- end
21
-
22
- it "returns success" do
23
- expect(subject).to be_kind_of SmsAero::Answer
24
- expect(subject.result).to eq "accepted"
25
- expect(subject.id).to eq "123"
26
- end
27
-
28
- context "with invalid phone" do
29
- let(:params) { { phone: "123" } }
30
-
31
- it "raises an exception" do
32
- expect { subject }.to raise_error(TypeError, /123/)
33
- end
34
- end
35
-
36
- context "without a phone" do
37
- let(:params) { {} }
38
-
39
- it "raises an exception" do
40
- expect { subject }.to raise_error(ArgumentError)
41
- end
42
- end
43
-
44
- context "when rejected" do
45
- let(:answer) { { result: "rejected" } }
46
-
47
- it "has success false" do
48
- expect(subject.success).to be_falsey
49
- end
50
- end
51
- end
52
-
53
- describe "#hlr_status" do
54
- let(:params) { { id: 1 } }
55
- let(:status) { 1 }
56
- let(:answer) { { result: "accepted", status: status } }
57
- let(:url) do
58
- "https://gate.smsaero.ru/hlrStatus?answer=json&user=LOGIN&" \
59
- "password=319f4d26e3c536b5dd871bb2c52e3178&id=1"
60
- end
61
-
62
- subject { client.hlr_status params }
63
-
64
- it "sends a request" do
65
- subject
66
- expect(a_request(:post, url)).to have_been_made
67
- end
68
-
69
- it "returns success" do
70
- expect(subject).to be_kind_of SmsAero::Answer
71
- expect(subject.result).to eq "accepted"
72
- end
73
-
74
- it "converts status to sym" do
75
- expect(subject.status).to eq :available
76
- end
77
-
78
- context "other statuses" do
79
- context "unavailable" do
80
- let(:status) { 2 }
81
-
82
- it "converts status to sym" do
83
- expect(subject.status).to eq :unavailable
84
- end
85
- end
86
-
87
- context "nonexistent" do
88
- let(:status) { 3 }
89
-
90
- it "converts status to sym" do
91
- expect(subject.status).to eq :nonexistent
92
- end
93
- end
94
- end
95
- end
96
- end