first commit
This commit is contained in:
commit
f3797b796d
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
sudo: false
|
||||||
|
language: ruby
|
||||||
|
cache: bundler
|
||||||
|
rvm:
|
||||||
|
- 2.5.0
|
||||||
|
- 2.3.8
|
||||||
|
before_install: gem install bundler -v 2.0.2
|
|
@ -0,0 +1,74 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity and
|
||||||
|
orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at yoslavskiy@innocode.no. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/4/
|
|
@ -0,0 +1,4 @@
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
# Specify your gem's dependencies in repost.gemspec
|
||||||
|
gemspec
|
|
@ -0,0 +1,35 @@
|
||||||
|
PATH
|
||||||
|
remote: .
|
||||||
|
specs:
|
||||||
|
repost (0.3.1)
|
||||||
|
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
diff-lcs (1.3)
|
||||||
|
rake (10.5.0)
|
||||||
|
rspec (3.8.0)
|
||||||
|
rspec-core (~> 3.8.0)
|
||||||
|
rspec-expectations (~> 3.8.0)
|
||||||
|
rspec-mocks (~> 3.8.0)
|
||||||
|
rspec-core (3.8.0)
|
||||||
|
rspec-support (~> 3.8.0)
|
||||||
|
rspec-expectations (3.8.3)
|
||||||
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
|
rspec-support (~> 3.8.0)
|
||||||
|
rspec-mocks (3.8.0)
|
||||||
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
|
rspec-support (~> 3.8.0)
|
||||||
|
rspec-support (3.8.0)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
bundler (~> 2.0)
|
||||||
|
rake (~> 10.0)
|
||||||
|
repost!
|
||||||
|
rspec (~> 3.0)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.0.2
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2019 YaroslavO
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
|
@ -0,0 +1,164 @@
|
||||||
|
<p align="right">
|
||||||
|
<a href="https://github.com/vergilet/repost"><img align="" src="https://user-images.githubusercontent.com/2478436/51829223-cb05d600-22f5-11e9-9245-bc6e82dcf028.png" width="56" height="56" /></a>
|
||||||
|
<a href="https://rubygems.org/gems/repost"><img align="right" src="https://user-images.githubusercontent.com/2478436/51829691-c55cc000-22f6-11e9-99a5-42f88a8f2a55.png" width="56" height="56" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://rubygems.org/gems/repost">
|
||||||
|
<img width="460" src="https://user-images.githubusercontent.com/2478436/55672583-44491880-58a5-11e9-945c-939f90470df8.png"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Gem **Repost** implements Redirect using POST method
|
||||||
|
|
||||||
|
[![Gem Version](https://badge.fury.io/rb/repost.svg)](https://badge.fury.io/rb/repost)
|
||||||
|
[![Build Status](https://travis-ci.org/vergilet/repost.svg?branch=master)](https://travis-ci.org/vergilet/repost)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Add this line to your application's Gemfile:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
gem 'repost'
|
||||||
|
```
|
||||||
|
|
||||||
|
And then execute:
|
||||||
|
|
||||||
|
$ bundle
|
||||||
|
|
||||||
|
Or install it yourself as:
|
||||||
|
|
||||||
|
$ gem install repost
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Diagram
|
||||||
|
|
||||||
|
What problem does it solve?
|
||||||
|
|
||||||
|
When you need to send some parameters to an endpoint which should redirect you after execution. There wouldn't be a problem if an endpoint receives [GET], because you can just use `redirect_to post_url(id: @model.id, token: model.token...)`.
|
||||||
|
|
||||||
|
But when an endpoint receives [POST], you have to generate html form and submit it. So `repost` gem helps to avoid creation of additional view with html form, just use `redirect_post` method instead.
|
||||||
|
I faced with this problem when was dealing with bank transactions. You can see the approximate scheme:
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://user-images.githubusercontent.com/2478436/55143646-d0da3500-5147-11e9-91a3-1bac9d560fb2.png">
|
||||||
|
<img src="https://user-images.githubusercontent.com/2478436/55143646-d0da3500-5147-11e9-91a3-1bac9d560fb2.png"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
If you use Rails, gem automatically includes helper methods to your controllers:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
repost(...)
|
||||||
|
```
|
||||||
|
and, as an alias
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
redirect_post(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Under the hood it calls `render` method of current controller with `html:`.*
|
||||||
|
|
||||||
|
### Example in Rails app:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MyController < ApplicationController
|
||||||
|
...
|
||||||
|
def index
|
||||||
|
repost(...)
|
||||||
|
end
|
||||||
|
...
|
||||||
|
end
|
||||||
|
```
|
||||||
|
______________
|
||||||
|
|
||||||
|
If you use Sinatra, Roda or etc., you need to require it first somewhere in you project:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
require 'repost'
|
||||||
|
```
|
||||||
|
|
||||||
|
Then ask your senpai to generate a string with html:
|
||||||
|
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Repost::Senpai.perform(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example in Sinatra, Roda, etc. app:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MyController < Sinatra::Base
|
||||||
|
get '/' do
|
||||||
|
Repost::Senpai.perform(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### *Reminder:*
|
||||||
|
|
||||||
|
- *In Rails app use `repost` or `redirect_post` method in your controller which performs 'redirect' when it is called.*
|
||||||
|
|
||||||
|
- *In Sinatra, Roda, etc. app or if you need html output - call Senpai*
|
||||||
|
|
||||||
|
|
||||||
|
#### Full example:
|
||||||
|
|
||||||
|
*UPD: authenticity token is **turned off** by default. Use `:auto` or `'auto'` to turn on default authenticity token from Rails. Any other string value would be treated as custom auth token value.*
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Repost::Senpai.perform('http://examp.io/endpoint', # URL, looks understandable
|
||||||
|
params: {a: 1, b: 2, c: '3', d: "4"}, # Your request body
|
||||||
|
options: {
|
||||||
|
method: :post, # OPTIONAL - DEFAULT is :post, but you can use others if needed
|
||||||
|
authenticity_token: 'auto', # OPTIONAL - :auto or 'auto' for Rails form_authenticity_token, string - custom token
|
||||||
|
charset: 'Windows-1251', # OPTIONAL - DEFAULT is "UTF-8", corresponds for accept-charset
|
||||||
|
form_id: 'CustomFormID', # OPTIONAL - DEFAULT is autogenerated
|
||||||
|
autosubmit: false, # OPTIONAL - DEFAULT is true, if you want to get a confirmation for redirect
|
||||||
|
decor: { # If autosubmit is turned off or Javascript is disabled on client
|
||||||
|
section: { # ... you can decorate confirmation section and button
|
||||||
|
classes: 'red-bg red-text', # OPTIONAL - <DIV> section, set classNames, separate with space
|
||||||
|
html: '<h1>Press this button, dude!</h1>' # OPTIONAL - Any html, which will appear before submit button
|
||||||
|
},
|
||||||
|
submit: {
|
||||||
|
classes: 'button-decorated round-border', # OPTIONAL - <Input> with type submit, set classNames, separate with space
|
||||||
|
text: 'c0n71nue ...' # OPTIONAL - DEFAULT is 'Continue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authenticity Token (Rails)
|
||||||
|
|
||||||
|
Currently you can pass the **authenticity token** in two ways:
|
||||||
|
|
||||||
|
* Recommended:
|
||||||
|
|
||||||
|
*Use `options` and `:auto` to pass the auth token. That should protect you from any implementation changes in future Rails versions*
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
redirect_post('https://exmaple.io/endpoint', options: {authenticity_token: :auto})
|
||||||
|
```
|
||||||
|
* Or, it is still valid to:
|
||||||
|
|
||||||
|
*use `params` and `form_authenticity_token` method directly from ActionController*
|
||||||
|
```ruby
|
||||||
|
redirect_post('https://exmaple.io/endpoint', params: {authenticity_token: form_authenticity_token})
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
The gem is available as open source under the terms of the MIT License.
|
||||||
|
|
||||||
|
Copyright © 2019 Yaro.
|
||||||
|
|
||||||
|
[![GitHub license](https://img.shields.io/badge/license-MIT-brightgreen)](https://raw.githubusercontent.com/vergilet/repost/master/LICENSE.txt)
|
||||||
|
|
||||||
|
**That's all folks.**
|
|
@ -0,0 +1,6 @@
|
||||||
|
require "bundler/gem_tasks"
|
||||||
|
require "rspec/core/rake_task"
|
||||||
|
|
||||||
|
RSpec::Core::RakeTask.new(:spec)
|
||||||
|
|
||||||
|
task :default => :spec
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require "bundler/setup"
|
||||||
|
require "repost"
|
||||||
|
|
||||||
|
# You can add fixtures and/or initialization code here to make experimenting
|
||||||
|
# with your gem easier. You can also use a different console, if you like.
|
||||||
|
|
||||||
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
||||||
|
# require "pry"
|
||||||
|
# Pry.start
|
||||||
|
|
||||||
|
require "irb"
|
||||||
|
IRB.start(__FILE__)
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
set -vx
|
||||||
|
|
||||||
|
bundle install
|
||||||
|
|
||||||
|
# Do any other automated setup that you need to do here
|
|
@ -0,0 +1,9 @@
|
||||||
|
require "repost/version"
|
||||||
|
require "repost/action"
|
||||||
|
require "repost/senpai"
|
||||||
|
require "repost/extend_controller"
|
||||||
|
|
||||||
|
module Repost
|
||||||
|
class Error < StandardError; end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
module Repost
|
||||||
|
class Action
|
||||||
|
def self.perform(*args)
|
||||||
|
action = new(*args)
|
||||||
|
action.perform
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
if defined?(Rails) && defined?(ActiveSupport)
|
||||||
|
ActiveSupport.on_load(:action_controller) do
|
||||||
|
class ::ActionController::Base
|
||||||
|
|
||||||
|
def repost(url, params: {}, options: {})
|
||||||
|
authenticity_token = form_authenticity_token if ['auto', :auto].include?(options[:authenticity_token])
|
||||||
|
render html: Repost::Senpai.perform(
|
||||||
|
url,
|
||||||
|
params: params,
|
||||||
|
options: options.merge({authenticity_token: authenticity_token}.compact)
|
||||||
|
).html_safe
|
||||||
|
end
|
||||||
|
|
||||||
|
alias :redirect_post :repost
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sinatra & Rack Protection
|
||||||
|
# TODO
|
||||||
|
# defined?(Sinatra::Base) && defined?(Rack::Protection::AuthenticityToken)
|
||||||
|
# env&.fetch('rack.session', :csrf)
|
|
@ -0,0 +1,79 @@
|
||||||
|
module Repost
|
||||||
|
class Senpai < Action
|
||||||
|
DEFAULT_SUBMIT_BUTTON_TEXT = 'Continue'
|
||||||
|
DEFAULT_CHARSET = 'UTF-8'
|
||||||
|
|
||||||
|
def initialize(url, params: {}, options: {})
|
||||||
|
@url = url
|
||||||
|
@params = params
|
||||||
|
@options = options
|
||||||
|
@method = options.fetch(:method, :post)
|
||||||
|
@authenticity_token = options.fetch(:authenticity_token, nil)
|
||||||
|
@charset = options.fetch(:charset, DEFAULT_CHARSET)
|
||||||
|
@form_id = options.fetch(:form_id, generated_form_id)
|
||||||
|
@autosubmit = options.fetch(:autosubmit, true)
|
||||||
|
@section_classes = nil#options.dig(:decor, :section, :classes)
|
||||||
|
@section_html = nil#options.dig(:decor, :section, :html)
|
||||||
|
@submit_classes = nil#options.dig(:decor, :submit, :classes)
|
||||||
|
@submit_text = DEFAULT_SUBMIT_BUTTON_TEXT#options.dig(:decor, :submit, :text) || DEFAULT_SUBMIT_BUTTON_TEXT
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform
|
||||||
|
compiled_body = if autosubmit
|
||||||
|
form_body << auto_submit_script << no_script
|
||||||
|
else
|
||||||
|
form_body << submit_section
|
||||||
|
end
|
||||||
|
form_head << compiled_body << form_footer
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :url, :params, :options, :method, :form_id, :autosubmit,
|
||||||
|
:section_classes, :section_html, :submit_classes,
|
||||||
|
:submit_text, :authenticity_token, :charset
|
||||||
|
|
||||||
|
def form_head
|
||||||
|
"<form id='#{form_id}' action='#{url}' method='#{method}' accept-charset='#{charset}'>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_body
|
||||||
|
inputs = params.map do |key, value|
|
||||||
|
"<input type='hidden' name='#{key}' value='#{value}'>"
|
||||||
|
end
|
||||||
|
inputs.unshift(csrf_token) if authenticity_token
|
||||||
|
inputs.join
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_footer
|
||||||
|
"</form>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def csrf_token
|
||||||
|
"<input name='authenticity_token' value='#{authenticity_token}' type='hidden'>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_script
|
||||||
|
"<noscript>
|
||||||
|
#{submit_section}
|
||||||
|
</noscript>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_section
|
||||||
|
"<div class='#{section_classes}'>
|
||||||
|
#{section_html}
|
||||||
|
<input class='#{submit_classes}' type='submit' value='#{submit_text}'></input>
|
||||||
|
</div>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def generated_form_id
|
||||||
|
"repost-#{Time.now.to_i}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def auto_submit_script
|
||||||
|
"<script>
|
||||||
|
document.getElementById('#{form_id}').submit();
|
||||||
|
</script>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
module Repost
|
||||||
|
VERSION = "0.3.1"
|
||||||
|
end
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
lib = File.expand_path("../lib", __FILE__)
|
||||||
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||||
|
require "repost/version"
|
||||||
|
|
||||||
|
Gem::Specification.new do |spec|
|
||||||
|
spec.name = "repost"
|
||||||
|
spec.version = Repost::VERSION
|
||||||
|
spec.authors = ["YaroslavO"]
|
||||||
|
spec.email = ["osyaroslav@gmail.com"]
|
||||||
|
|
||||||
|
spec.summary = %q{Gem implements Redirect using POST method}
|
||||||
|
spec.description = %q{Helps to make POST 'redirect', but actually builds [form] with method: :post under the hood}
|
||||||
|
spec.homepage = "https://vergilet.github.io/repost/"
|
||||||
|
spec.license = "MIT"
|
||||||
|
|
||||||
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
||||||
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
||||||
|
if spec.respond_to?(:metadata)
|
||||||
|
|
||||||
|
spec.metadata["homepage_uri"] = spec.homepage
|
||||||
|
# spec.metadata["source_code_uri"] = "Put your gem's public repo URL here."
|
||||||
|
# spec.metadata["changelog_uri"] = "Put your gem's CHANGELOG.md URL here."
|
||||||
|
else
|
||||||
|
raise "RubyGems 2.0 or newer is required to protect against " \
|
||||||
|
"public gem pushes."
|
||||||
|
end
|
||||||
|
|
||||||
|
spec.files = Dir['{app,config,db,lib}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.rdoc']
|
||||||
|
spec.bindir = "exe"
|
||||||
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||||
|
spec.require_paths = ["lib"]
|
||||||
|
|
||||||
|
spec.add_development_dependency "bundler", "~> 2.0"
|
||||||
|
spec.add_development_dependency "rake", "~> 10.0"
|
||||||
|
spec.add_development_dependency "rspec", "~> 3.0"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
RSpec.describe Repost do
|
||||||
|
it "has a version number" do
|
||||||
|
expect(Repost::VERSION).not_to be nil
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,96 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe Repost::Senpai do
|
||||||
|
let(:url) { 'http://example.com/endpoint' }
|
||||||
|
let(:html) { described_class.perform(url) }
|
||||||
|
|
||||||
|
it 'generates post form' do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(html).to include('form')
|
||||||
|
expect(html).to include(url)
|
||||||
|
expect(html).to include("type='submit'")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'autosubmit form by default' do
|
||||||
|
expect(html).to include('.submit()')
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'with params' do
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
name: 'TestName',
|
||||||
|
description: 'Some cool description',
|
||||||
|
count: 696,
|
||||||
|
string_size: '234',
|
||||||
|
boolean: true,
|
||||||
|
string_boolean: 'false'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:html) { described_class.perform(url, params: params) }
|
||||||
|
|
||||||
|
it 'generates post form' do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(html).to include("input type='hidden'")
|
||||||
|
expect(html).to include("value='#{params[:name]}'")
|
||||||
|
expect(html).to include("value='#{params[:description]}'")
|
||||||
|
expect(html).to include("value='#{params[:string_size]}'")
|
||||||
|
expect(html).to include("value='#{params[:string_boolean]}'")
|
||||||
|
|
||||||
|
expect(html).to include("value='#{params[:count]}'")
|
||||||
|
expect(html).to include("value='#{params[:boolean]}'")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'with options' do
|
||||||
|
let(:options) { {} }
|
||||||
|
let(:html) { described_class.perform(url, options: options) }
|
||||||
|
|
||||||
|
context 'empty options' do
|
||||||
|
it 'autosubmit form by default' do
|
||||||
|
expect(html).to include('.submit()')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'set options' do
|
||||||
|
describe 'autosubmit' do
|
||||||
|
context 'enabled' do
|
||||||
|
|
||||||
|
let(:options) do
|
||||||
|
{
|
||||||
|
autosubmit: true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns submit function' do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(html).to include('.submit()')
|
||||||
|
expect(html).to include('<noscript>')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'disabled' do
|
||||||
|
let(:options) do
|
||||||
|
{
|
||||||
|
autosubmit: false
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't return submit function" do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(html).to_not include('.submit()')
|
||||||
|
expect(html).to_not include('<noscript>')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'decor' do
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
require "bundler/setup"
|
||||||
|
|
||||||
|
require 'repost'
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
# Enable flags like --only-failures and --next-failure
|
||||||
|
config.example_status_persistence_file_path = ".rspec_status"
|
||||||
|
|
||||||
|
# Disable RSpec exposing methods globally on `Module` and `main`
|
||||||
|
config.disable_monkey_patching!
|
||||||
|
|
||||||
|
config.expect_with :rspec do |c|
|
||||||
|
c.syntax = :expect
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue