package_spec.rb 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Package, type: :model do
  4. # cleanup package files
  5. after :all do # rubocop:disable RSpec/BeforeAfterAll
  6. %w[example.rb app/controllers/test_controller.rb].each do |file|
  7. next if !File.exist?(Rails.root.join(file))
  8. File.delete(Rails.root.join(file))
  9. end
  10. end
  11. def get_package_structure(name, files, version = '1.0.1')
  12. <<-JSON
  13. {
  14. "name": "#{name}",
  15. "version": "#{version}",
  16. "vendor": "Zammad Foundation",
  17. "license": "ABC",
  18. "url": "https://zammad.org/",
  19. "description": [
  20. {
  21. "language": "en",
  22. "text": "some description"
  23. }
  24. ],
  25. "files": #{files}
  26. }
  27. JSON
  28. end
  29. let(:package_zpm_files_json) do
  30. <<-JSON
  31. [
  32. {
  33. "permission": "644",
  34. "location": "example.rb",
  35. "content": "YWJjw6TDtsO8w58="
  36. },
  37. {
  38. "permission": "644",
  39. "location": "app/controllers/test_controller.rb",
  40. "content": "YWJjw6TDtsO8w58="
  41. }
  42. ]
  43. JSON
  44. end
  45. let(:package_name) { 'UnitTestSample' }
  46. let(:package_zpm_json) { get_package_structure(package_name, package_zpm_files_json) }
  47. let(:old_package_zpm_json) { get_package_structure(package_name, package_zpm_files_json, '1.0.0') }
  48. let(:new_package_zpm_json) { get_package_structure(package_name, package_zpm_files_json, '1.0.2') }
  49. context 'when performing different package actions' do
  50. context 'when installing a package' do
  51. it 'does install package' do
  52. expect { described_class.install(string: package_zpm_json) }
  53. .to change(described_class, :count)
  54. .and change(Store, :count)
  55. end
  56. end
  57. context 'when reinstalling a package' do
  58. before do
  59. described_class.install(string: package_zpm_json)
  60. end
  61. it 'does not reinstall package' do
  62. expect { described_class.reinstall(package_name) }
  63. .to not_change(described_class, :count)
  64. .and not_change(Store, :count)
  65. end
  66. end
  67. context 'when installing a package again' do
  68. before do
  69. described_class.install(string: package_zpm_json)
  70. end
  71. it 'does not install package' do
  72. expect { described_class.install(string: package_zpm_json) }
  73. .to raise_error(RuntimeError)
  74. .and not_change(described_class, :count)
  75. .and not_change(Store, :count)
  76. end
  77. end
  78. context 'when installing a package with a lower version' do
  79. before do
  80. described_class.install(string: package_zpm_json)
  81. end
  82. it 'does not install package' do
  83. expect { described_class.install(string: old_package_zpm_json) }
  84. .to raise_error(RuntimeError)
  85. .and not_change(described_class, :count)
  86. .and not_change(Store, :count)
  87. end
  88. end
  89. context 'when upgrading a package' do
  90. before do
  91. described_class.install(string: package_zpm_json)
  92. end
  93. it 'does install package' do
  94. expect { described_class.install(string: new_package_zpm_json) }
  95. .to not_raise_error
  96. .and not_change(described_class, :count)
  97. .and change(Store, :count)
  98. end
  99. end
  100. context 'when installing + uninstalling a package' do
  101. before do
  102. described_class.install(string: package_zpm_json)
  103. end
  104. it 'does install + uninstall the package' do
  105. expect { described_class.uninstall(string: package_zpm_json) }
  106. .to not_raise_error
  107. .and change(described_class, :count)
  108. .and not_change(Store, :count)
  109. end
  110. end
  111. context 'when auto installing' do
  112. before do
  113. FileUtils.mkdir_p(Rails.root.join('auto_install'))
  114. location = Rails.root.join('auto_install/unittest.zpm')
  115. file = File.new(location, 'wb')
  116. file.write(package_zpm_json)
  117. file.close
  118. end
  119. after do
  120. File.delete(Rails.root.join('auto_install/unittest.zpm'))
  121. end
  122. it 'does install package' do
  123. expect { described_class.auto_install }
  124. .to change(described_class, :count)
  125. .and change(Store, :count)
  126. end
  127. end
  128. context 'when verify package install' do
  129. context 'when verify is ok' do
  130. it 'returns no verify issues' do
  131. package = described_class.install(string: package_zpm_json)
  132. expect(package.verify).to be_nil
  133. end
  134. end
  135. context 'when verify is not ok' do
  136. it 'returns verify issues' do
  137. package = described_class.install(string: package_zpm_json)
  138. File.delete(Rails.root.join('example.rb'))
  139. expect(package.verify).not_to be_nil
  140. end
  141. end
  142. end
  143. end
  144. context 'with different file locations' do
  145. context 'with correct file locations' do
  146. it 'installation should work' do
  147. expect(described_class.install(string: package_zpm_json)).to be_truthy
  148. end
  149. end
  150. shared_examples 'check not allowed file location' do |file_location|
  151. let(:package_zpm_files_json) do
  152. <<-JSON
  153. [
  154. {
  155. "permission": "644",
  156. "location": "example.rb",
  157. "content": "YWJjw6TDtsO8w58="
  158. },
  159. {
  160. "permission": "644",
  161. "location": "#{file_location}",
  162. "content": "YWJjw6TDtsO8w58="
  163. }
  164. ]
  165. JSON
  166. end
  167. it 'installation should raise a error and package/store should not be present, because of not allowed file location' do
  168. expect { described_class.install(string: package_zpm_json) }
  169. .to raise_error(RuntimeError)
  170. .and not_change(described_class, :count)
  171. .and not_change(Store, :count)
  172. end
  173. end
  174. context "with not allowed file location part: '..'" do
  175. include_examples 'check not allowed file location', '../../../../../tmp/test_controller.rb'
  176. end
  177. context "with not allowed file location part: '%2e%2e'" do
  178. include_examples 'check not allowed file location', '%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/tmp/test_controller.rb'
  179. end
  180. end
  181. end