search icon search icon ВЕРСИЯ ДЛЯ СЛАБОВИДЯЩИХ

Инженерный тур. 2 этап

Задачи второго этапа максимально приближены к реальным задачам разработки мобильных приложений, предоставляя участникам возможность испытать свои навыки в этой сфере.

Индивидуальные задачи

Перед выполнением индивидуальных заданий участник должен выбрать роль задания, которую он будет выполнять. Возможные роли: Android-разработчик, UI/UX-дизайнер, backend-разработчик. Выбрать можно только одну из ролей. Для каждой роли будут даны три задачи легкого, среднего и высокого уровня сложности.

Каждое задание для ролей Android-разработчика и UI/UX-дизайнера представляют собой заготовку Android-приложения, которую нужно доработать в соответствие с техническим заданием. Заготовка приложения размещена в git-репозитории, а техническое задание содержится в read.me этого репозитория, поэтому текст задания в учебной системе содержит только ссылку на этот репозиторий.

В качестве решения участник сдает в учебную систему zip-архив со всеми файлами проекта.

Решение участника проверяется автоматически с помощью UI-тестов.

Задача 1.1.(2 балла)
Подарочек
Тема: 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
Таблица: strings.xml
Ресурс Допустимое значение
0 @string/main_text_button Test Button
Задача 1.2.(3 балла)
Радуга
Тема: UI мобильного приложения

Условие

Файлы: 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.
Таблица: colors.xml
Ресурс Значение
@id/red #FF0000
@id/orange #F6A630
@id/yellow #FFEB3B
@id/green #00FF00
@id/azure #2196F3
@id/blue #0000FF
@id/violet #673AB7
@id/white #FFFFFF
Таблица: strings.xml
Ресурс Значение Квалификатор
@string/main_text каждый охотник желает знать где сидит фазан
@string/main_text Richard Of York Gave Battle In Vain en

Рис. 1.1. Портретная ориентация

Рис. 1.2. Альбомная ориентация

Критерии оценивания

Таблица: Критерии оценивания и тесты
# Тест Балл Проверка
1 interfaceTest 1 Accessibility Checks
2 languageTest 1 Строковые ресурсы на русском и английском языках
3 checkValues 1 Значения цветов
4 checkPortrait 2 Порядок следования цветов
5 checkLandscape 3 Порядок следования цветов
Задача 1.3.(5 баллов)
Ежедневник
Тема: UI мобильного приложения

Условие

Файлы: 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 Проверка наличия подсказок
Задача 1.4.(2 балла)
Жизненный цикл Activity
Тема: Android-разработка

Условие

Файлы: 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.3.

Критерии оценивания

Таблица: Критерии оценивания и тесты
Название теста Баллы Описание
1 checkPortait 2 Проверка последовательности Toast при запуске активности
2 checkLandscape 4 Проверка обработки поворотов экрана
Задача 1.5.(3 балла)
BroadcastReceiver
Тема: Android-разработка

Условие

Файлы: 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:

  1. ACTION_AIRPLANE_MODE_CHANGED;
  2. ACTION_APPLICATION_RESTRICTIONS_CHANGED;
  3. ACTION_APPLICATION_LOCALE_CHANGED;
  4. ACTION_ASSIST;
  5. ACTION_BATTERY_CHANGED;
  6. ACTION_BATTERY_LOW;
  7. ACTION_BATTERY_OKAY;
  8. ACTION_CALL;
  9. ACTION_DATE_CHANGED;
  10. ACTION_DEFAULT;
  11. ACTION_HEADSET_PLUG;
  12. ACTION_LOCALE_CHANGED;
  13. ACTION_TIME_TICK.

Сдать в систему тестирования необходимо zip-архив, в корневом каталоге которого располагается дополненный проект Android Studio. После загрузки zip-архива приложение будет запущено в системе автоматического тестирования для проверки на соответствие техническому заданию.

При сборке проекта вcе изменения в файле build.gradle игнорируются — будут использованы зависимости только из шаблона-заготовки; не изменяйте пакет приложения.

Критерии оценивания

Таблица: Критерии оценивания и тесты
Тест Балл Проверка
1–13 Intent.ACTION_* 13 Обработка широковещательных намерений
Задача 1.6.(5 баллов)
Tricky Hexahedron
Тема: Android-разработка

Условие

Файлы: 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
Таблица: strings.xml
Ресурс Допустимое значение
@string/side_a_text a
@string/side_b_text b
@string/side_c_text c
Задача 1.7.(2 балла)
Endpoint
Тема: backend-разработка

Условие

Ниже представлен код одного из методов REST-контроллера фреймворка Spring Boot. Заполните пропуски в коде так, чтобы метод обрабатывал запрос соответствующий OpenAPI: https://innovationcampus.ru/store/swagger-ui.html.

Доступные для перемещения фрагменты: 200, 300, 404, 402, id, Get, Post, Add, Delete, User.

Java
@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);
   }
Задача 1.8.(3 балла)
Entity класс
Тема: backend-разработка

Условие

