hephaestus 0.1.3 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 = "/"
|