Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions tcms/static/js/jsonrpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,45 @@ export function testPlanAutoComplete (selector, planCache) {
}
})
}

export function userAutoComplete (selector, cache) {
$(`${selector}.typeahead`).typeahead({
minLength: 1,
highlight: true
}, {
name: 'users-autocomplete',
limit: 100,
async: true,
display: function (user) {
let displayName = user.username
if (user.email) {
displayName += ` <${user.email}>`
}
cache[displayName] = user
return displayName
},
source: function (query, processSync, processAsync) {
query = query.trim()
if (query === '') {
return
}

let rpcQuery = { pk: query }

if (isNaN(query)) {
if (query.length < 3) {
return
}

rpcQuery = { username__icontains: query }
if (query.indexOf('@') > -1) {
rpcQuery = { email__icontains: query }
}
}

jsonRPC('User.filter', rpcQuery, function (data) {
return processAsync(data)
})
}
})
}
41 changes: 32 additions & 9 deletions tcms/testruns/static/testruns/js/get.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fetchBugDetails } from '../../../../static/js/bugs'
import { jsonRPC } from '../../../../static/js/jsonrpc'
import { jsonRPC, userAutoComplete } from '../../../../static/js/jsonrpc'
import { propertiesCard } from '../../../../static/js/properties'
import { tagsCard } from '../../../../static/js/tags'
import {
Expand All @@ -16,11 +16,13 @@ import { initSimpleMDE } from '../../../../static/js/simplemde_security_override
const allExecutionStatuses = {}
const allExecutions = {}
const expandedExecutionIds = []
const userAutocompleteCache = {}
const permissions = {
removeTag: false,
addComment: false,
removeComment: false,
viewHistoricalTestExecution: false
viewHistoricalTestExecution: false,
viewUser: false
}
const autocompleteCache = {}

Expand All @@ -42,6 +44,7 @@ export function pageTestrunsGetReadyHandler () {
permissions.addComment = $('#test_run_pk').data('perm-add-comment') === 'True'
permissions.removeComment = $('#test_run_pk').data('perm-remove-comment') === 'True'
permissions.viewHistoricalTestExecution = $('#test_run_pk').data('perm-view-historical-testexecution') === 'True'
permissions.viewUser = $('#test_run_pk').data('perm-view-user') === 'True'

const testRunId = $('#test_run_pk').data('pk')

Expand Down Expand Up @@ -135,7 +138,7 @@ export function pageTestrunsGetReadyHandler () {

$('.change-assignee-bulk').click(function () {
$(this).parents('.dropdown').toggleClass('open')
changeAssigneeBulk()
openChangeAssigneeModal()

return false
})
Expand Down Expand Up @@ -189,6 +192,10 @@ export function pageTestrunsGetReadyHandler () {
})

quickSearchAndAddTestCase(testRunId, addTestCaseToRun, autocompleteCache, { case_status__is_confirmed: true })
if (permissions.viewUser) {
userAutoComplete('#id-change-assignee', userAutocompleteCache)
}

$('#btn-search-cases').click(function () {
return advancedSearchAndAddTestCases(
testRunId, 'TestRun.add_case', $(this).attr('href'),
Expand Down Expand Up @@ -811,19 +818,35 @@ function reloadRowFor (execution, updateTestRun = false) {
})
}

function changeAssigneeBulk () {
function openChangeAssigneeModal () {
const selected = selectedCheckboxes()
if ($.isEmptyObject(selected)) {
return false
}

const enterAssigneeText = $('#test_run_pk').data('trans-enter-assignee-name-or-email')
const assignee = prompt(enterAssigneeText)
const input = $('#id-change-assignee')
input.val('')
$('.change-assignee-form').off('submit')
$('.change-assignee-form').submit(() => {
const assigneeValue = input.val().trim()
const selectedUser = userAutocompleteCache[assigneeValue]
const assignee = selectedUser ? selectedUser.username : assigneeValue

if (!assignee) {
return false
}

if (!assignee) {
changeAssigneeBulk(selected.executionIds, assignee)
$('#change-assignee-modal').modal('hide')
return false
}
selected.executionIds.forEach(executionId => {
})

$('#change-assignee-modal').modal('show')
return true
}

function changeAssigneeBulk (executionIds, assignee) {
executionIds.forEach(executionId => {
jsonRPC('TestExecution.update', [executionId, { assignee }], execution => {
reloadRowFor(execution)
})
Expand Down
35 changes: 35 additions & 0 deletions tcms/testruns/templates/testruns/get.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ <h1 class="col-md-12 kiwi-margin-top-0" {% if object.stop_date %}style="text-dec
data-perm-add-comment="{{ perms.django_comments.add_comment }}"
data-perm-remove-comment="{{ perms.django_comments.delete_comment }}"
data-perm-view-historical-testexecution="{{ perms.testruns.view_historicaltestexecution }}"
data-perm-view-user="{{ perms.auth.view_user }}"
data-trans-no-executions-selected="{% trans 'No rows selected! Please select at least one!'%}"
data-trans-enter-assignee-name-or-email="{% trans 'Enter username, email or user ID:'%}"
data-trans-are-you-sure="{% trans 'Are you sure?' %}"
Expand Down Expand Up @@ -605,6 +606,40 @@ <h4 class="modal-title" id="add-hyperlink-modal-title">{% trans "Add hyperlink"
</div>
</div>

{% if perms.testruns.change_testexecution %}
<div class="modal fade" id="change-assignee-modal" tabindex="-1" role="dialog" aria-labelledby="change-assignee-modal-title" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">
<span class="pficon pficon-close"></span>
</button>
<h4 class="modal-title" id="change-assignee-modal-title">{% trans "Assignee" %}</h4>
</div>
<form class="form-horizontal change-assignee-form">
<div class="modal-body">
<div class="form-group">
<label class="col-sm-3 control-label" for="id-change-assignee">{% trans "Assignee" %}</label>
<div class="col-sm-9">
<input type="text" id="id-change-assignee" class="form-control typeahead" placeholder="{% trans 'Username or email' %}">
{% if perms.auth.view_user %}
<span class="help-block">{% trans "Start typing to search for a user" %}</span>
{% else %}
<span class="help-block">{% trans "Enter an exact username, email or user ID" %}</span>
{% endif %}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">{% trans "Cancel" %}</button>
<button type="submit" class="btn btn-primary change-assignee-button">{% trans "Save" %}</button>
</div>
</form>
</div>
</div>
</div>
{% endif %}

<div class="modal fade" id="one-click-bug-report-modal" tabindex="-1" role="dialog" aria-labelledby="one-click-bug-report-title" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
Expand Down
11 changes: 11 additions & 0 deletions tcms/testruns/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,22 @@ def test_change_assignee_with_permission(self):
user_should_have_perm(self.tester, "testruns.change_testexecution")
response = self.client.get(self.url)
self.assertContains(response, self.change_assignee_html, html=True)
self.assertContains(response, 'id="change-assignee-modal"')
self.assertContains(response, 'data-perm-view-user="False"')
self.assertContains(response, _("Enter an exact username, email or user ID"))

def test_change_assignee_without_permission(self):
remove_perm_from_user(self.tester, "testruns.change_testexecution")
response = self.client.get(self.url)
self.assertNotContains(response, self.change_assignee_html, html=True)
self.assertNotContains(response, 'id="change-assignee-modal"')

def test_change_assignee_with_user_view_permission(self):
user_should_have_perm(self.tester, "testruns.change_testexecution")
user_should_have_perm(self.tester, "auth.view_user")
response = self.client.get(self.url)
self.assertContains(response, 'data-perm-view-user="True"')
self.assertContains(response, _("Start typing to search for a user"))

def test_update_text_version_with_permission(self):
user_should_have_perm(self.tester, "testruns.change_testexecution")
Expand Down