Инженерный тур. 2 этап
Задачи второго этапа максимально приближены к реальным задачам разработки мобильных приложений, предоставляя участникам возможность испытать свои навыки в этой сфере.
Перед выполнением индивидуальных заданий участник должен выбрать роль задания, которую он будет выполнять. Возможные роли: Android-разработчик, UI/UX-дизайнер, backend-разработчик. Выбрать можно только одну из ролей. Для каждой роли будут даны три задачи легкого, среднего и высокого уровня сложности.
Каждое задание для ролей Android-разработчика и UI/UX-дизайнера представляют собой заготовку Android-приложения, которую нужно доработать в соответствие с техническим заданием. Заготовка приложения размещена в git-репозитории, а техническое задание содержится в read.me этого репозитория, поэтому текст задания в учебной системе содержит только ссылку на этот репозиторий.
В качестве решения участник сдает в учебную систему zip-архив со всеми файлами проекта.
Решение участника проверяется автоматически с помощью UI-тестов.
Файлы: https://git.sicampus.ru/Java/present.
В задании предлагается дописать существующий проект Android-приложения, а именно, дополнить разметку.
- В разметке приложения в любой ориентации должны присутствовать элементы, указанные в таблице 1.2. У кнопки устанавливается строковый ресурс из таблицы 1.2.
- В портретной ориентации: в ImageView должен быть установлен ресурс
@drawable/orange, кнопку следует расположить строго под картинкой. - В ландшафтной ориентации: вместо оранжевой коробочки в ImageView должна отображаться коробочка синего цвета
@drawable/blue, картинка — слева от кнопки.
| № | View type | id |
|---|---|---|
| 0 | Button | test_button |
| 1 | ImageView | box_image |
| № | Ресурс | Допустимое значение |
|---|---|---|
| 0 | @string/main_text_button |
Test Button |
Файлы: https://git.sicampus.ru/Java/rainbow.
Дополните разметку следующими элементами:
- Элемент
TextView(@id/main_text), который содержит в себе текст с поддержкой языка по умолчанию и английского. Значения приведены в таблице 1.4. Элемент должен быть расположен всегда сверху экрана. - Элемент-наследник от
ViewGroup(например,FrameLayout,LinearLayoutи т. п.) с идентификатором@id/outer_layout, включающим только элементыViewв виде полос (вертикальные для альбомной ориентации и горизонтальные для портретной ориентации). - Каждая полоса соответствует необходимому цвету радуги, разделенному между собой белым цветом (белый, красный, белый, оранжевый, белый, желтый, белый, зеленый, белый, голубой, белый, синий, белый, фиолетовый, белый).
У каждой полосы с цветом должен быть идентификатор. Набор идентификаторов для цветов следующий:
@id/red;@id/orange;@id/yellow;@id/green;@id/azure;@id/blue;@id/violet;@id/white.
| Ресурс | Значение |
|---|---|
@id/red |
#FF0000 |
@id/orange |
#F6A630 |
@id/yellow |
#FFEB3B |
@id/green |
#00FF00 |
@id/azure |
#2196F3 |
@id/blue |
#0000FF |
@id/violet |
#673AB7 |
@id/white |
#FFFFFF |
| Ресурс | Значение | Квалификатор |
|---|---|---|
@string/main_text |
каждый охотник желает знать где сидит фазан | |
@string/main_text |
Richard Of York Gave Battle In Vain | en |
| # | Тест | Балл | Проверка |
|---|---|---|---|
| 1 | interfaceTest |
1 | Accessibility Checks |
| 2 | languageTest |
1 | Строковые ресурсы на русском и английском языках |
| 3 | checkValues |
1 | Значения цветов |
| 4 | checkPortrait |
2 | Порядок следования цветов |
| 5 | checkLandscape |
3 | Порядок следования цветов |
Файлы: https://git.sicampus.ru/Java/diary.
В задании предлагается дописать существующий проект-заготовку Android-приложения, имитирующего ведение ежедневника.
Измените код существующих классов и интерфейсов, дополните разметку, ресурсы и манифест, чтобы приложение отвечало следующим требованиям:
- Интерфейс приложения должен содержать элементы, перечисленные в таблице 1.6.
- При запуске приложения все текстовые поля для ввода данных остаются пустыми, в них будет отображаться подсказка.
- По нажатии на кнопку Сохранить в случае отсутствия информации о названии события появляется Snackbar c текстом «Введите название события!» (без кавычек).
- По нажатии на кнопку Сохранить в случае указания названия события появляется диалоговое окно с кнопкой OK и текстом, представленным ниже.
Записано! Событие: title Дата: date Время: time Заметки: notes - Дата выводится в формате: дд.мм.гггг.
- После нажатия на кнопку Сохранить все текстовые поля очищаются.
| # | View type | id | hint | text |
|---|---|---|---|---|
| 0 | EditText |
event_title_user_input |
Название события | |
| 1 | EditText |
event_time_user_input |
Время события | |
| 2 | EditText |
event_notes_user_input |
Заметки к событию | |
| 3 | CalendarView |
произвольно | — | |
| 4 | Button |
произвольно | — | Сохранить |
| # | Тест | Балл | Проверка |
|---|---|---|---|
| 1 | mainTest |
1 | Показ AlertDialog |
| 2 | emptyTest |
1 | Очищение полей ввода |
| 3 | hasHint |
1 | Проверка наличия подсказок |
Файлы: https://git.sicampus.ru/Java/activity-lifecycle.
Необходимо дополнить данное приложение отслеживанием состояний активности.
Основные требования к приложению:
- Не изменяйте место и название файла
MainActivity(но редактирование содержимого (в том числе и уже имеющихся в файле методов) — можно и нужно). - Последовательность состояния жизненого цикла приложения должна выводиться в
TextView(@id/protocol). - Каждое состояние жизненного цикла выводится в отдельной строке.
- Значения текстовых подсказок должны быть определены в строковых ресурсах
string.xml. - Текстовые подсказки должны быть корректно выводится при смене конфигурации приложения (например, поворот экрана).
Название строковых ресурсов и их значения приведено в таблице 1.8.
| № | Отслеживаемый метод | Строковый ресурс | Значение ресурса |
|---|---|---|---|
| 1 | onCreate |
ncreate |
Activity CREATED |
| 2 | onStart |
nstart |
Activity STARTED |
| 3 | onResume |
nresume |
Activity RESUMED |
| 4 | onPause |
npause |
Activity PAUSED |
| 5 | onStop |
nstop |
Activity STOPPED |
| 6 | onRestart |
nrestart |
Activity RESTARTED |
| 7 | onDestroy |
ndestroy |
Activity DESTROYED |
Запуск приложения
Входные данные: первый запуск приложения (после установки)
Ожидаемый результат:
TextView (@id/protocol) содержит три строки:
Activity CREATED
Activity STARTED
Activity RESUMED

