okcomputer-checks 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f08b3ef15b8e6a67e2cbedc17b6baf74353dce27f1823727d00a58adeca766b9
4
+ data.tar.gz: 515adfddf900ebb319b84534ed565824f6523414919dc6a3ba8dacf666f5cbb1
5
+ SHA512:
6
+ metadata.gz: eeb1ce14eb840282329501590b401b9f51d27763fc78b1f5d4899de0e7afed562df1403c50c0bb50999b48b4ef4424fab38a9e51e04dd505e36a226142e9702c
7
+ data.tar.gz: 7a77a7dc936f07d0658bb80c9d7233059e1148b8ae5d3058381e26f82d714224f709e2e2c1f77b5a9272fd7993abbcb9168f0a880b052df78c9e18fca1e146a2
@@ -0,0 +1,27 @@
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop.yml
3
+
4
+ AllCops:
5
+ DisabledByDefault: false
6
+ TargetRubyVersion: 2.6
7
+ Exclude:
8
+ - gemfiles/*
9
+ - spec/dummy/**/*
10
+
11
+ Lint/MissingSuper:
12
+ Exclude:
13
+ - lib/ok_computer/checks/*
14
+
15
+ Metrics/BlockLength:
16
+ Exclude:
17
+ - spec/ok_computer/*
18
+ - okcomputer-checks.gemspec
19
+
20
+ Naming/FileName:
21
+ Exclude:
22
+ - lib/okcomputer-checks.rb
23
+
24
+ ## TODOs
25
+
26
+ Style/Documentation:
27
+ Enabled: false
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise 'rails-5.1-stable' do
4
+ gem 'rails', github: 'rails/rails', branch: '5-1-stable'
5
+ end
6
+
7
+ appraise 'rails-5.2-stable' do
8
+ gem 'rails', github: 'rails/rails', branch: '5-2-stable'
9
+ end
10
+
11
+ appraise 'rails-6.0-stable' do
12
+ gem 'rails', github: 'rails/rails', branch: '6-0-stable'
13
+ gem 'sqlite3', '~> 1.4'
14
+ end
15
+
16
+ appraise 'rails-edge' do
17
+ gem 'rails', github: 'rails/rails', branch: :master
18
+ gem 'arel', github: 'rails/arel', branch: :master
19
+ gem 'sqlite3', '~> 1.4'
20
+ end
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'rails'
6
+ gem 'sprockets', '~> 3.0'
7
+
8
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 First Circle
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ [![Build Status](https://travis-ci.com/carabao-capital/okcomputer-checks.svg?branch=master)](https://travis-ci.com/carabao-capital/okcomputer-checks)
2
+ [![codecov](https://codecov.io/gh/carabao-capital/okcomputer-checks/branch/master/graph/badge.svg)](https://codecov.io/gh/carabao-capital/okcomputer-checks)
3
+
4
+ # OK Computer Checks Collection
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", github: "rails/rails", branch: "5-1-stable"
6
+ gem "sprockets", "~> 3.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", github: "rails/rails", branch: "5-2-stable"
6
+ gem "sprockets", "~> 3.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", github: "rails/rails", branch: "6-0-stable"
6
+ gem "sprockets", "~> 3.0"
7
+ gem "sqlite3", "~> 1.4"
8
+
9
+ gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", github: "rails/rails", branch: :master
6
+ gem "sprockets", "~> 3.0"
7
+ gem "arel", github: "rails/arel", branch: :master
8
+ gem "sqlite3", "~> 1.4"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/dependencies/autoload'
4
+
5
+ require 'ok_computer/check'
6
+ require 'ok_computer/checks/registry'
7
+
8
+ module OkComputer
9
+ extend ActiveSupport::Autoload
10
+
11
+ autoload :AlgoliaCheck, 'ok_computer/checks/algolia_check'
12
+ autoload :HubspotCheck, 'ok_computer/checks/hubspot_check'
13
+ autoload :NexmoCheck, 'ok_computer/checks/nexmo_check'
14
+ autoload :PusherCheck, 'ok_computer/checks/pusher_check'
15
+
16
+ # :nodoc:
17
+ module Checks
18
+ def self.register(collection = nil)
19
+ registry = Registry.new(collection)
20
+ yield registry if block_given?
21
+ registry
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'ok_computer/built_in_checks/http_check'
5
+
6
+ module OkComputer
7
+ class AlgoliaCheck < HttpCheck
8
+ StatusFailed = Class.new(StandardError)
9
+
10
+ STATUS_URL = 'https://status.algolia.com/1/status'
11
+
12
+ attr_accessor :app_id, :api_key
13
+
14
+ def initialize(url: STATUS_URL, app_id: nil, api_key: nil, request_timeout: 5)
15
+ super(url, request_timeout)
16
+
17
+ self.app_id = app_id.presence
18
+ self.api_key = api_key.presence
19
+ end
20
+
21
+ # Public: Return the status of the Monitoring check
22
+ def check
23
+ status, body = perform_request
24
+ raise(StatusFailed, body) unless status == 200 && body['status'].values.all? { |v| v == 'operational' }
25
+
26
+ mark_message('Monitoring check successful')
27
+ rescue StandardError => e
28
+ mark_message("Error: '#{e}'")
29
+ mark_failure
30
+ end
31
+
32
+ def perform_request
33
+ response = Faraday.get(url, request: { timeout: request_timeout }) do |req|
34
+ req.headers['Content-Type'] = 'application/json'
35
+ req.headers['X-Algolia-API-Key'] = api_key
36
+ req.headers['X-Algolia-Application-Id'] = app_id
37
+ end
38
+
39
+ [response.status, MultiJson.decode(response.body)]
40
+ rescue StandardError => e
41
+ raise(StatusFailed, e)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'ok_computer/built_in_checks/http_check'
5
+
6
+ module OkComputer
7
+ class HubspotCheck < HttpCheck
8
+ StatusFailed = Class.new(StandardError)
9
+
10
+ STATUS_URL = 'https://api.hubapi.com/integrations/v1/limit/daily'
11
+
12
+ attr_accessor :api_key
13
+
14
+ def initialize(url: STATUS_URL, api_key: nil, request_timeout: 5)
15
+ super(url, request_timeout)
16
+
17
+ self.api_key = api_key.presence
18
+ end
19
+
20
+ # Public: Return the status of the Rate-Limit check
21
+ def check
22
+ status, body = perform_request
23
+ raise(StatusFailed, body) unless status == 200
24
+
25
+ mark_message('Rate-Limit check successful')
26
+ rescue StandardError => e
27
+ mark_message("Error: '#{e}'")
28
+ mark_failure
29
+ end
30
+
31
+ def perform_request
32
+ response = Faraday.get(url, request: { timeout: request_timeout }) do |req|
33
+ req.headers['Content-Type'] = 'application/json'
34
+ req.body = { hapikey: api_key }.to_json
35
+ end
36
+
37
+ [response.status, MultiJson.decode(response.body)]
38
+ rescue StandardError => e
39
+ raise(StatusFailed, e)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nexmo'
4
+
5
+ module OkComputer
6
+ class NexmoCheck < Check
7
+ AccountError = Class.new(StandardError)
8
+
9
+ attr_accessor :client
10
+
11
+ def initialize(client: nil, api_key: nil, api_secret: nil, signature_secret: nil)
12
+ client ||= Nexmo::Client.new(
13
+ api_key: api_key,
14
+ api_secret: api_secret,
15
+ signature_secret: signature_secret
16
+ )
17
+
18
+ self.client = client
19
+ end
20
+
21
+ # Public: Return the status of the Account Balance check
22
+ def check
23
+ response = perform_request
24
+ return mark_failure unless response.http_response.code.to_i == 200
25
+
26
+ mark_message("Balance #{response.value} check successful")
27
+ rescue StandardError => e
28
+ mark_message("Error: '#{e}'")
29
+ mark_failure
30
+ end
31
+
32
+ def perform_request
33
+ client.account.balance
34
+ rescue StandardError => e
35
+ raise(AccountError, e)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pusher'
4
+
5
+ module OkComputer
6
+ class PusherCheck < Check
7
+ ChannelError = Class.new(StandardError)
8
+
9
+ attr_accessor :client
10
+
11
+ def initialize(client: nil, app_id: nil, app_key: nil, app_secret: nil, app_cluster: nil)
12
+ client ||= Pusher::Client.new(
13
+ app_id: app_id,
14
+ key: app_key,
15
+ secret: app_secret,
16
+ cluster: app_cluster,
17
+ use_tls: true
18
+ )
19
+
20
+ self.client = client
21
+ end
22
+
23
+ # Public: Return the status of the Channels check
24
+ def check
25
+ perform_request
26
+ mark_message('Channels check successful')
27
+ rescue StandardError => e
28
+ mark_message("Error: '#{e}'")
29
+ mark_failure
30
+ end
31
+
32
+ def perform_request
33
+ client.get('/channels')
34
+ rescue StandardError => e
35
+ raise(ChannelError, e)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/module/delegation'
4
+
5
+ require 'ok_computer/check_collection'
6
+ require 'ok_computer/registry'
7
+
8
+ module OkComputer
9
+ # :nodoc:
10
+ module Checks
11
+ class Registry < ::OkComputer::Registry
12
+ attr_accessor :collection
13
+
14
+ delegate_missing_to :collection
15
+
16
+ def initialize(collection = nil)
17
+ self.collection = if collection.is_a?(CheckCollection)
18
+ collection
19
+ elsif collection
20
+ ::OkComputer::Registry.default_collection.fetch(collection) || CheckCollection.new(collection)
21
+ else
22
+ ::OkComputer::Registry.default_collection
23
+ end
24
+ end
25
+
26
+ def add(klass_or_check, check_name, *args)
27
+ check = if klass_or_check.is_a?(CheckCollection) || klass_or_check.is_a?(Check)
28
+ klass_or_check
29
+ else
30
+ build_check(klass_or_check, *args)
31
+ end
32
+
33
+ collection.register(check_name, check)
34
+ end
35
+
36
+ private
37
+
38
+ def build_check(klass, *args)
39
+ unless klass.is_a?(Class)
40
+ begin
41
+ klass = OkComputer.const_get("#{klass}_check".camelize)
42
+ rescue NameError
43
+ raise LoadError, "Could not register #{klass.inspect}."
44
+ end
45
+ end
46
+ klass.new(*args)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OkComputer
4
+ module Checks
5
+ VERSION = '1.0.0'
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ok_computer/checks'
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push(File.expand_path('lib', __dir__))
4
+
5
+ # Maintain your gem's version:
6
+ require 'ok_computer/checks/version'
7
+
8
+ # Describe your gem and declare its dependencies:
9
+ Gem::Specification.new do |s|
10
+ s.name = 'okcomputer-checks'
11
+ s.version = OkComputer::Checks::VERSION
12
+ s.author = 'First Circle Engineering'
13
+ s.email = 'tech@firstcircle.com'
14
+ s.license = 'MIT'
15
+ s.homepage = 'https://github.com/carabao-capital/okcomputer-checks'
16
+ s.summary = 'Collection health-check for okcomputer'
17
+ s.description = %(
18
+ Collection health-check for okcomputer
19
+ )
20
+
21
+ s.files = %x(git ls-files).split("\n") - %w[.gitignore .travis.yml .ruby-version]
22
+ s.test_files = %x(git ls-files -- spec/*).split("\n")
23
+ s.require_paths = ['lib']
24
+ s.extra_rdoc_files = %w[LICENSE README.md]
25
+
26
+ s.metadata = {
27
+ 'source_code_uri' => "https://github.com/carabao-capital/okcomputer-checks/tree/v#{s.version}",
28
+ 'allowed_push_host' => 'https://rubygems.org',
29
+ }
30
+
31
+ s.required_ruby_version = '>= 2.6.5'
32
+
33
+ s.add_dependency('activesupport')
34
+ s.add_dependency('faraday')
35
+ s.add_dependency('okcomputer')
36
+
37
+ s.add_development_dependency('appraisal')
38
+ s.add_development_dependency('codecov')
39
+ s.add_development_dependency('em-http-request')
40
+ s.add_development_dependency('nexmo')
41
+ s.add_development_dependency('pusher')
42
+ s.add_development_dependency('rspec-rails', '~> 3.0')
43
+ s.add_development_dependency('rubocop-performance')
44
+ s.add_development_dependency('rubocop-rails')
45
+ s.add_development_dependency('rubocop-shopify')
46
+ s.add_development_dependency('simplecov')
47
+ s.add_development_dependency('sqlite3', '~> 1.3.6')
48
+ s.add_development_dependency('webmock')
49
+ end
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('config/environment', __dir__)
4
+ run Dummy::Application
@@ -0,0 +1,25 @@
1
+ require File.expand_path('boot', __dir__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require
6
+ require 'okcomputer'
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ config.encoding = 'utf-8'
11
+ config.filter_parameters += [:password]
12
+ config.active_support.escape_html_entities_in_json = true
13
+ config.assets.enabled = false
14
+ config.secret_key_base = '78987c1cc6dc799c6baf50cadf73700ae861e5d81d28b2ec702b6e168d0cf3c8ad7be699f1d0f98e5b2b563ca70d9516b9c2a66184de39516c09a19aa2d96817'
15
+ config.session_store(:cookie_store, key: '_dummy_session')
16
+ config.cache_classes = true
17
+ config.consider_all_requests_local = true
18
+ config.action_controller.perform_caching = false
19
+ config.action_dispatch.show_exceptions = false
20
+ config.action_controller.allow_forgery_protection = false
21
+ config.action_mailer.delivery_method = :test
22
+ config.active_support.deprecation = :stderr
23
+ config.eager_load = false
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path('../../../Gemfile', __dir__)
3
+
4
+ if File.exist?(gemfile)
5
+ ENV['BUNDLE_GEMFILE'] = gemfile
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ $:.unshift(File.expand_path('../../../lib', __dir__))
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: ":memory:"
4
+ pool: 5
5
+ timeout: 5000
@@ -0,0 +1,5 @@
1
+ # Load the rails application
2
+ require File.expand_path('application', __dir__)
3
+
4
+ # Initialize the rails application
5
+ Dummy::Application.initialize!
@@ -0,0 +1 @@
1
+ OkComputer.require_authentication('foo', 'bar')
@@ -0,0 +1,2 @@
1
+ Dummy::Application.routes.draw do
2
+ end
File without changes
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe(OkComputer::AlgoliaCheck) do
6
+ let(:app_id) { 'APPID' }
7
+ let(:api_key) { 'apikey' }
8
+ let(:response) { { status: 200, body: MultiJson.encode({}) } }
9
+
10
+ subject(:check) { described_class.new(app_id: app_id, api_key: api_key) }
11
+
12
+ before { stub_request(:get, %r{/1/status}).to_return(response) }
13
+
14
+ context('when successful') do
15
+ let(:response) do
16
+ {
17
+ status: 200,
18
+ body: MultiJson.encode(status: { 'c4-fr' => 'operational', 'c2-eu' => 'operational' }),
19
+ }
20
+ end
21
+
22
+ it { is_expected.to(be_successful_check) }
23
+ it { is_expected.to(have_message('Monitoring check successful')) }
24
+ end
25
+
26
+ context('when 401 fails') do
27
+ let(:response) do
28
+ {
29
+ status: 401,
30
+ body: MultiJson.encode(message: 'Invalid Application-Id or API-Key'),
31
+ }
32
+ end
33
+
34
+ it { is_expected.not_to(be_successful_check) }
35
+ it { is_expected.to(have_message("Error: '{\"message\"=>\"Invalid Application-Id or API-Key\"}'")) }
36
+ end
37
+
38
+ context('when not operational') do
39
+ let(:response) do
40
+ {
41
+ status: 200,
42
+ body: MultiJson.encode(status: { 'c4-fr' => 'degraded_performance', 'c2-eu' => 'major_outage' }),
43
+ }
44
+ end
45
+
46
+ it { is_expected.not_to(be_successful_check) }
47
+ end
48
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe(OkComputer::Checks) do
6
+ let(:response) do
7
+ {
8
+ status: 200,
9
+ body: MultiJson.encode(status: { 'c4-fr' => 'operational' }),
10
+ }
11
+ end
12
+
13
+ subject(:collection) { described_class.register }
14
+
15
+ before { stub_request(:get, %r{/1/status}).to_return(response) }
16
+
17
+ describe('.register') do
18
+ let(:app_id) { 'APPID' }
19
+ let(:api_key) { 'apikey' }
20
+
21
+ context('when klass') do
22
+ before do
23
+ described_class.register do |r|
24
+ r.add(:algolia, :search, app_id: app_id, api_key: api_key)
25
+ end
26
+ collection.run
27
+ end
28
+
29
+ it { expect(collection.fetch(:search)).to(be_present) }
30
+ it { is_expected.to(be_success) }
31
+ end
32
+
33
+ context('when check') do
34
+ let(:check) { OkComputer::AlgoliaCheck.new(app_id: app_id, api_key: api_key) }
35
+
36
+ before do
37
+ described_class.register do |r|
38
+ r.add(check, :search)
39
+ end
40
+ collection.run
41
+ end
42
+
43
+ it { expect(collection.fetch(:search)).to(be_present) }
44
+ it { is_expected.to(be_success) }
45
+ end
46
+
47
+ context('when check collection') do
48
+ let(:check) { OkComputer::AlgoliaCheck.new(app_id: app_id, api_key: api_key) }
49
+ let(:check_collection) { OkComputer::CheckCollection.new(:custom) }
50
+
51
+ before do
52
+ check_collection.register(:search, check)
53
+ described_class.register do |r|
54
+ r.add(check_collection, :custom)
55
+ end
56
+ collection.run
57
+ end
58
+
59
+ it { expect(collection.fetch(:custom)).to(be_present) }
60
+ it { expect(collection.fetch(:search)).to(be_present) }
61
+ it { is_expected.to(be_success) }
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe(OkComputer::HubspotCheck) do
6
+ let(:api_key) { 'apikey' }
7
+ let(:response) { { status: 200, body: MultiJson.encode({}) } }
8
+
9
+ subject(:check) { described_class.new(api_key: api_key) }
10
+
11
+ before { stub_request(:get, %r{/integrations/v1/limit/daily}).to_return(response) }
12
+
13
+ context('when successful') do
14
+ it { is_expected.to(be_successful_check) }
15
+ it { is_expected.to(have_message('Rate-Limit check successful')) }
16
+ end
17
+
18
+ context('when 401 fails') do
19
+ let(:response) { { status: 401, body: MultiJson.encode({}) } }
20
+
21
+ it { is_expected.not_to(be_successful_check) }
22
+ it { is_expected.to(have_message("Error: '{}'")) }
23
+ end
24
+
25
+ context('when rate-limit exceeded') do
26
+ let(:response) do
27
+ {
28
+ status: 429,
29
+ body: MultiJson.encode(status: 'error'),
30
+ }
31
+ end
32
+
33
+ it { is_expected.not_to(be_successful_check) }
34
+ end
35
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe(OkComputer::NexmoCheck) do
6
+ let(:api_key) { 'nexmo-api-key' }
7
+ let(:api_secret) { 'nexmo-api-secret' }
8
+ let(:signature_secret) { 'nexmo-signature-secret' }
9
+ let(:client) do
10
+ Nexmo::Client.new(
11
+ api_key: api_key,
12
+ api_secret: api_secret,
13
+ signature_secret: signature_secret
14
+ )
15
+ end
16
+ let(:headers) { { 'Content-Type' => 'application/json;charset=utf-8' } }
17
+ let(:response) { { status: 200, body: MultiJson.encode({}), headers: headers } }
18
+
19
+ subject(:check) { described_class.new(client: client) }
20
+
21
+ before { stub_request(:get, %r{/account/get-balance}).to_return(response) }
22
+
23
+ context('when successful') do
24
+ let(:response) do
25
+ {
26
+ status: 200,
27
+ body: MultiJson.encode(value: 10.28, autoReload: false),
28
+ headers: headers,
29
+ }
30
+ end
31
+
32
+ it { is_expected.to(be_successful_check) }
33
+ it { is_expected.to(have_message('Balance 10.28 check successful')) }
34
+
35
+ context('when not client') do
36
+ subject(:check) do
37
+ described_class.new(
38
+ api_key: api_key,
39
+ api_secret: api_secret,
40
+ signature_secret: signature_secret
41
+ )
42
+ end
43
+
44
+ it { is_expected.to(be_successful_check) }
45
+ end
46
+ end
47
+
48
+ context('when 401 fails') do
49
+ let(:response) { { status: 401, body: MultiJson.encode({}), headers: headers } }
50
+
51
+ it { is_expected.not_to(be_successful_check) }
52
+ it { is_expected.to(have_message("Error: 'Nexmo::AuthenticationError'")) }
53
+ end
54
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe(OkComputer::PusherCheck) do
6
+ let(:client) do
7
+ Pusher::Client.new({
8
+ app_id: '20',
9
+ key: '12345678900000001',
10
+ secret: '12345678900000001',
11
+ host: 'api.pusherapp.com',
12
+ port: 80,
13
+ })
14
+ end
15
+ let(:response) { { status: 200, body: MultiJson.encode({}) } }
16
+
17
+ subject(:check) { described_class.new(client: client) }
18
+
19
+ before { stub_request(:get, %r{/apps/20/channels}).to_return(response) }
20
+
21
+ context('when successful') do
22
+ let(:response) do
23
+ {
24
+ status: 200,
25
+ body: MultiJson.encode(channels: { channel1: {}, channel2: {} }),
26
+ }
27
+ end
28
+
29
+ it { is_expected.to(be_successful_check) }
30
+ it { is_expected.to(have_message('Channels check successful')) }
31
+
32
+ context('when not client') do
33
+ subject(:check) do
34
+ described_class.new(
35
+ app_id: '20',
36
+ app_key: '12345678900000001',
37
+ app_secret: '12345678900000001'
38
+ )
39
+ end
40
+
41
+ it { is_expected.to(be_successful_check) }
42
+ end
43
+ end
44
+
45
+ context('when 401 fails') do
46
+ let(:response) { { status: 401, body: MultiJson.encode({}) } }
47
+
48
+ it { is_expected.not_to(be_successful_check) }
49
+ it { is_expected.to(have_message("Error: '{}'")) }
50
+ end
51
+
52
+ context('when 403 fails') do
53
+ let(:response) { { status: 403, body: MultiJson.encode({}) } }
54
+
55
+ it { is_expected.not_to(be_successful_check) }
56
+ it { is_expected.to(have_message("Error: 'Unknown error (status code 403): {}'")) }
57
+ end
58
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Configure Rails Environment
4
+ ENV['RAILS_ENV'] = 'test'
5
+
6
+ require 'spec_helper'
7
+ require File.expand_path('dummy/config/environment.rb', __dir__)
8
+ require 'rspec/rails'
9
+
10
+ Rails.backtrace_cleaner.remove_silencers!
11
+
12
+ RSpec.configure do |config|
13
+ config.use_transactional_fixtures = true
14
+ config.infer_spec_type_from_file_location!
15
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start('rails') do
5
+ add_filter '/spec/'
6
+ end
7
+ if ENV['CI'] == 'true'
8
+ require 'codecov'
9
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
10
+ end
11
+
12
+ require 'bundler/setup'
13
+ require 'em-http' # As of webmock 1.4.0, em-http must be loaded first
14
+ require 'multi_json'
15
+ require 'webmock/rspec'
16
+
17
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
18
+
19
+ RSpec.configure do |config|
20
+ config.run_all_when_everything_filtered = true
21
+ config.filter_run(:focus)
22
+
23
+ config.expect_with(:rspec) do |expectations|
24
+ expectations.syntax = :expect
25
+ end
26
+
27
+ config.mock_with(:rspec) do |mocks|
28
+ mocks.syntax = :expect
29
+ end
30
+
31
+ config.order = :random
32
+
33
+ config.before(:each) do
34
+ WebMock.reset!
35
+ WebMock.disable_net_connect!
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RSpec::Matchers.define :be_a_multiple_of do |expected|
4
+ # match do |actual|
5
+ # actual % expected == 0
6
+ # end
7
+ # end
8
+ # 9.should be_a_multiple_of(3)
9
+ # expect(9).to be_a_multiple_of(3)
10
+
11
+ RSpec::Matchers.define(:have_message) do |message|
12
+ match do |actual|
13
+ actual.check
14
+ actual.message.include?(message)
15
+ end
16
+
17
+ failure_message do |actual|
18
+ "expected '#{actual.message}' to include '#{message}'"
19
+ end
20
+
21
+ failure_message_when_negated do |actual|
22
+ "expected '#{actual.message}' to not include '#{message}'"
23
+ end
24
+ end
25
+
26
+ RSpec::Matchers.define(:be_successful_check) do |_message|
27
+ match do |actual|
28
+ actual.check
29
+ actual.success?
30
+ end
31
+
32
+ failure_message do |actual|
33
+ "expected #{actual.inspect} to be successful"
34
+ end
35
+
36
+ failure_message_when_negated do |actual|
37
+ "expected '#{actual}' to not be successful"
38
+ end
39
+ end
metadata ADDED
@@ -0,0 +1,306 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: okcomputer-checks
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - First Circle Engineering
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-10-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: okcomputer
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: appraisal
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: codecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: em-http-request
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: nexmo
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pusher
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec-rails
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop-performance
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop-rails
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-shopify
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: sqlite3
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 1.3.6
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 1.3.6
209
+ - !ruby/object:Gem::Dependency
210
+ name: webmock
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ description: "\n Collection health-check for okcomputer\n "
224
+ email: tech@firstcircle.com
225
+ executables: []
226
+ extensions: []
227
+ extra_rdoc_files:
228
+ - LICENSE
229
+ - README.md
230
+ files:
231
+ - ".rubocop.yml"
232
+ - Appraisals
233
+ - Gemfile
234
+ - LICENSE
235
+ - README.md
236
+ - gemfiles/rails_5.1_stable.gemfile
237
+ - gemfiles/rails_5.2_stable.gemfile
238
+ - gemfiles/rails_6.0_stable.gemfile
239
+ - gemfiles/rails_edge.gemfile
240
+ - lib/ok_computer/checks.rb
241
+ - lib/ok_computer/checks/algolia_check.rb
242
+ - lib/ok_computer/checks/hubspot_check.rb
243
+ - lib/ok_computer/checks/nexmo_check.rb
244
+ - lib/ok_computer/checks/pusher_check.rb
245
+ - lib/ok_computer/checks/registry.rb
246
+ - lib/ok_computer/checks/version.rb
247
+ - lib/okcomputer-checks.rb
248
+ - okcomputer-checks.gemspec
249
+ - spec/dummy/config.ru
250
+ - spec/dummy/config/application.rb
251
+ - spec/dummy/config/boot.rb
252
+ - spec/dummy/config/database.yml
253
+ - spec/dummy/config/environment.rb
254
+ - spec/dummy/config/initializers/okcomputer.rb
255
+ - spec/dummy/config/routes.rb
256
+ - spec/dummy/log/.keep
257
+ - spec/ok_computer/algolia_check_spec.rb
258
+ - spec/ok_computer/checks_spec.rb
259
+ - spec/ok_computer/hubspot_check_spec.rb
260
+ - spec/ok_computer/nexmo_check_spec.rb
261
+ - spec/ok_computer/pusher_check_spec.rb
262
+ - spec/rails_helper.rb
263
+ - spec/spec_helper.rb
264
+ - spec/support/check_matcher.rb
265
+ homepage: https://github.com/carabao-capital/okcomputer-checks
266
+ licenses:
267
+ - MIT
268
+ metadata:
269
+ source_code_uri: https://github.com/carabao-capital/okcomputer-checks/tree/v1.0.0
270
+ allowed_push_host: https://rubygems.org
271
+ post_install_message:
272
+ rdoc_options: []
273
+ require_paths:
274
+ - lib
275
+ required_ruby_version: !ruby/object:Gem::Requirement
276
+ requirements:
277
+ - - ">="
278
+ - !ruby/object:Gem::Version
279
+ version: 2.6.5
280
+ required_rubygems_version: !ruby/object:Gem::Requirement
281
+ requirements:
282
+ - - ">="
283
+ - !ruby/object:Gem::Version
284
+ version: '0'
285
+ requirements: []
286
+ rubygems_version: 3.0.6
287
+ signing_key:
288
+ specification_version: 4
289
+ summary: Collection health-check for okcomputer
290
+ test_files:
291
+ - spec/dummy/config.ru
292
+ - spec/dummy/config/application.rb
293
+ - spec/dummy/config/boot.rb
294
+ - spec/dummy/config/database.yml
295
+ - spec/dummy/config/environment.rb
296
+ - spec/dummy/config/initializers/okcomputer.rb
297
+ - spec/dummy/config/routes.rb
298
+ - spec/dummy/log/.keep
299
+ - spec/ok_computer/algolia_check_spec.rb
300
+ - spec/ok_computer/checks_spec.rb
301
+ - spec/ok_computer/hubspot_check_spec.rb
302
+ - spec/ok_computer/nexmo_check_spec.rb
303
+ - spec/ok_computer/pusher_check_spec.rb
304
+ - spec/rails_helper.rb
305
+ - spec/spec_helper.rb
306
+ - spec/support/check_matcher.rb