summaryrefslogtreecommitdiff
path: root/spec/models/concerns
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2018-12-19 15:18:20 -0800
committerStan Hu <stanhu@gmail.com>2018-12-19 15:34:29 -0800
commit52fdddbd2d1e89a6a41a59a41adf0820cc98c435 (patch)
treed55bb5d076fe1a0e23338186ccf6eabfcb26f040 /spec/models/concerns
parent00096b52ced2962d237540c494f2ad6c3add70ef (diff)
downloadgitlab-ce-52fdddbd2d1e89a6a41a59a41adf0820cc98c435.tar.gz
Cache avatar URLs and paths within a request
In a merge request with many discussions, the avatar URL can be called thousands of times, inflicting a significant performance penalty especially when avatars are stored in object storage. To mitigate this problem, we can just cache the generated path any time it is requested. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/55355
Diffstat (limited to 'spec/models/concerns')
-rw-r--r--spec/models/concerns/avatarable_spec.rb37
1 files changed, 37 insertions, 0 deletions
diff --git a/spec/models/concerns/avatarable_spec.rb b/spec/models/concerns/avatarable_spec.rb
index 7d617cb7b19..1ea7f2b9985 100644
--- a/spec/models/concerns/avatarable_spec.rb
+++ b/spec/models/concerns/avatarable_spec.rb
@@ -33,6 +33,43 @@ describe Avatarable do
end
describe '#avatar_path' do
+ context 'with caching enabled', :request_store do
+ let!(:avatar_path) { [relative_url_root, project.avatar.local_url].join }
+ let!(:avatar_url) { [gitlab_host, relative_url_root, project.avatar.local_url].join }
+
+ it 'only calls local_url once' do
+ expect(project.avatar).to receive(:local_url).once.and_call_original
+
+ 2.times do
+ expect(project.avatar_path).to eq(avatar_path)
+ end
+ end
+
+ it 'calls local_url twice for path and URLs' do
+ expect(project.avatar).to receive(:local_url).exactly(2).times.and_call_original
+
+ expect(project.avatar_path(only_path: true)).to eq(avatar_path)
+ expect(project.avatar_path(only_path: false)).to eq(avatar_url)
+ end
+
+ it 'calls local_url twice for different sizes' do
+ expect(project.avatar).to receive(:local_url).exactly(2).times.and_call_original
+
+ expect(project.avatar_path).to eq(avatar_path)
+ expect(project.avatar_path(size: 40)).to eq(avatar_path + "?width=40")
+ end
+
+ it 'handles unpersisted objects' do
+ new_project = build(:project, :with_avatar)
+ path = [relative_url_root, new_project.avatar.local_url].join
+ expect(new_project.avatar).to receive(:local_url).exactly(2).times.and_call_original
+
+ 2.times do
+ expect(new_project.avatar_path).to eq(path)
+ end
+ end
+ end
+
using RSpec::Parameterized::TableSyntax
where(:has_asset_host, :visibility_level, :only_path, :avatar_path_prefix) do