Реализуйте Entity-класс фреймворка Spring Boot соответствующий сущности user базы данных: https://drawsql.app/teams/myteam-1108/diagrams/e-store-database.

Рис. 1.4. ER-диаграмма базы данных

Решение

Ниже представлено решение на языке Java.

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;
   }
}
Задача 1.9.(5 баллов)
Server
Тема: backend-разработка

Условие

Задача: разработать и развернуть серверное приложение, соответствующее следующему OpenAPI: https://innovationcampus.ru/store/swagger-ui.html.

Сервер должен быть доступен из сети интернет в момент проверки задания. Можно развернуть приложение на своем собственном сервере или в облачном сервисе, таком как VK Cloud или Yandex Cloud.

В качестве ответа предоставьте ссылку на развернутый сервер.

Решение

В качестве ответа участник должен предоставить ссылку на свое серверное приложение.

Командные задачи

В компании S контроль доступа в офис осуществляется с помощью системы контроля управления доступом (СКУД). На данный момент у каждого сотрудника компании есть карта-пропуск с NFC-меткой, а у каждой входной двери есть считыватель с обеих сторон. При поднесении карты к считывателю дверь открывается, а информация о времени входа или выхода сотрудника фиксируется в базе данных.

Администрации компании S требуется мобильное приложение как для рядовых сотрудников, так и для администрации с возможностью просмотра посещений и работой электронного пропуска в качестве временной замены обычного (при помощи сканировании QR-кода, который находится на считывателе). Поскольку в приложении есть возможность использовать телефон как пропуск, то к данному приложению повышенные требования к безопасности всех данных, находящихся внутри него.

Важно: сервер и клиент разрабатываются на основе предоставленных заготовок проекта. Версии зависимостей и сами зависимости изменяться не должны.

Задача 2.1.(35 баллов)
Создание мобильного приложения. Клиентская часть
Тема: Android-разработка

Системные требования к приложению

  • Минимальная версия ОС: 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-кода.
  • При нажатии на кнопку обновления данных необходимо повторно вызывать сетевой запрос для получения актуальных данных.

Экран сканирования QR-кода

Экран позволяет отсканировать код на турникете и войти с помощью смартфона. В данном случае данный экран будет уже написан и представлен в готовом виде в заготовке. Необходимо только подписаться на его результат с помощью Result API и обработать считанные данные из QR-кода.

Данный экран нельзя модифицировать. Он поставляется в исходном виде.

Экран с результатом сканирования QR-кода

На экране необходимо вывести успешность или неуспешность входа с помощью метода QR-кода.

Элементы, которые должны присутствовать на экране:

  • Текстовое поле (id/result), где содержится текст об успешности или неуспешности входа.
  • Кнопка (id/close) для закрытия данного экрана.

Требования к компонентам:

  • Если результат пришел пустым или со статусом Отмена, необходимо вывести пользователю текст «Вход был отменен/Operation was cancelled».
  • Если данные пришли, следует их отправить на сервер с запросе api/<LOGIN>/open, добавив данные из результата и получить ответ.
  • Если сервер ответил успешно, то отображаем текст: «Успешно/Success».
  • Если сервер ответил любой ошибкой, то отображаем текст: «Что-то пошло не так / Something wrong».
  • Кнопка закрытия всегда открывает главный экран.

Работу необходимо осуществлять в представленных проектах-заготовках (шаблонах). Шаблон для клиентской части можно найти по ссылке: https://git.sicampus.ru/Olympic/NTO-2024-Client.

Особенности оценивания

Оценивание происходит с помощью автоматической системы тестирования, которая в автоматическом режиме находит элементы и взаимодействует с ними (именно для этого у каждого элемента указан уникальный идентификатор, по которому будет производиться поиск). Каждый тест происходит с чистой установки приложения.

В случае тестирования сервера на него поочередно отправляются команды, описанные в API, и ожидаются определенные корректные ответы.

Сервер и приложение тестируются независимо.

Задача 2.2.(35 баллов)
Создание мобильного приложения. Серверная часть
Темы: RESTful API, Spring Boot

Техническое задание

Требуется разработать серверное приложение на 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 — ОК

{
 "id": 1,
 "login": "pivanov",
 "name": "Иванов Петр Федорович",
 "photo": "https://funnyducks.ru/ upload/iblock/0cd/ 0cdeb7ec3ed6fddda0f90 fccee05557d.jpg",
 "position": "Разработчик",
 "lastVisit": "2024-02-12T08:30:00"
}
PATCH api/<LOGIN>/open

<LOGIN> — никнейм/имя пользователя

Тело:{“value”: <CODE>}, где: <CODE> — это код, полученный из экрана сканирования QR кода.

 — что-то пошло не так;

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.

Критерии оценивания

Сервер

Проверка серверной части происходит при помощи интеграционных тестов. Участникам для выполнения задания первого этапа выдается заготовка для написания серверной части приложения. Они выполняют задание в рамках этой заготовки и присылают готовое решение.

В полученное решение добавляются интеграционные тесты и проверяется процент их успешного прохождения.

