summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2018-09-03 13:16:23 +0000
committerPhil Hughes <me@iamphill.com>2018-09-03 13:16:23 +0000
commita4fc370c9b26f44ac05161e8a0e1c7e39f3925b0 (patch)
treee2ff2db449f186d5c2dcb9da055d75851af6ab5a
parentc0625e5de1fe491675aadf825fdb9e976f089409 (diff)
parent743add978aafa43862867a89b00a04e888199947 (diff)
downloadgitlab-ce-a4fc370c9b26f44ac05161e8a0e1c7e39f3925b0.tar.gz
Merge branch 'winh-move-badge-settings' into 'master'
Move badge settings to general settings Closes #46590 See merge request gitlab-org/gitlab-ce!21333
-rw-r--r--app/assets/javascripts/badges/components/badge_form.vue105
-rw-r--r--app/assets/javascripts/badges/components/badge_list.vue2
-rw-r--r--app/assets/javascripts/badges/components/badge_list_row.vue10
-rw-r--r--app/assets/javascripts/pages/groups/edit/index.js7
-rw-r--r--app/assets/javascripts/pages/projects/edit/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/settings/badges/index/index.js10
-rw-r--r--app/controllers/groups/settings/badges_controller.rb13
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/projects/settings/badges_controller.rb13
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/views/groups/edit.html.haml12
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml6
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml5
-rw-r--r--app/views/projects/edit.html.haml12
-rw-r--r--changelogs/unreleased/winh-move-badge-settings.yml5
-rw-r--r--config/routes/group.rb1
-rw-r--r--config/routes/project.rb1
-rw-r--r--doc/user/project/badges.md4
-rw-r--r--locale/gitlab.pot24
-rw-r--r--spec/controllers/groups_controller_spec.rb10
-rw-r--r--spec/controllers/projects_controller_spec.rb13
-rw-r--r--spec/features/groups/settings/group_badges_spec.rb2
-rw-r--r--spec/features/projects/settings/project_badges_spec.rb2
-rw-r--r--spec/javascripts/badges/components/badge_form_spec.js150
24 files changed, 242 insertions, 172 deletions
diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue
index 7a13f74c570..b3f25da87ce 100644
--- a/app/assets/javascripts/badges/components/badge_form.vue
+++ b/app/assets/javascripts/badges/components/badge_form.vue
@@ -23,6 +23,11 @@ export default {
required: true,
},
},
+ data() {
+ return {
+ wasValidated: false,
+ };
+ },
computed: {
...mapState([
'badgeInAddForm',
@@ -39,16 +44,6 @@ export default {
return this.badgeInAddForm;
},
- canSubmit() {
- return (
- this.badge !== null &&
- this.badge.imageUrl &&
- this.badge.imageUrl.trim() !== '' &&
- this.badge.linkUrl &&
- this.badge.linkUrl.trim() !== '' &&
- !this.isSaving
- );
- },
helpText() {
const placeholders = ['project_path', 'project_id', 'default_branch', 'commit_sha']
.map(placeholder => `<code>%{${placeholder}}</code>`)
@@ -93,11 +88,18 @@ export default {
});
},
},
- submitButtonLabel() {
- if (this.isEditing) {
- return s__('Badges|Save changes');
- }
- return s__('Badges|Add badge');
+ badgeImageUrlExample() {
+ const exampleUrl =
+ 'https://example.gitlab.com/%{project_path}/badges/%{default_branch}/badge.svg';
+ return sprintf(s__('Badges|e.g. %{exampleUrl}'), {
+ exampleUrl,
+ });
+ },
+ badgeLinkUrlExample() {
+ const exampleUrl = 'https://example.gitlab.com/%{project_path}';
+ return sprintf(s__('Badges|e.g. %{exampleUrl}'), {
+ exampleUrl,
+ });
},
},
methods: {
@@ -109,7 +111,9 @@ export default {
this.stopEditing();
},
onSubmit() {
- if (!this.canSubmit) {
+ const form = this.$el;
+ if (!form.checkValidity()) {
+ this.wasValidated = true;
return Promise.resolve();
}
@@ -117,6 +121,7 @@ export default {
return this.saveBadge()
.then(() => {
createFlash(s__('Badges|The badge was saved.'), 'notice');
+ this.wasValidated = false;
})
.catch(error => {
createFlash(
@@ -129,6 +134,7 @@ export default {
return this.addBadge()
.then(() => {
createFlash(s__('Badges|A new badge was added.'), 'notice');
+ this.wasValidated = false;
})
.catch(error => {
createFlash(
@@ -138,47 +144,58 @@ export default {
});
},
},
- badgeImageUrlPlaceholder:
- 'https://example.gitlab.com/%{project_path}/badges/%{default_branch}/<badge>.svg',
- badgeLinkUrlPlaceholder: 'https://example.gitlab.com/%{project_path}',
};
</script>
<template>
<form
- class="prepend-top-default append-bottom-default"
+ :class="{ 'was-validated': wasValidated }"
+ class="prepend-top-default append-bottom-default needs-validation"
+ novalidate
@submit.prevent.stop="onSubmit"
>
<div class="form-group">
- <label for="badge-link-url">{{ s__('Badges|Link') }}</label>
+ <label
+ for="badge-link-url"
+ class="label-bold"
+ >{{ s__('Badges|Link') }}</label>
+ <p v-html="helpText"></p>
<input
id="badge-link-url"
v-model="linkUrl"
- :placeholder="$options.badgeLinkUrlPlaceholder"
- type="text"
+ type="URL"
class="form-control"
+ required
@input="debouncedPreview"
/>
- <span
- class="form-text text-muted"
- v-html="helpText"
- ></span>
+ <div class="invalid-feedback">
+ {{ s__('Badges|Please fill in a valid URL') }}
+ </div>
+ <span class="form-text text-muted">
+ {{ badgeLinkUrlExample }}
+ </span>
</div>
<div class="form-group">
- <label for="badge-image-url">{{ s__('Badges|Badge image URL') }}</label>
+ <label
+ for="badge-image-url"
+ class="label-bold"
+ >{{ s__('Badges|Badge image URL') }}</label>
+ <p v-html="helpText"></p>
<input
id="badge-image-url"
v-model="imageUrl"
- :placeholder="$options.badgeImageUrlPlaceholder"
- type="text"
+ type="URL"
class="form-control"
+ required
@input="debouncedPreview"
/>
- <span
- class="form-text text-muted"
- v-html="helpText"
- ></span>
+ <div class="invalid-feedback">
+ {{ s__('Badges|Please fill in a valid URL') }}
+ </div>
+ <span class="form-text text-muted">
+ {{ badgeImageUrlExample }}
+ </span>
</div>
<div class="form-group">
@@ -200,20 +217,32 @@ export default {
>{{ s__('Badges|No image to preview') }}</p>
</div>
- <div class="row-content-block">
+ <div
+ v-if="isEditing"
+ class="row-content-block"
+ >
<loading-button
- :disabled="!canSubmit"
:loading="isSaving"
- :label="submitButtonLabel"
+ :label="s__('Badges|Save changes')"
type="submit"
container-class="btn btn-success"
/>
<button
- v-if="isEditing"
class="btn btn-cancel"
type="button"
@click="onCancel"
>{{ __('Cancel') }}</button>
</div>
+ <div
+ v-else
+ class="form-group"
+ >
+ <loading-button
+ :loading="isSaving"
+ :label="s__('Badges|Add badge')"
+ type="submit"
+ container-class="btn btn-success"
+ />
+ </div>
</form>
</template>
diff --git a/app/assets/javascripts/badges/components/badge_list.vue b/app/assets/javascripts/badges/components/badge_list.vue
index 268968b63b3..d2ec0fbb2c0 100644
--- a/app/assets/javascripts/badges/components/badge_list.vue
+++ b/app/assets/javascripts/badges/components/badge_list.vue
@@ -28,7 +28,7 @@ export default {
{{ s__('Badges|Your badges') }}
<span
v-show="!isLoading"
- class="badge"
+ class="badge badge-pill"
>{{ badges.length }}</span>
</div>
<loading-icon
diff --git a/app/assets/javascripts/badges/components/badge_list_row.vue b/app/assets/javascripts/badges/components/badge_list_row.vue
index 98aa00af0d7..712d81d0430 100644
--- a/app/assets/javascripts/badges/components/badge_list_row.vue
+++ b/app/assets/javascripts/badges/components/badge_list_row.vue
@@ -43,13 +43,13 @@ export default {
<badge
:image-url="badge.renderedImageUrl"
:link-url="badge.renderedLinkUrl"
- class="table-section section-30"
+ class="table-section section-40"
/>
- <span class="table-section section-50 str-truncated">{{ badge.linkUrl }}</span>
- <div class="table-section section-10">
- <span class="badge">{{ badgeKindText }}</span>
+ <span class="table-section section-30 str-truncated">{{ badge.linkUrl }}</span>
+ <div class="table-section section-15">
+ <span class="badge badge-pill">{{ badgeKindText }}</span>
</div>
- <div class="table-section section-10 table-button-footer">
+ <div class="table-section section-15 table-button-footer">
<div
v-if="canEditBadge"
class="table-action-buttons">
diff --git a/app/assets/javascripts/pages/groups/edit/index.js b/app/assets/javascripts/pages/groups/edit/index.js
index 8737f537296..002b2279fcc 100644
--- a/app/assets/javascripts/pages/groups/edit/index.js
+++ b/app/assets/javascripts/pages/groups/edit/index.js
@@ -2,14 +2,13 @@ import groupAvatar from '~/group_avatar';
import TransferDropdown from '~/groups/transfer_dropdown';
import initConfirmDangerModal from '~/confirm_danger_modal';
import initSettingsPanels from '~/settings_panels';
+import mountBadgeSettings from '~/pages/shared/mount_badge_settings';
+import { GROUP_BADGE } from '~/badges/constants';
document.addEventListener('DOMContentLoaded', () => {
groupAvatar();
new TransferDropdown(); // eslint-disable-line no-new
initConfirmDangerModal();
-});
-
-document.addEventListener('DOMContentLoaded', () => {
- // Initialize expandable settings panels
initSettingsPanels();
+ mountBadgeSettings(GROUP_BADGE);
});
diff --git a/app/assets/javascripts/pages/projects/edit/index.js b/app/assets/javascripts/pages/projects/edit/index.js
index 628913483c6..f5b1cf85e68 100644
--- a/app/assets/javascripts/pages/projects/edit/index.js
+++ b/app/assets/javascripts/pages/projects/edit/index.js
@@ -1,6 +1,8 @@
+import { PROJECT_BADGE } from '~/badges/constants';
import initSettingsPanels from '~/settings_panels';
import setupProjectEdit from '~/project_edit';
import initConfirmDangerModal from '~/confirm_danger_modal';
+import mountBadgeSettings from '~/pages/shared/mount_badge_settings';
import initProjectLoadingSpinner from '../shared/save_project_loader';
import projectAvatar from '../shared/project_avatar';
import initProjectPermissionsSettings from '../shared/permissions';
@@ -13,4 +15,5 @@ document.addEventListener('DOMContentLoaded', () => {
projectAvatar();
initProjectPermissionsSettings();
initConfirmDangerModal();
+ mountBadgeSettings(PROJECT_BADGE);
});
diff --git a/app/assets/javascripts/pages/projects/settings/badges/index/index.js b/app/assets/javascripts/pages/projects/settings/badges/index/index.js
deleted file mode 100644
index 30469550866..00000000000
--- a/app/assets/javascripts/pages/projects/settings/badges/index/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import Vue from 'vue';
-import Translate from '~/vue_shared/translate';
-import { PROJECT_BADGE } from '~/badges/constants';
-import mountBadgeSettings from '~/pages/shared/mount_badge_settings';
-
-Vue.use(Translate);
-
-document.addEventListener('DOMContentLoaded', () => {
- mountBadgeSettings(PROJECT_BADGE);
-});
diff --git a/app/controllers/groups/settings/badges_controller.rb b/app/controllers/groups/settings/badges_controller.rb
deleted file mode 100644
index ccbd0a3bc02..00000000000
--- a/app/controllers/groups/settings/badges_controller.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Groups
- module Settings
- class BadgesController < Groups::ApplicationController
- include API::Helpers::RelatedResourcesHelpers
-
- before_action :authorize_admin_group!
-
- def index
- @badge_api_endpoint = expose_url(api_v4_groups_badges_path(id: @group.id))
- end
- end
- end
-end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 83169636ccf..e57b9ff23a7 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -1,4 +1,5 @@
class GroupsController < Groups::ApplicationController
+ include API::Helpers::RelatedResourcesHelpers
include IssuesAction
include MergeRequestsAction
include ParamsBackwardCompatibility
@@ -77,6 +78,7 @@ class GroupsController < Groups::ApplicationController
end
def edit
+ @badge_api_endpoint = expose_url(api_v4_groups_badges_path(id: @group.id))
end
def projects
diff --git a/app/controllers/projects/settings/badges_controller.rb b/app/controllers/projects/settings/badges_controller.rb
deleted file mode 100644
index 7887bee49c5..00000000000
--- a/app/controllers/projects/settings/badges_controller.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Projects
- module Settings
- class BadgesController < Projects::ApplicationController
- include API::Helpers::RelatedResourcesHelpers
-
- before_action :authorize_admin_project!
-
- def index
- @badge_api_endpoint = expose_url(api_v4_projects_badges_path(id: @project.id))
- end
- end
- end
-end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index e9ae8c13142..0eaf9f94e37 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -1,4 +1,5 @@
class ProjectsController < Projects::ApplicationController
+ include API::Helpers::RelatedResourcesHelpers
include IssuableCollections
include ExtractsPath
include PreviewMarkdown
@@ -32,6 +33,7 @@ class ProjectsController < Projects::ApplicationController
end
def edit
+ @badge_api_endpoint = expose_url(api_v4_projects_badges_path(id: @project.id))
render 'edit'
end
diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml
index cae2df4699e..fc17dd2d310 100644
--- a/app/views/groups/edit.html.haml
+++ b/app/views/groups/edit.html.haml
@@ -25,6 +25,18 @@
.settings-content
= render 'groups/settings/permissions'
+%section.settings.no-animate{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = s_('GroupSettings|Badges')
+ %button.btn.js-settings-toggle{ type: 'button' }
+ = expanded ? 'Collapse' : 'Expand'
+ %p
+ = s_('GroupSettings|Customize your group badges.')
+ = link_to s_('GroupSettings|Learn more about badges.'), help_page_path('user/project/badges')
+ .settings-content
+ = render 'shared/badges/badge_settings'
+
%section.settings.gs-advanced.no-animate#js-advanced-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index d471dd84550..4158bb69452 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -122,12 +122,6 @@
%span
= _('General')
- = nav_link(controller: :badges) do
- = link_to group_settings_badges_path(@group), title: _('Project Badges') do
- %span
- = _('Project Badges')
-
-
= nav_link(path: 'groups#projects') do
= link_to projects_group_path(@group), title: _('Projects') do
%span
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index 34f47806205..30e0e9fca27 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -313,11 +313,6 @@
%span
= _('Members')
- if can_edit
- = nav_link(controller: :badges) do
- = link_to project_settings_badges_path(@project), title: _('Badges') do
- %span
- = _('Badges')
- - if can_edit
= nav_link(controller: [:integrations, :services, :hooks, :hook_logs]) do
= link_to project_settings_integrations_path(@project), title: _('Integrations') do
%span
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index e37a444c1c9..fb837b27207 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -102,6 +102,18 @@
= render_if_exists 'projects/service_desk_settings'
+ %section.settings.no-animate{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = s_('ProjectSettings|Badges')
+ %button.btn.js-settings-toggle{ type: 'button' }
+ = expanded ? 'Collapse' : 'Expand'
+ %p
+ = s_('ProjectSettings|Customize your project badges.')
+ = link_to s_('ProjectSettings|Learn more about badges.'), help_page_path('user/project/badges')
+ .settings-content
+ = render 'shared/badges/badge_settings'
+
= render 'export', project: @project
%section.qa-advanced-settings.settings.advanced-settings.no-animate#js-project-advanced-settings{ class: ('expanded' if expanded) }
diff --git a/changelogs/unreleased/winh-move-badge-settings.yml b/changelogs/unreleased/winh-move-badge-settings.yml
new file mode 100644
index 00000000000..9638ba04c1e
--- /dev/null
+++ b/changelogs/unreleased/winh-move-badge-settings.yml
@@ -0,0 +1,5 @@
+---
+title: Move badge settings to general settings
+merge_request: 21333
+author:
+type: changed
diff --git a/config/routes/group.rb b/config/routes/group.rb
index d7313e43786..343865cc50c 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -25,7 +25,6 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
constraints: { group_id: Gitlab::PathRegex.full_namespace_route_regex }) do
namespace :settings do
resource :ci_cd, only: [:show], controller: 'ci_cd'
- resources :badges, only: [:index]
end
resource :variables, only: [:show, :update]
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 34f49546983..4021d62b931 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -442,7 +442,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resource :repository, only: [:show], controller: :repository do
post :create_deploy_token, path: 'deploy_token/create'
end
- resources :badges, only: [:index]
end
# Since both wiki and repository routing contains wildcard characters
diff --git a/doc/user/project/badges.md b/doc/user/project/badges.md
index c4e59444ef7..19eb95099ce 100644
--- a/doc/user/project/badges.md
+++ b/doc/user/project/badges.md
@@ -17,7 +17,7 @@ If you find that you have to add the same badges to several projects, you may wa
To add a new badge to a project:
-1. Navigate to your project's **Settings > Badges**.
+1. Navigate to your project's **Settings > General > Badges**.
1. Under "Link", enter the URL that the badges should point to and under
"Badge image URL" the URL of the image that should be displayed.
1. Submit the badge by clicking the **Add badge** button.
@@ -39,7 +39,7 @@ project, consider adding them on the [project level](#project-badges) or use
To add a new badge to a group:
-1. Navigate to your group's **Settings > Project Badges**.
+1. Navigate to your group's **Settings > General > Badges**.
1. Under "Link", enter the URL that the badges should point to and under
"Badge image URL" the URL of the image that should be displayed.
1. Submit the badge by clicking the **Add badge** button.
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index fad653908ab..394a226e5a5 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -805,6 +805,9 @@ msgstr ""
msgid "Badges|No image to preview"
msgstr ""
+msgid "Badges|Please fill in a valid URL"
+msgstr ""
+
msgid "Badges|Project Badge"
msgstr ""
@@ -838,6 +841,9 @@ msgstr ""
msgid "Badges|Your badges"
msgstr ""
+msgid "Badges|e.g. %{exampleUrl}"
+msgstr ""
+
msgid "Begin with the selected commit"
msgstr ""
@@ -2897,6 +2903,15 @@ msgstr ""
msgid "Group: %{group_name}"
msgstr ""
+msgid "GroupSettings|Badges"
+msgstr ""
+
+msgid "GroupSettings|Customize your group badges."
+msgstr ""
+
+msgid "GroupSettings|Learn more about badges."
+msgstr ""
+
msgid "GroupSettings|Prevent sharing a project within %{group} with other groups"
msgstr ""
@@ -4536,6 +4551,15 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectSettings|Badges"
+msgstr ""
+
+msgid "ProjectSettings|Customize your project badges."
+msgstr ""
+
+msgid "ProjectSettings|Learn more about badges."
+msgstr ""
+
msgid "Projects"
msgstr ""
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 7a037828035..ae49490f31c 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -57,6 +57,16 @@ describe GroupsController do
end
end
+ describe 'GET edit' do
+ it 'sets the badge API endpoint' do
+ sign_in(owner)
+
+ get :edit, id: group.to_param
+
+ expect(assigns(:badge_api_endpoint)).not_to be_nil
+ end
+ end
+
describe 'GET #new' do
context 'when creating subgroups', :nested_groups do
[true, false].each do |can_create_group_status|
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 94644b1f9fd..c3a66477b6a 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -284,6 +284,19 @@ describe ProjectsController do
end
end
+ describe 'GET edit' do
+ it 'sets the badge API endpoint' do
+ sign_in(user)
+ project.add_maintainer(user)
+
+ get :edit,
+ namespace_id: project.namespace.path,
+ id: project.path
+
+ expect(assigns(:badge_api_endpoint)).not_to be_nil
+ end
+ end
+
describe "#update" do
render_views
diff --git a/spec/features/groups/settings/group_badges_spec.rb b/spec/features/groups/settings/group_badges_spec.rb
index 070a4a31ffa..a5c8dbf18d0 100644
--- a/spec/features/groups/settings/group_badges_spec.rb
+++ b/spec/features/groups/settings/group_badges_spec.rb
@@ -14,7 +14,7 @@ describe 'Group Badges' do
group.add_owner(user)
sign_in(user)
- visit(group_settings_badges_path(group))
+ visit(edit_group_path(group))
end
it 'shows a list of badges', :js do
diff --git a/spec/features/projects/settings/project_badges_spec.rb b/spec/features/projects/settings/project_badges_spec.rb
index 2ec94274f80..42b5547d43b 100644
--- a/spec/features/projects/settings/project_badges_spec.rb
+++ b/spec/features/projects/settings/project_badges_spec.rb
@@ -15,7 +15,7 @@ describe 'Project Badges' do
group.add_maintainer(user)
sign_in(user)
- visit(project_settings_badges_path(project))
+ visit(edit_project_path(project))
end
it 'shows a list of badges', :js do
diff --git a/spec/javascripts/badges/components/badge_form_spec.js b/spec/javascripts/badges/components/badge_form_spec.js
index dd21ec279cb..31195bd762b 100644
--- a/spec/javascripts/badges/components/badge_form_spec.js
+++ b/spec/javascripts/badges/components/badge_form_spec.js
@@ -1,21 +1,31 @@
import Vue from 'vue';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
import store from '~/badges/store';
+import createEmptyBadge from '~/badges/empty_badge';
import BadgeForm from '~/badges/components/badge_form.vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import { createDummyBadge } from '../dummy_badge';
+import { DUMMY_IMAGE_URL, TEST_HOST } from '../../test_constants';
+
+// avoid preview background process
+BadgeForm.methods.debouncedPreview = () => {};
describe('BadgeForm component', () => {
const Component = Vue.extend(BadgeForm);
+ let axiosMock;
let vm;
beforeEach(() => {
setFixtures(`
<div id="dummy-element"></div>
`);
+
+ axiosMock = new MockAdapter(axios);
});
afterEach(() => {
vm.$destroy();
+ axiosMock.restore();
});
describe('methods', () => {
@@ -38,93 +48,86 @@ describe('BadgeForm component', () => {
expect(vm.stopEditing).toHaveBeenCalled();
});
});
+ });
- describe('onSubmit', () => {
- describe('if isEditing is true', () => {
- beforeEach(() => {
- spyOn(vm, 'saveBadge').and.returnValue(Promise.resolve());
- store.replaceState({
- ...store.state,
- isSaving: false,
- badgeInEditForm: createDummyBadge(),
- });
- vm.isEditing = true;
- });
-
- it('returns immediately if imageUrl is empty', () => {
- store.state.badgeInEditForm.imageUrl = '';
-
- vm.onSubmit();
-
- expect(vm.saveBadge).not.toHaveBeenCalled();
- });
-
- it('returns immediately if linkUrl is empty', () => {
- store.state.badgeInEditForm.linkUrl = '';
-
- vm.onSubmit();
-
- expect(vm.saveBadge).not.toHaveBeenCalled();
- });
-
- it('returns immediately if isSaving is true', () => {
- store.state.isSaving = true;
+ const sharedSubmitTests = submitAction => {
+ const imageUrlSelector = '#badge-image-url';
+ const findImageUrlElement = () => vm.$el.querySelector(imageUrlSelector);
+ const linkUrlSelector = '#badge-link-url';
+ const findLinkUrlElement = () => vm.$el.querySelector(linkUrlSelector);
+ const setValue = (inputElementSelector, url) => {
+ const inputElement = vm.$el.querySelector(inputElementSelector);
+ inputElement.value = url;
+ inputElement.dispatchEvent(new Event('input'));
+ };
+ const submitForm = () => {
+ const submitButton = vm.$el.querySelector('button[type="submit"]');
+ submitButton.click();
+ };
+ const expectInvalidInput = inputElementSelector => {
+ const inputElement = vm.$el.querySelector(inputElementSelector);
+ expect(inputElement).toBeMatchedBy(':invalid');
+ const feedbackElement = vm.$el.querySelector(`${inputElementSelector} + .invalid-feedback`);
+ expect(feedbackElement).toBeVisible();
+ };
- vm.onSubmit();
+ beforeEach(() => {
+ spyOn(vm, submitAction).and.returnValue(Promise.resolve());
+ store.replaceState({
+ ...store.state,
+ badgeInAddForm: createEmptyBadge(),
+ badgeInEditForm: createEmptyBadge(),
+ isSaving: false,
+ });
- expect(vm.saveBadge).not.toHaveBeenCalled();
- });
+ setValue(linkUrlSelector, `${TEST_HOST}/link/url`);
+ setValue(imageUrlSelector, `${window.location.origin}${DUMMY_IMAGE_URL}`);
+ });
- it('calls saveBadge', () => {
- vm.onSubmit();
+ it('returns immediately if imageUrl is empty', () => {
+ setValue(imageUrlSelector, '');
- expect(vm.saveBadge).toHaveBeenCalled();
- });
- });
+ submitForm();
- describe('if isEditing is false', () => {
- beforeEach(() => {
- spyOn(vm, 'addBadge').and.returnValue(Promise.resolve());
- store.replaceState({
- ...store.state,
- isSaving: false,
- badgeInAddForm: createDummyBadge(),
- });
- vm.isEditing = false;
- });
+ expectInvalidInput(imageUrlSelector);
+ expect(vm[submitAction]).not.toHaveBeenCalled();
+ });
- it('returns immediately if imageUrl is empty', () => {
- store.state.badgeInAddForm.imageUrl = '';
+ it('returns immediately if imageUrl is malformed', () => {
+ setValue(imageUrlSelector, 'not-a-url');
- vm.onSubmit();
+ submitForm();
- expect(vm.addBadge).not.toHaveBeenCalled();
- });
+ expectInvalidInput(imageUrlSelector);
+ expect(vm[submitAction]).not.toHaveBeenCalled();
+ });
- it('returns immediately if linkUrl is empty', () => {
- store.state.badgeInAddForm.linkUrl = '';
+ it('returns immediately if linkUrl is empty', () => {
+ setValue(linkUrlSelector, '');
- vm.onSubmit();
+ submitForm();
- expect(vm.addBadge).not.toHaveBeenCalled();
- });
+ expectInvalidInput(linkUrlSelector);
+ expect(vm[submitAction]).not.toHaveBeenCalled();
+ });
- it('returns immediately if isSaving is true', () => {
- store.state.isSaving = true;
+ it('returns immediately if linkUrl is malformed', () => {
+ setValue(linkUrlSelector, 'not-a-url');
- vm.onSubmit();
+ submitForm();
- expect(vm.addBadge).not.toHaveBeenCalled();
- });
+ expectInvalidInput(linkUrlSelector);
+ expect(vm[submitAction]).not.toHaveBeenCalled();
+ });
- it('calls addBadge', () => {
- vm.onSubmit();
+ it(`calls ${submitAction}`, () => {
+ submitForm();
- expect(vm.addBadge).toHaveBeenCalled();
- });
- });
+ expect(findImageUrlElement()).toBeMatchedBy(':valid');
+ expect(findLinkUrlElement()).toBeMatchedBy(':valid');
+ expect(vm[submitAction]).toHaveBeenCalled();
});
- });
+ };
describe('if isEditing is false', () => {
beforeEach(() => {
@@ -138,12 +141,15 @@ describe('BadgeForm component', () => {
});
it('renders one button', () => {
- const buttons = vm.$el.querySelectorAll('.row-content-block button');
+ expect(vm.$el.querySelector('.row-content-block')).toBeNull();
+ const buttons = vm.$el.querySelectorAll('.form-group:last-of-type button');
expect(buttons.length).toBe(1);
const buttonAddElement = buttons[0];
expect(buttonAddElement).toBeVisible();
expect(buttonAddElement).toHaveText('Add badge');
});
+
+ sharedSubmitTests('addBadge');
});
describe('if isEditing is true', () => {
@@ -167,5 +173,7 @@ describe('BadgeForm component', () => {
expect(buttonCancelElement).toBeVisible();
expect(buttonCancelElement).toHaveText('Cancel');
});
+
+ sharedSubmitTests('saveBadge');
});
});