diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..ef41bee5
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,50 @@
+name: Build
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ build:
+ runs-on: ubuntu-24.04
+ strategy:
+ matrix:
+ ruby-version:
+ - 3.2.6
+ fail-fast: false
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Set up Ruby ${{ matrix.ruby-version }}
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby-version }}
+ bundler-cache: true
+
+ - name: Install dependencies
+ run: |
+ bundle config set without 'development'
+ bundle config path vendor/bundle
+ bundle install --jobs=9 --retry=2 --quiet
+
+ - name: Setup test database
+ run: |
+ cp config/config.yml.sample config/config.yml
+ cp config/database.yml.sample config/database.yml
+ bin/rails db:migrate RAILS_ENV=test
+
+ - name: Rubocop
+ run: |
+ bundle exec rubocop
+
+ - name: Run RSpec
+ run: |
+ bundle exec rake spec
+
+ - name: Run Cucumber
+ run: |
+ bundle exec rake cucumber
diff --git a/.rubocop.yml b/.rubocop.yml
index 94569d64..c0f62e3f 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,12 +1,24 @@
inherit_from: .rubocop_todo.yml
+require:
+ - rubocop-rails
+ - rubocop-rspec
+
AllCops:
- TargetRubyVersion: 2.6
+ TargetRubyVersion: 3.2
NewCops: enable
Exclude:
- 'db/schema.rb'
- 'bin/*'
+ - 'vendor/**/*'
Style/Documentation:
Enabled: false
+
+Rails/DynamicFindBy:
+ Whitelist:
+ - find_by_url
+ - find_by_commit
+ - find_by_service_and_repo
+ - find_by_nickname
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index dc1014ad..a0d17a26 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,49 +1,52 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
-# on 2020-12-04 11:36:42 UTC using RuboCop version 1.3.1.
+# on 2023-03-21 13:21:19 UTC using RuboCop version 1.48.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
+# Offense count: 2
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Lint/OrAssignmentToConstant:
+ Exclude:
+ - 'config/application.rb'
+ - 'config/initializers/blacklist.rb'
+
# Offense count: 1
-Lint/MissingSuper:
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Lint/RedundantDirGlobSort:
Exclude:
- - 'lib/bitcoin_rpc.rb'
+ - 'spec/spec_helper.rb'
-# Offense count: 18
-# Configuration parameters: IgnoredMethods.
+# Offense count: 15
+# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize:
- Max: 51
+ Max: 34
-# Offense count: 17
-# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
-# ExcludedMethods: refine
+# Offense count: 1
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
+# AllowedMethods: refine
Metrics/BlockLength:
- Max: 224
+ Max: 29
# Offense count: 2
# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
Max: 187
-# Offense count: 4
-# Configuration parameters: IgnoredMethods.
+# Offense count: 2
+# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/CyclomaticComplexity:
- Max: 29
+ Max: 16
-# Offense count: 19
-# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
+# Offense count: 16
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
- Max: 57
-
-# Offense count: 1
-# Configuration parameters: CountComments, CountAsOne.
-Metrics/ModuleLength:
- Max: 163
+ Max: 30
-# Offense count: 4
-# Configuration parameters: IgnoredMethods.
+# Offense count: 2
+# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/PerceivedComplexity:
Max: 13
@@ -55,17 +58,154 @@ Metrics/PerceivedComplexity:
# MethodDefinitionMacros: define_method, define_singleton_method
Naming/PredicateName:
Exclude:
- - 'spec/**/*'
- 'app/models/project.rb'
+# Offense count: 9
+# This cop supports unsafe autocorrection (--autocorrect-all).
+RSpec/BeEq:
+ Exclude:
+ - 'spec/lib/blacklist_spec.rb'
+
+# Offense count: 1
+# Configuration parameters: Prefixes, AllowedPatterns.
+# Prefixes: when, with, without
+RSpec/ContextWording:
+ Exclude:
+ - 'spec/controllers/projects_controller_spec.rb'
+
+# Offense count: 13
+# Configuration parameters: CountAsOne.
+RSpec/ExampleLength:
+ Max: 16
+
+# Offense count: 1
+# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
+# Include: **/*_spec*rb*, **/spec/**/*
+RSpec/FilePath:
+ Exclude:
+ - 'spec/features/assets.rb'
+
+# Offense count: 2
+# Configuration parameters: AssignmentOnly.
+RSpec/InstanceVariable:
+ Exclude:
+ - 'spec/controllers/users_controller_spec.rb'
+ - 'spec/requests/cve_2005_9284_regression_spec.rb'
+
+# Offense count: 3
+# Configuration parameters: .
+# SupportedStyles: have_received, receive
+RSpec/MessageSpies:
+ EnforcedStyle: receive
+
+# Offense count: 3
+RSpec/MultipleExpectations:
+ Max: 9
+
+# Offense count: 26
+# Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
+# SupportedStyles: always, named_only
+RSpec/NamedSubject:
+ Exclude:
+ - 'spec/controllers/home_controller_spec.rb'
+ - 'spec/controllers/projects_controller_spec.rb'
+ - 'spec/controllers/users_controller_spec.rb'
+ - 'spec/models/wallet_spec.rb'
+
+# Offense count: 4
+# Configuration parameters: AllowedGroups.
+RSpec/NestedGroups:
+ Max: 5
+
+# Offense count: 22
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Inferences.
+RSpec/Rails/InferredSpecType:
+ Enabled: false
+
+# Offense count: 2
+RSpec/RepeatedExampleGroupBody:
+ Exclude:
+ - 'spec/models/user_spec.rb'
+
+# Offense count: 3
+RSpec/StubbedMock:
+ Exclude:
+ - 'spec/controllers/projects_controller_spec.rb'
+
+# Offense count: 8
+RSpec/SubjectDeclaration:
+ Exclude:
+ - 'spec/controllers/home_controller_spec.rb'
+ - 'spec/controllers/projects_controller_spec.rb'
+ - 'spec/controllers/users_controller_spec.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/ActiveSupportOnLoad:
+ Exclude:
+ - 'config/initializers/demoji.rb'
+
+# Offense count: 1
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: slashes, arguments
+Rails/FilePath:
+ Exclude:
+ - 'spec/spec_helper.rb'
+
+# Offense count: 6
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/HasManyOrHasOneDependent:
+ Exclude:
+ - 'app/models/project.rb'
+ - 'app/models/sendmany.rb'
+ - 'app/models/user.rb'
+
+# Offense count: 2
+Rails/OutputSafety:
+ Exclude:
+ - 'app/helpers/application_helper.rb'
+ - 'app/helpers/rates_helper.rb'
+
+# Offense count: 1
+# Configuration parameters: Include.
+# Include: db/**/*.rb
+Rails/ReversibleMigration:
+ Exclude:
+ - 'db/migrate/20140823060921_make_default_branch_blank.rb'
+
+# Offense count: 11
+# Configuration parameters: ForbiddenMethods, AllowedMethods.
+# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
+Rails/SkipsModelValidations:
+ Exclude:
+ - 'app/models/project.rb'
+ - 'app/models/sendmany.rb'
+ - 'app/models/tip.rb'
+ - 'db/migrate/20140223061035_add_project_host.rb'
+ - 'db/migrate/20140402082149_add_fee_size_to_deposits.rb'
+ - 'lib/bitcoin_tipper.rb'
+
# Offense count: 1
Style/MissingRespondToMissing:
Exclude:
- 'lib/bitcoin_rpc.rb'
+# Offense count: 1
+Style/OpenStructUse:
+ Exclude:
+ - 'features/support/to_ostruct.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/SelectByRegexp:
+ Exclude:
+ - 'spec/routing/users_routing_spec.rb'
+
# Offense count: 25
-# Cop supports --auto-correct.
-# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
# URISchemes: http, https
Layout/LineLength:
Max: 234
diff --git a/.tool-versions b/.tool-versions
new file mode 100644
index 00000000..a1e3a5ab
--- /dev/null
+++ b/.tool-versions
@@ -0,0 +1 @@
+ruby 3.2.6
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 8e4b01eb..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-language: ruby
-
-sudo: false
-
-git:
- depth: 10
-
-rvm:
- - 2.6.6
-
-bundler_args: --without development --jobs=9 --retry=2 --quiet
-
-before_script:
- - cp config/config.yml.sample config/config.yml
- - cp config/database.yml.sample config/database.yml
-
-script:
- - bundle exec rubocop
- - bundle exec rake db:migrate
- - bundle exec rake spec
- - bundle exec rake cucumber
diff --git a/Gemfile b/Gemfile
index a64bf791..63b9a325 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,9 +2,7 @@
source 'https://rubygems.org'
-ruby '2.6.6'
-
-gem 'rails', '5.2.4.4'
+gem 'rails', '6.1.7.10'
gem 'acts_as_paranoid'
gem 'airbrake'
@@ -32,15 +30,14 @@ gem 'octokit'
gem 'omniauth'
gem 'omniauth-github'
gem 'omniauth-rails_csrf_protection', '~> 0.1'
+gem 'puma'
gem 'rails-i18n'
gem 'render_csv'
gem 'rest-client'
gem 'sass-rails'
gem 'sawyer'
gem 'sdoc', group: :doc, require: false
-gem 'sidekiq'
gem 'sprockets'
-gem 'therubyracer', platforms: :ruby
gem 'turbolinks'
gem 'twitter-bootstrap-rails'
gem 'uglifier'
@@ -59,9 +56,13 @@ end
group :development, :test do
gem 'factory_bot_rails'
+ gem 'pry'
+ gem 'pry-byebug'
gem 'rspec-rails'
gem 'rubocop'
- gem 'sqlite3'
+ gem 'rubocop-rails'
+ gem 'rubocop-rspec'
+ gem 'sqlite3', '~> 1.4'
end
group :test do
diff --git a/Gemfile.lock b/Gemfile.lock
index 9ae8b838..518d1539 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,68 +1,87 @@
GEM
remote: https://rubygems.org/
specs:
- actioncable (5.2.4.4)
- actionpack (= 5.2.4.4)
+ actioncable (6.1.7.10)
+ actionpack (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
- actionmailer (5.2.4.4)
- actionpack (= 5.2.4.4)
- actionview (= 5.2.4.4)
- activejob (= 5.2.4.4)
+ actionmailbox (6.1.7.10)
+ actionpack (= 6.1.7.10)
+ activejob (= 6.1.7.10)
+ activerecord (= 6.1.7.10)
+ activestorage (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
+ mail (>= 2.7.1)
+ actionmailer (6.1.7.10)
+ actionpack (= 6.1.7.10)
+ actionview (= 6.1.7.10)
+ activejob (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
- actionpack (5.2.4.4)
- actionview (= 5.2.4.4)
- activesupport (= 5.2.4.4)
- rack (~> 2.0, >= 2.0.8)
+ actionpack (6.1.7.10)
+ actionview (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
+ rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (5.2.4.4)
- activesupport (= 5.2.4.4)
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
+ actiontext (6.1.7.10)
+ actionpack (= 6.1.7.10)
+ activerecord (= 6.1.7.10)
+ activestorage (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
+ nokogiri (>= 1.8.5)
+ actionview (6.1.7.10)
+ activesupport (= 6.1.7.10)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
- activejob (5.2.4.4)
- activesupport (= 5.2.4.4)
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
+ activejob (6.1.7.10)
+ activesupport (= 6.1.7.10)
globalid (>= 0.3.6)
- activemodel (5.2.4.4)
- activesupport (= 5.2.4.4)
- activerecord (5.2.4.4)
- activemodel (= 5.2.4.4)
- activesupport (= 5.2.4.4)
- arel (>= 9.0)
- activestorage (5.2.4.4)
- actionpack (= 5.2.4.4)
- activerecord (= 5.2.4.4)
- marcel (~> 0.3.1)
- activesupport (5.2.4.4)
+ activemodel (6.1.7.10)
+ activesupport (= 6.1.7.10)
+ activerecord (6.1.7.10)
+ activemodel (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
+ activestorage (6.1.7.10)
+ actionpack (= 6.1.7.10)
+ activejob (= 6.1.7.10)
+ activerecord (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
+ marcel (~> 1.0)
+ mini_mime (>= 1.1.0)
+ activesupport (6.1.7.10)
concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 0.7, < 2)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ zeitwerk (~> 2.3)
acts_as_paranoid (0.7.0)
activerecord (>= 5.2, < 7.0)
activesupport (>= 5.2, < 7.0)
- addressable (2.7.0)
- public_suffix (>= 2.0.2, < 5.0)
- airbrake (11.0.1)
- airbrake-ruby (~> 5.1)
- airbrake-ruby (5.1.1)
- rbtree3 (~> 0.5)
+ addressable (2.8.7)
+ public_suffix (>= 2.0.2, < 7.0)
+ airbrake (13.0.4)
+ airbrake-ruby (~> 6.0)
+ airbrake-ruby (6.2.2)
+ rbtree3 (~> 0.6)
airbrussh (1.4.0)
sshkit (>= 1.6.1, != 1.7.0)
- arel (9.0.0)
- ast (2.4.1)
- backports (3.18.2)
+ ast (2.4.2)
+ backports (3.25.0)
bcrypt (3.1.16)
bcrypt_pbkdf (1.0.1)
- bech32 (1.0.5)
+ bech32 (1.4.2)
+ thor (>= 1.1.0)
bootstrap_form (4.5.0)
actionpack (>= 5.2)
activemodel (>= 5.2)
- builder (3.2.4)
+ builder (3.3.0)
+ byebug (11.1.3)
cancancan (3.1.0)
capistrano (3.14.1)
airbrussh (>= 1.0.0)
@@ -77,14 +96,16 @@ GEM
capistrano-rvm (0.1.2)
capistrano (~> 3.0)
sshkit (~> 1.2)
- capybara (3.33.0)
+ capybara (3.40.0)
addressable
+ matrix
mini_mime (>= 0.1.3)
- nokogiri (~> 1.8)
+ nokogiri (~> 1.11)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
- regexp_parser (~> 1.5)
+ regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
+ coderay (1.1.3)
coffee-rails (5.0.0)
coffee-script (>= 2.2.0)
railties (>= 5.2.0)
@@ -93,8 +114,7 @@ GEM
execjs
coffee-script-source (1.12.2)
commonjs (0.2.7)
- concurrent-ruby (1.1.7)
- connection_pool (2.2.3)
+ concurrent-ruby (1.3.4)
crack (0.4.4)
crass (1.0.6)
cucumber (3.2.0)
@@ -120,6 +140,7 @@ GEM
cucumber-tag_expressions (1.1.1)
cucumber-wire (0.0.1)
database_cleaner (1.8.5)
+ date (3.4.1)
demoji (0.0.7)
devise (4.7.3)
bcrypt (~> 3.0)
@@ -129,8 +150,8 @@ GEM
warden (~> 1.2.3)
devise-i18n (1.9.2)
devise (>= 4.7.1)
- diff-lcs (1.4.4)
- docile (1.3.2)
+ diff-lcs (1.5.1)
+ docile (1.4.1)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dusen (0.6.1)
@@ -140,8 +161,7 @@ GEM
ed25519 (1.2.4)
edge_rider (1.1.0)
activerecord (>= 3.2)
- erubi (1.10.0)
- erubis (2.7.0)
+ erubi (1.13.0)
execjs (2.7.0)
factory_bot (6.1.0)
activesupport (>= 5.0.0)
@@ -151,31 +171,26 @@ GEM
faraday (1.1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords
- ffi (1.13.1)
+ ffi (1.17.0-arm64-darwin)
+ ffi (1.17.0-x86_64-linux-gnu)
gherkin (5.1.0)
- globalid (0.4.2)
- activesupport (>= 4.2.0)
- haml (5.2.0)
+ globalid (1.2.1)
+ activesupport (>= 6.1)
+ haml (5.2.1)
temple (>= 0.8.0)
tilt
- haml-rails (2.0.1)
+ haml-rails (2.1.0)
actionpack (>= 5.1)
activesupport (>= 5.1)
- haml (>= 4.0.6, < 6.0)
- html2haml (>= 1.0.1)
+ haml (>= 4.0.6)
railties (>= 5.1)
hashdiff (1.0.1)
hashie (4.1.0)
- html2haml (2.2.0)
- erubis (~> 2.7.0)
- haml (>= 4.0, < 6)
- nokogiri (>= 1.6.0)
- ruby_parser (~> 3.5)
http-accept (1.7.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
http_accept_language (2.1.1)
- i18n (1.8.5)
+ i18n (1.14.6)
concurrent-ruby (~> 1.0)
i18n-js (3.8.0)
i18n (>= 0.6.6)
@@ -188,6 +203,7 @@ GEM
jquery-turbolinks (2.1.0)
railties (>= 3.1.0)
turbolinks
+ json (2.6.3)
jwt (2.2.2)
kaminari (1.2.1)
activesupport (>= 4.1.0)
@@ -210,36 +226,50 @@ GEM
actionpack (>= 4)
less (~> 2.6.0)
sprockets (>= 2)
- libv8 (3.16.14.19)
- loofah (2.7.0)
+ logger (1.6.1)
+ loofah (2.23.1)
crass (~> 1.0.2)
- nokogiri (>= 1.5.9)
- mail (2.7.1)
+ nokogiri (>= 1.12.0)
+ mail (2.8.1)
mini_mime (>= 0.1.1)
- marcel (0.3.3)
- mimemagic (~> 0.3.2)
- method_source (1.0.0)
- mime-types (3.3.1)
+ net-imap
+ net-pop
+ net-smtp
+ marcel (1.0.4)
+ matrix (0.4.2)
+ method_source (1.1.0)
+ mime-types (3.6.0)
+ logger
mime-types-data (~> 3.2015)
- mime-types-data (3.2020.1104)
- mimemagic (0.3.5)
- mini_mime (1.0.2)
- mini_portile2 (2.4.0)
- minitest (5.14.2)
- money-tree (0.10.0)
- ffi
+ mime-types-data (3.2024.1001)
+ mini_mime (1.1.5)
+ minitest (5.25.1)
+ money-tree (0.11.2)
+ bech32 (~> 1.3)
+ openssl (~> 3.1)
multi_json (1.15.0)
- multi_test (0.1.2)
+ multi_test (1.1.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
- mysql2 (0.5.3)
+ mysql2 (0.5.5)
+ net-imap (0.4.20)
+ date
+ net-protocol
+ net-pop (0.1.2)
+ net-protocol
+ net-protocol (0.2.2)
+ timeout
net-scp (3.0.0)
net-ssh (>= 2.6.5, < 7.0.0)
+ net-smtp (0.5.0)
+ net-protocol
net-ssh (6.1.0)
netrc (0.11.0)
- nio4r (2.5.4)
- nokogiri (1.10.10)
- mini_portile2 (~> 2.4.0)
+ nio4r (2.7.4)
+ nokogiri (1.18.9-arm64-darwin)
+ racc (~> 1.4)
+ nokogiri (1.18.9-x86_64-linux-gnu)
+ racc (~> 1.4)
oauth2 (1.4.4)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
@@ -261,54 +291,69 @@ GEM
omniauth-rails_csrf_protection (0.1.2)
actionpack (>= 4.2)
omniauth (>= 1.3.1)
+ openssl (3.2.0)
orm_adapter (0.5.0)
- parallel (1.20.0)
- parser (2.7.2.0)
+ parallel (1.22.1)
+ parser (3.2.1.1)
ast (~> 2.4.1)
- public_suffix (4.0.6)
- rack (2.2.3)
- rack-test (1.1.0)
- rack (>= 1.0, < 3)
- rails (5.2.4.4)
- actioncable (= 5.2.4.4)
- actionmailer (= 5.2.4.4)
- actionpack (= 5.2.4.4)
- actionview (= 5.2.4.4)
- activejob (= 5.2.4.4)
- activemodel (= 5.2.4.4)
- activerecord (= 5.2.4.4)
- activestorage (= 5.2.4.4)
- activesupport (= 5.2.4.4)
- bundler (>= 1.3.0)
- railties (= 5.2.4.4)
+ pry (0.14.2)
+ coderay (~> 1.1)
+ method_source (~> 1.0)
+ pry-byebug (3.10.1)
+ byebug (~> 11.0)
+ pry (>= 0.13, < 0.15)
+ psych (5.1.2)
+ stringio
+ public_suffix (6.0.1)
+ puma (6.4.3)
+ nio4r (~> 2.0)
+ racc (1.8.1)
+ rack (2.2.14)
+ rack-test (2.1.0)
+ rack (>= 1.3)
+ rails (6.1.7.10)
+ actioncable (= 6.1.7.10)
+ actionmailbox (= 6.1.7.10)
+ actionmailer (= 6.1.7.10)
+ actionpack (= 6.1.7.10)
+ actiontext (= 6.1.7.10)
+ actionview (= 6.1.7.10)
+ activejob (= 6.1.7.10)
+ activemodel (= 6.1.7.10)
+ activerecord (= 6.1.7.10)
+ activestorage (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
+ bundler (>= 1.15.0)
+ railties (= 6.1.7.10)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
activesupport (>= 5.0.1.rc1)
- rails-dom-testing (2.0.3)
- activesupport (>= 4.2.0)
+ rails-dom-testing (2.2.0)
+ activesupport (>= 5.0.0)
+ minitest
nokogiri (>= 1.6)
- rails-html-sanitizer (1.3.0)
- loofah (~> 2.3)
- rails-i18n (5.1.3)
+ rails-html-sanitizer (1.6.1)
+ loofah (~> 2.21)
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
+ rails-i18n (7.0.6)
i18n (>= 0.7, < 2)
- railties (>= 5.0, < 6)
- railties (5.2.4.4)
- actionpack (= 5.2.4.4)
- activesupport (= 5.2.4.4)
+ railties (>= 6.0.0, < 8)
+ railties (6.1.7.10)
+ actionpack (= 6.1.7.10)
+ activesupport (= 6.1.7.10)
method_source
- rake (>= 0.8.7)
- thor (>= 0.19.0, < 2.0)
- rainbow (3.0.0)
- rake (13.0.1)
- rbnacl (7.1.1)
- ffi
- rbtree3 (0.6.0)
- rdoc (6.2.1)
- redis (4.2.5)
- ref (2.0.0)
- regexp_parser (1.8.2)
+ rake (>= 12.2)
+ thor (~> 1.0)
+ rainbow (3.1.1)
+ rake (13.2.1)
+ rbnacl (7.1.2)
+ ffi (~> 1)
+ rbtree3 (0.7.1)
+ rdoc (6.6.3.1)
+ psych (>= 4.0.0)
+ regexp_parser (2.9.2)
render_csv (2.0.0)
rails (>= 3.0)
responders (3.0.1)
@@ -319,7 +364,7 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
- rexml (3.2.4)
+ rexml (3.3.9)
rspec-activemodel-mocks (1.1.0)
activemodel (>= 3.0)
activesupport (>= 3.0)
@@ -341,21 +386,29 @@ GEM
rspec-mocks (~> 3.9)
rspec-support (~> 3.9)
rspec-support (3.10.0)
- rubocop (1.3.1)
+ rubocop (1.48.1)
+ json (~> 2.3)
parallel (~> 1.10)
- parser (>= 2.7.1.5)
+ parser (>= 3.2.0.0)
rainbow (>= 2.2.2, < 4.0)
- regexp_parser (>= 1.8)
- rexml
- rubocop-ast (>= 1.1.1)
+ regexp_parser (>= 1.8, < 3.0)
+ rexml (>= 3.2.5, < 4.0)
+ rubocop-ast (>= 1.26.0, < 2.0)
ruby-progressbar (~> 1.7)
- unicode-display_width (>= 1.4.0, < 2.0)
- rubocop-ast (1.1.1)
- parser (>= 2.7.1.5)
- ruby-progressbar (1.10.1)
+ unicode-display_width (>= 2.4.0, < 3.0)
+ rubocop-ast (1.27.0)
+ parser (>= 3.2.1.0)
+ rubocop-capybara (2.17.1)
+ rubocop (~> 1.41)
+ rubocop-rails (2.18.0)
+ activesupport (>= 4.2.0)
+ rack (>= 1.1)
+ rubocop (>= 1.33.0, < 2.0)
+ rubocop-rspec (2.19.0)
+ rubocop (~> 1.33)
+ rubocop-capybara (~> 2.17)
+ ruby-progressbar (1.13.0)
ruby2_keywords (0.0.2)
- ruby_parser (3.15.0)
- sexp_processor (~> 4.9)
sass-rails (6.0.0)
sassc-rails (~> 2.1, >= 2.1.1)
sassc (2.4.0)
@@ -371,35 +424,31 @@ GEM
faraday (> 0.8, < 2.0)
sdoc (2.0.2)
rdoc (>= 5.0)
- sexp_processor (4.15.1)
shoulda-matchers (4.4.1)
activesupport (>= 4.2.0)
- sidekiq (6.1.2)
- connection_pool (>= 2.2.2)
- rack (~> 2.0)
- redis (>= 4.2.0)
- simplecov (0.19.1)
+ simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
- simplecov-html (0.12.3)
- sprockets (4.0.2)
+ simplecov_json_formatter (~> 0.1)
+ simplecov-html (0.13.1)
+ simplecov_json_formatter (0.1.4)
+ sprockets (4.2.0)
concurrent-ruby (~> 1.0)
- rack (> 1, < 3)
- sprockets-rails (3.2.2)
- actionpack (>= 4.0)
- activesupport (>= 4.0)
+ rack (>= 2.2.4, < 4)
+ sprockets-rails (3.4.2)
+ actionpack (>= 5.2)
+ activesupport (>= 5.2)
sprockets (>= 3.0.0)
- sqlite3 (1.4.2)
- sshkit (1.21.0)
+ sqlite3 (1.7.3-arm64-darwin)
+ sqlite3 (1.7.3-x86_64-linux)
+ sshkit (1.21.1)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
+ stringio (3.1.0)
temple (0.8.2)
- therubyracer (0.12.3)
- libv8 (~> 3.16.14.15)
- ref
- thor (1.0.1)
- thread_safe (0.3.6)
+ thor (1.3.2)
tilt (2.0.10)
+ timeout (0.4.3)
turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
@@ -408,14 +457,14 @@ GEM
execjs (>= 2.2.2, >= 2.2)
less-rails (>= 2.5.0)
railties (>= 3.1)
- tzinfo (1.2.8)
- thread_safe (~> 0.1)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
- unicode-display_width (1.7.0)
+ unicode-display_width (2.4.2)
vcr (6.0.0)
warden (1.2.9)
rack (>= 2.0.9)
@@ -423,14 +472,17 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
- websocket-driver (0.7.3)
+ websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
+ zeitwerk (2.7.1)
PLATFORMS
- ruby
+ arm64-darwin-22
+ arm64-darwin-24
+ x86_64-linux
DEPENDENCIES
acts_as_paranoid
@@ -468,7 +520,10 @@ DEPENDENCIES
omniauth
omniauth-github
omniauth-rails_csrf_protection (~> 0.1)
- rails (= 5.2.4.4)
+ pry
+ pry-byebug
+ puma
+ rails (= 6.1.7.10)
rails-controller-testing
rails-i18n
rbnacl
@@ -477,23 +532,20 @@ DEPENDENCIES
rspec-activemodel-mocks
rspec-rails
rubocop
+ rubocop-rails
+ rubocop-rspec
sass-rails
sawyer
sdoc
shoulda-matchers
- sidekiq
simplecov
sprockets
- sqlite3
- therubyracer
+ sqlite3 (~> 1.4)
turbolinks
twitter-bootstrap-rails
uglifier
vcr
webmock
-RUBY VERSION
- ruby 2.6.6p146
-
BUNDLED WITH
- 2.1.4
+ 2.4.8
diff --git a/LICENSE b/LICENSE
index 62c97553..b3246315 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2018 tip4commit
+Copyright (c) 2023 tip4commit
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
diff --git a/README.md b/README.md
index 3bfda6b4..a3d8ae80 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@ Tip4commit
==========
[](https://tip4commit.com/projects/307)
-[](https://travis-ci.org/tip4commit/tip4commit)
+[](https://github.com/tip4commit/tip4commit/actions)
Donate bitcoins to open source projects or receive tips for code contributions.
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index 1f23d93f..6901e003 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -7,7 +7,7 @@
#= require i18n/translations
#= require_tree .
-$(document).on "ready page:change", ->
+$(document).on "turbolinks:load", ->
# Remove all global properties set by addthis, otherwise it won't reinitialize
for i of window
@@ -18,4 +18,4 @@ $(document).on "ready page:change", ->
$.getScript "//s7.addthis.com/js/250/addthis_widget.js#pubid=ra-526425ac0ea0780b"
$('.noclick').click () ->
- return false
\ No newline at end of file
+ return false
diff --git a/app/assets/javascripts/projects.js.coffee b/app/assets/javascripts/projects.js.coffee
index 86bd3f15..c34a24f2 100644
--- a/app/assets/javascripts/projects.js.coffee
+++ b/app/assets/javascripts/projects.js.coffee
@@ -6,4 +6,4 @@ init = () ->
$('.qrcode').each () ->
$(this).qrcode($(this).attr('data-qrcode'));
-$(document).on 'ready page:load', init
\ No newline at end of file
+$(document).on 'turbolinks:load', init
diff --git a/app/assets/javascripts/users.js.coffee b/app/assets/javascripts/users.js.coffee
index 056e5d7a..a52f5b93 100644
--- a/app/assets/javascripts/users.js.coffee
+++ b/app/assets/javascripts/users.js.coffee
@@ -39,7 +39,7 @@ load_bootstrap_validator = ->
notEmpty:
message: I18n.t('js.errors.password_confirmation.blank')
-$(document).on "ready page:load", load_bootstrap_validator
+$(document).on "turbolinks:load", load_bootstrap_validator
$ ->
$('.from-gravatar').click (e) ->
diff --git a/app/controllers/deposits_controller.rb b/app/controllers/deposits_controller.rb
index c692e4b4..c4981233 100644
--- a/app/controllers/deposits_controller.rb
+++ b/app/controllers/deposits_controller.rb
@@ -24,7 +24,7 @@ def load_project
return unless pretty_project_path? || params[:project_id].present?
if pretty_project_path?
- @project = Project.first_by_service_and_repo(params[:service], params[:repo])
+ @project = Project.find_by_service_and_repo(params[:service], params[:repo])
elsif params[:project_id].present?
@project = Project.where(id: params[:project_id]).first
redirect_to project_deposits_pretty_path(@project.host, @project.full_name) if @project
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index e7030607..e789d7e7 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -49,8 +49,17 @@ def update
def decide_tip_amounts
authorize! :decide_tip_amounts, @project
return unless request.patch?
+ return unless validate_project_tips
@project.available_amount # preload anything required to get the amount, otherwise it's loaded during the assignation and there are undesirable consequences
+ return unless @project.update(permitted_project_tips_params)
+
+ tips_decided
+ end
+
+ private
+
+ def validate_project_tips
percentages = params[:project][:tips_attributes].values.map { |tip| tip['amount_percentage'].to_f }
if percentages.sum > 100
redirect_to decide_tip_amounts_project_path(@project), alert: I18n.t('errors.can_assign_more_tips')
@@ -58,9 +67,14 @@ def decide_tip_amounts
end
raise 'wrong data' if percentages.min.negative?
- @project.attributes = params.require(:project).permit(tips_attributes: %i[id amount_percentage])
- return unless @project.save
+ true
+ end
+
+ def permitted_project_tips_params
+ params.require(:project).permit(tips_attributes: %i[id amount_percentage])
+ end
+ def tips_decided
message = I18n.t('notices.tips_decided')
if @project.has_undecided_tips?
redirect_to decide_tip_amounts_project_path(@project), notice: message
@@ -69,11 +83,9 @@ def decide_tip_amounts
end
end
- private
-
def load_project
@project = if pretty_project_path?
- Project.first_by_service_and_repo(params[:service], params[:repo])
+ Project.find_by_service_and_repo(params[:service], params[:repo])
else
Project.where(id: params[:id]).first
end
@@ -107,6 +119,7 @@ def redirect_to_pretty_url
path = pretty_project_decide_tip_amounts_path(@project)
end
format.html { redirect_to path }
+ format.svg
end
end
end
diff --git a/app/controllers/tips_controller.rb b/app/controllers/tips_controller.rb
index dad3b6fd..140b7161 100644
--- a/app/controllers/tips_controller.rb
+++ b/app/controllers/tips_controller.rb
@@ -32,7 +32,7 @@ def load_project
return unless pretty_project_path? || params[:project_id].present?
if pretty_project_path?
- @project = Project.first_by_service_and_repo(params[:service], params[:repo])
+ @project = Project.find_by_service_and_repo(params[:service], params[:repo])
elsif params[:project_id].present?
@project = Project.where(id: params[:project_id]).first
redirect_to project_tips_pretty_path(@project.host, @project.full_name) if @project
@@ -45,7 +45,7 @@ def load_user
return unless params[:user_id].present? || params[:nickname].present?
if params[:nickname].present?
- @user = User.first_by_nickname(params[:nickname])
+ @user = User.find_by_nickname(params[:nickname])
elsif params[:user_id].present?
@user = User.where(id: params[:user_id]).first
redirect_to user_tips_pretty_path(@user.nickname) if @user
diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb
index ca40bf05..c5f0984c 100644
--- a/app/controllers/users/omniauth_callbacks_controller.rb
+++ b/app/controllers/users/omniauth_callbacks_controller.rb
@@ -2,32 +2,36 @@
module Users
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
- before_action :load_omniauth_info, only: :github
+ before_action :load_omniauth_info,
+ :load_user_from_omniauth_info,
+ :update_user_from_omniauth_info, only: :github
def github
- @user = User.find_by(nickname: @omniauth_info.nickname) ||
- User.find_by(email: @omniauth_info.email)
-
- if @user.present?
- if @omniauth_info.email.present? && @user.email != @omniauth_info.email
- # update email if it has been changed
- @user.update email: @omniauth_info.email
- end
- elsif @omniauth_info.email.present? # user not found
- @user = User.create_with_omniauth!(@omniauth_info)
- else
- set_flash_message(:error, :failure, kind: 'GitHub', reason: I18n.t('devise.errors.primary_email'))
- redirect_to new_user_session_path and return
- end
-
- @user.update(@omniauth_info.slice(:name, :image).as_json)
-
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: 'GitHub') if is_navigational_format?
end
private
+ def update_user_from_omniauth_info
+ update_hash = @omniauth_info.slice(:name, :image).as_json
+ update_hash[:email] = @omniauth_info.email if @omniauth_info.email.present?
+
+ @user.update(update_hash)
+ end
+
+ def load_user_from_omniauth_info
+ @user = User.find_by(nickname: @omniauth_info.nickname) ||
+ User.find_by(email: @omniauth_info.email)
+ return if @user
+
+ @user = User.create_with_omniauth!(@omniauth_info) if @omniauth_info.email.present?
+ return if @user
+
+ set_flash_message(:error, :failure, kind: 'GitHub', reason: I18n.t('devise.errors.primary_email'))
+ redirect_to new_user_session_path
+ end
+
def load_omniauth_info
@omniauth_info = request.env['omniauth.auth']['info']
return if @omniauth_info
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 60fca9b2..75ca81d6 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -4,17 +4,17 @@ class UsersController < ApplicationController
before_action :authenticate_user!, :load_user, :valid_user!, except: %i[login index]
before_action :redirect_to_pretty_url, only: [:show]
+ def index
+ @users = User.order(withdrawn_amount: :desc, commits_count: :desc).where('commits_count > 0 AND withdrawn_amount > 0').page(params[:page]).per(30)
+ end
+
def show
@user_tips = @user.tips
@recent_tips = @user_tips.includes(:project).order(created_at: :desc).first(5)
end
- def index
- @users = User.order(withdrawn_amount: :desc, commits_count: :desc).where('commits_count > 0 AND withdrawn_amount > 0').page(params[:page]).per(30)
- end
-
def update
- if @user.update_attributes(users_params)
+ if @user.update(users_params)
redirect_to @user, notice: I18n.t('notices.user_updated')
else
show
@@ -54,7 +54,7 @@ def users_params
def load_user
@user = User.where(id: params[:id]).first if params[:id].present?
- @user ||= User.first_by_nickname(params[:nickname]) if params[:nickname].present?
+ @user ||= User.find_by_nickname(params[:nickname]) if params[:nickname].present?
user_not_found unless @user
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 67b38124..e4474169 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,171 +1,6 @@
# frozen_string_literal: true
module ApplicationHelper
- def btc_human(amount, options = {})
- amount ||= 0
- nobr = options.key?(:nobr) ? options[:nobr] : true
- denom = if options.key?(:denom)
- options[:denom]
- else
- (try(:current_user) ? current_user.denom : 0)
- end
- case denom
- when 0
- btc = to_btc(amount)
- when 1
- btc = to_mbtc(amount)
- when 2
- btc = to_ubtc(amount)
- when 3
- btc = to_satoshi(amount)
- when 4
- btc = to_usd(amount)
- when 5
- btc = to_eur(amount)
- when 6
- btc = to_aud(amount)
- when 7
- btc = to_brl(amount)
- when 8
- btc = to_cad(amount)
- when 9
- btc = to_cny(amount)
- when 10
- btc = to_gbp(amount)
- when 11
- btc = to_idr(amount)
- when 12
- btc = to_ils(amount)
- when 13
- btc = to_jpy(amount)
- when 14
- btc = to_mxn(amount)
- when 15
- btc = to_nok(amount)
- when 16
- btc = to_nzd(amount)
- when 17
- btc = to_pln(amount)
- when 18
- btc = to_ron(amount)
- when 19
- btc = to_rub(amount)
- when 20
- btc = to_sek(amount)
- when 21
- btc = to_sgd(amount)
- when 22
- btc = to_zar(amount)
- end
- btc = "#{btc}" if nobr
- btc.html_safe
- end
-
- def to_btc(satoshies)
- format('%.8f Ƀ', (1.0 * satoshies.to_i / 1e8))
- end
-
- def to_mbtc(satoshies)
- format('%.5f mɃ', (1.0 * satoshies.to_i / 1e5))
- end
-
- def to_ubtc(satoshies)
- format('%.2f μɃ', (1.0 * satoshies.to_i / 1e2))
- end
-
- def to_satoshi(satoshies)
- format('%.0f Satoshi', satoshies)
- end
-
- def to_usd(satoshies)
- format('$%.2f', rate('USD', satoshies))
- end
-
- def to_aud(satoshies)
- format('$%.2f', rate('AUD', satoshies))
- end
-
- def to_eur(satoshies)
- format('%.2f€', rate('EUR', satoshies))
- end
-
- def to_brl(satoshies)
- format('R$%.2f', rate('BRL', satoshies))
- end
-
- def to_cad(satoshies)
- format('$%.2f', rate('CAD', satoshies))
- end
-
- def to_cny(satoshies)
- format('%.2f¥', rate('CNY', satoshies))
- end
-
- def to_gbp(satoshies)
- format('%.2f£', rate('GBP', satoshies))
- end
-
- def to_idr(satoshies)
- format('%.2f Rp', rate('IDR', satoshies))
- end
-
- def to_ils(satoshies)
- format('%.2f₪', rate('ILS', satoshies))
- end
-
- def to_jpy(satoshies)
- format('%.2f¥', rate('JPY', satoshies))
- end
-
- def to_mxn(satoshies)
- format('%.2f MXN', rate('MXN', satoshies))
- end
-
- def to_nok(satoshies)
- format('%.2f kr', rate('NOK', satoshies))
- end
-
- def to_nzd(satoshies)
- format('$%.2f', rate('NZD', satoshies))
- end
-
- def to_pln(satoshies)
- format('%.2f zł', rate('PLN', satoshies))
- end
-
- def to_ron(satoshies)
- format('%.2f lei', rate('RON', satoshies))
- end
-
- def to_rub(satoshies)
- format('%.2f₽', rate('RUB', satoshies))
- end
-
- def to_sek(satoshies)
- format('%.2f kr', rate('SEK', satoshies))
- end
-
- def to_sgd(satoshies)
- format('%.2f S$', rate('SGD', satoshies))
- end
-
- def to_zar(satoshies)
- format('%.2f R', rate('ZAR', satoshies))
- end
-
- def rate(currency, satoshies)
- satoshies * 0.00000001 * get_rate(currency)
- end
-
- def get_rate(currency)
- Rails.cache.fetch("####{currency}", expires_in: 1.hours) do
- uri = URI("https://api.coindesk.com/v1/bpi/currentprice/#{currency}.json")
- response = Net::HTTP.get_response(uri)
- hash = JSON.parse(response.body)
- hash['bpi'][currency]['rate_float'].to_f
- end
- end
-
def render_flash_messages
html = []
flash.each do |type, message|
@@ -173,13 +8,13 @@ def render_flash_messages
when 'notice' then :success
when 'alert', 'error' then :danger
end
- html << content_tag(:div, class: "alert alert-#{alert_type}") { message }
+ html << tag.div(class: "alert alert-#{alert_type}") { message }
end
html.join("\n").html_safe
end
def commit_tag(sha1)
- content_tag(:span, truncate(sha1, length: 10, omission: ''), class: 'commit-sha')
+ tag.span(truncate(sha1, length: 10, omission: ''), class: 'commit-sha')
end
def list_friendly_text(a_list, conjunction)
@@ -194,6 +29,6 @@ def list_friendly_text(a_list, conjunction)
end
def block_explorer_tx_url(txid)
- "https://tradeblock.com/bitcoin/tx/#{txid}"
+ "https://mempool.space/tx/#{txid}"
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 349739be..ac49e100 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -8,11 +8,11 @@ def shield_btc_amount(amount)
def shield_color(project)
last_tip = project.tips.order(:created_at).last
- if last_tip.nil? || (Time.now - last_tip.created_at > 30.days)
+ if last_tip.nil? || (Time.zone.now - last_tip.created_at > 30.days)
'red'
- elsif Time.now - last_tip.created_at > 7.days
+ elsif Time.zone.now - last_tip.created_at > 7.days
'yellow'
- elsif Time.now - last_tip.created_at > 1.day
+ elsif Time.zone.now - last_tip.created_at > 1.day
'yellowgreen'
else
'green'
diff --git a/app/helpers/rates_helper.rb b/app/helpers/rates_helper.rb
new file mode 100644
index 00000000..537af960
--- /dev/null
+++ b/app/helpers/rates_helper.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+module RatesHelper
+ DENOMINATIONS = %w[
+ BTC mBTC μBTC Satoshi USD EUR AUD BRL CAD CNY GBP IDR ILS JPY MXN NOK NZD PLN RON RUB SEK SGD ZAR
+ ].freeze
+
+ def denom_options_for_select
+ # [["BTC", "0"], ["mBTC", "1"], ...
+ DENOMINATIONS.each_with_index.map { |label, index| [label, index.to_s] }
+ end
+
+ def btc_human(amount, options = {})
+ nobr = options.key?(:nobr) ? options[:nobr] : true
+ denom = options.key?(:denom) ? options[:denom] : current_user&.denom || 0
+
+ btc = to_denom(denom, amount)
+ btc = "#{btc}" if nobr
+ btc.html_safe
+ end
+
+ private
+
+ def to_denom(denom, amount)
+ amount ||= 0
+ convert_method_name = "to_#{DENOMINATIONS[denom].gsub('μ', 'u').downcase}"
+ send(convert_method_name, amount)
+ end
+
+ def to_btc(satoshies)
+ format('%.8f Ƀ', (1.0 * satoshies.to_i / 1e8))
+ end
+
+ def to_mbtc(satoshies)
+ format('%.5f mɃ', (1.0 * satoshies.to_i / 1e5))
+ end
+
+ def to_ubtc(satoshies)
+ format('%.2f μɃ', (1.0 * satoshies.to_i / 1e2))
+ end
+
+ def to_satoshi(satoshies)
+ format('%.0f Satoshi', satoshies)
+ end
+
+ def to_usd(satoshies)
+ format('$%.2f', rate('USD', satoshies))
+ end
+
+ def to_aud(satoshies)
+ format('$%.2f', rate('AUD', satoshies))
+ end
+
+ def to_eur(satoshies)
+ format('%.2f€', rate('EUR', satoshies))
+ end
+
+ def to_brl(satoshies)
+ format('R$%.2f', rate('BRL', satoshies))
+ end
+
+ def to_cad(satoshies)
+ format('$%.2f', rate('CAD', satoshies))
+ end
+
+ def to_cny(satoshies)
+ format('%.2f¥', rate('CNY', satoshies))
+ end
+
+ def to_gbp(satoshies)
+ format('%.2f£', rate('GBP', satoshies))
+ end
+
+ def to_idr(satoshies)
+ format('%.2f Rp', rate('IDR', satoshies))
+ end
+
+ def to_ils(satoshies)
+ format('%.2f₪', rate('ILS', satoshies))
+ end
+
+ def to_jpy(satoshies)
+ format('%.2f¥', rate('JPY', satoshies))
+ end
+
+ def to_mxn(satoshies)
+ format('%.2f MXN', rate('MXN', satoshies))
+ end
+
+ def to_nok(satoshies)
+ format('%.2f kr', rate('NOK', satoshies))
+ end
+
+ def to_nzd(satoshies)
+ format('$%.2f', rate('NZD', satoshies))
+ end
+
+ def to_pln(satoshies)
+ format('%.2f zł', rate('PLN', satoshies))
+ end
+
+ def to_ron(satoshies)
+ format('%.2f lei', rate('RON', satoshies))
+ end
+
+ def to_rub(satoshies)
+ format('%.2f₽', rate('RUB', satoshies))
+ end
+
+ def to_sek(satoshies)
+ format('%.2f kr', rate('SEK', satoshies))
+ end
+
+ def to_sgd(satoshies)
+ format('%.2f S$', rate('SGD', satoshies))
+ end
+
+ def to_zar(satoshies)
+ format('%.2f R', rate('ZAR', satoshies))
+ end
+
+ def rate(currency, satoshies)
+ satoshies * 0.00000001 * get_rate(currency)
+ end
+
+ def get_rate(currency)
+ Rails.cache.fetch("####{currency}", expires_in: 1.hour) do
+ uri = URI("https://api.coindesk.com/v1/bpi/currentprice/#{currency}.json")
+ response = Net::HTTP.get_response(uri)
+ hash = JSON.parse(response.body)
+ hash['bpi'][currency]['rate_float'].to_f
+ end
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index 10df1669..70d72905 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -138,8 +138,8 @@ def tip_for(commit)
# create a tip
tip = tips.create(
- user: user,
- amount: amount,
+ user:,
+ amount:,
commit: commit.sha,
commit_message: commit.commit.message
)
@@ -236,11 +236,11 @@ def generate_bitcoin_address
class << self
def export_labels
- Hash[pluck(:bitcoin_address, :full_name)].to_json
+ pluck(:bitcoin_address, :full_name).to_h.to_json
end
- def first_by_service_and_repo(service, repo)
- where(host: service).where('lower(`full_name`) = ?', repo.downcase).first
+ def find_by_service_and_repo(service, repo)
+ where(host: service).find_by('lower(`full_name`) = ?', repo.downcase)
end
end
end
diff --git a/app/models/tip.rb b/app/models/tip.rb
index 89cdabf8..1def86ca 100644
--- a/app/models/tip.rb
+++ b/app/models/tip.rb
@@ -136,7 +136,7 @@ def check_amount_against_project
end
def touch_decided_at_if_decided
- self.decided_at = Time.now if amount_changed? && decided?
+ self.decided_at = Time.zone.now if amount_changed? && decided?
end
def project_name
diff --git a/app/models/user.rb b/app/models/user.rb
index bf06cfe3..563b468b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -77,11 +77,11 @@ def find_by_commit(commit)
email = commit.commit.author.email
nickname = commit.author.try(:login)
- find_by(email: email) || (nickname.blank? ? nil : find_by(nickname: nickname))
+ find_by(email:) || (nickname.blank? ? nil : find_by(nickname:))
end
- def first_by_nickname(nickname)
- where('lower(`nickname`) = ?', nickname.downcase).first
+ def find_by_nickname(nickname)
+ find_by('lower(`nickname`) = ?', nickname.downcase)
end
end
@@ -94,7 +94,7 @@ def gravatar
def set_login_token!
loop do
self.login_token = SecureRandom.urlsafe_base64
- break login_token unless User.exists?(login_token: login_token)
+ break login_token unless User.exists?(login_token:)
end
end
end
diff --git a/app/models/wallet.rb b/app/models/wallet.rb
index 920f70b3..9b300cfa 100644
--- a/app/models/wallet.rb
+++ b/app/models/wallet.rb
@@ -4,7 +4,7 @@ class Wallet < ApplicationRecord
validates :name, :xpub, presence: true
def generate_address
- address = hd_wallet.node_for_path("0/#{last_address_index}.pub").to_address
+ address = address_by_index(last_address_index)
self.last_address_index += 1
save
address
diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml
index 4cbba835..0dbbffa5 100644
--- a/app/views/devise/confirmations/new.html.haml
+++ b/app/views/devise/confirmations/new.html.haml
@@ -1,6 +1,6 @@
= bootstrap_form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post, class: 'form-devise' }) do |f|
%h2= t('.title')
- = devise_error_messages!
+ = render "devise/shared/error_messages", resource: resource
= f.email_field :email, :autofocus => true
= f.submit t('.submit'), class: 'btn btn-primary'
%p
diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml
index 024a7f6d..55309a98 100644
--- a/app/views/devise/passwords/edit.html.haml
+++ b/app/views/devise/passwords/edit.html.haml
@@ -1,6 +1,6 @@
= bootstrap_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put, class: 'form-devise' }) do |f|
%h2= t('.title')
- = devise_error_messages!
+ = render "devise/shared/error_messages", resource: resource
= f.hidden_field :reset_password_token
= f.password_field :password, :autofocus => true, :autocomplete => "off"
= f.password_field :password_confirmation, :autocomplete => "off"
diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml
index ff2947a9..5eff00b0 100644
--- a/app/views/devise/passwords/new.html.haml
+++ b/app/views/devise/passwords/new.html.haml
@@ -1,6 +1,6 @@
= bootstrap_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post, class: 'form-devise', role: 'form' }) do |f|
%h2= t('.title')
- = devise_error_messages!
+ = render "devise/shared/error_messages", resource: resource
= f.email_field :email, :autofocus => true
= f.submit t('.submit'), class: 'btn btn-primary'
%p
diff --git a/app/views/devise/unlocks/new.html.haml b/app/views/devise/unlocks/new.html.haml
index d3c87d07..932e66f4 100644
--- a/app/views/devise/unlocks/new.html.haml
+++ b/app/views/devise/unlocks/new.html.haml
@@ -1,6 +1,6 @@
%h2 Resend unlock instructions
= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f|
- = devise_error_messages!
+ = render "devise/shared/error_messages", resource: resource
%div
= f.label :email
%br/
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 44b97a64..2ae12731 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -5,7 +5,7 @@
= btc_human @user.balance
= form_for(@user) do |f|
= f.select :denom,
- options_for_select([["BTC", "0"], ["mBTC", "1"], ["μBTC", "2"], ["Satoshi", "3"], ["USD", "4"], ["EUR", "5"], ["AUD", "6"], ["BRL", "7"], ["CAD", "8"], ["CNY", "9"], ["GBP", "10"], ["IDR", "11"], ["ILS", "12"], ["JPY", "13"], ["MXN", "14"], ["NOK", "15"], ["NZD", "16"], ["PLN", "17"], ["RON", "18"], ["RUB", "19"], ["SEK", "20"], ["SGD", "21"], ["ZAR", "22"]], selected: @user.denom)
+ options_for_select(denom_options_for_select, selected: @user.denom)
= f.submit "save"
%p
%small= raw t('.threshold', threshold: btc_human(CONFIG["min_payout"]))
@@ -53,4 +53,4 @@
= bootstrap_form_for @user, html: {class: (params[:delete_user] ? '' : 'collapse'), id: 'delete_user_form', method: 'DELETE'} do |f|
%p= t('.delete_account_notice')
= f.text_field :email, value: '', autocomplete: "off"
- = f.submit t('.delete_account_confirm'), class: 'btn btn-danger'
\ No newline at end of file
+ = f.submit t('.delete_account_confirm'), class: 'btn btn-danger'
diff --git a/bin/rails b/bin/rails
index 07396602..6fb4e405 100755
--- a/bin/rails
+++ b/bin/rails
@@ -1,4 +1,4 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)
-require_relative '../config/boot'
-require 'rails/commands'
+require_relative "../config/boot"
+require "rails/commands"
diff --git a/bin/rake b/bin/rake
index 17240489..4fbf10b9 100755
--- a/bin/rake
+++ b/bin/rake
@@ -1,4 +1,4 @@
#!/usr/bin/env ruby
-require_relative '../config/boot'
-require 'rake'
+require_relative "../config/boot"
+require "rake"
Rake.application.run
diff --git a/bin/setup b/bin/setup
index 94fd4d79..90700ac4 100755
--- a/bin/setup
+++ b/bin/setup
@@ -1,6 +1,5 @@
#!/usr/bin/env ruby
-require 'fileutils'
-include FileUtils
+require "fileutils"
# path to your application root.
APP_ROOT = File.expand_path('..', __dir__)
@@ -9,24 +8,25 @@ def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
-chdir APP_ROOT do
- # This script is a starting point to setup your application.
+FileUtils.chdir APP_ROOT do
+ # This script is a way to set up or update your development environment automatically.
+ # This script is idempotent, so that you can run it at any time and get an expectable outcome.
# Add necessary setup steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
- # Install JavaScript dependencies if using Yarn
- # system('bin/yarn')
+ # Install JavaScript dependencies
+ system! 'bin/yarn'
# puts "\n== Copying sample files =="
# unless File.exist?('config/database.yml')
- # cp 'config/database.yml.sample', 'config/database.yml'
+ # FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
# end
puts "\n== Preparing database =="
- system! 'bin/rails db:setup'
+ system! 'bin/rails db:prepare'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
diff --git a/bin/yarn b/bin/yarn
index 460dd565..9fab2c35 100755
--- a/bin/yarn
+++ b/bin/yarn
@@ -1,9 +1,15 @@
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do
- begin
- exec "yarnpkg", *ARGV
- rescue Errno::ENOENT
+ yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
+ select { |dir| File.expand_path(dir) != __dir__ }.
+ product(["yarn", "yarn.cmd", "yarn.ps1"]).
+ map { |dir, file| File.expand_path(file, dir) }.
+ find { |file| File.executable?(file) }
+
+ if yarn
+ exec yarn, *ARGV
+ else
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1
diff --git a/config.ru b/config.ru
index 667e328d..afd13e21 100644
--- a/config.ru
+++ b/config.ru
@@ -2,5 +2,5 @@
# This file is used by Rack-based servers to start the application.
-require ::File.expand_path('config/environment', __dir__)
+require File.expand_path('config/environment', __dir__)
run Rails.application
diff --git a/config/application.rb b/config/application.rb
index e2412382..fafdcf59 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -28,8 +28,6 @@ class Application < Rails::Application
config.autoload_paths += %W[#{config.root}/lib]
config.assets.initialize_on_precompile = true
config.available_locales = %w[en es fr nl ru pl hr de ro ko id ja pt my cn hk]
- config.active_job.queue_adapter = :sidekiq
- config.active_record.sqlite3.represent_boolean_as_integer = true
end
end
diff --git a/config/deploy.rb b/config/deploy.rb
index 73aa10e3..8b639376 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -8,7 +8,7 @@
set :deploy_to, '/home/apps/t4c'
set :rvm_type, :user
-set :rvm_ruby_version, '2.6.6'
+set :rvm_ruby_version, '3.2.6'
set :rvm_custom_path, '~/.rvm'
set :format, :pretty
diff --git a/config/deploy/production.rb b/config/deploy/production.rb
index 13bcd143..714353d5 100644
--- a/config/deploy/production.rb
+++ b/config/deploy/production.rb
@@ -7,9 +7,9 @@
# Supports bulk-adding hosts to roles, the primary
# server in each group is considered to be the first
# unless any hosts have the primary property set.
-role :app, %w[apps@50.116.2.58]
-role :web, %w[apps@50.116.2.58]
-role :db, %w[apps@50.116.2.58]
+role :app, %w[apps@tip4commit]
+role :web, %w[apps@tip4commit]
+role :db, %w[apps@tip4commit]
set :rails_env, 'production'
set :migration_role, 'db'
diff --git a/config/environments/production.rb b/config/environments/production.rb
index d2103f50..034d4342 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -84,5 +84,5 @@
# config.autoflush_log = false
# Use default logging formatter so that PID and timestamp are not suppressed.
- config.log_formatter = ::Logger::Formatter.new
+ config.log_formatter = Logger::Formatter.new
end
diff --git a/config/locales/de.yml b/config/locales/de.yml
index b2ea2e77..c8f0cef6 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -2,7 +2,7 @@ de:
tip4commit: Tip4Commit
meta:
title: Tragen Sie zu Open-Source-Projekten bei
- description: Spenden Sie bitcoins an Projekte die Sie interessieren oder fügen Sie commits hinzu um Trinkgelder zu erhalten
+ description: Spenden Sie Bitcoins an Projekte die Sie interessieren oder fügen Sie Commits hinzu um Trinkgelder zu erhalten
menu:
home: Home
projects: Unterstützte Projekte
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 969ae7ff..171a69a1 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -233,6 +233,6 @@ en:
general:
or: or
disclaimer:
- line1: "Tip4Commit is not affiliated with most of the projects."
+ line1: "Tip4Commit is not affiliated with most of these projects."
line2: "There is no guarantee that tips will be claimed by developers."
line3: "By donating the funds you agree that they can be sent to the Free Software Foundation or elsewhere at Tip4Commit's discretion."
diff --git a/config/routes.rb b/config/routes.rb
index 03fe0cd4..c1f67992 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -8,9 +8,9 @@
get '/users/login' => 'users#login', :as => 'login_users'
get '/users/:user_id/tips' => 'tips#index', :constraints => { user_id: /\d+/ }, :as => 'user_tips'
- get '/users/:nickname/tips' => 'tips#index', :constraints => { nickname: /\w[\d\w\-]*/ }, :as => 'user_tips_pretty'
+ get '/users/:nickname/tips' => 'tips#index', :constraints => { nickname: /\w[\d\w-]*/ }, :as => 'user_tips_pretty'
get '/users/:id' => 'users#show', :constraints => { id: /\d+/ }, :as => 'user'
- get '/users/:nickname' => 'users#show', :constraints => { nickname: /\w[\d\w\-]*/ }, :as => 'user_pretty'
+ get '/users/:nickname' => 'users#show', :constraints => { nickname: /\w[\d\w-]*/ }, :as => 'user_pretty'
get '/projects/:project_id/tips' => 'tips#index', :constraints => { project_id: /\d+/ }, :as => 'project_tips'
get '/projects/:project_id/deposits' => 'deposits#index', :constraints => { project_id: /\d+/ }, :as => 'project_deposits'
diff --git a/db/migrate/20131019133109_devise_create_users.rb b/db/migrate/20131019133109_devise_create_users.rb
index 156e258d..c87e3306 100644
--- a/db/migrate/20131019133109_devise_create_users.rb
+++ b/db/migrate/20131019133109_devise_create_users.rb
@@ -33,11 +33,11 @@ def change
# t.datetime :locked_at
t.timestamps
- end
- add_index :users, :email, unique: true
- add_index :users, :reset_password_token, unique: true
- # add_index :users, :confirmation_token, :unique => true
- # add_index :users, :unlock_token, :unique => true
+ t.index :email, unique: true
+ t.index :reset_password_token, unique: true
+ # t.index :confirmation_token, unique: true
+ # t.index :unlock_token, unique: true
+ end
end
end
diff --git a/db/migrate/20131019133235_add_columns_to_users.rb b/db/migrate/20131019133235_add_columns_to_users.rb
index 8e06d45a..781b1f54 100644
--- a/db/migrate/20131019133235_add_columns_to_users.rb
+++ b/db/migrate/20131019133235_add_columns_to_users.rb
@@ -2,8 +2,10 @@
class AddColumnsToUsers < ActiveRecord::Migration[4.2]
def change
- add_column :users, :nickname, :string
- add_column :users, :name, :string
- add_column :users, :image, :string
+ change_table :users, bulk: true do |t|
+ t.column :nickname, :string
+ t.column :name, :string
+ t.column :image, :string
+ end
end
end
diff --git a/db/migrate/20131019175751_add_some_fields_to_projects.rb b/db/migrate/20131019175751_add_some_fields_to_projects.rb
index 7c28bdb9..959dbf6f 100644
--- a/db/migrate/20131019175751_add_some_fields_to_projects.rb
+++ b/db/migrate/20131019175751_add_some_fields_to_projects.rb
@@ -2,11 +2,13 @@
class AddSomeFieldsToProjects < ActiveRecord::Migration[4.2]
def change
- add_column :projects, :name, :string
- add_column :projects, :full_name, :string
- add_column :projects, :source_full_name, :string
- add_column :projects, :description, :string
- add_column :projects, :watchers_count, :integer
- add_column :projects, :language, :string
+ change_table :projects, bulk: true do |t|
+ t.column :name, :string
+ t.column :full_name, :string
+ t.column :source_full_name, :string
+ t.column :description, :string
+ t.column :watchers_count, :integer
+ t.column :language, :string
+ end
end
end
diff --git a/db/migrate/20131030142749_drop_deposit_from_tip.rb b/db/migrate/20131030142749_drop_deposit_from_tip.rb
index da281869..90044a69 100644
--- a/db/migrate/20131030142749_drop_deposit_from_tip.rb
+++ b/db/migrate/20131030142749_drop_deposit_from_tip.rb
@@ -1,7 +1,11 @@
# frozen_string_literal: true
class DropDepositFromTip < ActiveRecord::Migration[4.2]
- def change
+ def up
remove_column :tips, :deposit_id
end
+
+ def down
+ add_reference :tips, :deposit, index: true
+ end
end
diff --git a/db/migrate/20131212190037_add_cache_to_users.rb b/db/migrate/20131212190037_add_cache_to_users.rb
index 5e47b789..1ecedd08 100644
--- a/db/migrate/20131212190037_add_cache_to_users.rb
+++ b/db/migrate/20131212190037_add_cache_to_users.rb
@@ -2,7 +2,9 @@
class AddCacheToUsers < ActiveRecord::Migration[4.2]
def change
- add_column :users, :commits_count, :integer, default: 0
- add_column :users, :withdrawn_amount, :integer, limit: 8, default: 0
+ change_table :users, bulk: true do |t|
+ t.column :commits_count, :integer, default: 0
+ t.column :withdrawn_amount, :integer, limit: 8, default: 0
+ end
end
end
diff --git a/db/migrate/20140102095035_add_refunded_at_to_tips.rb b/db/migrate/20140102095035_add_refunded_at_to_tips.rb
index 05d80cb5..5653751d 100644
--- a/db/migrate/20140102095035_add_refunded_at_to_tips.rb
+++ b/db/migrate/20140102095035_add_refunded_at_to_tips.rb
@@ -1,8 +1,17 @@
# frozen_string_literal: true
class AddRefundedAtToTips < ActiveRecord::Migration[4.2]
- def change
- add_column :tips, :refunded_at, :timestamp
- remove_column :tips, :is_refunded, :boolean
+ def up
+ change_table :tips, bulk: true do |t|
+ t.column :refunded_at, :timestamp
+ t.remove :is_refunded
+ end
+ end
+
+ def down
+ change_table :tips, bulk: true do |t|
+ t.remove :refunded_at
+ t.column :is_refunded, :boolean
+ end
end
end
diff --git a/db/migrate/20140209041123_create_indexes_for_projects.rb b/db/migrate/20140209041123_create_indexes_for_projects.rb
index d51f16bf..8a3345c8 100644
--- a/db/migrate/20140209041123_create_indexes_for_projects.rb
+++ b/db/migrate/20140209041123_create_indexes_for_projects.rb
@@ -2,7 +2,9 @@
class CreateIndexesForProjects < ActiveRecord::Migration[4.2]
def change
- add_index :projects, :full_name, unique: true
- add_index :projects, :github_id, unique: true
+ change_table :projects, bulk: true do |t|
+ t.index :full_name, unique: true
+ t.index :github_id, unique: true
+ end
end
end
diff --git a/db/migrate/20140223061035_add_project_host.rb b/db/migrate/20140223061035_add_project_host.rb
index 60fb7f07..d5e4c9d8 100644
--- a/db/migrate/20140223061035_add_project_host.rb
+++ b/db/migrate/20140223061035_add_project_host.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class AddProjectHost < ActiveRecord::Migration[4.2]
- class Project < ActiveRecord::Base
+ class Project < ApplicationRecord
end
def change
diff --git a/db/migrate/20140402082149_add_fee_size_to_deposits.rb b/db/migrate/20140402082149_add_fee_size_to_deposits.rb
index 9a4ff742..8811847b 100644
--- a/db/migrate/20140402082149_add_fee_size_to_deposits.rb
+++ b/db/migrate/20140402082149_add_fee_size_to_deposits.rb
@@ -1,13 +1,17 @@
# frozen_string_literal: true
class AddFeeSizeToDeposits < ActiveRecord::Migration[4.2]
- class Deposit < ActiveRecord::Base
+ class Deposit < ApplicationRecord
end
def change
- add_column :deposits, :fee_size, :float
- remove_column :deposits, :duration, :integer
reversible do |dir|
+ change_table :deposits, bulk: true do |t|
+ t.column :fee_size, :float
+ dir.up { t.remove :duration, :integer }
+ dir.down { t.column :duration }
+ end
+
# Update all existing deposits
dir.up { Deposit.update_all(fee_size: CONFIG['our_fee']) }
end
diff --git a/db/migrate/20140722092532_add_confirmation_fields_to_users.rb b/db/migrate/20140722092532_add_confirmation_fields_to_users.rb
index cb9fa533..5084b78f 100644
--- a/db/migrate/20140722092532_add_confirmation_fields_to_users.rb
+++ b/db/migrate/20140722092532_add_confirmation_fields_to_users.rb
@@ -2,9 +2,11 @@
class AddConfirmationFieldsToUsers < ActiveRecord::Migration[4.2]
def change
- add_column :users, :confirmed_at, :timestamp
- add_column :users, :confirmation_sent_at, :timestamp
- add_column :users, :confirmation_token, :string
- add_column :users, :unconfirmed_email, :string
+ change_table :users, bulk: true do |t|
+ t.column :confirmation_token, :string
+ t.column :confirmation_sent_at, :timestamp
+ t.column :confirmed_at, :timestamp
+ t.column :unconfirmed_email, :string
+ end
end
end
diff --git a/db/migrate/20140816062159_remove_paid_out_from_deposits.rb b/db/migrate/20140816062159_remove_paid_out_from_deposits.rb
index 240add45..e8cbff1e 100644
--- a/db/migrate/20140816062159_remove_paid_out_from_deposits.rb
+++ b/db/migrate/20140816062159_remove_paid_out_from_deposits.rb
@@ -1,8 +1,17 @@
# frozen_string_literal: true
class RemovePaidOutFromDeposits < ActiveRecord::Migration[4.2]
- def change
- remove_column :deposits, :paid_out, :integer, limit: 8
- remove_column :deposits, :paid_out_at, :datetime
+ def up
+ change_table :deposits, bulk: true do |t|
+ t.remove :paid_out
+ t.remove :paid_out_at
+ end
+ end
+
+ def down
+ change_table :deposits, bulk: true do |t|
+ t.add :paid_out, :integer, limit: 8
+ t.add :paid_out_at, :datetime
+ end
end
end
diff --git a/db/migrate/20151219081507_add_bitcoin_address2_to_projects.rb b/db/migrate/20151219081507_add_bitcoin_address2_to_projects.rb
index 4ac4957d..1f4122d4 100644
--- a/db/migrate/20151219081507_add_bitcoin_address2_to_projects.rb
+++ b/db/migrate/20151219081507_add_bitcoin_address2_to_projects.rb
@@ -2,7 +2,8 @@
class AddBitcoinAddress2ToProjects < ActiveRecord::Migration[4.2]
def change
- add_column :projects, :bitcoin_address2, :string, index: true
+ add_column :projects, :bitcoin_address2, :string
+ add_index :projects, :bitcoin_address2
reversible do |dir|
dir.up do
Project.find_each(&:generate_address2)
diff --git a/db/schema.rb b/db/schema.rb
index 02ad5898..4227cedf 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1,144 +1,137 @@
-# encoding: UTF-8
-# frozen_string_literal: true
-
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
-# Note that this schema.rb definition is the authoritative source for your
-# database schema. If you need to create the application database on another
-# system, you should be using db:schema:load, not running all the migrations
-# from scratch. The latter is a flawed and unsustainable approach (the more migrations
-# you'll amass, the slower it'll run and the greater likelihood for issues).
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20170308163825) do
- create_table 'collaborators', force: :cascade do |t|
- t.integer 'project_id', limit: 4
- t.string 'login', limit: 255
- t.datetime 'created_at'
- t.datetime 'updated_at'
- end
-
- add_index 'collaborators', ['project_id'], name: 'index_collaborators_on_project_id', using: :btree
+ActiveRecord::Schema.define(version: 2017_03_08_163825) do
- create_table 'deposits', force: :cascade do |t|
- t.integer 'project_id', limit: 4
- t.string 'txid', limit: 255
- t.integer 'confirmations', limit: 4
- t.datetime 'created_at'
- t.datetime 'updated_at'
- t.integer 'amount', limit: 8
- t.float 'fee_size', limit: 24
+ create_table "collaborators", force: :cascade do |t|
+ t.integer "project_id"
+ t.string "login"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["project_id"], name: "index_collaborators_on_project_id"
end
- add_index 'deposits', ['project_id'], name: 'index_deposits_on_project_id', using: :btree
-
- create_table 'projects', force: :cascade do |t|
- t.string 'url', limit: 255
- t.string 'bitcoin_address', limit: 255
- t.datetime 'created_at'
- t.datetime 'updated_at'
- t.string 'name', limit: 255
- t.string 'full_name', limit: 255
- t.string 'source_full_name', limit: 255
- t.text 'description', limit: 65535
- t.integer 'watchers_count', limit: 4
- t.string 'language', limit: 255
- t.string 'last_commit', limit: 255
- t.integer 'available_amount_cache', limit: 4
- t.string 'github_id', limit: 255
- t.string 'host', limit: 255, default: 'github'
- t.boolean 'hold_tips', default: false
- t.datetime 'info_updated_at'
- t.string 'branch', limit: 255
- t.boolean 'disable_notifications'
- t.string 'avatar_url', limit: 255
- t.datetime 'deleted_at'
- t.string 'bitcoin_address2', limit: 255
- t.integer 'wallet_id', limit: 4
- t.string 'legacy_address', limit: 255
+ create_table "deposits", force: :cascade do |t|
+ t.integer "project_id"
+ t.string "txid"
+ t.integer "confirmations"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "amount", limit: 8
+ t.float "fee_size"
+ t.index ["project_id"], name: "index_deposits_on_project_id"
end
- add_index 'projects', ['full_name'], name: 'index_projects_on_full_name', unique: true, using: :btree
- add_index 'projects', ['github_id'], name: 'index_projects_on_github_id', unique: true, using: :btree
-
- create_table 'sendmanies', force: :cascade do |t|
- t.string 'txid', limit: 255
- t.text 'data', limit: 65535
- t.string 'result', limit: 255
- t.boolean 'is_error'
- t.datetime 'created_at'
- t.datetime 'updated_at'
+ create_table "projects", force: :cascade do |t|
+ t.string "url"
+ t.string "bitcoin_address"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "name"
+ t.string "full_name"
+ t.string "source_full_name"
+ t.text "description"
+ t.integer "watchers_count"
+ t.string "language"
+ t.string "last_commit"
+ t.integer "available_amount_cache"
+ t.string "github_id"
+ t.string "host", default: "github"
+ t.boolean "hold_tips", default: false
+ t.datetime "info_updated_at"
+ t.string "branch"
+ t.boolean "disable_notifications"
+ t.string "avatar_url"
+ t.datetime "deleted_at"
+ t.string "bitcoin_address2"
+ t.integer "wallet_id"
+ t.string "legacy_address"
+ t.index ["full_name"], name: "index_projects_on_full_name", unique: true
+ t.index ["github_id"], name: "index_projects_on_github_id", unique: true
end
- create_table 'tipping_policies_texts', force: :cascade do |t|
- t.integer 'project_id', limit: 4
- t.integer 'user_id', limit: 4
- t.text 'text', limit: 65535
- t.datetime 'created_at'
- t.datetime 'updated_at'
+ create_table "sendmanies", force: :cascade do |t|
+ t.string "txid"
+ t.text "data"
+ t.string "result"
+ t.boolean "is_error"
+ t.datetime "created_at"
+ t.datetime "updated_at"
end
- add_index 'tipping_policies_texts', ['project_id'], name: 'index_tipping_policies_texts_on_project_id', using: :btree
- add_index 'tipping_policies_texts', ['user_id'], name: 'index_tipping_policies_texts_on_user_id', using: :btree
-
- create_table 'tips', force: :cascade do |t|
- t.integer 'user_id', limit: 4
- t.integer 'amount', limit: 8
- t.integer 'sendmany_id', limit: 4
- t.datetime 'created_at'
- t.datetime 'updated_at'
- t.string 'commit', limit: 255
- t.integer 'project_id', limit: 4
- t.datetime 'refunded_at'
- t.text 'commit_message', limit: 65535
- t.datetime 'decided_at'
+ create_table "tipping_policies_texts", force: :cascade do |t|
+ t.integer "project_id"
+ t.integer "user_id"
+ t.text "text"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["project_id"], name: "index_tipping_policies_texts_on_project_id"
+ t.index ["user_id"], name: "index_tipping_policies_texts_on_user_id"
end
- add_index 'tips', ['project_id'], name: 'index_tips_on_project_id', using: :btree
- add_index 'tips', ['sendmany_id'], name: 'index_tips_on_sendmany_id', using: :btree
- add_index 'tips', ['user_id'], name: 'index_tips_on_user_id', using: :btree
-
- create_table 'users', force: :cascade do |t|
- t.string 'email', limit: 255, default: '', null: false
- t.string 'encrypted_password', limit: 255, default: '', null: false
- t.string 'reset_password_token', limit: 255
- t.datetime 'reset_password_sent_at'
- t.datetime 'remember_created_at'
- t.integer 'sign_in_count', limit: 4, default: 0, null: false
- t.datetime 'current_sign_in_at'
- t.datetime 'last_sign_in_at'
- t.string 'current_sign_in_ip', limit: 255
- t.string 'last_sign_in_ip', limit: 255
- t.datetime 'created_at'
- t.datetime 'updated_at'
- t.string 'nickname', limit: 255
- t.string 'name', limit: 255
- t.string 'image', limit: 255
- t.string 'bitcoin_address', limit: 255
- t.string 'login_token', limit: 255
- t.boolean 'unsubscribed'
- t.datetime 'notified_at'
- t.integer 'commits_count', limit: 4, default: 0
- t.integer 'withdrawn_amount', limit: 8, default: 0
- t.datetime 'confirmed_at'
- t.datetime 'confirmation_sent_at'
- t.string 'confirmation_token', limit: 255
- t.string 'unconfirmed_email', limit: 255
- t.string 'display_name', limit: 255
- t.integer 'denom', limit: 4, default: 0
+ create_table "tips", force: :cascade do |t|
+ t.integer "user_id"
+ t.integer "amount", limit: 8
+ t.integer "sendmany_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "commit"
+ t.integer "project_id"
+ t.datetime "refunded_at"
+ t.text "commit_message"
+ t.datetime "decided_at"
+ t.index ["project_id"], name: "index_tips_on_project_id"
+ t.index ["sendmany_id"], name: "index_tips_on_sendmany_id"
+ t.index ["user_id"], name: "index_tips_on_user_id"
end
- add_index 'users', ['email'], name: 'index_users_on_email', unique: true, using: :btree
- add_index 'users', ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true, using: :btree
+ create_table "users", force: :cascade do |t|
+ t.string "email", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
+ t.string "reset_password_token"
+ t.datetime "reset_password_sent_at"
+ t.datetime "remember_created_at"
+ t.integer "sign_in_count", default: 0, null: false
+ t.datetime "current_sign_in_at"
+ t.datetime "last_sign_in_at"
+ t.string "current_sign_in_ip"
+ t.string "last_sign_in_ip"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "nickname"
+ t.string "name"
+ t.string "image"
+ t.string "bitcoin_address"
+ t.string "login_token"
+ t.boolean "unsubscribed"
+ t.datetime "notified_at"
+ t.integer "commits_count", default: 0
+ t.integer "withdrawn_amount", limit: 8, default: 0
+ t.string "confirmation_token"
+ t.datetime "confirmation_sent_at"
+ t.datetime "confirmed_at"
+ t.string "unconfirmed_email"
+ t.string "display_name"
+ t.integer "denom", default: 0
+ t.index ["email"], name: "index_users_on_email", unique: true
+ t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
+ end
- create_table 'wallets', force: :cascade do |t|
- t.string 'name', limit: 255
- t.string 'xpub', limit: 255
- t.integer 'last_address_index', limit: 4, default: 1
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
+ create_table "wallets", force: :cascade do |t|
+ t.string "name"
+ t.string "xpub"
+ t.integer "last_address_index", limit: 4, default: 1
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
end
+
end
diff --git a/features/step_definitions/common.rb b/features/step_definitions/common.rb
index 03a29c01..dc5307e3 100644
--- a/features/step_definitions/common.rb
+++ b/features/step_definitions/common.rb
@@ -72,7 +72,7 @@ def parse_path_from_page_string(page_string)
# explicit cases
# e.g. "a-user/a-project github-project edit"
# e.g. "a-user user edit"
- tokens = page_string.split ' '
+ tokens = page_string.split
name = tokens[0]
model = tokens[1]
action = tokens[2] || '' # '' => 'show'
@@ -89,17 +89,18 @@ def parse_path_from_page_string(page_string)
path = "/users/#{name}/#{action}" if is_valid_path # TODO: nyi
# implicit cases
- else case page_string
- when 'home' then path = root_path
- when 'sign_up' then path = new_user_registration_path
- when 'sign_in' then path = new_user_session_path
- when 'users' then path = users_path
- when 'projects' then path = projects_path
- when 'search' then path = search_projects_path
- when 'tips' then path = tips_path
- when 'deposits' then path = deposits_path
- when 'withdrawals' then path = withdrawals_path
- end
+ else
+ case page_string
+ when 'home' then path = root_path
+ when 'sign_up' then path = new_user_registration_path
+ when 'sign_in' then path = new_user_session_path
+ when 'users' then path = users_path
+ when 'projects' then path = projects_path
+ when 'search' then path = search_projects_path
+ when 'tips' then path = tips_path
+ when 'deposits' then path = deposits_path
+ when 'withdrawals' then path = withdrawals_path
+ end
end
path || page_string
diff --git a/features/step_definitions/users_steps.rb b/features/step_definitions/users_steps.rb
index 7984b949..9dffcff0 100644
--- a/features/step_definitions/users_steps.rb
+++ b/features/step_definitions/users_steps.rb
@@ -17,9 +17,9 @@ def create_user(nickname, has_bitcoiin_address)
end
Then(/^a developer named "(.*?)" does not exist$/) do |nickname|
- User.where(nickname: nickname).first.should be_nil
+ User.where(nickname:).first.should be_nil
end
Then(/^a developer named "(.*?)" exists$/) do |nickname|
- User.where(nickname: nickname).first.should_not be_nil
+ User.where(nickname:).first.should_not be_nil
end
diff --git a/features/support/ostruct_slice.rb b/features/support/ostruct_slice.rb
index 95e6ac4d..3267fe82 100644
--- a/features/support/ostruct_slice.rb
+++ b/features/support/ostruct_slice.rb
@@ -3,7 +3,7 @@
require 'ostruct'
class OpenStruct
- def slice(*args, &block)
- marshal_dump.slice(*args, &block)
+ def slice(...)
+ marshal_dump.slice(...)
end
end
diff --git a/lib/bitcoin_address_validator.rb b/lib/bitcoin_address_validator.rb
index 577a0f59..069f390b 100644
--- a/lib/bitcoin_address_validator.rb
+++ b/lib/bitcoin_address_validator.rb
@@ -4,7 +4,9 @@
class BitcoinAddressValidator < ActiveModel::EachValidator
def validate_each(record, field, value)
- record.errors[field] << 'Bitcoin address is invalid' unless value.blank? || valid_bitcoin_address?(value)
+ return if value.blank? || valid_bitcoin_address?(value)
+
+ record.errors.add(field, :invalid, message: 'Bitcoin address is invalid')
end
private
@@ -83,7 +85,7 @@ def b58_decode(value, length)
result = long_value.chr + result
- result = 0.chr * (length - result.length) + result if result.length < length
+ result = (0.chr * (length - result.length)) + result if result.length < length
result
end
diff --git a/lib/bitcoin_tipper.rb b/lib/bitcoin_tipper.rb
index 10506a6c..1cdde599 100644
--- a/lib/bitcoin_tipper.rb
+++ b/lib/bitcoin_tipper.rb
@@ -31,8 +31,8 @@ def check_and_withdrawal_funds
# self.create_sendmany
# end
- Rails.logger.info 'Traversing sendmanies...'
- Sendmany.where(txid: nil).each(&:send_transaction)
+ # Rails.logger.info 'Traversing sendmanies...'
+ # Sendmany.where(txid: nil).each(&:send_transaction)
end
def auto_decide_older_tips
@@ -76,13 +76,13 @@ def create_sendmany
Rails.logger.info 'Creating sendmany'
ActiveRecord::Base.transaction do
sendmany = Sendmany.create
- outs = calculate_outputs
+ outs = calculate_outputs(sendmany)
sendmany.update_attribute :data, outs.to_json
Rails.logger.info " #{sendmany.inspect}"
end
end
- def calculate_outputs
+ def calculate_outputs(sendmany)
outputs = {}
User.find_each do |user|
next unless user.ready_for_withdrawal?
diff --git a/lib/blacklist.rb b/lib/blacklist.rb
index d30d5a75..2fa2733b 100644
--- a/lib/blacklist.rb
+++ b/lib/blacklist.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'set'
-
class Blacklist
def initialize(urls)
urls = urls.map { |u| normalize_url(u) }
diff --git a/lib/tasks/cucumber.rake b/lib/tasks/cucumber.rake
index 4d81c9d1..18999e06 100644
--- a/lib/tasks/cucumber.rake
+++ b/lib/tasks/cucumber.rake
@@ -8,7 +8,7 @@
unless ARGV.any? { |a| a =~ /^gems/ } # Don't load anything when running the gems:* tasks
- vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
+ vendored_cucumber_bin = Dir[Rails.root.join('/vendor/{gems,plugins}/cucumber*/bin/cucumber')].first
$LOAD_PATH.unshift("#{File.dirname(vendored_cucumber_bin)}/../lib") unless vendored_cucumber_bin.nil?
begin
@@ -36,10 +36,10 @@ unless ARGV.any? { |a| a =~ /^gems/ } # Don't load anything when running the gem
desc 'Run all features'
task all: %i[ok wip]
- task :statsetup do
+ task statsetup: :environment do
require 'rails/code_statistics'
- ::STATS_DIRECTORIES << %w[Cucumber\ features features] if File.exist?('features')
- ::CodeStatistics::TEST_TYPES << 'Cucumber features' if File.exist?('features')
+ STATS_DIRECTORIES << ['Cucumber features', 'features'] if File.exist?('features')
+ CodeStatistics::TEST_TYPES << 'Cucumber features' if File.exist?('features')
end
end
desc 'Alias for cucumber:ok'
@@ -51,7 +51,7 @@ unless ARGV.any? { |a| a =~ /^gems/ } # Don't load anything when running the gem
warn "*** The 'features' task is deprecated. See rake -T cucumber ***"
end
- task 'test:prepare' do
+ task 'test:prepare' => :environment do
# In case we don't have the generic Rails test:prepare hook,
# append a no-op task that we can depend upon.
end
@@ -59,7 +59,7 @@ unless ARGV.any? { |a| a =~ /^gems/ } # Don't load anything when running the gem
task stats: 'cucumber:statsetup'
rescue LoadError
desc 'cucumber rake task not available (cucumber not installed)'
- task :cucumber do
+ task cucumber: :environment do
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
end
end
diff --git a/spec/controllers/deposits_controller_spec.rb b/spec/controllers/deposits_controller_spec.rb
index 287e58bf..40f18930 100644
--- a/spec/controllers/deposits_controller_spec.rb
+++ b/spec/controllers/deposits_controller_spec.rb
@@ -9,13 +9,4 @@
expect(response).to be_successful
end
end
-
- describe 'routing' do
- it 'routes GET / to Deposits#index' do
- expect({ get: '/deposits' }).to route_to(
- controller: 'deposits',
- action: 'index'
- )
- end
- end
end
diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb
index 8a6b1e79..09c20eed 100644
--- a/spec/controllers/home_controller_spec.rb
+++ b/spec/controllers/home_controller_spec.rb
@@ -14,36 +14,4 @@
expect(subject.status).to eq 200
end
end
-
- describe 'routing' do
- it 'routes GET / to Home#index' do
- expect({ get: '/' }).to route_to(
- controller: 'home',
- action: 'index'
- )
- end
-
- it 'routes GET /home to Home#index' do
- expect({ get: '/' }).to route_to(
- controller: 'home',
- action: 'index'
- )
- end
-
- it 'routes GET /users/999999/no-such-path to Home#index' do
- expect({ get: '/users/999999/no-such-path' }).to route_to(
- controller: 'home',
- action: 'index',
- path: 'users/999999/no-such-path'
- )
- end
-
- it 'routes GET /any/non-existent/path to Home#index' do
- expect({ get: '/any/non-existent/path' }).to route_to(
- controller: 'home',
- action: 'index',
- path: 'any/non-existent/path'
- )
- end
- end
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index d7d189f3..743fc801 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -5,6 +5,7 @@
describe ProjectsController, type: :controller do
describe 'GET #index' do
let(:subject) { get :index }
+
before do
allow(Project).to receive(:order).with(available_amount_cache: :desc, watchers_count: :desc, full_name: :asc).and_return(Project)
allow(Project).to receive(:page).with(nil).and_return(Project)
@@ -68,9 +69,9 @@
# end
shared_context 'accessing_project' do |verb, action|
- let(:a_project) { create :project, host: 'github', full_name: 'test/test' }
+ let(:a_project) { create(:project, host: 'github', full_name: 'test/test') }
- context 'existing_project' do
+ context 'with existsing project' do
it 'via project id returns 302 status code' do
case verb
when :get
@@ -92,7 +93,7 @@
end
end
- context 'nonexisting_project' do
+ context 'with non-existing project' do
it 'via project id returns 302 status code' do
case verb
when :get
@@ -157,125 +158,4 @@
expect(response).to be_redirect
end
end
-
- describe 'routing' do
- it 'routes GET /projects to Project#index' do
- expect({ get: '/projects' }).to route_to(
- controller: 'projects',
- action: 'index'
- )
- end
-
- it 'routes GET /projects/search?query= to Project#search' do
- expect({ get: '/projects/search?query=seldon&order=balance' }).to route_to(
- controller: 'projects',
- action: 'search',
- query: 'seldon',
- order: 'balance'
- )
- end
-
- it 'routes GET /projects/1 to Project#show' do
- expect({ get: '/projects/1' }).to route_to(
- controller: 'projects',
- action: 'show',
- id: '1'
- )
- end
-
- it 'routes GET /projects/1/edit to Project#edit' do
- expect({ get: '/projects/1/edit' }).to route_to(
- controller: 'projects',
- action: 'edit',
- id: '1'
- )
- end
-
- it 'routes PUT /projects/1 to Project#update' do
- expect({ put: '/projects/1' }).to route_to(
- controller: 'projects',
- action: 'update',
- id: '1'
- )
- end
-
- it 'routes GET /projects/1/decide_tip_amounts to Project#decide_tip_amounts' do
- expect({ get: '/projects/1/decide_tip_amounts' }).to route_to(
- controller: 'projects',
- action: 'decide_tip_amounts',
- id: '1'
- )
- end
-
- it 'routes PATCH /projects/1/decide_tip_amounts to Project#decide_tip_amounts' do
- expect({ patch: '/projects/1/decide_tip_amounts' }).to route_to(
- controller: 'projects',
- action: 'decide_tip_amounts',
- id: '1'
- )
- end
-
- it 'routes GET /projects/1/tips to Tips#index' do
- expect({ get: '/projects/1/tips' }).to route_to(
- controller: 'tips',
- action: 'index',
- project_id: '1'
- )
- end
-
- it 'routes GET /projects/1/deposits to Deposits#index' do
- expect({ get: '/projects/1/deposits' }).to route_to(
- controller: 'deposits',
- action: 'index',
- project_id: '1'
- )
- end
- end
-
- describe 'Project pretty url routing' do
- it 'routes GET /:provider/:repo to Project#show' do
- expect({ get: '/github/test/test' }).to route_to(
- controller: 'projects',
- action: 'show',
- service: 'github',
- repo: 'test/test'
- )
- end
-
- it 'routes GET /:provider/:repo/edit to Project#edit' do
- expect({ get: '/github/test/test/edit' }).to route_to(
- controller: 'projects',
- action: 'edit',
- service: 'github',
- repo: 'test/test'
- )
- end
-
- it 'routes GET /:provider/:repo/decide_tip_amounts to Project#decide_tip_amounts' do
- expect({ get: '/github/test/test/decide_tip_amounts' }).to route_to(
- controller: 'projects',
- action: 'decide_tip_amounts',
- service: 'github',
- repo: 'test/test'
- )
- end
-
- it 'routes GET /:provider/:repo/tips to Project#tips' do
- expect({ get: '/github/test/test/tips' }).to route_to(
- controller: 'tips',
- action: 'index',
- service: 'github',
- repo: 'test/test'
- )
- end
-
- it 'routes GET /:provider/:repo/deposits to Project#deposits' do
- expect({ get: '/github/test/test/deposits' }).to route_to(
- controller: 'deposits',
- action: 'index',
- service: 'github',
- repo: 'test/test'
- )
- end
- end
end
diff --git a/spec/controllers/tips_controller_spec.rb b/spec/controllers/tips_controller_spec.rb
index d060ccf2..c64e8395 100644
--- a/spec/controllers/tips_controller_spec.rb
+++ b/spec/controllers/tips_controller_spec.rb
@@ -9,13 +9,4 @@
expect(response).to be_successful
end
end
-
- describe 'routing' do
- it 'routes GET / to Tips#index' do
- expect({ get: '/tips' }).to route_to(
- controller: 'tips',
- action: 'index'
- )
- end
- end
end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 70b6cb2d..3cc59d1f 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -30,6 +30,7 @@
context 'when user found' do
context 'when viewing own page' do
before { allow(user).to receive(:id).and_return(@current_user.id) }
+
it 'renders show template' do
expect(subject).to render_template :show
end
@@ -94,68 +95,4 @@
end
end
end
-
- describe 'routing' do
- it 'routes GET /users to User#index' do
- expect({ get: '/users' }).to route_to(
- controller: 'users',
- action: 'index'
- )
- end
-
- it 'routes GET /users/nick-name321 to User#show' do
- expect({ get: '/users/nick-name321' }).to route_to(
- controller: 'users',
- action: 'show',
- nickname: 'nick-name321'
- )
- end
-
- it 'routes GET /users/login to User#login' do
- expect({ get: '/users/login' }).to route_to(
- controller: 'users',
- action: 'login'
- )
- end
-
- it 'routes GET /users/1/tips to Tips#index' do
- expect({ get: '/users/1/tips' }).to route_to(
- controller: 'tips',
- action: 'index',
- user_id: '1'
- )
- end
- end
-
- describe 'pretty url routing' do
- let(:user) { create(:user) }
-
- it 'regex rejects reserved user paths' do
- # accepted pertty url usernames
- should_accept = [' ', 'logi', 'ogin', 's4c2', '42x', 'nick name', 'kd']
- # reserved routes (rejected pertty url usernames)
- should_reject = ['', '1', '42']
-
- accepted = should_accept.select { |ea| ea =~ /\D+/ }
- rejected = should_reject.select { |ea| (ea =~ /\D+/).nil? }
- (expect(accepted.size).to eq(should_accept.size)) &&
- (expect(rejected.size).to eq(should_reject.size))
- end
-
- it 'routes GET /users/:nickname to User#show' do
- expect({ get: "/users/#{user.nickname}" }).to route_to(
- controller: 'users',
- action: 'show',
- nickname: 'kd'
- )
- end
-
- it 'routes GET /users/:nickname/tips to Tips#index' do
- expect({ get: "/users/#{user.nickname}/tips" }).to route_to(
- controller: 'tips',
- action: 'index',
- nickname: 'kd'
- )
- end
- end
end
diff --git a/spec/controllers/withdrawals_controller_spec.rb b/spec/controllers/withdrawals_controller_spec.rb
index d1db2351..6bbbea1f 100644
--- a/spec/controllers/withdrawals_controller_spec.rb
+++ b/spec/controllers/withdrawals_controller_spec.rb
@@ -9,13 +9,4 @@
expect(response).to be_successful
end
end
-
- describe 'routing' do
- it 'routes GET / to Withdrawals#index' do
- expect({ get: '/withdrawals' }).to route_to(
- controller: 'withdrawals',
- action: 'index'
- )
- end
- end
end
diff --git a/spec/factories/wallets.rb b/spec/factories/wallets.rb
index 9c2f74d9..61c3a212 100644
--- a/spec/factories/wallets.rb
+++ b/spec/factories/wallets.rb
@@ -5,7 +5,7 @@
name { 'test wallet' }
xpub do
'xpub661MyMwAqRbcFepxYZyGLKMTkTPDvbfLaoYDbw4d4iQT5SycGiJQREuraJ2N6Uh' \
- 'LGPcjXDhnARdtcUhgqN3a2dgQ3Dx8u1chtk8Rx16LrWg'
+ 'LGPcjXDhnARdtcUhgqN3a2dgQ3Dx8u1chtk8Rx16LrWg'
end
end
end
diff --git a/spec/misc_spec.rb b/spec/features/assets.rb
similarity index 71%
rename from spec/misc_spec.rb
rename to spec/features/assets.rb
index e8ff2b0e..1814fabb 100644
--- a/spec/misc_spec.rb
+++ b/spec/features/assets.rb
@@ -2,12 +2,12 @@
require 'spec_helper'
-describe 'Misc tets' do
+describe 'Assets', type: :feature do
let(:locales) { Rails.application.config.available_locales }
it 'has a flag image for each locale' do
locales.each do |locale|
- path = File.join(Rails.root, 'app', 'assets', 'images', 'flags', "#{locale}.png")
+ path = Rails.root.join("app/assets/images/flags/#{locale}.png")
expect(File.exist?(path)).to be_truthy, "#{locale} flag is missing"
end
end
diff --git a/spec/lib/blacklist_spec.rb b/spec/lib/blacklist_spec.rb
index 78c7e693..607499f0 100644
--- a/spec/lib/blacklist_spec.rb
+++ b/spec/lib/blacklist_spec.rb
@@ -11,7 +11,7 @@
'https://bitbucket.org/notips/*'
]
- list = Blacklist.new(urls)
+ list = described_class.new(urls)
# Blacklisted projects.
expect(list.include?('https://github.com/author/notips')).to eq(true)
diff --git a/spec/models/collaborator_spec.rb b/spec/models/collaborator_spec.rb
index 2fe276c8..994d31e9 100644
--- a/spec/models/collaborator_spec.rb
+++ b/spec/models/collaborator_spec.rb
@@ -4,6 +4,6 @@
describe Collaborator, type: :model do
describe 'Associations' do
- it { should belong_to :project }
+ it { is_expected.to belong_to :project }
end
end
diff --git a/spec/models/deposit_spec.rb b/spec/models/deposit_spec.rb
index 6456520e..1f50fc5f 100644
--- a/spec/models/deposit_spec.rb
+++ b/spec/models/deposit_spec.rb
@@ -6,7 +6,7 @@
let(:deposit) { create(:deposit) }
describe 'Associations' do
- it { should belong_to :project }
+ it { is_expected.to belong_to :project }
end
describe '#fee' do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index d72bcd79..535acec6 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -7,18 +7,18 @@
let(:project_of_bitbucket) { create(:project, :bitbucket) }
describe 'Associations' do
- it { should have_many(:deposits) }
- it { should have_many(:tips) }
- it { should belong_to(:wallet) }
+ it { is_expected.to have_many(:deposits) }
+ it { is_expected.to have_many(:tips) }
+ it { is_expected.to belong_to(:wallet) }
end
describe 'Validations' do
- it { should validate_presence_of(:full_name) }
- it { should validate_presence_of(:github_id) }
- it { should validate_presence_of(:host) }
- it { should validate_uniqueness_of(:full_name) }
- it { should validate_uniqueness_of(:github_id) }
- it { should validate_inclusion_of(:host).in_array %w[github bitbucket] }
+ it { is_expected.to validate_presence_of(:full_name) }
+ it { is_expected.to validate_presence_of(:github_id) }
+ it { is_expected.to validate_presence_of(:host) }
+ it { is_expected.to validate_uniqueness_of(:full_name) }
+ it { is_expected.to validate_uniqueness_of(:github_id) }
+ it { is_expected.to validate_inclusion_of(:host).in_array %w[github bitbucket] }
end
describe 'bitcoin_address' do
@@ -29,15 +29,15 @@
wallet
end
- it 'should generate a bitcoin address' do
+ it 'generates a bitcoin address' do
expect(project.bitcoin_address).not_to be_blank
end
- it 'should connect project to the last wallet' do
+ it 'connects project to the last wallet' do
expect(project.wallet).to eq wallet
end
- it 'should increment wallet\'s last_address_index' do
+ it "increments wallet's last_address_index" do
expect { project }.to change { wallet.reload.last_address_index }.by 1
end
end
diff --git a/spec/models/send_many_spec.rb b/spec/models/send_many_spec.rb
deleted file mode 100644
index 4f1c3435..00000000
--- a/spec/models/send_many_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Sendmany, type: :model do
- describe 'Associations' do
- it { should have_many :tips }
- end
-end
diff --git a/spec/models/sendmany_spec.rb b/spec/models/sendmany_spec.rb
index 4f1c3435..428efb30 100644
--- a/spec/models/sendmany_spec.rb
+++ b/spec/models/sendmany_spec.rb
@@ -4,6 +4,6 @@
describe Sendmany, type: :model do
describe 'Associations' do
- it { should have_many :tips }
+ it { is_expected.to have_many :tips }
end
end
diff --git a/spec/models/tip_spec.rb b/spec/models/tip_spec.rb
index 3bd46d4c..2aa1fd80 100644
--- a/spec/models/tip_spec.rb
+++ b/spec/models/tip_spec.rb
@@ -4,8 +4,8 @@
describe Tip, type: :model do
describe 'Associations' do
- it { should belong_to :user }
- it { should belong_to :sendmany }
- it { should belong_to :project }
+ it { is_expected.to belong_to :user }
+ it { is_expected.to belong_to :sendmany }
+ it { is_expected.to belong_to :project }
end
end
diff --git a/spec/models/tipping_policies_text_spec.rb b/spec/models/tipping_policies_text_spec.rb
index 869a51c2..86376f5f 100644
--- a/spec/models/tipping_policies_text_spec.rb
+++ b/spec/models/tipping_policies_text_spec.rb
@@ -4,7 +4,7 @@
describe TippingPoliciesText, type: :model do
describe 'Associations' do
- it { should belong_to :project }
- it { should belong_to :user }
+ it { is_expected.to belong_to :project }
+ it { is_expected.to belong_to :user }
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 677edf84..aac6997b 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -6,7 +6,7 @@
let(:user) { create(:user) }
describe 'Associations' do
- it { should have_many :tips }
+ it { is_expected.to have_many :tips }
end
describe 'full_name' do
@@ -33,56 +33,56 @@
describe 'bitcoin_address' do
context 'when address is blank' do
- it 'should be valid' do
+ it 'is valid' do
user.bitcoin_address = ''
expect(user).to be_valid
end
end
context 'when address is valid p2pkh address' do
- it 'should be valid' do
+ it 'is valid' do
user.bitcoin_address = '1M4bS4gPyA6Kb8w7aXsgth9oUZWcRk73tQ'
expect(user).to be_valid
end
end
context 'when address is valid p2sh address' do
- it 'should be valid' do
+ it 'is valid' do
user.bitcoin_address = '3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX'
expect(user).to be_valid
end
end
context 'when address is valid bech32 P2WPKH address' do
- it 'should be valid' do
+ it 'is valid' do
user.bitcoin_address = 'BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4'
expect(user).to be_valid
end
end
context 'when address is valid bech32 P2WSH address' do
- it 'should be valid' do
+ it 'is valid' do
user.bitcoin_address = 'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3'
expect(user).to be_valid
end
end
context 'when address is not valid p2pkh' do
- it 'should not be valid' do
+ it 'is not valid' do
user.bitcoin_address = '1M4bS4gPyA6Kb8w7aXsgth9oUZXXXXXXXX'
expect(user).not_to be_valid
end
end
context 'when address is testnet bech32' do
- it 'should not be valid' do
+ it 'is not valid' do
user.bitcoin_address = 'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx'
expect(user).not_to be_valid
end
end
context 'when address is not valid bech32' do
- it 'should not be valid' do
+ it 'is not valid' do
user.bitcoin_address = 'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx'
expect(user).not_to be_valid
end
diff --git a/spec/models/wallet_spec.rb b/spec/models/wallet_spec.rb
index c7ebeab9..78fd10c9 100644
--- a/spec/models/wallet_spec.rb
+++ b/spec/models/wallet_spec.rb
@@ -6,18 +6,18 @@
let(:wallet) { create(:wallet) }
describe 'Validations' do
- it { should validate_presence_of(:name) }
- it { should validate_presence_of(:xpub) }
+ it { is_expected.to validate_presence_of(:name) }
+ it { is_expected.to validate_presence_of(:xpub) }
end
describe '#generate_address' do
subject { wallet.generate_address }
- it 'should return a new address' do
+ it 'returns a new address' do
expect(subject).to eq '125q4q36PT2gGoeNWXm34RepMcgghLghiZ'
end
- it 'should increment last_address_index' do
+ it 'increments last_address_index' do
expect { subject }.to change { wallet.reload.last_address_index }.by 1
end
end
diff --git a/spec/requests/cve_2005_9284_regression_spec.rb b/spec/requests/cve_2005_9284_regression_spec.rb
index 6d6b82ea..b311506a 100644
--- a/spec/requests/cve_2005_9284_regression_spec.rb
+++ b/spec/requests/cve_2005_9284_regression_spec.rb
@@ -17,14 +17,14 @@
ActionController::Base.allow_forgery_protection = true
end
+ after do
+ ActionController::Base.allow_forgery_protection = @allow_forgery_protection
+ end
+
it do
expect do
post '/users/auth/github'
end.to raise_error(ActionController::InvalidAuthenticityToken)
end
-
- after do
- ActionController::Base.allow_forgery_protection = @allow_forgery_protection
- end
end
end
diff --git a/spec/routing/deposits_routing_spec.rb b/spec/routing/deposits_routing_spec.rb
new file mode 100644
index 00000000..8289c3aa
--- /dev/null
+++ b/spec/routing/deposits_routing_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'routes for Deposits', type: :routing do
+ it 'routes GET / to Deposits#index' do
+ expect({ get: '/deposits' }).to route_to(
+ controller: 'deposits',
+ action: 'index'
+ )
+ end
+end
diff --git a/spec/routing/home_routing_spec.rb b/spec/routing/home_routing_spec.rb
new file mode 100644
index 00000000..b8c3e81d
--- /dev/null
+++ b/spec/routing/home_routing_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'routes for Home', type: :routing do
+ it 'routes GET / to Home#index' do
+ expect({ get: '/' }).to route_to(
+ controller: 'home',
+ action: 'index'
+ )
+ end
+
+ it 'routes GET /users/999999/no-such-path to Home#index' do
+ expect({ get: '/users/999999/no-such-path' }).to route_to(
+ controller: 'home',
+ action: 'index',
+ path: 'users/999999/no-such-path'
+ )
+ end
+
+ it 'routes GET /any/non-existent/path to Home#index' do
+ expect({ get: '/any/non-existent/path' }).to route_to(
+ controller: 'home',
+ action: 'index',
+ path: 'any/non-existent/path'
+ )
+ end
+end
diff --git a/spec/routing/projects_routing_spec.rb b/spec/routing/projects_routing_spec.rb
new file mode 100644
index 00000000..41d1040f
--- /dev/null
+++ b/spec/routing/projects_routing_spec.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'routes for Projects', type: :routing do
+ it 'routes GET /projects to Project#index' do
+ expect({ get: '/projects' }).to route_to(
+ controller: 'projects',
+ action: 'index'
+ )
+ end
+
+ it 'routes GET /projects/search?query= to Project#search' do
+ expect({ get: '/projects/search?query=seldon&order=balance' }).to route_to(
+ controller: 'projects',
+ action: 'search',
+ query: 'seldon',
+ order: 'balance'
+ )
+ end
+
+ it 'routes GET /projects/1 to Project#show' do
+ expect({ get: '/projects/1' }).to route_to(
+ controller: 'projects',
+ action: 'show',
+ id: '1'
+ )
+ end
+
+ it 'routes GET /projects/1/edit to Project#edit' do
+ expect({ get: '/projects/1/edit' }).to route_to(
+ controller: 'projects',
+ action: 'edit',
+ id: '1'
+ )
+ end
+
+ it 'routes PUT /projects/1 to Project#update' do
+ expect({ put: '/projects/1' }).to route_to(
+ controller: 'projects',
+ action: 'update',
+ id: '1'
+ )
+ end
+
+ it 'routes GET /projects/1/decide_tip_amounts to Project#decide_tip_amounts' do
+ expect({ get: '/projects/1/decide_tip_amounts' }).to route_to(
+ controller: 'projects',
+ action: 'decide_tip_amounts',
+ id: '1'
+ )
+ end
+
+ it 'routes PATCH /projects/1/decide_tip_amounts to Project#decide_tip_amounts' do
+ expect({ patch: '/projects/1/decide_tip_amounts' }).to route_to(
+ controller: 'projects',
+ action: 'decide_tip_amounts',
+ id: '1'
+ )
+ end
+
+ it 'routes GET /projects/1/tips to Tips#index' do
+ expect({ get: '/projects/1/tips' }).to route_to(
+ controller: 'tips',
+ action: 'index',
+ project_id: '1'
+ )
+ end
+
+ it 'routes GET /projects/1/deposits to Deposits#index' do
+ expect({ get: '/projects/1/deposits' }).to route_to(
+ controller: 'deposits',
+ action: 'index',
+ project_id: '1'
+ )
+ end
+
+ describe 'Project pretty url routing' do
+ it 'routes GET /:provider/:repo to Project#show' do
+ expect({ get: '/github/test/test' }).to route_to(
+ controller: 'projects',
+ action: 'show',
+ service: 'github',
+ repo: 'test/test'
+ )
+ end
+
+ it 'routes GET /:provider/:repo/edit to Project#edit' do
+ expect({ get: '/github/test/test/edit' }).to route_to(
+ controller: 'projects',
+ action: 'edit',
+ service: 'github',
+ repo: 'test/test'
+ )
+ end
+
+ it 'routes GET /:provider/:repo/decide_tip_amounts to Project#decide_tip_amounts' do
+ expect({ get: '/github/test/test/decide_tip_amounts' }).to route_to(
+ controller: 'projects',
+ action: 'decide_tip_amounts',
+ service: 'github',
+ repo: 'test/test'
+ )
+ end
+
+ it 'routes GET /:provider/:repo/tips to Project#tips' do
+ expect({ get: '/github/test/test/tips' }).to route_to(
+ controller: 'tips',
+ action: 'index',
+ service: 'github',
+ repo: 'test/test'
+ )
+ end
+
+ it 'routes GET /:provider/:repo/deposits to Project#deposits' do
+ expect({ get: '/github/test/test/deposits' }).to route_to(
+ controller: 'deposits',
+ action: 'index',
+ service: 'github',
+ repo: 'test/test'
+ )
+ end
+ end
+end
diff --git a/spec/routing/tips_routing_spec.rb b/spec/routing/tips_routing_spec.rb
new file mode 100644
index 00000000..23216754
--- /dev/null
+++ b/spec/routing/tips_routing_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'routes for Tips', type: :routing do
+ it 'routes GET / to Tips#index' do
+ expect({ get: '/tips' }).to route_to(
+ controller: 'tips',
+ action: 'index'
+ )
+ end
+end
diff --git a/spec/routing/users_routing_spec.rb b/spec/routing/users_routing_spec.rb
new file mode 100644
index 00000000..3118aacd
--- /dev/null
+++ b/spec/routing/users_routing_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'routes for Users', type: :routing do
+ it 'routes GET /users to User#index' do
+ expect({ get: '/users' }).to route_to(
+ controller: 'users',
+ action: 'index'
+ )
+ end
+
+ it 'routes GET /users/nick-name321 to User#show' do
+ expect({ get: '/users/nick-name321' }).to route_to(
+ controller: 'users',
+ action: 'show',
+ nickname: 'nick-name321'
+ )
+ end
+
+ it 'routes GET /users/login to User#login' do
+ expect({ get: '/users/login' }).to route_to(
+ controller: 'users',
+ action: 'login'
+ )
+ end
+
+ it 'routes GET /users/1/tips to Tips#index' do
+ expect({ get: '/users/1/tips' }).to route_to(
+ controller: 'tips',
+ action: 'index',
+ user_id: '1'
+ )
+ end
+
+ it 'routes DELETE /users/1 to Tips#destroy' do
+ expect({ delete: '/users/1' }).to route_to(
+ controller: 'users',
+ action: 'destroy',
+ id: '1'
+ )
+ end
+
+ describe 'pretty url routing' do
+ let(:user) { create(:user) }
+
+ it 'regex rejects reserved user paths' do
+ # accepted pertty url usernames
+ should_accept = [' ', 'logi', 'ogin', 's4c2', '42x', 'nick name', 'kd']
+ # reserved routes (rejected pertty url usernames)
+ should_reject = ['', '1', '42']
+
+ accepted = should_accept.select { |ea| ea =~ /\D+/ }
+ rejected = should_reject.select { |ea| (ea =~ /\D+/).nil? }
+ (expect(accepted.size).to eq(should_accept.size)) &&
+ (expect(rejected.size).to eq(should_reject.size))
+ end
+
+ it 'routes GET /users/:nickname to User#show' do
+ expect({ get: "/users/#{user.nickname}" }).to route_to(
+ controller: 'users',
+ action: 'show',
+ nickname: 'kd'
+ )
+ end
+
+ it 'routes GET /users/:nickname/tips to Tips#index' do
+ expect({ get: "/users/#{user.nickname}/tips" }).to route_to(
+ controller: 'tips',
+ action: 'index',
+ nickname: 'kd'
+ )
+ end
+ end
+end
diff --git a/spec/routing/withdrawals_routing_spec.rb b/spec/routing/withdrawals_routing_spec.rb
new file mode 100644
index 00000000..e64eac7f
--- /dev/null
+++ b/spec/routing/withdrawals_routing_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'routes for Withdrawals', type: :routing do
+ it 'routes GET / to Withdrawals#index' do
+ expect({ get: '/withdrawals' }).to route_to(
+ controller: 'withdrawals',
+ action: 'index'
+ )
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 9231f65f..27a1ad36 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -40,7 +40,7 @@
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
- config.fixture_path = "#{::Rails.root}/spec/fixtures"
+ config.fixture_path = "#{Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.