You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/11/27 20:24:47 UTC
[37/49] ambari git commit: AMBARI-22508 Ambari 3.0: Implement new
design for Admin View: User Management. (atkach)
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html
new file mode 100644
index 0000000..e0c1144
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html
@@ -0,0 +1,86 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<form id="create-group-form" role="form" novalidate name="form.groupCreateForm">
+ <div class="modal-header">
+ <h1 class="modal-title">
+ {{'groups.createLocal' | translate}}
+ </h1>
+ </div>
+ <div class="modal-body">
+ <div class="form-group"
+ ng-class="{ 'has-error': (form.groupCreateForm.groupName.$error.required || form.groupCreateForm.groupName.$error.pattern) && form.groupCreateForm.submitted }">
+ <label for="groupName">
+ {{'groups.name' | translate}}<span> *</span>
+ </label>
+ <input type="text"
+ placeholder="{{'groups.name' | translate}}"
+ ng-pattern="/^([a-zA-Z0-9._\s]+)$/"
+ autofocus
+ ng-maxlength="80"
+ autocomplete="off"
+ class="form-control"
+ ng-model="formData.groupName"
+ name="groupName"
+ id="groupName"
+ ng-change="checkIfInstanceExist()"
+ required>
+ <span class="help-block validation-block"
+ ng-show='form.groupCreateForm.groupName.$error.required && form.groupCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ <span class="help-block validation-block"
+ ng-show='form.groupCreateForm.groupName.$error.pattern && form.groupCreateForm.submitted'>
+ {{'common.alerts.noSpecialChars' | translate}}
+ </span>
+ </div>
+
+ <div class="form-group">
+ <label>{{'groups.addUsers' | translate}}</label>
+ <div>
+ <editable-list items-source="formData.members" resource-type="User" editable="true"></editable-list>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="form-group col-sm-6"
+ ng-class="{ 'has-error': form.groupCreateForm.role.$error.required && form.groupCreateForm.submitted }">
+ <label for="role" class="nowrap">
+ {{'groups.role' | translate}}
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <select
+ class="form-control"
+ id="role"
+ name="role"
+ ng-model="formData.role">
+ <option value="" disabled selected>{{'common.select' | translate}}</option>
+ <option ng-repeat="role in roleOptions" value="{{role.permission_id}}">{{role.permission_label}}</option>
+ </select>
+ <span class="help-block validation-block" ng-show='form.groupCreateForm.role.$error.required && form.groupCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
+ </div>
+
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
+ <button class="btn btn-primary" ng-click="save()" type="submit">{{'common.controls.save' | translate}}</button>
+ </div>
+</form>
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html
new file mode 100644
index 0000000..0af26eb
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html
@@ -0,0 +1,147 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<form id="create-user-form" role="form" novalidate name="form.userCreateForm">
+ <div class="modal-header">
+ <h1 class="modal-title">
+ {{'users.create' | translate}}
+ </h1>
+ </div>
+ <div class="modal-body">
+ <div class="form-group"
+ ng-class="{ 'has-error': (form.userCreateForm.userName.$error.required || form.userCreateForm.userName.$error.pattern) && form.userCreateForm.submitted }">
+ <label for="userName">
+ {{'users.username' | translate}}<span> *</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <input type="text"
+ autofocus
+ placeholder="{{'users.user.name' | translate}}"
+ ng-pattern="/^[^<>&`|\\]+$/"
+ ng-maxlength="80"
+ tooltip="{{'users.userNameTip' | translate}}"
+ autocomplete="off"
+ tooltip-trigger="focus"
+ class="form-control"
+ ng-model="formData.userName"
+ name="userName"
+ id="userName"
+ ng-change="checkIfInstanceExist()"
+ required>
+ <span class="help-block validation-block"
+ ng-show='form.userCreateForm.userName.$error.required && form.userCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ <span class="help-block validation-block"
+ ng-show='form.userCreateForm.userName.$error.pattern && form.userCreateForm.submitted'>
+ {{'common.alerts.noSpecialChars' | translate}}
+ </span>
+ </div>
+
+ <div class="row">
+ <div class="form-group col-sm-6"
+ ng-class="{ 'has-error': form.userCreateForm.password.$error.required && form.userCreateForm.submitted }">
+ <label for="password">
+ {{'users.password' | translate}}<span> *</span>
+ </label>
+ <input type="password"
+ id="password"
+ class="form-control"
+ name="password"
+ placeholder="{{'users.password' | translate}}"
+ required
+ ng-model="formData.password"
+ autocomplete="off">
+ <span class="help-block validation-block"
+ ng-show='form.userCreateForm.password.$error.required && form.userCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
+ <div class="form-group col-sm-6"
+ ng-class="{ 'has-error': form.userCreateForm.confirmPassword.$error.passwordVerify || (form.userCreateForm.confirmPassword.$error.required && form.userCreateForm.submitted) }">
+ <label for="confirmPassword">
+ {{'users.confirmPassword' | translate}}<span> *</span>
+ </label>
+ <input type="password"
+ id="confirmPassword"
+ class="form-control"
+ name="confirmPassword"
+ placeholder="{{'users.confirmPassword' | translate}}"
+ required
+ password-verify="formData.password"
+ ng-model="formData.confirmPassword"
+ autocomplete="off">
+ <span class="help-block validation-block"
+ ng-show='form.userCreateForm.confirmPassword.$error.required && form.userCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ <span class="help-block validation-block"
+ ng-show='form.userCreateForm.confirmPassword.$error.passwordVerify'>
+ {{'users.alerts.wrongPassword' | translate}}
+ </span>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="form-group col-sm-6"
+ ng-class="{ 'has-error': form.userCreateForm.role.$error.required && form.userCreateForm.submitted }">
+ <label for="role" class="nowrap">
+ {{'users.role' | translate}}<span> *</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <select
+ class="form-control"
+ id="role"
+ name="role"
+ ng-model="formData.role"
+ required>
+ <option value="" disabled selected>{{'common.select' | translate}}</option>
+ <option ng-repeat="role in roleOptions" value="{{role.permission_id}}">{{role.permission_label}}</option>
+ </select>
+ <span class="help-block validation-block" ng-show='form.userCreateForm.role.$error.required && form.userCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label>
+ {{'users.isAmbariAdmin' | translate}}<span> *</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <div>
+ <toggle-switch model="formData.isAdmin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary" data-off-color="danger"></toggle-switch>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label>
+ {{'users.isActive' | translate}}<span> *</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <div>
+ <toggle-switch model="formData.isActive" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary" data-off-color="danger"></toggle-switch>
+ </div>
+ </div>
+
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
+ <button class="btn btn-primary" ng-click="save()" type="submit">{{'common.controls.save' | translate}}</button>
+ </div>
+</form>
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html
new file mode 100644
index 0000000..0372a11
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html
@@ -0,0 +1,122 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<div ng-show="user" class="user-edit-panel">
+ <div class="clearfix">
+ <ol class="breadcrumb pull-left">
+ <li><a href="#/userManagement">{{'common.users' | translate}}</a></li>
+ <li class="active"><span class="glyphicon glyphicon-flash" ng-show="user.admin"></span>{{user.user_name}}</li>
+ </ol>
+ <div class="pull-right top-margin-4">
+ <div ng-switch="isCurrentUser || user.user_type != 'LOCAL'">
+ <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'common.cannotDelete' | translate: '{term: constants.user}'}}">{{'common.delete' | translate: '{term: constants.user}'}}</button>
+ <button class="btn deleteuser-btn btn-danger" ng-switch-when="false" ng-click="deleteUser()">{{'common.delete' | translate: '{term: constants.user}'}}</button>
+ </div>
+ </div>
+ </div>
+ <hr>
+ <form class="form-horizontal" role="form" >
+ <div class="form-group">
+ <label for="" class="col-sm-2 control-label">{{'common.type' | translate}}</label>
+ <div class="col-sm-10">
+ <label for="" class="control-label">{{user.userTypeName}}</label>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="" class="col-sm-2 control-label">{{'users.status' | translate}}</label>
+ <div class="col-sm-10">
+ <toggle-switch on-change="toggleUserActive()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.status}'}}" ng-disabled="isCurrentUser" model="user.active" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="" class="col-sm-2 control-label"><span class="glyphicon glyphicon-flash"></span> {{'users.ambariAdmin' | translate}}</label>
+ <div class="col-sm-10">
+ <toggle-switch on-change="toggleUserAdmin()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.admin}'}}" ng-disabled="isCurrentUser" model="user.admin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="password" class="col-sm-2 control-label">{{'users.password' | translate}}</label>
+ <div class="col-sm-10">
+ <div ng-switch="user.user_type != 'LOCAL'">
+ <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.password}'}}">{{'users.changePassword' | translate}}</button>
+ <a href ng-click="openChangePwdDialog()" ng-switch-when="false" class="btn btn-default changepassword">{{'users.changePassword' | translate}}</a>
+ </div>
+
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="groups" class="col-sm-2 control-label">{{getUserMembership(user.user_type)}}</label>
+ <div class="col-sm-10">
+ <editable-list items-source="editingGroupsList" resource-type="Group" editable="user.user_type == 'LOCAL'"></editable-list>
+ </div>
+
+ </div>
+ <div class="form-group" >
+ <label for="" class="col-sm-2 control-label">{{'common.privileges' | translate}}</label>
+ <div class="col-sm-10">
+ <table class="table" ng-hide="hidePrivileges || user.admin">
+ <thead>
+ <tr>
+ <th>{{'common.cluster' | translate}}</th>
+ <th>{{'common.clusterRole' | translate}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="(name, privilege) in privileges.clusters">
+ <td>
+ <span class="glyphicon glyphicon-cloud"></span>
+ <a href="#/clusters/{{name}}/manageAccess">{{name}}</a>
+ </td>
+ <td>
+ <span tooltip="{{privilege.permission_label}}">{{privilege.permission_label}}</span>
+ </td>
+ </tr>
+ <tr>
+ <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.cluster}'}}</td>
+ </tr>
+ </tbody>
+ <thead class="view-permission-header">
+ <tr>
+ <th>{{'common.view' | translate}}</th>
+ <th>{{'common.viewPermissions' | translate}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="(name, privilege) in privileges.views">
+ <td>
+ <span class="glyphicon glyphicon-th"></span>
+ <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a>
+ </td>
+ <td>
+ <span tooltip="{{item}}" ng-repeat="item in privilege.privileges track by $index">{{item | translate}}{{$last ? '' : ', '}}</span>
+ </td>
+ <td>
+ <i class="fa fa-trash-o" aria-hidden="true" ng-click="removePrivilege(name, privilege);"></i>
+ </td>
+ </tr>
+ <tr>
+ <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.view}'}}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="alert alert-info" ng-show="!privileges && !user.admin">{{'common.alerts.noPrivilegesDescription' | translate: '{term: constants.user}'}}</div>
+ <div class="alert alert-info" ng-show="user.admin">{{'users.userIsAdmin' | translate}}</div>
+ </div>
+ </div>
+ </form>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
new file mode 100644
index 0000000..cc4789b
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
@@ -0,0 +1,119 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<div class="users-pane">
+ <div class="clearfix panel">
+ <button class="btn btn-default createuser-btn pull-right" ng-click="createUser();">
+ {{'users.create' | translate}}
+ </button>
+ </div>
+ <table class="table table-striped table-hover">
+ <thead>
+ <tr class="fix-bottom">
+ <th>
+ <span>{{'users.username' | translate}}</span>
+ </th>
+ <th>
+ <span>{{'clusters.role' | translate}}</span>
+ </th>
+ <th>
+ <span>{{'users.status' | translate}}</span>
+ </th>
+ <th>
+ <span>{{'common.type' | translate}}</span>
+ </th>
+ <th>
+ <span>{{'common.group' | translate}}</span>
+ </th>
+ <th class="entity-actions">
+ <span>{{'common.actions' | translate}}</span>
+ </th>
+ </tr>
+ <tr class="fix-top">
+ <th>
+ <div class="search-container">
+ <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="filters.name" ng-change="resetPagination()">
+ <button type="button" class="close clearfilter" ng-show="filters.name" ng-click="filters.name=''; resetPagination()">
+ <span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span>
+ </button>
+ </div>
+ </th>
+ <th></th>
+ <th>
+ <select class="form-control statusfilter"
+ ng-model="filters.status"
+ ng-options="item.label for item in activeFilterOptions"
+ ng-change="resetPagination()">
+ </select>
+ </th>
+ <th>
+ <select class="form-control typefilter"
+ ng-model="filters.type"
+ ng-options="item.label for item in typeFilterOptions"
+ ng-change="resetPagination()">
+ </select>
+ </th>
+ <th></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="user in users">
+ <td>
+ <span>{{user.Users.user_name}}</span>
+ </td>
+ <td>
+ <span>{{user.Users.role}}</span>
+ </td>
+ <td>
+ <span>
+ {{(user.Users.active ? 'users.active' : 'users.inactive') | translate}}
+ </span>
+ </td>
+ <td><span>{{user.Users.userTypeName}}</span></td>
+ <td><span>{{user.Users.groups.length ? user.Users.groups.join(' ') : '-'}}</span></td>
+ <td class="entity-actions">
+ <a href="#/users/{{user.Users.encodedName}}/edit">
+ <i class="fa fa-pencil"></i>
+ </a>
+ <a href ng-click="deleteUser(user.Users)">
+ <i class="fa fa-trash-o"></i>
+ </a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div ng-if="isLoading" class="spinner-container">
+ <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
+ </div>
+ <div class="alert empty-table-alert col-sm-12" ng-show="!users.length && !isLoading">
+ {{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}}
+ </div>
+ <div class="col-sm-12 table-bar" ng-show="totalUsers > minRowsToShowPagination">
+ <div class="pull-left filtered-info">
+ <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: constants.users}'}}</span>
+ <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
+ </div>
+ <div class="pull-right left-margin">
+ <pagination class="paginator" total-items="totalUsers" max-size="maxVisiblePages" items-per-page="usersPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+ </div>
+ <div class="pull-right">
+ <select class="form-control" ng-model="usersPerPage" ng-change="usersPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html
deleted file mode 100644
index 80a3b04..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-<ol class="breadcrumb">
- <li><a href="#/users">{{'common.users' | translate}}</a></li>
- <li class="active">{{'users.create' | translate}}</li>
-</ol>
-<hr>
-<form class="form-horizontal create-user-form" role="form" novalidate name="form" autocomplete="off">
- <div class="form-group" ng-class="{'has-error' : form.user_name.$error.required && form.submitted}">
- <label for="username" class="col-sm-2 control-label">{{'users.username' | translate}}</label>
- <div class="col-sm-10"
- ng-class="{'has-error': form.user_name.$error.pattern}">
- <input
- autofocus
- type="text"
- id="username"
- class="form-control username-input"
- name="user_name"
- placeholder="{{'users.userName' | translate}}"
- ng-model="user.user_name"
- ng-required="true"
- ng-pattern="/^[^<>&`|\\]+$/"
- ng-maxlength="80"
- tooltip="{{'users.userNameTip' | translate}}"
- autocomplete="off"
- tooltip-trigger="focus">
- <div class="alert alert-danger top-margin" ng-show="form.user_name.$error.required && form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
- </div>
- </div>
- <div class="form-group">
- <label for="" class="col-sm-2 control-label">{{'common.type' | translate}}</label>
- <div class="col-sm-10">
- <label for="" class="control-label">{{'common.local' | translate}}</label>
- </div>
- </div>
- <div class="form-group">
- <label for="" class="col-sm-2 control-label">{{'users.status' | translate}}</label>
- <div class="col-sm-10">
- <toggle-switch model="user.active" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary userstatus" data-off-color="danger"></toggle-switch>
- </div>
- </div>
- <div class="form-group">
- <label for="" class="col-sm-2 control-label"><span class="glyphicon glyphicon-flash"></span>{{'users.ambariAdmin' | translate}}</label>
- <div class="col-sm-10">
- <toggle-switch ng-disabled="isCurrentUser" model="user.admin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary userstatus" data-off-color="danger"></toggle-switch>
- </div>
- </div>
- <div class="form-group" ng-class="{'has-error' : (form.password.$error.required && form.submitted) || form.confirmPassword.$error.passwordVerify}">
- <label for="password" class="col-sm-2 control-label">{{'users.password' | translate}}</label>
- <div class="col-sm-10">
- <input type="password" class="form-control bottom-margin userpassword" name="password" placeholder="{{'users.password' | translate}}" required ng-model="user.password" autocomplete="off">
- <input type="password" class="form-control bottom-margin userpasswordconfirm" name="confirmPassword" placeholder="{{'users.passwordConfirmation' | translate}}" required ng-model="user.passwordConfirmation"
- password-verify="user.password" autocomplete="off">
-
- <div class="alert alert-danger" ng-show='form.confirmPassword.$error.passwordVerify'>{{'users.alerts.wrongPassword' | translate}}</div>
- <div class="alert alert-danger" ng-show='form.password.$error.required && form.submitted'>{{'users.alerts.passwordRequired' | translate}}</div>
-
- </div>
- </div>
- <div class="form-group">
- <div class="col-sm-offset-2 col-sm-10">
- <button class="btn btn-primary pull-right left-margin saveuser" ng-click="createUser()">{{'common.controls.save' | translate}}</button>
- <a class="btn btn-default pull-right cancel" href ng-click="cancel()">{{'common.controls.cancel' | translate}}</a>
- </div>
- </div>
-
-</form>
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
deleted file mode 100644
index 12227c3..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-
-<div class="users-pane">
- <div class="clearfix">
- <ol class="breadcrumb pull-left">
- <li class="active">{{'common.users' | translate}}</li>
- </ol>
- <div class="pull-right top-margin-4">
- <link-to route="users.create" class="btn btn-default createuser-btn">
- </span> {{'users.create' | translate}}
- </link-to>
- </div>
- </div>
- <table class="table table-striped table-hover">
- <thead>
- <tr>
- <th width="30">
- <span class="bottom-margin admin-filter glyphicon glyphicon-flash"
- ng-class="{'no-filter' : !adminFilter}"
- ng-click="toggleAdminFilter()"
- tooltip="{{(adminFilter ? 'users.showAll' : 'users.showAdmin') | translate}}"
- ></span>
- </th>
- <th>
- <div class="search-container">
- <label for="">{{'users.username' | translate}}</label>
- <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="currentNameFilter" ng-change="resetPagination()">
- <button type="button" class="close clearfilter" ng-show="currentNameFilter" ng-click="currentNameFilter=''; resetPagination()"><span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
- </div>
- </th>
- <th>
- <label for="">{{'common.type' | translate}}</label>
- <select class="form-control typefilter"
- ng-model="currentTypeFilter"
- ng-options="item.label for item in typeFilterOptions"
- ng-change="resetPagination()">
- </select>
-
- </th>
- <th>
- <label for="">{{'users.status' | translate}}</label>
- <select class="form-control statusfilter"
- ng-model="currentActiveFilter"
- ng-options="item.label for item in activeFilterOptions"
- ng-change="resetPagination()">
- </select>
- </th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="user in users">
- <td>
- <span class="glyphicon" tooltip="{{user.Users.admin ? constants.admin : ''}}" ng-class="{'glyphicon-flash' : user.Users.admin}"></span>
- </td>
- <td>
- <a href="#/users/{{user.Users.encoded_name}}">{{user.Users.user_name}}</a>
- </td>
- <td>{{user.Users.userTypeName}}</td>
- <td><span ng-class="user.Users.active ? 'text-success' : 'text-danger'">{{(user.Users.active ? 'users.active' : 'users.inactive') | translate}}</span></td>
- </tr>
- </tbody>
- </table>
- <div ng-if="isLoading" class="spinner-container">
- <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
- </div>
- <div class="alert empty-table-alert col-sm-12" ng-show="!users.length && !isLoading">
- {{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}}
- </div>
- <div class="col-sm-12 table-bar">
- <div class="pull-left filtered-info">
- <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: constants.users}'}}</span>
- <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
- </div>
- <div class="pull-right left-margin">
- <pagination class="paginator" total-items="totalUsers" max-size="maxVisiblePages" items-per-page="usersPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
- </div>
- <div class="pull-right">
- <select class="form-control" ng-model="usersPerPage" ng-change="usersPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
- </div>
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
deleted file mode 100644
index f29d315..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-<div class="modal-header">
- <h3 class="modal-title">{{'users.changePasswordFor' | translate: '{userName: userName}'}}</h3>
-</div>
-<div class="modal-body">
- <form class="form-horizontal" novalidate name="form.passwordChangeForm" role="form" >
- <div class="form-group" ng-class="{'has-error' : (form.passwordChangeForm.currentPassword.$error.required && form.passwordChangeForm.submitted)}">
- <label for="" class="col-sm-4 control-label" >{{'users.yourPassword' | translate}}</label>
- <div class="col-sm-8">
- <input type="password" name="currentPassword" class="form-control bottom-margin" placeholder="{{'users.yourPassword' | translate}}" required ng-model="passwordData.currentUserPassword" autocomplete="off">
- <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | translate}}</div>
- </div>
- </div>
- <div class="form-group no-margin-bottom" ng-class="{'has-error' : (form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted) || form.passwordChangeForm.confirmPassword.$error.passwordVerify}">
- <label for="" class="col-sm-4 control-label">{{'users.newPassword' | translate}}:</label>
- <div class="col-sm-8">
- <input type="password" class="form-control bottom-margin" name="password" placeholder="{{'users.newPassword' | translate}}" required ng-model="passwordData.password" autocomplete="off">
- <input type="password" class="form-control bottom-margin" name="confirmPassword" placeholder="{{'users.newPasswordConfirmation' | translate}}" required ng-model="passwordData.passwordConfirmation"
- password-verify="passwordData.password" autocomplete="off">
- <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.confirmPassword.$error.passwordVerify'>{{'users.alerts.wrongPassword' | translate}}</div>
- <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | translate}}</div>
- </div>
-
- </div>
- </form>
-</div>
-<div class="modal-footer">
- <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
- <button class="btn btn-primary" ng-click="ok()">{{'common.controls.ok' | translate}}</button>
-</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
deleted file mode 100644
index f965c5d..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-
-<div ng-show="user" class="user-edit-panel">
- <div class="clearfix">
- <ol class="breadcrumb pull-left">
- <li><a href="#/users">{{'common.users' | translate}}</a></li>
- <li class="active"><span class="glyphicon glyphicon-flash" ng-show="user.admin"></span>{{user.user_name}}</li>
- </ol>
- <div class="pull-right top-margin-4">
- <div ng-switch="isCurrentUser || user.user_type != 'LOCAL'">
- <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'common.cannotDelete' | translate: '{term: constants.user}'}}">{{'common.delete' | translate: '{term: constants.user}'}}</button>
- <button class="btn deleteuser-btn btn-danger" ng-switch-when="false" ng-click="deleteUser()">{{'common.delete' | translate: '{term: constants.user}'}}</button>
- </div>
- </div>
- </div>
- <hr>
- <form class="form-horizontal" role="form" >
- <div class="form-group">
- <label for="" class="col-sm-2 control-label">{{'common.type' | translate}}</label>
- <div class="col-sm-10">
- <label for="" class="control-label">{{user.userTypeName}}</label>
- </div>
- </div>
- <div class="form-group">
- <label for="" class="col-sm-2 control-label">{{'users.status' | translate}}</label>
- <div class="col-sm-10">
- <toggle-switch on-change="toggleUserActive()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.status}'}}" ng-disabled="isCurrentUser" model="user.active" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch>
- </div>
- </div>
- <div class="form-group">
- <label for="" class="col-sm-2 control-label"><span class="glyphicon glyphicon-flash"></span> {{'users.ambariAdmin' | translate}}</label>
- <div class="col-sm-10">
- <toggle-switch on-change="toggleUserAdmin()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.admin}'}}" ng-disabled="isCurrentUser" model="user.admin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch>
- </div>
- </div>
- <div class="form-group">
- <label for="password" class="col-sm-2 control-label">{{'users.password' | translate}}</label>
- <div class="col-sm-10">
- <div ng-switch="user.user_type != 'LOCAL'">
- <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.password}'}}">{{'users.changePassword' | translate}}</button>
- <a href ng-click="openChangePwdDialog()" ng-switch-when="false" class="btn btn-default changepassword">{{'users.changePassword' | translate}}</a>
- </div>
-
- </div>
- </div>
- <div class="form-group">
- <label for="groups" class="col-sm-2 control-label">{{getUserMembership(user.user_type)}}</label>
- <div class="col-sm-10">
- <editable-list items-source="editingGroupsList" resource-type="Group" editable="user.user_type == 'LOCAL'"></editable-list>
- </div>
-
- </div>
- <div class="form-group" >
- <label for="" class="col-sm-2 control-label">{{'common.privileges' | translate}}</label>
- <div class="col-sm-10">
- <table class="table" ng-hide="hidePrivileges || user.admin">
- <thead>
- <tr>
- <th>{{'common.cluster' | translate}}</th>
- <th>{{'common.clusterRole' | translate}}</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="(name, privilege) in privileges.clusters">
- <td>
- <span class="glyphicon glyphicon-cloud"></span>
- <a href="#/clusters/{{name}}/manageAccess">{{name}}</a>
- </td>
- <td>
- <span tooltip="{{privilege.permission_label}}">{{privilege.permission_label}}</span>
- </td>
- </tr>
- <tr>
- <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.cluster}'}}</td>
- </tr>
- </tbody>
- <thead class="view-permission-header">
- <tr>
- <th>{{'common.view' | translate}}</th>
- <th>{{'common.viewPermissions' | translate}}</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="(name, privilege) in privileges.views">
- <td>
- <span class="glyphicon glyphicon-th"></span>
- <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a>
- </td>
- <td>
- <span tooltip="{{item}}" ng-repeat="item in privilege.privileges track by $index">{{item | translate}}{{$last ? '' : ', '}}</span>
- </td>
- <td>
- <i class="fa fa-trash-o" aria-hidden="true" ng-click="removePrivilege(name, privilege);"></i>
- </td>
- </tr>
- <tr>
- <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.view}'}}</td>
- </tr>
- </tbody>
- </table>
- <div class="alert alert-info" ng-show="!privileges && !user.admin">{{'common.alerts.noPrivilegesDescription' | translate: '{term: constants.user}'}}</div>
- <div class="alert alert-info" ng-show="user.admin">{{'users.userIsAdmin' | translate}}</div>
- </div>
- </div>
- </form>
-</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/clusters/UserAccessListCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/clusters/UserAccessListCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/clusters/UserAccessListCtrl_test.js
deleted file mode 100644
index 14c0975..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/clusters/UserAccessListCtrl_test.js
+++ /dev/null
@@ -1,820 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-describe('#Cluster', function () {
-
- describe('UserAccessListCtrl', function() {
-
- var scope, ctrl, $t, $httpBackend, Cluster, deferred, Alert, mock;
-
- beforeEach(module('ambariAdminConsole', function () {}));
-
- beforeEach(inject(function($rootScope, $controller, _$translate_, _$httpBackend_, _Cluster_, _$q_, _Alert_) {
- scope = $rootScope.$new();
- $t = _$translate_.instant;
- $httpBackend = _$httpBackend_;
- Cluster = _Cluster_;
- Alert = _Alert_;
- deferred = {
- createPrivileges: _$q_.defer(),
- getPrivilegesForResource: _$q_.defer(),
- getPrivilegesWithFilters: _$q_.defer(),
- deletePrivileges: _$q_.defer(),
- deleteMultiplePrivileges: _$q_.defer()
- };
- ctrl = $controller('UserAccessListCtrl', {
- $scope: scope
- });
- mock = {
- Cluster: Cluster,
- Alert: Alert,
- scope: scope
- };
- spyOn(Cluster, 'createPrivileges').andReturn(deferred.createPrivileges.promise);
- spyOn(Cluster, 'deletePrivileges').andReturn(deferred.deletePrivileges.promise);
- spyOn(Cluster, 'getPrivilegesForResource').andReturn(deferred.getPrivilegesForResource.promise);
- spyOn(Cluster, 'getPrivilegesWithFilters').andReturn(deferred.getPrivilegesWithFilters.promise);
- spyOn(Alert, 'success').andCallFake(angular.noop);
- spyOn(Alert, 'error').andCallFake(angular.noop);
- spyOn(scope, 'loadRoles').andCallFake(angular.noop);
-
- $httpBackend.expectGET(/\/api\/v1\/permissions/).respond(200, {
- items: []
- });
- $httpBackend.expectGET(/\/api\/v1\/users?.*/).respond(200, {
- items:[]
- });
- $httpBackend.flush();
- }));
-
- describe('#clearFilters()', function () {
-
- it('should clear filters and reset pagination', function () {
- scope.currentPage = 2;
- scope.currentNameFilter = 'a';
- scope.roleFilterOptions = [
- {
- label: $t('common.all'),
- value: ''
- },
- {
- label: $t('users.roles.clusterUser'),
- value: 'CLUSTER.USER'
- }
- ];
- scope.currentRoleFilter = scope.roleFilterOptions[1];
- scope.clearFilters();
- expect(scope.currentNameFilter).toEqual('');
- expect(scope.currentRoleFilter).toEqual({
- label: $t('common.all'),
- value: ''
- });
- expect(scope.currentPage).toEqual(1);
- });
-
- });
-
- describe('#isNotEmptyFilter', function () {
-
- var cases = [
- {
- currentNameFilter: '',
- currentRoleFilter: null,
- isNotEmptyFilter: false,
- title: 'no filters'
- },
- {
- currentNameFilter: '',
- currentRoleFilter: {
- value: ''
- },
- isNotEmptyFilter: false,
- title: 'empty filters'
- },
- {
- currentNameFilter: 'a',
- currentRoleFilter: {
- value: ''
- },
- isNotEmptyFilter: true,
- title: 'name filter'
- },
- {
- currentNameFilter: '0',
- currentRoleFilter: {
- value: ''
- },
- isNotEmptyFilter: true,
- title: 'name filter with "0" as string'
- },
- {
- currentNameFilter: '',
- currentRoleFilter: {
- value: 'CLUSTER.USER'
- },
- isNotEmptyFilter: true,
- title: 'role filter'
- },
- {
- currentNameFilter: 'a',
- currentRoleFilter: {
- value: 'GROUP'
- },
- isNotEmptyFilter: true,
- title: 'all filters'
- },
- {
- currentNameFilter: '0',
- currentRoleFilter: {
- value: 'GROUP'
- },
- isNotEmptyFilter: true,
- title: 'all filters with "0" as string'
- }
- ];
-
- cases.forEach(function (item) {
- it(item.title, function () {
- scope.currentNameFilter = item.currentNameFilter;
- scope.currentRoleFilter = item.currentRoleFilter;
- scope.$digest();
- expect(scope.isNotEmptyFilter).toEqual(item.isNotEmptyFilter);
- });
- });
-
- });
-
- describe('#save() for Users', function(){
- var user = {};
-
- beforeEach(function() {
- items1 = {
- "href" : "http://abc.com:8080/api/v1/users/user1",
- "Users" : { "user_name" : "user1" },
- "privileges" : [
- {
- "href" : "http://abc.com:8080/api/v1/users/user1/privileges/222",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup2",
- "principal_type" : "GROUP",
- "privilege_id" : 222,
- "type" : "CLUSTER",
- "user_name" : "user1"
- }
- }, {
- "href" : "http://abc.com:8080/api/v1/users/user1/privileges/111",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup",
- "principal_type" : "GROUP",
- "privilege_id" : 111,
- "type" : "CLUSTER",
- "user_name" : "user1"
- }
- }, {
- "href" : "http://abc.com:8080/api/v1/users/user1/privileges/11",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Cluster Administrator",
- "permission_name" : "CLUSTER.ADMINISTRATOR",
- "principal_name" : "user1",
- "principal_type" : "USER",
- "privilege_id" : 11,
- "type" : "CLUSTER",
- "user_name" : "user1"
- }
- }
- ]
- };
-
- items2 =
- {
- "href" : "http://abc.com:8080/api/v1/users/user2",
- "Users" : { "user_name" : "user2" },
- "privileges" : [
- {
- "href" : "http://abc.com:8080/api/v1/users/user2/privileges/111",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup",
- "principal_type" : "GROUP",
- "privilege_id" : 111,
- "type" : "CLUSTER",
- "user_name" : "user2"
- }
- }, {
- "href" : "http://abc.com:8080/api/v1/users/user2/privileges/22",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "user2",
- "principal_type" : "USER",
- "privilege_id" : 22,
- "type" : "CLUSTER",
- "user_name" : "user2"
- }
- }
- ]
- };
-
- all_items = { "items": [items1, items2]};
-
- scope.loadUsers();
-
- spyOn(Cluster, 'deleteMultiplePrivileges').andCallFake(function(clusterId, privilege_ids) {
- privilege_ids.forEach(function(privilege_id) {
- items1.privileges.forEach(function(p, index) {
- if (p.PrivilegeInfo.privilege_id === privilege_id) {
- //Remove from array
- items1.privileges.splice(index, 1);
- }
- });
- });
- });
- spyOn(scope, 'addPrivilege').andCallFake(function(user) {
- var p = {};
- p.PrivilegeInfo = {};
- p.PrivilegeInfo.privilege_id = user.privilege_id + 1;
- p.PrivilegeInfo.permission_name = user.permission_name;
- p.PrivilegeInfo.principal_type = 'USER';
-
- items1.privileges.push(p);
- scope.loadUsers();
- });
-
- deferred.getPrivilegesWithFilters.resolve(all_items);
- deferred.getPrivilegesForResource.promise.then(function(data) {
- var arrayOfPrivileges = data.items[0].privileges;
- var privilegesOfTypeUser = [];
- var privilegesOfTypeGroup = [];
- for (var i = 0; i < arrayOfPrivileges.length; i++) {
- if(arrayOfPrivileges[i].PrivilegeInfo.principal_type === "GROUP"){
- privilegesOfTypeGroup.push(arrayOfPrivileges[i]);
- } else {
- privilegesOfTypeUser.push(arrayOfPrivileges[i].PrivilegeInfo);
- }
- }
-
- var effectivePrivilege = scope.pickEffectivePrivilege(arrayOfPrivileges);
- var effectivePrivilegeFromGroups = scope.pickEffectivePrivilege(privilegesOfTypeGroup);
- user.principal_type = 'USER';
- user.original_perm = effectivePrivilege.permission_name;
- user.editable = (Cluster.ineditableRoles.indexOf(effectivePrivilege.permission_name) === -1);
-
- //add a new privilege of type USER only if it is also the effective privilege considering the user's Group privileges
- var curIndex = scope.getRoleRank(user.permission_name);
- var prevIndex = -1;
- if (privilegesOfTypeGroup.length !== 0) {
- prevIndex = scope.getRoleRank(effectivePrivilegeFromGroups.permission_name);
- }
- if ((curIndex === 6) || (curIndex <= prevIndex)) {
- var privilege_ids = [];
- privilegesOfTypeUser.forEach(function(privilegeOfTypeUser) {
- privilege_ids.push(privilegeOfTypeUser.privilege_id);
- });
-
- //delete all privileges of type USER, if they exist
- //then add the privilege for the user, after which the user displays the effective privilege
- if(privilege_ids.length !== 0) {
- Cluster.deleteMultiplePrivileges(
- 123,
- privilege_ids
- );
- }
- scope.addPrivilege(user);
- } else {
- Alert.error($t('common.alerts.cannotSavePermissions'), "User's effective privilege through its Group(s) is higher than your selected privilege.");
- scope.loadUsers();
- }
- });
-
- scope.$apply();
- });
-
- it('Should save the Privilege equal to the user\'s group privileges. Should also remove any individual user privileges', function() {
- //using 'user1' for updating the new privilege
- user.principal_name = scope.users[0].principal_name;
- user.principal_type = scope.users[0].principal_type;
- user.privilege_id = scope.users[0].privilege_id;
- user.permission_name = "SERVICE.ADMINISTRATOR";
-
- deferred.getPrivilegesForResource.resolve({ "items" : [items1] });
-
- scope.$apply();
-
- expect(scope.users[0].permission_name).toEqual(user.permission_name);
- expect(scope.users[0].privilege_id).toEqual(user.privilege_id + 1);
-
- var oldPrivilege = {
- "href" : "http://abc.com:8080/api/v1/users/user1/privileges/11",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Cluster Administrator",
- "permission_name" : "CLUSTER.ADMINISTRATOR",
- "principal_name" : "user1",
- "principal_type" : "USER",
- "privilege_id" : 11,
- "type" : "CLUSTER",
- "user_name" : "user1"
- }
- };
- var newPrivilege = {
- "PrivilegeInfo" : {
- "permission_name" : user.permission_name,
- "privilege_id" : user.privilege_id+1,
- "principal_type" : "USER",
- "principal_name" : "user1",
- "encoded_name" : "user1",
- "original_perm" : user.permission_name,
- "url" : "users/user1",
- "editable" : true
- }
- };
-
- //test if the individual user privilege CLUSTER.ADMINISTRATOR is removed from 'items1' by deletePrivilege()
- expect(items1.privileges).toNotContain(oldPrivilege);
-
- //test if the new privilege got added to 'items1' by addPrivilege()
- expect(items1.privileges).toContain(newPrivilege);
- });
-
- it('Should save the Privilege greater than the user\'s group privileges. Should also remove any individual user privileges', function() {
- //using 'user1' for updating the new privilege
- user.principal_name = scope.users[0].principal_name;
- user.principal_type = scope.users[0].principal_type;
- user.privilege_id = scope.users[0].privilege_id;
- user.permission_name = "CLUSTER.OPERATOR";
-
- deferred.getPrivilegesForResource.resolve({ "items" : [items1] });
- scope.$apply();
-
- expect(scope.users[0].permission_name).toEqual(user.permission_name);
- expect(scope.users[0].privilege_id).toEqual(user.privilege_id + 1);
-
- var oldPrivilege = {
- "href" : "http://abc.com:8080/api/v1/users/user1/privileges/11",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Cluster Administrator",
- "permission_name" : "CLUSTER.ADMINISTRATOR",
- "principal_name" : "user1",
- "principal_type" : "USER",
- "privilege_id" : 11,
- "type" : "CLUSTER",
- "user_name" : "user1"
- }
- };
- var newPrivilege = {
- "PrivilegeInfo" : {
- "permission_name" : user.permission_name,
- "principal_name" : "user1",
- "principal_type" : "USER",
- "privilege_id" : user.privilege_id + 1,
- "encoded_name" : "user1",
- "original_perm" : user.permission_name,
- "url" : "users/user1",
- "editable" : true
- }
- };
-
- //test if the individual user privilege CLUSTER.ADMINISTRATOR is removed from 'items1' by deletePrivilege()
- expect(items1.privileges).toNotContain(oldPrivilege);
-
- //test if the new privilege got added to 'items1' by addPrivilege()
- expect(items1.privileges).toContain(newPrivilege);
- });
-
- it('Should NOT save the Privilege smaller than the user\'s group privileges. Should keep the user\'s original privileges intact', function() {
- //using 'user1' for updating the new privilege
- user.principal_name = scope.users[0].principal_name;
- user.principal_type = scope.users[0].principal_type;
- user.privilege_id = scope.users[0].privilege_id;
- user.permission_name = "CLUSTER.USER";
-
- deferred.getPrivilegesForResource.resolve({ "items" : [items1] });
- scope.$apply();
-
- expect(scope.users[0].permission_name).toEqual(user.original_perm);
- expect(scope.users[0].privilege_id).toEqual(user.privilege_id);
-
- var oldPrivilege = {
- "href" : "http://abc.com:8080/api/v1/users/user1/privileges/11",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "permission_label" : "Cluster Administrator",
- "permission_name" : "CLUSTER.ADMINISTRATOR",
- "principal_name" : "user1",
- "principal_type" : "USER",
- "privilege_id" : 11,
- "type" : "CLUSTER",
- "user_name" : "user1",
- "encoded_name" : "user1",
- "original_perm" : "CLUSTER.ADMINISTRATOR",
- "url" : "users/user1",
- "editable" : true
- }
- };
- var newPrivilege = {
- "PrivilegeInfo" : {
- "permission_name" : user.permission_name,
- "principal_name" : "user1",
- "principal_type" : "USER",
- "privilege_id" : user.privilege_id+1,
- "encoded_name" : "user1",
- "original_perm" : user.permission_name,
- "url" : "users/user1",
- "editable" : true
- }
- };
-
- //test if the individual user privilege CLUSTER.ADMINISTRATOR is NOT removed from 'items1'
- expect(items1.privileges).toContain(oldPrivilege);
-
- //test if the new privilege is NOT added to 'items1'
- expect(items1.privileges).toNotContain(newPrivilege);
- });
-
- });
-
- describe('#save() for Groups', function() {
- var user = {};
-
- beforeEach(function() {
- items1 = {
- "href" : "http://abc.com:8080/api/v1/groups/mygroup",
- "Groups" : { "group_name" : "mygroup" },
- "privileges" : [
- {
- "href" : "http://abc.com:8080/api/v1/groups/mygroup/privileges/3359",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "group_name" : "mygroup",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup",
- "principal_type" : "GROUP",
- "privilege_id" : 3359,
- "type" : "CLUSTER"
- }
- }
- ]
- };
-
- items2 = {
- "href" : "http://abc.com:8080/api/v1/groups/mygroup2",
- "Groups" : { "group_name" : "mygroup2" },
- "privileges" : [
- {
- "href" : "http://abc.com:8080/api/v1/groups/mygroup2/privileges/3356",
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "group_name" : "mygroup2",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup2",
- "principal_type" : "GROUP",
- "privilege_id" : 3356,
- "type" : "CLUSTER"
- }
- }
- ]
- };
-
- all_items = { "items": [items1, items2]};
-
- scope.loadUsers();
-
- spyOn(Cluster, 'deleteMultiplePrivileges').andCallFake(function(clusterId, privilege_ids) {
- privilege_ids.forEach(function(privilege_id) {
- items1.privileges.forEach(function(p, index) {
- if (p.PrivilegeInfo.privilege_id === privilege_id) {
- //Remove from array
- items1.privileges.splice(index, 1);
- }
- });
- });
- });
- spyOn(scope, 'addPrivilege').andCallFake(function(user) {
- var p = {};
- p.PrivilegeInfo = {};
- p.PrivilegeInfo.privilege_id = user.privilege_id + 1;
- p.PrivilegeInfo.permission_name = user.permission_name;
- p.PrivilegeInfo.principal_type = 'GROUP';
-
- items1.privileges.push(p);
- scope.loadUsers();
- });
-
- deferred.getPrivilegesWithFilters.resolve(all_items);
- deferred.getPrivilegesForResource.promise.then(function(data) {
- var arrayOfPrivileges = data.items[0].privileges;
- var privilegesOfTypeGroup = [];
- var privilege = scope.pickEffectivePrivilege(arrayOfPrivileges);
- user.principal_type = 'GROUP';
- user.original_perm = privilege.permission_name;
- user.editable = (Cluster.ineditableRoles.indexOf(privilege.permission_name) === -1);
-
- arrayOfPrivileges.forEach(function(privilegeOfTypeGroup){
- if (privilegeOfTypeGroup.PrivilegeInfo.principal_type === "GROUP") {
- privilegesOfTypeGroup.push(privilegeOfTypeGroup.PrivilegeInfo);
- }
- });
-
- var privilege_ids = [];
- privilegesOfTypeGroup.forEach(function(privilegeOfTypeGroup) {
- privilege_ids.push(privilegeOfTypeGroup.privilege_id);
- });
-
- //delete all privileges of type GROUP, if they exist
- //then add the privilege for the group, after which the group displays the effective privilege
- if(privilege_ids.length !== 0) {
- Cluster.deleteMultiplePrivileges(
- 123,
- privilege_ids
- );
- }
- scope.addPrivilege(user);
- });
-
- scope.$apply();
- });
-
- it('Should save the Privilege equal to the group\'s effective privilege. Should remove any other privileges of the group',function(){
- //using 'mygroup' for updating the new privilege
- user.principal_name = scope.users[0].principal_name;
- user.principal_type = scope.users[0].principal_type;
- user.privilege_id = scope.users[0].privilege_id;
- user.permission_name = "SERVICE.ADMINISTRATOR";
-
- deferred.getPrivilegesForResource.resolve({ "items" : [items1] });
-
- scope.$apply();
-
- expect(scope.users[0].permission_name).toEqual(user.permission_name);
- expect(scope.users[0].privilege_id).toEqual(user.privilege_id + 1);
-
- var oldPrivilege = {
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "group_name" : "mygroup",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup",
- "principal_type" : "GROUP",
- "privilege_id" : 3359,
- "type" : "CLUSTER"
- }
- };
- var newPrivilege = {
- "PrivilegeInfo" : {
- "privilege_id" : user.privilege_id + 1,
- "permission_name" : user.permission_name,
- "principal_type" : "GROUP",
- "principal_name" : "mygroup",
- "encoded_name" : "mygroup",
- "original_perm" : user.permission_name,
- "url" : "groups/mygroup/edit",
- "editable" : true
- }
- };
-
- //test if the older privilege is no longer present in 'items1'
- expect(items1.privileges).toNotContain(oldPrivilege);
-
- //test if the new privilege is added to 'items1'
- expect(items1.privileges).toContain(newPrivilege);
- });
-
- it('Should save the Privilege greater than the group\'s effective privilege. Should remove any other privileges of the group',function(){
- //using 'mygroup' for updating the new privilege
- user.principal_name = scope.users[0].principal_name;
- user.principal_type = scope.users[0].principal_type;
- user.privilege_id = scope.users[0].privilege_id;
- user.permission_name = "CLUSTER.ADMINISTRATOR";
-
- deferred.getPrivilegesForResource.resolve({ "items" : [items1] });
-
- scope.$apply();
-
- expect(scope.users[0].permission_name).toEqual(user.permission_name);
- expect(scope.users[0].privilege_id).toEqual(user.privilege_id + 1);
-
- var oldPrivilege = {
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "group_name" : "mygroup",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup",
- "principal_type" : "GROUP",
- "privilege_id" : 3359,
- "type" : "CLUSTER"
- }
- };
- var newPrivilege = {
- "PrivilegeInfo" : {
- "privilege_id" : user.privilege_id + 1,
- "permission_name" : user.permission_name,
- "principal_type" : "GROUP",
- "principal_name" : "mygroup",
- "encoded_name" : "mygroup",
- "original_perm" : user.permission_name,
- "url" : "groups/mygroup/edit",
- "editable" : true
- }
- };
-
- //test if the older privilege is no longer present in 'items1'
- expect(items1.privileges).toNotContain(oldPrivilege);
-
- //test if the new privilege is added to 'items1'
- expect(items1.privileges).toContain(newPrivilege);
- });
-
- it('Should save the Privilege lesser than the group\'s effective privilege. Should remove any other privileges of the group', function() {
- //using 'mygroup' for updating the new privilege
- user.principal_name = scope.users[0].principal_name;
- user.principal_type = scope.users[0].principal_type;
- user.privilege_id = scope.users[0].privilege_id;
- user.permission_name = "CLUSTER.USER";
-
- deferred.getPrivilegesForResource.resolve({ "items" : [items1] });
-
- scope.$apply();
-
- expect(scope.users[0].permission_name).toEqual(user.permission_name);
- expect(scope.users[0].privilege_id).toEqual(user.privilege_id + 1);
-
- var oldPrivilege = {
- "PrivilegeInfo" : {
- "cluster_name" : "myCluster",
- "group_name" : "mygroup",
- "permission_label" : "Service Administrator",
- "permission_name" : "SERVICE.ADMINISTRATOR",
- "principal_name" : "mygroup",
- "principal_type" : "GROUP",
- "privilege_id" : 3359,
- "type" : "CLUSTER"
- }
- };
- var newPrivilege = {
- "PrivilegeInfo" : {
- "privilege_id" : user.privilege_id + 1,
- "permission_name" : user.permission_name,
- "principal_type" : "GROUP",
- "principal_name" : "mygroup",
- "encoded_name" : "mygroup",
- "original_perm" : user.permission_name,
- "url" : "groups/mygroup/edit",
- "editable" : true
- }
- };
-
- //test if the older privilege is no longer present in 'items1'
- expect(items1.privileges).toNotContain(oldPrivilege);
-
- //test if the new privilege is added to 'items1'
- expect(items1.privileges).toContain(newPrivilege);
- });
-
- });
-
- describe('#pickEffectivePrivilege()', function() {
- var cases = [{
- "test" : [{
- "href" : "http://abc.com:8080/api/v1/groups/mygroup1",
- "PrivilegeInfo" : {
- "instance_name" : "jobs_view",
- "permission_label" : "View User",
- "permission_name" : "VIEW.USER",
- "principal_name" : "mygroup1",
- "principal_type" : "GROUP",
- "privilege_id" : 111,
- "type" : "VIEW",
- "user_name" : "mygroup1",
- "view_name" : "JOBS"
- }
- }],
- "result":{
- "permission_name": "CLUSTER.NONE"
- }
- }, {
- "test": [{
- "href" : "http://abc.com:8080/api/v1/groups/mygroup2",
- "PrivilegeInfo" : {
- "cluster_name":"mycluster",
- "permission_label" : "Cluster User",
- "permission_name" : "CLUSTER.USER",
- "principal_name" : "mygroup2",
- "principal_type" : "GROUP",
- "privilege_id" : 222,
- "type" : "CLUSTER",
- "user_name":"mygroup2"
- }
- }],
- "result":{
- "permission_name": "CLUSTER.USER"
- }
- }, {
- "test":[{
- "href" : "http://abc.com:8080/api/v1/groups/mygroup3",
- "PrivilegeInfo" : {
- "cluster_name":"mycluster",
- "permission_label" : "Cluster User",
- "permission_name" : "CLUSTER.USER",
- "principal_name" : "mygroup3",
- "principal_type" : "GROUP",
- "privilege_id" : 333,
- "type" : "CLUSTER",
- "user_name":"mygroup3"
- }
- }, {
- "href" : "http://abc.com:8080/api/v1/groups/mygroup3",
- "PrivilegeInfo" : {
- "instance_name": "jobs_view",
- "permission_label" : "View User",
- "permission_name" : "VIEW.USER",
- "principal_name" : "mygroup3",
- "principal_type" : "GROUP",
- "privilege_id" : 3333,
- "type" : "VIEW",
- "user_name":"mygroup3",
- "view_name":"JOBS"
- }
- }],
- "result":{
- "permission_name": "CLUSTER.USER"
- }
- }, {
- "test": [{
- "href" : "http://abc.com:8080/api/v1/users/myuser1/privileges/11",
- "PrivilegeInfo" : {
- "instance_name": "jobs_view",
- "permission_label" : "View User",
- "permission_name" : "VIEW.USER",
- "principal_name" : "myuser1",
- "principal_type" : "USER",
- "privilege_id" : 11,
- "type" : "VIEW",
- "user_name":"myuser1",
- "view_name":"JOBS"
- }
- }],
- "result":{
- "permission_name": "CLUSTER.NONE"
- }
- }, {
- "test":[{
- "href" : "http://abc.com:8080/api/v1/users/myuser2/privileges/22",
- "PrivilegeInfo" : {
- "cluster_name":"mycluster",
- "permission_label" : "Cluster Administrator",
- "permission_name" : "CLUSTER.ADMINISTRATOR",
- "principal_name" : "myuser2",
- "principal_type" : "USER",
- "privilege_id" : 22,
- "type" : "CLUSTER",
- "user_name":"myuser2"
- }
- }],
- "result":{
- "permission_name": "CLUSTER.ADMINISTRATOR"
- }
- }
- ];
-
- it('User/Group with only View User permission must show \'None\' as the Cluster Permission, otherwise show the effective privilege', function(){
- var effectivePrivilege;
- cases.forEach(function (item){
- effectivePrivilege = scope.pickEffectivePrivilege(item.test);
- scope.$apply();
- expect(effectivePrivilege.permission_name).toEqual(item.result.permission_name);
- });
- });
- });
-
- });
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/groups/GroupsListCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/groups/GroupsListCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/groups/GroupsListCtrl_test.js
deleted file mode 100644
index 8ed228b..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/groups/GroupsListCtrl_test.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-describe('#Cluster', function () {
-
- describe('GroupsListCtrl', function() {
-
- var scope, ctrl, $t, $httpBackend;
-
- beforeEach(module('ambariAdminConsole', function () {}));
-
- beforeEach(inject(function($rootScope, $controller, _$translate_, _$httpBackend_) {
- scope = $rootScope.$new();
- $t = _$translate_.instant;
- $httpBackend = _$httpBackend_;
- ctrl = $controller('GroupsListCtrl', {
- $scope: scope
- });
- }));
-
- describe('#clearFilters()', function () {
-
- it('should clear filters and reset pagination', function () {
- scope.currentPage = 2;
- scope.currentNameFilter = 'a';
- scope.currentTypeFilter = {
- label: $t('common.local'),
- value: false
- };
- scope.clearFilters();
- expect(scope.currentNameFilter).toEqual('');
- expect(scope.currentTypeFilter).toEqual({
- label: $t('common.all'),
- value: '*'
- });
- expect(scope.currentPage).toEqual(1);
- });
-
- });
-
- describe('#isNotEmptyFilter', function () {
-
- var cases = [
- {
- currentNameFilter: '',
- currentTypeFilter: null,
- isNotEmptyFilter: false,
- title: 'no filters'
- },
- {
- currentNameFilter: '',
- currentTypeFilter: {
- value: '*'
- },
- isNotEmptyFilter: false,
- title: 'empty filters'
- },
- {
- currentNameFilter: 'a',
- currentTypeFilter: {
- value: '*'
- },
- isNotEmptyFilter: true,
- title: 'name filter'
- },
- {
- currentNameFilter: '0',
- currentTypeFilter: {
- value: '*'
- },
- isNotEmptyFilter: true,
- title: 'name filter with "0" as string'
- },
- {
- currentNameFilter: '',
- currentTypeFilter: {
- value: false
- },
- isNotEmptyFilter: true,
- title: 'type filter'
- },
- {
- currentNameFilter: 'a',
- currentTypeFilter: {
- value: false
- },
- isNotEmptyFilter: true,
- title: 'both filters'
- },
- {
- currentNameFilter: '0',
- currentTypeFilter: {
- value: false
- },
- isNotEmptyFilter: true,
- title: 'both filters with "0" as string'
- }
- ];
-
- cases.forEach(function (item) {
- it(item.title, function () {
- $httpBackend.expectGET(/\/api\/v1\/groups/).respond(200);
- scope.currentNameFilter = item.currentNameFilter;
- scope.currentTypeFilter = item.currentTypeFilter;
- scope.$digest();
- expect(scope.isNotEmptyFilter).toEqual(item.isNotEmptyFilter);
- });
- });
-
- });
-
- });
-
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/99b19e58/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js
new file mode 100644
index 0000000..8d04757
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js
@@ -0,0 +1,129 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+describe('#Cluster', function () {
+
+ describe('GroupsListCtrl', function() {
+
+ var scope, ctrl, $t, $httpBackend;
+
+ beforeEach(module('ambariAdminConsole', function () {}));
+
+ beforeEach(inject(function($rootScope, $controller, _$translate_, _$httpBackend_) {
+ scope = $rootScope.$new();
+ $t = _$translate_.instant;
+ $httpBackend = _$httpBackend_;
+ ctrl = $controller('GroupsListCtrl', {
+ $scope: scope
+ });
+ }));
+
+ describe('#clearFilters()', function () {
+
+ it('should clear filters and reset pagination', function () {
+ scope.currentPage = 2;
+ scope.filter.name = 'a';
+ scope.filter.type = {
+ label: $t('common.local'),
+ value: false
+ };
+ scope.clearFilters();
+ expect(scope.filter.name).toEqual('');
+ expect(scope.filter.type).toEqual({
+ label: $t('common.all'),
+ value: '*'
+ });
+ expect(scope.currentPage).toEqual(1);
+ });
+
+ });
+
+ describe('#isNotEmptyFilter', function () {
+
+ var cases = [
+ {
+ currentNameFilter: '',
+ currentTypeFilter: null,
+ isNotEmptyFilter: false,
+ title: 'no filters'
+ },
+ {
+ currentNameFilter: '',
+ currentTypeFilter: {
+ value: '*'
+ },
+ isNotEmptyFilter: false,
+ title: 'empty filters'
+ },
+ {
+ currentNameFilter: 'a',
+ currentTypeFilter: {
+ value: '*'
+ },
+ isNotEmptyFilter: true,
+ title: 'name filter'
+ },
+ {
+ currentNameFilter: '0',
+ currentTypeFilter: {
+ value: '*'
+ },
+ isNotEmptyFilter: true,
+ title: 'name filter with "0" as string'
+ },
+ {
+ currentNameFilter: '',
+ currentTypeFilter: {
+ value: false
+ },
+ isNotEmptyFilter: true,
+ title: 'type filter'
+ },
+ {
+ currentNameFilter: 'a',
+ currentTypeFilter: {
+ value: false
+ },
+ isNotEmptyFilter: true,
+ title: 'both filters'
+ },
+ {
+ currentNameFilter: '0',
+ currentTypeFilter: {
+ value: false
+ },
+ isNotEmptyFilter: true,
+ title: 'both filters with "0" as string'
+ }
+ ];
+
+ cases.forEach(function (item) {
+ it(item.title, function () {
+ $httpBackend.expectGET(/\/api\/v1\/groups/).respond(200);
+ scope.filter.name = item.currentNameFilter;
+ scope.filter.type = item.currentTypeFilter;
+ scope.$digest();
+ expect(scope.isNotEmptyFilter).toEqual(item.isNotEmptyFilter);
+ });
+ });
+
+ });
+
+ });
+
+});