deathbycaptcha 5.0.2 → 5.2.0

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
- SHA1:
3
- metadata.gz: d578d0181a5e858098bc2329884daff5971f7bbd
4
- data.tar.gz: b2681b030c07099cc78cb52dfc4382c6015d64b6
2
+ SHA256:
3
+ metadata.gz: b7b0ae41ffa4cc961dc9600c23ec9f0e56bf09261fa4766ed2aa1cd686a2a09f
4
+ data.tar.gz: 87885c289fce41e9a34696514dc067b62b025a45e89f7728aaf28146beba4111
5
5
  SHA512:
6
- metadata.gz: 1eaf72f64a8b7e83d4e7b6933d17d3d48ea14a890cae901c1aa1f3e9693f7bbdac4e85ad23ba075010714a166946668fb60cd8032aa4d3814a31cf228e80a66c
7
- data.tar.gz: 2628bb9faeba7ee4e1438d307d3a20357bb69f3b2195afbf804add2c9d1979f48ddbc719c6f01d084e38572c76ec03b7d623f56d96733eec784d96a5e056a327
6
+ metadata.gz: 926bfd8b477e4d3888947bfca51521402c0f170c04fb70244b31fc9fa8aea47904f00587ea9f95fe9c9cb62c1c6780164aa59ef1bed19e0ac9e232adf01690a7
7
+ data.tar.gz: 72925f985964bf277675ebc86373871f0a3c865eb7996b0eb73bde1900d14d4d8e7b3765d1ced32979c0baae3bed7d762ca8d56de9273ed48e3d42e4452c5251
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015 Rafael Barbolo
1
+ Copyright (c) 2015 Infosimples
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  Developed by [Infosimples](https://infosimples.com), a brazilian company that
2
- offers [data extraction solutions](https://infosimples.com/en/data-engineering)
3
- and [Ruby on Rails development](https://infosimples.com/en/software-development).
2
+ offers [data extraction solutions](https://infosimples.com/en/data-engineering).
3
+
4
+ We suggest you to also check [2Captcha.com](http://2captcha.com/?from=1025109)
5
+ for a cheaper service. You can find it's gem fully compatible with the
6
+ deathbycaptcha gem at https://github.com/infosimples/two_captcha.
7
+
8
+ [Contact us](https://infosimples.com/en) if you need enterprise services for
9
+ CAPTCHAs solving or Internet automation.
4
10
 
5
11
 
6
12
  # DeathByCaptcha
@@ -24,14 +30,12 @@ Or install it yourself as:
24
30
 
25
31
  $ gem install deathbycaptcha
26
32
 
27
-
28
33
  ## Usage
29
34
 
30
35
  1. **Create a client**
31
36
 
32
37
  ```ruby
33
38
  # Create a client (:socket and :http clients are available)
34
- #
35
39
  client = DeathByCaptcha.new('myusername', 'mypassword', :http)
36
40
  ```
37
41
 
@@ -44,7 +48,7 @@ Or install it yourself as:
44
48
  If the solution is not available, an empty captcha object will be returned.
45
49
 
46
50
  ```ruby
47
- captcha = client.decode(url: 'http://bit.ly/1xXZcKo')
51
+ captcha = client.decode!(url: 'http://bit.ly/1xXZcKo')
48
52
  captcha.text # Solution of the captcha
49
53
  captcha.id # Numeric ID of the captcha solved by DeathByCaptcha
50
54
  captcha.is_correct # true if the solution is correct
@@ -53,16 +57,17 @@ Or install it yourself as:
53
57
  You can also specify *path*, *file*, *raw* and *raw64* when decoding an image.
54
58
 
55
59
  ```ruby
56
- client.decode(path: 'path/to/my/captcha/file')
60
+ client.decode!(path: 'path/to/my/captcha/file')
57
61
 
58
- client.decode(file: File.open('path/to/my/captcha/file', 'rb'))
62
+ client.decode!(file: File.open('path/to/my/captcha/file', 'rb'))
59
63
 
60
- client.decode(raw: File.open('path/to/my/captcha/file', 'rb').read)
64
+ client.decode!(raw: File.open('path/to/my/captcha/file', 'rb').read)
61
65
 
62
- client.decode(raw64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
66
+ client.decode!(raw64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
63
67
  ```
64
68
 
65
- > Internally, the gem will always convert the image to raw64 (binary base64 encoded).
69
+ > Internally, the gem will always convert any image to raw64 (binary base64
70
+ encoded).
66
71
 
67
72
  3. **Retrieve a previously solved captcha**
68
73
 
@@ -97,6 +102,135 @@ Or install it yourself as:
97
102
  status.is_service_overloaded # true if DeathByCaptcha is overloaded/unresponsive
98
103
  ```
99
104
 
105
+ ## New reCAPTCHA
106
+
107
+ > It's currently available only with the :http client.
108
+
109
+ To solve captchas similar to
110
+ [reCAPTCHA v2](https://support.google.com/recaptcha/?hl=en#6262736), you can use
111
+ both the DeathByCaptcha's **Coordinates API** or **Image Group API**.
112
+
113
+ Please, read the oficial documentation at
114
+ http://www.deathbycaptcha.com/user/api/newrecaptcha.
115
+
116
+ ### Using the Coordinates API
117
+
118
+ ```ruby
119
+ # Read above all the instructions on how to solve a captcha.
120
+ captcha = client.decode!(type: 2, url: 'http://bit.ly/1VCUuzk')
121
+ ```
122
+
123
+ You should specify arguments with *type = 2* and an image similar to a screenshot of
124
+ the captcha. See an example:
125
+
126
+ **Captcha (screenshot)**
127
+
128
+ > the argument is passed as *url*, *path*, *file*, *raw* or *raw64*
129
+
130
+ ![Example of a captcha based on image clicks](captchas/2.jpg)
131
+
132
+ The response will be an array containing coordinates (x, y) where the human
133
+ clicked to solve the captcha. For the captcha above it should look something
134
+ like:
135
+
136
+ ```ruby
137
+ # captcha.text
138
+ "[[30,143],[241,325]]"
139
+
140
+ # captcha.coordinates
141
+ [[30, 143], [241, 325]]
142
+ ```
143
+
144
+ ### Using the Image Group API
145
+
146
+ ```ruby
147
+ # Read above all the instructions on how to solve a captcha.
148
+ captcha = client.decode!(
149
+ type: 3,
150
+ url: 'http://bit.ly/1i1CIaB', # single image with the clickable grid
151
+ banner: { url: 'http://bit.ly/1JTG4T3' }, # the banner image
152
+ banner_text: 'Click all images with bananas' # the banner text
153
+ )
154
+ ```
155
+
156
+ You should specify arguments with *type = 3* and the decomposed captcha as seen in the
157
+ example below:
158
+
159
+ **Captcha: images grid**
160
+
161
+ > the argument is passed as *url*, *path*, *file*, *raw* or *raw64*
162
+
163
+ ![Example of a grid of a captcha based on image clicks](captchas/3-grid.jpg)
164
+
165
+ **Captcha: banner**
166
+
167
+ ![Example of a banner of a captcha based on image clicks](captchas/3-banner.jpg)
168
+
169
+ **Captcha: banner text**
170
+
171
+ > Click all images with bananas
172
+
173
+ The response will be an array containing the indexes for each image that should
174
+ be clicked counting from left to right. For the captcha above it should look
175
+ something like:
176
+
177
+ ```ruby
178
+ # captcha.text
179
+ "[1,9]"
180
+
181
+ # captcha.indexes
182
+ [1, 9]
183
+ ```
184
+
185
+ ## New Recaptcha by Token API
186
+
187
+ > It's currently available only with the :http client.
188
+
189
+ To solve captchas similar to
190
+ [reCAPTCHA v2](https://support.google.com/recaptcha/?hl=en#6262736), you can also use
191
+ **Token API**
192
+
193
+ Please, read the oficial documentation at
194
+ http://deathbycaptcha.com/user/api/newtokenrecaptcha
195
+
196
+ ### Using the Token API
197
+
198
+ ```ruby
199
+ # Read above all the instructions on how to solve a captcha.
200
+ captcha = client.decode!(type: 4, token_params: {
201
+ # optional proxy if needed and server verifies
202
+ #proxy: "http://127.0.0.1:3128",
203
+ #proxytype: "HTTP",
204
+ googlekey: "6Ld2sf4SAAAAAKSgzs0Q13IZhY02Pyo31S2jgOB5",
205
+ pageurl: "https://patrickhlauke.github.io/recaptcha/"
206
+ })
207
+ ```
208
+
209
+ You should specify arguments with *type = 4* and an all token params required by DBC API
210
+
211
+ The response will be a text (token), which you can access with **text** or **token** method.
212
+
213
+ ```ruby
214
+ # captcha.text
215
+ "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd
216
+ saD2H0e6S3547xi1FlqJB4rob46J0-wfZMj6YpyVa0WGCfpWzBWcLn7tO_EYs
217
+ vEC_3kfLNINWa5LnKrnJTDXTOz-JuCKvEXx0EQqzb0OU4z2np4uyu79lc_Ndv
218
+ L0IRFc3Cslu6UFV04CIfqXJBWCE5MY0Ag918r14b43ZdpwHSaVVrUqzCQMCyb
219
+ cGq0yxLQf9eSexFiAWmcWLI5nVNA81meTXhQlyCn5bbbI2IMSEErDqceZjf1m
220
+ X3M67BhIb4"
221
+
222
+ # captcha.token
223
+ "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd
224
+ saD2H0e6S3547xi1FlqJB4rob46J0-wfZMj6YpyVa0WGCfpWzBWcLn7tO_EYs
225
+ vEC_3kfLNINWa5LnKrnJTDXTOz-JuCKvEXx0EQqzb0OU4z2np4uyu79lc_Ndv
226
+ L0IRFc3Cslu6UFV04CIfqXJBWCE5MY0Ag918r14b43ZdpwHSaVVrUqzCQMCyb
227
+ cGq0yxLQf9eSexFiAWmcWLI5nVNA81meTXhQlyCn5bbbI2IMSEErDqceZjf1m
228
+ X3M67BhIb4"
229
+ ```
230
+
231
+ > Those captchas sometimes took more than 60 seconds to solve
232
+ > So consider increasing the client's *timeout*
233
+
100
234
  ## Notes
101
235
 
102
236
  #### Thread-safety
@@ -121,7 +255,7 @@ firewall.
121
255
  #### Ruby dependencies
122
256
 
123
257
  DeathByCaptcha >= 5.0.0 don't require specific dependencies. That saves you
124
- memmory and avoid conflicts with other gems.
258
+ memory and avoid conflicts with other gems.
125
259
 
126
260
  #### Input image format
127
261
 
@@ -131,7 +265,7 @@ you already have this format available on your side, there's no need to do
131
265
  convertions before calling the API.
132
266
 
133
267
  > Our recomendation is to never convert your image format, unless needed. Let
134
- > the gem convert internally. It may save you resources (CPU, memmory and IO).
268
+ > the gem convert internally. It may save you resources (CPU, memory and IO).
135
269
 
136
270
  #### Versioning
137
271
 
@@ -153,13 +287,6 @@ This gem has been tested on the following versions of Ruby:
153
287
  * MRI 2.0.0
154
288
  * MRI 1.9.3
155
289
 
156
- # Maintainers
157
-
158
- * [Débora Setton Fernandes](http://github.com/deborasetton)
159
- * [Rafael Barbolo](http://github.com/barbolo)
160
- * [Rafael Ivan Garcia](http://github.com/rafaelivan)
161
-
162
-
163
290
  ## Contributing
164
291
 
165
292
  1. Fork it ( https://github.com/infosimples/deathbycaptcha/fork )
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "deathbycaptcha"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
Binary file
Binary file
Binary file
@@ -6,7 +6,7 @@ require 'deathbycaptcha/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "deathbycaptcha"
8
8
  spec.version = DeathByCaptcha::VERSION
9
- spec.authors = ["Débora Setton Fernandes, Rafael Barbolo, Rafael Ivan Garcia"]
9
+ spec.authors = ["Rafael Barbolo, Rafael Ivan Garcia"]
10
10
  spec.email = ["team@infosimples.com.br"]
11
11
  spec.summary = %q{Ruby API for DeathByCaptcha (Captcha Solver as a Service)}
12
12
  spec.description = %q{DeathByCaptcha allows you to solve captchas with manual labor}
@@ -14,7 +14,11 @@ Gem::Specification.new do |spec|
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+
18
+ # Since our currently binstubs are used only during the gem's development, we
19
+ # are ignoring them in the gem specification.
20
+ # spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+
18
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
23
  spec.require_paths = ["lib"]
20
24
 
@@ -1,4 +1,5 @@
1
1
  require 'base64'
2
+ require 'openssl'
2
3
  require 'json'
3
4
  require 'bigdecimal'
4
5
  require 'socket'
@@ -12,7 +12,7 @@ module DeathByCaptcha
12
12
  #
13
13
  class Client
14
14
 
15
- attr_accessor :username, :password, :timeout, :polling
15
+ attr_accessor :username, :password, :timeout, :polling, :hostname
16
16
 
17
17
  # Create a DeathByCaptcha API client
18
18
  #
@@ -43,6 +43,7 @@ module DeathByCaptcha
43
43
  # @param [Hash] options Options hash.
44
44
  # @option options [Integer] :timeout (60) Seconds before giving up.
45
45
  # @option options [Integer] :polling (5) Seconds for polling the solution.
46
+ # @option options [String] :hostname ('api.dbcapi.me') Custom API hostname.
46
47
  #
47
48
  # @return [DeathByCaptcha::Client] A Client instance.
48
49
  #
@@ -51,6 +52,7 @@ module DeathByCaptcha
51
52
  self.password = password
52
53
  self.timeout = options[:timeout] || 60
53
54
  self.polling = options[:polling] || 5
55
+ self.hostname = options[:hostname] || 'api.dbcapi.me'
54
56
  end
55
57
 
56
58
  # Decode the text from an image (i.e. solve a captcha).
@@ -84,19 +86,24 @@ module DeathByCaptcha
84
86
  def decode!(options = {})
85
87
  started_at = Time.now
86
88
 
87
- raw64 = load_captcha(options)
88
- raise DeathByCaptcha::InvalidCaptcha if raw64.to_s.empty?
89
+ # don't load image data for Token API v2 & v3
90
+ raw64 = nil
91
+ unless [4, 5].include? options[:type]
92
+ raw64 = load_captcha(options)
93
+ raise DeathByCaptcha::InvalidCaptcha if raw64.to_s.empty?
94
+ end
95
+
96
+ decoded_captcha = self.upload(options.merge(raw64: raw64))
89
97
 
90
- _captcha = self.upload(raw64)
91
- while _captcha.text.to_s.empty?
98
+ while decoded_captcha.text.to_s.empty?
92
99
  sleep(self.polling)
93
- _captcha = self.captcha(_captcha.id)
100
+ decoded_captcha = self.captcha(decoded_captcha.id)
94
101
  raise DeathByCaptcha::Timeout if (Time.now - started_at) > self.timeout
95
102
  end
96
103
 
97
- raise DeathByCaptcha::IncorrectSolution if !_captcha.is_correct
104
+ raise DeathByCaptcha::IncorrectSolution if !decoded_captcha.is_correct
98
105
 
99
- _captcha
106
+ decoded_captcha
100
107
  end
101
108
 
102
109
  # Retrieve information from an uploaded captcha.
@@ -3,9 +3,6 @@ module DeathByCaptcha
3
3
  # HTTP client for DeathByCaptcha API.
4
4
  #
5
5
  class Client::HTTP < Client
6
-
7
- BASE_URL = 'http://api.dbcapi.me/api'
8
-
9
6
  # Retrieve information from an uploaded captcha.
10
7
  #
11
8
  # @param [Integer] captcha_id Numeric ID of the captcha.
@@ -53,8 +50,26 @@ module DeathByCaptcha
53
50
  #
54
51
  # @return [DeathByCaptcha::Captcha] The captcha object (not solved yet).
55
52
  #
56
- def upload(raw64)
57
- response = perform('captcha', :post_multipart, captchafile: "base64:#{raw64}")
53
+ def upload(options = {})
54
+ payload = {}
55
+ payload[:captchafile] = "base64:#{options[:raw64]}"
56
+ payload[:type] = options[:type] if options[:type].to_i > 0
57
+
58
+ if options[:type].to_i == 3
59
+ banner64 = load_captcha(options[:banner])
60
+ raise DeathByCaptcha::InvalidCaptcha if banner64.to_s.empty?
61
+
62
+ payload[:banner] = "base64:#{banner64}"
63
+ payload[:banner_text] = options[:banner_text].to_s
64
+
65
+ elsif [4, 5].include? options[:type].to_i
66
+ payload = {
67
+ type: options[:type].to_i,
68
+ token_params: options[:token_params].to_json,
69
+ }
70
+ end
71
+
72
+ response = perform('captcha', :post_multipart, payload)
58
73
  DeathByCaptcha::Captcha.new(response)
59
74
  end
60
75
 
@@ -74,19 +89,18 @@ module DeathByCaptcha
74
89
  headers = { 'User-Agent' => DeathByCaptcha::API_VERSION }
75
90
 
76
91
  if method == :post
77
- uri = URI("#{BASE_URL}/#{action}")
92
+ uri = URI("http://#{self.hostname}/api/#{action}")
78
93
  req = Net::HTTP::Post.new(uri.request_uri, headers)
79
94
  req.set_form_data(payload)
80
95
 
81
96
  elsif method == :post_multipart
82
- uri = URI("#{BASE_URL}/#{action}")
97
+ uri = URI("http://#{self.hostname}/api/#{action}")
83
98
  req = Net::HTTP::Post.new(uri.request_uri, headers)
84
99
  boundary, body = prepare_multipart_data(payload)
85
100
  req.content_type = "multipart/form-data; boundary=#{boundary}"
86
101
  req.body = body
87
-
88
102
  else
89
- uri = URI("#{BASE_URL}/#{action}?#{URI.encode_www_form(payload)}")
103
+ uri = URI("http://#{self.hostname}/api/#{action}?#{URI.encode_www_form(payload)}")
90
104
  req = Net::HTTP::Get.new(uri.request_uri, headers)
91
105
  end
92
106
 
@@ -4,7 +4,6 @@ module DeathByCaptcha
4
4
  #
5
5
  class Client::Socket < Client
6
6
 
7
- HOST = 'api.dbcapi.me'
8
7
  PORTS = (8123..8130).to_a
9
8
 
10
9
  # Retrieve information from an uploaded captcha.
@@ -54,8 +53,12 @@ module DeathByCaptcha
54
53
  #
55
54
  # @return [DeathByCaptcha::Captcha] The captcha object (not solved yet).
56
55
  #
57
- def upload(raw64)
58
- response = perform('upload', captcha: raw64)
56
+ def upload(options = {})
57
+ if options[:type] && options[:type].to_i != 1
58
+ # Socket client implementation currently supports only text captchas.
59
+ raise DeathByCaptcha::InvalidCaptcha
60
+ end
61
+ response = perform('upload', captcha: options[:raw64])
59
62
  DeathByCaptcha::Captcha.new(response)
60
63
  end
61
64
 
@@ -112,7 +115,7 @@ module DeathByCaptcha
112
115
  #
113
116
  def create_socket
114
117
  socket = ::Socket.new(::Socket::AF_INET, ::Socket::SOCK_STREAM, 0)
115
- sockaddr = ::Socket.sockaddr_in(PORTS.sample, HOST)
118
+ sockaddr = ::Socket.sockaddr_in(PORTS.sample, self.hostname)
116
119
  begin # emulate blocking connect
117
120
  socket.connect_nonblock(sockaddr)
118
121
  rescue IO::WaitWritable
@@ -16,5 +16,14 @@ module DeathByCaptcha
16
16
  def captcha=(value)
17
17
  @captcha = value.to_i
18
18
  end
19
+
20
+ def parsed_text
21
+ JSON.parse(text)
22
+ rescue
23
+ []
24
+ end
25
+ alias_method :coordinates, :parsed_text
26
+ alias_method :indexes, :parsed_text
27
+ alias_method :token, :text
19
28
  end
20
29
  end
@@ -1,4 +1,4 @@
1
1
  module DeathByCaptcha
2
- VERSION = "5.0.2"
2
+ VERSION = "5.2.0"
3
3
  API_VERSION = "DBC/Ruby v#{VERSION}"
4
4
  end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ username = CREDENTIALS['username']
4
+ password = CREDENTIALS['password']
5
+ path2 = './captchas/2.jpg' # path of the captcha (Coordinates API)
6
+ path3_grid = './captchas/3-grid.jpg' # path of the grid (Image Group API)
7
+ path3_banner = './captchas/3-banner.jpg' # path of the grid (Image Group API)
8
+ banner_text3 = 'Click all images with bananas'
9
+ token_params = {
10
+ #proxy: "http://127.0.0.1:3128",
11
+ #proxytype: "HTTP",
12
+ googlekey: "6Ld2sf4SAAAAAKSgzs0Q13IZhY02Pyo31S2jgOB5",
13
+ pageurl: "https://patrickhlauke.github.io/recaptcha/"
14
+ }
15
+
16
+ describe 'Solving an image based captcha' do
17
+ before(:all) { @client = DeathByCaptcha.new(username, password, :http) }
18
+
19
+ context 'Coordinates API' do
20
+ describe '#decode!' do
21
+ before(:all) { @captcha = @client.decode!(type: 2, path: path2) }
22
+ it { expect(@captcha).to be_a(DeathByCaptcha::Captcha) }
23
+ it { expect(@captcha.text).to match(/\A\[\[.*\]\]\Z/) }
24
+ it { expect(@captcha.coordinates).to be_a(Array) }
25
+ it { expect(@captcha.coordinates.size).to be > 0 }
26
+ it 'expect coordinates to be valid' do
27
+ @captcha.coordinates.each do |coordinate|
28
+ expect(coordinate).to be_a(Array)
29
+ expect(coordinate.size).to eq(2)
30
+ end
31
+ end
32
+ it { expect(@captcha.is_correct).to be true }
33
+ it { expect(@captcha.id).to be > 0 }
34
+ it { expect(@captcha.id).to eq(@captcha.captcha) }
35
+ end
36
+ end
37
+
38
+ context 'Image Group API' do
39
+ describe '#decode!' do
40
+ before(:all) do
41
+ @captcha = @client.decode!(
42
+ type: 3,
43
+ path: path3_grid,
44
+ banner: { path: path3_banner },
45
+ banner_text: banner_text3
46
+ )
47
+ end
48
+ it { expect(@captcha).to be_a(DeathByCaptcha::Captcha) }
49
+ it { expect(@captcha.text).to match(/\A\[.*\]\Z/) }
50
+ it { expect(@captcha.indexes).to be_a(Array) }
51
+ it { expect(@captcha.indexes.size).to be > 0 }
52
+ it 'expect indexes to be valid' do
53
+ @captcha.indexes.each do |index|
54
+ expect(index).to be_a(Numeric)
55
+ end
56
+ end
57
+ it { expect(@captcha.is_correct).to be true }
58
+ it { expect(@captcha.id).to be > 0 }
59
+ it { expect(@captcha.id).to eq(@captcha.captcha) }
60
+ end
61
+ end
62
+
63
+ context 'Token API' do
64
+ describe '#decode!' do
65
+ before(:all) do
66
+ @captcha = @client.decode!(
67
+ type: 4,
68
+ token_params: token_params,
69
+ )
70
+ end
71
+ it { expect(@captcha).to be_a(DeathByCaptcha::Captcha) }
72
+ it { expect(@captcha.text).to eq(@captcha.token) }
73
+ it { expect(@captcha.token).to match(/\A"?\S+"?\Z/) }
74
+ it { expect(@captcha.token.size).to be > 30 }
75
+ it { expect(@captcha.is_correct).to be true }
76
+ it { expect(@captcha.id).to be > 0 }
77
+ it { expect(@captcha.id).to eq(@captcha.captcha) }
78
+ end
79
+ end
80
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deathbycaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.2
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - Débora Setton Fernandes, Rafael Barbolo, Rafael Ivan Garcia
8
- autorequire:
7
+ - Rafael Barbolo, Rafael Ivan Garcia
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-26 00:00:00.000000000 Z
11
+ date: 2020-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,7 +65,12 @@ files:
65
65
  - LICENSE.txt
66
66
  - README.md
67
67
  - Rakefile
68
+ - bin/console
69
+ - bin/setup
68
70
  - captchas/1.png
71
+ - captchas/2.jpg
72
+ - captchas/3-banner.jpg
73
+ - captchas/3-grid.jpg
69
74
  - deathbycaptcha.gemspec
70
75
  - lib/deathbycaptcha.rb
71
76
  - lib/deathbycaptcha/client.rb
@@ -80,12 +85,13 @@ files:
80
85
  - lib/deathbycaptcha/version.rb
81
86
  - spec/credentials.yml.example
82
87
  - spec/lib/client_spec.rb
88
+ - spec/lib/image_captcha_spec.rb
83
89
  - spec/spec_helper.rb
84
90
  homepage: https://github.com/infosimples/deathbycaptcha
85
91
  licenses:
86
92
  - MIT
87
93
  metadata: {}
88
- post_install_message:
94
+ post_install_message:
89
95
  rdoc_options: []
90
96
  require_paths:
91
97
  - lib
@@ -100,12 +106,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
106
  - !ruby/object:Gem::Version
101
107
  version: '0'
102
108
  requirements: []
103
- rubyforge_project:
104
- rubygems_version: 2.4.3
105
- signing_key:
109
+ rubygems_version: 3.1.4
110
+ signing_key:
106
111
  specification_version: 4
107
112
  summary: Ruby API for DeathByCaptcha (Captcha Solver as a Service)
108
113
  test_files:
109
114
  - spec/credentials.yml.example
110
115
  - spec/lib/client_spec.rb
116
+ - spec/lib/image_captcha_spec.rb
111
117
  - spec/spec_helper.rb