Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @app.route('/todo/api/v1.0/tasks', methods=['POST'])
- @auth.login_required
- def create_task():
- ...
- 'id': len(tasks) + 1,
- ...
- /*
- у такой реализации - есть недостатки
- пример
- добавили 3 таски, удалили вторую
- добавляем новую
- результат - у двух тасок id = 3
- что не очень хорошо
- лучше проверь - если нет ни одной таски - пусть ид = 1
- иначе - как раньше было = tasks[-1]['id'] + 1
- так будет универсальнее
- https://lancelote.gitbooks.io/intermediate-python/content/book/ternary_operators.html
- https://lancelote.gitbooks.io/intermediate-python/content/book/comprehensions.html (dict абстракции)
- http://www.diveintopython.net/native_data_types/index.html#odbchelper.dict
- */
- ***********************************
- http://joxi.ru/Y2LXgYnfnyRoX2
- /*
- Имя пекеджа - поправь букву
- ресурс - это только TasksRest
- остальное - универсальные вещи - переноси в core - http://joxi.ru/E2pdR1lFB5Kx52
- */
- *******************************
- public class Configuration {
- public static String baseUrl = "http://localhost:5000/todo/api/v1.0/tasks";
- public static String credentials = "miguel:python";
- }
- /*
- а вот это - смесь)
- смесь универсального и уже контекста ресурса
- "miguel:python" - поскольку только такой способ аутентификации предполагается
- то можно зашивать внутри метода ресурса (переменной не нужно - т к это нам понадобится лишь единожды)
- если бы был вариант аутентификации - разными методами
- то "miguel:python" - это были бы уже тестовые даные
- и мы бы размещали их в ветке проекта src \ test
- baseUrl - лучше было бы baseUri - точнее
- и оставь значение = http://localhost:5000
- именно эта часть uri зависит от того - где наш рест сервер размещен
- а в классе - ресурсе - уже уточни
- public static String uri = Configuration.baseUri + "/todo/api/v1.0/tasks";
- и им уже оперируй
- в таком варианте - если меняется расположение сервера - мы меняем только Configuration.baseUri
- остальное - не трогаем
- */
- ************************
- public static Invocation.Builder authorized(Invocation.Builder requestBuilder) {
- /*
- лучше быть точнее
- и в универсальный метод - передавать с помощью параметров все для его работы
- именно из этих соображений мы не работаем в пейджах напрямую с тестовыми данными
- и тут логика похожая - в более универсальных методах мы не оперируем менене универсальными значениями напрямую
- а используем параметры - для передачи в метод таких вещей
- именно так мы и обеспечиваем универсальность)
- да и вызов - authorized("miguel:python", requestTo(uri));
- более понятный
- public static Invocation.Builder authorized(String credentials, Invocation.Builder requestBuilder) - будет грамотнее
- это для универсального RestHelpers
- а вот уже в TasksRest - реализуй уточненный
- public static Invocation.Builder authorizedRequest(String uri)
- в котором уточняйся до "miguel:python" и используй authorized из RestHelpers
- и его переиспользуй в других методах TasksRest
- */
- *********************
- public static final Task[] DEFAULT_TASKS(String description, boolean done, String title, int id) {
- Task[] DEFAULT_TASKS = new Task[2];
- DEFAULT_TASKS[0] = new Task("Milk, Cheese, Pizza, Fruit, Tylenol", false, "Buy groceries", 1);
- DEFAULT_TASKS[1] = new Task("Need to find a good Python tutorial on the web", false, "Learn Python", 2);
- return DEFAULT_TASKS;
- }
- public static final Task[] DEFAULT_TASKS = DEFAULT_TASKS(description, done, title, id);
- /*
- это - тестовые данные
- не нужно их зашивать в классе-ресурсе
- подобно тому - как мы не зашивали в пейджах тестовые данные
- если тебе эти данные понадобятся в нескольких тест-классах - то вынесешь это в отдельный класс
- (разместив в ветке src \ test)
- у нас такой проблемы нету
- размещай эти данные к тест-классе
- и можно это делать проще
- */
- public final Task[] DEFAULT_TASKS = {
- new Task(...),
- new Task(...)
- };
- *****************************************
- private static Response response;
- private static String description;
- private static String title;
- private static boolean done;
- private static int id;
- public static int getResponseStatus() {
- public static String getErrorAnswer() {
- public static Task getResponseTask() {
- /*
- вот эти переменные и методы - точно не нужны
- переменные description, title, done, id - тут не используются
- да и это свойства таски
- и класс-ресурс к этому не имеет отношения
- про response - писала в прошлый раз строки 112 - 170
- еще уточню
- туда же - и методы для работы с response
- */
- **************************************
- public static int getTasksSize() {
- return getTasks().size();
- }
- public static Task getTask(int id) {
- return getTasks().get(id);
- }
- /*
- для получения размера или таски - мы заново делаем запрос
- тоже - не наш метод)
- слишком неэффективно
- будем избавляться
- */
- **************************************************
- public static void getUnauthorizedAccess() {
- public static void getAuthorizedAccess() {
- /*
- метод getAuthorizedAccess() - можно назвать проще - get()
- да и сразу реализовать возвращающим List<Task>
- тогда и метод getTasks() - не будет нужен )
- TasksRest - это полноценный ресурс-модуль, который предоставляет CRUD
- я бы сэкономила на названиях методов)
- и вызывала методы ресурса - TasksRest.get()
- и точно, и понятно
- метод getUnauthorizedAccess() - не уверена - стоило ли реализовывать
- реально - это нужно лишь единожды
- когда нужно проверить собственно - UnauthorizedAccess )
- остальное - работает только при авторизации
- а раз нужно лишь единожды - так зачем тогда метод?
- если все же решишь оставить метод getUnauthorizedAccess() в ресурсе - то имя тоже подравняй
- unauthorizedGet - отвечает выше предложенной логике, но тоже ... мне не нравится
- вот сравни код
- Response response = TasksRest.unauthorizedGet();
- и
- Response response = requestTo(TasksRest.uri).get();
- Мы ж вообще ничего не выиграли
- ни в наглядности
- ни в DRY (нужно один раз)
- так что - очень рекомендую - удалить из ресурса метод getUnauthorizedAccess()
- */
- **************************************************
- public static void createTask(Task task) {
- response = authorized(requestTo(Configuration.baseUrl)).post(Entity.entity(task, MediaType.APPLICATION_JSON));
- }
- //сравни
- public static Task create(Task task) {
- Response response = authorizedRequest(uri).post(Entity.entity(task, MediaType.APPLICATION_JSON_TYPE));
- assertEquals(201, response.getStatus());
- return response.readEntity(TaskContainer.class).getTask();
- }
- /*
- вспомни - я выше в этом ревью писала - почему не нужна переменная response в классе-ресурсе
- при такой реализации - мы в методах класса-ресурса - проверяем статус ответа
- и уже возвращаем - данные из ответа
- пересмотри прошлое ревью про это
- если кажется это слишком "магическим" вариантом
- то возвращай из метода Response
- а проверку статуса ответа и получение данных - делай в тест-методе
- если выбирать "магию" - то лучше максимально полезную
- в том смысле - которая дает явные выигрыши какие-то
- в текущем твоем варианте - много всего в классе-ресурсе есть
- много сущностей, зависимых друг от друга
- и тут надо, как в оркестровом музыкальном произведении - правильно этим всем пользоваться
- вариант, что я предложила - значительно проще
- сделали запрос + сразу проверили статус ответа + вернули данные из запроса
- */
- *************************************************
- public static void createTask(Task task) {
- public static void updateTask(Task task) {
- public static void deleteTask(int id) {
- /*
- имена этих методов можно сделать полаконичнее
- create
- update
- delete
- Вызывая их как TasksRest.create(...) - получишь вполне наглядный код
- и каждый из этих методов подправь
- все методы реализуй по схеме
- сделали запрос + сразу проверили статус ответа + вернули данные из запроса(если есть что вернуть, конечно)
- */
- *************************************************
- public static void assertTasks(Task... tasks) {
- List<Task> expectedTasks = new ArrayList<Task>();
- for (Task task : tasks) {
- expectedTasks.add(task);
- }
- List<Task> actualTasks = getTasks();
- for (int i = 0; i < expectedTasks.size(); i++) {
- assertTasksAreEqual(expectedTasks.get(i), actualTasks.get(i));
- }
- }
- public static void assertTasksAreEqual(Task expectedTask, Task actualTask) {
- assertEquals(expectedTask.getDescription(), actualTask.getDescription());
- assertEquals(expectedTask.isDone(), actualTask.isDone());
- assertEquals(expectedTask.getTitle(), actualTask.getTitle());
- assertEquals(expectedTask.getUri(), actualTask.getUri());
- }
- /*
- преобразование Task... tasks к списку тасок - можно реализовать проще - Arrays.asList(tasks)
- задача сравнения объектов класса Task - должна решаться самим классом Task
- я не зря приводила линки
- http://www.java2s.com/Tutorial/Java/0140__Collections/CheckingforEquality.htm
- http://www.javapractices.com/topic/TopicAction.do?Id=17
- http://javadevnotes.com/java-array-to-list-examples
- в рамках класса Task - реализуй методы -
- public boolean equals(Object o)
- public int hashCode()
- вот на эту линку особое внимание обрати - http://www.javapractices.com/topic/TopicAction.do?Id=17
- IntelIJ Idea помогает в этом - используй контекстное меню в коде класса - generate...
- а чтобы сообщение об ошибке при сравнении было наглядным - реализуй в классе Task
- метод toString() - тоже можно использовать generate...
- */
- ************
- public Task(String description, boolean done, String title, int id)
- /*
- я бы на уровне конструктора класса - оперировала не параметром int id
- а уже uri
- цель - разделить логику
- пусть контейнеры ничего не знают о том, как мы работаем с uri
- */
Advertisement
Add Comment
Please, Sign In to add comment