mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-08 14:35:45 +01:00
Deliver HgConfigPackages no longer as embedded.
They don't have an own identity in terms of REST and its much simpler to return a simple list instead of an _embedded list. Also gets rid of one HgConfigPackageToDtoMapper.
This commit is contained in:
@@ -3,20 +3,19 @@ package sonia.scm.api.v2.resources;
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import de.otto.edison.hal.Links;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class HgConfigInstallationsDto extends HalRepresentation {
|
||||
|
||||
private List<String> paths;
|
||||
|
||||
public HgConfigInstallationsDto(Links links, List<String> paths) {
|
||||
super(links);
|
||||
this.paths = paths;
|
||||
}
|
||||
|
||||
private List<String> paths;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
@@ -11,7 +11,7 @@ public class HgConfigInstallationsToDtoMapper {
|
||||
private UriInfoStore uriInfoStore;
|
||||
|
||||
@Inject
|
||||
public HgConfigInstallationsToDtoMapper(UriInfoStore uriInfoStore, String path) {
|
||||
public HgConfigInstallationsToDtoMapper(UriInfoStore uriInfoStore) {
|
||||
this.uriInfoStore = uriInfoStore;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.installer.HgPackage;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
// TODO could this be simplified similar to HgConfigInstallationsToDtoMapper?
|
||||
// That is, do we really need the packages as _embedded list?
|
||||
public class HgConfigPackageCollectionToDtoMapper extends CollectionToDtoMapper<HgPackage, HgConfigPackageDto> {
|
||||
|
||||
static final String COLLECTION_NAME = "packages";
|
||||
private UriInfoStore uriInfoStore;
|
||||
|
||||
@Inject
|
||||
public HgConfigPackageCollectionToDtoMapper(HgConfigPackageToDtoMapper mapper, UriInfoStore uriInfoStore) {
|
||||
super(COLLECTION_NAME, mapper);
|
||||
this.uriInfoStore = uriInfoStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSelfLink() {
|
||||
LinkBuilder linkBuilder = new LinkBuilder(uriInfoStore.get(), HgConfigResource.class);
|
||||
return linkBuilder.method("getPackagesResource").parameters().href();
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class HgConfigPackageDto extends HalRepresentation {
|
||||
|
||||
private String arch;
|
||||
private HgConfigDto hgConfigTemplate;
|
||||
private String hgVersion;
|
||||
private String id;
|
||||
private String platform;
|
||||
private String pythonVersion;
|
||||
private long size;
|
||||
private String url;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import sonia.scm.installer.HgPackage;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Mapper
|
||||
public abstract class HgConfigPackageToDtoMapper extends BaseMapper<HgPackage, HgConfigPackageDto> {
|
||||
@Inject
|
||||
private UriInfoStore uriInfoStore;
|
||||
|
||||
@Override
|
||||
@Mapping(target = "attributes", ignore = true) // We do not map HAL attributes
|
||||
@Mapping(target = "hgConfigTemplate.attributes", ignore = true) // Also not for nested DTOs
|
||||
public abstract HgConfigPackageDto map(HgPackage modelObject);
|
||||
|
||||
// Don't add links because ConfigPackages don't have their own ressource
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import de.otto.edison.hal.Links;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class HgConfigPackagesDto extends HalRepresentation {
|
||||
|
||||
private List<HgConfigPackageDto> packages;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
||||
protected HalRepresentation add(Links links) {
|
||||
return super.add(links);
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public static class HgConfigPackageDto {
|
||||
|
||||
private String arch;
|
||||
private HgConfigDto hgConfigTemplate;
|
||||
private String hgVersion;
|
||||
private String id;
|
||||
private String platform;
|
||||
private String pythonVersion;
|
||||
private long size;
|
||||
private String url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.Links;
|
||||
import lombok.Getter;
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import sonia.scm.installer.HgPackage;
|
||||
import sonia.scm.installer.HgPackages;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
|
||||
// Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection.
|
||||
@SuppressWarnings("squid:S3306")
|
||||
@Mapper
|
||||
public abstract class HgConfigPackagesToDtoMapper {
|
||||
|
||||
@Inject
|
||||
private UriInfoStore uriInfoStore;
|
||||
|
||||
public HgConfigPackagesDto map(HgPackages hgpackages) {
|
||||
return map(new HgPackagesNonIterable(hgpackages));
|
||||
}
|
||||
|
||||
@Mapping(target = "attributes", ignore = true) // We do not map HAL attributes
|
||||
/* Favor warning "Unmapped target property: "attributes", to packages[].hgConfigTemplate"
|
||||
Over error "Unknown property "packages[].hgConfigTemplate.attributes"
|
||||
@Mapping(target = "packages[].hgConfigTemplate.attributes", ignore = true) // Also not for nested DTOs
|
||||
*/
|
||||
protected abstract HgConfigPackagesDto map(HgPackagesNonIterable hgPackagesNonIterable);
|
||||
|
||||
@AfterMapping
|
||||
void appendLinks(@MappingTarget HgConfigPackagesDto target) {
|
||||
Links.Builder linksBuilder = linkingTo().self(createSelfLink());
|
||||
target.add(linksBuilder.build());
|
||||
}
|
||||
|
||||
private String createSelfLink() {
|
||||
LinkBuilder linkBuilder = new LinkBuilder(uriInfoStore.get(), HgConfigResource.class);
|
||||
return linkBuilder.method("getPackagesResource").parameters().href();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unfortunately, HgPackages is iterable, HgConfigPackagesDto does not need to be iterable and MapStruct refuses to
|
||||
* map an iterable to a non-iterable. So use this little non-iterable "proxy".
|
||||
*/
|
||||
@Getter
|
||||
static class HgPackagesNonIterable {
|
||||
private List<HgPackage> packages;
|
||||
|
||||
HgPackagesNonIterable(HgPackages hgPackages) {
|
||||
this.packages = hgPackages.getPackages();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,8 +39,7 @@ import com.google.inject.servlet.ServletModule;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import sonia.scm.api.v2.resources.HgConfigDtoToHgConfigMapper;
|
||||
import sonia.scm.api.v2.resources.HgConfigInstallationsToDtoMapper;
|
||||
import sonia.scm.api.v2.resources.HgConfigPackageCollectionToDtoMapper;
|
||||
import sonia.scm.api.v2.resources.HgConfigPackageToDtoMapper;
|
||||
import sonia.scm.api.v2.resources.HgConfigPackagesToDtoMapper;
|
||||
import sonia.scm.api.v2.resources.HgConfigToHgConfigDtoMapper;
|
||||
import sonia.scm.installer.HgPackageReader;
|
||||
import sonia.scm.plugin.Extension;
|
||||
@@ -77,8 +76,7 @@ public class HgServletModule extends ServletModule
|
||||
|
||||
bind(HgConfigDtoToHgConfigMapper.class).to(Mappers.getMapper(HgConfigDtoToHgConfigMapper.class).getClass());
|
||||
bind(HgConfigToHgConfigDtoMapper.class).to(Mappers.getMapper(HgConfigToHgConfigDtoMapper.class).getClass());
|
||||
bind(HgConfigPackageToDtoMapper.class).to(Mappers.getMapper(HgConfigPackageToDtoMapper.class).getClass());
|
||||
bind(HgConfigPackageCollectionToDtoMapper.class);
|
||||
bind(HgConfigPackagesToDtoMapper.class).to(Mappers.getMapper(HgConfigPackagesToDtoMapper.class).getClass());
|
||||
bind(HgConfigInstallationsToDtoMapper.class);
|
||||
|
||||
// bind servlets
|
||||
|
||||
@@ -56,12 +56,12 @@ public class HgConfigPackageResourceTest {
|
||||
|
||||
private final URI baseUri = java.net.URI.create("/");
|
||||
|
||||
@InjectMocks
|
||||
private HgConfigPackageToDtoMapperImpl hgConfigPackageToDtoMapper;
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private UriInfoStore uriInfoStore;
|
||||
|
||||
@InjectMocks
|
||||
private HgConfigPackagesToDtoMapperImpl mapper;
|
||||
|
||||
@Mock
|
||||
private HgRepositoryHandler repositoryHandler;
|
||||
|
||||
@@ -96,11 +96,7 @@ public class HgConfigPackageResourceTest {
|
||||
String responseString = response.getContentAsString();
|
||||
ObjectNode responseJson = new ObjectMapper().readValue(responseString, ObjectNode.class);
|
||||
|
||||
|
||||
JsonNode embedded = responseJson.get("_embedded");
|
||||
assertThat(embedded).isNotNull();
|
||||
|
||||
JsonNode packages = embedded.get("packages");
|
||||
JsonNode packages = responseJson.get("packages");
|
||||
assertThat(packages).isNotNull();
|
||||
assertThat(packages).hasSize(2);
|
||||
|
||||
@@ -191,9 +187,6 @@ public class HgConfigPackageResourceTest {
|
||||
}
|
||||
|
||||
private void setupResources() {
|
||||
HgConfigPackageCollectionToDtoMapper mapper =
|
||||
new HgConfigPackageCollectionToDtoMapper(hgConfigPackageToDtoMapper, uriInfoStore);
|
||||
|
||||
HgConfigPackageResource hgConfigPackageResource =
|
||||
new HgConfigPackageResource(hgPackageReader, advancedHttpClient, repositoryHandler, mapper);
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import sonia.scm.installer.HgPackage;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sonia.scm.api.v2.resources.HgConfigTests.assertEqualsPackage;
|
||||
import static sonia.scm.api.v2.resources.HgConfigTests.createPackage;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HgConfigPackageToDtoMapperTest {
|
||||
|
||||
private URI baseUri = URI.create("http://example.com/base/");
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private UriInfoStore uriInfoStore;
|
||||
|
||||
@InjectMocks
|
||||
private HgConfigPackageToDtoMapperImpl mapper;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
when(uriInfoStore.get().getBaseUri()).thenReturn(baseUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMapFields() {
|
||||
HgPackage hgPackage = createPackage();
|
||||
|
||||
HgConfigPackageDto dto = mapper.map(hgPackage);
|
||||
|
||||
assertEqualsPackage(dto);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import sonia.scm.installer.HgPackage;
|
||||
import sonia.scm.installer.HgPackages;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
@@ -19,12 +20,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sonia.scm.api.v2.resources.HgConfigPackageCollectionToDtoMapper.COLLECTION_NAME;
|
||||
import static sonia.scm.api.v2.resources.HgConfigTests.assertEqualsPackage;
|
||||
import static sonia.scm.api.v2.resources.HgConfigTests.createPackage;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HgConfigPackageCollectionToDtoMapperTest {
|
||||
public class HgConfigPackagesToDtoMapperTest {
|
||||
|
||||
private URI baseUri = URI.create("http://example.com/base/");
|
||||
|
||||
@@ -32,9 +32,7 @@ public class HgConfigPackageCollectionToDtoMapperTest {
|
||||
private UriInfoStore uriInfoStore;
|
||||
|
||||
@InjectMocks
|
||||
private HgConfigPackageToDtoMapperImpl hgConfigPackageToDtoMapper;
|
||||
|
||||
private HgConfigPackageCollectionToDtoMapper mapper;
|
||||
private HgConfigPackagesToDtoMapperImpl mapper;
|
||||
|
||||
private URI expectedBaseUri;
|
||||
|
||||
@@ -42,35 +40,29 @@ public class HgConfigPackageCollectionToDtoMapperTest {
|
||||
public void init() {
|
||||
when(uriInfoStore.get().getBaseUri()).thenReturn(baseUri);
|
||||
expectedBaseUri = baseUri.resolve(HgConfigResource.HG_CONFIG_PATH_V2 + "/packages");
|
||||
mapper = new HgConfigPackageCollectionToDtoMapper(hgConfigPackageToDtoMapper, uriInfoStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMapFields() {
|
||||
Collection<HgPackage> hgPackages = createPackages();
|
||||
HgPackages hgPackages = new HgPackages();
|
||||
hgPackages.setPackages(createPackages());
|
||||
|
||||
HalRepresentation dto = mapper.map(hgPackages);
|
||||
HgConfigPackagesDto dto = mapper.map(hgPackages);
|
||||
|
||||
List<HalRepresentation> itemsBy = dto.getEmbedded().getItemsBy(COLLECTION_NAME);
|
||||
assertThat(itemsBy).hasSize(2);
|
||||
assertThat(dto.getPackages()).hasSize(2);
|
||||
|
||||
HgConfigPackageDto hgPackageDto1 = assertAndGetAsDto(itemsBy.get(0));
|
||||
HgConfigPackagesDto.HgConfigPackageDto hgPackageDto1 = dto.getPackages().get(0);
|
||||
assertEqualsPackage(hgPackageDto1);
|
||||
|
||||
HgConfigPackageDto hgPackageDto2 = assertAndGetAsDto(itemsBy.get(1));
|
||||
assertTrue(hgPackageDto2.getLinks().isEmpty());
|
||||
HgConfigPackagesDto.HgConfigPackageDto hgPackageDto2 = dto.getPackages().get(1);
|
||||
// Just verify a random field
|
||||
assertThat(hgPackageDto2.getId()).isNull();
|
||||
|
||||
assertEquals(expectedBaseUri.toString(), dto.getLinks().getLinkBy("self").get().getHref());
|
||||
}
|
||||
|
||||
private HgConfigPackageDto assertAndGetAsDto(HalRepresentation halRepresentation) {
|
||||
assertThat(halRepresentation).isInstanceOf(HgConfigPackageDto.class);
|
||||
return (HgConfigPackageDto) halRepresentation;
|
||||
}
|
||||
|
||||
private Collection<HgPackage> createPackages() {
|
||||
private List<HgPackage> createPackages() {
|
||||
return Arrays.asList(createPackage(), new HgPackage());
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class HgConfigTests {
|
||||
return hgPackage;
|
||||
}
|
||||
|
||||
static void assertEqualsPackage(HgConfigPackageDto dto) {
|
||||
static void assertEqualsPackage(HgConfigPackagesDto.HgConfigPackageDto dto) {
|
||||
assertEquals("arch", dto.getArch());
|
||||
assertEquals("1", dto.getId());
|
||||
assertEquals("2", dto.getHgVersion());
|
||||
@@ -64,8 +64,6 @@ class HgConfigTests {
|
||||
|
||||
assertEqualsConfiguration(dto.getHgConfigTemplate());
|
||||
assertTrue(dto.getHgConfigTemplate().getLinks().isEmpty());
|
||||
|
||||
assertTrue(dto.getLinks().isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user