diff options
author | Sean McGivern <sean@gitlab.com> | 2017-04-12 12:19:45 +0100 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2017-04-14 15:20:55 +0200 |
commit | 91ac0e038ab51dd2f30f2bb7c91837fa588ca250 (patch) | |
tree | 54b5ea7cb6115a09bbcead558252563664b4898c /spec | |
parent | 3cb84e06b7a118fb46b4e1e0d4885026c9d4a4d1 (diff) | |
download | gitlab-ce-91ac0e038ab51dd2f30f2bb7c91837fa588ca250.tar.gz |
Port 'Add user activities API' to CE
CE port of https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/962
Diffstat (limited to 'spec')
-rw-r--r-- | spec/lib/gitlab/pagination_delegate_spec.rb | 155 | ||||
-rw-r--r-- | spec/lib/gitlab/user_activities/activity_set_spec.rb | 77 | ||||
-rw-r--r-- | spec/lib/gitlab/user_activities/activity_spec.rb | 14 | ||||
-rw-r--r-- | spec/requests/api/users_spec.rb | 76 | ||||
-rw-r--r-- | spec/requests/api/users_spec.rb.rej | 124 |
5 files changed, 408 insertions, 38 deletions
diff --git a/spec/lib/gitlab/pagination_delegate_spec.rb b/spec/lib/gitlab/pagination_delegate_spec.rb new file mode 100644 index 00000000000..3220d611274 --- /dev/null +++ b/spec/lib/gitlab/pagination_delegate_spec.rb @@ -0,0 +1,155 @@ +require 'spec_helper' + +describe Gitlab::PaginationDelegate, lib: true do + context 'no data' do + let(:delegate) do + described_class.new(page: 1, + per_page: 10, + count: 0) + end + + it 'shows the correct total count' do + expect(delegate.total_count).to eq(0) + end + + it 'shows the correct total pages' do + expect(delegate.total_pages).to eq(0) + end + + it 'shows the correct next page' do + expect(delegate.next_page).to be_nil + end + + it 'shows the correct previous page' do + expect(delegate.prev_page).to be_nil + end + + it 'shows the correct current page' do + expect(delegate.current_page).to eq(1) + end + + it 'shows the correct limit value' do + expect(delegate.limit_value).to eq(10) + end + + it 'shows the correct first page' do + expect(delegate.first_page?).to be true + end + + it 'shows the correct last page' do + expect(delegate.last_page?).to be true + end + + it 'shows the correct offset' do + expect(delegate.offset).to eq(0) + end + end + + context 'with data' do + let(:delegate) do + described_class.new(page: 5, + per_page: 100, + count: 1000) + end + + it 'shows the correct total count' do + expect(delegate.total_count).to eq(1000) + end + + it 'shows the correct total pages' do + expect(delegate.total_pages).to eq(10) + end + + it 'shows the correct next page' do + expect(delegate.next_page).to eq(6) + end + + it 'shows the correct previous page' do + expect(delegate.prev_page).to eq(4) + end + + it 'shows the correct current page' do + expect(delegate.current_page).to eq(5) + end + + it 'shows the correct limit value' do + expect(delegate.limit_value).to eq(100) + end + + it 'shows the correct first page' do + expect(delegate.first_page?).to be false + end + + it 'shows the correct last page' do + expect(delegate.last_page?).to be false + end + + it 'shows the correct offset' do + expect(delegate.offset).to eq(400) + end + end + + context 'last page' do + let(:delegate) do + described_class.new(page: 10, + per_page: 100, + count: 1000) + end + + it 'shows the correct total count' do + expect(delegate.total_count).to eq(1000) + end + + it 'shows the correct total pages' do + expect(delegate.total_pages).to eq(10) + end + + it 'shows the correct next page' do + expect(delegate.next_page).to be_nil + end + + it 'shows the correct previous page' do + expect(delegate.prev_page).to eq(9) + end + + it 'shows the correct current page' do + expect(delegate.current_page).to eq(10) + end + + it 'shows the correct limit value' do + expect(delegate.limit_value).to eq(100) + end + + it 'shows the correct first page' do + expect(delegate.first_page?).to be false + end + + it 'shows the correct last page' do + expect(delegate.last_page?).to be true + end + + it 'shows the correct offset' do + expect(delegate.offset).to eq(900) + end + end + + context 'limits and defaults' do + it 'has a maximum limit per page' do + expect(described_class.new(page: nil, + per_page: 1000, + count: 0).limit_value).to eq(described_class::MAX_PER_PAGE) + end + + it 'has a default per page' do + expect(described_class.new(page: nil, + per_page: nil, + count: 0).limit_value).to eq(described_class::DEFAULT_PER_PAGE) + end + + it 'has a maximum page' do + expect(described_class.new(page: 100, + per_page: 10, + count: 1).current_page).to eq(1) + end + end +end diff --git a/spec/lib/gitlab/user_activities/activity_set_spec.rb b/spec/lib/gitlab/user_activities/activity_set_spec.rb new file mode 100644 index 00000000000..56745bdf0d1 --- /dev/null +++ b/spec/lib/gitlab/user_activities/activity_set_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +describe Gitlab::UserActivities::ActivitySet, :redis, lib: true do + let(:user) { create(:user) } + + it 'shows the last user activity' do + Timecop.freeze do + user.record_activity + + expect(described_class.new.activities.first).to be_an_instance_of(Gitlab::UserActivities::Activity) + end + end + + context 'pagination delegation' do + let(:pagination_delegate) do + Gitlab::PaginationDelegate.new(page: 1, + per_page: 10, + count: 20) + end + + let(:delegated_methods) { %i[total_count total_pages current_page limit_value first_page? prev_page last_page? next_page] } + + before do + allow(described_class.new).to receive(:pagination_delegate).and_return(pagination_delegate) + end + + it 'includes the delegated methods' do + expect(described_class.new.public_methods).to include(*delegated_methods) + end + end + + context 'paginated activities' do + before do + Timecop.scale(3600) + + 7.times do + create(:user).record_activity + end + end + + after do + Timecop.return + end + + it 'shows the 5 oldest user activities paginated' do + expect(described_class.new(per_page: 5).activities.count).to eq(5) + end + + it 'shows the 2 reamining user activities paginated' do + expect(described_class.new(per_page: 5, page: 2).activities.count).to eq(2) + end + + it 'shows the oldest first' do + activities = described_class.new.activities + + expect(activities.first.last_activity_at).to be < activities.last.last_activity_at + end + end + + context 'filter by date' do + before do + create(:user).record_activity + end + + it 'shows activities from today' do + today = Date.today.to_s("%Y-%m-%d") + + expect(described_class.new(from: today).activities.count).to eq(1) + end + + it 'filter activities from tomorrow' do + tomorrow = Date.tomorrow.to_s("%Y-%m-%d") + + expect(described_class.new(from: tomorrow).activities.count).to eq(0) + end + end +end diff --git a/spec/lib/gitlab/user_activities/activity_spec.rb b/spec/lib/gitlab/user_activities/activity_spec.rb new file mode 100644 index 00000000000..6a1150f50c1 --- /dev/null +++ b/spec/lib/gitlab/user_activities/activity_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe Gitlab::UserActivities::Activity, :redis, lib: true do + let(:username) { 'user' } + let(:activity) { described_class.new('user', Time.new(2016, 12, 12).to_i) } + + it 'has the username' do + expect(activity.username).to eq(username) + end + + it 'has the last activity at' do + expect(activity.last_activity_at).to eq('2016-12-12 00:00:00') + end +end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index f793c0db2f3..a4e8d8e4156 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -1,12 +1,12 @@ require 'spec_helper' -describe API::Users, api: true do +describe API::Users, api: true do include ApiHelpers - let(:user) { create(:user) } + let(:user) { create(:user) } let(:admin) { create(:admin) } - let(:key) { create(:key, user: user) } - let(:email) { create(:email, user: user) } + let(:key) { create(:key, user: user) } + let(:email) { create(:email, user: user) } let(:omniauth_user) { create(:omniauth_user) } let(:ldap_user) { create(:omniauth_user, provider: 'ldapmain') } let(:ldap_blocked_user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') } @@ -129,7 +129,7 @@ describe API::Users, api: true do end describe "POST /users" do - before{ admin } + before { admin } it "creates user" do expect do @@ -214,9 +214,9 @@ describe API::Users, api: true do it "does not create user with invalid email" do post api('/users', admin), - email: 'invalid email', - password: 'password', - name: 'test' + email: 'invalid email', + password: 'password', + name: 'test' expect(response).to have_http_status(400) end @@ -242,12 +242,12 @@ describe API::Users, api: true do it 'returns 400 error if user does not validate' do post api('/users', admin), - password: 'pass', - email: 'test@example.com', - username: 'test!', - name: 'test', - bio: 'g' * 256, - projects_limit: -1 + password: 'pass', + email: 'test@example.com', + username: 'test!', + name: 'test', + bio: 'g' * 256, + projects_limit: -1 expect(response).to have_http_status(400) expect(json_response['message']['password']). to eq(['is too short (minimum is 8 characters)']) @@ -267,19 +267,19 @@ describe API::Users, api: true do context 'with existing user' do before do post api('/users', admin), - email: 'test@example.com', - password: 'password', - username: 'test', - name: 'foo' + email: 'test@example.com', + password: 'password', + username: 'test', + name: 'foo' end it 'returns 409 conflict error if user with same email exists' do expect do post api('/users', admin), - name: 'foo', - email: 'test@example.com', - password: 'password', - username: 'foo' + name: 'foo', + email: 'test@example.com', + password: 'password', + username: 'foo' end.to change { User.count }.by(0) expect(response).to have_http_status(409) expect(json_response['message']).to eq('Email has already been taken') @@ -288,10 +288,10 @@ describe API::Users, api: true do it 'returns 409 conflict error if same username exists' do expect do post api('/users', admin), - name: 'foo', - email: 'foo@example.com', - password: 'password', - username: 'test' + name: 'foo', + email: 'foo@example.com', + password: 'password', + username: 'test' end.to change { User.count }.by(0) expect(response).to have_http_status(409) expect(json_response['message']).to eq('Username has already been taken') @@ -416,12 +416,12 @@ describe API::Users, api: true do it 'returns 400 error if user does not validate' do put api("/users/#{user.id}", admin), - password: 'pass', - email: 'test@example.com', - username: 'test!', - name: 'test', - bio: 'g' * 256, - projects_limit: -1 + password: 'pass', + email: 'test@example.com', + username: 'test!', + name: 'test', + bio: 'g' * 256, + projects_limit: -1 expect(response).to have_http_status(400) expect(json_response['message']['password']). to eq(['is too short (minimum is 8 characters)']) @@ -488,7 +488,7 @@ describe API::Users, api: true do key_attrs = attributes_for :key expect do post api("/users/#{user.id}/keys", admin), key_attrs - end.to change{ user.keys.count }.by(1) + end.to change { user.keys.count }.by(1) end it "returns 400 for invalid ID" do @@ -580,7 +580,7 @@ describe API::Users, api: true do email_attrs = attributes_for :email expect do post api("/users/#{user.id}/emails", admin), email_attrs - end.to change{ user.emails.count }.by(1) + end.to change { user.emails.count }.by(1) end it "returns a 400 for invalid ID" do @@ -842,7 +842,7 @@ describe API::Users, api: true do key_attrs = attributes_for :key expect do post api("/user/keys", user), key_attrs - end.to change{ user.keys.count }.by(1) + end.to change { user.keys.count }.by(1) expect(response).to have_http_status(201) end @@ -880,7 +880,7 @@ describe API::Users, api: true do delete api("/user/keys/#{key.id}", user) expect(response).to have_http_status(204) - end.to change{user.keys.count}.by(-1) + end.to change { user.keys.count}.by(-1) end it "returns 404 if key ID not found" do @@ -963,7 +963,7 @@ describe API::Users, api: true do email_attrs = attributes_for :email expect do post api("/user/emails", user), email_attrs - end.to change{ user.emails.count }.by(1) + end.to change { user.emails.count }.by(1) expect(response).to have_http_status(201) end @@ -989,7 +989,7 @@ describe API::Users, api: true do delete api("/user/emails/#{email.id}", user) expect(response).to have_http_status(204) - end.to change{user.emails.count}.by(-1) + end.to change { user.emails.count}.by(-1) end it "returns 404 if email ID not found" do diff --git a/spec/requests/api/users_spec.rb.rej b/spec/requests/api/users_spec.rb.rej new file mode 100644 index 00000000000..f7ade32ce42 --- /dev/null +++ b/spec/requests/api/users_spec.rb.rej @@ -0,0 +1,124 @@ +diff a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb (rejected hunks) +@@ -1,12 +1,12 @@ + require 'spec_helper' + +-describe API::Users, api: true do ++describe API::Users, api: true do + include ApiHelpers + +- let(:user) { create(:user) } ++ let(:user) { create(:user) } + let(:admin) { create(:admin) } +- let(:key) { create(:key, user: user) } +- let(:email) { create(:email, user: user) } ++ let(:key) { create(:key, user: user) } ++ let(:email) { create(:email, user: user) } + let(:omniauth_user) { create(:omniauth_user) } + let(:ldap_user) { create(:omniauth_user, provider: 'ldapmain') } + let(:ldap_blocked_user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') } +@@ -827,7 +827,7 @@ describe API::Users, api: true do + user.save + expect do + delete api("/user/keys/#{key.id}", user) +- end.to change{user.keys.count}.by(-1) ++ end.to change { user.keys.count }.by(-1) + expect(response).to have_http_status(200) + end + +@@ -931,7 +931,7 @@ describe API::Users, api: true do + user.save + expect do + delete api("/user/emails/#{email.id}", user) +- end.to change{user.emails.count}.by(-1) ++ end.to change { user.emails.count }.by(-1) + expect(response).to have_http_status(200) + end + +@@ -984,7 +984,7 @@ describe API::Users, api: true do + end + + describe 'PUT /users/:id/unblock' do +- let(:blocked_user) { create(:user, state: 'blocked') } ++ let(:blocked_user) { create(:user, state: 'blocked') } + before { admin } + + it 'unblocks existing user' do +@@ -1100,4 +1100,78 @@ describe API::Users, api: true do + expect(json_response['message']).to eq('404 User Not Found') + end + end ++ ++ context "user activities", :redis do ++ it_behaves_like 'a paginated resources' do ++ let(:request) { get api("/user/activities", admin) } ++ end ++ ++ context 'last activity as normal user' do ++ it 'has no permission' do ++ user.record_activity ++ ++ get api("/user/activities", user) ++ ++ expect(response).to have_http_status(403) ++ end ++ end ++ ++ context 'last activity as admin' do ++ it 'returns the last activity' do ++ allow(Time).to receive(:now).and_return(Time.new(2000, 1, 1)) ++ ++ user.record_activity ++ ++ get api("/user/activities", admin) ++ ++ activity = json_response.last ++ ++ expect(activity['username']).to eq(user.username) ++ expect(activity['last_activity_at']).to eq('2000-01-01 00:00:00') ++ end ++ end ++ ++ context 'last activities paginated', :redis do ++ let(:activity) { json_response.first } ++ let(:old_date) { 2.months.ago.to_date } ++ ++ before do ++ 5.times do |num| ++ Timecop.freeze(old_date + num) ++ ++ create(:user, username: num.to_s).record_activity ++ end ++ end ++ ++ after do ++ Timecop.return ++ end ++ ++ it 'returns 3 activities' do ++ get api("/user/activities?page=1&per_page=3", admin) ++ ++ expect(json_response.count).to eq(3) ++ end ++ ++ it 'contains the first activities' do ++ get api("/user/activities?page=1&per_page=3", admin) ++ ++ expect(json_response.map { |activity| activity['username'] }).to eq(%w[0 1 2]) ++ end ++ ++ it 'contains the last activities' do ++ get api("/user/activities?page=2&per_page=3", admin) ++ ++ expect(json_response.map { |activity| activity['username'] }).to eq(%w[3 4]) ++ end ++ ++ it 'contains activities created after user 3 was created' do ++ from = (old_date + 3).to_s("%Y-%m-%d") ++ ++ get api("/user/activities?page=1&per_page=5&from=#{from}", admin) ++ ++ expect(json_response.map { |activity| activity['username'] }).to eq(%w[3 4]) ++ end ++ end ++ end + end |