Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
32e91bd6
Commit
32e91bd6
authored
Aug 20, 2016
by
Ruben Davila
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'ce/8-11-stable' into 8-11-stable-ee
parents
f6bb1db8
9510073d
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
304 additions
and
63 deletions
+304
-63
GITLAB_SHELL_VERSION
GITLAB_SHELL_VERSION
+1
-1
app/assets/javascripts/gl_dropdown.js
app/assets/javascripts/gl_dropdown.js
+43
-31
app/assets/javascripts/search_autocomplete.js
app/assets/javascripts/search_autocomplete.js
+14
-4
app/models/ability.rb
app/models/ability.rb
+28
-22
app/models/note.rb
app/models/note.rb
+2
-0
doc/update/8.10-to-8.11.md
doc/update/8.10-to-8.11.md
+1
-1
spec/javascripts/fixtures/gl_dropdown.html.haml
spec/javascripts/fixtures/gl_dropdown.html.haml
+16
-0
spec/javascripts/gl_dropdown_spec.js.es6
spec/javascripts/gl_dropdown_spec.js.es6
+119
-0
spec/javascripts/search_autocomplete_spec.js
spec/javascripts/search_autocomplete_spec.js
+4
-4
spec/models/ability_spec.rb
spec/models/ability_spec.rb
+64
-0
spec/models/network/graph_spec.rb
spec/models/network/graph_spec.rb
+12
-0
No files found.
GITLAB_SHELL_VERSION
View file @
32e91bd6
3.
3.3
3.
4.0
app/assets/javascripts/gl_dropdown.js
View file @
32e91bd6
...
...
@@ -31,9 +31,8 @@
this
.
input
.
on
(
'
keydown
'
,
function
(
e
)
{
var
keyCode
=
e
.
which
;
if
(
keyCode
===
13
)
{
e
.
preventDefault
()
e
.
preventDefault
()
;
}
})
.
on
(
'
keyup
'
,
function
(
e
)
{
...
...
@@ -111,9 +110,9 @@
matches
=
fuzzaldrinPlus
.
match
(
$el
.
text
().
trim
(),
search_text
);
if
(
!
$el
.
is
(
'
.dropdown-header
'
))
{
if
(
matches
.
length
)
{
return
$el
.
show
();
return
$el
.
show
()
.
removeClass
(
'
option-hidden
'
)
;
}
else
{
return
$el
.
hide
();
return
$el
.
hide
()
.
addClass
(
'
option-hidden
'
)
;
}
}
});
...
...
@@ -179,7 +178,7 @@
})();
GitLabDropdown
=
(
function
()
{
var
ACTIVE_CLASS
,
FILTER_INPUT
,
INDETERMINATE_CLASS
,
LOADING_CLASS
,
PAGE_TWO_CLASS
,
currentIndex
;
var
ACTIVE_CLASS
,
FILTER_INPUT
,
INDETERMINATE_CLASS
,
LOADING_CLASS
,
PAGE_TWO_CLASS
,
NON_SELECTABLE_CLASSES
,
SELECTABLE_CLASSES
,
currentIndex
;
LOADING_CLASS
=
"
is-loading
"
;
...
...
@@ -191,6 +190,12 @@
currentIndex
=
-
1
;
NON_SELECTABLE_CLASSES
=
'
.divider, .separator, .dropdown-header, .dropdown-menu-empty-link, .option-hidden
'
;
SELECTABLE_CLASSES
=
"
.dropdown-content li:not(
"
+
NON_SELECTABLE_CLASSES
+
"
)
"
;
CURSOR_SELECT_SCROLL_PADDING
=
5
FILTER_INPUT
=
'
.dropdown-input .dropdown-input-field
'
;
function
GitLabDropdown
(
el1
,
options
)
{
...
...
@@ -213,6 +218,7 @@
if
(
this
.
options
.
data
)
{
if
(
_
.
isObject
(
this
.
options
.
data
)
&&
!
_
.
isFunction
(
this
.
options
.
data
))
{
this
.
fullData
=
this
.
options
.
data
;
currentIndex
=
-
1
;
this
.
parseData
(
this
.
options
.
data
);
}
else
{
this
.
remote
=
new
GitLabDropdownRemote
(
this
.
options
.
data
,
{
...
...
@@ -240,7 +246,7 @@
keys
:
searchFields
,
elements
:
(
function
(
_this
)
{
return
function
()
{
selector
=
'
.dropdown-content li:not(
.divider
)
'
;
selector
=
'
.dropdown-content li:not(
'
+
NON_SELECTABLE_CLASSES
+
'
)
'
;
if
(
_this
.
dropdown
.
find
(
'
.dropdown-toggle-page
'
).
length
)
{
selector
=
"
.dropdown-page-one
"
+
selector
;
}
...
...
@@ -256,7 +262,7 @@
return
function
(
data
)
{
_this
.
parseData
(
data
);
if
(
_this
.
filterInput
.
val
()
!==
''
)
{
selector
=
'
.dropdown-content li:not(.divider):visible
'
;
selector
=
SELECTABLE_CLASSES
;
if
(
_this
.
dropdown
.
find
(
'
.dropdown-toggle-page
'
).
length
)
{
selector
=
"
.dropdown-page-one
"
+
selector
;
}
...
...
@@ -376,7 +382,7 @@
var
$target
;
if
(
this
.
options
.
multiSelect
)
{
$target
=
$
(
e
.
target
);
if
(
!
$target
.
hasClass
(
'
dropdown-menu-close
'
)
&&
!
$target
.
hasClass
(
'
dropdown-menu-close-icon
'
)
&&
!
$target
.
data
(
'
is-link
'
))
{
if
(
$target
&&
!
$target
.
hasClass
(
'
dropdown-menu-close
'
)
&&
!
$target
.
hasClass
(
'
dropdown-menu-close-icon
'
)
&&
!
$target
.
data
(
'
is-link
'
))
{
e
.
stopPropagation
();
return
false
;
}
else
{
...
...
@@ -387,7 +393,7 @@
GitLabDropdown
.
prototype
.
opened
=
function
()
{
var
contentHtml
;
currentIndex
=
-
1
;
this
.
resetRows
()
;
this
.
addArrowKeyEvent
();
if
(
this
.
options
.
setIndeterminateIds
)
{
this
.
options
.
setIndeterminateIds
.
call
(
this
);
...
...
@@ -410,6 +416,7 @@
GitLabDropdown
.
prototype
.
hidden
=
function
(
e
)
{
var
$input
;
this
.
resetRows
();
this
.
removeArrayKeyEvent
();
$input
=
this
.
dropdown
.
find
(
"
.dropdown-input-field
"
);
if
(
this
.
options
.
filterable
)
{
...
...
@@ -463,7 +470,7 @@
return
"
<li class='separator'></li>
"
;
}
if
(
data
.
header
!=
null
)
{
return
"
<li class='dropdown-header'>
"
+
data
.
header
+
"
</li>
"
;
return
_
.
template
(
'
<li class="dropdown-header"><%- header %></li>
'
)({
header
:
data
.
header
})
;
}
if
(
this
.
options
.
renderRow
)
{
html
=
this
.
options
.
renderRow
.
call
(
this
.
options
,
data
,
this
);
...
...
@@ -495,11 +502,16 @@
text
=
this
.
highlightTextMatches
(
text
,
this
.
filterInput
.
val
());
}
if
(
group
)
{
groupAttrs
=
"
data-group='
"
+
group
+
"
' data-index='
"
+
index
+
"
'
"
;
groupAttrs
=
'
data-group=
'
+
group
+
'
data-index=
'
+
index
;
}
else
{
groupAttrs
=
''
;
}
html
=
"
<li> <a href='
"
+
url
+
"
'
"
+
groupAttrs
+
"
class='
"
+
cssClass
+
"
'>
"
+
text
+
"
</a> </li>
"
;
html
=
_
.
template
(
'
<li><a href="<%- url %>" <%- groupAttrs %> class="<%- cssClass %>"><%= text %></a></li>
'
)({
url
:
url
,
groupAttrs
:
groupAttrs
,
cssClass
:
cssClass
,
text
:
text
});
}
return
html
;
};
...
...
@@ -521,17 +533,6 @@
return
html
=
"
<li class='dropdown-menu-empty-link'> <a href='#' class='is-focused'> No matching results. </a> </li>
"
;
};
GitLabDropdown
.
prototype
.
highlightRow
=
function
(
index
)
{
var
selector
;
if
(
this
.
filterInput
.
val
()
!==
""
)
{
selector
=
'
.dropdown-content li:first-child a
'
;
if
(
this
.
dropdown
.
find
(
"
.dropdown-toggle-page
"
).
length
)
{
selector
=
"
.dropdown-page-one .dropdown-content li:first-child a
"
;
}
return
this
.
getElement
(
selector
).
addClass
(
'
is-focused
'
);
}
};
GitLabDropdown
.
prototype
.
rowClicked
=
function
(
el
)
{
var
field
,
fieldName
,
groupName
,
isInput
,
selectedIndex
,
selectedObject
,
value
;
isInput
=
$
(
this
.
el
).
is
(
'
input
'
);
...
...
@@ -612,13 +613,15 @@
GitLabDropdown
.
prototype
.
selectRowAtIndex
=
function
(
index
)
{
var
$el
,
selector
;
selector
=
"
.dropdown-content li:not(.divider,.dropdown-header,.separator)
:eq(
"
+
index
+
"
) a
"
;
selector
=
SELECTABLE_CLASSES
+
"
:eq(
"
+
index
+
"
) a
"
;
if
(
this
.
dropdown
.
find
(
"
.dropdown-toggle-page
"
).
length
)
{
selector
=
"
.dropdown-page-one
"
+
selector
;
}
$el
=
$
(
selector
,
this
.
dropdown
);
if
(
$el
.
length
)
{
return
$el
.
first
().
trigger
(
'
click
'
);
$el
.
first
().
trigger
(
'
click
'
);
var
href
=
$el
.
attr
(
'
href
'
);
if
(
href
&&
href
!==
'
#
'
)
Turbolinks
.
visit
(
href
);
}
};
...
...
@@ -626,7 +629,7 @@
var
$input
,
ARROW_KEY_CODES
,
selector
;
ARROW_KEY_CODES
=
[
38
,
40
];
$input
=
this
.
dropdown
.
find
(
"
.dropdown-input-field
"
);
selector
=
'
.dropdown-content li:not(.divider,.dropdown-header,.separator):visible
'
;
selector
=
SELECTABLE_CLASSES
;
if
(
this
.
dropdown
.
find
(
"
.dropdown-toggle-page
"
).
length
)
{
selector
=
"
.dropdown-page-one
"
+
selector
;
}
...
...
@@ -654,7 +657,7 @@
return
false
;
}
if
(
currentKeyCode
===
13
&&
currentIndex
!==
-
1
)
{
return
_this
.
selectRowAtIndex
(
$
(
'
.is-focused
'
,
_this
.
dropdown
).
closest
(
'
li
'
).
index
()
-
1
);
return
_this
.
selectRowAtIndex
(
currentIndex
);
}
};
})(
this
));
...
...
@@ -664,6 +667,11 @@
return
$
(
'
body
'
).
off
(
'
keydown
'
);
};
GitLabDropdown
.
prototype
.
resetRows
=
function
resetRows
()
{
currentIndex
=
-
1
;
$
(
'
.is-focused
'
,
this
.
dropdown
).
removeClass
(
'
is-focused
'
);
};
GitLabDropdown
.
prototype
.
highlightRowAtIndex
=
function
(
$listItems
,
index
)
{
var
$dropdownContent
,
$listItem
,
dropdownContentBottom
,
dropdownContentHeight
,
dropdownContentTop
,
dropdownScrollTop
,
listItemBottom
,
listItemHeight
,
listItemTop
;
$
(
'
.is-focused
'
,
this
.
dropdown
).
removeClass
(
'
is-focused
'
);
...
...
@@ -677,10 +685,14 @@
listItemHeight
=
$listItem
.
outerHeight
();
listItemTop
=
$listItem
.
prop
(
'
offsetTop
'
);
listItemBottom
=
listItemTop
+
listItemHeight
;
if
(
listItemBottom
>
dropdownContentBottom
+
dropdownScrollTop
)
{
return
$dropdownContent
.
scrollTop
(
listItemBottom
-
dropdownContentBottom
);
}
else
if
(
listItemTop
<
dropdownContentTop
+
dropdownScrollTop
)
{
return
$dropdownContent
.
scrollTop
(
listItemTop
-
dropdownContentTop
);
if
(
!
index
)
{
$dropdownContent
.
scrollTop
(
0
)
}
else
if
(
index
===
(
$listItems
.
length
-
1
))
{
$dropdownContent
.
scrollTop
(
$dropdownContent
.
prop
(
'
scrollHeight
'
));
}
else
if
(
listItemBottom
>
(
dropdownContentBottom
+
dropdownScrollTop
))
{
$dropdownContent
.
scrollTop
(
listItemBottom
-
dropdownContentBottom
+
CURSOR_SELECT_SCROLL_PADDING
);
}
else
if
(
listItemTop
<
(
dropdownContentTop
+
dropdownScrollTop
))
{
return
$dropdownContent
.
scrollTop
(
listItemTop
-
dropdownContentTop
-
CURSOR_SELECT_SCROLL_PADDING
);
}
};
...
...
app/assets/javascripts/search_autocomplete.js
View file @
32e91bd6
...
...
@@ -7,7 +7,9 @@
KEYCODE
=
{
ESCAPE
:
27
,
BACKSPACE
:
8
,
ENTER
:
13
ENTER
:
13
,
UP
:
38
,
DOWN
:
40
};
function
SearchAutocomplete
(
opts
)
{
...
...
@@ -223,6 +225,12 @@
case
KEYCODE
.
ESCAPE
:
this
.
restoreOriginalState
();
break
;
case
KEYCODE
.
ENTER
:
this
.
disableAutocomplete
();
break
;
case
KEYCODE
.
UP
:
case
KEYCODE
.
DOWN
:
return
;
default
:
if
(
this
.
searchInput
.
val
()
===
''
)
{
this
.
disableAutocomplete
();
...
...
@@ -319,9 +327,11 @@
};
SearchAutocomplete
.
prototype
.
disableAutocomplete
=
function
()
{
this
.
searchInput
.
addClass
(
'
disabled
'
);
this
.
dropdown
.
removeClass
(
'
open
'
);
return
this
.
restoreMenu
();
if
(
!
this
.
searchInput
.
hasClass
(
'
disabled
'
)
&&
this
.
dropdown
.
hasClass
(
'
open
'
))
{
this
.
searchInput
.
addClass
(
'
disabled
'
);
this
.
dropdown
.
removeClass
(
'
open
'
).
trigger
(
'
hidden.bs.dropdown
'
);
this
.
restoreMenu
();
}
};
SearchAutocomplete
.
prototype
.
restoreMenu
=
function
()
{
...
...
app/models/ability.rb
View file @
32e91bd6
...
...
@@ -179,40 +179,46 @@ class Ability
end
def
project_abilities
(
user
,
project
)
rules
=
[]
key
=
"/user/
#{
user
.
id
}
/project/
#{
project
.
id
}
"
RequestStore
.
store
[
key
]
||=
begin
# Push abilities on the users team role
rules
.
push
(
*
project_team_rules
(
project
.
team
,
user
))
if
RequestStore
.
active?
RequestStore
.
store
[
key
]
||=
uncached_project_abilities
(
user
,
project
)
else
uncached_project_abilities
(
user
,
project
)
end
end
rules
<<
:change_repository_storage
if
user
.
admin?
def
uncached_project_abilities
(
user
,
project
)
rules
=
[]
# Push abilities on the users team role
rules
.
push
(
*
project_team_rules
(
project
.
team
,
user
))
owner
=
user
.
admin?
||
project
.
owner
==
user
||
(
project
.
group
&&
project
.
group
.
has_owner?
(
user
))
rules
<<
:change_repository_storage
if
user
.
admin?
if
owner
rules
.
push
(
*
project_owner_rules
)
end
owner
=
user
.
admin?
||
project
.
owner
==
user
||
(
project
.
group
&&
project
.
group
.
has_owner?
(
user
))
if
project
.
public?
||
(
project
.
internal?
&&
!
user
.
external?
)
rules
.
push
(
*
public_project_rules
)
if
owner
rules
.
push
(
*
project_owner_rules
)
end
# Allow to read builds for internal projects
rules
<<
:read_build
if
project
.
public_builds?
if
project
.
public?
||
(
project
.
internal?
&&
!
user
.
external?
)
rules
.
push
(
*
public_project_rules
)
unless
owner
||
project
.
team
.
member?
(
user
)
||
project_group_member?
(
project
,
user
)
rules
<<
:request_access
if
project
.
request_access_enabled
end
end
# Allow to read builds for internal projects
rules
<<
:read_build
if
project
.
public_builds?
if
project
.
archived?
rules
-=
project_archived_rules
unless
owner
||
project
.
team
.
member?
(
user
)
||
project_group_member?
(
project
,
user
)
rules
<<
:request_access
if
project
.
request_access_enabled
end
end
rules
-
project_disabled_features_rules
(
project
)
if
project
.
archived?
rules
-=
project_archived_rules
end
(
rules
-
project_disabled_features_rules
(
project
)).
uniq
end
def
project_team_rules
(
team
,
user
)
...
...
app/models/note.rb
View file @
32e91bd6
...
...
@@ -265,6 +265,8 @@ class Note < ActiveRecord::Base
def
ensure_discussion_id
return
unless
self
.
persisted?
# Needed in case the SELECT statement doesn't ask for `discussion_id`
return
unless
self
.
has_attribute?
(:
discussion_id
)
return
if
self
.
discussion_id
set_discussion_id
...
...
doc/update/8.10-to-8.11.md
View file @
32e91bd6
...
...
@@ -46,7 +46,7 @@ sudo -u git -H git checkout 8-11-stable-ee
```
bash
cd
/home/git/gitlab-shell
sudo
-u
git
-H
git fetch
--all
--tags
sudo
-u
git
-H
git checkout v3.
3.3
sudo
-u
git
-H
git checkout v3.
4.0
```
### 5. Update gitlab-workhorse
...
...
spec/javascripts/fixtures/gl_dropdown.html.haml
0 → 100644
View file @
32e91bd6
%div
.dropdown.inline
%button
#js-project-dropdown
.dropdown-menu-toggle
{
type:
'button'
,
data:
{
toggle:
'dropdown'
}}
Projects
%i
.fa.fa-chevron-down.dropdown-toggle-caret.js-projects-dropdown-toggle
.dropdown-menu.dropdown-select.dropdown-menu-selectable
.dropdown-title
%span
Go to project
%button
.dropdown-title-button.dropdown-menu-close
{
aria:
{
label:
'Close'
}}
%i
.fa.fa-times.dropdown-menu-close-icon
.dropdown-input
%input
.dropdown-input-field
{
type:
'search'
,
placeholder:
'Filter results'
}
%i
.fa.fa-search.dropdown-input-search
.dropdown-content
.dropdown-loading
%i
.fa.fa-spinner.fa-spin
spec/javascripts/gl_dropdown_spec.js.es6
0 → 100644
View file @
32e91bd6
/*= require jquery */
/*= require gl_dropdown */
/*= require turbolinks */
/*= require lib/utils/common_utils */
/*= require lib/utils/type_utility */
(() => {
const NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-link';
const ITEM_SELECTOR = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES})`;
const FOCUSED_ITEM_SELECTOR = `${ITEM_SELECTOR} a.is-focused`;
const ARROW_KEYS = {
DOWN: 40,
UP: 38,
ENTER: 13,
ESC: 27
};
let navigateWithKeys = function navigateWithKeys(direction, steps, cb, i) {
i = i || 0;
if (!i) direction = direction.toUpperCase();
$('body').trigger({
type: 'keydown',
which: ARROW_KEYS[direction],
keyCode: ARROW_KEYS[direction]
});
i++;
if (i <= steps) {
navigateWithKeys(direction, steps, cb, i);
} else {
cb();
}
};
describe('Dropdown', function describeDropdown() {
fixture.preload('gl_dropdown.html');
fixture.preload('projects.json');
beforeEach(() => {
fixture.load('gl_dropdown.html');
this.dropdownContainerElement = $('.dropdown.inline');
this.dropdownMenuElement = $('.dropdown-menu', this.dropdownContainerElement);
this.projectsData = fixture.load('projects.json')[0];
this.dropdownButtonElement = $('#js-project-dropdown', this.dropdownContainerElement).glDropdown({
selectable: true,
data: this.projectsData,
text: (project) => {
(project.name_with_namespace || project.name);
},
id: (project) => {
project.id;
}
});
});
afterEach(() => {
$('body').unbind('keydown');
this.dropdownContainerElement.unbind('keyup');
});
it('should open on click', () => {
expect(this.dropdownContainerElement).not.toHaveClass('open');
this.dropdownButtonElement.click();
expect(this.dropdownContainerElement).toHaveClass('open');
});
describe('that is open', () => {
beforeEach(() => {
this.dropdownButtonElement.click();
});
it('should select a following item on DOWN keypress', () => {
expect($(FOCUSED_ITEM_SELECTOR, this.dropdownMenuElement).length).toBe(0);
let randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 1)) + 0);
navigateWithKeys('down', randomIndex, () => {
expect($(FOCUSED_ITEM_SELECTOR, this.dropdownMenuElement).length).toBe(1);
expect($(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.dropdownMenuElement)).toHaveClass('is-focused');
});
});
it('should select a previous item on UP keypress', () => {
expect($(FOCUSED_ITEM_SELECTOR, this.dropdownMenuElement).length).toBe(0);
navigateWithKeys('down', (this.projectsData.length - 1), () => {
expect($(FOCUSED_ITEM_SELECTOR, this.dropdownMenuElement).length).toBe(1);
let randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 2)) + 0);
navigateWithKeys('up', randomIndex, () => {
expect($(FOCUSED_ITEM_SELECTOR, this.dropdownMenuElement).length).toBe(1);
expect($(`${ITEM_SELECTOR}:eq(${((this.projectsData.length - 2) - randomIndex)}) a`, this.dropdownMenuElement)).toHaveClass('is-focused');
});
});
});
it('should click the selected item on ENTER keypress', () => {
expect(this.dropdownContainerElement).toHaveClass('open')
let randomIndex = Math.floor(Math.random() * (this.projectsData.length - 1)) + 0
navigateWithKeys('down', randomIndex, () => {
spyOn(Turbolinks, 'visit').and.stub();
navigateWithKeys('enter', null, () => {
expect(this.dropdownContainerElement).not.toHaveClass('open');
let link = $(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.dropdownMenuElement);
expect(link).toHaveClass('is-active');
let linkedLocation = link.attr('href');
if (linkedLocation && linkedLocation !== '#') expect(Turbolinks.visit).toHaveBeenCalledWith(linkedLocation);
});
});
});
it('should close on ESC keypress', () => {
expect(this.dropdownContainerElement).toHaveClass('open');
this.dropdownContainerElement.trigger({
type: 'keyup',
which: ARROW_KEYS.ESC,
keyCode: ARROW_KEYS.ESC
});
expect(this.dropdownContainerElement).not.toHaveClass('open');
});
});
});
})();
spec/javascripts/search_autocomplete_spec.js
View file @
32e91bd6
...
...
@@ -105,13 +105,13 @@
a3
=
"
a[href='
"
+
mrsAssignedToMeLink
+
"
']
"
;
a4
=
"
a[href='
"
+
mrsIHaveCreatedLink
+
"
']
"
;
expect
(
list
.
find
(
a1
).
length
).
toBe
(
1
);
expect
(
list
.
find
(
a1
).
text
()).
toBe
(
'
Issues assigned to me
'
);
expect
(
list
.
find
(
a1
).
text
()).
toBe
(
'
Issues assigned to me
'
);
expect
(
list
.
find
(
a2
).
length
).
toBe
(
1
);
expect
(
list
.
find
(
a2
).
text
()).
toBe
(
"
Issues I've created
"
);
expect
(
list
.
find
(
a2
).
text
()).
toBe
(
"
Issues I've created
"
);
expect
(
list
.
find
(
a3
).
length
).
toBe
(
1
);
expect
(
list
.
find
(
a3
).
text
()).
toBe
(
'
Merge requests assigned to me
'
);
expect
(
list
.
find
(
a3
).
text
()).
toBe
(
'
Merge requests assigned to me
'
);
expect
(
list
.
find
(
a4
).
length
).
toBe
(
1
);
return
expect
(
list
.
find
(
a4
).
text
()).
toBe
(
"
Merge requests I've created
"
);
return
expect
(
list
.
find
(
a4
).
text
()).
toBe
(
"
Merge requests I've created
"
);
};
describe
(
'
Search autocomplete dropdown
'
,
function
()
{
...
...
spec/models/ability_spec.rb
View file @
32e91bd6
...
...
@@ -171,6 +171,70 @@ describe Ability, lib: true do
end
end
shared_examples_for
".project_abilities"
do
|
enable_request_store
|
before
do
RequestStore
.
begin!
if
enable_request_store
end
after
do
if
enable_request_store
RequestStore
.
end!
RequestStore
.
clear!
end
end
describe
'.project_abilities'
do
let!
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let!
(
:user
)
{
create
(
:user
)
}
it
'returns permissions for admin user'
do
admin
=
create
(
:admin
)
results
=
described_class
.
project_abilities
(
admin
,
project
)
expect
(
results
.
count
).
to
eq
(
68
)
end
it
'returns permissions for an owner'
do
results
=
described_class
.
project_abilities
(
project
.
owner
,
project
)
expect
(
results
.
count
).
to
eq
(
68
)
end
it
'returns permissions for a master'
do
project
.
team
<<
[
user
,
:master
]
results
=
described_class
.
project_abilities
(
user
,
project
)
expect
(
results
.
count
).
to
eq
(
60
)
end
it
'returns permissions for a developer'
do
project
.
team
<<
[
user
,
:developer
]
results
=
described_class
.
project_abilities
(
user
,
project
)
expect
(
results
.
count
).
to
eq
(
44
)
end
it
'returns permissions for a guest'
do
project
.
team
<<
[
user
,
:guest
]
results
=
described_class
.
project_abilities
(
user
,
project
)
expect
(
results
.
count
).
to
eq
(
21
)
end
end
end
describe
'.project_abilities with RequestStore'
do
it_behaves_like
".project_abilities"
,
true
end
describe
'.project_abilities without RequestStore'
do
it_behaves_like
".project_abilities"
,
false
end
describe
'.issues_readable_by_user'
do
context
'with an admin user'
do
it
'returns all given issues'
do
...
...
spec/models/network/graph_spec.rb
0 → 100644
View file @
32e91bd6
require
'spec_helper'
describe
Network
::
Graph
,
models:
true
do
let
(
:project
)
{
create
(
:project
)
}
let!
(
:note_on_commit
)
{
create
(
:note_on_commit
,
project:
project
)
}
it
'#initialize'
do
graph
=
described_class
.
new
(
project
,
'refs/heads/master'
,
project
.
repository
.
commit
,
nil
)
expect
(
graph
.
notes
).
to
eq
(
{
note_on_commit
.
commit_id
=>
1
}
)
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment