s3_spec.rb 5.2 KB

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