2017-03-07 13:34:43 -05:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2017-07-10 10:24:02 -04:00
|
|
|
describe Gitlab::UserActivities, :clean_gitlab_redis_shared_state do
|
2017-03-07 13:34:43 -05:00
|
|
|
let(:now) { Time.now }
|
|
|
|
|
|
|
|
describe '.record' do
|
|
|
|
context 'with no time given' do
|
2017-07-10 23:35:47 -04:00
|
|
|
it 'uses Time.now and records an activity in SharedState' do
|
2017-03-07 13:34:43 -05:00
|
|
|
Timecop.freeze do
|
|
|
|
now # eager-load now
|
|
|
|
described_class.record(42)
|
|
|
|
end
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a time given' do
|
2017-07-10 23:35:47 -04:00
|
|
|
it 'uses the given time and records an activity in SharedState' do
|
2017-03-07 13:34:43 -05:00
|
|
|
described_class.record(42, now)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.delete' do
|
|
|
|
context 'with a single key' do
|
|
|
|
context 'and key exists' do
|
2017-07-10 23:35:47 -04:00
|
|
|
it 'removes the pair from SharedState' do
|
2017-03-07 13:34:43 -05:00
|
|
|
described_class.record(42, now)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]])
|
|
|
|
end
|
|
|
|
|
|
|
|
subject.delete(42)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and key does not exist' do
|
2017-07-10 23:35:47 -04:00
|
|
|
it 'removes the pair from SharedState' do
|
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []])
|
|
|
|
end
|
|
|
|
|
|
|
|
subject.delete(42)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with multiple keys' do
|
|
|
|
context 'and all keys exist' do
|
2017-07-10 23:35:47 -04:00
|
|
|
it 'removes the pair from SharedState' do
|
2017-03-07 13:34:43 -05:00
|
|
|
described_class.record(41, now)
|
|
|
|
described_class.record(42, now)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['41', now.to_i.to_s], ['42', now.to_i.to_s]]])
|
|
|
|
end
|
|
|
|
|
|
|
|
subject.delete(41, 42)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and some keys does not exist' do
|
2017-07-10 23:35:47 -04:00
|
|
|
it 'removes the existing pair from SharedState' do
|
2017-03-07 13:34:43 -05:00
|
|
|
described_class.record(42, now)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]])
|
|
|
|
end
|
|
|
|
|
|
|
|
subject.delete(41, 42)
|
|
|
|
|
2017-07-10 23:35:47 -04:00
|
|
|
Gitlab::Redis::SharedState.with do |redis|
|
2017-03-07 13:34:43 -05:00
|
|
|
expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'Enumerable' do
|
|
|
|
before do
|
|
|
|
described_class.record(40, now)
|
|
|
|
described_class.record(41, now)
|
|
|
|
described_class.record(42, now)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'allows to read the activities sequentially' do
|
|
|
|
expected = { '40' => now.to_i.to_s, '41' => now.to_i.to_s, '42' => now.to_i.to_s }
|
|
|
|
|
|
|
|
actual = described_class.new.each_with_object({}) do |(key, time), actual|
|
|
|
|
actual[key] = time
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(actual).to eq(expected)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with many records' do
|
|
|
|
before do
|
|
|
|
1_000.times { |i| described_class.record(i, now) }
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is possible to loop through all the records' do
|
|
|
|
expect(described_class.new.count).to eq(1_000)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|