| № | Название теста | Баллы | Описание |
|---|---|---|---|
| 1 | checkPortait |
2 | Проверка последовательности Toast при запуске активности |
| 2 | checkLandscape |
4 | Проверка обработки поворотов экрана |
Решение: https://git.sicampus.ru/Java/activity-lifecycle-solve.
Файлы: https://git.sicampus.ru/Java/Broadcast-Receiver.
В данном практическом задании предлагается дополнить существующий проект-заготовку Android-приложения.
Советуем сначала склонировать шаблон проекта и открыть его в Android Studio, так как этот процесс может занимать продолжительное время.
Допишите код проекта, чтобы приложение отвечало следующим требованиям:
- Нестатический метод
makeBroadcastReceiver(), определенный в классеMainActivity, возвращает объектBroadcastReceiver. - Объект
BroadcastReceiver, возвращаемый методомmakeBroadcast Receiver(), способен обрабатывать широковещательные намеренияandroid.intent.action.*(полный список констант представлен ниже). - При запуске приложения в
TextViewсid/status_textможет быть установлен произвольный текст. При получении широковещательного сообщения вTextViewустанавливается текст, соответствующий типуaction(как в списке ниже). Например, при получении намеренияIntent.ACTION_ASSISTвTextViewдолжен быть установлен текстACTION_ASSIST.
| View type | id |
|---|---|
TextView |
status_text |
Константы Intent:
ACTION_AIRPLANE_MODE_CHANGED;ACTION_APPLICATION_RESTRICTIONS_CHANGED;ACTION_APPLICATION_LOCALE_CHANGED;ACTION_ASSIST;ACTION_BATTERY_CHANGED;ACTION_BATTERY_LOW;ACTION_BATTERY_OKAY;ACTION_CALL;ACTION_DATE_CHANGED;ACTION_DEFAULT;ACTION_HEADSET_PLUG;ACTION_LOCALE_CHANGED;ACTION_TIME_TICK.
Сдать в систему тестирования необходимо zip-архив, в корневом каталоге которого располагается дополненный проект Android Studio. После загрузки zip-архива приложение будет запущено в системе автоматического тестирования для проверки на соответствие техническому заданию.
При сборке проекта вcе изменения в файле build.gradle игнорируются — будут использованы зависимости только из шаблона-заготовки; не изменяйте пакет приложения.
| № | Тест | Балл | Проверка |
|---|---|---|---|
| 1–13 | Intent.ACTION_* |
13 | Обработка широковещательных намерений |
Решение: https://git.sicampus.ru/Java/Broadcast-Receiver-solve.
Файлы: https://git.sicampus.ru/Java/tricky-hexahedron.
В данном практическом задании предлагается дописать существующий проект-заготовку Android-приложения для вычисления суммы длин сторон, длины диагонали, площади полной поверхности и объема прямоугольного параллелепипеда.
Измените код существующих классов и интерфейсов, дополните разметку, ресурсы и манифест, чтобы приложение отвечало следующим требованиям:
- Интерфейс приложения должен содержать элементы, перечисленные в таблице 1.11, чтобы они были видны полностью даже при открытой виртуальной клавиатуре.
- Элементы
EditTextобязаны поддерживать ввод чисел с плавающей точкой. ЭлементEditTextс большим номером по порядку располагается нижеEditTextс меньшим номером. - Ограничения на вводимые значения указаны в таблице 1.11. Точность проверки: 1e-5.
- Элемент
@id/spinnerпозволяет выбрать одну из четырех опций для проведения расчетов в порядке, определенном в данном задании. - При нажатии на элемент
@id/calculateв текстовое поле@id/solutionустанавливается текст с результатом проведенных расчетов в соответствии с выбранной в@id/spinnerопцией. Гарантируется, что в момент нажатия все триEditTextимеют непустой текст. - При нажатии на
TextViewс@id/solutionтекущее значение копируется в буфер обмена.
| View type | id | Максимальное значение |
|---|---|---|
TextView |
side_a_label |
|
EditText |
side_a |
\(10^{12}\) |
TextView |
side_b_label |
|
EditText |
side_b |
\(10^{12}\) |
TextView |
side_c_label |
|
EditText |
side_c |
\(10^{12}\) |
Spinner |
spinner |
|
Button |
calculate |
|
TextView |
solution |
| Ресурс | Допустимое значение |
|---|---|
@string/side_a_text |
a |
@string/side_b_text |
b |
@string/side_c_text |
c |
Ниже представлен код одного из методов REST-контроллера фреймворка Spring Boot. Заполните пропуски в коде так, чтобы метод обрабатывал запрос соответствующий OpenAPI: https://innovationcampus.ru/store/swagger-ui.html.
Доступные для перемещения фрагменты: 200, 300, 404, 402, id, Get, Post, Add, Delete, User.
@Operation(summary = "Get user with id")
@ApiResponses(value = {
@ApiResponse(responseCode = " ",
description = "Get user with id",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = User.class)) }),
@ApiResponse(responseCode = " ",
description = "No user found",
content = @Content) })
@GetMapping("/user")
public Optional< > getUser(@RequestParam(value = " ", defaultValue = "1") Integer ) throws UserNotFound {
if (repo.existsById(id)) {
return repo.findById(id);
}
else {
User emptyUser = new User();
emptyUser.setId( );
throw new UserNotFound("User with id %s not found", emptyUser);
}
Реализуйте Entity-класс фреймворка Spring Boot соответствующий сущности user базы данных: https://drawsql.app/teams/myteam-1108/diagrams/e-store-database.
Ниже представлено решение на языке Java.
@Entity
@Table(name = "user", schema = "public")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usersIdSeq")
@SequenceGenerator(name = "usersIdSeq", sequenceName = "users_id_seq", allocationSize = 1)
@Column(name = "id")
private Integer id;
@Column(name = "username", length = 255)
private String userName;
@Column(name = "password", columnDefinition = "TEXT")
private String password;
@Column(name = "first_name", length = 255)
private String firstName;
@Column(name = "last_name", length = 255)
private String lastName;
@Column(name = "telephone")
private Integer telephone;
@Column(name = "created_at")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime createdAt;
@Column(name = "modified_at")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime modifiedAt;
@Column(name = "created_by")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Schema(description = "The field identifies the user who created the entity. As the value of this field, you must indicate your user id in innovationcampus.ru/lms")
private Integer createdBy;
// Constructors
public User() {
}
public User(String username, String password, String firstName, String lastName, Integer telephone, Integer createdBy, LocalDateTime createdAt, LocalDateTime modifiedAt) {
this.userName = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.telephone = telephone;
this.createdAt = createdAt;
this.modifiedAt = modifiedAt;
this.createdBy = createdBy;
}
public User(String username, String password, String firstName, String lastName, Integer telephone, Integer createdBy) {
new User(username, password, firstName, lastName, telephone, createdBy, LocalDateTime.now(), LocalDateTime.now());
}
// Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getTelephone() {
return telephone;
}
public void setTelephone(Integer telephone) {
this.telephone = telephone;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getModifiedAt() {
return modifiedAt;
}
public void setModifiedAt(LocalDateTime modifiedAt) {
this.modifiedAt = modifiedAt;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
}
Задача: разработать и развернуть серверное приложение, соответствующее следующему OpenAPI: https://innovationcampus.ru/store/swagger-ui.html.
Сервер должен быть доступен из сети интернет в момент проверки задания. Можно развернуть приложение на своем собственном сервере или в облачном сервисе, таком как VK Cloud или Yandex Cloud.
В качестве ответа предоставьте ссылку на развернутый сервер.
В качестве ответа участник должен предоставить ссылку на свое серверное приложение.
В компании S контроль доступа в офис осуществляется с помощью системы контроля управления доступом (СКУД). На данный момент у каждого сотрудника компании есть карта-пропуск с NFC-меткой, а у каждой входной двери есть считыватель с обеих сторон. При поднесении карты к считывателю дверь открывается, а информация о времени входа или выхода сотрудника фиксируется в базе данных.
Администрации компании S требуется мобильное приложение как для рядовых сотрудников, так и для администрации с возможностью просмотра посещений и работой электронного пропуска в качестве временной замены обычного (при помощи сканировании QR-кода, который находится на считывателе). Поскольку в приложении есть возможность использовать телефон как пропуск, то к данному приложению повышенные требования к безопасности всех данных, находящихся внутри него.
Важно: сервер и клиент разрабатываются на основе предоставленных заготовок проекта. Версии зависимостей и сами зависимости изменяться не должны.
- Минимальная версия ОС: Android 9.0 (API 28).
- Целевая версия ОС: Android 14 (API 34).
- Работоспособность приложения для платформ: mobile (смартфоны), tablet (планшеты).
- Поддерживаемая ориентация: портретная.
- Поддержка языков: русский, английский.
- Разрешения: доступ к интернету, камера (только при необходимости).
Требуется разработать нативное мобильное приложение, которое будет содержать:
- экран авторизации,
- главный экран,
- экран с результатом сканирования QR-кода.
Экран показывается при первом входе в приложение, а также в ситуациях, когда пользователь не зарегистрировался в приложении.
Элементы, которые должны присутствовать на экране:
- Поле ввода (
id/username), в котором пользователю необходимо ввести свой логин. - Кнопка входа (
id/login), после нажатия на которую пользователь авторизуется в системе. - По умолчанию скрытое текстовое поле с ошибкой (
id/error).
Требования к компонентам:
- В пустом поле ввода отображается подсказка, что именно требуется ввести пользователю.
Кнопка становится неактивной, если хотя бы одно из приведенных ниже условий соблюдено:
- поле ввода пустое;
- количество символов менее трех;
- логин начинается с цифры;
- логин содержит любой другой символ, кроме цифр и латинского алфавита.
- При раскрытии клавиатуры поле ввода и кнопку должно быть видно.
- При нажатии на кнопку входа необходимо проверить, что данный пользователь существует с помощью запроса
api/<LOGIN>/auth(подробное описание ниже). - В случае отсутствия логина или любой другой неполадки необходимо вывести ошибку, пока пользователь не изменит текстовое поле или повторно не нажмет на кнопку.
- После нажатия на кнопку логин сохраняется и при следующем открытии приложения экран авторизации не отображается.
- После нажатия на кнопку при нажатии стрелки назад экран авторизации не должен быть показан повторно.
- Экран авторизации показывается только в случае, если пользователь не авторизован.
Экран содержит общую информацию о пользователе:
- Ф. И. О.
- Фото.
- Должность.
- Время последнего входа.
Элементы, которые должны присутствовать на экране:
- Текстовое поле (
id/fullname), в котором написано имя пользователя. - Изображение (
id/photo), на котором отображено фото пользователя. - Текстовое поле (
id/position), в котором написана должность пользователя. - Текстовое поле (
id/lastEntry), в котором написана дата и время последнего входа пользователя. - Кнопка (
id/logout) для выхода пользователя из аккаунта. - Кнопка (
id/refresh) для обновления данных. - Кнопка (
id/scan) для сканирования QR-кода. - По умолчанию скрытое текстовое поле с ошибкой (
id/error).
Требования к компонентам:
- В случае любой ошибки необходимо скрыть все элементы, кроме текстового поля с ошибкой и кнопки обновления данных.
- Для получения данных необходимо использовать сетевой запрос
/api/<LOGIN>/info. - Формат даты и времени последнего входа пользователя: YYYY-MM-DDTHH:mm:ss (например: 2024-02-31T08:31). Время необходимо отображать с сервера, без поправок на часовой пояс или локальное смещение.
- При нажатии на кнопку выход все данные (если есть) пользователя должны быть очищены, а приложение должно открыть экран авторизации.
- При нажатии кнопки сканирования необходимо открыть экран сканирования QR-кода.
- При нажатии на кнопку обновления данных необходимо повторно вызывать сетевой запрос для получения актуальных данных.
Экран позволяет отсканировать код на турникете и войти с помощью смартфона. В данном случае данный экран будет уже написан и представлен в готовом виде в заготовке. Необходимо только подписаться на его результат с помощью Result API и обработать считанные данные из QR-кода.
Данный экран нельзя модифицировать. Он поставляется в исходном виде.
На экране необходимо вывести успешность или неуспешность входа с помощью метода QR-кода.
Элементы, которые должны присутствовать на экране:
- Текстовое поле (
id/result), где содержится текст об успешности или неуспешности входа. - Кнопка (
id/close) для закрытия данного экрана.
Требования к компонентам:
- Если результат пришел пустым или со статусом Отмена, необходимо вывести пользователю текст «Вход был отменен/Operation was cancelled».
- Если данные пришли, следует их отправить на сервер с запросе
api/<LOGIN>/open, добавив данные из результата и получить ответ. - Если сервер ответил успешно, то отображаем текст: «Успешно/Success».
- Если сервер ответил любой ошибкой, то отображаем текст: «Что-то пошло не так / Something wrong».
- Кнопка закрытия всегда открывает главный экран.
Работу необходимо осуществлять в представленных проектах-заготовках (шаблонах). Шаблон для клиентской части можно найти по ссылке: https://git.sicampus.ru/Olympic/NTO-2024-Client.
Оценивание происходит с помощью автоматической системы тестирования, которая в автоматическом режиме находит элементы и взаимодействует с ними (именно для этого у каждого элемента указан уникальный идентификатор, по которому будет производиться поиск). Каждый тест происходит с чистой установки приложения.
В случае тестирования сервера на него поочередно отправляются команды, описанные в API, и ожидаются определенные корректные ответы.
Сервер и приложение тестируются независимо.
Требуется разработать серверное приложение на Java (Java 11) с использованием Spring Boot, которое работает на основе протоколов TCP/IP и взаимодействует с клиентами благодаря RESTful API. Для хранения данных о сотрудниках и их посещениях будет использоваться реляционная база данных (H2). Сотрудникам не нужно регистрироваться, все данные в базе заполняются заранее. Картинки для аватаров пользователей не должны оставаться в БД, сохраняются лишь URL-адреса на ресурсы, откуда в последующем мобильное приложение загрузит соответствующий аватар.
В предоставленном проекте необходимо изучить, но никак не модифицировать, не перемещать и не удалять следующие файлы:
pom.xml;application.yml;data.sql.
Кроме описанных выше файлов, в проекте уже созданы основные классы-сущности и добавлены пустые классы всех слоев. В этих классах необходимо будет написать программный код и добавить аннотации для реализации описанного задания. Наименования классов и прочий код, уже написанный в представляемом проекте, изменять/удалять не нужно, необходимо их доработать. Добавлять свои дополнительные классы в проект можно.
Серверное приложение должно быть разработано и протестировано локально (не требуется размещать сервер удаленно и осуществлять его функционирование 24/7).
Для конфигурирования сервера (его хоста/IP адреса) используйте константы из файла Constants.kt.
| Тип запроса | Путь | Параметры/Тело | Ответы |
|---|---|---|---|
| GET | api/<LOGIN>/auth |
<LOGIN> — никнейм / имя пользователя |
— что-то пошло не так; 401 — логина не существует или неверный; 200 — данный логин существует — можно пользоваться приложением |
| GET | api/<LOGIN>/info |
<LOGIN> — никнейм / имя пользователя |
— что-то пошло не так; 401 — логина не существует или неверный; 200 — ОК |
| PATCH | api/<LOGIN>/open |
Тело: |
— что-то пошло не так; 401 — логина не существует или неверный; 200 — дверь открылась |
Данные, которыми необходимо наполнить базу данных:
| id | login | name | photo | position | lastVisit |
|---|---|---|---|---|---|
| 1 | pivanov | Иванов Петр Федорович | https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg | Разработчик | 2024-02-31T08:30 |
| 2 | ipetrov | Петров Иван Константинович | https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg | Аналитик | 2024-02-30T08:35 |
| 3 | asemenov | Семенов Анатолий Анатольевич | https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg | Разработчик | 2024-02-31T08:31 |
| 4 | afedorov | Федоров Александр Сергеевич | https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg | Тестировщик | 2024-02-30T08:36 |
| id | code |
|---|---|
| 1 | 1234567890123456789 |
| 2 | 9223372036854775807 |
| 3 | 1122334455667788990 |
| 4 | 998877665544332211 |
| 5 | 5566778899001122334 |
Работу необходимо осуществлять в представленных проектах-заготовках (шаблонах). Шаблон для серверной части можно найти по ссылке: https://git.sicampus.ru/Olympic/NTO-2024-Backend.
Проверка серверной части происходит при помощи интеграционных тестов. Участникам для выполнения задания первого этапа выдается заготовка для написания серверной части приложения. Они выполняют задание в рамках этой заготовки и присылают готовое решение.
В полученное решение добавляются интеграционные тесты и проверяется процент их успешного прохождения.
Список интеграционных тестов:
- Проверка подлинности для предзаполненных сотрудников.
Тест проверяет, что каждый предзаполненный сотрудник может успешно аутентифицироваться по логину. Для каждого сотрудника из предзаполненного списка выполняется GET-запрос на/api/{login}/auth. Если аутентификация прошла успешно, сервер возвращает статус200 OK. Тест также выводит результат запроса в консоль для наглядности. Это подтверждает, что все предустановленные данные сотрудников корректны и позволяют им входить в систему. - Проверка аутентификации с неверным логином.
Тест проверяет, что при попытке аутентификации с логином, которого нет в базе, сервер возвращает статус401 Unauthorized. Таким образом, тест защищает от несанкционированного доступа, убедившись, что только существующие пользователи могут войти в систему. - Проверка на работоспособность логининга не только с предзаполненными данными.
Тест проверяет, что новый сотрудник, добавленный в базу в процессе@BeforeEach-метода (testEmployee), может успешно аутентифицироваться по логину. GET-запрос на/api/{login}/authдолжен вернуть200 OK, что подтверждает возможность корректной работы приложения с динамически добавленными пользователями. - Проверка получения полной информации о всех предзаполненных сотрудниках.
Тест проверяет, что приложение правильно возвращает полную информацию о каждом предзаполненном сотруднике по его логину. Для каждого пользователя из предзаполненного списка выполняется GET-запрос на/api/{login}/infoи проверяется, что возвращенные данные соответствуют полям сотрудника: логин, имя, позиция, фото и дата последнего визита. Это гарантирует, что данные из базы данных корректно отдаются по запросу. - Проверка полной информации без учета поля даты.
Тест похож на тест 4, но исключает проверку даты последнего визита, чтобы удостовериться, что остальные поля (логин, имя, позиция и фото) остаются корректными. Полезен для случаев, когда изменение формата даты может повлиять на отображение, но остальные поля остаются актуальными. - Проверка на работоспособность получения полной информации не только о предзаполненных сотрудниках.
Тест проверяет, что новый сотрудник, добавленный в базу, отображается с полными данными. GET-запрос на/api/login/infoвозвращает статус200 OK, и тест проверяет все поля сотрудника (логин, имя, позиция, фото, дата последнего визита). Это подтверждает, что система обрабатывает новые записи корректно. - Проверка полной информации без учета поля даты для динамически добавленного сотрудника.
Тест аналогичен предыдущему, но проверяет только поля логина, имени, позиции и фото без учета даты последнего визита. Это полезно для проверки основной информации о новом сотруднике без учета динамических данных, таких как дата. - Проверка получения данных о несуществующем сотруднике.
Тест проверяет, что при запросе информации о несуществующем логине сервер возвращает статус401 Unauthorized. Это помогает удостовериться, что доступ к данным возможен только для существующих сотрудников, предотвращая получение информации по неверным или поддельным логинам. - Проверка возможности входа динамически добавленным сотрудником в случае предоставления корректного кода.
Проверяет, что новый сотрудник может успешно выполнить операцию «открыть дверь», если он передает один из верных кодов изexpectedCodeList. PATCH-запрос на/api/{login}/openдолжен возвращать200 OK. Это подтверждает, что сервис распознает предоставленный код как допустимый и разрешает доступ. - Проверка возможности входа всеми предзаполненными сотрудниками в случае предоставления корректного кода.
Тест проверяет, что каждый из предзаполненных сотрудников может успешно открыть дверь, предоставив любой из корректных кодов изexpectedCodeList. Тест проходит по всем сотрудникам и проверяет каждый код, убеждаясь, что статус ответа —200 OK. Это подтверждает, что система допускает предзаполненных сотрудников с действующими кодами. - Проверка обновления даты последнего визита для динамически добавленного сотрудника.
Тест проверяет, что при успешной операции «открытие двери» для нового сотрудника дата его последнего визита обновляется. Изначально тест сохраняет дату последнего визита сотрудника, затем выполняет PATCH-запрос с правильным кодом. После успешного запроса дата последнего визита в базе должна отличаться от предыдущей, что подтверждает корректное обновление данных после успешного «входа». - Проверка отсутствия возможности войти по неверному коду.
Тест проверяет, что при передаче неверного кода (например, \(-1\)) сервер возвращает400 Bad Request. Это предотвращает успешную операцию «открытия двери» при передаче недействительных кодов, подтверждая корректность обработки ошибочных данных. - Проверка корректности даты последнего визита.
Тест проверяет, что при использовании неправильного кода дата последнего визита сотрудника не обновляется в базе данных. Сначала он сохраняет данные сотрудника, затем выполняет PATCH-запрос с неверным кодом, и после выполнения проверяет, что данные о сотруднике остались прежними. Это гарантирует, что при неудачном запросе данные пользователя не будут изменены.
| № | Описание теста | Баллы |
|---|---|---|
| 1 | Проверка логининга для предзаполненных сотрудников | 3 |
| 2 | Проверка аутентификации с неверным логином | 2 |
| 3 | Проверка на работоспособность логининга не только с предзаполненными данными | 4 |
| 4 | Проверка получения полной информации о всех предзаполненных сотрудниках | 3 |
| 5 | Проверка полной информации без учета поля даты | 2 |
| 6 | Проверка на работоспособность получения полной информации не только о предзаполненных сотрудниках | 4 |
| 7 | Проверка полной информации без учета поля даты для динамически добавленного сотрудника | 2 |
| 8 | Проверка получения данных о несуществующем сотруднике | 2 |
| 9 | Проверка возможности входа динамически добавленным сотрудником при предоставлении корректного кода | 3 |
| 10 | Проверка возможности входа всеми предзаполненными сотрудниками при предоставлении корректного кода | 3 |
| 11 | Проверка обновления даты последнего визита для динамически добавленного сотрудника | 3 |
| 12 | Проверка отсутствия возможности войти по неверному коду | 2 |
| 13 | Проверка корректности даты последнего визита (обновление при правильном коде и отсутствие обновления при неправильном) | 2 |
Сумма за сервер — 35.
Проходной балл — 20 — прошли все тесты, для предзаполненных и хотя бы 1 для динамически добавленного.
Проверка клиентской части происходит при помощи UI-тестов. Для выполнения задания первого этапа участникам выдается заготовка для написания клиентской части приложения, с помощью которой они выполняют задание и присылают готовое решение.
В полученное решение добавляются UI-тесты и проверяется их успешное выполнение. Каждый тест имеет разный вес, который предоставлен участникам в открытом виде. Сумма баллов приводится к стобалльной системе.
Тесты, таблица 1.17.
| Название | Сценарий |
|---|---|
| Авторизация | Проверяем работу с неверным логином. Проверяем работу с верным логином и последующим открытием профиля. |
| Выход из профиля | На профиле нажимаем кнопку выхода и проверяем переход в логин. |
| Кнопка обновления | Нажимаем на профиле кнопку обновить и проверяем, что данные изменились. |
| Сканируем неверный код | Авторизуемся и переходим в профиль, после чего сканируем QR-код с некорректным кодом. Ожидаем увидеть экран с результатом сканирования. Изменяем локаль. Проверяем, что текст изменился |
| Сканируем верный код | Авторизуемся и переходим в профиль, после чего сканируем QR-код с корректным кодом. Ожидаем увидеть экран с результатом сканирования. Изменяем локаль. Проверяем, что текст изменился. |
| Отменяем сканирование QR-кода | Авторизуемся и переходим в профиль, после чего нажимаем кнопку сканирования и закрываем экран с камерой. Ожидаем увидеть экран с результатом сканирования. Изменяем локаль. Проверяем, что текст изменился. |
| Форматирование профиля | Переходим профиль и проверяем, обработку ошибок, а также формат вывода даты и текстовок в полях. |