Список интеграционных тестов:

  1. Проверка подлинности для предзаполненных сотрудников.
    Тест проверяет, что каждый предзаполненный сотрудник может успешно аутентифицироваться по логину. Для каждого сотрудника из предзаполненного списка выполняется GET-запрос на /api/{login}/auth. Если аутентификация прошла успешно, сервер возвращает статус 200 OK. Тест также выводит результат запроса в консоль для наглядности. Это подтверждает, что все предустановленные данные сотрудников корректны и позволяют им входить в систему.
  2. Проверка аутентификации с неверным логином.
    Тест проверяет, что при попытке аутентификации с логином, которого нет в базе, сервер возвращает статус 401 Unauthorized. Таким образом, тест защищает от несанкционированного доступа, убедившись, что только существующие пользователи могут войти в систему.
  3. Проверка на работоспособность логининга не только с предзаполненными данными.
    Тест проверяет, что новый сотрудник, добавленный в базу в процессе @BeforeEach-метода (testEmployee), может успешно аутентифицироваться по логину. GET-запрос на /api/{login}/auth должен вернуть 200 OK, что подтверждает возможность корректной работы приложения с динамически добавленными пользователями.
  4. Проверка получения полной информации о всех предзаполненных сотрудниках.
    Тест проверяет, что приложение правильно возвращает полную информацию о каждом предзаполненном сотруднике по его логину. Для каждого пользователя из предзаполненного списка выполняется GET-запрос на /api/{login}/info и проверяется, что возвращенные данные соответствуют полям сотрудника: логин, имя, позиция, фото и дата последнего визита. Это гарантирует, что данные из базы данных корректно отдаются по запросу.
  5. Проверка полной информации без учета поля даты.
    Тест похож на тест 4, но исключает проверку даты последнего визита, чтобы удостовериться, что остальные поля (логин, имя, позиция и фото) остаются корректными. Полезен для случаев, когда изменение формата даты может повлиять на отображение, но остальные поля остаются актуальными.
  6. Проверка на работоспособность получения полной информации не только о предзаполненных сотрудниках.
    Тест проверяет, что новый сотрудник, добавленный в базу, отображается с полными данными. GET-запрос на /api/login/info возвращает статус 200 OK, и тест проверяет все поля сотрудника (логин, имя, позиция, фото, дата последнего визита). Это подтверждает, что система обрабатывает новые записи корректно.
  7. Проверка полной информации без учета поля даты для динамически добавленного сотрудника.
    Тест аналогичен предыдущему, но проверяет только поля логина, имени, позиции и фото без учета даты последнего визита. Это полезно для проверки основной информации о новом сотруднике без учета динамических данных, таких как дата.
  8. Проверка получения данных о несуществующем сотруднике.
    Тест проверяет, что при запросе информации о несуществующем логине сервер возвращает статус 401 Unauthorized. Это помогает удостовериться, что доступ к данным возможен только для существующих сотрудников, предотвращая получение информации по неверным или поддельным логинам.
  9. Проверка возможности входа динамически добавленным сотрудником в случае предоставления корректного кода.
    Проверяет, что новый сотрудник может успешно выполнить операцию «открыть дверь», если он передает один из верных кодов из expectedCodeList. PATCH-запрос на /api/{login}/open должен возвращать 200 OK. Это подтверждает, что сервис распознает предоставленный код как допустимый и разрешает доступ.
  10. Проверка возможности входа всеми предзаполненными сотрудниками в случае предоставления корректного кода.
    Тест проверяет, что каждый из предзаполненных сотрудников может успешно открыть дверь, предоставив любой из корректных кодов из expectedCodeList. Тест проходит по всем сотрудникам и проверяет каждый код, убеждаясь, что статус ответа — 200 OK. Это подтверждает, что система допускает предзаполненных сотрудников с действующими кодами.
  11. Проверка обновления даты последнего визита для динамически добавленного сотрудника.
    Тест проверяет, что при успешной операции «открытие двери» для нового сотрудника дата его последнего визита обновляется. Изначально тест сохраняет дату последнего визита сотрудника, затем выполняет PATCH-запрос с правильным кодом. После успешного запроса дата последнего визита в базе должна отличаться от предыдущей, что подтверждает корректное обновление данных после успешного «входа».
  12. Проверка отсутствия возможности войти по неверному коду.
    Тест проверяет, что при передаче неверного кода (например, \(-1\)) сервер возвращает 400 Bad Request. Это предотвращает успешную операцию «открытия двери» при передаче недействительных кодов, подтверждая корректность обработки ошибочных данных.
  13. Проверка корректности даты последнего визита.
    Тест проверяет, что при использовании неправильного кода дата последнего визита сотрудника не обновляется в базе данных. Сначала он сохраняет данные сотрудника, затем выполняет 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-кода

Авторизуемся и переходим в профиль, после чего нажимаем кнопку сканирования и закрываем экран с камерой. Ожидаем увидеть экран с результатом сканирования.

Изменяем локаль. Проверяем, что текст изменился.

Форматирование профиля Переходим профиль и проверяем, обработку ошибок, а также формат вывода даты и текстовок в полях.
text slider background image text slider background image
text slider background image text slider background image text slider background image text slider background image