new SeleneseTest(selenese).runOn(orchestrator);
}
+ @Test
+ public void should_display_issues() throws Exception {
+ Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("should_display_issues",
+ "/user/MyAccountPageTest/should_display_issues.html"
+ ).build();
+ new SeleneseTest(selenese).runOn(orchestrator);
+ }
+
private static void createUser(String login, String name, String email) {
adminWsClient.wsConnector().call(
new PostRequest("api/users/create")
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <link rel="selenium.base" href="http://localhost:49506"/>
+ <title>should_display_issues</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+ <thead>
+ <tr>
+ <td rowspan="1" colspan="3">should_display_issues</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>open</td>
+ <td>/sonar/sessions/login</td>
+ <td></td>
+</tr>
+<tr>
+ <td>type</td>
+ <td>login</td>
+ <td>account-user</td>
+</tr>
+<tr>
+ <td>type</td>
+ <td>password</td>
+ <td>password</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>commit</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/sonar/account/issues</td>
+ <td></td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>css=[data-unresolved]</td>
+ <td></td>
+</tr>
+</tbody>
+</table>
+</body>
+</html>
import Home from './components/Home';
import NotificationsContainer from './containers/NotificationsContainer';
import SecurityContainer from './containers/SecurityContainer';
+import IssuesContainer from './containers/IssuesContainer';
import './styles/account.css';
<Router history={history}>
<Route path="/" component={AccountApp}>
<IndexRoute component={Home}/>
+ <Route path="issues" component={IssuesContainer}/>
<Route path="notifications" component={NotificationsContainer}/>
<Route path="security" component={SecurityContainer}/>
<i className="icon-home"/>
</IndexLink>
</li>
+ <li>
+ <a
+ className={window.location.pathname === `${window.baseUrl}/account/issues` && 'active'}
+ href={`${window.baseUrl}/account/issues`}>
+ {translate('issues.page')}
+ </a>
+ </li>
<li>
<IndexLink to="notifications" activeClassName="active">
{translate('my_account.notifications')}
});
return (
- <div>
+ <div className="account-page">
<Nav user={user}/>
{children}
</div>
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import React, { Component } from 'react';
+
+import IssuesApp from '../issues-app';
+
+export default class IssuesContainer extends Component {
+ componentDidMount () {
+ this.issuesApp = IssuesApp;
+ this.issuesApp.start({
+ el: this.refs.container
+ });
+ }
+
+ componentWillUnmount () {
+ this.issuesApp.stop();
+ }
+
+ render () {
+ return <div ref="container"></div>;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import $ from 'jquery';
+import _ from 'underscore';
+import Backbone from 'backbone';
+import Marionette from 'backbone.marionette';
+import State from '../issues/models/state';
+import Layout from '../issues/layout';
+import Issues from '../issues/models/issues';
+import Facets from '../../components/navigator/models/facets';
+import Filters from '../issues/models/filters';
+import Controller from '../issues/controller';
+import Router from '../issues/router';
+import WorkspaceListView from '../issues/workspace-list-view';
+import WorkspaceHeaderView from '../issues/workspace-header-view';
+import FacetsView from './../issues/facets-view';
+
+var App = new Marionette.Application(),
+ init = function (options) {
+ this.config = options.config;
+ this.state = new State({
+ isContext: true,
+ contextQuery: { assignees: '__me__' }
+ });
+ this.updateContextFacets();
+ this.list = new Issues();
+ this.facets = new Facets();
+ this.filters = new Filters();
+
+ this.layout = new Layout({ app: this });
+ this.layout.$el.appendTo(options.el);
+ this.layout.render();
+ $('#footer').addClass('search-navigator-footer');
+
+ this.controller = new Controller({ app: this });
+
+ this.issuesView = new WorkspaceListView({
+ app: this,
+ collection: this.list
+ });
+ this.layout.workspaceListRegion.show(this.issuesView);
+ this.issuesView.bindScrollEvents();
+
+ this.workspaceHeaderView = new WorkspaceHeaderView({
+ app: this,
+ collection: this.list
+ });
+ this.layout.workspaceHeaderRegion.show(this.workspaceHeaderView);
+
+ this.facetsView = new FacetsView({
+ app: this,
+ collection: this.facets
+ });
+ this.layout.facetsRegion.show(this.facetsView);
+
+ this.controller.fetchFilters().done(function () {
+ key.setScope('list');
+ App.router = new Router({ app: App });
+ Backbone.history.start();
+ });
+ };
+
+App.getContextQuery = function () {
+ return { assignees: '__me__' };
+};
+
+App.updateContextFacets = function () {
+ var facets = this.state.get('facets'),
+ allFacets = this.state.get('allFacets'),
+ facetsFromServer = this.state.get('facetsFromServer');
+ return this.state.set({
+ facets: facets,
+ allFacets: _.difference(allFacets, ['assignees']),
+ facetsFromServer: _.difference(facetsFromServer, ['assignees'])
+ });
+};
+
+App.stop = function () {
+ App.layout.destroy();
+ Backbone.history.stop();
+};
+
+App.on('start', function (options) {
+ init.call(App, options);
+});
+
+export default App;
.account-header {
+ position: fixed;
+ top: 30px;
+ left: 0;
+ right: 0;
+ z-index: 420;
background-color: #f3f3f3;
}
float: left;
margin-right: 20px;
}
+
+.account-page {
+ padding-top: 102px;
+}
key('c', 'list', function () {
return doAction('comment');
});
- return key('t', 'list', function () {
+ key('t', 'list', function () {
return doAction('edit-tags');
});
},
+ unbindShortcuts: function () {
+ WorkspaceListView.prototype.unbindShortcuts.apply(this, arguments);
+ key.unbind('right', 'list');
+ key.unbind('space', 'list');
+ key.unbind('f', 'list');
+ key.unbind('a', 'list');
+ key.unbind('m', 'list');
+ key.unbind('p', 'list');
+ key.unbind('i', 'list');
+ key.unbind('c', 'list');
+ key.unbind('t', 'list');
+ },
+
scrollTo: function () {
var selectedIssue = this.collection.at(this.options.app.state.get('selectedIndex'));
if (selectedIssue == null) {
});
},
+ unbindShortcuts: function () {
+ key.unbind('up', 'list');
+ key.unbind('down', 'list');
+ },
+
loadMore: function () {
if (!this.options.app.state.get('maxResultsReached')) {
var that = this;