diff options
-rw-r--r-- | app/assets/stylesheets/framework/header.scss | 5 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/search.scss | 7 | ||||
-rw-r--r-- | app/models/note.rb | 1 | ||||
-rw-r--r-- | app/services/notes/create_service.rb | 7 | ||||
-rw-r--r-- | app/workers/new_note_worker.rb | 12 | ||||
-rw-r--r-- | changelogs/unreleased/new-note-worker-record-not-found-fix.yml | 4 | ||||
-rw-r--r-- | doc/administration/high_availability/redis.md | 10 | ||||
-rw-r--r-- | doc/development/README.md | 2 | ||||
-rw-r--r-- | doc/integration/README.md | 2 | ||||
-rw-r--r-- | spec/services/notes/create_service_spec.rb | 37 | ||||
-rw-r--r-- | spec/workers/new_note_worker_spec.rb | 49 |
11 files changed, 118 insertions, 18 deletions
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 5a34132112a..7f226b7920d 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -63,6 +63,7 @@ header { &:focus, &:active { background-color: $background-color; + color: darken($gl-icon-color, 50%); } .fa-caret-down { @@ -191,6 +192,10 @@ header { font-size: 10px; text-align: center; cursor: pointer; + + &:hover { + color: darken($color: $gl-text-color, $amount: 50%); + } } .project-item-select { diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index b4761df3f23..a0108bba6d9 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -21,6 +21,11 @@ padding: 4px; width: $search-input-width; line-height: 24px; + + &:hover { + border-color: lighten($dropdown-input-focus-border, 20%); + box-shadow: 0 0 4px lighten($search-input-focus-shadow-color, 20%); + } } .location-text { @@ -153,6 +158,7 @@ width: 68%; } } + } .search-holder { @@ -229,4 +235,5 @@ &:focus { color: $gl-link-color; } + } diff --git a/app/models/note.rb b/app/models/note.rb index 2d644b03e4d..9ff5e308ed2 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -7,6 +7,7 @@ class Note < ActiveRecord::Base include Importable include FasterCacheKeys include CacheMarkdownField + include AfterCommitQueue cache_markdown_field :note, pipeline: :note diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb index 723cc0e6834..e338792412b 100644 --- a/app/services/notes/create_service.rb +++ b/app/services/notes/create_service.rb @@ -26,9 +26,12 @@ module Notes note.note = content end - if !only_commands && note.save + note.run_after_commit do # Finish the harder work in the background - NewNoteWorker.perform_in(2.seconds, note.id, params) + NewNoteWorker.perform_async(note.id) + end + + if !only_commands && note.save todo_service.new_note(note, current_user) end diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb index c3e62bb88c0..66574d0fd01 100644 --- a/app/workers/new_note_worker.rb +++ b/app/workers/new_note_worker.rb @@ -2,10 +2,12 @@ class NewNoteWorker include Sidekiq::Worker include DedicatedSidekiqQueue - def perform(note_id, note_params) - note = Note.find(note_id) - - NotificationService.new.new_note(note) - Notes::PostProcessService.new(note).execute + def perform(note_id) + if note = Note.find_by(id: note_id) + NotificationService.new.new_note(note) + Notes::PostProcessService.new(note).execute + else + Rails.logger.error("NewNoteWorker: couldn't find note with ID=#{note_id}, skipping job") + end end end diff --git a/changelogs/unreleased/new-note-worker-record-not-found-fix.yml b/changelogs/unreleased/new-note-worker-record-not-found-fix.yml new file mode 100644 index 00000000000..abfba640cc0 --- /dev/null +++ b/changelogs/unreleased/new-note-worker-record-not-found-fix.yml @@ -0,0 +1,4 @@ +--- +title: Fix record not found error on NewNoteWorker processing +merge_request: 6863 +author: Oswaldo Ferreira diff --git a/doc/administration/high_availability/redis.md b/doc/administration/high_availability/redis.md index bc424330656..8656b42f274 100644 --- a/doc/administration/high_availability/redis.md +++ b/doc/administration/high_availability/redis.md @@ -48,15 +48,15 @@ Redis. redis['password'] = 'Redis Password' ``` -1. Run `sudo gitlab-ctl reconfigure` to install and configure PostgreSQL. +1. Run `sudo touch /etc/gitlab/skip-auto-migrations` to prevent database migrations + from running on upgrade. Only the primary GitLab application server should + handle migrations. + +1. Run `sudo gitlab-ctl reconfigure` to install and configure Redis. > **Note**: This `reconfigure` step will result in some errors. That's OK - don't be alarmed. -1. Run `touch /etc/gitlab/skip-auto-migrations` to prevent database migrations - from running on upgrade. Only the primary GitLab application server should - handle migrations. - ## Experimental Redis Sentinel support > [Introduced][ce-1877] in GitLab 8.11. diff --git a/doc/development/README.md b/doc/development/README.md index 87306b1501d..f88456a7a7a 100644 --- a/doc/development/README.md +++ b/doc/development/README.md @@ -14,7 +14,7 @@ contributing to documentation. - [SQL Migration Style Guide](migration_style_guide.md) for creating safe SQL migrations - [Testing standards and style guidelines](testing.md) -- [UX guide](ux_guide/README.md) for building GitLab with existing CSS styles and elements +- [UX guide](ux_guide/index.md) for building GitLab with existing CSS styles and elements - [Frontend guidelines](frontend.md) - [SQL guidelines](sql.md) for working with SQL queries - [Sidekiq guidelines](sidekiq_style_guide.md) for working with Sidekiq workers diff --git a/doc/integration/README.md b/doc/integration/README.md index c2fd299db07..77bea3d2ceb 100644 --- a/doc/integration/README.md +++ b/doc/integration/README.md @@ -44,7 +44,7 @@ This [resource](http://kb.kerio.com/product/kerio-connect/server-configuration/s has all the information you need to add a certificate to the main trusted chain. This [answer](http://superuser.com/questions/437330/how-do-you-add-a-certificate-authority-ca-to-ubuntu) -at SuperUser also has relevant information. +at Super User also has relevant information. **Omnibus Trusted Chain** diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb index 93885c84dc3..25804696d2e 100644 --- a/spec/services/notes/create_service_spec.rb +++ b/spec/services/notes/create_service_spec.rb @@ -14,12 +14,41 @@ describe Notes::CreateService, services: true do end context "valid params" do - before do - @note = Notes::CreateService.new(project, user, opts).execute + it 'returns a valid note' do + note = Notes::CreateService.new(project, user, opts).execute + + expect(note).to be_valid + end + + it 'returns a persisted note' do + note = Notes::CreateService.new(project, user, opts).execute + + expect(note).to be_persisted + end + + it 'note has valid content' do + note = Notes::CreateService.new(project, user, opts).execute + + expect(note.note).to eq(opts[:note]) end - it { expect(@note).to be_valid } - it { expect(@note.note).to eq(opts[:note]) } + it 'TodoService#new_note is called' do + note = build(:note) + allow(project).to receive_message_chain(:notes, :new).with(opts) { note } + + expect_any_instance_of(TodoService).to receive(:new_note).with(note, user) + + Notes::CreateService.new(project, user, opts).execute + end + + it 'enqueues NewNoteWorker' do + note = build(:note, id: 999) + allow(project).to receive_message_chain(:notes, :new).with(opts) { note } + + expect(NewNoteWorker).to receive(:perform_async).with(note.id) + + Notes::CreateService.new(project, user, opts).execute + end end describe 'note with commands' do diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb new file mode 100644 index 00000000000..8fdbb35afd0 --- /dev/null +++ b/spec/workers/new_note_worker_spec.rb @@ -0,0 +1,49 @@ +require "spec_helper" + +describe NewNoteWorker do + context 'when Note found' do + let(:note) { create(:note) } + + it "calls NotificationService#new_note" do + expect_any_instance_of(NotificationService).to receive(:new_note).with(note) + + described_class.new.perform(note.id) + end + + it "calls Notes::PostProcessService#execute" do + notes_post_process_service = double(Notes::PostProcessService) + allow(Notes::PostProcessService).to receive(:new).with(note) { notes_post_process_service } + + expect(notes_post_process_service).to receive(:execute) + + described_class.new.perform(note.id) + end + end + + context 'when Note not found' do + let(:unexistent_note_id) { 999 } + + it 'logs NewNoteWorker process skipping' do + expect(Rails.logger).to receive(:error). + with("NewNoteWorker: couldn't find note with ID=999, skipping job") + + described_class.new.perform(unexistent_note_id) + end + + it 'does not raise errors' do + expect { described_class.new.perform(unexistent_note_id) }.not_to raise_error + end + + it "does not call NotificationService#new_note" do + expect_any_instance_of(NotificationService).not_to receive(:new_note) + + described_class.new.perform(unexistent_note_id) + end + + it "does not call Notes::PostProcessService#execute" do + expect_any_instance_of(Notes::PostProcessService).not_to receive(:execute) + + described_class.new.perform(unexistent_note_id) + end + end +end |