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
This commit is contained in:
commit
d318075aba
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
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'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# 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
|
||||||
# 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
|
||||||
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
|
||||||
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
|
||||||
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}"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
%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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
# 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
|
||||||
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|
|
||||||
|
|
||||||
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|
|
||||||
|
|
||||||
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|
|
||||||
|
|
||||||
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|
|
||||||
|
|
||||||
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|
|
||||||
|
|
||||||
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|
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue