FactoryService extends Service { @ApiOperation(value = "Get Factory information by its ID", notes = "Get JSON with Factory information. Factory ID is passed in a path parameter", response = Factory.class, position = 2) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 404, message = "Factory not found"), @ApiResponse(code = 409, message = "Failed to validate Factory URL"), @ApiResponse(code = 500, message = "Internal Server Error")}) @GET @Path("/{id}") @Produces({MediaType.APPLICATION_JSON}) public Factory getFactory(@ApiParam(value = "Factory ID", required = true) @PathParam("id") String id, @ApiParam(value = "Legacy. Whether or not to transform Factory into the most recent format", allowableValues = "true,false", defaultValue = "false") @DefaultValue("false") @QueryParam("legacy") Boolean legacy, @ApiParam(value = "Whether or not to validate values like it is done when accepting a Factory", allowableValues = "true,false", defaultValue = "false") @DefaultValue("false") @QueryParam("validate") Boolean validate, @Context UriInfo uriInfo) throws ApiException { Factory factoryUrl = factoryStore.getFactory(id); if (factoryUrl == null) { LOG.warn("Factory URL with id {} is not found.", id); throw new NotFoundException("Factory URL with id " + id + " is not found."); } if (legacy) { factoryUrl = factoryBuilder.convertToLatest(factoryUrl); } try { factoryUrl = factoryUrl.withLinks(linksHelper.createLinks(factoryUrl, factoryStore.getFactoryImages(id, null), uriInfo)); } catch (UnsupportedEncodingException e) { throw new ServerException(e.getLocalizedMessage()); } if (validate) { acceptValidator.validateOnAccept(factoryUrl, true); } return factoryUrl; } @Inject  FactoryService(@Named("api.endpoint") String baseApiUrl,
                          FactoryStore factoryStore,
                          AccountDao accountDao,
                          FactoryCreateValidator createValidator,
                          FactoryAcceptValidator acceptValidator,
                          FactoryEditValidator factoryEditValidator,
                          LinksHelper linksHelper,
                          FactoryBuilder factoryBuilder,
                          HttpJsonRequestFactory requestFactory,
                          ProjectManager projectManager,
                          DtoConverter dtoConverter); @ApiOperation(value = "Create a Factory and return data", notes = "Save factory to storage and return stored data. Field 'factoryUrl' should contains factory url information.", response = Factory.class, position = 1) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 409, message = "Conflict error. Some parameter is missing"), @ApiResponse(code = 500, message = "Unable to identify user from context")}) @RolesAllowed("user") @POST @Consumes({MediaType.MULTIPART_FORM_DATA}) @Produces({MediaType.APPLICATION_JSON}) Factory saveFactory(Iterator<FileItem> formData,
                               @Context UriInfo uriInfo); @ApiOperation(value = "Get Factory information by its ID", notes = "Get JSON with Factory information. Factory ID is passed in a path parameter", response = Factory.class, position = 2) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 404, message = "Factory not found"), @ApiResponse(code = 409, message = "Failed to validate Factory URL"), @ApiResponse(code = 500, message = "Internal Server Error")}) @GET @Path("/{id}") @Produces({MediaType.APPLICATION_JSON}) Factory getFactory(@ApiParam(value = "Factory ID", required = true)
                              @PathParam("id") String id,
                              @ApiParam(value = "Legacy. Whether or not to transform Factory into the most recent format",
                                        allowableValues = "true,false", defaultValue = "false")
                              @DefaultValue("false") @QueryParam("legacy") Boolean legacy,
                              @ApiParam(value = "Whether or not to validate values like it is done when accepting a Factory",
                                        allowableValues = "true,false", defaultValue = "false")
                              @DefaultValue("false") @QueryParam("validate") Boolean validate,
                              @Context UriInfo uriInfo); @ApiOperation(value = "Removes Factory by its ID", notes = "Removes factory based on the Factory ID which is passed in a path parameter") @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 403, message = "User not authorized to call this operation"), @ApiResponse(code = 404, message = "Factory not found"), @ApiResponse(code = 500, message = "Internal Server Error")}) @DELETE @Path("/{id}") @RolesAllowed("user") void removeFactory(@ApiParam(value = "Factory ID", required = true)
                              @PathParam("id") String id,
                              @Context UriInfo uriInfo); @ApiOperation(value = "Updates factory information by its ID", notes = "Updates factory based on the Factory ID which is passed in a path parameter") @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 403, message = "User not authorized to call this operation"), @ApiResponse(code = 404, message = "Factory not found"), @ApiResponse(code = 500, message = "Internal Server Error")}) @PUT @Path("/{id}") @RolesAllowed("user") @Consumes({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON}) Factory updateFactory(@ApiParam(value = "Factory ID", required = true)
                                 @PathParam("id") String id,
                                 Factory newFactory); @RolesAllowed({"user", "system/manager"}) @GET @Path("/find") @Produces({MediaType.APPLICATION_JSON}) @SuppressWarnings("unchecked") List<Link> getFactoryByAttribute(@Context UriInfo uriInfo); @ApiOperation(value = "Get Factory image information", notes = "Get Factory image information by Factory and image ID", position = 3) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 404, message = "Factory or Image ID Not Found"), @ApiResponse(code = 500, message = "Internal Server Error")}) @GET @Path("/{factoryId}/image") @Produces("image/*") Response getImage(@ApiParam(value = "Factory ID", required = true)
                             @PathParam("factoryId") String factoryId,
                             @ApiParam(value = "Image ID", required = true)
                             @DefaultValue("") @QueryParam("imgId") String imageId); @ApiOperation(value = "Get Factory snippet by ID", notes = "Get Factory snippet by ID", position = 4) @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 404, message = "Factory not Found"), @ApiResponse(code = 409, message = "Unknown snippet type"), @ApiResponse(code = 500, message = "Internal Server Error")}) @GET @Path("/{id}/snippet") @Produces({MediaType.TEXT_PLAIN}) String getFactorySnippet(@ApiParam(value = "Factory ID", required = true)
                                    @PathParam("id") String id,
                                    @ApiParam(value = "Snippet type", required = true, allowableValues = "url,html,iframe,markdown",
                                              defaultValue = "url")
                                    @DefaultValue("url") @QueryParam("type") String type,
                                    @Context UriInfo uriInfo); @ApiOperation(value = "Get project Factory parameters", notes = "This call returns a Factory.json that is used to create a Factory. " + "To be able to get project's configuration json file, it should be under Git") @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 404, message = "Workspace or project not found"), @ApiResponse(code = 500, message = "Internal Server Error")}) @GET @Path("/{ws-id}/{path:.*}") @Produces(MediaType.APPLICATION_JSON) Response getFactoryJson(@ApiParam(value = "Workspace ID", required = true)
                                   @PathParam("ws-id") String workspace,
                                   @ApiParam(value = "Project name", required = true)
                                   @PathParam("path") String path);  }
