prelands_rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +6 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +4 -0
  8. data/Gemfile.lock +1456 -0
  9. data/LICENSE.txt +21 -0
  10. data/Makefile +4 -0
  11. data/README.md +4 -0
  12. data/Rakefile +6 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/lib/prelands_rails/concerns/abstract_interactor.rb +48 -0
  16. data/lib/prelands_rails/concerns/base.rb +25 -0
  17. data/lib/prelands_rails/concerns/can_handle_errors.rb +31 -0
  18. data/lib/prelands_rails/concerns/hash.rb +11 -0
  19. data/lib/prelands_rails/concerns/my_aws_client.rb +123 -0
  20. data/lib/prelands_rails/create_simple_source/check_zip_files/detect_absent_files.rb +25 -0
  21. data/lib/prelands_rails/create_simple_source/check_zip_files/extract_files.rb +31 -0
  22. data/lib/prelands_rails/create_simple_source/check_zip_files.rb +79 -0
  23. data/lib/prelands_rails/create_simple_source/compile/html_compiler.rb +106 -0
  24. data/lib/prelands_rails/create_simple_source/compile.rb +44 -0
  25. data/lib/prelands_rails/create_simple_source/create_record.rb +44 -0
  26. data/lib/prelands_rails/create_simple_source/detect_incoming_locales.rb +35 -0
  27. data/lib/prelands_rails/create_simple_source/upload/uploader.rb +47 -0
  28. data/lib/prelands_rails/create_simple_source/upload.rb +83 -0
  29. data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_html/html.rb +115 -0
  30. data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_html.rb +40 -0
  31. data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_js/js.rb +62 -0
  32. data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_js.rb +32 -0
  33. data/lib/prelands_rails/create_simple_source/validate_zip_content.rb +26 -0
  34. data/lib/prelands_rails/create_simple_source.rb +48 -0
  35. data/lib/prelands_rails/update_simple_source/check_zip_files.rb +39 -0
  36. data/lib/prelands_rails/update_simple_source/compile.rb +38 -0
  37. data/lib/prelands_rails/update_simple_source/update_record.rb +41 -0
  38. data/lib/prelands_rails/update_simple_source/upload/delete_compiled_files.rb +30 -0
  39. data/lib/prelands_rails/update_simple_source/upload.rb +43 -0
  40. data/lib/prelands_rails/update_simple_source/validate_zip_content.rb +35 -0
  41. data/lib/prelands_rails/update_simple_source.rb +48 -0
  42. data/lib/prelands_rails/validate_simple_source.rb +26 -0
  43. data/lib/prelands_rails/version.rb +3 -0
  44. data/lib/prelands_rails.rb +41 -0
  45. data/prelands_rails.gemspec +48 -0
  46. metadata +314 -0
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class CreateSimpleSource
5
+ class Upload
6
+ #
7
+ # Загрузчик файлов на AWS.
8
+ #
9
+ class Uploader
10
+ def initialize(creds, aws_prefix, client_class = ::PrelandsRails::MyAwsClient)
11
+ @folder = aws_prefix
12
+ @client = client_class.new creds[:access_key], creds[:secret_key], creds[:region]
13
+ end
14
+
15
+ # На вход подан путь к файлу на хосте, который грузим на aws с указанным именем.
16
+ #
17
+ # @param [String] file_path
18
+ # @param [String] s3_file_name
19
+ # @param [String] bucket_name
20
+
21
+ def upload_file(s3_file_name, file_path, bucket_name)
22
+ @client.upload_file file_path, path(s3_file_name), bucket_name
23
+ end
24
+
25
+ # На вход подана строка +file_content+. Сохраняем её, как файл с указанным именем.
26
+ #
27
+ # @param [String] s3_file_name
28
+ # @param [String] file_content
29
+ # @param [String] bucket_name
30
+
31
+ def upload_content(s3_file_name, file_content, bucket_name)
32
+ Tempfile.create(SecureRandom.uuid) do |file|
33
+ file.write file_content.force_encoding('utf-8')
34
+ file.close
35
+ @client.upload_file file.path, path(s3_file_name), bucket_name
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def path(file)
42
+ [@folder, file].join('/')
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class CreateSimpleSource
5
+ #
6
+ # Загрузит на aws скомпилированные html, icon.ico, index.js и содержимое директории images/
7
+ #
8
+ class Upload
9
+ include ::PrelandsRails::AbstractInteractor
10
+ include ::Interactor
11
+ include ::Interactor::Contracts
12
+ include ::PrelandsRails::Base
13
+
14
+ expects do
15
+ required(:archive).filled # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
16
+ required(:compiled_htmls).value(type?: Hash) # скомпилированные исходники { file_name[String] => compiled_content[String], ... }
17
+ required(:s3_credentials).schema do
18
+ required(:access_key).filled(:str?)
19
+ required(:secret_key).filled(:str?)
20
+ required(:region).filled(:str?)
21
+ end
22
+ required(:bucket_names).value(type?: Array)
23
+ required(:aws_prefix).value(type?: String)
24
+ required(:files_content).value(type?: Hash) # { file_name => file_content, ... }
25
+ end
26
+
27
+ assures do
28
+
29
+ end
30
+
31
+ before do
32
+ @uploader = Uploader.new(context.s3_credentials, context.aws_prefix)
33
+ end
34
+
35
+ def act
36
+ context.bucket_names.each do |bucket_name|
37
+ images_files.map do |file_name, file_path|
38
+ @uploader.upload_file file_name, file_path, bucket_name
39
+ end
40
+
41
+ compiled_html_files.map do |file_name, content|
42
+ @uploader.upload_content file_name, content, bucket_name
43
+ end
44
+
45
+ @uploader.upload_content 'index.js', context.files_content['index.js'], bucket_name
46
+ end
47
+
48
+ del_tmp_files
49
+ context.uploaded_images = images_files
50
+ end
51
+
52
+ on_breach { |breaches| bad_expects breaches }
53
+
54
+ private
55
+
56
+ IMAGES = /\A(images\/.+|icon\.ico)\z/
57
+
58
+ def images_files
59
+ return @images_files if defined?(@images_files)
60
+
61
+ @tmp_paths = []
62
+
63
+ @images_files ||= Zip::File.open(context.archive.tempfile) do |zipfile|
64
+ zipfile.map do |entry|
65
+ next if entry.name.index(IMAGES) != 0
66
+
67
+ tmp_path = Rails.root.join make_tmp_path
68
+ entry.extract tmp_path
69
+ @tmp_paths << tmp_path
70
+
71
+ [entry.name, tmp_path]
72
+ end.compact.to_h
73
+ end
74
+ end
75
+
76
+ def del_tmp_files
77
+ @tmp_paths.each do |path|
78
+ File.delete(path) if File.exists?(path)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class CreateSimpleSource
5
+ class ValidateZipContent
6
+ class ValidateHtml
7
+ #
8
+ # Принимает строку с html разметкой и валидирует её.
9
+ #
10
+ class Html
11
+ attr_reader :errors
12
+
13
+ # @param [String] string Содержимое html файла.
14
+ def initialize(string, continue_id)
15
+ @errors = []
16
+ @continue_id = continue_id
17
+ @string = string.gsub(/(\r\n?|\n)/, '') # убираем переносы, мешающие регуляркам
18
+ end
19
+
20
+ def valid?
21
+ @errors = [
22
+ check_internal_scripts,
23
+ check_internal_styles,
24
+ check_continue_element,
25
+ check_js_plug,
26
+ check_css_plug,
27
+ check_title_presence,
28
+ check_a_hrefs,
29
+ check_favicon
30
+ ].compact
31
+
32
+ !@errors.any?
33
+ end
34
+
35
+ private
36
+
37
+ # @return [nil] Если внутри html НЕ содержится JavaScript код в виде <script>...</script>
38
+ # @return [String] Иначе - вернёт сообщение об ошибке
39
+ def check_internal_scripts
40
+ rx = /<script[^>]*>([^<]+)<\/script>/
41
+ return unless any(rx)
42
+
43
+ 'A JavaScript code is detected inside html-file. Please, move it to index.js.'
44
+ end
45
+
46
+ def check_internal_styles
47
+ rx = /<style[^>]*>([^<]+)<\/style>/
48
+ return unless any(rx)
49
+
50
+ 'An internal CSS is detected inside html-file. Please, move it to index.css.'
51
+ end
52
+
53
+ def check_continue_element
54
+ rx = Regexp.new('id="%s"' % @continue_id)
55
+ res = @string.scan(rx).flatten
56
+ return if res.size == 1
57
+
58
+ return 'The continue element with id="%s" must be uniq. Found %s matches.' % [@continue_id, res.size] if res.size > 1
59
+
60
+ 'Not found continue element with id="%s"' % @continue_id
61
+ end
62
+
63
+ def check_js_plug
64
+ body_rx = /<body[^>]*>(.+)<\/body>/
65
+ js_rx = '<script src="index.js"'
66
+
67
+ @string[body_rx]
68
+ res = $1&.[](js_rx)
69
+ return if res.present?
70
+
71
+ 'Plug index.js script before closing tag of body.'
72
+ end
73
+
74
+ def check_css_plug
75
+ head_rx = /(?<=<head)(.+)(?=<\/head>)/
76
+ css_rx = 'href="index.css"'
77
+
78
+ @string[head_rx]
79
+ res = $1&.[](css_rx)
80
+ return if res.present?
81
+
82
+ 'Plug index.css before closing tag of head.'
83
+ end
84
+
85
+ def check_title_presence
86
+ title_rx = /<title>[^<]+<\/title>/
87
+ return if @string[title_rx]
88
+
89
+ 'Tag <title> not found.'
90
+ end
91
+
92
+ def check_a_hrefs
93
+ ahref_rx = /<a[^>]+href="[^"]+"/
94
+ return unless @string[ahref_rx]
95
+
96
+ 'Links with href attribute found.'
97
+ end
98
+
99
+ def check_favicon
100
+ favicon_rx = '<link rel="shortcut icon" href="icon.ico">'
101
+ return if @string[favicon_rx]
102
+
103
+ '<link rel="shortcut icon" href="icon.ico"> not found.'
104
+ end
105
+
106
+ protected
107
+
108
+ def any(regex)
109
+ @string.scan(regex).flatten.map(&:strip).map(&:present?).any?
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class CreateSimpleSource
5
+ class ValidateZipContent
6
+ #
7
+ # Валидирует все html файлы.
8
+ #
9
+ class ValidateHtml
10
+ include ::PrelandsRails::AbstractInteractor
11
+ include ::Interactor
12
+ include ::Interactor::Contracts
13
+ include ::PrelandsRails::Base
14
+
15
+ CONTINUE_ID = 'continue'
16
+
17
+ expects do
18
+ required(:files_content).value(type?: Hash) # { file_name => file_content, ... }
19
+ end
20
+
21
+ assures do
22
+
23
+ end
24
+
25
+ def act
26
+ errors =
27
+ incoming_html_files.map do |key, content|
28
+ content = Html.new(content, CONTINUE_ID)
29
+ next if content.valid?
30
+ [key, content.errors]
31
+ end.compact.to_h
32
+
33
+ fail! errors: errors if errors.any?
34
+ end
35
+
36
+ on_breach { |breaches| bad_expects breaches }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class CreateSimpleSource
5
+ class ValidateZipContent
6
+ class ValidateJs
7
+ #
8
+ # Принимает строку с JavaScript кодом разметкой и валидирует её.
9
+ #
10
+ class Js
11
+ attr_reader :errors
12
+
13
+ # @param [String] string Содержимое JavaScript файла.
14
+ def initialize(string)
15
+ @errors = []
16
+ @string = string.gsub(/(\r\n?|\n)/, '') # убираем переносы, мешающие регуляркам
17
+ end
18
+
19
+ def valid?
20
+ @errors = [
21
+ check_location_changes,
22
+ check_framework_calls
23
+ ].compact
24
+
25
+ !@errors.any?
26
+ end
27
+
28
+ private
29
+
30
+ def check_location_changes
31
+ match_data = @string.match LOCATION_RX
32
+ is_loc_assign = ->(matched) { matched =~ /^('|")$/ || @string.match(/(;|\s*)#{matched}\s*=\s*('|")/) }
33
+ return unless match_data && is_loc_assign[match_data[3]]
34
+
35
+ 'Location statement has found'
36
+ end
37
+
38
+ def check_framework_calls
39
+ res = FUNCS_RX.map do |key, func|
40
+ [ key, !!@string[func] ]
41
+ end
42
+
43
+ return if res.map { |kf| kf[1] }.all?
44
+
45
+ res.to_h.map do |key, result|
46
+ 'Call of %s() not found' % key if !result
47
+ end.compact.join('; ')
48
+ end
49
+
50
+ private
51
+
52
+ LOCATION_RX = /(;|\s*)location(\.href\s*=|\.replace\(|\.assign\(|\s*=)\s*(\w+|"|')/
53
+ FUNCS_RX = {
54
+ post_email: /post_email\([^)]+\)/,
55
+ post_gender: /post_gender\([^)]+\)/,
56
+ post_age: /post_age\([^)]+\)/
57
+ }.freeze
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class CreateSimpleSource
5
+ class ValidateZipContent
6
+ #
7
+ # Валидирует JavaScript код.
8
+ #
9
+ class ValidateJs
10
+ include ::PrelandsRails::AbstractInteractor
11
+ include ::Interactor
12
+ include ::Interactor::Contracts
13
+
14
+ expects do
15
+ required(:files_content).value(type?: Hash) # { file_name => file_content, ... }
16
+ end
17
+
18
+ assures do
19
+
20
+ end
21
+
22
+ def act
23
+ content = context[:files_content]['index.js']
24
+ content = Js.new(content)
25
+ fail! errors: {'index.js' => content.errors} unless content.valid?
26
+ end
27
+
28
+ on_breach { |breaches| bad_expects breaches }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class CreateSimpleSource
5
+ #
6
+ # Примет содержимое файлов и валидирует их контент.
7
+ #
8
+ class ValidateZipContent
9
+ include ::PrelandsRails::AbstractInteractor
10
+ include ::Interactor::Organizer
11
+ include ::Interactor::Contracts
12
+
13
+ expects do
14
+ required(:files_content).value(type?: Hash) # { file_name[String] => file_content[String], ... }
15
+ end
16
+
17
+ assures do
18
+
19
+ end
20
+
21
+ organize ValidateHtml, ValidateJs#, ValidateCss
22
+
23
+ on_breach { |breaches| bad_expects breaches }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ #
5
+ # Примет zip-файл с исходниками преленда и опубликует этот преленд.
6
+ #
7
+ class CreateSimpleSource
8
+ include ::PrelandsRails::AbstractInteractor
9
+ include ::Interactor::Organizer
10
+ include ::Interactor::Contracts
11
+
12
+ expects do
13
+ required(:archive).filled # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
14
+ required(:preland_domain_ids).filled(type?: Array)
15
+ required(:expected_locales).filled(type?: Array) # Список локалей, для которых must were all index_<locale>.html files in the zip archive
16
+ required(:s3_credentials).schema do
17
+ required(:access_key).filled(:str?)
18
+ required(:secret_key).filled(:str?)
19
+ required(:region).filled(:str?)
20
+ end
21
+ required(:bucket_names).filled(type?: Array)
22
+ required(:aws_prefix).value(type?: String) # имя директории в букете
23
+ required(:preland_id).filled
24
+ required(:static_js_path).value(type?: String) # путь к размещённым в интернете нашим js скриптам
25
+ required(:model_preland_simple_source).filled
26
+ end
27
+
28
+ before do
29
+ fail!(errors: 'Preland domains missing') if context.preland_domain_ids.empty?
30
+ end
31
+
32
+ assures do
33
+ required(:incoming_locales).filled(type?: Array)
34
+ required(:files_content).value(type?: Hash) # распакованные файлы из архива { file_name[String] => file_content[String], ... }
35
+ required(:compiled_htmls).value(type?: Hash) # скомпилированные исходники { file_name[String] => compiled_content[String], ... }
36
+ required(:preland_simple_source).filled
37
+ end
38
+
39
+ organize DetectIncomingLocales,
40
+ CheckZipFiles,
41
+ ValidateZipContent,
42
+ Compile,
43
+ Upload,
44
+ CreateRecord
45
+
46
+ on_breach { |breaches| bad_expects breaches }
47
+ end
48
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class UpdateSimpleSource
5
+
6
+ class CheckZipFiles
7
+ include ::PrelandsRails::AbstractInteractor
8
+ include ::Interactor
9
+ include ::Interactor::Contracts
10
+
11
+ expects do
12
+ required(:archive) # Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
13
+ required(:expected_locales).value(type?: Array)
14
+ required(:incoming_locales).filled(type?: Array)
15
+ end
16
+
17
+ assures do
18
+ optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
19
+ end
20
+
21
+ before do
22
+
23
+ end
24
+
25
+ def act
26
+ if context.archive
27
+ result = ::PrelandsRails::CreateSimpleSource::CheckZipFiles.call context
28
+ if result.success?
29
+ context.files_content = result.files_content
30
+ else
31
+ fail!(errors: result.errors)
32
+ end
33
+ end
34
+ end
35
+
36
+ on_breach { |breaches| bad_expects breaches }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class UpdateSimpleSource
5
+
6
+ class Compile
7
+ include ::PrelandsRails::AbstractInteractor
8
+ include ::Interactor
9
+ include ::Interactor::Contracts
10
+
11
+ expects do
12
+ optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
13
+ required(:static_js_path).value(type?: String)
14
+ end
15
+
16
+ assures do
17
+ optional(:compiled_htmls).value(type?: Hash) # { file_name[String] => compiled_content[String], ... }
18
+ end
19
+
20
+ before do
21
+
22
+ end
23
+
24
+ def act
25
+ if context.files_content
26
+ result = ::PrelandsRails::CreateSimpleSource::Compile.call context
27
+ if result.success?
28
+ context.compiled_htmls = result.compiled_htmls
29
+ else
30
+ fail!(errors: result.errors)
31
+ end
32
+ end
33
+ end
34
+
35
+ on_breach { |breaches| bad_expects breaches }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ module PrelandsRails
2
+ class UpdateSimpleSource
3
+ #
4
+ # обновит запись ::Preland::SimpleSource
5
+ #
6
+ class UpdateRecord
7
+ include ::PrelandsRails::AbstractInteractor
8
+ include ::Interactor
9
+ include ::Interactor::Contracts
10
+ include ::PrelandsRails::Base
11
+
12
+ expects do
13
+ required(:archive) # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
14
+ required(:aws_prefix).value(type?: String) # имя директории в букете
15
+ required(:preland_id).filled
16
+ required(:preland_domain_ids).value(type?: Array)
17
+ required(:incoming_locales).filled(type?: Array)
18
+ required(:model_preland_simple_source).filled
19
+ end
20
+
21
+ assures do
22
+ required(:preland_simple_source).filled
23
+ end
24
+
25
+ before do
26
+
27
+ end
28
+
29
+ def act
30
+ source = context.model_preland_simple_source.find_by aws_prefix: context.aws_prefix
31
+ source.archive = context.archive if context.archive
32
+ source.preland_domain_ids = context.preland_domain_ids
33
+ source.locales = context.incoming_locales
34
+ source.save!
35
+ context.preland_simple_source = source
36
+ end
37
+
38
+ on_breach { |breaches| bad_expects breaches }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class UpdateSimpleSource
5
+ class Upload
6
+ #
7
+ # Удалить из +bucket_names+ файлы преленда из директории +aws_prefix+.
8
+ #
9
+ module DeleteCompiledFiles
10
+ def delete_compiled_files
11
+ creds = context.s3_credentials
12
+ client = ::PrelandsRails::MyAwsClient.new creds[:access_key], creds[:secret_key], creds[:region]
13
+
14
+ context.bucket_names.each do |bucket_name|
15
+ files = client.list_objects bucket_name
16
+ next unless files
17
+
18
+ files = files.map do |file_name|
19
+ { key: file_name } if file_name.index(context.aws_prefix) == 0
20
+ end.compact
21
+
22
+ next if files.empty?
23
+
24
+ client.delete_objects bucket_name, files
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class UpdateSimpleSource
5
+
6
+ class Upload
7
+ include ::PrelandsRails::AbstractInteractor
8
+ include ::Interactor
9
+ include ::Interactor::Contracts
10
+ include DeleteCompiledFiles
11
+
12
+ expects do
13
+ required(:archive) # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
14
+ optional(:compiled_htmls).maybe(type?: Hash) # скомпилированные исходники { file_name[String] => compiled_content[String], ... }
15
+ required(:s3_credentials).schema do
16
+ required(:access_key).filled(:str?)
17
+ required(:secret_key).filled(:str?)
18
+ required(:region).filled(:str?)
19
+ end
20
+ required(:bucket_names).value(type?: Array)
21
+ required(:aws_prefix).value(type?: String)
22
+ optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
23
+ end
24
+
25
+ assures do
26
+
27
+ end
28
+
29
+ before do
30
+
31
+ end
32
+
33
+ def act
34
+ if context.archive && context.compiled_htmls && context.files_content
35
+ delete_compiled_files
36
+ ::PrelandsRails::CreateSimpleSource::Upload.call context
37
+ end
38
+ end
39
+
40
+ on_breach { |breaches| bad_expects breaches }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrelandsRails
4
+ class UpdateSimpleSource
5
+
6
+ class ValidateZipContent
7
+ include ::PrelandsRails::AbstractInteractor
8
+ include ::Interactor
9
+ include ::Interactor::Contracts
10
+
11
+ expects do
12
+ optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
13
+ end
14
+
15
+ assures do
16
+
17
+ end
18
+
19
+ before do
20
+
21
+ end
22
+
23
+ def act
24
+ if context.files_content
25
+ result = ::PrelandsRails::CreateSimpleSource::ValidateZipContent.call context
26
+ unless result.success?
27
+ fail!(errors: result.errors)
28
+ end
29
+ end
30
+ end
31
+
32
+ on_breach { |breaches| bad_expects breaches }
33
+ end
34
+ end
35
+ end