hephaestus 0.1.3 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +27 -1
- data/bin/hephaestus +9 -3
- data/lib/hephaestus/app_builder.rb +26 -5
- data/lib/hephaestus/exit_on_failure.rb +4 -4
- data/lib/hephaestus/generators/app_generator.rb +148 -56
- data/lib/hephaestus/generators/config_generator.rb +30 -2
- data/lib/hephaestus/generators/core_generator.rb +30 -1
- data/lib/hephaestus/generators/deployment_generator.rb +9 -3
- data/lib/hephaestus/generators/lib_generator.rb +1 -0
- data/lib/hephaestus/generators/sorbet_generator.rb +1 -1
- data/lib/hephaestus/version.rb +1 -1
- data/lib/hephaestus.rb +8 -0
- data/templates/.dockerignore +39 -0
- data/templates/.env.sample +6 -0
- data/templates/.github/dependabot.yml +12 -7
- data/templates/.github/workflows/automerge.yml +5 -85
- data/templates/.github/workflows/deploy.yml +30 -0
- data/templates/.github/workflows/licenses.yml +11 -31
- data/templates/.github/workflows/lint.yml +14 -34
- data/templates/.github/workflows/security.yml +9 -32
- data/templates/.github/workflows/sorbet.yml +7 -37
- data/templates/.github/workflows/test.yml +7 -41
- data/templates/.licensed.yml +7 -3
- data/templates/.ruby-version +1 -0
- data/templates/Dockerfile +79 -0
- data/templates/Gemfile.erb +23 -26
- data/templates/Procfile.debug +1 -1
- data/templates/app/controllers/app_controller.rb +71 -0
- data/templates/app/controllers/application_controller.rb +14 -1
- data/templates/app/controllers/concerns/authable.rb +20 -2
- data/templates/app/controllers/settings_controller.rb +32 -2
- data/templates/app/jobs/update_yetto_job.rb +6 -7
- data/templates/app/lib/body_parameter/yetto_parameters.rb +32 -0
- data/templates/app/lib/path_parameter/settings_parameters.rb +22 -0
- data/templates/app/lib/plug_app/middleware/openapi_validation.rb +5 -5
- data/templates/app/lib/plug_app/middleware/tracing_attributes.rb +1 -1
- data/templates/app/services/http_service.rb +27 -0
- data/templates/app/services/yetto_service.rb +24 -32
- data/templates/app/views/settings/new.json.jbuilder +21 -0
- data/templates/bin/docker-entrypoint +14 -0
- data/templates/compose.yml +7 -0
- data/templates/config/initializers/environment.rb +5 -8
- data/templates/config/initializers/filter_parameter_logging.rb +3 -0
- data/templates/config/initializers/opentelemetry.rb +32 -0
- data/templates/config/locales/en.yml +32 -0
- data/templates/config/locales/settings/en.yml +5 -0
- data/templates/lib/plug_app/schemas/api/2023-03-06/components/schemas/yetto.json +2 -2
- data/templates/lib/plug_app/schemas/api/2023-03-06/openapi.json +4 -4
- data/templates/lib/plug_app/schemas/api/2023-03-06/paths/plug.json +1 -1
- data/templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/after_create_message.json +2 -2
- data/templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/after_create_plug_installation.json +2 -2
- data/templates/lib/tasks/test_tasks.rake +6 -2
- data/templates/script/edit-credentials +29 -0
- data/templates/script/hmac_text +1 -1
- data/templates/script/licenses +4 -48
- data/templates/script/server +62 -2
- data/templates/script/sorbet +7 -0
- data/templates/test/controllers/application_controller_test.rb +32 -0
- data/templates/test/controllers/settings_controller_test.rb +1 -1
- data/templates/test/controllers/yetto_controller_test.rb +1 -1
- data/templates/test/fixtures/files/fake_pem_file/fake.pem +27 -0
- data/templates/test/jobs/update_yetto_job_test.rb +3 -18
- data/templates/test/support/api.rb +1 -1
- data/templates/test/support/rails.rb +1 -1
- data/templates/test/support/webmocks/slack_webmock.rb +2 -2
- data/templates/test/support/webmocks/yetto_webmock.rb +119 -0
- data/templates/test/test_helper.rb +16 -3
- data/templates/vendor/fly/fly-production.toml +38 -0
- data/templates/vendor/fly/fly-staging.toml +33 -0
- metadata +39 -16
- data/templates/.env.test +0 -4
- data/templates/.github/actions/license/action.yml +0 -11
- data/templates/.github/actions/setup/action.yml +0 -10
- data/templates/.github/actions/sisyphus/action.yml +0 -11
- data/templates/.github/actions/sorbet/action.yml +0 -19
- data/templates/app/views/settings/index.json.jbuilder +0 -15
- data/templates/config/initializers/open_telemetry.rb +0 -27
- data/templates/script/security_checks/brakeman +0 -5
- data/templates/script/security_checks/bundle-audit +0 -5
- data/templates/script/server-debug +0 -5
- data/templates/script/typecheck +0 -44
- data/templates/test/fixtures/files/.keep +0 -0
- data/templates/test/support/webmocks/yetto.rb +0 -94
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"
|
2
|
+
"CreateAppMessage": {
|
3
3
|
"type": "object",
|
4
4
|
"required": [
|
5
5
|
"plug_installation",
|
@@ -98,7 +98,7 @@
|
|
98
98
|
},
|
99
99
|
"additionalProperties": false
|
100
100
|
},
|
101
|
-
"
|
101
|
+
"CreateApp": {
|
102
102
|
"type": "object",
|
103
103
|
"required": [
|
104
104
|
"plug_installation",
|
@@ -1,8 +1,8 @@
|
|
1
1
|
{
|
2
2
|
"openapi": "3.0.0",
|
3
3
|
"info": {
|
4
|
-
"title": "
|
5
|
-
"description": "An OpenAPI definition for the
|
4
|
+
"title": "App Plug API",
|
5
|
+
"description": "An OpenAPI definition for the App Plug REST API.",
|
6
6
|
"version": "2023-03-06",
|
7
7
|
"termsOfService": "https://yetto.app/terms/",
|
8
8
|
"license": {
|
@@ -23,8 +23,8 @@
|
|
23
23
|
"/api/2023-03-06/after_create/message": {
|
24
24
|
"$ref": "paths/yetto/after_create_message.json"
|
25
25
|
},
|
26
|
-
"
|
27
|
-
"$ref": "paths
|
26
|
+
"/app/2023-03-06/{plugInstallationId}": {
|
27
|
+
"$ref": "paths/app.json"
|
28
28
|
}
|
29
29
|
}
|
30
30
|
}
|
@@ -4,13 +4,13 @@
|
|
4
4
|
"Yetto"
|
5
5
|
],
|
6
6
|
"description": "After a message is created in Yetto, this delivers it.",
|
7
|
-
"operationId": "Create a new
|
7
|
+
"operationId": "Create a new App",
|
8
8
|
"requestBody": {
|
9
9
|
"required": true,
|
10
10
|
"content": {
|
11
11
|
"application/json": {
|
12
12
|
"schema": {
|
13
|
-
"$ref": "../../components/schemas/yetto.json#/
|
13
|
+
"$ref": "../../components/schemas/yetto.json#/CreateAppMessage"
|
14
14
|
}
|
15
15
|
}
|
16
16
|
}
|
data/templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/after_create_plug_installation.json
CHANGED
@@ -4,13 +4,13 @@
|
|
4
4
|
"Yetto"
|
5
5
|
],
|
6
6
|
"description": "After a plug installation is created, this executes",
|
7
|
-
"operationId": "Post a
|
7
|
+
"operationId": "Post a plug installation",
|
8
8
|
"requestBody": {
|
9
9
|
"required": true,
|
10
10
|
"content": {
|
11
11
|
"application/json": {
|
12
12
|
"schema": {
|
13
|
-
"$ref": "../../components/schemas/yetto.json#/
|
13
|
+
"$ref": "../../components/schemas/yetto.json#/CreateAppSwitch"
|
14
14
|
}
|
15
15
|
}
|
16
16
|
}
|
@@ -4,7 +4,11 @@
|
|
4
4
|
require "rake/testtask"
|
5
5
|
|
6
6
|
if Rails.env.development? || Rails.env.test?
|
7
|
-
|
7
|
+
begin
|
8
|
+
require "rubocop/rake_task"
|
8
9
|
|
9
|
-
|
10
|
+
RuboCop::RakeTask.new(:rubocop)
|
11
|
+
rescue LoadError => e
|
12
|
+
warn("WARNING: rubocop is not available in this environment: #{e}")
|
13
|
+
end
|
10
14
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
# Initialize flags
|
6
|
+
staging=false
|
7
|
+
production=false
|
8
|
+
|
9
|
+
# Check for and parse flags
|
10
|
+
for arg in "$@"
|
11
|
+
do
|
12
|
+
case $arg in
|
13
|
+
--staging)
|
14
|
+
staging=true
|
15
|
+
;;
|
16
|
+
--production)
|
17
|
+
production=true
|
18
|
+
;;
|
19
|
+
*)
|
20
|
+
# Unknown arguments can be ignored or handled here
|
21
|
+
;;
|
22
|
+
esac
|
23
|
+
done
|
24
|
+
|
25
|
+
if [[ $staging == true ]]; then
|
26
|
+
RAILS_MASTER_KEY=$(op read op://Plug-App/staging-rails-master-key/...) bin/rails credentials:edit -e staging
|
27
|
+
else
|
28
|
+
RAILS_MASTER_KEY=$(op read op://Plug-App/production-rails-master-key/...) bin/rails credentials:edit -e production
|
29
|
+
fi
|
data/templates/script/hmac_text
CHANGED
data/templates/script/licenses
CHANGED
@@ -1,51 +1,7 @@
|
|
1
|
-
#!/bin/bash
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
# This script is "symlink"ed from our actions repo.
|
3
|
+
# Not really, obviously, it's a real file.
|
2
4
|
|
3
5
|
set -e
|
4
6
|
|
5
|
-
|
6
|
-
echo "Usage:"
|
7
|
-
echo "$0 [options]"
|
8
|
-
echo ""
|
9
|
-
echo " Options:"
|
10
|
-
echo " -u/--update Update license information"
|
11
|
-
echo " -v/--verify Verify license information"
|
12
|
-
echo " -g/--generate Generate CSV license data"
|
13
|
-
echo " -h/--help Display this help message"
|
14
|
-
echo ""
|
15
|
-
exit 1
|
16
|
-
}
|
17
|
-
|
18
|
-
while [ "$1" != "" ]; do
|
19
|
-
case $1 in
|
20
|
-
-v | --verify)
|
21
|
-
echo "Verifying dependency licenses ..."
|
22
|
-
bin/bundle exec licensed env -c .licensed.yml
|
23
|
-
bin/bundle exec licensed list -c .licensed.yml
|
24
|
-
bin/bundle exec licensed status -c .licensed.yml
|
25
|
-
RET=$?
|
26
|
-
if [ $RET -ne 0 ]; then
|
27
|
-
echo
|
28
|
-
echo "*** When fixed, please run 'script/licenses -c' to update the license cache. ***"
|
29
|
-
echo
|
30
|
-
fi
|
31
|
-
|
32
|
-
exit $RET
|
33
|
-
;;
|
34
|
-
-u | --update)
|
35
|
-
echo "Caching dependency licenses ..."
|
36
|
-
bin/bundle exec licensed cache -c .licensed.yml
|
37
|
-
;;
|
38
|
-
-g | --generate)
|
39
|
-
echo "Generating CSV licenses ..."
|
40
|
-
bin/bundle exec rake licenses:generate
|
41
|
-
;;
|
42
|
-
-h | --help)
|
43
|
-
usage
|
44
|
-
;;
|
45
|
-
*)
|
46
|
-
usage
|
47
|
-
exit 1
|
48
|
-
;;
|
49
|
-
esac
|
50
|
-
shift
|
51
|
-
done
|
7
|
+
../actions/script/licenses "$@"
|
data/templates/script/server
CHANGED
@@ -1,5 +1,65 @@
|
|
1
|
-
#!/bin/
|
1
|
+
#!/usr/bin/env bash
|
2
2
|
|
3
3
|
set -e
|
4
4
|
|
5
|
-
|
5
|
+
# Initialize flags
|
6
|
+
local_dev=true
|
7
|
+
api_only=false
|
8
|
+
debug=false
|
9
|
+
|
10
|
+
function opr_cmd() {
|
11
|
+
if $local_dev; then
|
12
|
+
bin/opr $1
|
13
|
+
else
|
14
|
+
$1
|
15
|
+
fi
|
16
|
+
}
|
17
|
+
|
18
|
+
function cleanup() {
|
19
|
+
echo "Cleaning up attached services..."
|
20
|
+
docker compose down
|
21
|
+
echo "...Done"
|
22
|
+
}
|
23
|
+
|
24
|
+
# Check for and parse flags
|
25
|
+
for arg in "$@"
|
26
|
+
do
|
27
|
+
case $arg in
|
28
|
+
--api-only)
|
29
|
+
api_only=true
|
30
|
+
;;
|
31
|
+
--docker)
|
32
|
+
local_dev=false
|
33
|
+
;;
|
34
|
+
--debug)
|
35
|
+
export DEBUG=true
|
36
|
+
debug=true
|
37
|
+
;;
|
38
|
+
*)
|
39
|
+
# Unknown arguments can be ignored or handled here
|
40
|
+
;;
|
41
|
+
esac
|
42
|
+
done
|
43
|
+
|
44
|
+
# In non-local dev scenarios, change ownership of the application to the non-root 'plug-app' user
|
45
|
+
if [[ $local_dev == false ]]; then
|
46
|
+
chown -R plug-app:plug-app /usr/src/app
|
47
|
+
else
|
48
|
+
# In local dev scenarios, run attached compose services in detached mode
|
49
|
+
docker compose up --wait
|
50
|
+
fi
|
51
|
+
|
52
|
+
if $local_dev; then
|
53
|
+
|
54
|
+
# Ensure docker-compose goes down when the server is stopped
|
55
|
+
trap cleanup SIGINT
|
56
|
+
trap cleanup SIGTSTP
|
57
|
+
|
58
|
+
if $debug; then
|
59
|
+
bin/foreman start -f Procfile.debug
|
60
|
+
else
|
61
|
+
bin/foreman start -f Procfile.dev
|
62
|
+
fi
|
63
|
+
else
|
64
|
+
bin/puma -C config/puma.rb
|
65
|
+
fi
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "test_helper"
|
5
|
+
|
6
|
+
class ApplicationControllerTest < ActionDispatch::IntegrationTest
|
7
|
+
test "renders a 404" do
|
8
|
+
get "/asdasdasdasd"
|
9
|
+
|
10
|
+
assert_response :not_found
|
11
|
+
assert_match(/Not Found/, response.body)
|
12
|
+
end
|
13
|
+
|
14
|
+
test "bogus js does not 500" do
|
15
|
+
get "/js/admin.js"
|
16
|
+
|
17
|
+
assert_response :not_found
|
18
|
+
assert_match(/Not Found/, response.body)
|
19
|
+
end
|
20
|
+
|
21
|
+
test "bogus routes do not 500" do
|
22
|
+
post "/"
|
23
|
+
|
24
|
+
assert_response :not_found
|
25
|
+
assert_match(/Not Found/, response.body)
|
26
|
+
|
27
|
+
put "/asdads"
|
28
|
+
|
29
|
+
assert_response :not_found
|
30
|
+
assert_match(/Not Found/, response.body)
|
31
|
+
end
|
32
|
+
end
|
@@ -6,7 +6,7 @@ require "test_helper"
|
|
6
6
|
class SettingsControllerTest < ActionDispatch::IntegrationTest
|
7
7
|
include API::TestHelpers
|
8
8
|
|
9
|
-
include Webmocks::
|
9
|
+
include Webmocks::YettoWebmock
|
10
10
|
|
11
11
|
test "GET /settings without asking for JSON fails" do
|
12
12
|
api(:get, "/settings", headers: nil)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpAIBAAKCAQEAljw3p40+fSF5QkoVWnof6J3UVH8NRu80CZWLK+FXH/yEzfZj
|
3
|
+
5ZQdbLRZzbhd24PIqbyCKJe0JS82ya9AbElT7VkfTGrj/smqepgv1FuhxWsTYGSy
|
4
|
+
kIBST06mZGnzaOLzP0H2CEHZwQtIX3W9vgqBrUYu5RCz3zUI7z7MwE2J8lZ6I9hy
|
5
|
+
pUzPFK3FIAar8sgA0FNTK2I3P5MWUGwGW+8BiudpNz3dMMHJVQ7dRuNj/PazCv4p
|
6
|
+
DIF0ZSwzaqTP+XBaaLRAwOD24dZWbiJNLKR6l2CU/xpIABHqk6WoO7FZcfn2sI8c
|
7
|
+
Bey7YoJOvGe8+AB7MYPJ2IXOdgFihr4WVX74ZQIDAQABAoIBAQCEomc0KnOnv1yx
|
8
|
+
lHwjo7v1/xlM+9o57MbRS1BSDiCAIc0RlNx++/O6W8MI5yMdwMvwZne25K/rQDKr
|
9
|
+
fmhu8ZIB8nO6YIgnEd3LW/6mCbvZcf3qVRx8jH2efL5T2mJGEE9WYqKWiaR4VMCx
|
10
|
+
Xl6En/v6gQK3wrY6cjUQGy5i/FG0OyBIQZDucIc4b4TdLBUzo85xbXvodX9hWCvm
|
11
|
+
qGoZlrmKWxn/Ro+Hi0NJbKPR0DUAfQVBzg9QqJTVvQtdVeAnisgYVUUDKevFV7sm
|
12
|
+
jyryJ2vKzvPNOHYsBMD/bRlj1loHlpqIddEsBoxSeq8aNJ5nEz31qG7AHBLu+TK+
|
13
|
+
ZGILRnDhAoGBAMdiMSz1jrur55dDHoclciPFbKop6j/HmpU85LuMsi1nXejog9Bs
|
14
|
+
uir75boKgd3P51rbEruOPVZqf6bkPhO3da1YI2x8j0B+V/kDXbPLYPxfVmfOo/ct
|
15
|
+
cxBqXloe0036ZO96y/IJlRPvSY2H/mXiNCnGzej6ROgH4t+vR0iEl2/NAoGBAMDl
|
16
|
+
R9IRjdB4bemZEMAoeORpsD7esb0dLA7W7/ObJxBRFuUcQOJq/JNb7SYFdXrLAeUd
|
17
|
+
QWevXsS2ZjqmxlEWwGtqy0D548Rh4F3SpWiDh7hG3hePtC/XC57t00/cWYe2kTWQ
|
18
|
+
0662y00qwsWCo4Uy++iIiNx44ilWhcE5phCowiL5AoGAUQKwgFf1eoNKQcdfrAGm
|
19
|
+
8qnQkQMeznNHd8OaHCn6a0BIg82VYSYMLlLS8Fg8k+dZVS0V22bbvTTgUOsD3fb4
|
20
|
+
tUnOetHRUp8DF4YqmFbWPTRvYxYuwMuSqOTPGUbVDCXkxPjbzKfgDo13ES5kSvkx
|
21
|
+
wJeqKjMltDEgGUqaZ/iXnzECgYArMKs+G/QW44Aot78KZ4V6DzgJO6+sWmXNBM9B
|
22
|
+
SlIa0y0/K25TxAS9se2Nf9doISBRfpVwc9HSVczaARGSgnefFZBhAhK/m/Kyz0F9
|
23
|
+
/0VaO3Pq7qA3vfy6HyIbVYkuW/Bzf/QFwKQQqSxnMPMQFfRVgoyyYNayzs6wDwph
|
24
|
+
3IdrcQKBgQC+VpUU/04AD9qFk+6GwXer69i3NQJ+LtYEsJ8yeKzS5MUOt3s+C2T6
|
25
|
+
uKLdq/j5XwzIIulcBQEJOoa1A3KcaIpkiWgvAbAKrirH9IobHvVLk9RxQ4EMihhU
|
26
|
+
/GBStICbD54zeJmrEJx+yxa4HYx/aKViPpt6xg3WJdBJplTmCq181g==
|
27
|
+
-----END RSA PRIVATE KEY-----
|
@@ -4,30 +4,15 @@
|
|
4
4
|
require "test_helper"
|
5
5
|
|
6
6
|
class UpdateYettoJobTest < ActiveJob::TestCase
|
7
|
-
include Webmocks::
|
7
|
+
include Webmocks::YettoWebmock
|
8
8
|
|
9
9
|
def setup
|
10
10
|
super
|
11
11
|
|
12
12
|
@update_installation_body = {
|
13
|
-
|
14
|
-
|
15
|
-
settings: {},
|
16
|
-
},
|
13
|
+
credentials: {},
|
14
|
+
settings: {},
|
17
15
|
}
|
18
|
-
|
19
|
-
@installation_params = {
|
20
|
-
type: "installation",
|
21
|
-
inbox: {
|
22
|
-
id: @inbox_id,
|
23
|
-
},
|
24
|
-
organization: {
|
25
|
-
id: @organization_id,
|
26
|
-
},
|
27
|
-
}
|
28
|
-
|
29
|
-
@installation_params[:plug_installation] = @update_installation_body[:plug_installation].dup
|
30
|
-
@installation_params[:plug_installation][:id] = @plug_installation_id
|
31
16
|
end
|
32
17
|
|
33
18
|
test "does nothing if type is not supported" do
|
@@ -32,7 +32,7 @@ module ActiveSupport
|
|
32
32
|
|
33
33
|
expected_value = expected_args[actual_key]
|
34
34
|
|
35
|
-
assert_equal(expected_value, actual_value)
|
35
|
+
assert_equal(expected_value, actual_value, "Expected `#{actual_key}` to be `#{expected_value.nil? ? "nil" : expected_value}`, but was `#{actual_value.nil? ? "nil" : actual_value}`")
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -8,12 +8,12 @@ module Webmocks
|
|
8
8
|
|
9
9
|
sig { returns(T.untyped) }
|
10
10
|
def assert_requested_send_to_slack_log
|
11
|
-
assert_requested(:post, "https://slack.com
|
11
|
+
assert_requested(:post, "https://slack.com/the_log_room")
|
12
12
|
end
|
13
13
|
|
14
14
|
sig { returns(T.untyped) }
|
15
15
|
def stub_send_to_slack_log
|
16
|
-
stub_request(:post, "https://slack.com
|
16
|
+
stub_request(:post, "https://slack.com/the_log_room")
|
17
17
|
.to_return(
|
18
18
|
status: 200,
|
19
19
|
headers: { content_type: "application/json; charset=utf-8" },
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Webmocks
|
5
|
+
module YettoWebmock
|
6
|
+
def yetto_auth_header(payload, signing_secret = "super-secret")
|
7
|
+
"sha256=#{OpenSSL::HMAC.hexdigest(Authable::SHA256_DIGEST, signing_secret, payload.to_json)}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def assert_requested_post_access_token(plug_installation_id)
|
11
|
+
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/plugs/installations/#{plug_installation_id}/access_tokens")
|
12
|
+
end
|
13
|
+
|
14
|
+
def stub_post_access_token(plug_installation_id)
|
15
|
+
response = {
|
16
|
+
token: Faker::Alphanumeric.alphanumeric(number: 26).upcase,
|
17
|
+
}
|
18
|
+
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/plugs/installations/#{plug_installation_id}/access_tokens")
|
19
|
+
.to_return(
|
20
|
+
body: response.to_json,
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def assert_requested_get_plug_installation(plug_installation_id)
|
25
|
+
assert_requested_post_access_token(plug_installation_id)
|
26
|
+
assert_requested(:get, "#{::YettoService::YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def stub_get_plug_installation(plug_installation_id, response = nil, status: 200)
|
30
|
+
stub_post_access_token(plug_installation_id)
|
31
|
+
|
32
|
+
response ||= {
|
33
|
+
installed_on_inbox: {
|
34
|
+
id: inbox_id,
|
35
|
+
organization: {
|
36
|
+
id: organization_id,
|
37
|
+
status: "active",
|
38
|
+
},
|
39
|
+
},
|
40
|
+
plug: {
|
41
|
+
id: "plg_#{Faker::Alphanumeric.alphanumeric(number: 26).upcase}",
|
42
|
+
},
|
43
|
+
settings: {
|
44
|
+
from_email: "new@from.company",
|
45
|
+
},
|
46
|
+
}
|
47
|
+
|
48
|
+
stub_request(:get, "#{::YettoService::YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}")
|
49
|
+
.to_return(
|
50
|
+
status: status,
|
51
|
+
headers: { content_type: "application/json; charset=utf-8" },
|
52
|
+
body: response.to_json,
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def assert_requested_update_installation(plug_installation_id)
|
57
|
+
assert_requested_post_access_token(plug_installation_id)
|
58
|
+
|
59
|
+
assert_requested(:patch, "#{::YettoService::YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}")
|
60
|
+
end
|
61
|
+
|
62
|
+
def stub_update_installation(plug_installation_id, params, response: {}, status: 200)
|
63
|
+
stub_post_access_token(plug_installation_id)
|
64
|
+
|
65
|
+
stub_request(:patch, "#{::YettoService::YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}")
|
66
|
+
.with(
|
67
|
+
body: params,
|
68
|
+
)
|
69
|
+
.to_return(
|
70
|
+
status: status,
|
71
|
+
headers: { content_type: "application/json; charset=utf-8" },
|
72
|
+
body: response.to_json,
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
def assert_requested_create_message(inbox_id)
|
77
|
+
assert_requested_post_access_token(plug_installation_id)
|
78
|
+
|
79
|
+
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/inboxes/#{inbox_id}/messages")
|
80
|
+
end
|
81
|
+
|
82
|
+
def stub_create_message(inbox_id, payload)
|
83
|
+
stub_post_access_token(plug_installation_id)
|
84
|
+
|
85
|
+
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/inboxes/#{inbox_id}/messages")
|
86
|
+
.with(
|
87
|
+
body: payload,
|
88
|
+
)
|
89
|
+
.to_return(
|
90
|
+
status: 200,
|
91
|
+
headers: { content_type: "application/json; charset=utf-8" },
|
92
|
+
body: {}.to_json,
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def assert_requested_create_inbox_switch(inbox_id, plug_installation_id)
|
97
|
+
assert_requested_post_access_token(plug_installation_id)
|
98
|
+
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/inboxes/#{inbox_id}/switches")
|
99
|
+
end
|
100
|
+
|
101
|
+
def stub_create_inbox_switch(inbox_id, plug_installation_id, params)
|
102
|
+
stub_post_access_token(plug_installation_id)
|
103
|
+
|
104
|
+
payload = {
|
105
|
+
name: "After install",
|
106
|
+
}
|
107
|
+
|
108
|
+
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/inboxes/#{inbox_id}/switches")
|
109
|
+
.with(
|
110
|
+
body: payload,
|
111
|
+
)
|
112
|
+
.to_return(
|
113
|
+
status: 200,
|
114
|
+
headers: { content_type: "application/json; charset=utf-8" },
|
115
|
+
body: {}.to_json,
|
116
|
+
)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -3,15 +3,28 @@
|
|
3
3
|
|
4
4
|
require "debug" if ENV.fetch("DEBUG", false)
|
5
5
|
|
6
|
+
if ENV["COVERAGE"] == "1"
|
7
|
+
require "simplecov"
|
8
|
+
require "simplecov-console"
|
9
|
+
|
10
|
+
SimpleCov.start("rails")
|
11
|
+
|
12
|
+
# do not crash on failure; we want a distinct job to report the coverage error
|
13
|
+
module SimpleCov
|
14
|
+
class << self
|
15
|
+
def result_exit_status(_)
|
16
|
+
SimpleCov::ExitCodes::SUCCESS
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
6
22
|
require "httpx"
|
7
23
|
require "webmock/minitest"
|
8
24
|
require "httpx/adapters/webmock"
|
9
25
|
WebMock.enable!
|
10
26
|
WebMock.disable_net_connect!(allow_localhost: true)
|
11
27
|
|
12
|
-
require "dotenv"
|
13
|
-
Dotenv.load(".env.test")
|
14
|
-
|
15
28
|
require_relative "./support/rails"
|
16
29
|
|
17
30
|
require "minitest/pride"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# fly.toml app configuration file generated for plug-app on 2023-05-05T07:11:14-04:00
|
2
|
+
#
|
3
|
+
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
4
|
+
#
|
5
|
+
|
6
|
+
app = "plug-app-production"
|
7
|
+
primary_region = "iad"
|
8
|
+
|
9
|
+
[env]
|
10
|
+
RAILS_ENV = "production"
|
11
|
+
LD_PRELOAD_PATH = "/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
|
12
|
+
|
13
|
+
[processes]
|
14
|
+
web = "./bin/rails server"
|
15
|
+
worker = "bundle exec sidekiq"
|
16
|
+
|
17
|
+
[http_service]
|
18
|
+
internal_port = 3000
|
19
|
+
force_https = true
|
20
|
+
auto_stop_machines = true
|
21
|
+
auto_start_machines = true
|
22
|
+
min_machines_running = 1
|
23
|
+
processes = ["web"]
|
24
|
+
[http_service.concurrency]
|
25
|
+
type = "requests"
|
26
|
+
soft_limit = 200
|
27
|
+
hard_limit = 250
|
28
|
+
|
29
|
+
[checks]
|
30
|
+
[checks.alive]
|
31
|
+
type = "tcp"
|
32
|
+
interval = "15s"
|
33
|
+
timeout = "2s"
|
34
|
+
grace_period = "5s"
|
35
|
+
|
36
|
+
[[statics]]
|
37
|
+
guest_path = "/plug-app/public"
|
38
|
+
url_prefix = "/"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
app = "plug-app-staging"
|
2
|
+
primary_region = "iad"
|
3
|
+
|
4
|
+
[env]
|
5
|
+
RAILS_ENV = "plug-app-staging"
|
6
|
+
LD_PRELOAD_PATH = "/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
|
7
|
+
|
8
|
+
[processes]
|
9
|
+
web = "./bin/rails server"
|
10
|
+
worker = "bundle exec sidekiq"
|
11
|
+
|
12
|
+
[http_service]
|
13
|
+
internal_port = 3000
|
14
|
+
force_https = true
|
15
|
+
auto_stop_machines = true
|
16
|
+
auto_start_machines = true
|
17
|
+
min_machines_running = 0
|
18
|
+
processes = ["web"]
|
19
|
+
[http_service.concurrency]
|
20
|
+
type = "requests"
|
21
|
+
soft_limit = 200
|
22
|
+
hard_limit = 250
|
23
|
+
|
24
|
+
[checks]
|
25
|
+
[checks.alive]
|
26
|
+
type = "tcp"
|
27
|
+
interval = "15s"
|
28
|
+
timeout = "2s"
|
29
|
+
grace_period = "5s"
|
30
|
+
|
31
|
+
[[statics]]
|
32
|
+
guest_path = "/plug-app/public"
|
33
|
+
url_prefix = "/"
|