captcher 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +210 -0
- data/Rakefile +22 -0
- data/app/controllers/captcher/captchas_controller.rb +22 -0
- data/app/controllers/concerns/captcher/captcha_aware.rb +30 -0
- data/app/helpers/captcher/application_helper.rb +13 -0
- data/app/views/layouts/captcher/application.html.erb +16 -0
- data/config/routes.rb +10 -0
- data/lib/captcher.rb +57 -0
- data/lib/captcher/base_captcha.rb +46 -0
- data/lib/captcher/captchas/awesome_captcha.rb +7 -0
- data/lib/captcher/captchas/code_captcha.rb +40 -0
- data/lib/captcher/captchas/math_captcha.rb +7 -0
- data/lib/captcher/config.rb +41 -0
- data/lib/captcher/engine.rb +5 -0
- data/lib/captcher/text_image.rb +48 -0
- data/lib/captcher/version.rb +3 -0
- data/lib/fonts/Bangers-Regular.ttf +0 -0
- data/lib/fonts/CarterOne.ttf +0 -0
- data/lib/fonts/FrederickatheGreat-Regular.ttf +0 -0
- data/lib/fonts/IndieFlower-Regular.ttf +0 -0
- data/lib/fonts/LobsterTwo-BoldItalic.ttf +0 -0
- data/lib/fonts/SigmarOne-Regular.ttf +0 -0
- data/lib/tasks/captcher_tasks.rake +4 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +4 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +36 -0
- data/spec/dummy/bin/update +31 -0
- data/spec/dummy/bin/yarn +11 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +30 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +61 -0
- data/spec/dummy/config/environments/production.rb +94 -0
- data/spec/dummy/config/environments/test.rb +46 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +34 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +6608 -0
- data/spec/dummy/log/test.log +6492 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/development_secret.txt +1 -0
- data/spec/helpers.rb +23 -0
- data/spec/lib/captcher/config_spec.rb +41 -0
- data/spec/models/captchas/code_captcha_spec.rb +45 -0
- data/spec/rails_helper.rb +72 -0
- data/spec/requests/captcha_management_spec.rb +48 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/tmp/test.png +0 -0
- metadata +291 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/404.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
e6b56e9fe927454594f30c2eae6a83e2787a57acfccf2843484a6e48ace4ec81d95e7b60dd5c56e77baa8671bae8c4544f43e49b97899eb44f1a8ccb29a0e0a1
|
data/spec/helpers.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Helpers
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def save_image(image_data, path)
|
5
|
+
f = File.new(path, encoding: "ascii-8bit", mode: "w")
|
6
|
+
f.binmode
|
7
|
+
f.write(image_data)
|
8
|
+
f.close
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_tmp_dir(options = {})
|
12
|
+
remove_tmp_dir if options[:remove]
|
13
|
+
Dir.mkdir(tmp_dir) unless File.exist?(tmp_dir)
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove_tmp_dir
|
17
|
+
FileUtils.rm_rf(tmp_dir)
|
18
|
+
end
|
19
|
+
|
20
|
+
def tmp_dir
|
21
|
+
@tmp_dir ||= Captcher::Engine.root.join("spec/tmp")
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/BlockLength
|
4
|
+
RSpec.describe Captcher::Config do
|
5
|
+
def init_config(c)
|
6
|
+
c.foo 1
|
7
|
+
c.boo 2
|
8
|
+
c.bar { |b| b.boo { |bb| bb.foo 3 } }
|
9
|
+
end
|
10
|
+
|
11
|
+
def init_config2(c)
|
12
|
+
c.foo 2
|
13
|
+
c.baz 2
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:config) { described_class.new }
|
17
|
+
|
18
|
+
let(:config2) { described_class.new }
|
19
|
+
|
20
|
+
describe "#to_h" do
|
21
|
+
before { init_config(config) }
|
22
|
+
|
23
|
+
it "sets up config and translates it to hash" do
|
24
|
+
expected_result = { foo: 1, boo: 2, bar: { boo: { foo: 3 } } }
|
25
|
+
expect(config.to_h).to eq(expected_result)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#merge" do
|
30
|
+
before do
|
31
|
+
init_config(config)
|
32
|
+
init_config2(config2)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "merges two configs" do
|
36
|
+
expected_result = { foo: 2, boo: 2, baz: 2, bar: { boo: { foo: 3 } } }
|
37
|
+
expect(config.merge(config2)).to eq(expected_result)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
# rubocop:enable Metrics/BlockLength
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
RSpec.describe Captcher::Captchas::CodeCaptcha do
|
4
|
+
let(:config) { Captcher.config }
|
5
|
+
let(:own_config) { config[:code_captcha] }
|
6
|
+
let(:captcha) { described_class.new(config: config) }
|
7
|
+
|
8
|
+
describe "#initialize" do
|
9
|
+
it "receives config for code_captcha" do
|
10
|
+
expect(captcha.own_config).to eq(own_config.with_indifferent_access)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "generates a text when initialized" do
|
14
|
+
expect(captcha.payload.size).to eq(5)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#represent" do
|
19
|
+
let(:raw_image) { captcha.represent(:html) }
|
20
|
+
let(:image_path) { "#{tmp_dir}/test.png" }
|
21
|
+
let(:validate_img) { system("convert #{image_path} -", out: "/dev/null") }
|
22
|
+
|
23
|
+
it "produces a valid png image" do
|
24
|
+
save_image(raw_image, image_path)
|
25
|
+
expect(File).to exist(image_path)
|
26
|
+
expect(validate_img).to eq(true)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#validate" do
|
31
|
+
let(:payload) { "LVsll" }
|
32
|
+
let(:captcha) { described_class.new(config: config, payload: payload) }
|
33
|
+
|
34
|
+
it "accepts a valid confirmation code" do
|
35
|
+
expect(captcha.validate(" LVsll ")).to eq(true)
|
36
|
+
expect(captcha.validate("lvsll")).to eq(true)
|
37
|
+
expect(captcha.validate("LVSLL")).to eq(true)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "declines invalid confirmation code" do
|
41
|
+
expect(captcha.validate("IIIII")).to eq(false)
|
42
|
+
expect(captcha.validate("")).to eq(false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
require "spec_helper"
|
3
|
+
ENV["RAILS_ENV"] ||= "test"
|
4
|
+
require File.expand_path("../dummy/config/environment", __FILE__)
|
5
|
+
# Prevent database truncation if the environment is production
|
6
|
+
abort("The Rails environment is running in production mode!") if Rails.env.production?
|
7
|
+
require "rspec/rails"
|
8
|
+
# Add additional requires below this line. Rails is not loaded until this point!
|
9
|
+
require "helpers"
|
10
|
+
|
11
|
+
# Requires supporting ruby files with custom matchers and macros, etc, in
|
12
|
+
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
|
13
|
+
# run as spec files by default. This means that files in spec/support that end
|
14
|
+
# in _spec.rb will both be required and run as specs, causing the specs to be
|
15
|
+
# run twice. It is recommended that you do not name files matching this glob to
|
16
|
+
# end with _spec.rb. You can configure this pattern with the --pattern
|
17
|
+
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
|
18
|
+
#
|
19
|
+
# The following line is provided for convenience purposes. It has the downside
|
20
|
+
# of increasing the boot-up time by auto-requiring all files in the support
|
21
|
+
# directory. Alternatively, in the individual `*_spec.rb` files, manually
|
22
|
+
# require only the support files necessary.
|
23
|
+
#
|
24
|
+
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
|
25
|
+
|
26
|
+
# Checks for pending migrations and applies them before tests are run.
|
27
|
+
# If you are not using ActiveRecord, you can remove these lines.
|
28
|
+
begin
|
29
|
+
ActiveRecord::Migration.maintain_test_schema!
|
30
|
+
rescue ActiveRecord::PendingMigrationError => e
|
31
|
+
puts e.to_s.strip
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
RSpec.configure do |config|
|
35
|
+
config.include(Helpers)
|
36
|
+
|
37
|
+
config.before(:suite) do
|
38
|
+
Helpers.create_tmp_dir(remove: true)
|
39
|
+
end
|
40
|
+
|
41
|
+
config.after(:suite) do
|
42
|
+
# Helpers.remove_tmp_dir
|
43
|
+
end
|
44
|
+
|
45
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
46
|
+
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
47
|
+
|
48
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
49
|
+
# examples within a transaction, remove the following line or assign false
|
50
|
+
# instead of true.
|
51
|
+
config.use_transactional_fixtures = true
|
52
|
+
|
53
|
+
# RSpec Rails can automatically mix in different behaviours to your tests
|
54
|
+
# based on their file location, for example enabling you to call `get` and
|
55
|
+
# `post` in specs under `spec/controllers`.
|
56
|
+
#
|
57
|
+
# You can disable this behaviour by removing the line below, and instead
|
58
|
+
# explicitly tag your specs with their type, e.g.:
|
59
|
+
#
|
60
|
+
# RSpec.describe UsersController, :type => :controller do
|
61
|
+
# # ...
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# The different available types are documented in the features, such as in
|
65
|
+
# https://relishapp.com/rspec/rspec-rails/docs
|
66
|
+
config.infer_spec_type_from_file_location!
|
67
|
+
|
68
|
+
# Filter lines from Rails gems in backtraces.
|
69
|
+
config.filter_rails_from_backtrace!
|
70
|
+
# arbitrary gems may also be filtered via:
|
71
|
+
# config.filter_gems_from_backtrace("gem name")
|
72
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/BlockLength
|
4
|
+
RSpec.describe "Captcha management" do
|
5
|
+
def captcha_payload
|
6
|
+
session[Captcher::BaseCaptcha::SESSION_KEY][:payload] ||
|
7
|
+
session[Captcher::BaseCaptcha::SESSION_KEY]["payload"]
|
8
|
+
end
|
9
|
+
|
10
|
+
scenario "shows the captcha image" do
|
11
|
+
get "/captcher/captcha"
|
12
|
+
expect(response.status).to eq(200)
|
13
|
+
end
|
14
|
+
|
15
|
+
scenario "captcha payload remains unchanged between requests" do
|
16
|
+
get "/captcher/captcha"
|
17
|
+
payload1 = captcha_payload
|
18
|
+
|
19
|
+
get "/captcher/captcha"
|
20
|
+
payload2 = captcha_payload
|
21
|
+
expect(payload1).to eq(payload2)
|
22
|
+
end
|
23
|
+
|
24
|
+
scenario "refresh the state of captcha" do
|
25
|
+
post "/captcher/captcha/refresh"
|
26
|
+
expect(response.status).to eq(200)
|
27
|
+
payload1 = captcha_payload
|
28
|
+
|
29
|
+
post "/captcher/captcha/refresh"
|
30
|
+
payload2 = captcha_payload
|
31
|
+
expect(payload1).to_not eq(payload2)
|
32
|
+
end
|
33
|
+
|
34
|
+
scenario "submit valid captcha confirmation" do
|
35
|
+
get "/captcher/captcha"
|
36
|
+
payload = captcha_payload
|
37
|
+
|
38
|
+
post "/captcher/captcha/confirm", params: { confirmation: payload }
|
39
|
+
expect(response.status).to eq(200)
|
40
|
+
end
|
41
|
+
|
42
|
+
scenario "submit invalid captcha confirmation" do
|
43
|
+
post "/captcher/captcha/confirm", params: { confirmation: "IIIII" }
|
44
|
+
expect(response.status).to eq(422)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
# rubocop:enable Metrics/BlockLength
|
48
|
+
|