activestorage-memory 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -2
- data/app/controllers/activestorage/memory/memory_controller.rb +60 -0
- data/config/routes.rb +6 -0
- data/lib/active_storage/service/memory_service.rb +78 -5
- data/lib/activestorage/memory/engine.rb +7 -0
- data/lib/{active_storage → activestorage}/memory/version.rb +2 -2
- data/lib/{active_storage → activestorage}/memory.rb +2 -1
- data/spec/active_storage/service/memory_service_spec.rb +99 -0
- data/spec/activestorage/memory_spec.rb +7 -0
- data/spec/controllers/activestorage/memory/memory_controller_spec.rb +136 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config/application.rb +44 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +76 -0
- data/spec/dummy/config/environments/production.rb +97 -0
- data/spec/dummy/config/environments/test.rb +66 -0
- data/spec/dummy/config/initializers/assets.rb +12 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +8 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/permissions_policy.rb +13 -0
- data/spec/dummy/config/locales/en.yml +31 -0
- data/spec/dummy/config/puma.rb +35 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/storage.yml +37 -0
- data/spec/dummy/config.ru +6 -0
- data/spec/dummy/db/migrate/20240413101449_create_active_storage_tables.active_storage.rb +57 -0
- data/spec/dummy/db/schema.rb +44 -0
- data/spec/dummy/log/development.log +53 -0
- data/spec/dummy/log/test.log +4820 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/storage/development.sqlite3 +0 -0
- data/spec/dummy/storage/test.sqlite3 +0 -0
- data/spec/dummy/tmp/local_secret.txt +1 -0
- data/spec/dummy/tmp/restart.txt +0 -0
- data/spec/rails_helper.rb +65 -0
- data/spec/spec_helper.rb +15 -0
- metadata +118 -18
- data/.github/workflows/main.yml +0 -18
- data/.gitignore +0 -11
- data/.rspec +0 -3
- data/Gemfile +0 -10
- data/Gemfile.lock +0 -204
- data/LICENSE.txt +0 -21
- data/activestorage-memory.gemspec +0 -36
- data/bin/console +0 -15
- data/bin/setup +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b5979d939220916998f7502ffce56be3fbf14328601cdcfae7d3aeaaa181ce2
|
4
|
+
data.tar.gz: 615c9f1c2472e74058a353f1c17c79a80eee114a6fb97a770973f68dd0c1fde9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0161b44194c712db207d028801bb57174ed2ba05322ae056b6989a690e870df5d4769316313bae0f0c1df4e9bb9ccf0d434f6e0cffdc6f02147f41b95534bc5b
|
7
|
+
data.tar.gz: 2698dd5ca0974dcdc6443dbcde2065822e2b32f91a13da1d22c6f7b07f5f423b2d0c9e0ee50b70401cd38e904500c58de7206a4cac41582a9504af4f0a77eb0e
|
data/README.md
CHANGED
@@ -34,11 +34,20 @@ To use the Memory service in test, you add the following to config/environments/
|
|
34
34
|
config.active_storage.service = :memory
|
35
35
|
```
|
36
36
|
|
37
|
-
In Active Storage's analyzer feature, asynchronous jobs are executed. So
|
37
|
+
In Active Storage's analyzer feature, asynchronous jobs are executed. So you should set the queue adapter to inline at config/environments/test.
|
38
38
|
```
|
39
|
-
config.active_job.queue_adapter = :
|
39
|
+
config.active_job.queue_adapter = :inline
|
40
40
|
```
|
41
41
|
|
42
|
+
If you are conducting file downloads and uploads during system testing or integration testing, please add the following to the routing.
|
43
|
+
|
44
|
+
``` config/routes.rb
|
45
|
+
|
46
|
+
mount ActiveStorage::Memory::Engine => "/" if Rails.env.test?
|
47
|
+
|
48
|
+
```
|
49
|
+
|
50
|
+
|
42
51
|
You can read more about Active Storage in the Active Storage Overview guide.
|
43
52
|
|
44
53
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Activestorage::Memory
|
4
|
+
class MemoryController < ActiveStorage::BaseController
|
5
|
+
skip_forgery_protection
|
6
|
+
|
7
|
+
def show
|
8
|
+
key = decode_verified_key
|
9
|
+
|
10
|
+
unless key
|
11
|
+
head :not_found
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
service = named_memory_service(key[:service_name])
|
16
|
+
if service.exist?(key[:key])
|
17
|
+
send_data(service.store[key[:key]], content_type: key[:content_type], disposition: key[:disposition])
|
18
|
+
else
|
19
|
+
head :not_found
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def update
|
24
|
+
token = decode_verified_token
|
25
|
+
|
26
|
+
unless token
|
27
|
+
head :not_found
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
unless acceptable_content?(token)
|
32
|
+
head :unprocessable_entity
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
named_memory_service(token[:service_name]).upload token[:key], request.body, checksum: token[:checksum]
|
37
|
+
head :no_content
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def named_memory_service(name)
|
43
|
+
ActiveStorage::Blob.services.fetch(name) do
|
44
|
+
ActiveStorage::Blob.service
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def decode_verified_key
|
49
|
+
ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key)&.deep_symbolize_keys
|
50
|
+
end
|
51
|
+
|
52
|
+
def decode_verified_token
|
53
|
+
ActiveStorage.verifier.verified(params[:encoded_token], purpose: :blob_token)&.deep_symbolize_keys
|
54
|
+
end
|
55
|
+
|
56
|
+
def acceptable_content?(token)
|
57
|
+
token[:content_type] == request.content_mime_type.to_s && token[:content_length] == request.content_length
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/config/routes.rb
ADDED
@@ -11,9 +11,10 @@ module ActiveStorage
|
|
11
11
|
@config = config
|
12
12
|
end
|
13
13
|
|
14
|
-
def upload(key, io, **)
|
14
|
+
def upload(key, io, checksum: nil, **)
|
15
15
|
instrument(:upload, key: key) do
|
16
16
|
store[key] = io.read
|
17
|
+
ensure_integrity_of(key, checksum) if checksum
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
@@ -49,13 +50,28 @@ module ActiveStorage
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
52
|
-
def
|
53
|
-
instrument
|
54
|
-
|
55
|
-
|
53
|
+
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, **)
|
54
|
+
instrument :url, key: key do |payload|
|
55
|
+
verified_token_with_expiration = generate_verified_token(
|
56
|
+
key,
|
57
|
+
expires_in: expires_in,
|
58
|
+
content_type: content_type,
|
59
|
+
content_length: content_length,
|
60
|
+
checksum: checksum
|
61
|
+
)
|
62
|
+
url_helpers.update_rails_memory_service_url(
|
63
|
+
verified_token_with_expiration,
|
64
|
+
url_options
|
65
|
+
).tap do |generated_url|
|
66
|
+
payload[:url] = generated_url
|
67
|
+
end
|
56
68
|
end
|
57
69
|
end
|
58
70
|
|
71
|
+
def headers_for_direct_upload(_key, content_type:, **)
|
72
|
+
{ 'Content-Type' => content_type }
|
73
|
+
end
|
74
|
+
|
59
75
|
private
|
60
76
|
|
61
77
|
def stream(key)
|
@@ -66,5 +82,62 @@ module ActiveStorage
|
|
66
82
|
rescue KeyError
|
67
83
|
raise ActiveStorage::FileNotFoundError
|
68
84
|
end
|
85
|
+
|
86
|
+
def url_helpers
|
87
|
+
@url_helpers ||= Activestorage::Memory::Engine.routes.url_helpers
|
88
|
+
end
|
89
|
+
|
90
|
+
def generate_verified_token(key, expires_in:, content_type:, content_length:, checksum:)
|
91
|
+
ActiveStorage.verifier.generate(
|
92
|
+
{
|
93
|
+
key: key,
|
94
|
+
content_type: content_type,
|
95
|
+
content_length: content_length,
|
96
|
+
checksum: checksum,
|
97
|
+
service_name: name
|
98
|
+
},
|
99
|
+
expires_in: expires_in,
|
100
|
+
purpose: :blob_token
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def private_url(key, expires_in:, filename:, content_type:, disposition: :inline, **)
|
105
|
+
generate_url(key, expires_in: expires_in, filename: filename, content_type: content_type, disposition: disposition)
|
106
|
+
end
|
107
|
+
|
108
|
+
def public_url(key, filename:, content_type: nil, disposition: :attachment, **)
|
109
|
+
generate_url(key, expires_in: nil, filename: filename, content_type: content_type, disposition: disposition)
|
110
|
+
end
|
111
|
+
|
112
|
+
def generate_url(key, expires_in:, filename:, content_type:, disposition:)
|
113
|
+
content_disposition = content_disposition_with(type: disposition, filename: ActiveStorage::Filename.wrap(filename))
|
114
|
+
verified_key_with_expiration = ActiveStorage.verifier.generate(
|
115
|
+
{
|
116
|
+
key: key,
|
117
|
+
disposition: content_disposition,
|
118
|
+
content_type: content_type,
|
119
|
+
service_name: name
|
120
|
+
},
|
121
|
+
expires_in: expires_in,
|
122
|
+
purpose: :blob_key
|
123
|
+
)
|
124
|
+
|
125
|
+
if url_options.blank?
|
126
|
+
raise ArgumentError, "Cannot generate URL for #{filename} using Memory service, please set ActiveStorage::Current.url_options."
|
127
|
+
end
|
128
|
+
|
129
|
+
url_helpers.rails_memory_service_url(verified_key_with_expiration, filename: filename, **url_options)
|
130
|
+
end
|
131
|
+
|
132
|
+
def url_options
|
133
|
+
ActiveStorage::Current.url_options || Rails.application.default_url_options
|
134
|
+
end
|
135
|
+
|
136
|
+
def ensure_integrity_of(key, checksum)
|
137
|
+
return if OpenSSL::Digest.new('md5', store[key]).base64digest == checksum
|
138
|
+
|
139
|
+
delete key
|
140
|
+
raise ActiveStorage::IntegrityError
|
141
|
+
end
|
69
142
|
end
|
70
143
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe ActiveStorage::Service::MemoryService do
|
4
|
+
let(:service) { ActiveStorage::Service::MemoryService.new }
|
5
|
+
let(:content) { 'content' }
|
6
|
+
let(:io) { StringIO.new(content) }
|
7
|
+
let(:key) { 'key' }
|
8
|
+
let(:host) { 'example.com' }
|
9
|
+
|
10
|
+
before do
|
11
|
+
ActiveStorage::Current.url_options = { host: host }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#upload' do
|
15
|
+
it 'stores by key' do
|
16
|
+
service.upload(key, io)
|
17
|
+
expect(service.store[key]).to eq(content)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#download' do
|
22
|
+
context 'when key does not exist' do
|
23
|
+
it 'raises ActiveStorage::FileNotFoundError' do
|
24
|
+
expect { service.download(key) }.to raise_error(ActiveStorage::FileNotFoundError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when key exists' do
|
29
|
+
before do
|
30
|
+
service.upload(key, io)
|
31
|
+
end
|
32
|
+
it 'retrieves by key' do
|
33
|
+
expect(service.download(key).read).to eq(content)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#delete' do
|
39
|
+
context 'when key does not exist' do
|
40
|
+
it 'ignores key errors' do
|
41
|
+
expect { service.delete(key) }.not_to raise_error
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when key exists' do
|
46
|
+
before do
|
47
|
+
service.upload(key, io)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'deletes by key' do
|
51
|
+
service.delete(key)
|
52
|
+
expect(service.store).not_to have_key(key)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#exist?' do
|
58
|
+
context 'when key does not exist' do
|
59
|
+
it 'returns false' do
|
60
|
+
expect(service.exist?(key)).to be false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when key exists' do
|
65
|
+
before do
|
66
|
+
service.upload(key, io)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'checks by key' do
|
70
|
+
expect(service.exist?(key)).to be true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#url_for_direct_upload' do
|
76
|
+
let(:filename) { 'filename' }
|
77
|
+
let(:content_type) { 'image/jpeg' }
|
78
|
+
let(:content_length) { content.size }
|
79
|
+
let(:checksum) { OpenSSL::Digest.new('md5', content).base64digest }
|
80
|
+
let(:service_name) { 'memory' }
|
81
|
+
let(:expires_in) { 5.minutes }
|
82
|
+
|
83
|
+
before do
|
84
|
+
service.upload(key, io)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns a memory url' do
|
88
|
+
expect(service.url(key, expires_in: expires_in, filename: filename, content_type: content_type)).to start_with("http://#{host}/")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#headers_for_direct_upload' do
|
93
|
+
let(:content_type) { 'image/jpeg' }
|
94
|
+
|
95
|
+
it 'returns content type' do
|
96
|
+
expect(service.headers_for_direct_upload(key, content_type: content_type)).to eq('Content-Type' => content_type)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Activestorage::Memory::MemoryController, type: :request do
|
6
|
+
let(:key) { 'file_key' }
|
7
|
+
let(:content) { 'content' }
|
8
|
+
let(:filename) { 'file.jpg' }
|
9
|
+
let(:content_type) { 'image/jpeg' }
|
10
|
+
let(:service_name) { :memory }
|
11
|
+
let(:disposition) { "inline; filename=\"file.jpg\"; filename*=UTF-8''file.jpg" }
|
12
|
+
let(:expires_in) { ActiveStorage.service_urls_expire_in }
|
13
|
+
let(:checksum) { OpenSSL::Digest.new('md5', content).base64digest }
|
14
|
+
let!(:blob) do
|
15
|
+
ActiveStorage::Blob.create_and_upload!(
|
16
|
+
key: key,
|
17
|
+
io: StringIO.new(content),
|
18
|
+
filename: filename,
|
19
|
+
content_type: content_type,
|
20
|
+
service_name: service_name
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
before do
|
25
|
+
ActiveStorage::Current.url_options = { only_path: true }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "GET #show" do
|
29
|
+
let(:valid_key) do
|
30
|
+
ActiveStorage.verifier.generate(
|
31
|
+
{
|
32
|
+
key: key,
|
33
|
+
service_name: service_name,
|
34
|
+
content_type: content_type,
|
35
|
+
disposition: disposition
|
36
|
+
},
|
37
|
+
expires_in: expires_in,
|
38
|
+
purpose: :blob_key
|
39
|
+
)
|
40
|
+
end
|
41
|
+
let(:invalid_key) { 'invalid_key' }
|
42
|
+
|
43
|
+
subject { get "/rails/active_storage/memory/#{valid_key}/#{filename}" }
|
44
|
+
|
45
|
+
context "when key is valid" do
|
46
|
+
it "returns http success if key is valid and file exists" do
|
47
|
+
subject
|
48
|
+
expect(response).to have_http_status(:success)
|
49
|
+
expect(response.body).to eq(content)
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when file does not exist" do
|
53
|
+
before do
|
54
|
+
ActiveStorage::Blob.services.fetch(service_name).delete(key)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns http not_found" do
|
58
|
+
subject
|
59
|
+
expect(response).to have_http_status(:not_found)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when key is invalid" do
|
65
|
+
subject { get "/rails/active_storage/memory/#{invalid_key}/#{filename}" }
|
66
|
+
|
67
|
+
it "returns http not_found" do
|
68
|
+
subject
|
69
|
+
expect(response).to have_http_status(:not_found)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "PATCH #update" do
|
75
|
+
let(:valid_token) do
|
76
|
+
ActiveStorage.verifier.generate(
|
77
|
+
{
|
78
|
+
key: key,
|
79
|
+
service_name: service_name,
|
80
|
+
checksum: checksum,
|
81
|
+
content_type: content_type,
|
82
|
+
content_length: content.length
|
83
|
+
},
|
84
|
+
purpose: :blob_token
|
85
|
+
)
|
86
|
+
end
|
87
|
+
let(:invalid_token) { 'invalid_token' }
|
88
|
+
|
89
|
+
context "when token is valid" do
|
90
|
+
context "when content is acceptable" do
|
91
|
+
subject do
|
92
|
+
put(
|
93
|
+
"/rails/active_storage/memory/#{valid_token}",
|
94
|
+
params: content,
|
95
|
+
headers: { 'Content-Type' => content_type, 'Content-Length' => content.size }
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "returns http no_content if token is valid and content is acceptable" do
|
100
|
+
subject
|
101
|
+
expect(response).to have_http_status(:no_content)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when content is not acceptable" do
|
106
|
+
subject do
|
107
|
+
put(
|
108
|
+
"/rails/active_storage/memory/#{valid_token}",
|
109
|
+
params: content,
|
110
|
+
headers: { 'Content-Type' => "image/png", 'Content-Length' => content.size }
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "returns http unprocessable_entity" do
|
115
|
+
subject
|
116
|
+
expect(response).to have_http_status(:unprocessable_entity)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when token is invalid" do
|
122
|
+
subject do
|
123
|
+
put(
|
124
|
+
"/rails/active_storage/memory/#{invalid_token}",
|
125
|
+
params: content,
|
126
|
+
headers: { 'Content-Type' => content_type, 'Content-Length' => content.size }
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "returns http not_found" do
|
131
|
+
subject
|
132
|
+
expect(response).to have_http_status(:not_found)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class ApplicationJob < ActiveJob::Base
|
2
|
+
# Automatically retry jobs that encountered a deadlock
|
3
|
+
# retry_on ActiveRecord::Deadlocked
|
4
|
+
|
5
|
+
# Most jobs are safe to ignore if the underlying records are no longer available
|
6
|
+
# discard_on ActiveJob::DeserializationError
|
7
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Dummy</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
<%= csp_meta_tag %>
|
8
|
+
|
9
|
+
<%= stylesheet_link_tag "application" %>
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<%= yield %>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield %>
|
data/spec/dummy/bin/rake
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "fileutils"
|
3
|
+
|
4
|
+
# path to your application root.
|
5
|
+
APP_ROOT = File.expand_path("..", __dir__)
|
6
|
+
|
7
|
+
def system!(*args)
|
8
|
+
system(*args, exception: true)
|
9
|
+
end
|
10
|
+
|
11
|
+
FileUtils.chdir APP_ROOT do
|
12
|
+
# This script is a way to set up or update your development environment automatically.
|
13
|
+
# This script is idempotent, so that you can run it at any time and get an expectable outcome.
|
14
|
+
# Add necessary setup steps to this file.
|
15
|
+
|
16
|
+
puts "== Installing dependencies =="
|
17
|
+
system! "gem install bundler --conservative"
|
18
|
+
system("bundle check") || system!("bundle install")
|
19
|
+
|
20
|
+
# puts "\n== Copying sample files =="
|
21
|
+
# unless File.exist?("config/database.yml")
|
22
|
+
# FileUtils.cp "config/database.yml.sample", "config/database.yml"
|
23
|
+
# end
|
24
|
+
|
25
|
+
puts "\n== Preparing database =="
|
26
|
+
system! "bin/rails db:prepare"
|
27
|
+
|
28
|
+
puts "\n== Removing old logs and tempfiles =="
|
29
|
+
system! "bin/rails log:clear tmp:clear"
|
30
|
+
|
31
|
+
puts "\n== Restarting application server =="
|
32
|
+
system! "bin/rails restart"
|
33
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative "boot"
|
2
|
+
|
3
|
+
require "rails"
|
4
|
+
# Pick the frameworks you want:
|
5
|
+
require "active_model/railtie"
|
6
|
+
require "active_job/railtie"
|
7
|
+
require "active_record/railtie"
|
8
|
+
require "active_storage/engine"
|
9
|
+
require "action_controller/railtie"
|
10
|
+
require "action_mailer/railtie"
|
11
|
+
require "action_mailbox/engine"
|
12
|
+
require "action_text/engine"
|
13
|
+
require "action_view/railtie"
|
14
|
+
require "action_cable/engine"
|
15
|
+
# require "rails/test_unit/railtie"
|
16
|
+
|
17
|
+
# Require the gems listed in Gemfile, including any gems
|
18
|
+
# you've limited to :test, :development, or :production.
|
19
|
+
Bundler.require(*Rails.groups)
|
20
|
+
|
21
|
+
module Dummy
|
22
|
+
class Application < Rails::Application
|
23
|
+
config.load_defaults Rails::VERSION::STRING.to_f
|
24
|
+
|
25
|
+
# For compatibility with applications that use this config
|
26
|
+
config.action_controller.include_all_helpers = false
|
27
|
+
|
28
|
+
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
29
|
+
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
30
|
+
# Common ones are `templates`, `generators`, or `middleware`, for example.
|
31
|
+
config.autoload_lib(ignore: %w(assets tasks))
|
32
|
+
|
33
|
+
# Configuration for the application, engines, and railties goes here.
|
34
|
+
#
|
35
|
+
# These settings can be overridden in specific environments using the files
|
36
|
+
# in config/environments, which are processed later.
|
37
|
+
#
|
38
|
+
# config.time_zone = "Central Time (US & Canada)"
|
39
|
+
# config.eager_load_paths << Rails.root.join("extras")
|
40
|
+
|
41
|
+
# Don't generate system test files.
|
42
|
+
config.generators.system_tests = nil
|
43
|
+
end
|
44
|
+
end
|