Skip to content

Commit 62f0f96

Browse files
added tests
1 parent 9a695c3 commit 62f0f96

File tree

18 files changed

+552
-52
lines changed

18 files changed

+552
-52
lines changed

.idea/compiler.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 138 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,63 @@
1-
# java-project-72
1+
# Page Analyzer — Анализатор страниц
22

33
![Java CI](https://github.com/irinakomarchenko/java-project-72/actions/workflows/ci.yml/badge.svg)
44
[![Maintainability](https://qlty.sh/gh/irinakomarchenko/projects/java-project-72/maintainability.svg)](https://qlty.sh/gh/irinakomarchenko/projects/java-project-72)
55

6+
## О проекте
7+
8+
Page Analyzer — это учебный проект на Java + Javalin, показывающий классическую MVC-архитектуру, работу с HTTP, шаблонами JTE, подключение к БД (H2, PostgreSQL), тестирование и автоматический деплой через Render.
9+
10+
## Возможности
11+
12+
- Добавление и хранение URL-адресов в базе
13+
- Анализ SEO-параметров страниц (`title`, `h1`, `meta description`)
14+
- Ручной запуск и история проверок для каждой страницы
15+
- Пагинация, валидация форм, flash-сообщения
16+
- Современное оформление на Bootstrap 5
17+
18+
## Технологии
19+
20+
- Java 21
21+
- Gradle
22+
- Javalin (бэкенд)
23+
- JTE (шаблонизатор)
24+
- HikariCP (пул соединений)
25+
- H2 (dev) / PostgreSQL (production)
26+
- Jsoup, Unirest (парсинг HTML и HTTP-запросы)
27+
- Bootstrap 5
28+
- Render (PaaS-деплой)
29+
- JUnit, MockMvc (тесты)
30+
31+
## Запуск проекта локально
32+
33+
```sh
34+
git clone https://github.com/irinakomarchenko/java-project-72.git
35+
cd java-project-72/app
36+
./gradlew build
37+
./gradlew run
38+
```
39+
## Структура проекта
40+
```sh
41+
app/
42+
├── src/main/java/hexlet/code/
43+
│ ├── controller/
44+
│ ├── dto/
45+
│ ├── model/
46+
│ ├── repository/
47+
│ └── util/
48+
├── src/main/resources/
49+
│ ├── templates/
50+
│ └── schema.sql
51+
├── src/test/java/hexlet/code/
52+
```
53+
54+
655

756

857
## 🚀 Деплой на Render
958

1059
[🌐 Открыть деплой](https://java-project-72-55ck.onrender.com/)
1160

61+
## Пример работы
62+
![Video_1](readme-resources/Video_1)
63+

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ dependencies {
4444
testImplementation(platform("org.junit:junit-bom:5.12.2"))
4545
testImplementation("org.junit.jupiter:junit-jupiter")
4646
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
47-
testImplementation("com.squareup.okhttp3:mockwebserver:5.1.0")
47+
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
4848
}
4949

5050
tasks.named<Test>("test") {

app/readme-resources/Video_1.mp4

404 KB
Binary file not shown.

app/src/main/java/hexlet/code/App.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55
import gg.jte.ContentType;
66
import gg.jte.TemplateEngine;
77
import gg.jte.resolve.ResourceCodeResolver;
8+
import hexlet.code.controller.UrlChecksController;
9+
import hexlet.code.controller.UrlsController;
10+
import hexlet.code.repository.BaseRepository;
11+
import hexlet.code.util.NamedRoutes;
812
import io.javalin.Javalin;
913
import lombok.extern.slf4j.Slf4j;
1014
import io.javalin.rendering.template.JavalinJte;
15+
import org.postgresql.Driver;
1116

1217
import java.io.BufferedReader;
1318
import java.io.IOException;
@@ -52,7 +57,7 @@ public static Javalin getApp() throws IOException, SQLException {
5257
var hikariConfig = new HikariConfig();
5358
String databaseUrl = getDatabaseUrl();
5459
if (databaseUrl.contains("postgresql")) {
55-
hikariConfig.setDriverClassName(org.postgresql.Driver.class.getName());
60+
hikariConfig.setDriverClassName(Driver.class.getName());
5661
}
5762
hikariConfig.setJdbcUrl(databaseUrl);
5863

@@ -65,12 +70,20 @@ public static Javalin getApp() throws IOException, SQLException {
6570
statement.execute(sql);
6671
}
6772

73+
BaseRepository.dataSource = dataSource;
74+
6875
var app = Javalin.create(config -> {
6976
config.bundledPlugins.enableDevLogging();
7077
config.fileRenderer(new JavalinJte(createTemplateEngine()));
71-
7278
});
7379

80+
app.before(ctx -> ctx.contentType("text/html; charset=utf-8"));
81+
82+
app.get(NamedRoutes.rootPath(), UrlsController::build);
83+
app.post(NamedRoutes.urlsPath(), UrlsController::create);
84+
app.get(NamedRoutes.urlsPath(), UrlsController::index);
85+
app.get(NamedRoutes.urlPath("{id}"), UrlsController::show);
86+
app.post(NamedRoutes.urlCheckPath("{id}"), UrlChecksController::check);
7487

7588
return app;
7689
}

app/src/main/java/hexlet/code/controller/UrlChecksController.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,31 @@ public static void check(Context ctx) throws SQLException {
2424

2525
try {
2626
var response = Unirest.get(name).asString();
27-
Document responseBody = Jsoup.parse(response.getBody());
28-
2927
int statusCode = response.getStatus();
3028

31-
String h1 = responseBody.selectFirst("h1") != null
32-
? responseBody.selectFirst("h1").text() : "";
29+
if (statusCode == 200) {
30+
Document responseBody = Jsoup.parse(response.getBody());
3331

34-
String title = responseBody.title();
32+
String h1 = responseBody.selectFirst("h1") != null
33+
? responseBody.selectFirst("h1").text() : "";
3534

36-
String description = !responseBody.select("meta[name=description]").isEmpty()
37-
? responseBody.select("meta[name=description]").get(0).attr("content") : "";
35+
String title = responseBody.title();
3836

39-
var createdAt = new Timestamp(System.currentTimeMillis());
37+
String description = !responseBody.select("meta[name=description]").isEmpty()
38+
? responseBody.select("meta[name=description]").get(0).attr("content") : "";
4039

41-
var urlCheck = new UrlCheck(statusCode, h1, title, description, createdAt);
42-
urlCheck.setUrlId(urlId);
43-
UrlCheckRepository.save(urlCheck);
40+
var createdAt = new Timestamp(System.currentTimeMillis());
4441

42+
var urlCheck = new UrlCheck(statusCode, h1, title, description, createdAt);
43+
urlCheck.setUrlId(urlId);
44+
UrlCheckRepository.save(urlCheck);
45+
}
4546
ctx.redirect(NamedRoutes.urlPath(urlId));
46-
} catch (RuntimeException e) {
47-
ctx.sessionAttribute("message", "Проверка не прошла");
47+
} catch (Exception e) {
48+
ctx.sessionAttribute("message", "The test failed");
4849
ctx.redirect(NamedRoutes.urlPath(urlId));
4950
}
51+
5052
}
5153
}
5254

app/src/main/java/hexlet/code/controller/UrlsController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static void create(Context ctx) throws SQLException {
4444
}
4545
ctx.redirect(NamedRoutes.urlsPath());
4646
} catch (IllegalArgumentException | URISyntaxException | MalformedURLException e) {
47-
ctx.sessionAttribute("message", "Некорректный URL");
47+
ctx.sessionAttribute("message", "Incorrect URL");
4848
ctx.redirect(NamedRoutes.rootPath());
4949
}
5050
}

app/src/main/java/hexlet/code/repository/UrlRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
public class UrlRepository {
1616

1717
public static void save(Url url) throws SQLException {
18-
var sql = "INSERT INTO urls (name, created_at, updated_at) VALUES (? ,?)";
18+
var sql = "INSERT INTO urls (name, created_at) VALUES (? ,?)";
1919
try (var conn = dataSource.getConnection();
2020
var stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
2121

app/src/main/resources/templates/.jteroot

Whitespace-only changes.

0 commit comments

Comments
 (0)