Skip to content

Commit

Permalink
[Hexlet#276]. update js script, update tests, add override handleMeth…
Browse files Browse the repository at this point in the history
…odArgumentNotValid method
  • Loading branch information
kitdim committed Jun 23, 2024
1 parent 4c25a7c commit d813da8
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package io.hexlet.typoreporter.handler;

import io.hexlet.typoreporter.handler.domain.ApiError;
import io.hexlet.typoreporter.handler.exception.AccountAlreadyExistException;
import io.hexlet.typoreporter.handler.exception.AccountNotFoundException;
import io.hexlet.typoreporter.handler.exception.NewPasswordTheSameException;
import io.hexlet.typoreporter.handler.exception.OldPasswordWrongException;
import io.hexlet.typoreporter.handler.exception.WorkspaceAlreadyExistException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.security.auth.login.AccountExpiredException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@ControllerAdvice
Expand Down Expand Up @@ -52,4 +61,22 @@ public ResponseEntity<String> handleTypoNotFoundException(TypeNotPresentExceptio
public ResponseEntity<String> handleWorkSpaceAlreadyExistException(WorkspaceAlreadyExistException ex) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
}

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatusCode status,
WebRequest request) {

List<String> errors = new ArrayList<>();
for (FieldError error : ex.getBindingResult().getFieldErrors()) {
errors.add(error.getField() + ": " + error.getDefaultMessage());
}
for (ObjectError error : ex.getBindingResult().getGlobalErrors()) {
errors.add(error.getObjectName() + ": " + error.getDefaultMessage());
}

ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors);
return handleExceptionInternal(ex, apiError, headers, apiError.getStatus(), request);
}
}
29 changes: 29 additions & 0 deletions src/main/java/io/hexlet/typoreporter/handler/domain/ApiError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.hexlet.typoreporter.handler.domain;

import lombok.Getter;
import org.springframework.http.HttpStatus;

import java.util.Collections;
import java.util.List;

@Getter
public class ApiError {

private final HttpStatus status;
private final String message;
private final List<String> errors;

public ApiError(HttpStatus status, String message, List<String> errors) {
super();
this.status = status;
this.message = message;
this.errors = errors;
}

public ApiError(HttpStatus status, String message, String error) {
super();
this.status = status;
this.message = message;
errors = Collections.singletonList(error);
}
}
13 changes: 6 additions & 7 deletions src/test/java/io/hexlet/typoreporter/web/WorkspaceApiIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import static io.hexlet.typoreporter.test.factory.EntitiesFactory.WORKSPACE_101_TOKEN;
import static java.time.Instant.now;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.http.MediaType.APPLICATION_PROBLEM_JSON;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
Expand Down Expand Up @@ -114,8 +113,8 @@ void addTypoReportWithPageUrlBlank() throws Exception {
.header("Referer", ALLOWED_URL_101_URL)
.contentType(APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(content().contentType(APPLICATION_PROBLEM_JSON))
.andExpect(jsonPath("$.title").value("Bad Request"));
.andExpect(content().contentType(APPLICATION_JSON))
.andExpect(jsonPath("$.status").value("BAD_REQUEST"));
}

@Test
Expand All @@ -135,8 +134,8 @@ void addTypoReportWithPageUrlNull() throws Exception {
.header("Referer", ALLOWED_URL_101_URL)
.contentType(APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(content().contentType(APPLICATION_PROBLEM_JSON))
.andExpect(jsonPath("$.title").value("Bad Request"));
.andExpect(content().contentType(APPLICATION_JSON))
.andExpect(jsonPath("$.status").value("BAD_REQUEST"));
}

@Test
Expand All @@ -157,8 +156,8 @@ void addTypoReportWithPageUrlNotValid() throws Exception {
.header("Referer", ALLOWED_URL_101_URL)
.contentType(APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(content().contentType(APPLICATION_PROBLEM_JSON))
.andExpect(jsonPath("$.title").value("Bad Request"));
.andExpect(content().contentType(APPLICATION_JSON))
.andExpect(jsonPath("$.status").value("BAD_REQUEST"));
}

@ParameterizedTest
Expand Down
30 changes: 27 additions & 3 deletions src/widget/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,28 @@ const sendData = (elements, state) => async (event) => {
state.data.reporterName = value === '' ? 'Anonymous' : value;
state.data.reporterComment = elements.commentEl.value;
try {
await fetch(`${state.options.workSpaceUrl}/api/workspaces/${state.options.workSpaceId}/typos`, {
let response = await fetch(`${state.options.workSpaceUrl}/api/workspaces/${state.options.workSpaceId}/typos`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${state.options.authorizationToken}`,
},
body: JSON.stringify(state.data),
});
resetModalState(state);
let data = await response.json();
if (isSuccessPost(response)) {
resetModalState(state);
} else {
const errors = getErrors(data);
alert(errors);
}
} catch (error) {
throw new Error('Произошла ошибка:', error);
let errorText =
'Error in plugin integration.\n' +
'Check the settings (https://fixit.hexlet.io/workspace/{workspaceID}/integration).';
alert(errorText)
resetModalState(state);
throw new Error('Произошла ошибка:', error);
}
};

Expand Down Expand Up @@ -267,6 +278,19 @@ const isSelectionLeftToRight = (selection) => {
return range.collapsed;
}

const isSuccessPost = (response) => {
return response.status === 201;
}

const getErrors = (data) => {
let text = 'There are the following errors in the submission form:\n';
Object.keys(data.errors).forEach(key => {
let message = data.errors[key];
text += `${message} \n`;
});
return text;
}

const handleTypoReporter = (options) => {
if (!options || !options.authorizationToken && !options.workSpaceId) {
throw new Error('Для работы модуля требуется указать workSpaceId и authorizationToken');
Expand Down

0 comments on commit d813da8

Please sign in to comment.