Commit 2c9bb135 authored by Luke "Jared" Bennett's avatar Luke "Jared" Bennett

Fixed tests

Grab permissions description from backend

Review changes

Added unit tests
parent 26b0fe8d
...@@ -262,7 +262,6 @@ ...@@ -262,7 +262,6 @@
case 'edit': case 'edit':
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
new ProjectNew(); new ProjectNew();
new gl.VisibilitySelect();
break; break;
case 'new': case 'new':
new ProjectNew(); new ProjectNew();
......
...@@ -14,11 +14,21 @@ ...@@ -14,11 +14,21 @@
return $('.save-project-loader').show(); return $('.save-project-loader').show();
}; };
})(this)); })(this));
this.initVisibilitySelect();
this.toggleSettings(); this.toggleSettings();
this.toggleSettingsOnclick(); this.toggleSettingsOnclick();
this.toggleRepoVisibility(); this.toggleRepoVisibility();
} }
ProjectNew.prototype.initVisibilitySelect = function() {
const visibilityContainer = document.querySelector('.js-visibility-select');
if (!visibilityContainer) return;
const visibilitySelect = new gl.VisibilitySelect(visibilityContainer);
visibilitySelect.init();
};
ProjectNew.prototype.toggleSettings = function() { ProjectNew.prototype.toggleSettings = function() {
var self = this; var self = this;
......
(() => { (() => {
const global = window.gl || (window.gl = {}); const gl = window.gl || (window.gl = {});
const VISIBILITY_DESCRIPTIONS = {
0: 'Project access must be granted explicitly to each user.',
10: 'This project can be cloned by any logged in user.',
20: 'The project can be cloned without any authentication.',
};
class VisibilitySelect { class VisibilitySelect {
constructor() { constructor(container) {
this.visibilitySelect = document.querySelector('.js-visibility-select'); if (!container) throw new Error('VisibilitySelect requires a container element as argument 1');
this.helpBlock = this.visibilitySelect.querySelector('.help-block'); this.container = container;
this.select = this.visibilitySelect.querySelector('select'); this.helpBlock = this.container.querySelector('.help-block');
this.select = this.container.querySelector('select');
}
init() {
if (this.select) { if (this.select) {
this.visibilityChanged(); this.updateHelpText();
this.select.addEventListener('change', this.visibilityChanged.bind(this)); this.select.addEventListener('change', this.updateHelpText.bind(this));
} else { } else {
this.helpBlock.textContent = this.visibilitySelect.querySelector('.js-locked').dataset.helpBlock; this.helpBlock.textContent = this.container.querySelector('.js-locked').dataset.helpBlock;
} }
} }
visibilityChanged() { updateHelpText() {
this.helpBlock.innerText = VISIBILITY_DESCRIPTIONS[this.select.value]; this.helpBlock.textContent = this.select.querySelector('option:checked').dataset.description;
} }
} }
global.VisibilitySelect = VisibilitySelect; gl.VisibilitySelect = VisibilitySelect;
})(); })();
...@@ -865,6 +865,8 @@ pre.light-well { ...@@ -865,6 +865,8 @@ pre.light-well {
} }
.project-feature { .project-feature {
padding-top: 10px;
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
padding-left: 45px; padding-left: 45px;
} }
......
...@@ -445,4 +445,15 @@ module ProjectsHelper ...@@ -445,4 +445,15 @@ module ProjectsHelper
def project_issues(project) def project_issues(project)
IssuesFinder.new(current_user, project_id: project.id).execute IssuesFinder.new(current_user, project_id: project.id).execute
end end
def visibility_select_options(project, selected_level)
levels_options_array = Gitlab::VisibilityLevel.values.map do |level|
[
visibility_level_label(level),
{ data: { description: visibility_level_description(level, project) } },
level
]
end
options_for_select(levels_options_array, selected_level)
end
end end
- if can_change_visibility_level?(@project, current_user) - if can_change_visibility_level?(@project, current_user)
- levels_options_hash = {} = form.select(model_method, visibility_select_options(@project, selected_level), {}, class: 'form-control visibility-select')
- Gitlab::VisibilityLevel.values.each do |level|
- levels_options_hash[visibility_level_label(level)] = level
- options = options_for_select(levels_options_hash, selected_level)
= form.select(model_method, options, {}, class: 'form-control visibility-select')
- else - else
.info.js-locked{ data: { help_block: visibility_level_description(@project.visibility_level, @project)}} .info.js-locked{ data: { help_block: visibility_level_description(@project.visibility_level, @project) } }
= visibility_level_icon(@project.visibility_level) = visibility_level_icon(@project.visibility_level)
%strong %strong
= visibility_level_label(@project.visibility_level) = visibility_level_label(@project.visibility_level)
...@@ -37,13 +37,13 @@ ...@@ -37,13 +37,13 @@
= link_to "(?)", help_page_path("public_access/public_access") = link_to "(?)", help_page_path("public_access/public_access")
%span.help-block %span.help-block
.col-md-3.visibility-select-container .col-md-3.visibility-select-container
= render('shared/visibility_select', model_method: :visibility_level, form: f, selected_level: @project.visibility_level) = render('projects/visibility_select', model_method: :visibility_level, form: f, selected_level: @project.visibility_level)
= f.fields_for :project_feature do |feature_fields| = f.fields_for :project_feature do |feature_fields|
%fieldset.features %fieldset.features
.row .row
.col-md-9.project-feature .col-md-9.project-feature
= feature_fields.label :repository_access_level, "Repository", class: 'label-light' = feature_fields.label :repository_access_level, "Repository", class: 'label-light'
%span.help-block Push files to be stored in this project %span.help-block View and edit files in this project
.col-md-3.js-repo-access-level .col-md-3.js-repo-access-level
= project_feature_access_select(:repository_access_level) = project_feature_access_select(:repository_access_level)
......
...@@ -97,7 +97,7 @@ module SharedProject ...@@ -97,7 +97,7 @@ module SharedProject
step 'I should see project settings' do step 'I should see project settings' do
expect(current_path).to eq edit_namespace_project_path(@project.namespace, @project) expect(current_path).to eq edit_namespace_project_path(@project.namespace, @project)
expect(page).to have_content("Project name") expect(page).to have_content("Project name")
expect(page).to have_content("Feature Visibility") expect(page).to have_content("Sharing & Permissions")
end end
def current_project def current_project
......
require 'spec_helper' require 'spec_helper'
require 'byebug'
feature 'Visibility settings', feature: true, js: true do feature 'Visibility settings', feature: true, js: true do
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -13,6 +12,7 @@ feature 'Visibility settings', feature: true, js: true do ...@@ -13,6 +12,7 @@ feature 'Visibility settings', feature: true, js: true do
scenario 'project visibility select is available' do scenario 'project visibility select is available' do
visibility_select_container = find('.js-visibility-select') visibility_select_container = find('.js-visibility-select')
expect(visibility_select_container.find('.visibility-select').value).to eq project.visibility_level.to_s expect(visibility_select_container.find('.visibility-select').value).to eq project.visibility_level.to_s
expect(visibility_select_container).to have_content 'The project can be cloned without any authentication.' expect(visibility_select_container).to have_content 'The project can be cloned without any authentication.'
end end
...@@ -21,6 +21,7 @@ feature 'Visibility settings', feature: true, js: true do ...@@ -21,6 +21,7 @@ feature 'Visibility settings', feature: true, js: true do
visibility_select_container = find('.js-visibility-select') visibility_select_container = find('.js-visibility-select')
visibility_select = visibility_select_container.find('.visibility-select') visibility_select = visibility_select_container.find('.visibility-select')
visibility_select.select('Private') visibility_select.select('Private')
expect(visibility_select.value).to eq '0' expect(visibility_select.value).to eq '0'
expect(visibility_select_container).to have_content 'Project access must be granted explicitly to each user.' expect(visibility_select_container).to have_content 'Project access must be granted explicitly to each user.'
end end
...@@ -37,6 +38,7 @@ feature 'Visibility settings', feature: true, js: true do ...@@ -37,6 +38,7 @@ feature 'Visibility settings', feature: true, js: true do
scenario 'project visibility is locked' do scenario 'project visibility is locked' do
visibility_select_container = find('.js-visibility-select') visibility_select_container = find('.js-visibility-select')
expect(visibility_select_container).not_to have_select '.visibility-select' expect(visibility_select_container).not_to have_select '.visibility-select'
expect(visibility_select_container).to have_content 'Public' expect(visibility_select_container).to have_content 'Public'
expect(visibility_select_container).to have_content 'The project can be cloned without any authentication.' expect(visibility_select_container).to have_content 'The project can be cloned without any authentication.'
......
/*= require visibility_select */
(() => {
const VisibilitySelect = gl.VisibilitySelect;
describe('VisibilitySelect', function () {
const lockedElement = document.createElement('div');
lockedElement.dataset.helpBlock = 'lockedHelpBlock';
const checkedElement = document.createElement('div');
checkedElement.dataset.description = 'checkedDescription';
const mockElements = {
container: document.createElement('div'),
select: document.createElement('div'),
'.help-block': document.createElement('div'),
'.js-locked': lockedElement,
'option:checked': checkedElement,
};
beforeEach(function () {
spyOn(Element.prototype, 'querySelector').and.callFake(selector => mockElements[selector]);
});
describe('#constructor', function () {
beforeEach(function () {
this.visibilitySelect = new VisibilitySelect(mockElements.container);
});
it('sets the container member', function () {
expect(this.visibilitySelect.container).toEqual(mockElements.container);
});
it('queries and sets the helpBlock member', function () {
expect(Element.prototype.querySelector).toHaveBeenCalledWith('.help-block');
expect(this.visibilitySelect.helpBlock).toEqual(mockElements['.help-block']);
});
it('queries and sets the select member', function () {
expect(Element.prototype.querySelector).toHaveBeenCalledWith('select');
expect(this.visibilitySelect.select).toEqual(mockElements.select);
});
describe('if there is no container element provided', function () {
it('throws an error', function () {
expect(() => new VisibilitySelect()).toThrowError('VisibilitySelect requires a container element as argument 1');
});
});
});
describe('#init', function () {
describe('if there is a select', function () {
beforeEach(function () {
this.visibilitySelect = new VisibilitySelect(mockElements.container);
});
it('calls updateHelpText', function () {
spyOn(VisibilitySelect.prototype, 'updateHelpText');
this.visibilitySelect.init();
expect(this.visibilitySelect.updateHelpText).toHaveBeenCalled();
});
it('adds a change event listener', function () {
spyOn(this.visibilitySelect.select, 'addEventListener');
this.visibilitySelect.init();
expect(this.visibilitySelect.select.addEventListener.calls.argsFor(0)).toContain('change');
});
});
describe('if there is no select', function () {
beforeEach(function () {
mockElements.select = undefined;
this.visibilitySelect = new VisibilitySelect(mockElements.container);
this.visibilitySelect.init();
});
it('updates the helpBlock text to the locked `data-help-block` messaged', function () {
expect(this.visibilitySelect.helpBlock.textContent)
.toEqual(lockedElement.dataset.helpBlock);
});
afterEach(function () {
mockElements.select = document.createElement('div');
});
});
});
describe('#updateHelpText', function () {
beforeEach(function () {
this.visibilitySelect = new VisibilitySelect(mockElements.container);
this.visibilitySelect.init();
});
it('updates the helpBlock text to the selected options `data-description`', function () {
expect(this.visibilitySelect.helpBlock.textContent)
.toEqual(checkedElement.dataset.description);
});
});
});
})();
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