@Test public void shouldReturnSavedFactoryIfUserDidNotUseSpecialMethod() throws Exception { Factory factory = dto.createDto(Factory.class) .withV("2.0") .withSource(dto.createDto(Source.class) .withProject(dto.createDto(ImportSourceDescriptor.class) .withType("git") .withLocation( "http: .withParameters(ImmutableMap.of("keepVcs", "true")))) .withProject(dto.createDto(NewProject.class) .withType("ptype") .withName("pname")); factory.setId(CORRECT_FACTORY_ID); Factory expected = dto.clone(factory); when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(factory); when(factoryStore.getFactoryImages(CORRECT_FACTORY_ID, null)).thenReturn(Collections.<FactoryImage>emptySet()); Response response = given().when().get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID); assertEquals(response.getStatusCode(), 200); Factory responseFactoryUrl = dto.createDtoFromJson(response.getBody().asInputStream(), Factory.class); responseFactoryUrl.setLinks(Collections.<Link>emptyList()); assertEquals(responseFactoryUrl, expected); }
@Test public void shouldBeAbleToGetFactory(ITestContext context) throws Exception { Factory factoryUrl = dto.createDto(Factory.class); factoryUrl.setId(CORRECT_FACTORY_ID); Path path = Paths.get(Thread.currentThread().getContextClassLoader().getResource("100x100_image.jpeg").toURI()); byte[] data = Files.readAllBytes(path); FactoryImage image1 = new FactoryImage(data, "image/jpeg", "image123456789"); FactoryImage image2 = new FactoryImage(data, "image/png", "image987654321"); Set<FactoryImage> images = new HashSet<>(); images.add(image1); images.add(image2); Link expectedCreateProject = dto.createDto(Link.class); expectedCreateProject.setProduces("text/html"); expectedCreateProject.setHref(getServerUrl(context) + "/f?id=" + CORRECT_FACTORY_ID); expectedCreateProject.setRel("create-project"); when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(factoryUrl); when(factoryStore.getFactoryImages(CORRECT_FACTORY_ID, null)).thenReturn(images); Response response = given().when().get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID); assertEquals(response.getStatusCode(), 200); Factory responseFactoryUrl = JsonHelper.fromJson(response.getBody().asString(), Factory.class, null); List<Link> expectedLinks = new ArrayList<>(9); expectedLinks.add(expectedCreateProject); Link self = dto.createDto(Link.class); self.setProduces(MediaType.APPLICATION_JSON); self.setHref(getServerUrl(context) + "/rest/factory/" + CORRECT_FACTORY_ID); self.setRel("self"); expectedLinks.add(self); Link imageJpeg = dto.createDto(Link.class); imageJpeg.setProduces("image/jpeg"); imageJpeg.setHref(getServerUrl(context) + "/rest/factory/" + CORRECT_FACTORY_ID + "/image?imgId=image123456789"); imageJpeg.setRel("image"); expectedLinks.add(imageJpeg); Link imagePng = dto.createDto(Link.class); imagePng.setProduces("image/png"); imagePng.setHref(getServerUrl(context) + "/rest/factory/" + CORRECT_FACTORY_ID + "/image?imgId=image987654321"); imagePng.setRel("image"); expectedLinks.add(imagePng); Link accepted = dto.createDto(Link.class); accepted.setProduces(MediaType.TEXT_PLAIN); accepted.setHref(getServerUrl(context) + "/rest/analytics/public-metric/factory_used?factory=" + encode(expectedCreateProject.getHref(), "UTF-8")); accepted.setRel("accepted"); expectedLinks.add(accepted); Link snippetUrl = dto.createDto(Link.class); snippetUrl.setProduces(MediaType.TEXT_PLAIN); snippetUrl.setHref(getServerUrl(context) + "/rest/factory/" + CORRECT_FACTORY_ID + "/snippet?type=url"); snippetUrl.setRel("snippet/url"); expectedLinks.add(snippetUrl); Link snippetHtml = dto.createDto(Link.class); snippetHtml.setProduces(MediaType.TEXT_PLAIN); snippetHtml.setHref(getServerUrl(context) + "/rest/factory/" + CORRECT_FACTORY_ID + "/snippet?type=html"); snippetHtml.setRel("snippet/html"); expectedLinks.add(snippetHtml); Link snippetMarkdown = dto.createDto(Link.class); snippetMarkdown.setProduces(MediaType.TEXT_PLAIN); snippetMarkdown.setHref(getServerUrl(context) + "/rest/factory/" + CORRECT_FACTORY_ID + "/snippet?type=markdown"); snippetMarkdown.setRel("snippet/markdown"); expectedLinks.add(snippetMarkdown); Link snippetiFrame = dto.createDto(Link.class); snippetiFrame.setProduces(MediaType.TEXT_PLAIN); snippetiFrame.setHref(getServerUrl(context) + "/rest/factory/" + CORRECT_FACTORY_ID + "/snippet?type=iframe"); snippetiFrame.setRel("snippet/iframe"); expectedLinks.add(snippetiFrame); for (Link link : responseFactoryUrl.getLinks()) { Link testLink = dto.createDto(Link.class); testLink.setProduces(link.getProduces()); testLink.setHref(link.getHref()); testLink.setRel(link.getRel()); assertTrue(expectedLinks.contains(testLink)); } }
@Test public void shouldReturnStatus404OnGetFactoryWithIllegalId() throws Exception { when(factoryStore.getFactory(ILLEGAL_FACTORY_ID)).thenReturn(null); Response response = given(). expect(). statusCode(404). when(). get(SERVICE_PATH + "/" + ILLEGAL_FACTORY_ID); assertEquals(dto.createDtoFromJson(response.getBody().asString(), ServiceError.class).getMessage(), format("Factory URL with id %s is not found.", ILLEGAL_FACTORY_ID)); }
@Test public void shouldBeAbleToReturnUrlSnippet(ITestContext context) throws Exception { when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(dto.createDto (Factory.class)); given(). expect(). statusCode(200). contentType(MediaType.TEXT_PLAIN). body(equalTo(getServerUrl(context) + "/factory?id=" + CORRECT_FACTORY_ID)). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=url"); }
@Test public void shouldBeAbleToReturnUrlSnippetIfTypeIsNotSet(ITestContext context) throws Exception { when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(dto.createDto (Factory.class)); given(). expect(). statusCode(200). contentType(MediaType.TEXT_PLAIN). body(equalTo(getServerUrl(context) + "/factory?id=" + CORRECT_FACTORY_ID)). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet"); }
@Test public void shouldBeAbleToReturnHtmlSnippet(ITestContext context) throws Exception { when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(dto.createDto(Factory.class)); Response response = given(). expect(). statusCode(200). contentType(MediaType.TEXT_PLAIN). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=html"); assertEquals(response.body().asString(), "<script type=\"text/javascript\" src=\"" + getServerUrl(context) + "/factory/resources/factory.js?" + CORRECT_FACTORY_ID + "\"></script>"); }
@Test public void shouldBeAbleToReturnMarkdownSnippetForFactory1WithImage(ITestContext context) throws Exception { Factory factory = (Factory)dto.createDto(Factory.class) .withV("2.0") .withSource(dto.createDto(Source.class) .withProject(dto.createDto(ImportSourceDescriptor.class) .withType("git") .withLocation( "http: .withParameters(ImmutableMap.of("commitId", "12345679")))) .withId(CORRECT_FACTORY_ID) .withButton(dto.createDto(Button.class).withType(Button.ButtonType.logo)); String imageName = "1241234"; FactoryImage image = new FactoryImage(); image.setName(imageName); when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(factory); when(factoryStore.getFactoryImages(CORRECT_FACTORY_ID, null)).thenReturn(new HashSet<>(Arrays.asList(image))); given(). expect(). statusCode(200). contentType(MediaType.TEXT_PLAIN). body( equalTo("[![alt](" + getServerUrl(context) + "/api/factory/" + CORRECT_FACTORY_ID + "/image?imgId=" + imageName + ")](" + getServerUrl(context) + "/factory?id=" + CORRECT_FACTORY_ID + ")") ). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=markdown"); }
@Test public void shouldBeAbleToReturnMarkdownSnippetForFactory2WithImage(ITestContext context) throws Exception { String imageName = "1241234"; Factory furl = dto.createDto(Factory.class); furl.setId(CORRECT_FACTORY_ID); furl.setV("2.0"); furl.setButton(dto.createDto(Button.class).withType(Button.ButtonType.logo)); FactoryImage image = new FactoryImage(); image.setName(imageName); when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(furl); when(factoryStore.getFactoryImages(CORRECT_FACTORY_ID, null)).thenReturn(new HashSet<>(Arrays.asList(image))); given(). expect(). statusCode(200). contentType(MediaType.TEXT_PLAIN). body( equalTo("[![alt](" + getServerUrl(context) + "/api/factory/" + CORRECT_FACTORY_ID + "/image?imgId=" + imageName + ")](" + getServerUrl(context) + "/factory?id=" + CORRECT_FACTORY_ID + ")") ). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=markdown"); }
@Test public void shouldBeAbleToReturnMarkdownSnippetForFactory1WithoutImage(ITestContext context) throws Exception { Factory factory = (Factory)dto.createDto(Factory.class) .withV("2.0") .withSource(dto.createDto(Source.class) .withProject(dto.createDto(ImportSourceDescriptor.class) .withType("git") .withLocation( "http: .withParameters(ImmutableMap.of("commitId", "12345679")))) .withId(CORRECT_FACTORY_ID) .withButton(dto.createDto(Button.class).withType(Button.ButtonType.nologo) .withAttributes(dto.createDto(ButtonAttributes.class).withColor("white"))); when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(factory); given(). expect(). statusCode(200). contentType(MediaType.TEXT_PLAIN). body( equalTo("[![alt](" + getServerUrl(context) + "/factory/resources/factory-white.png)](" + getServerUrl (context) + "/factory?id=" + CORRECT_FACTORY_ID + ")") ). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=markdown"); }
@Test public void shouldNotBeAbleToGetMarkdownSnippetForFactory1WithoutStyle() throws Exception { Factory factory = (Factory)dto.createDto(Factory.class) .withV("2.0") .withSource(dto.createDto(Source.class) .withProject(dto.createDto(ImportSourceDescriptor.class) .withType("git") .withLocation( "http: .withParameters(ImmutableMap.of("commitId", "12345679")))) .withId(CORRECT_FACTORY_ID); when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(factory); Response response = given(). expect(). statusCode(409). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=markdown"); assertEquals(dto.createDtoFromJson(response.getBody().asInputStream(), ServiceError.class).getMessage(), "Unable to generate markdown snippet for factory without button"); }
@Test public void shouldNotBeAbleToGetMarkdownSnippetForFactory2WithoutColor() throws Exception { Factory factory = (Factory)dto.createDto(Factory.class) .withV("2.0") .withSource(dto.createDto(Source.class) .withProject(dto.createDto(ImportSourceDescriptor.class) .withType("git") .withLocation( "http: .withParameters(ImmutableMap.of("commitId", "12345679")))) .withId(CORRECT_FACTORY_ID) .withButton(dto.createDto(Button.class).withType(Button.ButtonType.nologo) .withAttributes(dto.createDto(ButtonAttributes.class).withColor(null))); when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(factory); Response response = given(). expect(). statusCode(409). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=markdown"); assertEquals(dto.createDtoFromJson(response.getBody().asInputStream(), ServiceError.class).getMessage(), "Unable to generate markdown snippet with nologo button and empty color"); }
@Test public void shouldResponse404OnGetSnippetIfFactoryDoesNotExist() throws Exception { when(factoryStore.getFactory(ILLEGAL_FACTORY_ID)).thenReturn(null); Response response = given(). expect(). statusCode(404). when(). get(SERVICE_PATH + "/" + ILLEGAL_FACTORY_ID + "/snippet?type=url"); assertEquals(dto.createDtoFromJson(response.getBody().asString(), ServiceError.class).getMessage(), "Factory URL with id " + ILLEGAL_FACTORY_ID + " is not found."); }
@Test(dataProvider = "badSnippetTypeProvider") public void shouldResponse409OnGetSnippetIfTypeIsIllegal(String type) throws Exception { when(factoryStore.getFactory(CORRECT_FACTORY_ID)).thenReturn(dto.createDto(Factory.class)); Response response = given(). expect(). statusCode(409). when(). get(SERVICE_PATH + "/" + CORRECT_FACTORY_ID + "/snippet?type=" + type); assertEquals(dto.createDtoFromJson(response.getBody().asString(), ServiceError.class).getMessage(), format("Snippet type \"%s\" is unsupported.", type)); }