Commit 6dee8b41 authored by Rémy Coutable's avatar Rémy Coutable

Merge remote-tracking branch 'ce/master' into rc/ce-to-ee-friday

Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parents 78ec4e8f 00cb8237
......@@ -426,7 +426,7 @@ merge request:
1. [Ruby](https://github.com/bbatsov/ruby-style-guide).
Important sections include [Source Code Layout][rss-source] and
[Naming][rss-naming]. Use:
- multi-line method chaining style **Option B**: dot `.` on previous line
- multi-line method chaining style **Option A**: dot `.` on the second line
- string literal quoting style **Option A**: single quoted by default
1. [Rails](https://github.com/bbatsov/rails-style-guide)
1. [Newlines styleguide][newlines-styleguide]
......
/* global Vue */
require('./issue_card_inner');
const Store = gl.issueBoards.BoardsStore;
module.exports = {
name: 'BoardsIssueCard',
template: `
<li class="card"
:class="{ 'user-can-drag': !disabled && issue.id, 'is-disabled': disabled || !issue.id, 'is-active': issueDetailVisible }"
:index="index"
:data-issue-id="issue.id"
@mousedown="mouseDown"
@mousemove="mouseMove"
@mouseup="showIssue($event)">
<issue-card-inner
:list="list"
:issue="issue"
:issue-link-base="issueLinkBase"
:root-path="rootPath" />
</li>
`,
components: {
'issue-card-inner': gl.issueBoards.IssueCardInner,
},
props: {
list: Object,
issue: Object,
issueLinkBase: String,
disabled: Boolean,
index: Number,
rootPath: String,
},
data() {
return {
showDetail: false,
detailIssue: Store.detail,
};
},
computed: {
issueDetailVisible() {
return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id;
},
},
methods: {
mouseDown() {
this.showDetail = true;
},
mouseMove() {
this.showDetail = false;
},
showIssue(e) {
const targetTagName = e.target.tagName.toLowerCase();
if (targetTagName === 'a' || targetTagName === 'button') return;
if (this.showDetail) {
this.showDetail = false;
if (Store.detail.issue && Store.detail.issue.id === this.issue.id) {
Store.detail.issue = {};
} else {
Store.detail.issue = this.issue;
Store.detail.list = this.list;
}
}
},
},
};
/* eslint-disable comma-dangle, space-before-function-paren, dot-notation */
/* global Vue */
require('./issue_card_inner');
(() => {
const Store = gl.issueBoards.BoardsStore;
window.gl = window.gl || {};
window.gl.issueBoards = window.gl.issueBoards || {};
gl.issueBoards.BoardCard = Vue.extend({
template: '#js-board-list-card',
components: {
'issue-card-inner': gl.issueBoards.IssueCardInner,
},
props: {
list: Object,
issue: Object,
issueLinkBase: String,
disabled: Boolean,
index: Number,
rootPath: String,
},
data () {
return {
showDetail: false,
detailIssue: Store.detail
};
},
computed: {
issueDetailVisible () {
return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id;
}
},
methods: {
mouseDown () {
this.showDetail = true;
},
mouseMove() {
this.showDetail = false;
},
showIssue (e) {
const targetTagName = e.target.tagName.toLowerCase();
if (targetTagName === 'a' || targetTagName === 'button') return;
if (this.showDetail) {
this.showDetail = false;
if (Store.detail.issue && Store.detail.issue.id === this.issue.id) {
Store.detail.issue = {};
} else {
Store.detail.issue = this.issue;
Store.detail.list = this.list;
}
}
}
}
});
})();
......@@ -2,7 +2,7 @@
/* global Vue */
/* global Sortable */
require('./board_card');
const boardCard = require('./board_card');
require('./board_new_issue');
(() => {
......@@ -14,7 +14,7 @@ require('./board_new_issue');
gl.issueBoards.BoardList = Vue.extend({
template: '#js-board-list-template',
components: {
'board-card': gl.issueBoards.BoardCard,
boardCard,
'board-new-issue': gl.issueBoards.BoardNewIssue
},
props: {
......
require('./stat_graph_contributors_graph');
require('./stat_graph_contributors_util');
require('./stat_graph_contributors');
require('./stat_graph');
import ContributorsStatGraph from './stat_graph_contributors';
// export to global scope
window.ContributorsStatGraph = ContributorsStatGraph;
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-return-assign, max-len */
(function() {
this.StatGraph = (function() {
function StatGraph() {}
StatGraph.log = {};
StatGraph.get_log = function() {
return this.log;
};
StatGraph.set_log = function(data) {
return this.log = data;
};
return StatGraph;
})();
}).call(window);
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, camelcase, one-var-declaration-per-line, quotes, no-param-reassign, quote-props, comma-dangle, prefer-template, max-len, no-return-assign */
/* global ContributorsGraph */
/* global ContributorsAuthorGraph */
/* global ContributorsMasterGraph */
/* global ContributorsStatGraphUtil */
/* global d3 */
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, camelcase, one-var-declaration-per-line, quotes, no-param-reassign, quote-props, comma-dangle, prefer-template, max-len, no-return-assign, no-shadow */
window.d3 = require('d3');
import d3 from 'd3';
import { ContributorsGraph, ContributorsAuthorGraph, ContributorsMasterGraph } from './stat_graph_contributors_graph';
import ContributorsStatGraphUtil from './stat_graph_contributors_util';
(function() {
this.ContributorsStatGraph = (function() {
function ContributorsStatGraph() {}
export default (function() {
function ContributorsStatGraph() {}
ContributorsStatGraph.prototype.init = function(log) {
var author_commits, total_commits;
this.parsed_log = ContributorsStatGraphUtil.parse_log(log);
this.set_current_field("commits");
total_commits = ContributorsStatGraphUtil.get_total_data(this.parsed_log, this.field);
author_commits = ContributorsStatGraphUtil.get_author_data(this.parsed_log, this.field);
this.add_master_graph(total_commits);
this.add_authors_graph(author_commits);
return this.change_date_header();
};
ContributorsStatGraph.prototype.init = function(log) {
var author_commits, total_commits;
this.parsed_log = ContributorsStatGraphUtil.parse_log(log);
this.set_current_field("commits");
total_commits = ContributorsStatGraphUtil.get_total_data(this.parsed_log, this.field);
author_commits = ContributorsStatGraphUtil.get_author_data(this.parsed_log, this.field);
this.add_master_graph(total_commits);
this.add_authors_graph(author_commits);
return this.change_date_header();
};
ContributorsStatGraph.prototype.add_master_graph = function(total_data) {
this.master_graph = new ContributorsMasterGraph(total_data);
return this.master_graph.draw();
};
ContributorsStatGraph.prototype.add_master_graph = function(total_data) {
this.master_graph = new ContributorsMasterGraph(total_data);
return this.master_graph.draw();
};
ContributorsStatGraph.prototype.add_authors_graph = function(author_data) {
var limited_author_data;
this.authors = [];
limited_author_data = author_data.slice(0, 100);
return _.each(limited_author_data, (function(_this) {
return function(d) {
var author_graph, author_header;
author_header = _this.create_author_header(d);
$(".contributors-list").append(author_header);
_this.authors[d.author_name] = author_graph = new ContributorsAuthorGraph(d.dates);
return author_graph.draw();
};
})(this));
};
ContributorsStatGraph.prototype.add_authors_graph = function(author_data) {
var limited_author_data;
this.authors = [];
limited_author_data = author_data.slice(0, 100);
return _.each(limited_author_data, (function(_this) {
return function(d) {
var author_graph, author_header;
author_header = _this.create_author_header(d);
$(".contributors-list").append(author_header);
_this.authors[d.author_name] = author_graph = new ContributorsAuthorGraph(d.dates);
return author_graph.draw();
};
})(this));
};
ContributorsStatGraph.prototype.format_author_commit_info = function(author) {
var commits;
commits = $('<span/>', {
"class": 'graph-author-commits-count'
});
commits.text(author.commits + " commits");
return $('<span/>').append(commits);
};
ContributorsStatGraph.prototype.format_author_commit_info = function(author) {
var commits;
commits = $('<span/>', {
"class": 'graph-author-commits-count'
});
commits.text(author.commits + " commits");
return $('<span/>').append(commits);
};
ContributorsStatGraph.prototype.create_author_header = function(author) {
var author_commit_info, author_commit_info_span, author_email, author_name, list_item;
list_item = $('<li/>', {
"class": 'person',
style: 'display: block;'
});
author_name = $('<h4>' + author.author_name + '</h4>');
author_email = $('<p class="graph-author-email">' + author.author_email + '</p>');
author_commit_info_span = $('<span/>', {
"class": 'commits'
});
author_commit_info = this.format_author_commit_info(author);
author_commit_info_span.html(author_commit_info);
list_item.append(author_name);
list_item.append(author_email);
list_item.append(author_commit_info_span);
return list_item;
};
ContributorsStatGraph.prototype.create_author_header = function(author) {
var author_commit_info, author_commit_info_span, author_email, author_name, list_item;
list_item = $('<li/>', {
"class": 'person',
style: 'display: block;'
});
author_name = $('<h4>' + author.author_name + '</h4>');
author_email = $('<p class="graph-author-email">' + author.author_email + '</p>');
author_commit_info_span = $('<span/>', {
"class": 'commits'
});
author_commit_info = this.format_author_commit_info(author);
author_commit_info_span.html(author_commit_info);
list_item.append(author_name);
list_item.append(author_email);
list_item.append(author_commit_info_span);
return list_item;
};
ContributorsStatGraph.prototype.redraw_master = function() {
var total_data;
total_data = ContributorsStatGraphUtil.get_total_data(this.parsed_log, this.field);
this.master_graph.set_data(total_data);
return this.master_graph.redraw();
};
ContributorsStatGraph.prototype.redraw_master = function() {
var total_data;
total_data = ContributorsStatGraphUtil.get_total_data(this.parsed_log, this.field);
this.master_graph.set_data(total_data);
return this.master_graph.redraw();
};
ContributorsStatGraph.prototype.redraw_authors = function() {
var author_commits, x_domain;
$("ol").html("");
x_domain = ContributorsGraph.prototype.x_domain;
author_commits = ContributorsStatGraphUtil.get_author_data(this.parsed_log, this.field, x_domain);
return _.each(author_commits, (function(_this) {
return function(d) {
_this.redraw_author_commit_info(d);
$(_this.authors[d.author_name].list_item).appendTo("ol");
_this.authors[d.author_name].set_data(d.dates);
return _this.authors[d.author_name].redraw();
};
})(this));
};
ContributorsStatGraph.prototype.redraw_authors = function() {
var author_commits, x_domain;
$("ol").html("");
x_domain = ContributorsGraph.prototype.x_domain;
author_commits = ContributorsStatGraphUtil.get_author_data(this.parsed_log, this.field, x_domain);
return _.each(author_commits, (function(_this) {
return function(d) {
_this.redraw_author_commit_info(d);
$(_this.authors[d.author_name].list_item).appendTo("ol");
_this.authors[d.author_name].set_data(d.dates);
return _this.authors[d.author_name].redraw();
};
})(this));
};
ContributorsStatGraph.prototype.set_current_field = function(field) {
return this.field = field;
};
ContributorsStatGraph.prototype.set_current_field = function(field) {
return this.field = field;
};
ContributorsStatGraph.prototype.change_date_header = function() {
var print, print_date_format, x_domain;
x_domain = ContributorsGraph.prototype.x_domain;
print_date_format = d3.time.format("%B %e %Y");
print = print_date_format(x_domain[0]) + " - " + print_date_format(x_domain[1]);
return $("#date_header").text(print);
};
ContributorsStatGraph.prototype.change_date_header = function() {
var print, print_date_format, x_domain;
x_domain = ContributorsGraph.prototype.x_domain;
print_date_format = d3.time.format("%B %e %Y");
print = print_date_format(x_domain[0]) + " - " + print_date_format(x_domain[1]);
return $("#date_header").text(print);
};
ContributorsStatGraph.prototype.redraw_author_commit_info = function(author) {
var author_commit_info, author_list_item;
author_list_item = $(this.authors[author.author_name].list_item);
author_commit_info = this.format_author_commit_info(author);
return author_list_item.find("span").html(author_commit_info);
};
ContributorsStatGraph.prototype.redraw_author_commit_info = function(author) {
var author_commit_info, author_list_item;
author_list_item = $(this.authors[author.author_name].list_item);
author_commit_info = this.format_author_commit_info(author);
return author_list_item.find("span").html(author_commit_info);
};
return ContributorsStatGraph;
})();
}).call(window);
return ContributorsStatGraph;
})();
/* eslint-disable func-names, space-before-function-paren, object-shorthand, no-var, one-var, camelcase, one-var-declaration-per-line, comma-dangle, no-param-reassign, no-return-assign, quotes, prefer-arrow-callback, wrap-iife, consistent-return, no-unused-vars, max-len, no-cond-assign, no-else-return, max-len */
(function() {
window.ContributorsStatGraphUtil = {
parse_log: function(log) {
var by_author, by_email, data, entry, i, len, total, normalized_email;
total = {};
by_author = {};
by_email = {};
for (i = 0, len = log.length; i < len; i += 1) {
entry = log[i];
if (total[entry.date] == null) {
this.add_date(entry.date, total);
}
normalized_email = entry.author_email.toLowerCase();
data = by_author[entry.author_name] || by_email[normalized_email];
if (data == null) {
data = this.add_author(entry, by_author, by_email);
}
if (!data[entry.date]) {
this.add_date(entry.date, data);
}
this.store_data(entry, total[entry.date], data[entry.date]);
}
total = _.toArray(total);
by_author = _.toArray(by_author);
return {
total: total,
by_author: by_author
};
},
add_date: function(date, collection) {
collection[date] = {};
return collection[date].date = date;
},
add_author: function(author, by_author, by_email) {
var data, normalized_email;
data = {};
data.author_name = author.author_name;
data.author_email = author.author_email;
normalized_email = author.author_email.toLowerCase();
by_author[author.author_name] = data;
by_email[normalized_email] = data;
return data;
},
store_data: function(entry, total, by_author) {
this.store_commits(total, by_author);
this.store_additions(entry, total, by_author);
return this.store_deletions(entry, total, by_author);
},
store_commits: function(total, by_author) {
this.add(total, "commits", 1);
return this.add(by_author, "commits", 1);
},
add: function(collection, field, value) {
if (collection[field] == null) {
collection[field] = 0;
}
return collection[field] += value;
},
store_additions: function(entry, total, by_author) {
if (entry.additions == null) {
entry.additions = 0;
export default {
parse_log: function(log) {
var by_author, by_email, data, entry, i, len, total, normalized_email;
total = {};
by_author = {};
by_email = {};
for (i = 0, len = log.length; i < len; i += 1) {
entry = log[i];
if (total[entry.date] == null) {
this.add_date(entry.date, total);
}
this.add(total, "additions", entry.additions);
return this.add(by_author, "additions", entry.additions);
},
store_deletions: function(entry, total, by_author) {
if (entry.deletions == null) {
entry.deletions = 0;
normalized_email = entry.author_email.toLowerCase();
data = by_author[entry.author_name] || by_email[normalized_email];
if (data == null) {
data = this.add_author(entry, by_author, by_email);
}
this.add(total, "deletions", entry.deletions);
return this.add(by_author, "deletions", entry.deletions);
},
get_total_data: function(parsed_log, field) {
var log, total_data;
log = parsed_log.total;
total_data = this.pick_field(log, field);
return _.sortBy(total_data, function(d) {
return d.date;
});
},
pick_field: function(log, field) {
var total_data;
total_data = [];
_.each(log, function(d) {
return total_data.push(_.pick(d, [field, 'date']));
});
return total_data;
},
get_author_data: function(parsed_log, field, date_range) {
var author_data, log;
if (date_range == null) {
date_range = null;
}
log = parsed_log.by_author;
author_data = [];
_.each(log, (function(_this) {
return function(log_entry) {
var parsed_log_entry;
parsed_log_entry = _this.parse_log_entry(log_entry, field, date_range);
if (!_.isEmpty(parsed_log_entry.dates)) {
return author_data.push(parsed_log_entry);
}
};
})(this));
return _.sortBy(author_data, function(d) {
return d[field];
}).reverse();
},
parse_log_entry: function(log_entry, field, date_range) {
var parsed_entry;
parsed_entry = {};
parsed_entry.author_name = log_entry.author_name;
parsed_entry.author_email = log_entry.author_email;
parsed_entry.dates = {};
parsed_entry.commits = parsed_entry.additions = parsed_entry.deletions = 0;
_.each(_.omit(log_entry, 'author_name', 'author_email'), (function(_this) {
return function(value, key) {
if (_this.in_range(value.date, date_range)) {
parsed_entry.dates[value.date] = value[field];
parsed_entry.commits += value.commits;
parsed_entry.additions += value.additions;
return parsed_entry.deletions += value.deletions;
}
};
})(this));
return parsed_entry;
},
in_range: function(date, date_range) {
var ref;
if (date_range === null || (date_range[0] <= (ref = new Date(date)) && ref <= date_range[1])) {
return true;
} else {
return false;
if (!data[entry.date]) {
this.add_date(entry.date, data);
}
this.store_data(entry, total[entry.date], data[entry.date]);
}
total = _.toArray(total);
by_author = _.toArray(by_author);
return {
total: total,
by_author: by_author
};
},
add_date: function(date, collection) {
collection[date] = {};
return collection[date].date = date;
},
add_author: function(author, by_author, by_email) {
var data, normalized_email;
data = {};
data.author_name = author.author_name;
data.author_email = author.author_email;
normalized_email = author.author_email.toLowerCase();
by_author[author.author_name] = data;
by_email[normalized_email] = data;
return data;
},
store_data: function(entry, total, by_author) {
this.store_commits(total, by_author);
this.store_additions(entry, total, by_author);
return this.store_deletions(entry, total, by_author);
},
store_commits: function(total, by_author) {
this.add(total, "commits", 1);
return this.add(by_author, "commits", 1);
},
add: function(collection, field, value) {
if (collection[field] == null) {
collection[field] = 0;
}
return collection[field] += value;
},
store_additions: function(entry, total, by_author) {
if (entry.additions == null) {
entry.additions = 0;
}
this.add(total, "additions", entry.additions);
return this.add(by_author, "additions", entry.additions);
},
store_deletions: function(entry, total, by_author) {
if (entry.deletions == null) {
entry.deletions = 0;
}
this.add(total, "deletions", entry.deletions);
return this.add(by_author, "deletions", entry.deletions);
},
get_total_data: function(parsed_log, field) {
var log, total_data;
log = parsed_log.total;
total_data = this.pick_field(log, field);
return _.sortBy(total_data, function(d) {
return d.date;
});
},
pick_field: function(log, field) {
var total_data;
total_data = [];
_.each(log, function(d) {
return total_data.push(_.pick(d, [field, 'date']));
});
return total_data;
},
get_author_data: function(parsed_log, field, date_range) {
var author_data, log;
if (date_range == null) {
date_range = null;
}
log = parsed_log.by_author;
author_data = [];
_.each(log, (function(_this) {
return function(log_entry) {
var parsed_log_entry;
parsed_log_entry = _this.parse_log_entry(log_entry, field, date_range);
if (!_.isEmpty(parsed_log_entry.dates)) {
return author_data.push(parsed_log_entry);
}
};
})(this));
return _.sortBy(author_data, function(d) {
return d[field];
}).reverse();
},
parse_log_entry: function(log_entry, field, date_range) {
var parsed_entry;
parsed_entry = {};
parsed_entry.author_name = log_entry.author_name;
parsed_entry.author_email = log_entry.author_email;
parsed_entry.dates = {};
parsed_entry.commits = parsed_entry.additions = parsed_entry.deletions = 0;
_.each(_.omit(log_entry, 'author_name', 'author_email'), (function(_this) {
return function(value, key) {
if (_this.in_range(value.date, date_range)) {
parsed_entry.dates[value.date] = value[field];
parsed_entry.commits += value.commits;
parsed_entry.additions += value.additions;
return parsed_entry.deletions += value.deletions;
}
};
})(this));
return parsed_entry;
},
in_range: function(date, date_range) {
var ref;
if (date_range === null || (date_range[0] <= (ref = new Date(date)) && ref <= date_range[1])) {
return true;
} else {
return false;
}
};
}).call(window);
}
};
......@@ -39,7 +39,7 @@
$value = $block.find('.value');
$loading = $block.find('.block-loading').fadeOut();
if (issueUpdateURL) {
milestoneLinkTemplate = _.template('<a href="/<%- namespace %>/<%- path %>/milestones/<%- iid %>" class="bold has-tooltip" data-container="body" title="<%- remaining %>"><%- title %></a>');
milestoneLinkTemplate = _.template('<a href="/<%- full_path %>/milestones/<%- iid %>" class="bold has-tooltip" data-container="body" title="<%- remaining %>"><%- title %></a>');
milestoneLinkNoneTemplate = '<span class="no-value">None</span>';
collapsedSidebarLabelTemplate = _.template('<span class="has-tooltip" data-container="body" title="<%- remaining %>" data-placement="left"> <%- title %> </span>');
}
......@@ -181,8 +181,7 @@
$selectbox.hide();
$value.css('display', '');
if (data.milestone != null) {
data.milestone.namespace = _this.currentProject.namespace;
data.milestone.path = _this.currentProject.path;
data.milestone.full_path = _this.currentProject.full_path;
data.milestone.remaining = gl.utils.timeFor(data.milestone.due_date);
$value.html(milestoneLinkTemplate(data.milestone));
return $sidebarCollapsedValue.find('span').html(collapsedSidebarLabelTemplate(data.milestone));
......
......@@ -23,6 +23,13 @@
required: true,
},
},
updated() {
if (this.builds) {
this.stopDropdownClickPropagation();
}
},
methods: {
fetchBuilds(e) {
const areaExpanded = e.currentTarget.attributes['aria-expanded'];
......@@ -37,17 +44,19 @@
return flash;
});
},
keepGraph(e) {
const { target } = e;
if (target.className.indexOf('js-ci-action-icon') >= 0) return null;
if (
target.parentElement &&
(target.parentElement.className.indexOf('js-ci-action-icon') >= 0)
) return null;
return e.stopPropagation();
/**
* When the user right clicks or cmd/ctrl + click in the job name
* the dropdown should not be closed and the link should open in another tab,
* so we stop propagation of the click event inside the dropdown.
*
* Since this component is rendered multiple times per page we need to guarantee we only
* target the click event of this component.
*/
stopDropdownClickPropagation() {
$(this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item')).on('click', (e) => {
e.stopPropagation();
});
},
},
computed: {
......@@ -76,13 +85,13 @@
template: `
<div>
<button
@click='fetchBuilds($event)'
@click="fetchBuilds($event)"
:class="triggerButtonClass"
:title='stage.title'
:title="stage.title"
data-placement="top"
data-toggle="dropdown"
type="button"
:aria-label='stage.title'
:aria-label="stage.title"
>
<span v-html="svg" aria-hidden="true"></span>
<i class="fa fa-caret-down" aria-hidden="true"></i>
......@@ -90,7 +99,6 @@
<ul class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container">
<div class="arrow-up" aria-hidden="true"></div>
<div
@click='keepGraph($event)'
:class="dropdownClass"
class="js-builds-dropdown-list scrollable-menu"
v-html="buildsOrSpinner"
......
......@@ -29,16 +29,14 @@
}
}
@media (min-width: $screen-sm-min) {
.content-wrapper {
padding-right: $gutter_collapsed_width;
}
}
.right-sidebar-collapsed {
padding-right: 0;
@media (min-width: $screen-sm-min) {
.content-wrapper {
padding-right: $gutter_collapsed_width;
}
.merge-request-tabs-holder.affix {
right: $gutter_collapsed_width;
}
......@@ -56,6 +54,12 @@
.right-sidebar-expanded {
padding-right: 0;
@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
.content-wrapper {
padding-right: $gutter_collapsed_width;
}
}
@media (min-width: $screen-md-min) {
.content-wrapper {
padding-right: $gutter_width;
......
......@@ -92,6 +92,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:akismet_api_key,
:akismet_enabled,
:container_registry_token_expire_delay,
:default_artifacts_expire_in,
:default_branch_protection,
:default_group_visibility,
:default_project_visibility,
......
class Projects::BranchesController < Projects::ApplicationController
include ActionView::Helpers::SanitizeHelper
include SortingHelper
# Authorize
before_action :require_non_empty_project
before_action :require_non_empty_project, except: :create
before_action :authorize_download_code!
before_action :authorize_push_code!, only: [:new, :create, :destroy, :destroy_all_merged]
......@@ -32,6 +33,8 @@ class Projects::BranchesController < Projects::ApplicationController
branch_name = sanitize(strip_tags(params[:branch_name]))
branch_name = Addressable::URI.unescape(branch_name)
redirect_to_autodeploy = project.empty_repo? && project.deployment_services.present?
result = CreateBranchService.new(project, current_user).
execute(branch_name, ref)
......@@ -42,8 +45,15 @@ class Projects::BranchesController < Projects::ApplicationController
if result[:status] == :success
@branch = result[:branch]
redirect_to namespace_project_tree_path(@project.namespace, @project,
@branch.name)
if redirect_to_autodeploy
redirect_to(
url_to_autodeploy_setup(project, branch_name),
notice: view_context.autodeploy_flash_notice(branch_name))
else
redirect_to namespace_project_tree_path(@project.namespace, @project,
@branch.name)
end
else
@error = result[:message]
render action: 'new'
......@@ -76,7 +86,19 @@ class Projects::BranchesController < Projects::ApplicationController
ref_escaped = sanitize(strip_tags(params[:ref]))
Addressable::URI.unescape(ref_escaped)
else
@project.default_branch
@project.default_branch || 'master'
end
end
def url_to_autodeploy_setup(project, branch_name)
namespace_project_new_blob_path(
project.namespace,
project,
branch_name,
file_name: '.gitlab-ci.yml',
commit_message: 'Set up auto deploy',
target_branch: branch_name,
context: 'autodeploy'
)
end
end
......@@ -52,7 +52,7 @@ module IssuablesHelper
field_name: 'issuable_template',
selected: selected_template(issuable),
project_path: ref_project.path,
namespace_path: ref_project.namespace.path
namespace_path: ref_project.namespace.full_path
}
}
......
......@@ -150,6 +150,15 @@ module ProjectsHelper
).html_safe
end
def link_to_autodeploy_doc
link_to 'About auto deploy', help_page_path('ci/autodeploy/index'), target: '_blank'
end
def autodeploy_flash_notice(branch_name)
"Branch <strong>#{truncate(sanitize(branch_name))}</strong> was created. To set up auto deploy, \
choose a GitLab CI Yaml template and commit your changes. #{link_to_autodeploy_doc}".html_safe
end
private
def repo_children_classes(field)
......
......@@ -77,9 +77,17 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
numericality: { only_integer: true, greater_than: 0 }
<<<<<<< HEAD
validates :repository_size_limit,
presence: true,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
=======
validates :max_artifacts_size,
presence: true,
numericality: { only_integer: true, greater_than: 0 }
validates :default_artifacts_expire_in, presence: true, duration: true
>>>>>>> ce/master
validates :container_registry_token_expire_delay,
presence: true,
......@@ -187,6 +195,7 @@ class ApplicationSetting < ActiveRecord::Base
after_sign_up_text: nil,
akismet_enabled: false,
container_registry_token_expire_delay: 5,
default_artifacts_expire_in: '30 days',
default_branch_protection: Settings.gitlab['default_branch_protection'],
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_projects_limit: Settings.gitlab['default_projects_limit'],
......@@ -220,9 +229,9 @@ class ApplicationSetting < ActiveRecord::Base
sign_in_text: nil,
signin_enabled: Settings.gitlab['signin_enabled'],
signup_enabled: Settings.gitlab['signup_enabled'],
terminal_max_session_time: 0,
two_factor_grace_period: 48,
user_default_external: false,
terminal_max_session_time: 0
user_default_external: false
}
end
......@@ -243,6 +252,7 @@ class ApplicationSetting < ActiveRecord::Base
create(defaults)
end
<<<<<<< HEAD
def update_mirror_cron_jobs
Project.mirror.where('sync_time < ?', minimum_mirror_sync_time)
.update_all(sync_time: minimum_mirror_sync_time)
......@@ -254,6 +264,14 @@ class ApplicationSetting < ActiveRecord::Base
def elasticsearch_host
read_attribute(:elasticsearch_host).split(',').map(&:strip)
=======
def self.human_attribute_name(attr, _options = {})
if attr == :default_artifacts_expire_in
'Default artifacts expiration'
else
super
end
>>>>>>> ce/master
end
def home_page_url_column_exist
......
......@@ -485,7 +485,7 @@ module Ci
def artifacts_expire_in=(value)
self.artifacts_expire_at =
if value
Time.now + ChronicDuration.parse(value)
ChronicDuration.parse(value)&.seconds&.from_now
end
end
......
......@@ -21,8 +21,6 @@ class Issue < ActiveRecord::Base
DueThisWeek = DueDateStruct.new('Due This Week', 'week').freeze
DueThisMonth = DueDateStruct.new('Due This Month', 'month').freeze
ActsAsTaggableOn.strict_case_match = true
belongs_to :project
belongs_to :moved_to, class_name: 'Issue'
......
......@@ -64,8 +64,7 @@ class Project < ActiveRecord::Base
after_validation :check_pending_delete
ActsAsTaggableOn.strict_case_match = true
acts_as_taggable_on :tags
acts_as_taggable
attr_accessor :new_default_branch
attr_accessor :old_path_with_namespace
......@@ -399,7 +398,7 @@ class Project < ActiveRecord::Base
end
def reference_pattern
name_pattern = Gitlab::Regex::NAMESPACE_REGEX_STR
name_pattern = Gitlab::Regex::FULL_NAMESPACE_REGEX_STR
%r{
((?<namespace>#{name_pattern})\/)?
......@@ -958,10 +957,6 @@ class Project < ActiveRecord::Base
gitlab_shell.url_to_repo(path_with_namespace)
end
def namespace_dir
namespace.try(:path) || ''
end
def repo_exists?
@repo_exists ||= repository.exists?
rescue
......@@ -1015,8 +1010,8 @@ class Project < ActiveRecord::Base
def rename_repo
path_was = previous_changes['path'].first
old_path_with_namespace = File.join(namespace_dir, path_was)
new_path_with_namespace = File.join(namespace_dir, path)
old_path_with_namespace = File.join(namespace.full_path, path_was)
new_path_with_namespace = File.join(namespace.full_path, path)
Rails.logger.error "Attempting to rename #{old_path_with_namespace} -> #{new_path_with_namespace}"
......
......@@ -364,7 +364,7 @@ class User < ActiveRecord::Base
def reference_pattern
%r{
#{Regexp.escape(reference_prefix)}
(?<user>#{Gitlab::Regex::NAMESPACE_REF_REGEX_STR})
(?<user>#{Gitlab::Regex::FULL_NAMESPACE_REGEX_STR})
}x
end
......
class CreateBranchService < BaseService
def execute(branch_name, ref)
create_master_branch if project.empty_repo?
result = ValidateNewBranchService.new(project, current_user)
.execute(branch_name)
......@@ -19,4 +21,16 @@ class CreateBranchService < BaseService
def success(branch)
super().merge(branch: branch)
end
private
def create_master_branch
project.repository.commit_file(
current_user,
'/README.md',
'',
message: 'Add README.md',
branch_name: 'master',
update: false)
end
end
# DurationValidator
#
# Validate the format conforms with ChronicDuration
#
# Example:
#
# class ApplicationSetting < ActiveRecord::Base
# validates :default_artifacts_expire_in, presence: true, duration: true
# end
#
class DurationValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
ChronicDuration.parse(value)
rescue ChronicDuration::DurationParseError
record.errors.add(attribute, "is not a correct duration")
end
end
......@@ -232,8 +232,16 @@
.col-sm-10
= f.number_field :max_artifacts_size, class: 'form-control'
.help-block
Set the maximum file size each jobs's artifacts can have
= link_to "(?)", help_page_path("user/admin_area/settings/continuous_integration", anchor: "maximum-artifacts-size")
Set the maximum file size for each job's artifacts
= link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size')
.form-group
= f.label :default_artifacts_expire_in, 'Default artifacts expiration', class: 'control-label col-sm-2'
.col-sm-10
= f.text_field :default_artifacts_expire_in, class: 'form-control'
.help-block
Set the default expiration time for each job's artifacts.
0 for unlimited.
= link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'default-artifacts-expiration')
- if Gitlab.config.registry.enabled
%fieldset
......
......@@ -8,7 +8,7 @@
= f.text_field :name, class: "form-control top", required: true, title: "This field is required."
.username.form-group
= f.label :username
= f.text_field :username, class: "form-control middle", pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_SIMPLE, required: true, title: 'Please create a username with only alphanumeric characters.'
= f.text_field :username, class: "form-control middle", pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_JS, required: true, title: 'Please create a username with only alphanumeric characters.'
%p.validation-error.hide Username is already taken.
%p.validation-success.hide Username is available.
%p.validation-pending.hide Checking username availability...
......
......@@ -19,10 +19,10 @@
= line_content
- when :parallel
%td.old_line.diff-line-num{ data: { linenumber: line_old } }
= link_to raw(line_old), "##{line_old}"
%a{ href: "##{line_old}", data: { linenumber: line_old } }
= line_content
%td.new_line.diff-line-num{ data: { linenumber: line_new } }
= link_to raw(line_new), "##{line_new}"
%a{ href: "##{line_new}", data: { linenumber: line_new } }
= line_content
- if @form.unfold? && @form.bottom? && @form.to < @blob.lines.size
......
......@@ -9,7 +9,6 @@
%script#js-board-template{ type: "text/x-template" }= render "projects/boards/components/board"
%script#js-board-list-template{ type: "text/x-template" }= render "projects/boards/components/board_list"
%script#js-board-list-card{ type: "text/x-template" }= render "projects/boards/components/card"
= render "projects/issues/head"
......
%li.card{ ":class" => '{ "user-can-drag": !disabled && issue.id, "is-disabled": disabled || !issue.id, "is-active": issueDetailVisible }',
":index" => "index",
":data-issue-id" => "issue.id",
"@mousedown" => "mouseDown",
"@mousemove" => "mouseMove",
"@mouseup" => "showIssue($event)" }
%issue-card-inner{ ":list" => "list",
":issue" => "issue",
":issue-link-base" => "issueLinkBase",
":root-path" => "rootPath" }
......@@ -10,10 +10,10 @@
- if diff_file.renamed_file
- old_path, new_path = mark_inline_diffs(diff_file.old_path, diff_file.new_path)
%strong.file-title-name.has-tooltip{ data: { title: old_path, container: 'body' } }
%strong.file-title-name.has-tooltip{ data: { title: diff_file.old_path, container: 'body' } }
= old_path
&rarr;
%strong.file-title-name.has-tooltip{ data: { title: new_path, container: 'body' } }
%strong.file-title-name.has-tooltip{ data: { title: diff_file.new_path, container: 'body' } }
= new_path
- else
%strong.file-title-name.has-tooltip{ data: { title: diff_file.new_path, container: 'body' } }
......
......@@ -131,7 +131,7 @@
.form-group
- if @project.avatar?
.avatar-container.s160
= project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160')
= project_icon(@project.full_path, alt: '', class: 'avatar project-avatar s160')
%p.light
- if @project.avatar_in_git
Project avatar in repository: #{ @project.avatar_in_git }
......
......@@ -17,7 +17,7 @@
%strong= parent.full_path + '/'
= f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_SIMPLE,
pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_JS,
title: 'Please choose a group name with no special characters.'
- if parent
= f.hidden_field :parent_id, value: parent.id
......
......@@ -200,7 +200,7 @@
:javascript
gl.IssuableResource = new gl.SubbableResource('#{issuable_json_path(issuable)}');
new gl.IssuableTimeTracking("#{escape_javascript(serialize_issuable(issuable))}");
new MilestoneSelect('{"namespace":"#{@project.namespace.path}","path":"#{@project.path}"}');
new MilestoneSelect('{"full_path":"#{@project.full_path}"}');
new LabelsSelect();
new WeightSelect();
new IssuableContext('#{escape_javascript(current_user.to_json(only: [:username, :id, :name]))}');
......
---
title: Fixes job dropdown action throws error in js console
merge_request: 9182
author:
---
title: Add admin setting for default artifacts expiration
merge_request: 9219
author:
---
title: Disable unused tags count cache for Projects, Builds and Runners
merge_request:
author:
---
title: Remove markup that was showing in tooltip for renamed files
merge_request: 9374
author:
---
title: Fixes includes line number during unfold copy n paste in parallel diff view
merge_request: 9365
author:
---
title: Return 202 with JSON body on async removals on V4 API
merge_request:
author:
---
title: 'API: Remove /groups/owned endpoint'
merge_request: 9505
author: Robert Schilling
---
title: Creating a new branch from an issue will automatically initialize a repository if one doesn't already exist.
merge_request:
author:
ActsAsTaggableOn.strict_case_match = true
# tags_counter enables caching count of tags which results in an update whenever a tag is added or removed
# since the count is not used anywhere its better performance wise to disable this cache
ActsAsTaggableOn.tags_counter = false
class AddDefaultArtifactsExpirationToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :application_settings,
:default_artifacts_expire_in, :string,
null: false, default: '0'
end
end
......@@ -120,7 +120,11 @@ ActiveRecord::Schema.define(version: 20170216141440) do
t.integer "shared_runners_minutes", default: 0, null: false
t.integer "repository_size_limit", limit: 8, default: 0
t.integer "terminal_max_session_time", default: 0, null: false
<<<<<<< HEAD
t.integer "minimum_mirror_sync_time", default: 15, null: false
=======
t.string "default_artifacts_expire_in", default: '0', null: false
>>>>>>> ce/master
end
create_table "approvals", force: :cascade do |t|
......
......@@ -13,7 +13,7 @@ To enable the GitLab monitor exporter:
1. Add or find and uncomment the following line, making sure it's set to `true`:
```ruby
gitlab_monitor_exporter['enable'] = true
gitlab_monitor['enable'] = true
```
1. Save the file and [reconfigure GitLab][reconfigure] for the changes to
......
......@@ -26,22 +26,24 @@ it works.
---
In the case of custom domains, the Pages daemon needs to listen on ports `80`
and/or `443`. For that reason, there is some flexibility in the way which you
can set it up:
In the case of [custom domains](#custom-domains) (but not
[wildcard domains](#wildcard-domains)), the Pages daemon needs to listen on
ports `80` and/or `443`. For that reason, there is some flexibility in the way
which you can set it up:
1. Run the pages daemon in the same server as GitLab, listening on a secondary IP.
1. Run the pages daemon in a separate server. In that case, the
1. Run the Pages daemon in the same server as GitLab, listening on a secondary IP.
1. Run the Pages daemon in a separate server. In that case, the
[Pages path](#change-storage-path) must also be present in the server that
the pages daemon is installed, so you will have to share it via network.
1. Run the pages daemon in the same server as GitLab, listening on the same IP
the Pages daemon is installed, so you will have to share it via network.
1. Run the Pages daemon in the same server as GitLab, listening on the same IP
but on different ports. In that case, you will have to proxy the traffic with
a loadbalancer. If you choose that route note that you should use TCP load
balancing for HTTPS. If you use TLS-termination (HTTPS-load balancing) the
pages will not be able to be served with user provided certificates. For
HTTP it's OK to use HTTP or TCP load balancing.
In this document, we will proceed assuming the first option.
In this document, we will proceed assuming the first option. If you are not
supporting custom domains a secondary IP is not needed.
## Prerequisites
......@@ -54,6 +56,7 @@ Before proceeding with the Pages configuration, you will need to:
serve Pages under HTTPS.
1. (Optional but recommended) Enable [Shared runners](../../ci/runners/README.md)
so that your users don't have to bring their own.
1. (Only for custom domains) Have a **secondary IP**.
### DNS configuration
......@@ -150,7 +153,7 @@ that without TLS certificates.
>
URL scheme: `http://page.example.io` and `http://domain.com`
In that case, the pages daemon is running, Nginx still proxies requests to
In that case, the Pages daemon is running, Nginx still proxies requests to
the daemon but the daemon is also able to receive requests from the outside
world. Custom domains are supported, but no TLS.
......@@ -179,7 +182,7 @@ world. Custom domains are supported, but no TLS.
>
URL scheme: `https://page.example.io` and `https://domain.com`
In that case, the pages daemon is running, Nginx still proxies requests to
In that case, the Pages daemon is running, Nginx still proxies requests to
the daemon but the daemon is also able to receive requests from the outside
world. Custom domains and TLS are supported.
......
......@@ -69,7 +69,9 @@ please consult [RFC 5322](https://tools.ietf.org/html/rfc5322#section-3.6.4).
If you want to use Gmail / Google Apps with Reply by email, make sure you have
[IMAP access enabled](https://support.google.com/mail/troubleshooter/1668960?hl=en#ts=1665018)
and [allowed less secure apps to access the account](https://support.google.com/accounts/answer/6010255).
and [allowed less secure apps to access the account](https://support.google.com/accounts/answer/6010255)
or [turn-on 2-step validation](https://support.google.com/accounts/answer/185839)
and use [an application password](https://support.google.com/mail/answer/185833).
To set up a basic Postfix mail server with IMAP access on Ubuntu, follow the
[Postfix setup documentation](reply_by_email_postfix_setup.md).
......
......@@ -14,6 +14,7 @@ Parameters:
| `order_by` | string | no | Order groups by `name` or `path`. Default is `name` |
| `sort` | string | no | Order groups in `asc` or `desc` order. Default is `asc` |
| `statistics` | boolean | no | Include group statistics (admins only) |
| `owned` | boolean | no | Limit by groups owned by the current user |
```
GET /groups
......@@ -40,20 +41,6 @@ GET /groups
You can search for groups by name or path, see below.
## List owned groups
Get a list of groups which are owned by the authenticated user.
```
GET /groups/owned
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `statistics` | boolean | no | Include group statistics |
## List a group's projects
Get a list of projects in this group.
......
......@@ -42,3 +42,5 @@ changes are in V4:
- Remove `public` param from create and edit actions of projects [!8736](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8736)
- Remove the ProjectGitHook API. Use the ProjectPushRule API instead [!1301](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1301)
- Notes do not return deprecated field `upvote` and `downvote` [!9384](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9384)
- Remove `GET /groups/owned`. Use `GET /groups?owned=true` instead [!9505](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9505)
- Return 202 with JSON body on async removals on V4 API (DELETE `/projects/:id/repository/merged_branches` and DELETE `/projects/:id`) [!9449](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9449)
\ No newline at end of file
......@@ -148,7 +148,8 @@ available in the build environment. It's the recommended method to use for
storing things like passwords, secret keys and credentials.
Secret variables can be added by going to your project's
**Settings ➔ Variables ➔ Add variable**.
**Settings ➔ CI/CD Pipelines**, then finding the section called
**Secret Variables**.
Once you set them, they will be available for all subsequent jobs.
......
......@@ -54,7 +54,7 @@ for initial settings.
gitlab_rails['omniauth_providers'] = [
{
"name" => "auth0",
"args" => { client_id: 'YOUR_AUTH0_CLIENT_ID'',
"args" => { client_id: 'YOUR_AUTH0_CLIENT_ID',
client_secret: 'YOUR_AUTH0_CLIENT_SECRET',
namespace: 'YOUR_AUTH0_DOMAIN'
}
......
......@@ -74,7 +74,7 @@ in your SAML IdP:
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
idp_sso_target_url: 'https://login.example.com/idp',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
},
label: 'Company Login' # optional label for SAML login button, defaults to "Saml"
}
......@@ -91,7 +91,7 @@ in your SAML IdP:
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
idp_sso_target_url: 'https://login.example.com/idp',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
},
label: 'Company Login' # optional label for SAML login button, defaults to "Saml"
}
......@@ -172,7 +172,7 @@ tell GitLab which groups are external via the `external_groups:` element:
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
idp_sso_target_url: 'https://login.example.com/idp',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
} }
```
......@@ -251,7 +251,7 @@ args: {
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
idp_sso_target_url: 'https://login.example.com/idp',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
attribute_statements: { email: ['EmailAddress'] }
}
```
......@@ -269,7 +269,7 @@ args: {
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
idp_sso_target_url: 'https://login.example.com/idp',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
attribute_statements: { email: ['EmailAddress'] },
allowed_clock_drift: 1 # for one second clock drift
}
......
......@@ -3,19 +3,20 @@
## Maximum artifacts size
The maximum size of the [job artifacts][art-yml] can be set in the Admin area
of your GitLab instance. The value is in MB and the default is 100MB. Note that
this setting is set for each job.
of your GitLab instance. The value is in *MB* and the default is 100MB. Note
that this setting is set for each job.
1. Go to the **Admin area ➔ Settings** (`/admin/application_settings`).
![Admin area settings button](img/admin_area_settings_button.png)
1. Change the value of the maximum artifacts size (in MB):
1. Change the value of maximum artifacts size (in MB):
![Admin area maximum artifacts size](img/admin_area_maximum_artifacts_size.png)
1. Hit **Save** for the changes to take effect.
<<<<<<< HEAD
## Shared Runners build minutes quota
> [Introduced][ee-1078] in GitLab Enterprise Edition 8.16.
......@@ -72,3 +73,25 @@ the group.
[art-yml]: ../../../administration/job_artifacts.md
[ee-1078]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1078
=======
## Default artifacts expiration
The default expiration time of the [job artifacts][art-yml] can be set in
the Admin area of your GitLab instance. The syntax of duration is described
in [artifacts:expire_in][duration-syntax]. The default is `30 days`. Note that
this setting is set for each job. Set it to 0 if you don't want default
expiration.
1. Go to **Admin area > Settings** (`/admin/application_settings`).
![Admin area settings button](img/admin_area_settings_button.png)
1. Change the value of default expiration time ([syntax][duration-syntax]):
![Admin area default artifacts expiration](img/admin_area_default_artifacts_expiration.png)
1. Hit **Save** for the changes to take effect.
[art-yml]: ../../../administration/job_artifacts.md
[duration-syntax]: ../../../ci/yaml/README.md#artifactsexpire_in
>>>>>>> ce/master
......@@ -10,6 +10,7 @@ module API
mount ::API::V3::Commits
mount ::API::V3::DeployKeys
mount ::API::V3::Files
mount ::API::V3::Groups
mount ::API::V3::Issues
mount ::API::V3::Labels
mount ::API::V3::Members
......
......@@ -137,7 +137,7 @@ module API
delete ":id/repository/merged_branches" do
DeleteMergedBranchesService.new(user_project, current_user).async_execute
status(200)
accepted!
end
end
end
......
......@@ -610,6 +610,7 @@ module API
expose :default_project_visibility
expose :default_snippet_visibility
expose :default_group_visibility
expose :default_artifacts_expire_in
expose :domain_whitelist
expose :domain_blacklist_enabled
expose :domain_blacklist
......
......@@ -44,12 +44,15 @@ module API
optional :skip_groups, type: Array[Integer], desc: 'Array of group ids to exclude from list'
optional :all_available, type: Boolean, desc: 'Show all group that you have access to'
optional :search, type: String, desc: 'Search for a specific group'
optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user'
optional :order_by, type: String, values: %w[name path], default: 'name', desc: 'Order by name or path'
optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)'
use :pagination
end
get do
groups = if current_user.admin
groups = if params[:owned]
current_user.owned_groups
elsif current_user.admin
Group.all
elsif params[:all_available]
GroupsFinder.new.execute(current_user)
......@@ -64,17 +67,6 @@ module API
present_groups groups, statistics: params[:statistics] && current_user.is_admin?
end
desc 'Get list of owned groups for authenticated user' do
success Entities::Group
end
params do
use :pagination
use :statistics_params
end
get '/owned' do
present_groups current_user.owned_groups, statistics: params[:statistics]
end
desc 'Create a group. Available only for users who can create groups.' do
success Entities::Group
end
......
......@@ -216,6 +216,10 @@ module API
render_api_error!('204 No Content', 204)
end
def accepted!
render_api_error!('202 Accepted', 202)
end
def render_validation_error!(model)
if model.errors.any?
render_api_error!(model.errors.messages || '400 Bad Request', 400)
......
......@@ -288,6 +288,8 @@ module API
delete ":id" do
authorize! :remove_project, user_project
::Projects::DestroyService.new(user_project, current_user, {}).async_execute
accepted!
end
desc 'Mark this project as forked from another'
......
......@@ -56,7 +56,8 @@ module API
given shared_runners_enabled: ->(val) { val } do
requires :shared_runners_text, type: String, desc: 'Shared runners text '
end
optional :max_artifacts_size, type: Integer, desc: "Set the maximum file size each build's artifacts can have"
optional :max_artifacts_size, type: Integer, desc: "Set the maximum file size for each job's artifacts"
optional :default_artifacts_expire_in, type: String, desc: "Set the default expiration time for each job's artifacts"
optional :max_pages_size, type: Integer, desc: 'Maximum size of pages in MB'
optional :container_registry_token_expire_delay, type: Integer, desc: 'Authorization token duration (minutes)'
optional :metrics_enabled, type: Boolean, desc: 'Enable the InfluxDB metrics'
......@@ -130,7 +131,9 @@ module API
:send_user_confirmation_email, :domain_whitelist, :domain_blacklist_enabled,
:after_sign_up_text, :signin_enabled, :require_two_factor_authentication,
:home_page_url, :after_sign_out_path, :sign_in_text, :help_page_text,
:shared_runners_enabled, :max_artifacts_size, :max_pages_size, :container_registry_token_expire_delay,
:shared_runners_enabled, :max_artifacts_size,
:default_artifacts_expire_in, :max_pages_size,
:container_registry_token_expire_delay,
:metrics_enabled, :sidekiq_throttling_enabled, :recaptcha_enabled,
:akismet_enabled, :admin_notification_email, :sentry_enabled,
:repository_checks_enabled, :koding_enabled, :housekeeping_enabled, :terminal_max_session_time, :plantuml_enabled,
......
......@@ -21,14 +21,9 @@ module API
unauthorized! unless trigger.project == project
# validate variables
variables = params[:variables]
if variables
unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) }
render_api_error!('variables needs to be a map of key-valued strings', 400)
end
# convert variables from Mash to Hash
variables = variables.to_h
variables = params[:variables].to_h
unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) }
render_api_error!('variables needs to be a map of key-valued strings', 400)
end
# create request and trigger builds
......
......@@ -18,6 +18,13 @@ module API
present branches, with: ::API::Entities::RepoBranch, project: user_project
end
desc 'Delete all merged branches'
delete ":id/repository/merged_branches" do
DeleteMergedBranchesService.new(user_project, current_user).async_execute
status(200)
end
end
end
end
......
module API
module V3
class Groups < Grape::API
include PaginationParams
before { authenticate! }
helpers do
params :statistics_params do
optional :statistics, type: Boolean, default: false, desc: 'Include project statistics'
end
def present_groups(groups, options = {})
options = options.reverse_merge(
with: ::API::Entities::Group,
current_user: current_user,
)
groups = groups.with_statistics if options[:statistics]
present paginate(groups), options
end
end
resource :groups do
desc 'Get list of owned groups for authenticated user' do
success ::API::Entities::Group
end
params do
use :pagination
use :statistics_params
end
get '/owned' do
present_groups current_user.owned_groups, statistics: params[:statistics]
end
end
end
end
end
......@@ -167,7 +167,10 @@ module Ci
build.artifacts_file = artifacts
build.artifacts_metadata = metadata
build.artifacts_expire_in = params['expire_in']
build.artifacts_expire_in =
params['expire_in'] ||
Gitlab::CurrentSettings.current_application_settings
.default_artifacts_expire_in
if build.save
present(build, with: Entities::BuildDetails)
......
......@@ -35,7 +35,7 @@ module Gitlab
end
def export_filename(project:)
basename = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_#{project.namespace.full_path}_#{project.path}"
basename = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_#{project.full_path.tr('/', '_')}"
"#{basename[0..FILENAME_LIMIT]}_export.tar.gz"
end
......
......@@ -5,17 +5,18 @@ module Gitlab
# The namespace regex is used in Javascript to validate usernames in the "Register" form. However, Javascript
# does not support the negative lookbehind assertion (?<!) that disallows usernames ending in `.git` and `.atom`.
# Since this is a non-trivial problem to solve in Javascript (heavily complicate the regex, modify view code to
# allow non-regex validatiions, etc), `NAMESPACE_REGEX_STR_SIMPLE` serves as a Javascript-compatible version of
# allow non-regex validatiions, etc), `NAMESPACE_REGEX_STR_JS` serves as a Javascript-compatible version of
# `NAMESPACE_REGEX_STR`, with the negative lookbehind assertion removed. This means that the client-side validation
# will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation.
PATH_REGEX_STR = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*'.freeze
NAMESPACE_REGEX_STR_SIMPLE = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
NAMESPACE_REGEX_STR = '(?:' + NAMESPACE_REGEX_STR_SIMPLE + ')(?<!\.git|\.atom)'.freeze
PROJECT_REGEX_STR = PATH_REGEX_STR + '(?<!\.git|\.atom)'.freeze
NAMESPACE_REGEX_STR_JS = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
NO_SUFFIX_REGEX_STR = '(?<!\.git|\.atom)'.freeze
NAMESPACE_REGEX_STR = "(?:#{NAMESPACE_REGEX_STR_JS})#{NO_SUFFIX_REGEX_STR}".freeze
PROJECT_REGEX_STR = "(?:#{PATH_REGEX_STR})#{NO_SUFFIX_REGEX_STR}".freeze
# Same as NAMESPACE_REGEX_STR but allows `/` in the path.
# So `group/subgroup` will match this regex but not NAMESPACE_REGEX_STR
NAMESPACE_REF_REGEX_STR = '(?:[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.\/]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_])(?<!\.git|\.atom)'.freeze
FULL_NAMESPACE_REGEX_STR = "(?:#{NAMESPACE_REGEX_STR}/)*#{NAMESPACE_REGEX_STR}".freeze
def namespace_regex
@namespace_regex ||= /\A#{NAMESPACE_REGEX_STR}\z/.freeze
......
......@@ -19,8 +19,8 @@ describe Projects::BlobController do
before do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: id)
end
......@@ -50,8 +50,8 @@ describe Projects::BlobController do
before do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: id)
controller.instance_variable_set(:@blob, nil)
end
......
......@@ -16,8 +16,8 @@ describe Projects::BlameController do
before do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: id)
end
......
......@@ -14,8 +14,8 @@ describe Projects::BlobController do
render_views
def do_get(opts = {})
params = { namespace_id: project.namespace.to_param,
project_id: project.to_param,
params = { namespace_id: project.namespace,
project_id: project,
id: 'master/CHANGELOG' }
get :diff, params.merge(opts)
end
......@@ -40,8 +40,8 @@ describe Projects::BlobController do
describe 'PUT update' do
let(:default_params) do
{
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: 'master/CHANGELOG',
target_branch: 'master',
content: 'Added changes',
......@@ -96,8 +96,8 @@ describe Projects::BlobController do
context 'when editing on the fork' do
before do
default_params[:namespace_id] = forked_project.namespace.to_param
default_params[:project_id] = forked_project.to_param
default_params[:namespace_id] = forked_project.namespace
default_params[:project_id] = forked_project
end
it 'redirects to blob' do
......
......@@ -90,7 +90,7 @@ describe Projects::Boards::IssuesController do
params = {
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
list_id: list.try(:to_param)
}
......@@ -162,7 +162,7 @@ describe Projects::Boards::IssuesController do
sign_in(user)
post :create, namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
list_id: list.to_param,
issue: { title: title },
......@@ -225,7 +225,7 @@ describe Projects::Boards::IssuesController do
sign_in(user)
patch :update, namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
id: issue.to_param,
from_list_id: from_list_id,
......
......@@ -47,7 +47,7 @@ describe Projects::Boards::ListsController do
sign_in(user)
get :index, namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
format: :json
end
......@@ -104,7 +104,7 @@ describe Projects::Boards::ListsController do
sign_in(user)
post :create, namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
list: { label_id: label_id },
format: :json
......@@ -157,7 +157,7 @@ describe Projects::Boards::ListsController do
sign_in(user)
patch :update, namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
id: list.to_param,
list: { position: position },
......@@ -200,7 +200,7 @@ describe Projects::Boards::ListsController do
sign_in(user)
delete :destroy, namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
id: list.to_param,
format: :json
......@@ -244,7 +244,7 @@ describe Projects::Boards::ListsController do
sign_in(user)
post :generate, namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
board_id: board.to_param,
format: :json
end
......
......@@ -65,8 +65,8 @@ describe Projects::BoardsController do
end
def list_boards(format: :html)
get :index, namespace_id: project.namespace.to_param,
project_id: project.to_param,
get :index, namespace_id: project.namespace,
project_id: project,
format: format
end
end
......@@ -130,8 +130,8 @@ describe Projects::BoardsController do
end
def read_board(board:, format: :html)
get :show, namespace_id: project.namespace.to_param,
project_id: project.to_param,
get :show, namespace_id: project.namespace,
project_id: project,
id: board.to_param,
format: format
end
......
......@@ -22,8 +22,8 @@ describe Projects::BranchesController do
sign_in(user)
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
branch_name: branch,
ref: ref
end
......@@ -68,7 +68,7 @@ describe Projects::BranchesController do
describe "created from the new branch button on issues" do
let(:branch) { "1-feature-branch" }
let!(:issue) { create(:issue, project: project) }
let(:issue) { create(:issue, project: project) }
before do
sign_in(user)
......@@ -76,8 +76,8 @@ describe Projects::BranchesController do
it 'redirects' do
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
branch_name: branch,
issue_iid: issue.iid
......@@ -89,12 +89,49 @@ describe Projects::BranchesController do
expect(SystemNoteService).to receive(:new_issue_branch).with(issue, project, user, "1-feature-branch")
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
branch_name: branch,
issue_iid: issue.iid
end
context 'repository-less project' do
let(:project) { create :empty_project }
it 'redirects to newly created branch' do
result = { status: :success, branch: double(name: branch) }
expect_any_instance_of(CreateBranchService).to receive(:execute).and_return(result)
expect(SystemNoteService).to receive(:new_issue_branch).and_return(true)
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
branch_name: branch,
issue_iid: issue.iid
expect(response).to redirect_to namespace_project_tree_path(project.namespace, project, branch)
end
it 'redirects to autodeploy setup page' do
result = { status: :success, branch: double(name: branch) }
project.services << build(:kubernetes_service)
expect_any_instance_of(CreateBranchService).to receive(:execute).and_return(result)
expect(SystemNoteService).to receive(:new_issue_branch).and_return(true)
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
branch_name: branch,
issue_iid: issue.iid
expect(response.location).to include(namespace_project_new_blob_path(project.namespace, project, branch))
expect(response).to have_http_status(302)
end
end
context 'without issue feature access' do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
......@@ -106,8 +143,8 @@ describe Projects::BranchesController do
expect(SystemNoteService).not_to receive(:new_issue_branch)
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
branch_name: branch,
issue_iid: issue.iid
end
......@@ -126,8 +163,8 @@ describe Projects::BranchesController do
post :destroy,
format: :html,
id: 'foo/bar/baz',
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
expect(response).to have_http_status(303)
end
......@@ -142,8 +179,8 @@ describe Projects::BranchesController do
post :destroy,
format: :js,
id: branch,
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
end
context "valid branch name, valid source" do
......@@ -173,8 +210,8 @@ describe Projects::BranchesController do
describe "DELETE destroy_all_merged" do
def destroy_all_merged
delete :destroy_all_merged,
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
end
context 'when user is allowed to push' do
......
......@@ -17,8 +17,8 @@ describe Projects::CommitController do
def go(extra_params = {})
params = {
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
}
get :show, params.merge(extra_params)
......@@ -125,8 +125,8 @@ describe Projects::CommitController do
it 'renders it' do
get(:show,
namespace_id: fork_project.namespace.to_param,
project_id: fork_project.to_param,
namespace_id: fork_project.namespace,
project_id: fork_project,
id: commit.id)
expect(response).to be_success
......@@ -139,8 +139,8 @@ describe Projects::CommitController do
commit = project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
get(:branches,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: commit.id)
expect(assigns(:branches)).to include("master", "feature_conflict")
......@@ -152,8 +152,8 @@ describe Projects::CommitController do
context 'when target branch is not provided' do
it 'renders the 404 page' do
post(:revert,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: commit.id)
expect(response).not_to be_success
......@@ -164,8 +164,8 @@ describe Projects::CommitController do
context 'when the revert was successful' do
it 'redirects to the commits page' do
post(:revert,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
target_branch: 'master',
id: commit.id)
......@@ -177,8 +177,8 @@ describe Projects::CommitController do
context 'when the revert failed' do
before do
post(:revert,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
target_branch: 'master',
id: commit.id)
end
......@@ -186,8 +186,8 @@ describe Projects::CommitController do
it 'redirects to the commit page' do
# Reverting a commit that has been already reverted.
post(:revert,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
target_branch: 'master',
id: commit.id)
......@@ -201,8 +201,8 @@ describe Projects::CommitController do
context 'when target branch is not provided' do
it 'renders the 404 page' do
post(:cherry_pick,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: master_pickable_commit.id)
expect(response).not_to be_success
......@@ -213,8 +213,8 @@ describe Projects::CommitController do
context 'when the cherry-pick was successful' do
it 'redirects to the commits page' do
post(:cherry_pick,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
target_branch: 'master',
id: master_pickable_commit.id)
......@@ -226,8 +226,8 @@ describe Projects::CommitController do
context 'when the cherry_pick failed' do
before do
post(:cherry_pick,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
target_branch: 'master',
id: master_pickable_commit.id)
end
......@@ -235,8 +235,8 @@ describe Projects::CommitController do
it 'redirects to the commit page' do
# Cherry-picking a commit that has been already cherry-picked.
post(:cherry_pick,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
target_branch: 'master',
id: master_pickable_commit.id)
......@@ -249,8 +249,8 @@ describe Projects::CommitController do
describe 'GET diff_for_path' do
def diff_for_path(extra_params = {})
params = {
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
}
get :diff_for_path, params.merge(extra_params)
......@@ -313,8 +313,8 @@ describe Projects::CommitController do
describe 'GET pipelines' do
def get_pipelines(extra_params = {})
params = {
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
}
get :pipelines, params.merge(extra_params)
......
......@@ -16,8 +16,8 @@ describe Projects::CommitsController do
context "when the ref does not exist with the suffix" do
it "renders as atom" do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: "master.atom")
expect(response).to be_success
......@@ -33,8 +33,8 @@ describe Projects::CommitsController do
allow_any_instance_of(Repository).to receive(:commit).with('master.atom').and_return(commit)
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: "master.atom")
end
......
......@@ -13,8 +13,8 @@ describe Projects::CompareController do
it 'compare shows some diffs' do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
from: ref_from,
to: ref_to)
......@@ -25,8 +25,8 @@ describe Projects::CompareController do
it 'compare shows some diffs with ignore whitespace change option' do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
from: '08f22f25',
to: '66eceea0',
w: 1)
......@@ -43,8 +43,8 @@ describe Projects::CompareController do
describe 'non-existent refs' do
it 'uses invalid source ref' do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
from: 'non-existent',
to: ref_to)
......@@ -55,8 +55,8 @@ describe Projects::CompareController do
it 'uses invalid target ref' do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
from: ref_from,
to: 'non-existent')
......@@ -67,8 +67,8 @@ describe Projects::CompareController do
it 'redirects back to index when params[:from] is empty and preserves params[:to]' do
post(:create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
from: '',
to: 'master')
......@@ -77,8 +77,8 @@ describe Projects::CompareController do
it 'redirects back to index when params[:to] is empty and preserves params[:from]' do
post(:create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
from: 'master',
to: '')
......@@ -87,8 +87,8 @@ describe Projects::CompareController do
it 'redirects back to index when params[:from] and params[:to] are empty' do
post(:create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
from: '',
to: '')
......@@ -99,8 +99,8 @@ describe Projects::CompareController do
describe 'GET diff_for_path' do
def diff_for_path(extra_params = {})
params = {
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
}
get :diff_for_path, params.merge(extra_params)
......
......@@ -13,8 +13,8 @@ describe Projects::CycleAnalyticsController do
context 'with no data' do
it 'is true' do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param)
namespace_id: project.namespace,
project_id: project)
expect(response).to be_success
expect(assigns(:cycle_analytics_no_data)).to eq(true)
......@@ -32,8 +32,8 @@ describe Projects::CycleAnalyticsController do
it 'is false' do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param)
namespace_id: project.namespace,
project_id: project)
expect(response).to be_success
expect(assigns(:cycle_analytics_no_data)).to eq(false)
......
......@@ -17,8 +17,8 @@ describe Projects::FindFileController do
before do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: id)
end
......@@ -36,8 +36,8 @@ describe Projects::FindFileController do
describe "GET #list" do
def go(format: 'json')
get :list,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
id: id,
format: format
end
......
......@@ -9,8 +9,8 @@ describe Projects::ForksController do
describe 'GET index' do
def get_forks
get :index,
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
end
context 'when fork is public' do
......@@ -71,8 +71,8 @@ describe Projects::ForksController do
describe 'GET new' do
def get_new
get :new,
namespace_id: project.namespace.to_param,
project_id: project.to_param
namespace_id: project.namespace,
project_id: project
end
context 'when user is signed in' do
......@@ -99,8 +99,8 @@ describe Projects::ForksController do
describe 'POST create' do
def post_create
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
namespace_id: project.namespace,
project_id: project,
namespace_key: user.namespace.id
end
......
......@@ -34,7 +34,7 @@ describe Projects::GraphsController do
end
it 'sets the correct colour according to language' do
get(:languages, namespace_id: project.namespace.path, project_id: project.path, id: 'master')
get(:languages, namespace_id: project.namespace, project_id: project, id: 'master')
expected_values.each do |val|
expect(assigns(:languages)).to include(a_hash_including(val))
......
......@@ -14,8 +14,8 @@ describe Projects::GroupLinksController do
describe '#create' do
shared_context 'link project to group' do
before do
post(:create, namespace_id: project.namespace.to_param,
project_id: project.to_param,
post(:create, namespace_id: project.namespace,
project_id: project,
link_group_id: group.id,
link_group_access: ProjectGroupLink.default_access)
end
......@@ -50,8 +50,8 @@ describe Projects::GroupLinksController do
context 'when project group id equal link group id' do
before do
post(:create, namespace_id: project.namespace.to_param,
project_id: project.to_param,
post(:create, namespace_id: project.namespace,
project_id: project,
link_group_id: group2.id,
link_group_access: ProjectGroupLink.default_access)
end
......@@ -69,8 +69,8 @@ describe Projects::GroupLinksController do
context 'when link group id is not present' do
before do
post(:create, namespace_id: project.namespace.to_param,
project_id: project.to_param,
post(:create, namespace_id: project.namespace,
project_id: project,
link_group_access: ProjectGroupLink.default_access)
end
......
......@@ -13,13 +13,13 @@ describe Projects::ImportsController do
end
it 'renders template' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param
get :show, namespace_id: project.namespace.to_param, project_id: project
expect(response).to render_template :show
end
it 'sets flash.now if params is present' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param, continue: { to: '/', notice_now: 'Started' }
get :show, namespace_id: project.namespace.to_param, project_id: project, continue: { to: '/', notice_now: 'Started' }
expect(flash.now[:notice]).to eq 'Started'
end
......@@ -39,13 +39,13 @@ describe Projects::ImportsController do
end
it 'renders template' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param
get :show, namespace_id: project.namespace.to_param, project_id: project
expect(response).to render_template :show
end
it 'sets flash.now if params is present' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param, continue: { to: '/', notice_now: 'In progress' }
get :show, namespace_id: project.namespace.to_param, project_id: project, continue: { to: '/', notice_now: 'In progress' }
expect(flash.now[:notice]).to eq 'In progress'
end
......@@ -57,7 +57,7 @@ describe Projects::ImportsController do
end
it 'redirects to new_namespace_project_import_path' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param
get :show, namespace_id: project.namespace.to_param, project_id: project
expect(response).to redirect_to new_namespace_project_import_path(project.namespace, project)
end
......@@ -72,7 +72,7 @@ describe Projects::ImportsController do
it 'redirects to namespace_project_path' do
allow_any_instance_of(Project).to receive(:forked?).and_return(true)
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param
get :show, namespace_id: project.namespace.to_param, project_id: project
expect(flash[:notice]).to eq 'The project was successfully forked.'
expect(response).to redirect_to namespace_project_path(project.namespace, project)
......@@ -81,7 +81,7 @@ describe Projects::ImportsController do
context 'when project is external' do
it 'redirects to namespace_project_path' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param
get :show, namespace_id: project.namespace.to_param, project_id: project
expect(flash[:notice]).to eq 'The project was successfully imported.'
expect(response).to redirect_to namespace_project_path(project.namespace, project)
......@@ -97,7 +97,7 @@ describe Projects::ImportsController do
end
it 'redirects to params[:to]' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param, continue: params
get :show, namespace_id: project.namespace.to_param, project_id: project, continue: params
expect(flash[:notice]).to eq params[:notice]
expect(response).to redirect_to params[:to]
......@@ -111,7 +111,7 @@ describe Projects::ImportsController do
end
it 'redirects to namespace_project_path' do
get :show, namespace_id: project.namespace.to_param, project_id: project.to_param
get :show, namespace_id: project.namespace.to_param, project_id: project
expect(response).to redirect_to namespace_project_path(project.namespace, project)
end
......
......@@ -12,7 +12,7 @@ describe Projects::IssuesController do
allow(project).to receive(:external_issue_tracker).and_return(external)
controller.instance_variable_set(:@project, project)
get :index, namespace_id: project.namespace.path, project_id: project
get :index, namespace_id: project.namespace, project_id: project
expect(response).to redirect_to('https://example.com/project')
end
......@@ -27,13 +27,13 @@ describe Projects::IssuesController do
it_behaves_like "issuables list meta-data", :issue
it "returns index" do
get :index, namespace_id: project.namespace.path, project_id: project.path
get :index, namespace_id: project.namespace, project_id: project
expect(response).to have_http_status(200)
end
it "returns 301 if request path doesn't match project path" do
get :index, namespace_id: project.namespace.path, project_id: project.path.upcase
get :index, namespace_id: project.namespace, project_id: project.path.upcase
expect(response).to redirect_to(namespace_project_issues_path(project.namespace, project))
end
......@@ -42,7 +42,7 @@ describe Projects::IssuesController do
project.issues_enabled = false
project.save
get :index, namespace_id: project.namespace.path, project_id: project.path
get :index, namespace_id: project.namespace, project_id: project
expect(response).to have_http_status(404)
end
......@@ -50,7 +50,7 @@ describe Projects::IssuesController do
controller.instance_variable_set(:@project, project)
allow(project).to receive(:default_issues_tracker?).and_return(false)
get :index, namespace_id: project.namespace.path, project_id: project.path
get :index, namespace_id: project.namespace, project_id: project
expect(response).to have_http_status(404)
end
end
......@@ -67,8 +67,8 @@ describe Projects::IssuesController do
it 'redirects to last_page if page number is larger than number of pages' do
get :index,
namespace_id: project.namespace.path.to_param,
project_id: project.path.to_param,
namespace_id: project.namespace.to_param,
project_id: project,
page: (last_page + 1).to_param
expect(response).to redirect_to(namespace_project_issues_path(page: last_page, state: controller.params[:state], scope: controller.params[:scope]))
......@@ -76,8 +76,8 @@ describe Projects::IssuesController do
it 'redirects to specified page' do
get :index,
namespace_id: project.namespace.path.to_param,
project_id: project.path.to_param,
namespace_id: project.namespace.to_param,
project_id: project,
page: last_page.to_param
expect(assigns(:issues).current_page).to eq(last_page)
......@@ -94,7 +94,7 @@ describe Projects::IssuesController do
end
it 'builds a new issue' do
get :new, namespace_id: project.namespace.path, project_id: project
get :new, namespace_id: project.namespace, project_id: project
expect(assigns(:issue)).to be_a_new(Issue)
end
......@@ -104,7 +104,7 @@ describe Projects::IssuesController do
project_with_repository.team << [user, :developer]
mr = create(:merge_request_with_diff_notes, source_project: project_with_repository)
get :new, namespace_id: project_with_repository.namespace.path, project_id: project_with_repository, merge_request_for_resolving_discussions: mr.iid
get :new, namespace_id: project_with_repository.namespace, project_id: project_with_repository, merge_request_for_resolving_discussions: mr.iid
expect(assigns(:issue).title).not_to be_empty
expect(assigns(:issue).description).not_to be_empty
......@@ -117,7 +117,7 @@ describe Projects::IssuesController do
allow(project).to receive(:external_issue_tracker).and_return(external)
controller.instance_variable_set(:@project, project)
get :new, namespace_id: project.namespace.path, project_id: project
get :new, namespace_id: project.namespace, project_id: project
expect(response).to redirect_to('https://example.com/issues/new')
end
......@@ -251,7 +251,7 @@ describe Projects::IssuesController do
def update_issue(issue_params = {}, additional_params = {})
params = {
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: issue.iid,
issue: issue_params
}.merge(additional_params)
......@@ -262,7 +262,7 @@ describe Projects::IssuesController do
def move_issue
put :update,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: issue.iid,
issue: { title: 'New title' },
move_to_project_id: another_project.id
......@@ -342,7 +342,7 @@ describe Projects::IssuesController do
def get_issues
get :index,
namespace_id: project.namespace.to_param,
project_id: project.to_param
project_id: project
end
end
......@@ -405,7 +405,7 @@ describe Projects::IssuesController do
def go(id:)
get :show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: id
end
end
......@@ -416,7 +416,7 @@ describe Projects::IssuesController do
def go(id:)
get :edit,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: id
end
end
......@@ -427,7 +427,7 @@ describe Projects::IssuesController do
def go(id:)
put :update,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: id,
issue: { title: 'New title' }
end
......@@ -442,7 +442,7 @@ describe Projects::IssuesController do
post :create, {
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
issue: { title: 'Title', description: 'Description' }.merge(issue_attrs)
}.merge(additional_params)
......@@ -464,7 +464,7 @@ describe Projects::IssuesController do
end
def post_issue(issue_params)
post :create, namespace_id: project.namespace.to_param, project_id: project.to_param, issue: issue_params, merge_request_for_resolving_discussions: merge_request.iid
post :create, namespace_id: project.namespace.to_param, project_id: project, issue: issue_params, merge_request_for_resolving_discussions: merge_request.iid
end
it 'creates an issue for the project' do
......@@ -607,8 +607,8 @@ describe Projects::IssuesController do
project.team << [admin, :master]
sign_in(admin)
post :mark_as_spam, {
namespace_id: project.namespace.path,
project_id: project.path,
namespace_id: project.namespace,
project_id: project,
id: issue.iid
}
end
......@@ -624,7 +624,7 @@ describe Projects::IssuesController do
context "when the user is a developer" do
before { sign_in(user) }
it "rejects a developer to destroy an issue" do
delete :destroy, namespace_id: project.namespace.path, project_id: project.path, id: issue.iid
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
expect(response).to have_http_status(404)
end
end
......@@ -637,7 +637,7 @@ describe Projects::IssuesController do
before { sign_in(owner) }
it "deletes the issue" do
delete :destroy, namespace_id: project.namespace.path, project_id: project.path, id: issue.iid
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
expect(response).to have_http_status(302)
expect(controller).to set_flash[:notice].to(/The issue was successfully deleted\./).now
......@@ -646,7 +646,7 @@ describe Projects::IssuesController do
it 'delegates the update of the todos count cache to TodoService' do
expect_any_instance_of(TodoService).to receive(:destroy_issue).with(issue, owner).once
delete :destroy, namespace_id: project.namespace.path, project_id: project.path, id: issue.iid
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
end
end
end
......@@ -659,8 +659,8 @@ describe Projects::IssuesController do
it "toggles the award emoji" do
expect do
post(:toggle_award_emoji, namespace_id: project.namespace.path,
project_id: project.path, id: issue.iid, name: "thumbsup")
post(:toggle_award_emoji, namespace_id: project.namespace,
project_id: project, id: issue.iid, name: "thumbsup")
end.to change { issue.award_emoji.count }.by(1)
expect(response).to have_http_status(200)
......
......@@ -67,7 +67,7 @@ describe Projects::LabelsController do
end
def list_labels
get :index, namespace_id: project.namespace.to_param, project_id: project.to_param
get :index, namespace_id: project.namespace.to_param, project_id: project
end
end
......@@ -76,7 +76,7 @@ describe Projects::LabelsController do
let(:personal_project) { create(:empty_project, namespace: user.namespace) }
it 'creates labels' do
post :generate, namespace_id: personal_project.namespace.to_param, project_id: personal_project.to_param
post :generate, namespace_id: personal_project.namespace.to_param, project_id: personal_project
expect(response).to have_http_status(302)
end
......@@ -84,7 +84,7 @@ describe Projects::LabelsController do
context 'project belonging to a group' do
it 'creates labels' do
post :generate, namespace_id: project.namespace.to_param, project_id: project.to_param
post :generate, namespace_id: project.namespace.to_param, project_id: project
expect(response).to have_http_status(302)
end
......@@ -109,7 +109,7 @@ describe Projects::LabelsController do
end
def toggle_subscription(label)
post :toggle_subscription, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label.to_param
post :toggle_subscription, namespace_id: project.namespace.to_param, project_id: project, id: label.to_param
end
end
......@@ -119,7 +119,7 @@ describe Projects::LabelsController do
context 'not group owner' do
it 'denies access' do
post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
expect(response).to have_http_status(404)
end
......@@ -131,13 +131,13 @@ describe Projects::LabelsController do
end
it 'gives access' do
post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
expect(response).to redirect_to(namespace_project_labels_path)
end
it 'promotes the label' do
post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
expect(Label.where(id: label_1.id)).to be_empty
expect(GroupLabel.find_by(title: promoted_label_name)).not_to be_nil
......@@ -151,7 +151,7 @@ describe Projects::LabelsController do
end
it 'returns to label list' do
post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
expect(response).to redirect_to(namespace_project_labels_path)
end
end
......
......@@ -18,7 +18,7 @@ describe Projects::MattermostsController do
it 'accepts the request' do
get(:new,
namespace_id: project.namespace.to_param,
project_id: project.to_param)
project_id: project)
expect(response).to have_http_status(200)
end
......@@ -30,7 +30,7 @@ describe Projects::MattermostsController do
subject do
post(:create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
mattermost: mattermost_params)
end
......
......@@ -17,8 +17,8 @@ describe Projects::PipelinesController do
create(:ci_empty_pipeline, status: 'created', project: project)
create(:ci_empty_pipeline, status: 'success', project: project)
get :index, namespace_id: project.namespace.path,
project_id: project.path,
get :index, namespace_id: project.namespace,
project_id: project,
format: :json
end
......@@ -62,8 +62,8 @@ describe Projects::PipelinesController do
end
def get_stage(name)
get :stage, namespace_id: project.namespace.path,
project_id: project.path,
get :stage, namespace_id: project.namespace,
project_id: project,
id: pipeline.id,
stage: name,
format: :json
......
......@@ -4,7 +4,7 @@ describe Projects::ProtectedBranchesController do
describe "GET #index" do
let(:project) { create(:project_empty_repo, :public) }
it "redirects empty repo to projects page" do
get(:index, namespace_id: project.namespace.to_param, project_id: project.to_param)
get(:index, namespace_id: project.namespace.to_param, project_id: project)
end
end
end
......@@ -10,7 +10,7 @@ describe Projects::RawController do
it 'delivers ASCII file' do
get(:show,
namespace_id: public_project.namespace.to_param,
project_id: public_project.to_param,
project_id: public_project,
id: id)
expect(response).to have_http_status(200)
......@@ -27,7 +27,7 @@ describe Projects::RawController do
it 'sets image content type header' do
get(:show,
namespace_id: public_project.namespace.to_param,
project_id: public_project.to_param,
project_id: public_project,
id: id)
expect(response).to have_http_status(200)
......@@ -51,7 +51,7 @@ describe Projects::RawController do
expect(controller).to receive(:send_file).with("#{Gitlab.config.shared.path}/lfs-objects/91/ef/f75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897", filename: "lfs_object.iso", disposition: 'attachment')
get(:show,
namespace_id: public_project.namespace.to_param,
project_id: public_project.to_param,
project_id: public_project,
id: id)
expect(response).to have_http_status(200)
......@@ -62,7 +62,7 @@ describe Projects::RawController do
it 'does not serve the file' do
get(:show,
namespace_id: public_project.namespace.to_param,
project_id: public_project.to_param,
project_id: public_project,
id: id)
expect(response).to have_http_status(404)
......
......@@ -13,7 +13,7 @@ describe Projects::RefsController do
def default_get(format = :html)
get :logs_tree,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: 'master',
path: 'foo/bar/baz.html',
format: format
......@@ -23,7 +23,7 @@ describe Projects::RefsController do
xhr :get,
:logs_tree,
namespace_id: project.namespace.to_param,
project_id: project.to_param, id: 'master',
project_id: project, id: 'master',
path: 'foo/bar/baz.html', format: format
end
......
......@@ -16,7 +16,7 @@ describe Projects::ReleasesController do
tag_id = release.tag
project.releases.destroy_all
get :edit, namespace_id: project.namespace.path, project_id: project.path, tag_id: tag_id
get :edit, namespace_id: project.namespace, project_id: project, tag_id: tag_id
release = assigns(:release)
expect(release).not_to be_nil
......@@ -24,7 +24,7 @@ describe Projects::ReleasesController do
end
it 'retrieves an existing release' do
get :edit, namespace_id: project.namespace.path, project_id: project.path, tag_id: release.tag
get :edit, namespace_id: project.namespace, project_id: project, tag_id: release.tag
release = assigns(:release)
expect(release).not_to be_nil
......@@ -48,7 +48,7 @@ describe Projects::ReleasesController do
def update_release(description)
put :update,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
tag_id: release.tag,
release: { description: description }
end
......
......@@ -6,7 +6,7 @@ describe Projects::RepositoriesController do
describe "GET archive" do
context 'as a guest' do
it 'responds with redirect in correct format' do
get :archive, namespace_id: project.namespace.path, project_id: project.path, format: "zip"
get :archive, namespace_id: project.namespace, project_id: project, format: "zip"
expect(response.header["Content-Type"]).to start_with('text/html')
expect(response).to be_redirect
......@@ -22,7 +22,7 @@ describe Projects::RepositoriesController do
end
it "uses Gitlab::Workhorse" do
get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip"
get :archive, namespace_id: project.namespace, project_id: project, ref: "master", format: "zip"
expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-archive:")
end
......@@ -33,7 +33,7 @@ describe Projects::RepositoriesController do
end
it "renders Not Found" do
get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip"
get :archive, namespace_id: project.namespace, project_id: project, ref: "master", format: "zip"
expect(response).to have_http_status(404)
end
......
......@@ -17,16 +17,16 @@ describe Projects::SnippetsController do
it 'redirects to last_page if page number is larger than number of pages' do
get :index,
namespace_id: project.namespace.path,
project_id: project.path, page: (last_page + 1).to_param
namespace_id: project.namespace,
project_id: project, page: (last_page + 1).to_param
expect(response).to redirect_to(namespace_project_snippets_path(page: last_page))
end
it 'redirects to specified page' do
get :index,
namespace_id: project.namespace.path,
project_id: project.path, page: last_page.to_param
namespace_id: project.namespace,
project_id: project, page: last_page.to_param
expect(assigns(:snippets).current_page).to eq(last_page)
expect(response).to have_http_status(200)
......@@ -38,7 +38,7 @@ describe Projects::SnippetsController do
context 'when anonymous' do
it 'does not include the private snippet' do
get :index, namespace_id: project.namespace.path, project_id: project.path
get :index, namespace_id: project.namespace, project_id: project
expect(assigns(:snippets)).not_to include(project_snippet)
expect(response).to have_http_status(200)
......@@ -49,7 +49,7 @@ describe Projects::SnippetsController do
before { sign_in(user) }
it 'renders the snippet' do
get :index, namespace_id: project.namespace.path, project_id: project.path
get :index, namespace_id: project.namespace, project_id: project
expect(assigns(:snippets)).to include(project_snippet)
expect(response).to have_http_status(200)
......@@ -60,7 +60,7 @@ describe Projects::SnippetsController do
before { sign_in(user2) }
it 'renders the snippet' do
get :index, namespace_id: project.namespace.path, project_id: project.path
get :index, namespace_id: project.namespace, project_id: project
expect(assigns(:snippets)).to include(project_snippet)
expect(response).to have_http_status(200)
......@@ -77,7 +77,7 @@ describe Projects::SnippetsController do
post :create, {
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
project_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params)
}.merge(additional_params)
end
......@@ -152,7 +152,7 @@ describe Projects::SnippetsController do
put :update, {
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: snippet.id,
project_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params)
}.merge(additional_params)
......@@ -281,8 +281,8 @@ describe Projects::SnippetsController do
sign_in(admin)
post :mark_as_spam,
namespace_id: project.namespace.path,
project_id: project.path,
namespace_id: project.namespace,
project_id: project,
id: snippet.id
end
......@@ -300,7 +300,7 @@ describe Projects::SnippetsController do
context 'when anonymous' do
it 'responds with status 404' do
get action, namespace_id: project.namespace.path, project_id: project.path, id: project_snippet.to_param
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
expect(response).to have_http_status(404)
end
......@@ -310,7 +310,7 @@ describe Projects::SnippetsController do
before { sign_in(user) }
it 'renders the snippet' do
get action, namespace_id: project.namespace.path, project_id: project.path, id: project_snippet.to_param
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
expect(assigns(:snippet)).to eq(project_snippet)
expect(response).to have_http_status(200)
......@@ -321,7 +321,7 @@ describe Projects::SnippetsController do
before { sign_in(user2) }
it 'renders the snippet' do
get action, namespace_id: project.namespace.path, project_id: project.path, id: project_snippet.to_param
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
expect(assigns(:snippet)).to eq(project_snippet)
expect(response).to have_http_status(200)
......@@ -332,7 +332,7 @@ describe Projects::SnippetsController do
context 'when the project snippet does not exist' do
context 'when anonymous' do
it 'responds with status 404' do
get action, namespace_id: project.namespace.path, project_id: project.path, id: 42
get action, namespace_id: project.namespace, project_id: project, id: 42
expect(response).to have_http_status(404)
end
......@@ -342,7 +342,7 @@ describe Projects::SnippetsController do
before { sign_in(user) }
it 'responds with status 404' do
get action, namespace_id: project.namespace.path, project_id: project.path, id: 42
get action, namespace_id: project.namespace, project_id: project, id: 42
expect(response).to have_http_status(404)
end
......@@ -364,8 +364,8 @@ describe Projects::SnippetsController do
context 'CRLF line ending' do
let(:params) do
{
namespace_id: project.namespace.path,
project_id: project.path,
namespace_id: project.namespace,
project_id: project,
id: project_snippet.to_param
}
end
......
......@@ -6,7 +6,7 @@ describe Projects::TagsController do
let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') }
describe 'GET index' do
before { get :index, namespace_id: project.namespace.to_param, project_id: project.to_param }
before { get :index, namespace_id: project.namespace.to_param, project_id: project }
it 'returns the tags for the page' do
expect(assigns(:tags).map(&:name)).to eq(['v1.1.0', 'v1.0.0'])
......@@ -19,7 +19,7 @@ describe Projects::TagsController do
end
describe 'GET show' do
before { get :show, namespace_id: project.namespace.to_param, project_id: project.to_param, id: id }
before { get :show, namespace_id: project.namespace.to_param, project_id: project, id: id }
context "valid tag" do
let(:id) { 'v1.0.0' }
......
......@@ -20,7 +20,7 @@ describe Projects::TemplatesController do
describe '#show' do
it 'renders template name and content as json' do
get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project.path, format: :json)
get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project, format: :json)
expect(response.status).to eq(200)
expect(body["name"]).to eq("bug")
......@@ -29,21 +29,21 @@ describe Projects::TemplatesController do
it 'renders 404 when unauthorized' do
sign_in(user2)
get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project.path, format: :json)
get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project, format: :json)
expect(response.status).to eq(404)
end
it 'renders 404 when template type is not found' do
sign_in(user)
get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project.path, format: :json)
get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project, format: :json)
expect(response.status).to eq(404)
end
it 'renders 404 without errors' do
sign_in(user)
expect { get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project.path, format: :json) }.not_to raise_error
expect { get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project, format: :json) }.not_to raise_error
end
end
end
......@@ -12,8 +12,8 @@ describe Projects::TodosController do
describe 'POST create' do
def go
post :create,
namespace_id: project.namespace.path,
project_id: project.path,
namespace_id: project.namespace,
project_id: project,
issuable_id: issue.id,
issuable_type: 'issue',
format: 'html'
......@@ -80,8 +80,8 @@ describe Projects::TodosController do
describe 'POST create' do
def go
post :create,
namespace_id: project.namespace.path,
project_id: project.path,
namespace_id: project.namespace,
project_id: project,
issuable_id: merge_request.id,
issuable_type: 'merge_request',
format: 'html'
......
......@@ -18,7 +18,7 @@ describe Projects::TreeController do
before do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: id)
end
......@@ -74,7 +74,7 @@ describe Projects::TreeController do
before do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: id)
end
......@@ -94,7 +94,7 @@ describe Projects::TreeController do
before do
post(:create_dir,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
id: 'master',
dir_name: path,
target_branch: target_branch,
......
......@@ -16,7 +16,7 @@ describe Projects::UploadsController do
it "returns an error" do
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
format: :json
expect(response).to have_http_status(422)
end
......@@ -26,7 +26,7 @@ describe Projects::UploadsController do
before do
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
file: jpg,
format: :json
end
......@@ -41,7 +41,7 @@ describe Projects::UploadsController do
before do
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
file: txt,
format: :json
end
......@@ -57,7 +57,7 @@ describe Projects::UploadsController do
let(:go) do
get :show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
project_id: project,
secret: "123456",
filename: "image.jpg"
end
......
......@@ -12,7 +12,7 @@ describe Projects::VariablesController do
describe 'POST #create' do
context 'variable is valid' do
it 'shows a success flash message' do
post :create, namespace_id: project.namespace.to_param, project_id: project.to_param,
post :create, namespace_id: project.namespace.to_param, project_id: project,
variable: { key: "one", value: "two" }
expect(flash[:notice]).to include 'Variables were successfully updated.'
......@@ -22,7 +22,7 @@ describe Projects::VariablesController do
context 'variable is invalid' do
it 'shows an alert flash message' do
post :create, namespace_id: project.namespace.to_param, project_id: project.to_param,
post :create, namespace_id: project.namespace.to_param, project_id: project,
variable: { key: "..one", value: "two" }
expect(response).to render_template("projects/variables/show")
......@@ -40,7 +40,7 @@ describe Projects::VariablesController do
end
it 'shows a success flash message' do
post :update, namespace_id: project.namespace.to_param, project_id: project.to_param,
post :update, namespace_id: project.namespace.to_param, project_id: project,
id: variable.id, variable: { key: variable.key, value: 'two' }
expect(flash[:notice]).to include 'Variable was successfully updated.'
......@@ -48,7 +48,7 @@ describe Projects::VariablesController do
end
it 'renders the action #show if the variable key is invalid' do
post :update, namespace_id: project.namespace.to_param, project_id: project.to_param,
post :update, namespace_id: project.namespace.to_param, project_id: project,
id: variable.id, variable: { key: '?', value: variable.value }
expect(response).to have_http_status(200)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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