summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/profiles/emails_controller_spec.rb37
-rw-r--r--spec/features/admin/admin_users_spec.rb3
-rw-r--r--spec/features/dashboard/datetime_on_tooltips_spec.rb35
-rw-r--r--spec/frontend/design_management/components/design_todo_button_spec.js32
-rw-r--r--spec/frontend/header_spec.js2
-rw-r--r--spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap14
-rw-r--r--spec/frontend/packages/shared/components/__snapshots__/publish_method_spec.js.snap2
-rw-r--r--spec/frontend/tooltips/components/tooltips_spec.js44
-rw-r--r--spec/frontend/tooltips/index_spec.js39
-rw-r--r--spec/helpers/issuables_helper_spec.rb1
-rw-r--r--spec/lib/gitlab/graphql/docs/renderer_spec.rb48
-rw-r--r--spec/rubocop/cop/static_translation_definition_spec.rb25
-rw-r--r--spec/workers/ci_platform_metrics_update_cron_worker_spec.rb15
13 files changed, 249 insertions, 48 deletions
diff --git a/spec/controllers/profiles/emails_controller_spec.rb b/spec/controllers/profiles/emails_controller_spec.rb
index 246f8a6cd76..08552cc28fa 100644
--- a/spec/controllers/profiles/emails_controller_spec.rb
+++ b/spec/controllers/profiles/emails_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Profiles::EmailsController do
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
before do
sign_in(user)
@@ -16,36 +16,43 @@ RSpec.describe Profiles::EmailsController do
end
describe '#create' do
- context 'when email address is valid' do
- let(:email_params) { { email: "add_email@example.com" } }
+ let(:email) { 'add_email@example.com' }
+ let(:params) { { email: { email: email } } }
- it 'sends an email confirmation' do
- expect { post(:create, params: { email: email_params }) }.to change { ActionMailer::Base.deliveries.size }
- end
+ subject { post(:create, params: params) }
+
+ it 'sends an email confirmation' do
+ expect { subject }.to change { ActionMailer::Base.deliveries.size }
end
context 'when email address is invalid' do
- let(:email_params) { { email: "test.@example.com" } }
+ let(:email) { 'invalid.@example.com' }
it 'does not send an email confirmation' do
- expect { post(:create, params: { email: email_params }) }.not_to change { ActionMailer::Base.deliveries.size }
+ expect { subject }.not_to change { ActionMailer::Base.deliveries.size }
end
end
end
describe '#resend_confirmation_instructions' do
- let(:email_params) { { email: "add_email@example.com" } }
+ let_it_be(:email) { create(:email, user: user) }
+ let(:params) { { id: email.id } }
+
+ subject { put(:resend_confirmation_instructions, params: params) }
it 'resends an email confirmation' do
- email = user.emails.create(email: 'add_email@example.com')
+ expect { subject }.to change { ActionMailer::Base.deliveries.size }
- expect { put(:resend_confirmation_instructions, params: { id: email }) }.to change { ActionMailer::Base.deliveries.size }
- expect(ActionMailer::Base.deliveries.last.to).to eq [email_params[:email]]
- expect(ActionMailer::Base.deliveries.last.subject).to match "Confirmation instructions"
+ expect(ActionMailer::Base.deliveries.last.to).to eq [email.email]
+ expect(ActionMailer::Base.deliveries.last.subject).to match 'Confirmation instructions'
end
- it 'unable to resend an email confirmation' do
- expect { put(:resend_confirmation_instructions, params: { id: 1 }) }.not_to change { ActionMailer::Base.deliveries.size }
+ context 'email does not exist' do
+ let(:params) { { id: non_existing_record_id } }
+
+ it 'does not send an email confirmation' do
+ expect { subject }.not_to change { ActionMailer::Base.deliveries.size }
+ end
end
end
end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 9bfd3319ff1..55c92fa353e 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -279,7 +279,8 @@ RSpec.describe "Admin::Users" do
expect(page).to have_content(user.email)
expect(page).to have_content(user.name)
- expect(page).to have_content(user.id)
+ expect(page).to have_content("ID: #{user.id}")
+ expect(page).to have_content("Namespace ID: #{user.namespace_id}")
expect(page).to have_button('Deactivate user')
expect(page).to have_button('Block user')
expect(page).to have_button('Delete user')
diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb
index ed28ec6099d..a3eacd6147c 100644
--- a/spec/features/dashboard/datetime_on_tooltips_spec.rb
+++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb
@@ -3,44 +3,53 @@
require 'spec_helper'
RSpec.describe 'Tooltips on .timeago dates', :js do
- let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
- let(:created_date) { Date.yesterday.to_time }
- let(:expected_format) { created_date.in_time_zone.strftime('%b %-d, %Y %l:%M%P') }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, name: 'test', namespace: user.namespace) }
+ let(:created_date) { 1.day.ago.beginning_of_minute - 1.hour }
+
+ before_all do
+ project.add_maintainer(user)
+ end
context 'on the activity tab' do
before do
- project.add_maintainer(user)
-
Event.create( project: project, author_id: user.id, action: :joined,
updated_at: created_date, created_at: created_date)
sign_in user
visit user_activity_path(user)
wait_for_requests
-
- page.find('.js-timeago').hover
end
it 'has the datetime formated correctly' do
- expect(page).to have_selector('.local-timeago', text: expected_format)
+ expect(page).to have_selector('.js-timeago', text: '1 day ago')
+
+ page.find('.js-timeago').hover
+
+ expect(datetime_in_tooltip).to eq(created_date)
end
end
context 'on the snippets tab' do
before do
- project.add_maintainer(user)
create(:snippet, author: user, updated_at: created_date, created_at: created_date)
sign_in user
visit user_snippets_path(user)
wait_for_requests
-
- page.find('.js-timeago.snippet-created-ago').hover
end
it 'has the datetime formated correctly' do
- expect(page).to have_selector('.local-timeago', text: expected_format)
+ expect(page).to have_selector('.js-timeago.snippet-created-ago', text: '1 day ago')
+
+ page.find('.js-timeago.snippet-created-ago').hover
+
+ expect(datetime_in_tooltip).to eq(created_date)
end
end
+
+ def datetime_in_tooltip
+ datetime_text = page.find('.local-timeago').text
+ DateTime.parse(datetime_text)
+ end
end
diff --git a/spec/frontend/design_management/components/design_todo_button_spec.js b/spec/frontend/design_management/components/design_todo_button_spec.js
index 950876108ee..451c23f0fea 100644
--- a/spec/frontend/design_management/components/design_todo_button_spec.js
+++ b/spec/frontend/design_management/components/design_todo_button_spec.js
@@ -52,6 +52,7 @@ describe('Design management design todo button', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
+ jest.clearAllMocks();
});
it('renders TodoButton component', () => {
@@ -68,7 +69,14 @@ describe('Design management design todo button', () => {
});
describe('when clicked', () => {
+ let dispatchEventSpy;
+
beforeEach(() => {
+ dispatchEventSpy = jest.spyOn(document, 'dispatchEvent');
+ jest.spyOn(document, 'querySelector').mockReturnValue({
+ innerText: 2,
+ });
+
createComponent({ design: mockDesignWithPendingTodos }, { mountFn: mount });
wrapper.trigger('click');
return wrapper.vm.$nextTick();
@@ -86,6 +94,14 @@ describe('Design management design todo button', () => {
expect(mutate).toHaveBeenCalledTimes(1);
expect(mutate).toHaveBeenCalledWith(todoMarkDoneMutationVariables);
});
+
+ it('calls dispatchDocumentEvent to update global To-Do counter correctly', () => {
+ const dispatchedEvent = dispatchEventSpy.mock.calls[0][0];
+
+ expect(dispatchEventSpy).toHaveBeenCalledTimes(1);
+ expect(dispatchedEvent.detail).toEqual({ count: 1 });
+ expect(dispatchedEvent.type).toBe('todo:toggle');
+ });
});
});
@@ -99,7 +115,14 @@ describe('Design management design todo button', () => {
});
describe('when clicked', () => {
+ let dispatchEventSpy;
+
beforeEach(() => {
+ dispatchEventSpy = jest.spyOn(document, 'dispatchEvent');
+ jest.spyOn(document, 'querySelector').mockReturnValue({
+ innerText: 2,
+ });
+
createComponent({}, { mountFn: mount });
wrapper.trigger('click');
return wrapper.vm.$nextTick();
@@ -112,6 +135,7 @@ describe('Design management design todo button', () => {
variables: {
atVersion: null,
filenames: ['my-design.jpg'],
+ designId: '1',
issueId: '1',
issueIid: '10',
projectPath: 'project-path',
@@ -121,6 +145,14 @@ describe('Design management design todo button', () => {
expect(mutate).toHaveBeenCalledTimes(1);
expect(mutate).toHaveBeenCalledWith(createDesignTodoMutationVariables);
});
+
+ it('calls dispatchDocumentEvent to update global To-Do counter correctly', () => {
+ const dispatchedEvent = dispatchEventSpy.mock.calls[0][0];
+
+ expect(dispatchEventSpy).toHaveBeenCalledTimes(1);
+ expect(dispatchedEvent.detail).toEqual({ count: 3 });
+ expect(dispatchedEvent.type).toBe('todo:toggle');
+ });
});
});
});
diff --git a/spec/frontend/header_spec.js b/spec/frontend/header_spec.js
index 59a8ca2ed23..27305abfafa 100644
--- a/spec/frontend/header_spec.js
+++ b/spec/frontend/header_spec.js
@@ -4,7 +4,7 @@ import initTodoToggle, { initNavUserDropdownTracking } from '~/header';
describe('Header', () => {
describe('Todos notification', () => {
- const todosPendingCount = '.todos-count';
+ const todosPendingCount = '.js-todos-count';
const fixtureTemplate = 'issues/open-issue.html';
function isTodosCountHidden() {
diff --git a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
index 4b1346925cc..6aaefed92d0 100644
--- a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
+++ b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
@@ -40,7 +40,7 @@ exports[`packages_list_row renders 1`] = `
</div>
<div
- class="gl-text-gray-500 gl-mt-1 gl-min-h-6 gl-min-w-0 gl-flex-fill-1"
+ class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1 gl-min-h-6 gl-min-w-0 gl-flex-fill-1"
>
<div
class="gl-display-flex"
@@ -94,7 +94,7 @@ exports[`packages_list_row renders 1`] = `
class="gl-display-flex gl-flex-direction-column gl-sm-align-items-flex-end gl-justify-content-space-between gl-text-gray-500 gl-flex-shrink-0"
>
<div
- class="gl-sm-text-body gl-sm-font-weight-bold gl-min-h-6"
+ class="gl-display-flex gl-align-items-center gl-sm-text-body gl-sm-font-weight-bold gl-min-h-6"
>
<publish-method-stub
packageentity="[object Object]"
@@ -102,11 +102,13 @@ exports[`packages_list_row renders 1`] = `
</div>
<div
- class="gl-mt-1 gl-min-h-6"
+ class="gl-display-flex gl-align-items-center gl-mt-1 gl-min-h-6"
>
- <gl-sprintf-stub
- message="Created %{timestamp}"
- />
+ <span>
+ <gl-sprintf-stub
+ message="Created %{timestamp}"
+ />
+ </span>
</div>
</div>
</div>
diff --git a/spec/frontend/packages/shared/components/__snapshots__/publish_method_spec.js.snap b/spec/frontend/packages/shared/components/__snapshots__/publish_method_spec.js.snap
index 55ac86f9c49..9a0c52cee47 100644
--- a/spec/frontend/packages/shared/components/__snapshots__/publish_method_spec.js.snap
+++ b/spec/frontend/packages/shared/components/__snapshots__/publish_method_spec.js.snap
@@ -2,7 +2,7 @@
exports[`publish_method renders 1`] = `
<div
- class="gl-display-flex gl-align-items-center gl-mb-2"
+ class="gl-display-flex gl-align-items-center"
>
<gl-icon-stub
class="gl-mr-2"
diff --git a/spec/frontend/tooltips/components/tooltips_spec.js b/spec/frontend/tooltips/components/tooltips_spec.js
index 1a97c7c9111..0edc5248629 100644
--- a/spec/frontend/tooltips/components/tooltips_spec.js
+++ b/spec/frontend/tooltips/components/tooltips_spec.js
@@ -120,7 +120,7 @@ describe('tooltips/components/tooltips.vue', () => {
wrapper.vm.addTooltips([target, createTooltipTarget()]);
await wrapper.vm.$nextTick();
- wrapper.vm.dispose([target]);
+ wrapper.vm.dispose(target);
await wrapper.vm.$nextTick();
expect(allTooltips()).toHaveLength(1);
@@ -148,6 +148,48 @@ describe('tooltips/components/tooltips.vue', () => {
});
});
+ describe('triggerEvent', () => {
+ it('triggers a bootstrap-vue tooltip global event for the tooltip specified', async () => {
+ const target = createTooltipTarget();
+ const event = 'hide';
+
+ buildWrapper();
+
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ wrapper.vm.triggerEvent(target, event);
+
+ expect(wrapper.find(GlTooltip).emitted(event)).toHaveLength(1);
+ });
+ });
+
+ describe('fixTitle', () => {
+ it('updates tooltip content with the latest value the target title property', async () => {
+ const target = createTooltipTarget();
+ const currentTitle = 'title';
+ const newTitle = 'new title';
+
+ target.setAttribute('title', currentTitle);
+
+ buildWrapper();
+
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).text()).toBe(currentTitle);
+
+ target.setAttribute('title', newTitle);
+ wrapper.vm.fixTitle(target);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).text()).toBe(newTitle);
+ });
+ });
+
it('disconnects mutation observer on beforeDestroy', () => {
buildWrapper();
wrapper.vm.addTooltips([createTooltipTarget()]);
diff --git a/spec/frontend/tooltips/index_spec.js b/spec/frontend/tooltips/index_spec.js
index a304ffce0a5..2b75707caed 100644
--- a/spec/frontend/tooltips/index_spec.js
+++ b/spec/frontend/tooltips/index_spec.js
@@ -1,4 +1,4 @@
-import { initTooltips, dispose, destroy } from '~/tooltips';
+import { initTooltips, dispose, destroy, hide, show, enable, disable, fixTitle } from '~/tooltips';
describe('tooltips/index.js', () => {
let tooltipsApp;
@@ -80,4 +80,41 @@ describe('tooltips/index.js', () => {
expect(document.querySelector('.gl-tooltip')).toBe(null);
});
});
+
+ it.each`
+ methodName | method | event
+ ${'enable'} | ${enable} | ${'enable'}
+ ${'disable'} | ${disable} | ${'disable'}
+ ${'hide'} | ${hide} | ${'close'}
+ ${'show'} | ${show} | ${'open'}
+ `(
+ '$methodName calls triggerEvent in tooltip app with $event event',
+ async ({ method, event }) => {
+ const target = createTooltipTarget();
+
+ buildTooltipsApp();
+
+ await tooltipsApp.$nextTick();
+
+ jest.spyOn(tooltipsApp, 'triggerEvent');
+
+ method([target]);
+
+ expect(tooltipsApp.triggerEvent).toHaveBeenCalledWith(target, event);
+ },
+ );
+
+ it('fixTitle calls fixTitle in tooltip app with the target specified', async () => {
+ const target = createTooltipTarget();
+
+ buildTooltipsApp();
+
+ await tooltipsApp.$nextTick();
+
+ jest.spyOn(tooltipsApp, 'fixTitle');
+
+ fixTitle([target]);
+
+ expect(tooltipsApp.fixTitle).toHaveBeenCalledWith(target);
+ });
});
diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb
index 1f47ec4bf97..89a2a92ea57 100644
--- a/spec/helpers/issuables_helper_spec.rb
+++ b/spec/helpers/issuables_helper_spec.rb
@@ -198,6 +198,7 @@ RSpec.describe IssuablesHelper do
initialDescriptionHtml: '<p dir="auto">issue text</p>',
initialDescriptionText: 'issue text',
initialTaskStatus: '0 of 0 tasks completed',
+ issueType: 'issue',
iid: issue.iid.to_s
}
expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data))
diff --git a/spec/lib/gitlab/graphql/docs/renderer_spec.rb b/spec/lib/gitlab/graphql/docs/renderer_spec.rb
index 81ef7fcda97..0f0127819fa 100644
--- a/spec/lib/gitlab/graphql/docs/renderer_spec.rb
+++ b/spec/lib/gitlab/graphql/docs/renderer_spec.rb
@@ -36,10 +36,10 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
specify do
expectation = <<~DOC
- ## ArrayTest
+ ### ArrayTest
- | Name | Type | Description |
- | --- | ---- | ---------- |
+ | Field | Type | Description |
+ | ----- | ---- | ----------- |
| `foo` | String! => Array | A description |
DOC
@@ -59,10 +59,10 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
specify do
expectation = <<~DOC
- ## OrderingTest
+ ### OrderingTest
- | Name | Type | Description |
- | --- | ---- | ---------- |
+ | Field | Type | Description |
+ | ----- | ---- | ----------- |
| `bar` | String! | A description of bar field |
| `foo` | String! | A description of foo field |
DOC
@@ -82,15 +82,45 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
specify do
expectation = <<~DOC
- ## DeprecatedTest
+ ### DeprecatedTest
- | Name | Type | Description |
- | --- | ---- | ---------- |
+ | Field | Type | Description |
+ | ----- | ---- | ----------- |
| `foo` **{warning-solid}** | String! | **Deprecated:** This is deprecated. Deprecated in 1.10 |
DOC
is_expected.to include(expectation)
end
end
+
+ context 'A type with an emum field' do
+ let(:type) do
+ enum_type = Class.new(Types::BaseEnum) do
+ graphql_name 'MyEnum'
+
+ value 'BAZ', description: 'A description of BAZ'
+ value 'BAR', description: 'A description of BAR', deprecation_reason: 'This is deprecated'
+ end
+
+ Class.new(Types::BaseObject) do
+ graphql_name 'EnumTest'
+
+ field :foo, enum_type, null: false, description: 'A description of foo field'
+ end
+ end
+
+ specify do
+ expectation = <<~DOC
+ ### MyEnum
+
+ | Value | Description |
+ | ----- | ----------- |
+ | `BAR` **{warning-solid}** | **Deprecated:** This is deprecated |
+ | `BAZ` | A description of BAZ |
+ DOC
+
+ is_expected.to include(expectation)
+ end
+ end
end
end
diff --git a/spec/rubocop/cop/static_translation_definition_spec.rb b/spec/rubocop/cop/static_translation_definition_spec.rb
index b6c9f6a25df..f3185def3d7 100644
--- a/spec/rubocop/cop/static_translation_definition_spec.rb
+++ b/spec/rubocop/cop/static_translation_definition_spec.rb
@@ -40,6 +40,17 @@ RSpec.describe RuboCop::Cop::StaticTranslationDefinition, type: :rubocop do
['C = n_("c")', 'n_("c")', 1],
[
<<~CODE,
+ class MyClass
+ def self.translations
+ @cache ||= { hello: _("hello") }
+ end
+ end
+ CODE
+ '_("hello")',
+ 3
+ ],
+ [
+ <<~CODE,
module MyModule
A = {
b: {
@@ -79,6 +90,20 @@ RSpec.describe RuboCop::Cop::StaticTranslationDefinition, type: :rubocop do
'CONSTANT_2 = s__("a")',
'CONSTANT_3 = n__("a")',
<<~CODE,
+ class MyClass
+ def self.method
+ @cache ||= { hello: -> { _("hello") } }
+ end
+ end
+ CODE
+ <<~CODE,
+ class MyClass
+ def method
+ @cache ||= { hello: _("hello") }
+ end
+ end
+ CODE
+ <<~CODE,
def method
s_('a')
end
diff --git a/spec/workers/ci_platform_metrics_update_cron_worker_spec.rb b/spec/workers/ci_platform_metrics_update_cron_worker_spec.rb
new file mode 100644
index 00000000000..0bb6822a0a5
--- /dev/null
+++ b/spec/workers/ci_platform_metrics_update_cron_worker_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CiPlatformMetricsUpdateCronWorker, type: :worker do
+ describe '#perform' do
+ subject { described_class.new.perform }
+
+ it 'inserts new platform metrics' do
+ expect(CiPlatformMetric).to receive(:insert_auto_devops_platform_targets!).and_call_original
+
+ subject
+ end
+ end
+end