s3_spec.rb 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Store::Provider::S3, authenticated_as: false, integration: true do
  4. around do |example|
  5. VCR.configure do |c|
  6. c.ignore_hosts 's3.eu-central-1.amazonaws.com'
  7. c.ignore_hosts 's3.eu-central-1.zammad.org'
  8. c.ignore_hosts ENV['S3_ENDPOINT'] if ENV['S3_ENDPOINT'].present?
  9. end
  10. example.run
  11. described_class.reset
  12. end
  13. describe '.client' do
  14. it 'returns an Aws::S3::Client object' do
  15. expect(described_class.client).to be_a(Aws::S3::Client)
  16. end
  17. end
  18. describe 'ping?' do
  19. it 'returns true' do
  20. expect(described_class.ping?).to be(true)
  21. end
  22. context 'when credentials are bad' do
  23. before do
  24. config = Store::Provider::S3::Config.send(:settings)
  25. config[:access_key_id] = 'bad'
  26. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  27. end
  28. it 'returns false' do
  29. expect(described_class.ping?).to be(false)
  30. end
  31. end
  32. context 'when bucket is not existing' do
  33. before do
  34. config = Store::Provider::S3::Config.send(:settings)
  35. config[:bucket] = config[:bucket] + DateTime.now.strftime('%Q')
  36. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  37. end
  38. it 'returns false' do
  39. expect(described_class.ping?).to be(false)
  40. end
  41. end
  42. context 'when endpoint is not reachable' do
  43. before do
  44. config = Store::Provider::S3::Config.send(:settings)
  45. config[:endpoint] = 'https://s3.eu-central-1.zammad.org'
  46. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  47. end
  48. it 'returns false' do
  49. expect(described_class.ping?).to be(false)
  50. end
  51. end
  52. end
  53. describe '.ping!' do
  54. context 'when connection succeeds' do
  55. it 'raises no error' do
  56. expect { described_class.ping! }.not_to raise_error
  57. end
  58. end
  59. context 'when connection fails' do
  60. before do
  61. config = Store::Provider::S3::Config.send(:settings)
  62. config[:endpoint] = 'https://s3.eu-central-1.zammad.org'
  63. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  64. end
  65. it 'raises an error' do
  66. expect { described_class.ping! }.to raise_error(Store::Provider::S3::Error)
  67. end
  68. end
  69. end
  70. describe '.reset' do
  71. it 'resets the client and its config', :aggregate_failures do
  72. described_class.reset
  73. expect(described_class.instance_variable_get(:@client)).to be_nil
  74. expect(Store::Provider::S3::Config.instance_variable_get(:@config)).to be_nil
  75. expect(Aws.config).to be_empty
  76. end
  77. end
  78. describe '.add' do
  79. let(:data) { Rails.root.join('spec/fixtures/files/image/large.png').read }
  80. let(:sha256) { Digest::SHA256.hexdigest(data) }
  81. it 'adds a file' do
  82. expect(described_class.add(data, sha256)).to be_truthy
  83. end
  84. context 'when connection fails' do
  85. before do
  86. config = Store::Provider::S3::Config.send(:settings)
  87. config[:endpoint] = 'https://s3.eu-central-1.zammad.org'
  88. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  89. end
  90. it 'raises an error' do
  91. expect { described_class.add(data, sha256) }.to raise_error(Store::Provider::S3::Error)
  92. end
  93. end
  94. context 'when file already exists' do
  95. before do
  96. described_class.add(data, sha256)
  97. end
  98. it 'overrides file' do
  99. expect { described_class.add(data, sha256) }.not_to raise_error
  100. end
  101. end
  102. end
  103. describe '.upload' do
  104. let(:data) { 'data' * 15.megabytes }
  105. let(:sha256) { Digest::SHA256.hexdigest(data) }
  106. before do
  107. config = Store::Provider::S3::Config.send(:settings)
  108. config[:max_chunk_size] = 10.megabytes
  109. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  110. end
  111. it 'uploads a file' do
  112. expect(described_class.upload(data, sha256)).to be_truthy
  113. end
  114. context 'when max_chunk_size setting is smaller 5MB' do
  115. before do
  116. config = Store::Provider::S3::Config.send(:settings)
  117. config[:max_chunk_size] = 2.megabytes
  118. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  119. end
  120. it 'raises an error' do
  121. expect { described_class.upload(data, sha256) }.to raise_error(Store::Provider::S3::Error)
  122. end
  123. end
  124. end
  125. describe '.delete' do
  126. let(:data) { Rails.root.join('spec/fixtures/files/image/large.png').read }
  127. let(:sha256) { Digest::SHA256.hexdigest(data) }
  128. it 'deletes a file' do
  129. described_class.add(data, sha256)
  130. expect(described_class.delete(sha256)).to be_truthy
  131. end
  132. context 'when connection fails' do
  133. before do
  134. config = Store::Provider::S3::Config.send(:settings)
  135. config[:endpoint] = 'https://s3.eu-central-1.zammad.org'
  136. Store::Provider::S3::Config.instance_variable_set(:@config, config)
  137. end
  138. it 'raises an error' do
  139. expect { described_class.delete(sha256) }.to raise_error(Store::Provider::S3::Error)
  140. end
  141. end
  142. context 'when file does not exist' do
  143. it 'raises no error' do
  144. expect { described_class.delete(sha256) }.not_to raise_error
  145. end
  146. end
  147. end
  148. end