Merge branch 'rails6'

This commit is contained in:
Jérémy Lecour 2019-08-25 17:40:36 +02:00
commit 29ee6fae97
103 changed files with 3176 additions and 3203 deletions

View File

@ -1,18 +0,0 @@
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": "> 1%",
"uglify": true
},
"useBuiltIns": true
}]
],
"plugins": [
"syntax-dynamic-import",
"transform-object-rest-spread",
["transform-class-properties", { "spec": true }]
]
}

1
.browserslistrc Normal file
View File

@ -0,0 +1 @@
defaults

10
.gitignore vendored
View File

@ -19,9 +19,6 @@
# Ignore uploaded files in development
/storage/*
/node_modules
/yarn-error.log
/public/assets
.byebug_history
@ -44,3 +41,10 @@ yarn-debug.log*
# OS file
.DS_Store
/public/packs
/public/packs-test
/node_modules
/yarn-error.log
yarn-debug.log*
.yarn-integrity

View File

@ -1,3 +0,0 @@
plugins:
postcss-import: {}
postcss-cssnext: {}

View File

@ -4,8 +4,8 @@
language:
- ruby
rvm:
- 2.3
- 2.4
### Zeitwerk is not fully compatible with < 2.5.4
### cf. https://github.com/Evolix/chexpire/pull/104
- 2.5
- 2.6
@ -23,8 +23,6 @@ services:
- mysql
before_install:
- gem update --system
- gem install bundler
- mysql -e 'CREATE DATABASE chexpire_test;'
- cp config/database.travis.yml config/database.yml
- cp config/secrets.example.yml config/secrets.yml
@ -37,6 +35,7 @@ install:
- bundle install
- yarn install
- rails db:create db:migrate
- rails webpacker:compile
script:
- bundle exec rubocop

51
Gemfile
View File

@ -1,45 +1,44 @@
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '>= 2.3.3'
ruby '>= 2.5.4'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.0'
gem 'rails-i18n', '~> 5.1'
gem 'rails', '6.0.0'
gem 'rails-i18n', '~> 6.0.0'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
gem 'devise', '~> 4.4'
gem 'devise-i18n', '~> 1.6'
# responders 3 depends on Ruy >= 2.4.0, let's keep a 2.x for now
gem 'responders', '~> 2.4.1'
gem 'puma', '~> 4.0'
gem 'devise', '~> 4.7'
gem 'devise-i18n', '~> 1.8'
gem 'simple_form', '~> 4.0'
gem 'pundit', '~> 1.1'
# Use SCSS for stylesheets
# sass-rails 5.1 depends on Ruy >= 2.4.0, let's keep 5.0.7 for now
gem 'sass-rails', '5.0.7'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
gem 'webpacker', '~> 3.5'
gem 'sass-rails', '~> 5'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby
# Use CoffeeScript for .coffee assets and views
# gem 'coffee-rails', '~> 4.2'
gem 'bootstrap', '~> 4.3.1'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use ActiveModel has_secure_password
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
gem 'bcrypt', '~> 3.1.7'
# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
gem 'rack-contrib'
@ -55,12 +54,10 @@ gem 'has_scope'
gem 'logging'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'binding_of_caller'
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
# gem 'binding_of_caller'
gem 'pry-byebug'
gem 'pry-rails'
@ -69,7 +66,7 @@ end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'web-console', '~> 4.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
@ -95,7 +92,7 @@ end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15', '< 4.0'
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
gem 'webdrivers'
gem 'launchy'

View File

@ -1,47 +1,61 @@
GEM
remote: https://rubygems.org/
specs:
actioncable (5.2.3)
actionpack (= 5.2.3)
actioncable (6.0.0)
actionpack (= 6.0.0)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
actionmailbox (6.0.0)
actionpack (= 6.0.0)
activejob (= 6.0.0)
activerecord (= 6.0.0)
activestorage (= 6.0.0)
activesupport (= 6.0.0)
mail (>= 2.7.1)
actionmailer (6.0.0)
actionpack (= 6.0.0)
actionview (= 6.0.0)
activejob (= 6.0.0)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.3)
actionview (= 5.2.3)
activesupport (= 5.2.3)
actionpack (6.0.0)
actionview (= 6.0.0)
activesupport (= 6.0.0)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.3)
activesupport (= 5.2.3)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.0.0)
actionpack (= 6.0.0)
activerecord (= 6.0.0)
activestorage (= 6.0.0)
activesupport (= 6.0.0)
nokogiri (>= 1.8.5)
actionview (6.0.0)
activesupport (= 6.0.0)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.2.3)
activesupport (= 5.2.3)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (6.0.0)
activesupport (= 6.0.0)
globalid (>= 0.3.6)
activemodel (5.2.3)
activesupport (= 5.2.3)
activerecord (5.2.3)
activemodel (= 5.2.3)
activesupport (= 5.2.3)
arel (>= 9.0)
activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
activemodel (6.0.0)
activesupport (= 6.0.0)
activerecord (6.0.0)
activemodel (= 6.0.0)
activesupport (= 6.0.0)
activestorage (6.0.0)
actionpack (= 6.0.0)
activejob (= 6.0.0)
activerecord (= 6.0.0)
marcel (~> 0.3.1)
activesupport (5.2.3)
activesupport (6.0.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.1, >= 2.1.8)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
airbrussh (1.3.3)
@ -49,15 +63,18 @@ GEM
annotate (2.7.5)
activerecord (>= 3.2, < 7.0)
rake (>= 10.4, < 13.0)
arel (9.0.0)
ast (2.4.0)
autoprefixer-rails (9.6.1.1)
execjs
bcrypt (3.1.13)
bcrypt_pbkdf (1.0.1)
bindex (0.8.1)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
bootsnap (1.4.4)
msgpack (~> 1.0)
bootstrap (4.3.1)
autoprefixer-rails (>= 9.1.0)
popper_js (>= 1.14.3, < 2)
sassc-rails (>= 2.0.0)
builder (3.2.3)
byebug (11.0.1)
capistrano (3.11.0)
@ -73,10 +90,10 @@ GEM
capistrano-rbenv (2.1.4)
capistrano (~> 3.1)
sshkit (~> 1.3)
capistrano3-puma (3.1.1)
capistrano3-puma (4.0.0)
capistrano (~> 3.7)
capistrano-bundler
puma (~> 3.4)
puma (~> 4.0)
capybara (3.28.0)
addressable
mini_mime (>= 0.1.3)
@ -92,11 +109,10 @@ GEM
concurrent-ruby (1.1.5)
crass (1.0.4)
database_cleaner (1.7.0)
debug_inspector (0.0.3)
devise (4.6.2)
devise (4.7.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 6.0)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
devise-i18n (1.8.1)
@ -198,6 +214,7 @@ GEM
parallel (1.17.0)
parser (2.6.3.0)
ast (~> 2.4.0)
popper_js (1.14.5)
powerpack (0.1.2)
pry (0.12.2)
coderay (~> 1.1.0)
@ -208,7 +225,8 @@ GEM
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (3.1.1)
puma (3.12.1)
puma (4.1.0)
nio4r (~> 2.0)
pundit (1.1.0)
activesupport (>= 3.0.0)
rack (2.0.7)
@ -218,33 +236,35 @@ GEM
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.3)
actioncable (= 5.2.3)
actionmailer (= 5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
activemodel (= 5.2.3)
activerecord (= 5.2.3)
activestorage (= 5.2.3)
activesupport (= 5.2.3)
rails (6.0.0)
actioncable (= 6.0.0)
actionmailbox (= 6.0.0)
actionmailer (= 6.0.0)
actionpack (= 6.0.0)
actiontext (= 6.0.0)
actionview (= 6.0.0)
activejob (= 6.0.0)
activemodel (= 6.0.0)
activerecord (= 6.0.0)
activestorage (= 6.0.0)
activesupport (= 6.0.0)
bundler (>= 1.3.0)
railties (= 5.2.3)
railties (= 6.0.0)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.2.0)
loofah (~> 2.2, >= 2.2.2)
rails-i18n (5.1.3)
rails-i18n (6.0.0)
i18n (>= 0.7, < 2)
railties (>= 5.0, < 6)
railties (5.2.3)
actionpack (= 5.2.3)
activesupport (= 5.2.3)
railties (>= 6.0.0, < 7)
railties (6.0.0)
actionpack (= 6.0.0)
activesupport (= 6.0.0)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
thor (>= 0.20.3, < 2.0)
rainbow (3.0.0)
rake (12.3.3)
rb-fsevent (0.10.3)
@ -253,9 +273,9 @@ GEM
rbnacl (4.0.2)
ffi
regexp_parser (1.6.0)
responders (2.4.1)
actionpack (>= 4.2.0, < 6.0)
railties (>= 4.2.0, < 6.0)
responders (3.0.0)
actionpack (>= 5.0)
railties (>= 5.0)
rubocop (0.56.0)
parallel (~> 1.10)
parser (>= 2.5)
@ -271,12 +291,20 @@ GEM
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.7)
railties (>= 4.0.0, < 6)
sass-rails (5.1.0)
railties (>= 5.2.0)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
sassc (2.1.0)
ffi (~> 1.9)
sassc-rails (2.1.2)
railties (>= 4.0.0)
sassc (>= 2.0)
sprockets (> 3.0)
sprockets-rails
tilt
selenium-webdriver (3.142.3)
childprocess (>= 0.5, < 2.0)
rubyzip (~> 1.2, >= 1.2.2)
@ -311,21 +339,19 @@ GEM
turbolinks-source (5.2.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uglifier (4.1.20)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.6.0)
warden (1.2.8)
rack (>= 2.0.6)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
web-console (4.0.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 5.0)
railties (>= 6.0.0)
webdrivers (4.1.2)
nokogiri (~> 1.6)
rubyzip (~> 1.0)
selenium-webdriver (>= 3.0, < 4.0)
webpacker (3.6.0)
webpacker (4.0.7)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
@ -336,6 +362,7 @@ GEM
chronic (>= 0.6.3)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.1.9)
PLATFORMS
ruby
@ -344,23 +371,24 @@ DEPENDENCIES
annotate
bcrypt (~> 3.1.7)
bcrypt_pbkdf (>= 1.0, < 2.0)
binding_of_caller
bootsnap (>= 1.1.0)
bootsnap (>= 1.4.2)
bootstrap (~> 4.3.1)
byebug
capistrano (~> 3.10)
capistrano-rails (~> 1.4)
capistrano-rbenv
capistrano3-puma
capybara (>= 2.15, < 4.0)
capybara (>= 2.15)
database_cleaner
devise (~> 4.4)
devise-i18n (~> 1.6)
devise (~> 4.7)
devise-i18n (~> 1.8)
ed25519 (>= 1.2, < 2.0)
factory_bot_rails (~> 5.0)
guard
guard-minitest
has_scope
hashie
jbuilder (~> 2.5)
jbuilder (~> 2.7)
kaminari
launchy
letter_opener_web
@ -372,15 +400,14 @@ DEPENDENCIES
open4
pry-byebug
pry-rails
puma (~> 3.11)
puma (~> 4.0)
pundit (~> 1.1)
rack-contrib
rails (~> 5.2.0)
rails-i18n (~> 5.1)
rails (= 6.0.0)
rails-i18n (~> 6.0.0)
rbnacl (>= 3.2, < 5.0)
responders (~> 2.4.1)
rubocop (~> 0.56.0)
sass-rails (= 5.0.7)
sass-rails (~> 5)
selenium-webdriver
simple_form (~> 4.0)
simplecov
@ -388,14 +415,13 @@ DEPENDENCIES
spring-watcher-listen (~> 2.0.0)
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
web-console (>= 3.3.0)
web-console (~> 4.0)
webdrivers
webpacker (~> 3.5)
webpacker (~> 4.0)
whenever
RUBY VERSION
ruby 2.3.3p222
ruby 2.6.3p62
BUNDLED WITH
1.17.2

View File

@ -3,15 +3,15 @@
## Requirements
Chexpire requires :
* Ruby > 2.3.3 and Bundler
* Ruby > 2.5.4 and Bundler
* NodeJS and Yarn
* MySQL or MariaDB
We are usually running Chexpire on typical POSIX servers like :
- Linux Debian 9, Ruby 2.5.1, NodeJS 8.11 and MariaDB 10.1
- macOS High Sierra, Ruby 2.5.1, NodeJS 10.2.1 and MariaDB 10.2
- Linux Debian 9, Ruby 2.5.4, NodeJS 8.11 and MariaDB 10.1
- macOS High Sierra, Ruby 2.5.4, NodeJS 10.2.1 and MariaDB 10.2
It probably works on any system that supports Ruby >2.3, NodeJS >6 and MySQL >5.5. Feel free to report any unexpected incompatibilities.
It probably works on any system that supports Ruby >= 2.5.4, NodeJS >= 6 and MySQL >= 5.5. Feel free to report any unexpected incompatibilities.
If you use rbenv, chruby or RVM, you can set your prefered Ruby version in the `.ruby-version` file at the root of the project.
@ -21,7 +21,7 @@ If you are familiar with Ansible, you can use our [Ansible roles](http://forge.e
[…]
roles:
- mysql
- { role: rbenv, username: "{{ ansible_user }}", rbenv_ruby_version: "2.5.1" }
- { role: rbenv, username: "{{ ansible_user }}", rbenv_ruby_version: "2.5.4" }
- { role: nodejs, nodejs_install_yarn: yes }
[…]
```
@ -34,7 +34,7 @@ If you want to do manual installations, you can use our Wiki documentations for
Execute `# bundle install` to install Ruby gems (including Rails itself).
Execute `# yarn install` to install Javascript/NodeJS packages.
Execute `# yarn install --check-files` to install Javascript/NodeJS packages.
Depending on what is already installed on your OS or not, you might need to install a few system packages to be able to have everything working.
@ -45,15 +45,21 @@ To use elliptic curve SSH keys, we need to have `libsodium` and its headers.
* on macOS with Homebrew : `# brew install libsodium`.
## Rails configuration
## Application configuration
After cloning this repository, you have to create and edit a few files for your local development/test configuration. Theses files will be ignored by git.
### Environment variables
A handful of settings can be set by environment variables. If you use Heroku-like platforms they offer a simple way to set them.
If you use Rbenv, there is the `rbenv-vars` plugin. That is what we recommend on POSIX servers. You have to put an `.rbenv-vars` file at the root of the project. If you use Capistrano, put it in the shared directory and have it linked in the `current` directory at deploy time.
### Database configuration
Create the file if missing : `cp config/database.example.yml config/database.yml`. If you change the settings in the `defaults` section it applies to the `development` and `test` sections. More information is available at "guides.rubyonrails.org":https://guides.rubyonrails.org/configuring.html#configuring-a-database
Note that on Debian 9 with MariaDB, the database socket is at `/var/run/mysqld/mysqld.sock`, which is not the default in the configuration file.
Note that on Debian 9+ with MariaDB, the database socket is at `/var/run/mysqld/mysqld.sock`, which is not the default in the configuration file.
### Rails secrets
@ -63,7 +69,7 @@ Create the file if missing : `cp config/secrets.example.yml config/secrets.yml`.
Create the file if missing : `cp config/chexpire.example.yml config/chexpire.yml`. Set at least the `mailer_default_from` and `host` variables. See other configuration overridable in `config/chexpire.defaults.yml`.
## Database
## Database
You need databases for development and tests. You can create them like this (once connected to you MySQL server) :
@ -75,8 +81,8 @@ MariaDB [none]> CREATE DATABASE `chexpire_test`;
If you don't want to use the default `root` MySQL user with no password, you can create users :
```
MariaDB [none]> GRANT ALL PRIVILEGES ON `chexpire_development`.* TO `chexpire_development`@localhost IDENTIFIED BY 'MY_PASSWORD_FOR_DEV';
MariaDB [none]> GRANT ALL PRIVILEGES ON `chexpire_test`.* TO `chexpire_test`@localhost IDENTIFIED BY 'MY_PASSWORD_FOR_TEST';
MariaDB [none]> GRANT ALL PRIVILEGES ON `chexpire_development%`.* TO `chexpire_development`@localhost IDENTIFIED BY 'MY_PASSWORD_FOR_DEV';
MariaDB [none]> GRANT ALL PRIVILEGES ON `chexpire_test%`.* TO `chexpire_test`@localhost IDENTIFIED BY 'MY_PASSWORD_FOR_TEST';
MariaDB [none]> FLUSH PRIVILEGES;
```
@ -113,3 +119,17 @@ You can use the `script/to_staging` and/or `script/to_production` scripts.
* with `to_production` you deploy the `master` branch to production.
On the remote servers where the application will be deployed you have to copy the configuration files just as you've just did for your development setup. The files has to go in the `shared/config/` directory, relative to your `deploy_to` path. They will be symlinked to the proper destination by Capistrano.
If an `.rbenv-vars` file is found in the shared directory, it will be linked to help loading environment files (by Ruby via Rbenv, systemd…).
### systemd
If you want to use systemd to manage your Puma process, there are [a few different ways](https://github.com/puma/puma/blob/master/docs/systemd.md). We've prepared a systemd unit file (`config/deploy/puma-chexpire@.service`) but you can adjust to better suit your needs.
If you deploy your application to `/home/chexpire_<environment>`, the systemd unit can be used as a template, for example : `puma-chexpire@production.service`. This template is compatible with systemd actions like `systemctl stop puma-chexpire@production.service` and also with Capistrano tasks like `cap production puma:stop`.
To install the systemd unit :
```
$ cp config/deploy/puma-chexpire@.service /etc/systemd/system/puma-chexpire@.service
$ systemctl enable puma-chexpire@<environment>.service
```

View File

@ -1 +1,2 @@
//= link_tree ../images
//= link_directory ../stylesheets .css

View File

@ -45,6 +45,6 @@ class ApplicationController < ActionController::Base
end
def render_404
render file: "#{Rails.root}/public/404", status: :not_found
render file: "#{Rails.root}/public/404.html", status: :not_found
end
end

View File

@ -1,15 +0,0 @@
// Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
// License: GNU AGPL-3+ (see full text in LICENSE file)
$input-placeholder-color: #b9bbbb;
$enable-rounded: false;
$theme-colors: (
"primary": #118b83, //light-green
"secondary": #013d3a, //dark-green
"tertiary": #be0c04, //red
"quaternary": #d6b20e, // yellow
"success": #118b83, //light-green
"warning": #F6AE2D,
"danger": #be0c04, //red
"info": #2E86AB,
);

View File

@ -1,4 +0,0 @@
// Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
// License: GNU AGPL-3+ (see full text in LICENSE file)
import './index.scss';

View File

@ -6,27 +6,25 @@
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
import Rails from 'rails-ujs';
import Turbolinks from 'turbolinks';
require("@rails/ujs").start()
require("turbolinks").start()
// require("@rails/activestorage").start()
// require("channels")
import 'bootstrap/js/dist/collapse';
import 'bootstrap/js/dist/dropdown';
import 'bootstrap/js/dist/button';
import 'bootstrap/js/dist/tooltip';
import '../scss';
import 'bootstrap'
import '../stylesheets/application'
import checkValidationInitialize from '../components/check_validation';
Rails.start()
Turbolinks.start()
document.addEventListener("turbolinks:load", () => {
$('[data-toggle="tooltip"]').tooltip();
checkValidationInitialize();
});
// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

View File

@ -0,0 +1,15 @@
// Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
// License: GNU AGPL-3+ (see full text in LICENSE file)
$input-placeholder-color: #b9bbbb;
$enable-rounded: false;
$theme-colors: (
"primary": #118b83, //light-green
"secondary": #013d3a, //dark-green
"tertiary": #be0c04, //red
"quaternary": #d6b20e, //yellow
"success": #118b83, //light-green
"warning": #F6AE2D, //orange
"danger": #be0c04, //red
"info": #2E86AB, //light-blue
);

View File

@ -1,10 +1,9 @@
// Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
// License: GNU AGPL-3+ (see full text in LICENSE file)
@import '_variables';
@import '_custom';
@import '~bootstrap/scss/bootstrap';
@import 'layout';
@import 'icons';
@import 'components/callouts';
@import 'components/users';
@import 'components/checks';

View File

@ -146,7 +146,7 @@ a.navbar-item.navbar-link {
.row {
height: 100%;
}
.homepage-img {
border: 1px solid map-get($theme-colors, secondary);
}

View File

@ -1,4 +1,10 @@
class ApplicationJob < ActiveJob::Base
# Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked
# Most jobs are safe to ignore if the underlying records are no longer available
# discard_on ActiveJob::DeserializationError
# from http://api.rubyonrails.org/classes/ActiveJob/Core.html
attr_writer :attempt_number

View File

@ -1,3 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
class SSLSyncJob < ApplicationJob
queue_as :default

View File

@ -1,3 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
class WhoisSyncJob < ApplicationJob
queue_as :default

View File

@ -11,19 +11,15 @@ class NotificationsMailer < ApplicationMailer
end
def domain_expires_soon
@expire_in_days = Integer(@check.domain_expires_at.to_date - Date.today)
I18n.with_locale params&.fetch(:locale) { @check.user.locale } do
subject = t(".subject", domain: @check.domain, count: @expire_in_days)
subject = t(".subject", domain: @check.domain, count: @check.domain_expires_in_days)
mail subject: subject, to: @notification.recipient
end
end
def ssl_expires_soon
@expire_in_days = Integer(@check.domain_expires_at.to_date - Date.today)
I18n.with_locale params&.fetch(:locale) { @check.user.locale } do
subject = t(".subject", domain: @check.domain, count: @expire_in_days)
subject = t(".subject", domain: @check.domain, count: @check.domain_expires_in_days)
mail subject: subject, to: @notification.recipient
end
end

View File

@ -44,6 +44,8 @@ class Check < ApplicationRecord
enum kind: [:domain, :ssl]
enum mode: [:auto, :manual]
# Those dates are written as UTC,
# but not converted back when read from the database
self.skip_time_zone_conversion_for_attributes = [
:domain_created_at,
:domain_updated_at,
@ -82,7 +84,8 @@ class Check < ApplicationRecord
def days_from_last_success
return unless last_success_at.present?
(Date.today - last_success_at.to_date).to_i
# return the number of whole days
((Time.now - last_success_at) / (24 * 3600)).to_i
end
def increment_consecutive_failures!
@ -104,6 +107,10 @@ class Check < ApplicationRecord
end
end
def domain_expires_in_days
Integer(domain_expires_at.to_date - Time.now.utc.to_date)
end
private
def domain_created_at_past

View File

@ -1,8 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "notifier/processor"
module Notifier
class << self
def process_all(configuration = nil)

View File

@ -1,6 +1,4 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "naught"
NullLogger = Naught.build

View File

@ -1,13 +1,17 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "null_logger"
require "system_command"
require_relative "ssl/parser"
require_relative "ssl/response"
require_relative "ssl/errors"
module SSL
class Error < StandardError; end
class CommandError < Error; end
class ConfigurationError < Error; end
class ParserError < Error; end
class DomainNotMatchError < ParserError; end
class InvalidResponseError < ParserError; end
class InvalidDateError < ParserError; end
class << self
def ask(domain, system_klass: SystemCommand, logger: NullLogger.new)
Service.new(domain, system_klass: system_klass, logger: logger).call
@ -41,7 +45,7 @@ module SSL
result = command.execute
unless result.exit_status.zero?
fail SSLCommandError, "SSL command failed with status #{result.exit_status}"
fail SSL::CommandError, "SSL command failed with status #{result.exit_status}"
end
result
@ -69,7 +73,7 @@ module SSL
def custom_check_http_args
return nil unless configuration.check_http_args.present?
fail SSLConfigurationError, "check_http_args option must be an array of argument." \
fail SSL::ConfigurationError, "check_http_args option must be an array of argument." \
unless configuration.check_http_args.is_a?(Array)
configuration.check_http_args

View File

@ -1,14 +0,0 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
module SSL
class Error < StandardError; end
class SSLCommandError < Error; end
class SSLConfigurationError < Error; end
class ParserError < Error; end
class DomainNotMatchError < ParserError; end
class InvalidResponseError < ParserError; end
class InvalidDateError < ParserError; end
end

View File

@ -1,9 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "null_logger"
require "ssl/errors"
module SSL
class Parser
DATE_REGEX = /will expire on (.+)\./

View File

@ -1,12 +1,10 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "open4"
require "null_logger"
SystemCommandResult = Struct.new(:command, :exit_status, :stdout, :stderr)
class SystemCommand
Result = Struct.new(:command, :exit_status, :stdout, :stderr)
class NotAllowedError < StandardError; end
attr_reader :program
attr_reader :args
attr_reader :logger
@ -42,7 +40,7 @@ class SystemCommand
pid, _, stdout, stderr = Open4.popen4 cmd
_, status = Process.waitpid2 pid
SystemCommandResult.new(
Result.new(
syscmd,
status.exitstatus || 255,
stdout.read.strip,

View File

@ -1,14 +1,17 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "null_logger"
require "domain_helper"
require "system_command"
require_relative "whois/parser"
require_relative "whois/response"
require_relative "whois/errors"
module Whois
class Error < StandardError; end
class CommandError < Error; end
class UnsupportedDomainError < Error; end
class DomainNotFoundError < Error; end
class ParserError < Error; end
class FieldNotFoundError < ParserError; end
class InvalidDateError < ParserError; end
class << self
def ask(domain, system_klass: SystemCommand, logger: NullLogger.new)
Service.new(domain, system_klass: system_klass, logger: logger).call
@ -39,7 +42,7 @@ module Whois
result = command.execute
unless result.exit_status.zero?
fail WhoisCommandError, "Whois command failed with status #{result.exit_status}"
fail Whois::CommandError, "Whois command failed with status #{result.exit_status}"
end
result

View File

@ -1,14 +0,0 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
module Whois
class Error < StandardError; end
class WhoisCommandError < Error; end
class UnsupportedDomainError < Error; end
class DomainNotFoundError < Error; end
class ParserError < Error; end
class FieldNotFoundError < ParserError; end
class InvalidDateError < ParserError; end
end

View File

@ -1,16 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "null_logger"
require "whois/errors"
require "whois/parser/afilias"
require "whois/parser/afnic"
require "whois/parser/cira"
require "whois/parser/io"
require "whois/parser/neustar"
require "whois/parser/sonic"
require "whois/parser/verisign"
module Whois
module Parser
PARSERS = [

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "domain_helper"
require "whois/errors"
require_relative "base"
module Whois
module Parser
class Afilias < Base

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "domain_helper"
require "whois/errors"
require_relative "base"
module Whois
module Parser
class AFNIC < Base

View File

@ -1,10 +1,7 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "null_logger"
require_relative "../response"
require_relative "../errors"
require_relative "entry_builder"
module Whois
module Parser

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "domain_helper"
require "whois/errors"
require_relative "base"
module Whois
module Parser
class CIRA < Base

View File

@ -1,8 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require_relative "base"
module Whois
module Parser
module Entry

View File

@ -1,8 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require_relative "base"
module Whois
module Parser
module Entry

View File

@ -1,8 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require_relative "base"
module Whois
module Parser
module Entry

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require_relative "entry/blank"
require_relative "entry/field"
require_relative "entry/text"
module Whois
module Parser
class EntryBuilder

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "domain_helper"
require "whois/errors"
require_relative "base"
module Whois
module Parser
class IO < Base

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "domain_helper"
require "whois/errors"
require_relative "base"
module Whois
module Parser
class Neustar < Base

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "domain_helper"
require "whois/errors"
require_relative "base"
module Whois
module Parser
class Sonic < Base

View File

@ -1,10 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "domain_helper"
require "whois/errors"
require_relative "base"
module Whois
module Parser
class Verisign < Base

View File

@ -33,7 +33,7 @@
</div>
<div class="col-auto">
<%= link_to Octicons::Octicon.new("x").to_svg.html_safe, checks_path, class: "btn btn-danger btn-sm btn-outline-danger" %>
<%= link_to Octicons::Octicon.new("x").to_svg.html_safe, checks_path, class: "btn btn-sm btn-outline-danger" %>
</div>
</div>

View File

@ -1,63 +1,62 @@
<% # Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr> %>
<% # License: GNU AGPL-3+ (see full text in LICENSE file) %>
<nav class="navbar navbar-expand-lg navbar-dark justify-content-between">
<div class="container-fluid">
<%= link_to (user_signed_in? ? checks_path : root_path), class: "navbar-brand" do %>
<%= image_tag 'chexpire10.png', width: 200, alt: 'chexpire logo' %>
<% end %>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<% # License: GNU AGPL-3+ (see full text in LICENSE file) %>
<nav class="navbar navbar-expand-lg navbar-dark justify-content-between">
<div class="container-fluid">
<%= link_to (user_signed_in? ? checks_path : root_path), class: "navbar-brand" do %>
<%= image_tag 'chexpire10.png', width: 200, alt: 'chexpire logo' %>
<% end %>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<% if user_signed_in? %>
<li class="nav-item">
<%= link_to(t(".my_checks"), checks_path, class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to(t(".new_domain_check"), new_check_path(kind: :domain), class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to(t(".new_ssl_check"), new_check_path(kind: :ssl), class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to(t(".my_notifications"), notifications_path, class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to("GitHub", "https://github.com/Evolix/chexpire", class: "nav-link") %>
</li>
<% end %>
</ul>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<% if user_signed_in? %>
<li class="nav-item">
<%= link_to(t(".my_checks"), checks_path, class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to(t(".new_domain_check"), new_check_path(kind: :domain), class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to(t(".new_ssl_check"), new_check_path(kind: :ssl), class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to(t(".my_notifications"), notifications_path, class: "nav-link") %>
</li>
<li class="nav-item">
<%= link_to("GitHub", "https://github.com/Evolix/chexpire", class: "nav-link") %>
</li>
<% end %>
</ul>
<div class="my-2 my-lg-0">
<% if user_signed_in? %>
<div class="navbar-item">
<div class="dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<%= current_user.email %>
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<%= link_to edit_user_registration_path, class: "dropdown-item" do %>
<div class="my-2 my-lg-0">
<% if user_signed_in? %>
<div class="navbar-item">
<div class="dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<%= current_user.email %>
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<%= link_to edit_user_registration_path, class: "dropdown-item" do %>
<i class="fa fa-user"></i>
<%= t(".profile", default: "Profile") %>
<% end %>
<%= link_to destroy_user_session_path, method: :delete, class: "dropdown-item" do %>
<i class="fa fa-sign-out"></i>
<%= t(".sign_out", default: "Sign out") %>
<% end %>
<i class="fa fa-sign-out"></i>
<%= t(".sign_out", default: "Sign out") %>
<% end %>
</div>
</div>
</div>
</div>
<% else %>
<!-- Login link (when logged out) -->
<%= link_to t(".sign_in"), new_user_session_path, class: "navbar-item navbar-link" %>
<%= link_to t(".sign_up"), new_user_registration_path, class: "navbar-item navbar-link" %>
<%= link_to "GitHub", "https://github.com/Evolix/chexpire", class: "navbar-item navbar-link" %>
<% end %>
<% else %>
<!-- Login link (when logged out) -->
<%= link_to t(".sign_in"), new_user_session_path, class: "navbar-item navbar-link" %>
<%= link_to t(".sign_up"), new_user_registration_path, class: "navbar-item navbar-link" %>
<%= link_to "GitHub", "https://github.com/Evolix/chexpire", class: "navbar-item navbar-link" %>
<% end %>
</div>
</div>
</div>
</div>
</nav>

72
babel.config.js Normal file
View File

@ -0,0 +1,72 @@
module.exports = function(api) {
var validEnv = ['development', 'test', 'production']
var currentEnv = api.env()
var isDevelopmentEnv = api.env('development')
var isProductionEnv = api.env('production')
var isTestEnv = api.env('test')
if (!validEnv.includes(currentEnv)) {
throw new Error(
'Please specify a valid `NODE_ENV` or ' +
'`BABEL_ENV` environment variables. Valid values are "development", ' +
'"test", and "production". Instead, received: ' +
JSON.stringify(currentEnv) +
'.'
)
}
return {
presets: [
isTestEnv && [
require('@babel/preset-env').default,
{
targets: {
node: 'current'
}
}
],
(isProductionEnv || isDevelopmentEnv) && [
require('@babel/preset-env').default,
{
forceAllTransforms: true,
useBuiltIns: 'entry',
corejs: 3,
modules: false,
exclude: ['transform-typeof-symbol']
}
]
].filter(Boolean),
plugins: [
require('babel-plugin-macros'),
require('@babel/plugin-syntax-dynamic-import').default,
isTestEnv && require('babel-plugin-dynamic-import-node'),
require('@babel/plugin-transform-destructuring').default,
[
require('@babel/plugin-proposal-class-properties').default,
{
loose: true
}
],
[
require('@babel/plugin-proposal-object-rest-spread').default,
{
useBuiltIns: true
}
],
[
require('@babel/plugin-transform-runtime').default,
{
helpers: false,
regenerator: true,
corejs: false
}
],
[
require('@babel/plugin-transform-regenerator').default,
{
async: false
}
]
].filter(Boolean)
}
}

View File

@ -1,3 +1,105 @@
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
load Gem.bin_path('bundler', 'bundle')
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'bundle' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require "rubygems"
m = Module.new do
module_function
def invoked_as_script?
File.expand_path($0) == File.expand_path(__FILE__)
end
def env_var_version
ENV["BUNDLER_VERSION"]
end
def cli_arg_version
return unless invoked_as_script? # don't want to hijack other binstubs
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
bundler_version = nil
update_index = nil
ARGV.each_with_index do |a, i|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
bundler_version = a
end
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
bundler_version = $1 || ">= 0.a"
update_index = i
end
bundler_version
end
def gemfile
gemfile = ENV["BUNDLE_GEMFILE"]
return gemfile if gemfile && !gemfile.empty?
File.expand_path("../../Gemfile", __FILE__)
end
def lockfile
lockfile =
case File.basename(gemfile)
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
else "#{gemfile}.lock"
end
File.expand_path(lockfile)
end
def lockfile_version
return unless File.file?(lockfile)
lockfile_contents = File.read(lockfile)
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
Regexp.last_match(1)
end
def bundler_version
@bundler_version ||= begin
env_var_version || cli_arg_version ||
lockfile_version || "#{Gem::Requirement.default}.a"
end
end
def load_bundler!
ENV["BUNDLE_GEMFILE"] ||= gemfile
# must dup string for RG < 1.8 compatibility
activate_bundler(bundler_version.dup)
end
def activate_bundler(bundler_version)
if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
bundler_version = "< 2"
end
gem_error = activation_error_handling do
gem "bundler", bundler_version
end
return if gem_error.nil?
require_error = activation_error_handling do
require "bundler/version"
end
return if require_error.nil? && Gem::Requirement.new(bundler_version).satisfied_by?(Gem::Version.new(Bundler::VERSION))
warn "Activating bundler (#{bundler_version}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_version}'`"
exit 42
end
def activation_error_handling
yield
nil
rescue StandardError, LoadError => e
e
end
end
m.load_bundler!
if m.invoked_as_script?
load Gem.bin_path("bundler", "bundle")
end

View File

@ -1,9 +1,4 @@
#!/usr/bin/env ruby
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'

View File

@ -1,9 +1,4 @@
#!/usr/bin/env ruby
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
require_relative '../config/boot'
require 'rake'
Rake.application.run

View File

@ -1,6 +1,5 @@
#!/usr/bin/env ruby
require 'fileutils'
include 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 setup or update your development environment automatically.
# This script is idempotent, so that you can run it at anytime 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
# 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'

View File

@ -1,6 +1,5 @@
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = File.expand_path('..', __dir__)
@ -9,7 +8,7 @@ def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
FileUtils.chdir APP_ROOT do
# This script is a way to update your development environment automatically.
# Add necessary update steps to this file.
@ -17,15 +16,15 @@ chdir APP_ROOT do
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
# Install JavaScript dependencies if using Yarn
# Install JavaScript dependencies
# system('bin/yarn')
puts "\n== Updating database =="
system! 'bin/rails db:migrate'
system! 'rails db:migrate'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
system! 'rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
system! 'rails restart'
end

View File

@ -12,4 +12,8 @@ require "bundler/setup"
require "webpacker"
require "webpacker/webpack_runner"
Webpacker::WebpackRunner.run(ARGV)
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Webpacker::WebpackRunner.run(ARGV)
end

View File

@ -12,4 +12,8 @@ require "bundler/setup"
require "webpacker"
require "webpacker/dev_server_runner"
Webpacker::DevServerRunner.run(ARGV)
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Webpacker::DevServerRunner.run(ARGV)
end

View File

@ -1,4 +1,4 @@
require_relative "boot"
require_relative 'boot'
require "rails"
# Pick the frameworks you want:
@ -7,6 +7,8 @@ require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
# require "action_mailbox/engine"
# require "action_text/engine"
require "action_mailer/railtie"
require "action_view/railtie"
# require "action_cable/engine"
@ -20,7 +22,7 @@ Bundler.require(*Rails.groups)
module Chexpire
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.load_defaults 6.0
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
@ -41,3 +43,6 @@ module Chexpire
config.chexpire = Hashie::Mash.new(config_for(:"chexpire.defaults").deep_merge(config_for(:chexpire)))
end
end
### Uncomment this to have zeitwerk debug log printed in stdout.
# Rails.autoloaders.logger = method(:puts)

View File

@ -24,12 +24,16 @@ set :repo_url, "https://github.com/Evolix/chexpire.git"
# Default value for :linked_files is []
append :linked_files,
".rbenv-vars",
"config/chexpire.yml",
"config/database.yml",
"config/secrets.yml"
# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
append :linked_dirs,
"tmp/pids",
"tmp/sockets"
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }

View File

@ -0,0 +1,21 @@
[Unit]
Description=Puma Server for Chexpire (%i)
After=network.target
[Service]
Type=forking
User=chexpire_%i
EnvironmentFile=/home/chexpire_%i/www/current/.rbenv-vars
Environment=RAILS_ENV=%i
WorkingDirectory=/home/chexpire_%i/www/current/
PIDFile=/home/chexpire_%i/www/shared/tmp/pids/puma.pid
ExecStart=/home/chexpire_%i/.rbenv/bin/rbenv exec bundle exec puma -C /home/chexpire_%i/www/current/config/puma.rb --daemon
ExecStop=/home/chexpire_%i/.rbenv/bin/rbenv exec bundle exec pumactl -F /home/chexpire_%i/www/current/config/puma.rb stop
ExecReload=/home/chexpire_%i/.rbenv/bin/rbenv exec bundle exec pumactl -F /home/chexpire_%i/www/current/config/puma.rb phased-restart
Restart=no
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

View File

@ -20,6 +20,7 @@ Rails.application.configure do
# Run rails dev:cache to toggle caching.
if Rails.root.join('tmp', 'caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
config.cache_store = :memory_store
config.public_file_server.headers = {
@ -31,7 +32,7 @@ Rails.application.configure do
config.cache_store = :null_store
end
# Store uploaded files on the local file system (see config/storage.yml for options)
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
config.action_mailer.delivery_method = :letter_opener_web
@ -58,14 +59,14 @@ Rails.application.configure do
config.active_record.verbose_query_logs = true
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant intervals in view rendering with a large
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Raises error for missing translations
# Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true
# Use an evented file watcher to asynchronously detect changes in source code,

View File

@ -24,15 +24,12 @@ Rails.application.configure do
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# Compress CSS using a preprocessor.
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
@ -40,7 +37,7 @@ Rails.application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Store uploaded files on the local file system (see config/storage.yml for options)
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
@ -56,9 +53,9 @@ Rails.application.configure do
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Use a real queuing backend for Active Job (and separate queues per environment)
# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "chexpire_#{Rails.env}"
# config.active_job.queue_name_prefix = "chexpire_production"
config.action_mailer.perform_caching = false
@ -93,4 +90,25 @@ Rails.application.configure do
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Inserts middleware to perform automatic connection switching.
# The `database_selector` hash is used to pass options to the DatabaseSelector
# middleware. The `delay` is used to determine how long to wait after a write
# to send a subsequent read to the primary.
#
# The `database_resolver` class is used by the middleware to determine which
# database is appropriate to use based on the time delay.
#
# The `database_resolver_context` class is used by the middleware to set
# timestamps for the last write to the primary. The resolver uses the context
# class timestamps to determine how long to wait before reading from the
# replica.
#
# By default Rails will store a last write timestamp in the session. The
# DatabaseSelector middleware is designed as such you can define your own
# strategy for connection switching and pass that into the middleware through
# these configuration options.
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end

View File

@ -1,11 +1,7 @@
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
config.cache_classes = false
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
@ -23,6 +19,7 @@ Rails.application.configure do
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.cache_store = :null_store
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
@ -30,7 +27,7 @@ Rails.application.configure do
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Store uploaded files on the local file system in a temporary directory
# Store uploaded files on the local file system in a temporary directory.
config.active_storage.service = :test
config.action_mailer.perform_caching = false
@ -45,6 +42,6 @@ Rails.application.configure do
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
# Raises error for missing translations
# Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true
end

View File

@ -10,16 +10,24 @@ Rails.application.config.content_security_policy do |policy|
policy.img_src :self, :https, :data
policy.object_src :none
policy.script_src :self, :https
policy.style_src :self, :https
if Rails.env.development?
policy.style_src :self, :https, :blob
else
policy.style_src :self, :https
end
# If you are using webpack-dev-server then specify webpack-dev-server host
policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
# Specify URI for violation reports
# policy.report_uri "/csp-violation-report-endpoint"
policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
end
# If you are using UJS then enable automatic nonce generation
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
# Set the nonce only to specific directives
# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only

View File

@ -13,4 +13,7 @@
# These inflection rules are supported but not enabled by default:
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'SSL'
inflect.acronym 'AFNIC'
inflect.acronym 'CIRA'
inflect.acronym 'IO'
end

View File

@ -0,0 +1,45 @@
# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 6.0 upgrade.
#
# Once upgraded flip defaults one by one to migrate to the new default.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
# Don't force requests from old versions of IE to be UTF-8 encoded.
# Rails.application.config.action_view.default_enforce_utf8 = false
# Embed purpose and expiry metadata inside signed and encrypted
# cookies for increased security.
#
# This option is not backwards compatible with earlier Rails versions.
# It's best enabled when your entire app is migrated and stable on 6.0.
# Rails.application.config.action_dispatch.use_cookies_with_metadata = true
# Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification.
# Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false
# Return false instead of self when enqueuing is aborted from a callback.
# Rails.application.config.active_job.return_false_on_aborted_enqueue = true
# Send Active Storage analysis and purge jobs to dedicated queues.
# Rails.application.config.active_storage.queues.analysis = :active_storage_analysis
# Rails.application.config.active_storage.queues.purge = :active_storage_purge
# When assigning to a collection of attachments declared via `has_many_attached`, replace existing
# attachments instead of appending. Use #attach to add new attachments without replacing existing ones.
# Rails.application.config.active_storage.replace_on_assign_to_many = true
# Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail.
#
# The default delivery jobs (ActionMailer::Parameterized::DeliveryJob, ActionMailer::DeliveryJob),
# will be removed in Rails 6.1. This setting is not backwards compatible with earlier Rails versions.
# If you send mail in the background, job workers need to have a copy of
# MailDeliveryJob to ensure all delivery jobs are processed properly.
# Make sure your entire app is migrated and stable on 6.0 before using this setting.
# Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob"
# Enable the same cache key to be reused when the object being cached of type
# `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count)
# of the relation's cache key into the cache version to support recycling cache key.
# Rails.application.config.active_record.collection_cache_versioning = true

View File

@ -4,31 +4,48 @@
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT") { 3000 }
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
rails_env = ENV.fetch("RAILS_ENV") { "development" }
environment rails_env
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked webserver processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
app_dir = File.expand_path("../..", __FILE__)
directory app_dir
shared_dir = "#{app_dir}/tmp"
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
if %w[production staging].member?(rails_env)
# Logging
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
# Change to match your CPU core count
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
preload_app!
# Set up socket location and port
bind "unix://#{shared_dir}/sockets/puma.sock"
port ENV.fetch("PORT") { 3000 }
before_fork do
ActiveRecord::Base.connection_pool.disconnect!
end
on_worker_boot do
ActiveSupport.on_load(:active_record) do
db_url = ENV.fetch('DATABASE_URL')
# puts "puma: connecting to DB at #{db_url}"
ActiveRecord::Base.establish_connection(db_url)
end
end
elsif rails_env == "development"
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
port ENV.fetch("PORT") { 3000 }
plugin :tmp_restart
end

View File

@ -4,7 +4,7 @@
# In order to update the route map below,
# run `bundle exec annotate -r` after modifying this file
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
resources :checks, except: [:show] do
collection do
@ -63,7 +63,7 @@ end
# rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
# update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
# rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
#
#
# Routes for LetterOpenerWeb::Engine:
# clear_letters DELETE /clear(.:format) letter_opener_web/letters#clear
# delete_letter DELETE /:id(.:format) letter_opener_web/letters#destroy

View File

@ -1,6 +1,6 @@
%w[
.ruby-version
.rbenv-vars
tmp/restart.txt
tmp/caching-dev.txt
].each { |path| Spring.watch(path) }
Spring.watch(
".ruby-version",
".rbenv-vars",
"tmp/restart.txt",
"tmp/caching-dev.txt"
)

View File

@ -1,12 +1,11 @@
const webpack = require('webpack')
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default'],
Util: "exports-loader?Util!bootstrap/js/dist/util",
// Util: "exports-loader?Util!bootstrap/js/dist/util",
}))
module.exports = environment

View File

@ -1,10 +1,13 @@
# Note: You must restart bin/webpack-dev-server for changes to take effect
default: &default
source_path: app/frontend
source_path: app/javascript
source_entry_path: packs
public_root_path: public
public_output_path: packs
cache_path: tmp/cache/webpacker
check_yarn_integrity: false
webpack_compile_output: false
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
@ -13,7 +16,25 @@ default: &default
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
# Extract and emit a css file
extract_css: false
static_assets_extensions:
- .jpg
- .jpeg
- .png
- .gif
- .tiff
- .ico
- .svg
- .eot
- .otf
- .ttf
- .woff
- .woff2
extensions:
- .mjs
- .js
- .sass
- .scss
@ -31,6 +52,9 @@ development:
<<: *default
compile: true
# Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
check_yarn_integrity: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
@ -48,7 +72,7 @@ development:
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: /node_modules/
ignored: '**/node_modules/**'
test:
@ -64,6 +88,9 @@ production:
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true
@ -73,5 +100,8 @@ staging:
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true

View File

@ -0,0 +1,10 @@
# This migration comes from active_storage (originally 20180723000244)
class AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId < ActiveRecord::Migration[6.0]
def up
return if foreign_key_exists?(:active_storage_attachments, column: :blob_id)
if table_exists?(:active_storage_blobs)
add_foreign_key :active_storage_attachments, :active_storage_blobs, column: :blob_id
end
end
end

View File

@ -2,15 +2,15 @@
# 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 `rails
# db:schema:load`. When creating a new database, `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: 2018_08_30_083927) do
ActiveRecord::Schema.define(version: 2019_08_16_223645) do
create_table "check_logs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.bigint "check_id"

View File

@ -1,4 +0,0 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
class SystemCommandNotAllowedError < StandardError; end

View File

@ -1,8 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "null_logger"
namespace :checks do
namespace :sync_dates do
task all: [:domain, :ssl]

View File

@ -1,8 +1,6 @@
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
# require "services/notifier"
namespace :notifications do
desc "Send all notifications after checks have been performend"
task send_all: :environment do

View File

@ -2,15 +2,18 @@
"name": "chexpire",
"private": true,
"dependencies": {
"@rails/webpacker": "3.5",
"bootstrap": "^4.1.1",
"@rails/ujs": "^6.0.0-alpha",
"@rails/webpacker": "^4.0.7",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"bootstrap": "4.3.1",
"exports-loader": "^0.7.0",
"jquery": "^3.3.1",
"popper.js": "^1.14.3",
"rails-ujs": "^5.2.0",
"turbolinks": "^5.1.1"
"jquery": "^3.4.1",
"popper.js": "^1.15.0",
"postcss-preset-env": "^6.7.0",
"turbolinks": "^5.2.0"
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "2.11.2"
"webpack-dev-server": "^3.8.0"
}
}

12
postcss.config.js Normal file
View File

@ -0,0 +1,12 @@
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
})
]
}

View File

@ -34,6 +34,7 @@ if [ "${confirmed}" != "y" ]; then
exit 1
fi
echo "🚀 Deploying master to production !"
bundle exec cap production deploy
echo "😎 Done !"

View File

@ -6,7 +6,15 @@
set -e
[ -n "$DEBUG" ] && set -x
echo "👀 Fetching git repository information…"
git fetch origin --quiet
CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD`
echo "🚀 Deploying ${CURRENT_BRANCH} to staging !"
git branch -f staging
git push --force origin staging
bundle exec cap staging deploy
echo "😎 Done !"

View File

@ -4,7 +4,7 @@
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :headless_chrome
driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
def teardown
Warden.test_reset!

View File

@ -2,7 +2,6 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "domain_helper"
class DomainHelperTest < ActiveSupport::TestCase
include DomainHelper

View File

@ -5,64 +5,62 @@ require "test_helper"
class NotificationsMailerTest < ActionMailer::TestCase # rubocop:disable Metrics/ClassLength
test "domain_expires_soon" do
check = create(:check, domain_expires_at: Time.new(2018, 6, 10, 12, 0, 5, "+02:00"))
expiration_date = 8.days.from_now.utc
check = create(:check, domain_expires_at: expiration_date)
notification = build(:notification, interval: 10, recipient: "colin@example.org")
check_notification = build(:check_notification, check: check, notification: notification)
Date.stub :today, Date.new(2018, 6, 2) do
mail = NotificationsMailer.with(check_notification: check_notification).domain_expires_soon
mail = NotificationsMailer.with(check_notification: check_notification).domain_expires_soon
assert_emails 1 do
mail.deliver_now
end
assert_emails 1 do
mail.deliver_now
end
assert_match "domain.fr", mail.subject
assert_match "in 8 days", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
assert_match "domain.fr", mail.subject
assert_match "in 8 days", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts.each do |part|
assert_match "domain.fr", part
assert_match "Sun, 10 Jun 2018 10:00:05 +0000", part
assert_match "10 days", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "comment", part
assert_no_match "vendor", part
end
parts.each do |part|
assert_match "domain.fr", part
assert_match I18n.l(expiration_date, locale: :en), part
assert_match "10 days", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "comment", part
assert_no_match "vendor", part
end
end
test "domain_expires_soon FR" do
expiration_date = 8.days.from_now.utc
check = create(:check,
domain_expires_at: Time.new(2018, 6, 10, 12, 0, 5, "+02:00"),
domain_expires_at: expiration_date,
user: build(:user, :fr))
notification = build(:notification, interval: 10, recipient: "colin@example.org")
check_notification = build(:check_notification, check: check, notification: notification)
Date.stub :today, Date.new(2018, 6, 2) do
mail = NotificationsMailer.with(check_notification: check_notification).domain_expires_soon
mail = NotificationsMailer.with(check_notification: check_notification).domain_expires_soon
assert_emails 1 do
mail.deliver_now
end
assert_emails 1 do
mail.deliver_now
end
assert_match "domain.fr", mail.subject
assert_match "dans 8 jours", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
assert_match "domain.fr", mail.subject
assert_match "dans 8 jours", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts.each do |part|
assert_match "domain.fr", part
assert_match "dim 10 juin 2018 10:00:05 +0000", part
assert_match "10 jours", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "commentaire", part
assert_no_match "fournisseur", part
end
parts.each do |part|
assert_match "domain.fr", part
assert_match I18n.l(expiration_date, locale: :fr), part
assert_match "10 jours", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "commentaire", part
assert_no_match "fournisseur", part
end
end
@ -159,66 +157,64 @@ class NotificationsMailerTest < ActionMailer::TestCase # rubocop:disable Metrics
end
test "ssl_expires_soon" do
check = create(:check, :ssl, domain_expires_at: Time.new(2018, 6, 10, 12, 0, 5, "+02:00"))
expiration_date = 8.days.from_now.utc
check = create(:check, :ssl, domain_expires_at: 8.days.from_now)
notification = build(:notification, interval: 10, recipient: "colin@example.org")
check_notification = build(:check_notification, check: check, notification: notification)
Date.stub :today, Date.new(2018, 6, 2) do
mail = NotificationsMailer.with(check_notification: check_notification).ssl_expires_soon
mail = NotificationsMailer.with(check_notification: check_notification).ssl_expires_soon
assert_emails 1 do
mail.deliver_now
end
assert_emails 1 do
mail.deliver_now
end
assert_match "domain.fr", mail.subject
assert_match "SSL", mail.subject
assert_match "in 8 days", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
assert_match "domain.fr", mail.subject
assert_match "SSL", mail.subject
assert_match "in 8 days", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts.each do |part|
assert_match "domain.fr", part
assert_match "Sun, 10 Jun 2018 10:00:05 +0000", part
assert_match "10 days", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "comment", part
assert_no_match "vendor", part
end
parts.each do |part|
assert_match "domain.fr", part
assert_match I18n.l(expiration_date, locale: :en), part
assert_match "10 days", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "comment", part
assert_no_match "vendor", part
end
end
test "ssl_expires_soon - FR" do
expiration_date = 8.days.from_now.utc
check = create(:check, :ssl,
domain_expires_at: Time.new(2018, 6, 10, 12, 0, 5, "+02:00"),
domain_expires_at: expiration_date,
user: build(:user, :fr))
notification = build(:notification, interval: 10, recipient: "colin@example.org")
check_notification = build(:check_notification, check: check, notification: notification)
Date.stub :today, Date.new(2018, 6, 2) do
mail = NotificationsMailer.with(check_notification: check_notification).ssl_expires_soon
mail = NotificationsMailer.with(check_notification: check_notification).ssl_expires_soon
assert_emails 1 do
mail.deliver_now
end
assert_emails 1 do
mail.deliver_now
end
assert_match "domain.fr", mail.subject
assert_match "SSL", mail.subject
assert_match "dans 8 jours", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
assert_match "domain.fr", mail.subject
assert_match "SSL", mail.subject
assert_match "dans 8 jours", mail.subject
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts.each do |part|
assert_match "domain.fr", part
assert_match "dim 10 juin 2018 10:00:05 +0000", part
assert_match "10 jours", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "commentaire", part
assert_no_match "fournisseur", part
end
parts.each do |part|
assert_match "domain.fr", part
assert_match I18n.l(expiration_date, locale: :fr), part
assert_match "10 jours", part
assert_match "/checks/#{check.id}/edit", part
assert_no_match "commentaire", part
assert_no_match "fournisseur", part
end
end
end

View File

@ -117,10 +117,28 @@ class CheckTest < ActiveSupport::TestCase
test "set mode before saving" do
check = build(:check, domain: "domain.fr")
check.save!
assert check.auto?
check.domain = "domain.xyz"
check.save!
assert check.mode?
end
test "expiration in days (future)" do
check = create(:check, domain_expires_at: 1.week.from_now)
expected = 7
actual = check.domain_expires_in_days
assert_equal expected, actual
end
test "expiration in days (past)" do
check = create(:check, domain_expires_at: 1.week.ago)
expected = -7
actual = check.domain_expires_in_days
assert_equal expected, actual
end
end

View File

@ -2,8 +2,6 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "check_logger"
require "system_command"
class CheckLoggerTest < ActiveSupport::TestCase
setup do
@ -20,7 +18,7 @@ class CheckLoggerTest < ActiveSupport::TestCase
end
test "should log a success raw result command" do
result = SystemCommandResult.new("command", 0, "the result", "")
result = SystemCommand::Result.new("command", 0, "the result", "")
assert_no_difference -> { CheckLog.where(check: @check).count } do
@logger.log :after_command, result
@ -33,7 +31,7 @@ class CheckLoggerTest < ActiveSupport::TestCase
end
test "should log a raw result command with an error" do
result = SystemCommandResult.new("command", 1, "optional stdout", "an error occured")
result = SystemCommand::Result.new("command", 1, "optional stdout", "an error occured")
@logger.log :after_command, result
assert_equal "optional stdout", @logger.check_log.raw_response
@ -43,7 +41,7 @@ class CheckLoggerTest < ActiveSupport::TestCase
end
test "should log an error when there is not exit status" do
result = SystemCommandResult.new("command", nil, nil, "an error")
result = SystemCommand::Result.new("command", nil, nil, "an error")
@logger.log :after_command, result
assert_nil @logger.check_log.raw_response

View File

@ -2,7 +2,6 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "notifier"
class NotifierTest < ActiveSupport::TestCase
test "#process_all process expirable & failures notifications" do

View File

@ -2,8 +2,6 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "ssl/parser"
require "ssl/errors"
module SSL
class ParserTest < ActiveSupport::TestCase
@ -11,7 +9,7 @@ module SSL
parser = Parser.new("ssl0.domain.org")
domain = file_fixture("ssl/ssl0.domain.org.txt").read
response = parser.parse(domain)
assert_kind_of Response, response
assert_kind_of SSL::Response, response
assert_equal Time.new(2028, 6, 10, 9, 14, 18, 0), response.expire_at
assert response.expire_at.utc?
@ -21,7 +19,7 @@ module SSL
parser = Parser.new("ssl1.domain.org")
domain = file_fixture("ssl/ssl1.domain.org.txt").read
response = parser.parse(domain)
assert_kind_of Response, response
assert_kind_of SSL::Response, response
assert_equal Time.new(2022, 8, 6, 0, 57, 0, 0), response.expire_at
assert response.expire_at.utc?

View File

@ -2,8 +2,6 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "ssl"
require "system_command"
module SSL
class ServiceTest < ActiveSupport::TestCase
@ -11,7 +9,7 @@ module SSL
result = OpenStruct.new(exit_status: 0)
mock_system_klass("check_http", standard_args, result) do |system_klass|
service = Service.new("example.org", system_klass: system_klass)
service = SSL::Service.new("example.org", system_klass: system_klass)
assert_equal result, service.run_command
end
end
@ -20,9 +18,9 @@ module SSL
result = OpenStruct.new(exit_status: 1)
mock_system_klass("check_http", standard_args, result) do |system_klass|
service = Service.new("example.org", system_klass: system_klass)
service = SSL::Service.new("example.org", system_klass: system_klass)
assert_raises SSLCommandError do
assert_raises SSL::CommandError do
service.run_command
end
end
@ -34,8 +32,8 @@ module SSL
stdout: file_fixture("ssl/ssl0.domain.org.txt").read,
)
service = Service.new("ssl0.domain.org")
assert_kind_of Response, service.parse(result)
service = SSL::Service.new("ssl0.domain.org")
assert_kind_of SSL::Response, service.parse(result)
end
test "should uses the command line arguments of the configuration" do
@ -44,7 +42,7 @@ module SSL
expected_args = standard_args.concat ["-f", "-I 127.0.0.1"]
mock_system_klass("check_http", expected_args, result) do |system_klass|
service = Service.new("example.org", configuration: config, system_klass: system_klass)
service = SSL::Service.new("example.org", configuration: config, system_klass: system_klass)
assert_equal result, service.run_command
end
end
@ -53,8 +51,8 @@ module SSL
black_hole = Naught.build(&:black_hole)
config = OpenStruct.new(check_http_args: "-f")
assert_raises SSLConfigurationError do
service = Service.new("example.org", configuration: config, system_klass: black_hole)
assert_raises SSL::ConfigurationError do
service = SSL::Service.new("example.org", configuration: config, system_klass: black_hole)
service.run_command
end
end
@ -64,7 +62,7 @@ module SSL
config = OpenStruct.new(check_http_path: "/usr/local/custom/path")
mock_system_klass("/usr/local/custom/path", standard_args, result) do |sys|
service = Service.new("example.org", configuration: config, system_klass: sys)
service = SSL::Service.new("example.org", configuration: config, system_klass: sys)
assert_equal result, service.run_command
end
end

View File

@ -2,14 +2,13 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "system_command"
class SystemCommandTest < ActiveSupport::TestCase
test "should execute and log a command" do
mock_logger = Minitest::Mock.new
expected_cmd = 'whois "example.org"'
expected_result = SystemCommandResult.new(
expected_result = SystemCommand::Result.new(
expected_cmd,
0,
"my result",

View File

@ -2,17 +2,14 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser/afilias"
require "whois/response"
require "whois/errors"
module Whois
class AfiliasTest < ActiveSupport::TestCase
test "should parse a whois response for .info" do
parser = Parser::Afilias.new("domain.info")
parser = Whois::Parser::Afilias.new("domain.info")
whois_output = file_fixture("whois/domain.info.txt").read
response = parser.parse(whois_output)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(2006, 3, 25, 14, 1, 14, 0), response.created_at
assert response.created_at.utc?
@ -22,7 +19,7 @@ module Whois
end
test "should raises DomainNotFoundError for .info when domain is not registered" do
parser = Parser::Afilias.new("willneverexist.info")
parser = Whois::Parser::Afilias.new("willneverexist.info")
not_found = file_fixture("whois/willneverexist.info.txt").read
assert_raises DomainNotFoundError do
@ -31,7 +28,7 @@ module Whois
end
test "should raises InvalidDateError for .info when a date is not parsable" do
parser = Parser::Afilias.new("domain.info")
parser = Whois::Parser::Afilias.new("domain.info")
whois_output = file_fixture("whois/domain.info.txt").read
whois_output.gsub!("2020-03-25T14:01:14Z", "not a date")
@ -41,10 +38,10 @@ module Whois
end
test "should parse a whois response for .org" do
parser = Parser::Afilias.new("domain.org")
parser = Whois::Parser::Afilias.new("domain.org")
domain_com = file_fixture("whois/domain.org.txt").read
response = parser.parse(domain_com)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(1995, 4, 30, 4, 0, 0, 0), response.created_at
assert response.created_at.utc?
@ -54,7 +51,7 @@ module Whois
end
test "should raises DomainNotFoundError for .org when domain is not registered" do
parser = Parser::Afilias.new("willneverexist.org")
parser = Whois::Parser::Afilias.new("willneverexist.org")
not_found = file_fixture("whois/willneverexist.org.txt").read
assert_raises DomainNotFoundError do
@ -63,7 +60,7 @@ module Whois
end
test "should raises InvalidDateError for .org when a date is not parsable" do
parser = Parser::Afilias.new("domain.org")
parser = Whois::Parser::Afilias.new("domain.org")
domain_com = file_fixture("whois/domain.org.txt").read
domain_com.gsub!("2018-04-02T03:47:23Z", "not a date")

View File

@ -2,17 +2,14 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser/afnic"
require "whois/response"
require "whois/errors"
module Whois
class AFNICTest < ActiveSupport::TestCase
test "should parse a whois response" do
parser = Parser::AFNIC.new("domain.fr")
parser = Whois::Parser::AFNIC.new("domain.fr")
domain_fr = file_fixture("whois/domain.fr.txt").read
response = parser.parse(domain_fr)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(2004, 2, 18, 0, 0, 0, 0), response.created_at
assert response.created_at.utc?
@ -22,7 +19,7 @@ module Whois
end
test "should raises DomainNotFoundError when domain is not registered" do
parser = Parser::AFNIC.new("willneverexist.fr")
parser = Whois::Parser::AFNIC.new("willneverexist.fr")
not_found_fr = file_fixture("whois/willneverexist.fr.txt").read
assert_raises DomainNotFoundError do
@ -31,7 +28,7 @@ module Whois
end
test "should raises InvalidDateError when a date is not in the expected format" do
parser = Parser::AFNIC.new("domain.fr")
parser = Whois::Parser::AFNIC.new("domain.fr")
domain_fr = file_fixture("whois/domain.fr.txt").read
domain_fr.gsub!("17/02/2019", "17-02-2019")

View File

@ -2,17 +2,14 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser/cira"
require "whois/response"
require "whois/errors"
module Whois
class CIRATest < ActiveSupport::TestCase
test "should parse a whois response for .ca" do
parser = Parser::CIRA.new("domain.ca")
parser = Whois::Parser::CIRA.new("domain.ca")
whois_output = file_fixture("whois/domain.ca.txt").read
response = parser.parse(whois_output)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(2015, 3, 24, 9, 10, 16, 0), response.created_at
assert response.created_at.utc?
@ -22,7 +19,7 @@ module Whois
end
test "should raises DomainNotFoundError for .ca when domain is not registered" do
parser = Parser::CIRA.new("willneverexist.ca")
parser = Whois::Parser::CIRA.new("willneverexist.ca")
not_found = file_fixture("whois/willneverexist.ca.txt").read
assert_raises DomainNotFoundError do
@ -31,7 +28,7 @@ module Whois
end
test "should raises InvalidDateError for .ca when a date is not parsable" do
parser = Parser::CIRA.new("domain.ca")
parser = Whois::Parser::CIRA.new("domain.ca")
whois_output = file_fixture("whois/domain.ca.txt").read
whois_output.gsub!("2015-03-24T09:10:16Z", "not a date")

View File

@ -2,17 +2,14 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser/io"
require "whois/response"
require "whois/errors"
module Whois
class IOTest < ActiveSupport::TestCase
test "should parse a whois response for .io" do
parser = Parser::IO.new("domain.io")
parser = Whois::Parser::IO.new("domain.io")
whois_output = file_fixture("whois/domain.io.txt").read
response = parser.parse(whois_output)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(2016, 7, 26, 6, 16, 0, 0), response.created_at
assert response.created_at.utc?
@ -22,7 +19,7 @@ module Whois
end
test "should raises DomainNotFoundError for .io when domain is not registered" do
parser = Parser::IO.new("willneverexist.io")
parser = Whois::Parser::IO.new("willneverexist.io")
not_found = file_fixture("whois/willneverexist.io.txt").read
assert_raises DomainNotFoundError do
@ -31,7 +28,7 @@ module Whois
end
test "should raises InvalidDateError for .io when a date is not parsable" do
parser = Parser::IO.new("domain.io")
parser = Whois::Parser::IO.new("domain.io")
whois_output = file_fixture("whois/domain.io.txt").read
whois_output.gsub!("2016-07-26T06:16:00Z", "not a date")

View File

@ -2,17 +2,14 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser/neustar"
require "whois/response"
require "whois/errors"
module Whois
class NeustarTest < ActiveSupport::TestCase
test "should parse a whois response for .us" do
parser = Parser::Neustar.new("domain.us")
parser = Whois::Parser::Neustar.new("domain.us")
whois_output = file_fixture("whois/domain.us.txt").read
response = parser.parse(whois_output)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(2002, 4, 18, 15, 36, 40, 0), response.created_at
assert response.created_at.utc?
@ -22,7 +19,7 @@ module Whois
end
test "should raises DomainNotFoundError for .us when domain is not registered" do
parser = Parser::Neustar.new("willneverexist.us")
parser = Whois::Parser::Neustar.new("willneverexist.us")
not_found = file_fixture("whois/willneverexist.us.txt").read
assert_raises DomainNotFoundError do
@ -31,7 +28,7 @@ module Whois
end
test "should raises InvalidDateError for .us when a date is not parsable" do
parser = Parser::Neustar.new("domain.us")
parser = Whois::Parser::Neustar.new("domain.us")
whois_output = file_fixture("whois/domain.us.txt").read
whois_output.gsub!("2018-06-02T00:05:41Z", "not a date")

View File

@ -2,17 +2,14 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser/sonic"
require "whois/response"
require "whois/errors"
module Whois
class SonicTest < ActiveSupport::TestCase
test "should parse a whois response for .so" do
parser = Parser::Sonic.new("domain.so")
parser = Whois::Parser::Sonic.new("domain.so")
whois_output = file_fixture("whois/domain.so.txt").read
response = parser.parse(whois_output)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(2010, 10, 31, 0, 0, 0, 0), response.created_at
assert response.created_at.utc?
@ -26,7 +23,7 @@ module Whois
end
test "should raises DomainNotFoundError for .so when domain is not registered" do
parser = Parser::Sonic.new("willneverexist.so")
parser = Whois::Parser::Sonic.new("willneverexist.so")
not_found = file_fixture("whois/willneverexist.so.txt").read
assert_raises DomainNotFoundError do
@ -35,7 +32,7 @@ module Whois
end
test "should raises InvalidDateError for .so when a date is not parsable" do
parser = Parser::Sonic.new("domain.so")
parser = Whois::Parser::Sonic.new("domain.so")
whois_output = file_fixture("whois/domain.so.txt").read
whois_output.gsub!("2010-10-31T00:00:00.0Z", "not a date")

View File

@ -2,17 +2,14 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser/verisign"
require "whois/response"
require "whois/errors"
module Whois
class VerisignTest < ActiveSupport::TestCase
test "should parse a whois response" do
parser = Parser::Verisign.new("domain.com")
parser = Whois::Parser::Verisign.new("domain.com")
domain_com = file_fixture("whois/domain.com.txt").read
response = parser.parse(domain_com)
assert_kind_of Response, response
assert_kind_of Whois::Response, response
assert_equal Time.new(1994, 7, 1, 4, 0, 0, 0), response.created_at
assert response.created_at.utc?
@ -22,7 +19,7 @@ module Whois
end
test "should raises DomainNotFoundError when domain is not registered" do
parser = Parser::Verisign.new("willneverexist.com")
parser = Whois::Parser::Verisign.new("willneverexist.com")
not_found_com = file_fixture("whois/willneverexist.com.txt").read
assert_raises DomainNotFoundError do
@ -31,7 +28,7 @@ module Whois
end
test "should raises InvalidDateError when a date is not parsable" do
parser = Parser::Verisign.new("domain.com")
parser = Whois::Parser::Verisign.new("domain.com")
domain_com = file_fixture("whois/domain.com.txt").read
domain_com.gsub!("2018-02-13T18:33:26Z", "not a date")

View File

@ -2,8 +2,6 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois/parser"
require "whois/errors"
module Whois
class ParserTest < ActiveSupport::TestCase

View File

@ -2,8 +2,6 @@
# License: GNU AGPL-3+ (see full text in LICENSE file)
require "test_helper"
require "whois"
require "system_command"
module Whois
class ServiceTest < ActiveSupport::TestCase
@ -11,7 +9,7 @@ module Whois
result = OpenStruct.new(exit_status: 0)
mock_system_klass("whois", "example.org", result) do |system_klass|
service = Service.new("example.org", system_klass: system_klass)
service = Whois::Service.new("example.org", system_klass: system_klass)
assert_equal result, service.run_command
end
end
@ -20,9 +18,9 @@ module Whois
result = OpenStruct.new(exit_status: 1)
mock_system_klass("whois", "example.org", result) do |system_klass|
service = Service.new("example.org", system_klass: system_klass)
service = Whois::Service.new("example.org", system_klass: system_klass)
assert_raises WhoisCommandError do
assert_raises Whois::CommandError do
service.run_command
end
end
@ -34,8 +32,8 @@ module Whois
stdout: file_fixture("whois/domain.fr.txt").read,
)
service = Service.new("domain.fr")
assert_kind_of Response, service.parse(result)
service = Whois::Service.new("domain.fr")
assert_kind_of Whois::Response, service.parse(result)
end
def mock_system_klass(program, command_args, result)

View File

@ -14,7 +14,7 @@ class ChecksTest < ApplicationSystemTestCase
choose "domain"
fill_and_valid_new_check
create_new_check
end
test "create a predefined domain check" do
@ -22,7 +22,7 @@ class ChecksTest < ApplicationSystemTestCase
refute page.has_css? "domain[kind]"
fill_and_valid_new_check
create_new_check
end
test "create a manual domain check" do
@ -49,7 +49,7 @@ class ChecksTest < ApplicationSystemTestCase
refute page.has_css? "domain[kind]"
fill_and_valid_new_check
create_new_check
end
test "dettach a notification from a check" do
@ -277,7 +277,7 @@ class ChecksTest < ApplicationSystemTestCase
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def fill_and_valid_new_check
def create_new_check
domain = "domain-test.fr"
fill_in("check[domain]", with: domain)
@ -287,7 +287,7 @@ class ChecksTest < ApplicationSystemTestCase
fill_in("check[notifications_attributes][0][recipient]", with: recipient)
fill_in("check[notifications_attributes][0][interval]", with: 30)
click_button
click_button I18n.t("helpers.submit.check.create")
assert_equal checks_path, page.current_path

Some files were not shown because too many files have changed in this diff Show More