Commit d318075a authored by Douwe Maan's avatar Douwe Maan

Merge branch 'rs-blocks-json-serialization' into 'master'

Add BlocksJsonSerialization model concern and include it in User

Closes #37947

See merge request gitlab-org/gitlab-ce!14350
parents febb0b9a 099e2742
...@@ -8,12 +8,12 @@ class AutocompleteController < ApplicationController ...@@ -8,12 +8,12 @@ class AutocompleteController < ApplicationController
def users def users
@users = AutocompleteUsersFinder.new(params: params, current_user: current_user, project: @project, group: @group).execute @users = AutocompleteUsersFinder.new(params: params, current_user: current_user, project: @project, group: @group).execute
render json: @users, only: [:name, :username, :id], methods: [:avatar_url] render json: UserSerializer.new.represent(@users)
end end
def user def user
@user = User.find(params[:id]) @user = User.find(params[:id])
render json: @user, only: [:name, :username, :id], methods: [:avatar_url] render json: UserSerializer.new.represent(@user)
end end
def projects def projects
......
...@@ -35,7 +35,7 @@ module FormHelper ...@@ -35,7 +35,7 @@ module FormHelper
multi_select: true, multi_select: true,
'input-meta': 'name', 'input-meta': 'name',
'always-show-selectbox': true, 'always-show-selectbox': true,
current_user_info: current_user.to_json(only: [:id, :name]) current_user_info: UserSerializer.new.represent(current_user)
} }
} }
end end
......
...@@ -362,7 +362,7 @@ module IssuablesHelper ...@@ -362,7 +362,7 @@ module IssuablesHelper
moveIssueEndpoint: move_namespace_project_issue_path(namespace_id: issuable.project.namespace.to_param, project_id: issuable.project, id: issuable), moveIssueEndpoint: move_namespace_project_issue_path(namespace_id: issuable.project.namespace.to_param, project_id: issuable.project, id: issuable),
projectsAutocompleteEndpoint: autocomplete_projects_path(project_id: @project.id), projectsAutocompleteEndpoint: autocomplete_projects_path(project_id: @project.id),
editable: can_edit_issuable, editable: can_edit_issuable,
currentUser: current_user.as_json(only: [:username, :id, :name], methods: :avatar_url), currentUser: UserSerializer.new.represent(current_user),
rootPath: root_path, rootPath: root_path,
fullPath: @project.full_path fullPath: @project.full_path
} }
......
...@@ -139,7 +139,7 @@ module SearchHelper ...@@ -139,7 +139,7 @@ module SearchHelper
id: "filtered-search-#{type}", id: "filtered-search-#{type}",
placeholder: 'Search or filter results...', placeholder: 'Search or filter results...',
data: { data: {
'username-params' => @users.to_json(only: [:id, :username]) 'username-params' => UserSerializer.new.represent(@users)
}, },
autocomplete: 'off' autocomplete: 'off'
} }
......
# Overrides `as_json` and `to_json` to raise an exception when called in order
# to prevent accidentally exposing attributes
#
# Not that that would ever happen... but just in case.
module BlocksJsonSerialization
extend ActiveSupport::Concern
JsonSerializationError = Class.new(StandardError)
def to_json(*)
raise JsonSerializationError,
"JSON serialization has been disabled on #{self.class.name}"
end
alias_method :as_json, :to_json
end
...@@ -24,7 +24,7 @@ module TimeTrackable ...@@ -24,7 +24,7 @@ module TimeTrackable
# rubocop:disable Gitlab/ModuleWithInstanceVariables # rubocop:disable Gitlab/ModuleWithInstanceVariables
def spend_time(options) def spend_time(options)
@time_spent = options[:duration] @time_spent = options[:duration]
@time_spent_user = options[:user] @time_spent_user = User.find(options[:user_id])
@spent_at = options[:spent_at] @spent_at = options[:spent_at]
@original_total_time_spent = nil @original_total_time_spent = nil
......
...@@ -18,6 +18,7 @@ class User < ActiveRecord::Base ...@@ -18,6 +18,7 @@ class User < ActiveRecord::Base
include CreatedAtFilterable include CreatedAtFilterable
include IgnorableColumn include IgnorableColumn
include BulkMemberAccessLoad include BulkMemberAccessLoad
include BlocksJsonSerialization
DEFAULT_NOTIFICATION_LEVEL = :participating DEFAULT_NOTIFICATION_LEVEL = :participating
......
...@@ -405,7 +405,7 @@ module QuickActions ...@@ -405,7 +405,7 @@ module QuickActions
if time_spent if time_spent
@updates[:spend_time] = { @updates[:spend_time] = {
duration: time_spent, duration: time_spent,
user: current_user, user_id: current_user.id,
spent_at: time_spent_date spent_at: time_spent_date
} }
end end
...@@ -428,7 +428,7 @@ module QuickActions ...@@ -428,7 +428,7 @@ module QuickActions
current_user.can?(:"admin_#{issuable.to_ability_name}", project) current_user.can?(:"admin_#{issuable.to_ability_name}", project)
end end
command :remove_time_spent do command :remove_time_spent do
@updates[:spend_time] = { duration: :reset, user: current_user } @updates[:spend_time] = { duration: :reset, user_id: current_user.id }
end end
desc "Append the comment with #{SHRUG}" desc "Append the comment with #{SHRUG}"
......
%board-sidebar{ "inline-template" => true, %board-sidebar{ "inline-template" => true, ":current-user" => (UserSerializer.new.represent(current_user) || {}).to_json }
":current-user" => "#{current_user ? current_user.to_json(only: [:username, :id, :name], methods: [:avatar_url]) : {}}" }
%transition{ name: "boards-sidebar-slide" } %transition{ name: "boards-sidebar-slide" }
%aside.right-sidebar.right-sidebar-expanded.issue-boards-sidebar{ "v-show" => "showSidebar" } %aside.right-sidebar.right-sidebar-expanded.issue-boards-sidebar{ "v-show" => "showSidebar" }
.issuable-sidebar .issuable-sidebar
......
...@@ -85,7 +85,7 @@ module API ...@@ -85,7 +85,7 @@ module API
update_issuable(spend_time: { update_issuable(spend_time: {
duration: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)), duration: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)),
user: current_user user_id: current_user.id
}) })
end end
...@@ -97,7 +97,7 @@ module API ...@@ -97,7 +97,7 @@ module API
authorize! update_issuable_key, load_issuable authorize! update_issuable_key, load_issuable
status :ok status :ok
update_issuable(spend_time: { duration: :reset, user: current_user }) update_issuable(spend_time: { duration: :reset, user_id: current_user.id })
end end
desc "Show time stats for a project #{issuable_name}" desc "Show time stats for a project #{issuable_name}"
......
...@@ -86,7 +86,7 @@ module API ...@@ -86,7 +86,7 @@ module API
update_issuable(spend_time: { update_issuable(spend_time: {
duration: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)), duration: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)),
user: current_user user_id: current_user.id
}) })
end end
...@@ -98,7 +98,7 @@ module API ...@@ -98,7 +98,7 @@ module API
authorize! update_issuable_key, load_issuable authorize! update_issuable_key, load_issuable
status :ok status :ok
update_issuable(spend_time: { duration: :reset, user: current_user }) update_issuable(spend_time: { duration: :reset, user_id: current_user.id })
end end
desc "Show time stats for a project #{issuable_name}" desc "Show time stats for a project #{issuable_name}"
......
...@@ -82,9 +82,9 @@ feature 'Milestone' do ...@@ -82,9 +82,9 @@ feature 'Milestone' do
milestone = create(:milestone, project: project, title: 8.7) milestone = create(:milestone, project: project, title: 8.7)
issue1 = create(:issue, project: project, milestone: milestone) issue1 = create(:issue, project: project, milestone: milestone)
issue2 = create(:issue, project: project, milestone: milestone) issue2 = create(:issue, project: project, milestone: milestone)
issue1.spend_time(duration: 3600, user: user) issue1.spend_time(duration: 3600, user_id: user.id)
issue1.save! issue1.save!
issue2.spend_time(duration: 7200, user: user) issue2.spend_time(duration: 7200, user_id: user.id)
issue2.save! issue2.save!
visit project_milestone_path(project, milestone) visit project_milestone_path(project, milestone)
......
require 'rails_helper'
describe BlocksJsonSerialization do
DummyModel = Class.new do
include BlocksJsonSerialization
end
it 'blocks as_json' do
expect { DummyModel.new.as_json }
.to raise_error(described_class::JsonSerializationError, /DummyModel/)
end
it 'blocks to_json' do
expect { DummyModel.new.to_json }
.to raise_error(described_class::JsonSerializationError, /DummyModel/)
end
end
...@@ -291,7 +291,7 @@ describe Issuable do ...@@ -291,7 +291,7 @@ describe Issuable do
context 'total_time_spent is updated' do context 'total_time_spent is updated' do
before do before do
issue.spend_time(duration: 2, user: user, spent_at: Time.now) issue.spend_time(duration: 2, user_id: user.id, spent_at: Time.now)
issue.save issue.save
expect(Gitlab::HookData::IssuableBuilder) expect(Gitlab::HookData::IssuableBuilder)
.to receive(:new).with(issue).and_return(builder) .to receive(:new).with(issue).and_return(builder)
...@@ -485,7 +485,7 @@ describe Issuable do ...@@ -485,7 +485,7 @@ describe Issuable do
let(:issue) { create(:issue) } let(:issue) { create(:issue) }
def spend_time(seconds) def spend_time(seconds)
issue.spend_time(duration: seconds, user: user) issue.spend_time(duration: seconds, user_id: user.id)
issue.save! issue.save!
end end
......
...@@ -189,9 +189,9 @@ describe Milestone, 'Milestoneish' do ...@@ -189,9 +189,9 @@ describe Milestone, 'Milestoneish' do
describe '#total_issue_time_spent' do describe '#total_issue_time_spent' do
it 'calculates total issue time spent' do it 'calculates total issue time spent' do
closed_issue_1.spend_time(duration: 300, user: author) closed_issue_1.spend_time(duration: 300, user_id: author.id)
closed_issue_1.save! closed_issue_1.save!
closed_issue_2.spend_time(duration: 600, user: assignee) closed_issue_2.spend_time(duration: 600, user_id: assignee.id)
closed_issue_2.save! closed_issue_2.save!
expect(milestone.total_issue_time_spent).to eq(900) expect(milestone.total_issue_time_spent).to eq(900)
......
...@@ -12,6 +12,7 @@ describe User do ...@@ -12,6 +12,7 @@ describe User do
it { is_expected.to include_module(Referable) } it { is_expected.to include_module(Referable) }
it { is_expected.to include_module(Sortable) } it { is_expected.to include_module(Sortable) }
it { is_expected.to include_module(TokenAuthenticatable) } it { is_expected.to include_module(TokenAuthenticatable) }
it { is_expected.to include_module(BlocksJsonSerialization) }
end end
describe 'delegations' do describe 'delegations' do
......
...@@ -209,7 +209,7 @@ describe QuickActions::InterpretService do ...@@ -209,7 +209,7 @@ describe QuickActions::InterpretService do
expect(updates).to eq(spend_time: { expect(updates).to eq(spend_time: {
duration: 3600, duration: 3600,
user: developer, user_id: developer.id,
spent_at: DateTime.now.to_date spent_at: DateTime.now.to_date
}) })
end end
...@@ -221,7 +221,7 @@ describe QuickActions::InterpretService do ...@@ -221,7 +221,7 @@ describe QuickActions::InterpretService do
expect(updates).to eq(spend_time: { expect(updates).to eq(spend_time: {
duration: -1800, duration: -1800,
user: developer, user_id: developer.id,
spent_at: DateTime.now.to_date spent_at: DateTime.now.to_date
}) })
end end
...@@ -233,7 +233,7 @@ describe QuickActions::InterpretService do ...@@ -233,7 +233,7 @@ describe QuickActions::InterpretService do
expect(updates).to eq(spend_time: { expect(updates).to eq(spend_time: {
duration: 1800, duration: 1800,
user: developer, user_id: developer.id,
spent_at: Date.parse(date) spent_at: Date.parse(date)
}) })
end end
...@@ -267,7 +267,7 @@ describe QuickActions::InterpretService do ...@@ -267,7 +267,7 @@ describe QuickActions::InterpretService do
it 'populates spend_time: :reset if content contains /remove_time_spent' do it 'populates spend_time: :reset if content contains /remove_time_spent' do
_, updates = service.execute(content, issuable) _, updates = service.execute(content, issuable)
expect(updates).to eq(spend_time: { duration: :reset, user: developer }) expect(updates).to eq(spend_time: { duration: :reset, user_id: developer.id })
end end
end end
......
...@@ -927,7 +927,7 @@ describe SystemNoteService do ...@@ -927,7 +927,7 @@ describe SystemNoteService do
# We need a custom noteable in order to the shared examples to be green. # We need a custom noteable in order to the shared examples to be green.
let(:noteable) do let(:noteable) do
mr = create(:merge_request, source_project: project) mr = create(:merge_request, source_project: project)
mr.spend_time(duration: 360000, user: author) mr.spend_time(duration: 360000, user_id: author.id)
mr.save! mr.save!
mr mr
end end
...@@ -965,7 +965,7 @@ describe SystemNoteService do ...@@ -965,7 +965,7 @@ describe SystemNoteService do
end end
def spend_time!(seconds) def spend_time!(seconds)
noteable.spend_time(duration: seconds, user: author) noteable.spend_time(duration: seconds, user_id: author.id)
noteable.save! noteable.save!
end end
end end
......
...@@ -79,7 +79,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| ...@@ -79,7 +79,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
context 'when subtracting time' do context 'when subtracting time' do
it 'subtracts time of the total spent time' do it 'subtracts time of the total spent time' do
issuable.update_attributes!(spend_time: { duration: 7200, user: user }) issuable.update_attributes!(spend_time: { duration: 7200, user_id: user.id })
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
duration: '-1h' duration: '-1h'
...@@ -91,7 +91,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| ...@@ -91,7 +91,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
context 'when time to subtract is greater than the total spent time' do context 'when time to subtract is greater than the total spent time' do
it 'does not modify the total time spent' do it 'does not modify the total time spent' do
issuable.update_attributes!(spend_time: { duration: 7200, user: user }) issuable.update_attributes!(spend_time: { duration: 7200, user_id: user.id })
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
duration: '-1w' duration: '-1w'
...@@ -119,7 +119,7 @@ shared_examples 'time tracking endpoints' do |issuable_name| ...@@ -119,7 +119,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
describe "GET /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_stats" do describe "GET /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_stats" do
it "returns the time stats for #{issuable_name}" do it "returns the time stats for #{issuable_name}" do
issuable.update_attributes!(spend_time: { duration: 1800, user: user }, issuable.update_attributes!(spend_time: { duration: 1800, user_id: user.id },
time_estimate: 3600) time_estimate: 3600)
get api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_stats", user) get api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_stats", user)
......
...@@ -75,7 +75,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name| ...@@ -75,7 +75,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
context 'when subtracting time' do context 'when subtracting time' do
it 'subtracts time of the total spent time' do it 'subtracts time of the total spent time' do
issuable.update_attributes!(spend_time: { duration: 7200, user: user }) issuable.update_attributes!(spend_time: { duration: 7200, user_id: user.id })
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/add_spent_time", user), post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/add_spent_time", user),
duration: '-1h' duration: '-1h'
...@@ -87,7 +87,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name| ...@@ -87,7 +87,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
context 'when time to subtract is greater than the total spent time' do context 'when time to subtract is greater than the total spent time' do
it 'does not modify the total time spent' do it 'does not modify the total time spent' do
issuable.update_attributes!(spend_time: { duration: 7200, user: user }) issuable.update_attributes!(spend_time: { duration: 7200, user_id: user.id })
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/add_spent_time", user), post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/add_spent_time", user),
duration: '-1w' duration: '-1w'
...@@ -115,7 +115,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name| ...@@ -115,7 +115,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
describe "GET /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_stats" do describe "GET /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_stats" do
it "returns the time stats for #{issuable_name}" do it "returns the time stats for #{issuable_name}" do
issuable.update_attributes!(spend_time: { duration: 1800, user: user }, issuable.update_attributes!(spend_time: { duration: 1800, user_id: user.id },
time_estimate: 3600) time_estimate: 3600)
get v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/time_stats", user) get v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/time_stats", user)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment