Skip to content

Commit eca110b

Browse files
committed
/series/import/requests: show a list of import requests.
Fix #692
1 parent cc76e61 commit eca110b

File tree

16 files changed

+255
-0
lines changed

16 files changed

+255
-0
lines changed

src/main/java/ru/mystamps/web/Url.java

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public final class Url {
5555

5656
public static final String REQUEST_IMPORT_SERIES_PAGE = "/series/import/request";
5757
public static final String REQUEST_IMPORT_PAGE = "/series/import/request/{id}";
58+
public static final String LIST_IMPORT_REQUESTS_PAGE = "/series/import/requests";
5859

5960
public static final String SUGGEST_SERIES_COUNTRY = "/suggest/series_country";
6061

@@ -142,6 +143,7 @@ public static Map<String, String> asMap(boolean production) {
142143
map.put("SEARCH_SERIES_BY_CATALOG", SEARCH_SERIES_BY_CATALOG);
143144
map.put("REQUEST_IMPORT_SERIES_PAGE", REQUEST_IMPORT_SERIES_PAGE);
144145
map.put("REQUEST_IMPORT_PAGE", REQUEST_IMPORT_PAGE);
146+
map.put("LIST_IMPORT_REQUESTS_PAGE", LIST_IMPORT_REQUESTS_PAGE);
145147
map.put("SUGGEST_SERIES_COUNTRY", SUGGEST_SERIES_COUNTRY);
146148
map.put("ADD_CATEGORY_PAGE", ADD_CATEGORY_PAGE);
147149
map.put("INFO_CATEGORY_PAGE", INFO_CATEGORY_PAGE);

src/main/java/ru/mystamps/web/controller/SeriesImportController.java

+7
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,12 @@ public String processImportSeriesForm(
187187
return redirectTo(Url.INFO_SERIES_PAGE, seriesId);
188188
}
189189

190+
@GetMapping(Url.LIST_IMPORT_REQUESTS_PAGE)
191+
public String showListOfImportRequests(Model model) {
192+
model.addAttribute("requests", seriesImportService.findAll());
193+
194+
return "series/import/list";
195+
}
196+
190197
}
191198

src/main/java/ru/mystamps/web/dao/SeriesImportDao.java

+3
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
package ru.mystamps.web.dao;
1919

2020
import java.util.Date;
21+
import java.util.List;
2122

2223
import ru.mystamps.web.dao.dto.ImportRequestDto;
24+
import ru.mystamps.web.dao.dto.ImportRequestFullInfo;
2325
import ru.mystamps.web.dao.dto.ImportRequestInfo;
2426
import ru.mystamps.web.dao.dto.ImportSeriesDbDto;
2527
import ru.mystamps.web.dao.dto.ParsedDataDto;
@@ -41,4 +43,5 @@ void setSeriesIdAndChangeStatus(
4143
void addParsedContent(Integer requestId, SaveParsedDataDbDto data);
4244
ParsedDataDto findParsedDataByRequestId(Integer requestId, String lang);
4345
ImportRequestInfo findRequestInfo(Integer seriesId);
46+
List<ImportRequestFullInfo> findAll();
4447
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (C) 2009-2017 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.dao.dto;
19+
20+
import java.util.Date;
21+
22+
import lombok.Getter;
23+
import lombok.RequiredArgsConstructor;
24+
import lombok.ToString;
25+
26+
@Getter
27+
@ToString
28+
@RequiredArgsConstructor
29+
public class ImportRequestFullInfo {
30+
private final Integer id;
31+
private final String url;
32+
private final String status;
33+
private final Date updatedAt;
34+
}

src/main/java/ru/mystamps/web/dao/impl/JdbcSeriesImportDao.java

+14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Collections;
2121
import java.util.Date;
2222
import java.util.HashMap;
23+
import java.util.List;
2324
import java.util.Map;
2425

2526
import org.apache.commons.lang3.Validate;
@@ -35,6 +36,7 @@
3536

3637
import ru.mystamps.web.dao.SeriesImportDao;
3738
import ru.mystamps.web.dao.dto.ImportRequestDto;
39+
import ru.mystamps.web.dao.dto.ImportRequestFullInfo;
3840
import ru.mystamps.web.dao.dto.ImportRequestInfo;
3941
import ru.mystamps.web.dao.dto.ImportSeriesDbDto;
4042
import ru.mystamps.web.dao.dto.ParsedDataDto;
@@ -74,6 +76,9 @@ public class JdbcSeriesImportDao implements SeriesImportDao {
7476
@Value("${series_import_requests.find_request_info_by_series_id}")
7577
private String findRequestInfoSql;
7678

79+
@Value("${series_import_requests.find_all}")
80+
private String findAllSql;
81+
7782
@Override
7883
public Integer add(ImportSeriesDbDto importRequest) {
7984
Map<String, Object> params = new HashMap<>();
@@ -255,4 +260,13 @@ public ImportRequestInfo findRequestInfo(Integer seriesId) {
255260
}
256261
}
257262

263+
@Override
264+
public List<ImportRequestFullInfo> findAll() {
265+
return jdbcTemplate.query(
266+
findAllSql,
267+
Collections.emptyMap(),
268+
RowMappers::forImportRequestFullInfo
269+
);
270+
}
271+
258272
}

src/main/java/ru/mystamps/web/dao/impl/RowMappers.java

+11
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,17 @@ public static ImportRequestInfo forImportRequestInfo(ResultSet rs, int i) throws
276276
return new ImportRequestInfo(rs.getInt("id"), rs.getString("url"));
277277
}
278278

279+
public static ImportRequestFullInfo forImportRequestFullInfo(ResultSet rs, int i)
280+
throws SQLException {
281+
282+
return new ImportRequestFullInfo(
283+
rs.getInt("id"),
284+
rs.getString("url"),
285+
rs.getString("status"),
286+
rs.getTimestamp("updated_at")
287+
);
288+
}
289+
279290
private static LinkEntityDto createLinkEntityDto(
280291
ResultSet rs,
281292
String idColumn,

src/main/java/ru/mystamps/web/service/SeriesImportService.java

+4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
*/
1818
package ru.mystamps.web.service;
1919

20+
import java.util.List;
21+
2022
import ru.mystamps.web.dao.dto.ImportRequestDto;
23+
import ru.mystamps.web.dao.dto.ImportRequestFullInfo;
2124
import ru.mystamps.web.dao.dto.ImportRequestInfo;
2225
import ru.mystamps.web.dao.dto.ParsedDataDto;
2326
import ru.mystamps.web.service.dto.AddSeriesDto;
@@ -34,4 +37,5 @@ public interface SeriesImportService {
3437
void saveParsedData(Integer requestId, RawParsedDataDto data);
3538
ParsedDataDto getParsedData(Integer requestId, String lang);
3639
ImportRequestInfo findRequestInfo(Integer seriesId);
40+
List<ImportRequestFullInfo> findAll();
3741
}

src/main/java/ru/mystamps/web/service/SeriesImportServiceImpl.java

+9
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import ru.mystamps.web.controller.event.ParsingFailed;
3737
import ru.mystamps.web.dao.SeriesImportDao;
3838
import ru.mystamps.web.dao.dto.ImportRequestDto;
39+
import ru.mystamps.web.dao.dto.ImportRequestFullInfo;
3940
import ru.mystamps.web.dao.dto.ImportRequestInfo;
4041
import ru.mystamps.web.dao.dto.ImportSeriesDbDto;
4142
import ru.mystamps.web.dao.dto.ParsedDataDto;
@@ -211,4 +212,12 @@ public ImportRequestInfo findRequestInfo(Integer seriesId) {
211212
return seriesImportDao.findRequestInfo(seriesId);
212213
}
213214

215+
// @todo #692 SeriesImportServiceImpl.findAll(): add unit tests
216+
@Override
217+
@Transactional(readOnly = true)
218+
@PreAuthorize(HasAuthority.IMPORT_SERIES)
219+
public List<ImportRequestFullInfo> findAll() {
220+
return seriesImportDao.findAll();
221+
}
222+
214223
}

src/main/resources/ru/mystamps/i18n/Messages.properties

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ t_index_title = create your own virtual collection!
5353
t_you_may = You may
5454
t_show_categories_list = show list of categories
5555
t_show_countries_list = show list of countries
56+
t_show_import_requests_list = show list of import requests
5657
t_in_db = In our database
5758
t_categories_amount = Categories
5859
t_countries_amount = Countries
@@ -197,3 +198,7 @@ t_status = Status
197198
t_imported_series = Imported series
198199
t_gathered_data = Gathered data
199200
t_import = Import
201+
202+
# series/import/list.html
203+
t_no_import_requests = No import requests
204+
t_import_requests = import requests

src/main/resources/ru/mystamps/i18n/Messages_ru.properties

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ t_index_title = создай свою виртуальную коллекцию!
5353
t_you_may = Вы можете
5454
t_show_categories_list = посмотреть список категорий
5555
t_show_countries_list = посмотреть список стран
56+
t_show_import_requests_list = посмотреть список запросов на импорт
5657
t_in_db = В нашей базе
5758
t_categories_amount = Категорий
5859
t_countries_amount = Стран
@@ -197,3 +198,7 @@ t_status = Статус
197198
t_imported_series = Импортированная серия
198199
t_gathered_data = Собранные данные
199200
t_import = Импортировать
201+
202+
# series/import/list.html
203+
t_no_import_requests = Нет запросов на импорт
204+
t_import_requests = запросы на импорт

src/main/resources/sql/series_import_request_dao_queries.properties

+9
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,12 @@ SELECT id \
122122
, url \
123123
FROM series_import_requests \
124124
WHERE series_id = :series_id
125+
126+
series_import_requests.find_all = \
127+
SELECT r.id \
128+
, r.url \
129+
, s.name AS status \
130+
, r.updated_at \
131+
FROM series_import_requests r \
132+
JOIN series_import_request_statuses s \
133+
ON r.status_id = s.id
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<!DOCTYPE html>
2+
<html lang="en" th:lang="${#locale.language == 'ru' ? 'ru' : 'en'}"
3+
xmlns="http://www.w3.org/1999/xhtml"
4+
xmlns:th="http://www.thymeleaf.org"
5+
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
6+
<head>
7+
<meta charset="utf-8" />
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
9+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
10+
<meta name="robots" content="noindex" />
11+
<title th:text="|#{t_my_stamps}: #{t_import_requests}|">My stamps: import requests</title>
12+
<link rel="shortcut icon" type="image/x-icon" href="../../../../favicon.ico" th:href="${FAVICON_ICO}" />
13+
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" th:href="${BOOTSTRAP_CSS}" />
14+
<link rel="stylesheet" href="https://cdn.rawgit.com/usrz/bootstrap-languages/3ac2a3d2b27ac43a471cd99e79d378a03b2c6b5f/languages.min.css" th:href="${BOOTSTRAP_LANGUAGE}" />
15+
<link rel="stylesheet" href="../../../static/styles/main.css" th:href="${MAIN_CSS}" />
16+
</head>
17+
<body>
18+
<div class="container-fluid">
19+
<div class="row" id="header">
20+
<div id="logo" class="col-sm-9 vcenter">
21+
<a href="../../site/index.html" th:href="'/'" th:text="#{t_my_stamps}">My stamps</a>
22+
</div><!--
23+
24+
--><div class="col-sm-1 vcenter"
25+
th:with="lang=${#locale.language == 'en' ? 'ru' : 'en'},langName=${#locale.language == 'en' ? 'Русский' : 'English'}">
26+
<span class="lang-xs" lang="ru"
27+
th:lang="${lang}"></span>
28+
<a href="javascript:void(0)" hreflang="ru"
29+
th:href="|?lang=${lang}|" th:hreflang="${lang}" th:text="${langName}">Русский</a>
30+
</div><!--
31+
32+
--><div id="user_bar" class="col-sm-2 vcenter">
33+
<ul class="list-unstyled">
34+
<li sec:authorize="isAuthenticated()">
35+
<i class="glyphicon glyphicon-user"></i>
36+
<a sec:authentication="principal.userName"
37+
href="../../collection/info.html"
38+
title="Open my collection"
39+
th:title="#{t_open_my_collection}"
40+
th:href="@{${INFO_COLLECTION_PAGE}(slug=${#authentication.principal.userCollectionSlug})}">
41+
John Doe
42+
</a>
43+
</li>
44+
<!--/*/
45+
<li sec:authorize="isAnonymous()">
46+
<a href="../../account/auth.html" th:href="@{${AUTHENTICATION_PAGE}}" th:text="#{t_enter}">Sign in</a>
47+
</li>
48+
/*/-->
49+
<li sec:authorize="isAuthenticated()">
50+
<form id="logout-form" method="get" action="../../site/index.html" class="no-margin" th:method="post" th:action="@{${LOGOUT_PAGE}}">
51+
<i class="glyphicon glyphicon-share"></i>&nbsp;<input type="submit" value="Sign out" class="btn btn-link no-padding" th:value="#{t_logout}" />
52+
</form>
53+
</li>
54+
<!--/*/
55+
<li sec:authorize="isAnonymous()">
56+
<a href="../../account/register.html" th:href="@{${REGISTRATION_PAGE}}" th:text="#{t_register}">Register</a>
57+
</li>
58+
/*/-->
59+
</ul>
60+
</div>
61+
</div>
62+
<div class="row">
63+
<div id="content" class="col-sm-8 col-sm-offset-2" th:with="header=#{t_import_requests}">
64+
<h3 th:text="${#strings.capitalize(header)}">
65+
Import requests
66+
</h3>
67+
68+
<!--/*/
69+
<p class="text-center" th:if="${#lists.isEmpty(requests)}" th:text="#{t_no_import_requests}">
70+
No import requests
71+
</p>
72+
/*/-->
73+
74+
<div class="col-sm-12 table-responsive" th:if="${not #lists.isEmpty(requests)}">
75+
<table class="table table-bordered table-striped">
76+
<thead>
77+
<tr>
78+
<th th:text="#{t_date}">Date</th>
79+
<th th:text="#{t_status}">Status</th>
80+
<th th:text="#{t_url}">URL</th>
81+
</tr>
82+
</thead>
83+
<tbody th:remove="all-but-first">
84+
<tr th:each="request : ${requests}">
85+
<td th:text="${#dates.format(request.updatedAt, 'dd.MM.yyyy HH:mm:ss')}">19.12.2017 21:57:12</td>
86+
<td th:switch="${request.status}">
87+
<!--/*/
88+
<span class="label label-default" th:text="${request.status}" th:case=" 'Unprocessed' ">Unprocessed</span>
89+
<span class="label label-info" th:text="${request.status}" th:case=" 'DownloadingSucceeded' ">DownloadingSucceeded</span>
90+
<span class="label label-danger" th:text="${request.status}" th:case=" 'DownloadingFailed' ">DownloadingFailed</span>
91+
/*/-->
92+
<span class="label label-info" th:text="${request.status}" th:case=" 'ParsingSucceeded' ">ParsingSucceeded</span>
93+
<!--/*/
94+
<span class="label label-danger" th:text="${request.status}" th:case=" 'ParsingFailed' ">ParsingFailed</span>
95+
<span class="label label-success" th:text="${request.status}" th:case=" 'ImportSucceeded' ">ImportSucceeded</span>
96+
<span class="label label-warning" th:text="${request.status}" th:case="*">Unknown</span>
97+
/*/-->
98+
</td>
99+
<td>
100+
<a href="./info.html" th:href="@{${REQUEST_IMPORT_PAGE}(id=${request.id})}" th:text="${request.url}">
101+
http://example.com/my-first-series.html
102+
</a>
103+
</td>
104+
</tr>
105+
<tr>
106+
<td>19.12.2017 21:50:01</td>
107+
<td><span class="label label-success">ImportSucceeded</span></td>
108+
<td><a href="./info.html">http://example.com/my-second-series.html</a></td>
109+
</tr>
110+
<tr>
111+
<td>19.12.2017 21:47:05</td>
112+
<td><span class="label label-danger">ParsingFailed</span></td>
113+
<td><a href="./info.html">http://example.com/my-third-series.html</a></td>
114+
</tr>
115+
</tbody>
116+
</table>
117+
</div>
118+
119+
</div>
120+
</div>
121+
<div class="row">
122+
<footer class="col-sm-12 text-right">
123+
<i class="glyphicon glyphicon-envelope"></i>
124+
<a href="mailto:[email protected]" title="Write e-mail" th:href="|mailto:#{t_site_author_email}|" th:title="#{t_write_email}" th:text="#{t_site_author_name}">Slava Semushin</a>, 2009-2017
125+
</footer>
126+
</div>
127+
</div>
128+
129+
<!-- Placed at the end of the document so the pages load faster -->
130+
<script src="http://yandex.st/jquery/1.9.1/jquery.min.js" th:src="${JQUERY_JS}"></script>
131+
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" th:src="${BOOTSTRAP_JS}"></script>
132+
</body>
133+
</html>

src/main/webapp/WEB-INF/views/site/index.html

+3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@
7070
<li togglz:active="LIST_COUNTRIES">
7171
<a th:href="@{${LIST_COUNTRIES_PAGE}}" th:text="#{t_show_countries_list}" href="../country/list.html">show list of countries</a>
7272
</li>
73+
<li sec:authorize="hasAuthority('IMPORT_SERIES')">
74+
<a th:href="@{${LIST_IMPORT_REQUESTS_PAGE}}" th:text="#{t_show_import_requests_list}" href="../series/import/list.html">show list of import requests</a>
75+
</li>
7376
<li sec:authorize="hasAuthority('CREATE_SERIES')">
7477
<a th:href="@{${ADD_SERIES_PAGE}}" th:text="#{t_add_series}" href="../series/add.html">add stamp series</a>
7578
</li>

src/test/robotframework/series/import/access.robot

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ Anonymous user cannot access the status of the series import
1818
Element Text Should Be id=error-code 403
1919
Element Text Should Be id=error-msg Forbidden
2020

21+
Anonymous user cannot see a lise of import requests
22+
[Documentation] Verify that anonymous user gets 403 error
23+
Go To ${SITE_URL}/series/import/requests
24+
Element Text Should Be id=error-code 403
25+
Element Text Should Be id=error-msg Forbidden
26+
2127
*** Keywords ***
2228
Before Test Suite
2329
[Documentation] Open browser and register fail hook

src/test/robotframework/site/misc-admin.robot

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ Admin should see a link to a page for importing a series
1212
[Tags] import-series
1313
Page Should Contain Link link=import a series
1414

15+
Admin should see a link to a list of import requests
16+
[Documentation] Verify presence of a link for list of import requests
17+
[Tags] import-series
18+
Page Should Contain Link link=show list of import requests
19+
1520
*** Keywords ***
1621
Before Test Suite
1722
[Documentation] Login as admin and go to the main page

0 commit comments

Comments
 (0)