diff --git a/README.md b/README.md
index 67d4ca0..74e0743 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,12 @@
-# OtusSpringHW
-Домашние задания по Spring для Otus.
+# OtusSpringHW
+
+Домашнее задание #2:
+- Добавить файл настроек в приложение и для тестирования.
+- Локализовать выводимые сообщения и вопросы теста.
+- Переписать конфигурацию в виде Java + Annotation-based конфигурации.
+
+### 19-03-22 Доработки:
+- Убраны лишние тесты.
+- Изменена работа с файлом.
+- Использование @Data вместо @Getter, @Setter.
+- Добавлены *.properties для тестов.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ae8c2f6
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,138 @@
+
+
+ 4.0.0
+
+ home-work-01
+
+ ru.otus.mkulikov
+ home-work
+ 1.0-SNAPSHOT
+
+
+ 11
+ ${java.version}
+ ${java.version}
+ UTF-8
+
+
+
+
+ org.springframework
+ spring-context
+ 5.0.9.RELEASE
+
+
+
+ org.springframework
+ spring-test
+ 5.0.9.RELEASE
+
+
+
+ net.sf.opencsv
+ opencsv
+ 2.3
+
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.4.0
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.4.0
+ test
+
+
+
+ org.assertj
+ assertj-core
+ 3.11.1
+ test
+
+
+
+ org.junit.platform
+ junit-platform-launcher
+ 1.4.1
+ test
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.4
+ provided
+
+
+
+
+ org.mockito
+ mockito-all
+ 1.10.19
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+ ${encoding}
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+
+ ${encoding}
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.0
+
+
+ false
+
+
+
+
+
+
+ src/main/resources
+
+ **/*.csv
+ **/*.properties
+
+ false
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java
new file mode 100644
index 0000000..3f6ee5d
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/Application.java
@@ -0,0 +1,33 @@
+package ru.otus.mkulikov;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import ru.otus.mkulikov.exceptions.QuestionsFileLoadingException;
+import ru.otus.mkulikov.services.processor.ProcessorService;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 15:27
+ */
+
+@Configuration
+@ComponentScan
+@PropertySource("classpath:application.properties")
+public class Application {
+
+ public static void main(String[] args) {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
+ try {
+ ProcessorService processor = context.getBean(ProcessorService.class);
+ processor.startTest();
+ } catch (QuestionsFileLoadingException e) {
+ e.printStackTrace();
+ } finally {
+ context.close();
+ }
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/exceptions/QuestionsFileLoadingException.java b/src/main/java/ru/otus/mkulikov/exceptions/QuestionsFileLoadingException.java
new file mode 100644
index 0000000..2105a5b
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/exceptions/QuestionsFileLoadingException.java
@@ -0,0 +1,19 @@
+package ru.otus.mkulikov.exceptions;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-17
+ * Time: 01:40
+ */
+
+public class QuestionsFileLoadingException extends RuntimeException {
+
+ public QuestionsFileLoadingException(String message) {
+ super(message);
+ }
+
+ public QuestionsFileLoadingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/models/Question.java b/src/main/java/ru/otus/mkulikov/models/Question.java
new file mode 100644
index 0000000..e148602
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/models/Question.java
@@ -0,0 +1,39 @@
+package ru.otus.mkulikov.models;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 15:54
+ */
+
+@Data
+public class Question implements Serializable {
+
+ private String id;
+ private String question;
+ private String answer1;
+ private String answer2;
+ private String answer3;
+ private String answer4;
+ private String trueAnswer;
+ private String userAnswer;
+
+ public Question(String id, String question, String answer1, String answer2, String answer3, String answer4, String trueAnswer, String userAnswer) {
+ this.id = id;
+ this.question = question;
+ this.answer1 = answer1;
+ this.answer2 = answer2;
+ this.answer3 = answer3;
+ this.answer4 = answer4;
+ this.trueAnswer = trueAnswer;
+ this.userAnswer = userAnswer;
+ }
+
+ public Question() {
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/models/User.java b/src/main/java/ru/otus/mkulikov/models/User.java
new file mode 100644
index 0000000..52a10f1
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/models/User.java
@@ -0,0 +1,22 @@
+package ru.otus.mkulikov.models;
+
+import lombok.Data;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 15:29
+ */
+
+@Data
+public class User {
+
+ private final String name;
+ private final String surname;
+
+ public User(String name, String surname) {
+ this.name = name;
+ this.surname = surname;
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/console/ConsoleIOServiceImpl.java b/src/main/java/ru/otus/mkulikov/services/console/ConsoleIOServiceImpl.java
new file mode 100644
index 0000000..115a0e1
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/console/ConsoleIOServiceImpl.java
@@ -0,0 +1,38 @@
+package ru.otus.mkulikov.services.console;
+
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PreDestroy;
+import java.util.Scanner;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 17.03.2019
+ * Time: 23:21
+ */
+
+@Service
+public class ConsoleIOServiceImpl implements IOService {
+
+ private final Scanner in;
+
+ public ConsoleIOServiceImpl() {
+ in = new Scanner(System.in);
+ }
+
+ @Override
+ public void write(String text) {
+ System.out.println(text);
+ }
+
+ @Override
+ public String read() {
+ return in.nextLine();
+ }
+
+ @PreDestroy
+ public void destroy() {
+ in.close();
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/console/IOService.java b/src/main/java/ru/otus/mkulikov/services/console/IOService.java
new file mode 100644
index 0000000..b6f92d3
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/console/IOService.java
@@ -0,0 +1,15 @@
+package ru.otus.mkulikov.services.console;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 17.03.2019
+ * Time: 23:21
+ */
+
+public interface IOService {
+
+ void write(String text);
+
+ String read();
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/localisation/LocalisationService.java b/src/main/java/ru/otus/mkulikov/services/localisation/LocalisationService.java
new file mode 100644
index 0000000..fa1f7fe
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/localisation/LocalisationService.java
@@ -0,0 +1,15 @@
+package ru.otus.mkulikov.services.localisation;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-21
+ * Time: 14:02
+ */
+
+public interface LocalisationService {
+
+ String getValue(String key);
+
+ String getValueWithParams(String key, String[] params);
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/localisation/LocalisationServiceImpl.java b/src/main/java/ru/otus/mkulikov/services/localisation/LocalisationServiceImpl.java
new file mode 100644
index 0000000..2af1b75
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/localisation/LocalisationServiceImpl.java
@@ -0,0 +1,43 @@
+package ru.otus.mkulikov.services.localisation;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.support.ReloadableResourceBundleMessageSource;
+import org.springframework.stereotype.Service;
+
+import java.util.Locale;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-21
+ * Time: 14:02
+ */
+
+@Service
+public class LocalisationServiceImpl extends ReloadableResourceBundleMessageSource implements LocalisationService {
+
+ private final Locale locale;
+ private final Locale russian = new Locale("ru");
+
+ public LocalisationServiceImpl(
+ @Value("${locale.basename}") String basename,
+ @Value("${locale.default.encoding}") String defaultEncoding,
+ @Value("${locale.default}") String localeDefault
+ ) {
+ super();
+ setBasename(basename);
+ setDefaultEncoding(defaultEncoding);
+
+ locale = (localeDefault != null)
+ ? new Locale(localeDefault)
+ : russian;
+ }
+
+ public String getValue(String key) {
+ return getMessage(key, null, locale);
+ }
+
+ public String getValueWithParams(String key, String[] params) {
+ return getMessage(key, params, locale);
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/processor/ProcessorService.java b/src/main/java/ru/otus/mkulikov/services/processor/ProcessorService.java
new file mode 100644
index 0000000..bfb3896
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/processor/ProcessorService.java
@@ -0,0 +1,13 @@
+package ru.otus.mkulikov.services.processor;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 15:54
+ */
+
+public interface ProcessorService {
+
+ void startTest();
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/processor/ProcessorServiceImpl.java b/src/main/java/ru/otus/mkulikov/services/processor/ProcessorServiceImpl.java
new file mode 100644
index 0000000..50a00aa
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/processor/ProcessorServiceImpl.java
@@ -0,0 +1,32 @@
+package ru.otus.mkulikov.services.processor;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import ru.otus.mkulikov.services.questions.QuestionsService;
+import ru.otus.mkulikov.services.registration.RegistrationService;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 15:54
+ */
+
+@Service
+public class ProcessorServiceImpl implements ProcessorService {
+
+ private final QuestionsService questionsService;
+ private final RegistrationService registration;
+
+ @Autowired
+ public ProcessorServiceImpl(QuestionsService questionsService, RegistrationService registration) {
+ this.questionsService = questionsService;
+ this.registration = registration;
+ }
+
+ @Override
+ public void startTest() {
+ registration.addNewUser();
+ questionsService.showQuestions();
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/questions/QuestionsService.java b/src/main/java/ru/otus/mkulikov/services/questions/QuestionsService.java
new file mode 100644
index 0000000..15fd4bb
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/questions/QuestionsService.java
@@ -0,0 +1,15 @@
+package ru.otus.mkulikov.services.questions;
+
+import ru.otus.mkulikov.exceptions.QuestionsFileLoadingException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 16:41
+ */
+
+public interface QuestionsService {
+
+ void showQuestions() throws QuestionsFileLoadingException;
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/questions/QuestionsServiceImpl.java b/src/main/java/ru/otus/mkulikov/services/questions/QuestionsServiceImpl.java
new file mode 100644
index 0000000..672ff7e
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/questions/QuestionsServiceImpl.java
@@ -0,0 +1,75 @@
+package ru.otus.mkulikov.services.questions;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import ru.otus.mkulikov.exceptions.QuestionsFileLoadingException;
+import ru.otus.mkulikov.models.Question;
+import ru.otus.mkulikov.services.console.IOService;
+import ru.otus.mkulikov.services.localisation.LocalisationService;
+import ru.otus.mkulikov.services.questions.dao.QuestionsDAO;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 16:41
+ */
+
+@Service
+public class QuestionsServiceImpl implements QuestionsService {
+
+ private final String c_delimeter = "---------------------------------------------------";
+ private final String c_answerNumbers = "1234";
+
+ private final QuestionsDAO questionsDAO;
+ private final IOService consoleService;
+ private final LocalisationService localisationService;
+
+ @Autowired
+ public QuestionsServiceImpl(QuestionsDAO questionsDAO, IOService consoleService, LocalisationService localisationService) {
+ this.questionsDAO = questionsDAO;
+ this.consoleService = consoleService;
+ this.localisationService = localisationService;
+ }
+
+ @Override
+ public void showQuestions() throws QuestionsFileLoadingException {
+ consoleService.write(c_delimeter);
+ List questions = questionsDAO.getQuestions();
+
+ for (Question question : questions) {
+ consoleService.write(question.getQuestion());
+ consoleService.write(question.getAnswer1());
+ consoleService.write(question.getAnswer2());
+ consoleService.write(question.getAnswer3());
+ consoleService.write(question.getAnswer4());
+
+ String answer = null;
+ boolean okAnswer = false;
+ int i = 0;
+ while (!okAnswer && i < 4) {
+ consoleService.write(localisationService.getValue("enter.answer"));
+ answer = consoleService.read();
+ okAnswer = c_answerNumbers.contains(answer) && !answer.isEmpty();
+ i++;
+ }
+
+ question.setUserAnswer((!okAnswer && i == 4) ? "0" : answer);
+ consoleService.write(c_delimeter);
+ }
+
+ long count = questions.stream()
+ .filter(obj -> obj.getTrueAnswer().equals(obj.getUserAnswer()))
+ .count();
+
+ consoleService.write(
+ localisationService.getValueWithParams(
+ "count.true.answers",
+ new String[] {String.valueOf(count), String.valueOf(questions.size())}
+ )
+ );
+ consoleService.write(c_delimeter);
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/questions/dao/QuestionsDAO.java b/src/main/java/ru/otus/mkulikov/services/questions/dao/QuestionsDAO.java
new file mode 100644
index 0000000..96beeeb
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/questions/dao/QuestionsDAO.java
@@ -0,0 +1,18 @@
+package ru.otus.mkulikov.services.questions.dao;
+
+import ru.otus.mkulikov.exceptions.QuestionsFileLoadingException;
+import ru.otus.mkulikov.models.Question;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 16:41
+ */
+
+public interface QuestionsDAO {
+
+ List getQuestions() throws QuestionsFileLoadingException;
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/questions/dao/QuestionsDAOImpl.java b/src/main/java/ru/otus/mkulikov/services/questions/dao/QuestionsDAOImpl.java
new file mode 100644
index 0000000..eb09c51
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/questions/dao/QuestionsDAOImpl.java
@@ -0,0 +1,67 @@
+package ru.otus.mkulikov.services.questions.dao;
+
+import au.com.bytecode.opencsv.CSVReader;
+import au.com.bytecode.opencsv.bean.ColumnPositionMappingStrategy;
+import au.com.bytecode.opencsv.bean.CsvToBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Repository;
+import ru.otus.mkulikov.exceptions.QuestionsFileLoadingException;
+import ru.otus.mkulikov.models.Question;
+import ru.otus.mkulikov.services.localisation.LocalisationService;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 16:42
+ */
+
+@Repository
+public class QuestionsDAOImpl implements QuestionsDAO {
+
+ private final LocalisationService localisationService;
+ private final String defaultFileDir;
+
+ public QuestionsDAOImpl(
+ LocalisationService localisationService,
+ @Value("${questions.default.dir}") String defaultFileDir
+ ) {
+ this.localisationService = localisationService;
+ this.defaultFileDir = defaultFileDir;
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ @Override
+ public List getQuestions() throws QuestionsFileLoadingException {
+ String csvFilename = defaultFileDir + "/" + localisationService.getValue("csv.file.name");
+ List questions;
+ try {
+ ClassPathResource resource = new ClassPathResource(csvFilename);
+ CSVReader csvReader = new CSVReader(new InputStreamReader(resource.getInputStream(), "UTF-8"));
+ questions = new CsvToBean().parse(setColumMapping(), csvReader);
+ } catch (FileNotFoundException e) {
+ throw new QuestionsFileLoadingException(localisationService.getValueWithParams("questions.find.error.filename", new String[] {csvFilename}), e);
+ } catch (UnsupportedEncodingException e) {
+ throw new QuestionsFileLoadingException(localisationService.getValue("questions.encoding.error"), e);
+ } catch (IOException e) {
+ throw new QuestionsFileLoadingException(localisationService.getValue("questions.io.error"), e);
+ }
+ return questions;
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ private ColumnPositionMappingStrategy setColumMapping() {
+ ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy();
+ strategy.setType(Question.class);
+ String[] columns = new String[]{"id", "question", "answer1", "answer2", "answer3", "answer4", "trueAnswer"};
+ strategy.setColumnMapping(columns);
+ return strategy;
+ }
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/registration/RegistrationService.java b/src/main/java/ru/otus/mkulikov/services/registration/RegistrationService.java
new file mode 100644
index 0000000..8e0d4e1
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/registration/RegistrationService.java
@@ -0,0 +1,13 @@
+package ru.otus.mkulikov.services.registration;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 16:34
+ */
+
+public interface RegistrationService {
+
+ void addNewUser();
+}
diff --git a/src/main/java/ru/otus/mkulikov/services/registration/RegistrationServiceImpl.java b/src/main/java/ru/otus/mkulikov/services/registration/RegistrationServiceImpl.java
new file mode 100644
index 0000000..08c64a0
--- /dev/null
+++ b/src/main/java/ru/otus/mkulikov/services/registration/RegistrationServiceImpl.java
@@ -0,0 +1,42 @@
+package ru.otus.mkulikov.services.registration;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import ru.otus.mkulikov.models.User;
+import ru.otus.mkulikov.services.console.IOService;
+import ru.otus.mkulikov.services.localisation.LocalisationService;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-14
+ * Time: 16:34
+ */
+
+@Service
+public class RegistrationServiceImpl implements RegistrationService {
+
+ private final IOService consoleService;
+ private final LocalisationService localisationService;
+
+ @Autowired
+ public RegistrationServiceImpl(IOService consoleService, LocalisationService localisationService) {
+ this.consoleService = consoleService;
+ this.localisationService = localisationService;
+ }
+
+ @Override
+ public void addNewUser() {
+ consoleService.write(localisationService.getValue("enter.your.data"));
+ consoleService.write(localisationService.getValue("enter.your.surname"));
+ String surname = consoleService.read();
+
+ consoleService.write(localisationService.getValue("enter.your.name"));
+ String name = consoleService.read();
+
+ User user = new User(name, surname);
+ consoleService.write(
+ localisationService.getValueWithParams("hello.user", new String[] {user.getName(), user.getSurname()})
+ );
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..c6450d1
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+locale.basename=/i18n/bundle
+locale.default.encoding=UTF-8
+locale.default=ru
+
+questions.default.dir=/questions
\ No newline at end of file
diff --git a/src/main/resources/i18n/bundle_en.properties b/src/main/resources/i18n/bundle_en.properties
new file mode 100644
index 0000000..9907680
--- /dev/null
+++ b/src/main/resources/i18n/bundle_en.properties
@@ -0,0 +1,11 @@
+count.true.answers=Number of correct answers: {0} of {1}
+enter.answer=Enter answer number:
+enter.your.data=Enter your data
+enter.your.name=Name:
+enter.your.surname=Surname:
+hello.user=Hello, {0} {1}!
+questions.encoding.error=File encoding error!
+questions.find.error.filename=File named {0} not found!
+questions.io.error=Error I/O when working with a file!
+
+csv.file.name=en.csv
diff --git a/src/main/resources/i18n/bundle_ru.properties b/src/main/resources/i18n/bundle_ru.properties
new file mode 100644
index 0000000..5ff9c0a
--- /dev/null
+++ b/src/main/resources/i18n/bundle_ru.properties
@@ -0,0 +1,11 @@
+count.true.answers=Количество правильных ответов: {0} из {1}
+enter.answer=Введите номер ответа:
+enter.your.data=Введите свои данные
+enter.your.name=Имя:
+enter.your.surname=Фамилия:
+hello.user=Здравствуйте, {0} {1}!
+questions.encoding.error=Ошибка кодировки файла!
+questions.find.error.filename=Файл с именем {0} не найден!
+questions.io.error=Ошибка ввода/вывода при работе с файлом!
+
+csv.file.name=ru.csv
diff --git a/src/main/resources/questions/en.csv b/src/main/resources/questions/en.csv
new file mode 100644
index 0000000..4d91327
--- /dev/null
+++ b/src/main/resources/questions/en.csv
@@ -0,0 +1,5 @@
+1,Which list is not a design pattern?,1. Facade,2. Object,3. Factory,4. Singleton,2
+2,Which type is not primitive?,1. String,2. int,3. char,4. boolean,1
+3,How many classes can be inherited in Java?,1. One,2. Two,3. Three,4. Four,1
+4,Which collection contains unique objects?,1. List,2. Map,3. Set,4. Queue,3
+5,What value cannot be put in the primitive type - int?,1. -1,2. 0,3. 10,4. null,4
\ No newline at end of file
diff --git a/src/main/resources/questions/ru.csv b/src/main/resources/questions/ru.csv
new file mode 100644
index 0000000..6114d64
--- /dev/null
+++ b/src/main/resources/questions/ru.csv
@@ -0,0 +1,5 @@
+1,Что из списка не является паттерном проектирования?,1. Фасад,2. Объект,3. Фабрика,4. Синглтон,2
+2,Какой тип не является примитивным?,1. String,2. int,3. char,4. boolean,1
+3,Сколько классов можно наследовать в Java?,1. Один,2. Два,3. Три,4. Четыре,1
+4,Какая коллекция содержит уникальне объекты?,1. List,2. Map,3. Set,4. Queue,3
+5,Какое значение нельзя положить в примитивный тип - int?,1. -1,2. 0,3. 10,4. null,4
\ No newline at end of file
diff --git a/src/test/java/ru/otus/mkulikov/questions/QuestionsDAOTest.java b/src/test/java/ru/otus/mkulikov/questions/QuestionsDAOTest.java
new file mode 100644
index 0000000..a9bb600
--- /dev/null
+++ b/src/test/java/ru/otus/mkulikov/questions/QuestionsDAOTest.java
@@ -0,0 +1,59 @@
+package ru.otus.mkulikov.questions;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import ru.otus.mkulikov.Application;
+import ru.otus.mkulikov.exceptions.QuestionsFileLoadingException;
+import ru.otus.mkulikov.models.Question;
+import ru.otus.mkulikov.services.localisation.LocalisationServiceImpl;
+import ru.otus.mkulikov.services.questions.dao.QuestionsDAO;
+import ru.otus.mkulikov.services.questions.dao.QuestionsDAOImpl;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@DisplayName("Класс QuestionsDAO")
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(classes = Application.class)
+@TestPropertySource("/test.properties")
+class QuestionsDAOTest {
+
+ @Value("${test.basename}")
+ private String folder;
+ @Value("${test.default.encoding}")
+ private String encoding;
+ @Value("${test.default.ru}")
+ private String ru;
+ @Value("${test.default.en}")
+ private String en;
+ @Value("${test.question.folder}")
+ private String questionFolder;
+
+ private final String c_test1 = "Тест1";
+ private final String c_test2 = "Тест2";
+ private final String c_test3 = "Тест3";
+
+ @Test
+ @DisplayName("Корректная загрузка вопросов")
+ public void loadQuestionsTest() throws QuestionsFileLoadingException {
+ LocalisationServiceImpl localisationService = new LocalisationServiceImpl(folder, encoding, ru);
+ QuestionsDAO questionsDAO = new QuestionsDAOImpl(localisationService, questionFolder);
+
+ List questions = questionsDAO.getQuestions();
+
+ assertAll("questions",
+ () -> assertNotNull(questions),
+ () -> assertEquals(3, questions.size()),
+ () -> assertEquals(c_test1, questions.get(0).getQuestion()),
+ () -> assertEquals(c_test2, questions.get(1).getQuestion()),
+ () -> assertEquals(c_test3, questions.get(2).getQuestion())
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/ru/otus/mkulikov/services/localisation/LocalisationServiceImplTest.java b/src/test/java/ru/otus/mkulikov/services/localisation/LocalisationServiceImplTest.java
new file mode 100644
index 0000000..2984838
--- /dev/null
+++ b/src/test/java/ru/otus/mkulikov/services/localisation/LocalisationServiceImplTest.java
@@ -0,0 +1,84 @@
+package ru.otus.mkulikov.services.localisation;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import ru.otus.mkulikov.Application;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Developer: Maksim Kulikov
+ * Date: 2019-03-22
+ * Time: 13:58
+ */
+
+@DisplayName("Класс LocalisationServiceImpl")
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(classes = Application.class)
+@TestPropertySource("/test.properties")
+class LocalisationServiceImplTest {
+
+ @Value("${test.basename}")
+ private String folder;
+ @Value("${test.default.encoding}")
+ private String encoding;
+ @Value("${test.default.ru}")
+ private String ru;
+ @Value("${test.default.en}")
+ private String en;
+
+ @Test
+ @DisplayName("Проверка получения значения ru локали")
+ void getValueRuTest() {
+ LocalisationService ruLocale = new LocalisationServiceImpl(folder, encoding, ru);
+ String value = ruLocale.getValue("test.key");
+
+ assertAll("value",
+ () -> assertNotNull(value),
+ () -> assertEquals("тест123", value)
+ );
+ }
+
+ @Test
+ @DisplayName("Проверка получения значения en локали")
+ void getValueEnTest() {
+ LocalisationService enLocale = new LocalisationServiceImpl(folder, encoding, en);
+ String value = enLocale.getValue("test.key");
+
+ assertAll("value",
+ () -> assertNotNull(value),
+ () -> assertEquals("test123", value)
+ );
+ }
+
+ @Test
+ @DisplayName("Проверка получения значения ru локали с параметром")
+ void getValueRuWithParamsTest() {
+ LocalisationService ruLocale = new LocalisationServiceImpl(folder, encoding, ru);
+ String value = ruLocale.getValueWithParams("test.key.params", new String[]{"При", "вет"});
+
+ assertAll("value",
+ () -> assertNotNull(value),
+ () -> assertEquals("При и вет - Привет", value)
+ );
+ }
+
+ @Test
+ @DisplayName("Проверка получения значения en локали с параметром")
+ void getValueEnWithParamsTest() {
+ LocalisationService enLocale = new LocalisationServiceImpl(folder, encoding, en);
+ String value = enLocale.getValueWithParams("test.key.params", new String[]{"Hel", "lo"});
+
+ assertAll("value",
+ () -> assertNotNull(value),
+ () -> assertEquals("Hel & lo - Hello", value)
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/locale/bundle_en.properties b/src/test/resources/locale/bundle_en.properties
new file mode 100644
index 0000000..4c04204
--- /dev/null
+++ b/src/test/resources/locale/bundle_en.properties
@@ -0,0 +1,14 @@
+count.true.answers=Number of correct answers: {0} of {1}
+enter.answer=Enter answer number:
+enter.your.data=Enter your data
+enter.your.name=Name:
+enter.your.surname=Surname:
+hello.user=Hello, {0} {1}!
+questions.encoding.error=File encoding error!
+questions.find.error.filename=File named {0} not found!
+questions.io.error=Error I/O when working with a file!
+
+csv.file.name=en.csv
+
+test.key=test123
+test.key.params={0} & {1} - Hello
\ No newline at end of file
diff --git a/src/test/resources/locale/bundle_ru.properties b/src/test/resources/locale/bundle_ru.properties
new file mode 100644
index 0000000..2fc5bc9
--- /dev/null
+++ b/src/test/resources/locale/bundle_ru.properties
@@ -0,0 +1,14 @@
+count.true.answers=Количество правильных ответов: {0} из {1}
+enter.answer=Введите номер ответа:
+enter.your.data=Введите свои данные
+enter.your.name=Имя:
+enter.your.surname=Фамилия:
+hello.user=Здравствуйте, {0} {1}!
+questions.encoding.error=Ошибка кодировки файла!
+questions.find.error.filename=Файл с именем {0} не найден!
+questions.io.error=Ошибка ввода/вывода при работе с файлом!
+
+csv.file.name=ru.csv
+
+test.key=тест123
+test.key.params={0} и {1} - Привет
\ No newline at end of file
diff --git a/src/test/resources/questions/ru.csv b/src/test/resources/questions/ru.csv
new file mode 100644
index 0000000..47cc49f
--- /dev/null
+++ b/src/test/resources/questions/ru.csv
@@ -0,0 +1,3 @@
+1,Тест1,Ответ1,Ответ2,Ответ3,Ответ4,Ответ1
+2,Тест2,Ответ1,Ответ2,Ответ3,Ответ4,Ответ1
+3,Тест3,Ответ1,Ответ2,Ответ3,Ответ4,Ответ1
diff --git a/src/test/resources/test.properties b/src/test/resources/test.properties
new file mode 100644
index 0000000..ea04e2e
--- /dev/null
+++ b/src/test/resources/test.properties
@@ -0,0 +1,6 @@
+test.basename=/locale/bundle
+test.default.encoding=UTF-8
+test.default.ru=ru
+test.default.en=en
+
+test.question.folder=/questions