Added MaterialControllerIntegrationTest

Fixed all errors related to these tests.
This commit is contained in:
Jan 2025-07-11 20:32:04 +02:00
parent 7109a1386d
commit 438fabefb9
21 changed files with 3651 additions and 53 deletions

View file

@ -10,6 +10,7 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import java.util.HashMap;
import java.util.Map;
@ -63,6 +64,26 @@ public class GlobalExceptionHandler {
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<ErrorResponseDTO> handleConstraintViolation(MethodArgumentTypeMismatchException exception) { //
ErrorDTO error = new ErrorDTO(
exception.getClass().getSimpleName(),
"Wrong Datatype",
exception.getMessage(),
new HashMap<>() {{
put("errorMessage", exception.getMessage());
put("stackTrace", exception.getStackTrace());
}}
);
return new ResponseEntity<>(new ErrorResponseDTO(error), HttpStatus.BAD_REQUEST);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<ErrorResponseDTO> handleConstraintViolation(ConstraintViolationException exception) { //

View file

@ -4,14 +4,18 @@ import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
import de.avatic.lcc.dto.generic.MaterialDTO;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.access.MaterialService;
import jakarta.validation.constraints.Min;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api/materials")
@Validated
public class MaterialController {
@ -33,9 +37,9 @@ public class MaterialController {
*/
@GetMapping("/")
public ResponseEntity<List<MaterialDTO>> listMaterials(
@RequestParam(defaultValue = "20") int limit,
@RequestParam(defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "") String filter) {
@RequestParam(defaultValue = "20") @Min(1) int limit,
@RequestParam(defaultValue = "1") @Min(1) int page,
@RequestParam(required = false) Optional<String> filter) {
SearchQueryResult<MaterialDTO> materials = materialService.listMaterial(filter, page, limit);

View file

@ -11,6 +11,9 @@ public class MaterialDetailDTO {
@JsonProperty("part_number")
private String partNumber;
@JsonProperty("normalized_part_number")
private String normalizedPartNumber;
private String name;
@JsonProperty("hs_code")
@ -19,6 +22,9 @@ public class MaterialDetailDTO {
@JsonProperty("packaging")
private List<MaterialDetailPackagingDTO> handlingUnits;
@JsonProperty("is_deprecated")
private boolean isDeprecated;
public MaterialDetailDTO() {
}
@ -66,11 +72,12 @@ public class MaterialDetailDTO {
this.hsCode = hsCode;
}
@JsonProperty("handling_units")
@JsonProperty("packaging")
public List<MaterialDetailPackagingDTO> getHandlingUnits() {
return handlingUnits;
}
@JsonProperty("packaging")
public void setHandlingUnits(List<MaterialDetailPackagingDTO> handlingUnits) {
this.handlingUnits = handlingUnits;
}
@ -102,4 +109,22 @@ public class MaterialDetailDTO {
public int hashCode() {
return Objects.hash(id, partNumber, name, hsCode, handlingUnits);
}
public String getNormalizedPartNumber() {
return normalizedPartNumber;
}
public void setNormalizedPartNumber(String normalizedPartNumber) {
this.normalizedPartNumber = normalizedPartNumber;
}
@JsonProperty("is_deprecated")
public boolean isDeprecated() {
return isDeprecated;
}
@JsonProperty("is_deprecated")
public void setDeprecated(boolean deprecated) {
isDeprecated = deprecated;
}
}

View file

@ -40,10 +40,12 @@ public class MaterialDetailPackagingDTO {
this.id = id;
}
@JsonProperty("is_deprecated")
public Boolean getDeprecated() {
return isDeprecated;
}
@JsonProperty("is_deprecated")
public void setDeprecated(Boolean deprecated) {
isDeprecated = deprecated;
}

View file

@ -103,6 +103,7 @@ public class DimensionDTO {
this.contentUnitCount = contentUnitCount;
}
@JsonProperty("is_deprecated")
public Boolean getDeprecated() {
return isDeprecated;
}

View file

@ -11,6 +11,8 @@ public class MaterialDTO {
@JsonProperty("part_number")
private String partNumber;
private String name;
@JsonProperty("hs_code")
private String hsCode;
public MaterialDTO() {

View file

@ -67,6 +67,7 @@ public class NodeDTO {
this.types = types;
}
@JsonProperty("is_deprecated")
public Boolean getDeprecated() {
return isDeprecated;
}

View file

@ -51,9 +51,9 @@ public class MaterialRepository {
queryBuilder.append(" AND is_deprecated = FALSE");
}
if (filter != null) {
queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ?) ");
queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ? ) ");
}
queryBuilder.append("ORDER BY normalized_part_number LIMIT ? OFFSET ?");
queryBuilder.append(" ORDER BY normalized_part_number LIMIT ? OFFSET ?");
return queryBuilder.toString();
}
@ -81,17 +81,22 @@ public class MaterialRepository {
}
@Transactional
public SearchQueryResult<Material> listMaterials(String filter, boolean excludeDeprecated, SearchQueryPagination pagination) {
public SearchQueryResult<Material> listMaterials(Optional<String> filter, boolean excludeDeprecated, SearchQueryPagination pagination) {
String query = buildQuery(filter, excludeDeprecated);
String query = buildQuery(filter.orElse(null), excludeDeprecated);
var materials = jdbcTemplate.query(query, new MaterialMapper(),
"%" + filter + "%", "%" + filter + "%", !excludeDeprecated, pagination.getLimit(), pagination.getOffset());
var materials = filter.isPresent() ?
jdbcTemplate.query(query, new MaterialMapper(),
"%" + filter.get() + "%", "%" + filter.get() + "%", pagination.getLimit(), pagination.getOffset()) :
jdbcTemplate.query(query, new MaterialMapper(),
pagination.getLimit(), pagination.getOffset());
Integer totalCount = jdbcTemplate.queryForObject(
buildCountQuery(filter, excludeDeprecated),
Integer.class, "%" + filter + "%", "%" + filter + "%", !excludeDeprecated
);
String countQuery = buildCountQuery(filter.orElse(null), excludeDeprecated);
Integer totalCount = filter.isPresent() ?
jdbcTemplate.queryForObject(countQuery, Integer.class,
"%" + filter.get() + "%", "%" + filter.get() + "%") :
jdbcTemplate.queryForObject(countQuery, Integer.class);
return new SearchQueryResult<>(materials, pagination.getPage(), totalCount, pagination.getLimit());
}
@ -100,9 +105,12 @@ public class MaterialRepository {
public Optional<Material> getById(Integer id) {
String query = "SELECT * FROM material WHERE id = ? AND is_deprecated = FALSE";
Material material = jdbcTemplate.queryForObject(query, new MaterialMapper(), id);
var material = jdbcTemplate.query(query, new MaterialMapper(), id);
return Optional.ofNullable(material);
if(material.isEmpty())
return Optional.empty();
return Optional.ofNullable(material.getFirst());
}
@Transactional
@ -125,9 +133,7 @@ public class MaterialRepository {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection
.prepareStatement("INSERT INTO material (name, part_number, normalized_part_number, hs_code) VALUES (?, ?, ?, ?)",
Statement.RETURN_GENERATED_KEYS);
PreparedStatement ps = connection.prepareStatement("INSERT INTO material (name, part_number, normalized_part_number, hs_code) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, material.getName()); //
ps.setString(2, material.getPartNumber());
ps.setString(3, material.getNormalizedPartNumber());
@ -136,8 +142,7 @@ public class MaterialRepository {
}, keyHolder);
return Optional.ofNullable(!Objects.requireNonNull(keyHolder.getKeys()).isEmpty() ? ((Integer) keyHolder.getKeys().values().iterator().next())
: null);
return Optional.ofNullable(!Objects.requireNonNull(keyHolder.getKeys()).isEmpty() ? ((Integer) keyHolder.getKeys().values().iterator().next()) : null);
}

View file

@ -27,8 +27,7 @@ public class NodeRepository {
public Optional<Node> getById(Integer id) {
String query = """
SELECT node.id AS id, node.name AS name, node.address as address, node.is_source as is_source,
node.is_destination as is_destination, node.is_intermediate as is_intermediate, node.country_id as country_id, node.predecessor_required as predecessor_required
SELECT *
FROM node
WHERE node.id = ?""";
@ -41,8 +40,7 @@ public class NodeRepository {
String placeholders = String.join(",", Collections.nCopies(nodeIds.size(), "?"));
String query = """
SELECT node.id AS id, node.name AS name, node.address as address, node.is_source as is_source,
node.is_destination as is_destination, node.is_intermediate as is_intermediate, node.country_id as country_id, node.predecessor_required as predecessor_required
SELECT *
FROM node
WHERE node.id IN (?)""";
@ -186,8 +184,7 @@ public class NodeRepository {
public Optional<Node> getByExternalMappingId(String mappingId) {
String query = """
SELECT node.id AS id, node.name AS name, node.address as address, node.is_source as is_source,
node.is_destination as is_destination, node.is_intermediate as is_intermediate, node.country_id as country_id, node.predecessor_required as predecessor_required
SELECT *
FROM node
WHERE node.external_mapping_id = ?""";
@ -385,6 +382,11 @@ public class NodeRepository {
data.setIntermediate(rs.getBoolean("is_intermediate"));
data.setPredecessorRequired(rs.getBoolean("predecessor_required"));
data.setGeoLat(rs.getBigDecimal("geo_lat"));
data.setGeoLng(rs.getBigDecimal("geo_lng"));
data.setDeprecated(rs.getBoolean("is_deprecated"));
data.setNodePredecessors(getPredecessorsOf(data.getId()));
data.setOutboundCountries(getOutboundCountriesOf(data.getId()));

View file

@ -27,13 +27,15 @@ public class PackagingDimensionRepository {
@Transactional
public Optional<PackagingDimension> getById(Integer id) {
String query = """
SELECT id, displayed_dimension_unit, displayed_weight_unit, width, length, height,
content_unit_count, type, is_deprecated
FROM packaging_dimension
WHERE packaging_dimension.id = ? AND packaging_dimension.is_deprecated = ?""";
SELECT id, displayed_dimension_unit, displayed_weight_unit, width, length, height,
weight, content_unit_count, type, is_deprecated
FROM packaging_dimension
WHERE packaging_dimension.id = ? AND packaging_dimension.is_deprecated = false""";
var dimension = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
//TODO: what if i need to get deprecated materials?
var dimension = jdbcTemplate.query(query, (rs, rowNum) -> {
var entity = new PackagingDimension();
entity.setId(rs.getInt("id"));
@ -48,10 +50,15 @@ public class PackagingDimensionRepository {
entity.setHeight(rs.getInt("height"));
entity.setLength(rs.getInt("length"));
entity.setContentUnitCount(rs.getInt("content_unit_count"));
return entity;
}, id);
return Optional.ofNullable(dimension);
if(dimension.isEmpty())
return Optional.empty();
return Optional.ofNullable(dimension.getFirst());
}
public void update(PackagingDimension dimension) {

View file

@ -26,7 +26,7 @@ public class PackagingPropertiesRepository {
String query = """
SELECT property.id as id, property.property_value AS value, property.packaging_id as packaging_id,
type.name AS type_name, type.data_type AS type_data_type, type.is_required AS type_is_required,
type.id AS type_id, type.name AS type_name, type.data_type AS type_data_type, type.is_required AS type_is_required,
type.external_mapping_id AS type_external_mapping_id, type.validation_rule AS type_validation_rule
FROM packaging_property property LEFT JOIN packaging_property_type type ON property.packaging_property_type_id = type.id WHERE packaging_id = ?""";
@ -37,7 +37,7 @@ public class PackagingPropertiesRepository {
public Optional<PackagingProperty> getByPackagingIdAndType(Integer id, String type) {
String query = """
SELECT property.id as id, property.property_value AS value, property.packaging_id as packaging_id,
type.name AS type_name, type.data_type AS type_data_type, type.is_required AS type_is_required,
type.id AS type_id, type.name AS type_name, type.data_type AS type_data_type, type.is_required AS type_is_required,
type.external_mapping_id AS type_external_mapping_id, type.validation_rule AS type_validation_rule
FROM packaging_property property LEFT JOIN packaging_property_type type ON property.packaging_property_type_id = type.id WHERE packaging_id = ? AND type.external_mapping_id = ?""";

View file

@ -77,7 +77,7 @@ public class UserNodeRepository {
node.setAddress(rs.getString("address"));
node.setGeoLat(rs.getBigDecimal("geo_lat"));
node.setGeoLng(rs.getBigDecimal("geo_lng"));
node.setDeprecated(rs.getBoolean("deprecated"));
node.setDeprecated(rs.getBoolean("is_deprecated"));
node.setCountryId(rs.getInt("country_id"));
return node;

View file

@ -9,8 +9,11 @@ import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.transformer.generic.MaterialTransformer;
import de.avatic.lcc.service.transformer.material.MaterialDetailTransformer;
import de.avatic.lcc.util.exception.badrequest.MaterialNotFoundException;
import de.avatic.lcc.util.exception.badrequest.NotFoundException;
import org.springframework.stereotype.Service;
import java.util.Optional;
/**
* Service class responsible for managing materials. Provides functionality to
* list, retrieve, and manipulate material data. Acts as a bridge between the
@ -44,7 +47,7 @@ public class MaterialService {
* @param limit the maximum number of items per page
* @return a {@link SearchQueryResult} containing a list of material DTOs and pagination details
*/
public SearchQueryResult<MaterialDTO> listMaterial(String filter, int page, int limit) {
public SearchQueryResult<MaterialDTO> listMaterial(Optional<String> filter, int page, int limit) {
SearchQueryResult<Material> queryResult = materialRepository.listMaterials(filter, true, new SearchQueryPagination(page, limit));
return SearchQueryResult.map(queryResult, materialTransformer::toMaterialDTO);
}
@ -57,7 +60,7 @@ public class MaterialService {
* @throws MaterialNotFoundException if no material with the given ID is found
*/
public MaterialDetailDTO getMaterial(Integer id) {
return materialDetailTransformer.toMaterialDetailDTO(materialRepository.getById(id).orElseThrow(() -> new MaterialNotFoundException(id)));
return materialDetailTransformer.toMaterialDetailDTO(materialRepository.getById(id).orElseThrow(() -> new NotFoundException(NotFoundException.NotFoundType.MATERIAL,id.toString())));
}
/**

View file

@ -35,9 +35,11 @@ public class MaterialDetailTransformer {
dto.setId(entity.getId());
dto.setPartNumber(entity.getPartNumber());
dto.setNormalizedPartNumber(entity.getNormalizedPartNumber());
dto.setName(entity.getName());
dto.setHsCode(entity.getHsCode());
dto.setHandlingUnits(packaging);
dto.setDeprecated(entity.getDeprecated());
return dto;

View file

@ -92,6 +92,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get all countries without pagination")
void allCountries() throws Exception {
mockMvc.perform(get(BASE_URL + "/all"))
.andExpect(status().isOk())
@ -100,6 +101,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get all countries filtered by EMEA region")
void allCountriesFilteredByEmea() throws Exception {
mockMvc.perform(get(BASE_URL + "/all")
.param("filter", "EMEA"))
@ -108,6 +110,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get country details by ID")
void getCountryDetailsById() throws Exception {
final String isoCode = "DE";
@ -127,6 +130,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get country details by ISO code")
void getCountryDetailsByIsoCode() throws Exception {
final String isoCode = "US";
@ -142,6 +146,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get country with specific property set")
void getWithPropertySet() throws Exception {
final String isoCode = "US";
Integer propertySetId = getExpiredPropertySet();
@ -154,6 +159,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get country with invalid property set should return bad request")
void getWithBadPropertySet() throws Exception {
final String isoCode = "US";
Integer propertySetId = 999999;
@ -170,18 +176,21 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get country with invalid ID should return bad request")
void getCountryWithBadId() throws Exception {
mockMvc.perform(get(BASE_URL + "/999"))
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("get country with invalid ISO code should return bad request")
void getCountryWithBadIsoCode() throws Exception {
mockMvc.perform(get(BASE_URL + "/XY"))
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("get countries with invalid pagination parameters should return bad request")
void countriesPaginationWithBadParams() throws Exception {
mockMvc.perform(get(BASE_URL + "/")
.param("limit", "-1")
@ -190,6 +199,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get countries with large pagination limit should return all countries")
void countriesPaginationWithLargeParams() throws Exception {
mockMvc.perform(get(BASE_URL + "/")
.param("limit", "1000"))
@ -198,6 +208,7 @@ public class CountryControllerIntegrationTest {
}
@Test
@DisplayName("get countries with SQL injection attempt should be safe")
void countriesSqlInjection() throws Exception {
String maliciousFilter = "'; DROP TABLE country; --";

View file

@ -0,0 +1,415 @@
package de.avatic.lcc.controller.configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.avatic.lcc.dto.generic.MaterialDTO;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
@DisplayName("MaterialController Integration Tests")
class MaterialControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Nested
@DisplayName("GET /api/materials/ - List Materials")
@Sql(scripts = {"classpath:master_data/countries_properties.sql", "classpath:master_data/nodes.sql", "classpath:master_data/material_packaging.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = {"classpath:master_data/material_packaging-cleanup.sql", "classpath:master_data/nodes-cleanup.sql", "classpath:master_data/countries_properties-cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
class ListMaterialsTests {
@Test
@DisplayName("Should return all materials with default pagination")
void shouldReturnAllMaterialsWithDefaultPagination() throws Exception {
mockMvc.perform(get("/api/materials/")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(18))) // Based on the test data, we have 18 materials
.andExpect(header().string("X-Total-Count", "18"))
.andExpect(header().string("X-Page-Count", "1"))
.andExpect(header().string("X-Current-Page", "1"))
.andExpect(jsonPath("$", hasSize(18)))
.andExpect(jsonPath("$[0].part_number", notNullValue()))
.andExpect(jsonPath("$[0].name", notNullValue()))
.andExpect(jsonPath("$[0].hs_code", notNullValue()));
}
@Test
@DisplayName("Should return materials with custom pagination")
void shouldReturnMaterialsWithCustomPagination() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("limit", "5")
.param("page", "1")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(5)))
.andExpect(header().string("X-Total-Count", "18"))
.andExpect(header().string("X-Page-Count", "4")) // 18 materials / 5 per page = 4 pages
.andExpect(header().string("X-Current-Page", "1"));
}
@Test
@DisplayName("Should return second page of materials")
void shouldReturnSecondPageOfMaterials() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("limit", "10")
.param("page", "2")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(8))) // Second page should have 8 materials (18 - 10)
.andExpect(header().string("X-Total-Count", "18"))
.andExpect(header().string("X-Page-Count", "2"))
.andExpect(header().string("X-Current-Page", "2"));
}
@Test
@DisplayName("Should filter materials by part number")
void shouldFilterMaterialsByPartNumber() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("filter", "28152640129")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].part_number", is("28152640129")))
.andExpect(jsonPath("$[0].name", containsString("gearbox housing blank")))
.andExpect(header().string("X-Total-Count", "1"))
.andExpect(header().string("X-Page-Count", "1"))
.andExpect(header().string("X-Current-Page", "1"));
}
@Test
@DisplayName("Should filter materials by name")
void shouldFilterMaterialsByName() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("filter", "wheel")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(greaterThan(0))))
.andExpect(jsonPath("$[*].name", everyItem(containsStringIgnoringCase("wheel"))));
}
@Test
@DisplayName("Should return empty list when filter matches no materials")
void shouldReturnEmptyListWhenFilterMatchesNoMaterials() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("filter", "nonexistent")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(0)))
.andExpect(header().string("X-Total-Count", "0"))
.andExpect(header().string("X-Page-Count", "0"))
.andExpect(header().string("X-Current-Page", "1"));
}
@Test
@DisplayName("Should handle empty filter parameter")
void shouldHandleEmptyFilterParameter() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("filter", "")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(18))) // Should return all materials
.andExpect(header().string("X-Total-Count", "18"));
}
@Test
@DisplayName("Should handle out of bounds page number")
void shouldHandleOutOfBoundsPageNumber() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("page", "999")
.param("limit", "10")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(0))) // Should return empty list
.andExpect(header().string("X-Total-Count", "18"))
.andExpect(header().string("X-Current-Page", "999"));
}
@Test
@DisplayName("Should handle negative page number")
void shouldHandleNegativePageNumber() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("page", "-1")
.param("limit", "10")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("Should handle large limit parameter")
void shouldHandleLargeLimitParameter() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("limit", "1000")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(18))) // Should return all available materials
.andExpect(header().string("X-Total-Count", "18"))
.andExpect(header().string("X-Page-Count", "1"));
}
}
@Nested
@DisplayName("GET /api/materials/{id} - Get Material Details")
@Sql(scripts = {"classpath:master_data/countries_properties.sql", "classpath:master_data/nodes.sql", "classpath:master_data/material_packaging.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = {"classpath:master_data/material_packaging-cleanup.sql", "classpath:master_data/nodes-cleanup.sql", "classpath:master_data/countries_properties-cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
class GetMaterialDetailsTests {
@Test
@DisplayName("Should return material details for existing material")
void shouldReturnMaterialDetailsForExistingMaterial() throws Exception {
// First, get the list of materials to find a valid ID
MvcResult listResult = mockMvc.perform(get("/api/materials/")
.param("limit", "1"))
.andExpect(status().isOk())
.andReturn();
var content = objectMapper.readValue(listResult.getResponse().getContentAsString(), MaterialDTO[].class);
assertThat(content.length).isEqualTo(1);
mockMvc.perform(get("/api/materials/" + content[0].getId())
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id", notNullValue()))
.andExpect(jsonPath("$.part_number", notNullValue()))
.andExpect(jsonPath("$.name", notNullValue()))
.andExpect(jsonPath("$.hs_code", notNullValue()))
.andExpect(jsonPath("$.normalized_part_number", notNullValue()))
.andExpect(jsonPath("$.is_deprecated", notNullValue()));
}
@Test
@DisplayName("Should return material details with correct data structure")
void shouldReturnMaterialDetailsWithCorrectDataStructure() throws Exception {
MvcResult listResult = mockMvc.perform(get("/api/materials/")
.param("limit", "1")
.param("page", "3"))
.andExpect(status().isOk())
.andReturn();
var content = objectMapper.readValue(listResult.getResponse().getContentAsString(), MaterialDTO[].class);
assertThat(content.length).isEqualTo(1);
mockMvc.perform(get("/api/materials/" + content[0].getId())
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.part_number", matchesPattern("\\d+"))) // Part numbers are numeric strings
.andExpect(jsonPath("$.normalized_part_number", matchesPattern("\\d+"))) // Normalized part numbers are numeric strings
.andExpect(jsonPath("$.hs_code", matchesPattern("\\d{8}"))) // HS codes are 8-digit strings
.andExpect(jsonPath("$.name", is(not(emptyString()))))
.andExpect(jsonPath("$.is_deprecated", isA(Boolean.class)));
}
@Test
@DisplayName("Should return specific material details by known part number")
void shouldReturnSpecificMaterialDetailsByKnownPartNumber() throws Exception {
MvcResult listResult = mockMvc.perform(get("/api/materials/")
.param("limit", "1").param("filter", "28152640129"))
.andExpect(status().isOk())
.andReturn();
var content = objectMapper.readValue(listResult.getResponse().getContentAsString(), MaterialDTO[].class);
assertThat(content.length).isEqualTo(1);
// We know from test data that material with part number '28152640129' exists
// We need to find its ID first or assume it has ID 1
mockMvc.perform(get("/api/materials/" + content[0].getId())
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.part_number", anyOf(
is("28152640129"), is("8222640822"), is("3064540201")))) // Any of the test materials
.andExpect(jsonPath("$.hs_code", anyOf(
is("84839089"), is("84312000"), is("84831095")))); // Corresponding HS codes
}
@Test
@DisplayName("Should return 400 for non-existent material ID")
void shouldReturn404ForNonExistentMaterialId() throws Exception {
mockMvc.perform(get("/api/materials/99999")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("Should return 400 for negative material ID")
void shouldReturn404ForNegativeMaterialId() throws Exception {
mockMvc.perform(get("/api/materials/-1")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("Should return 400 for invalid material ID format")
void shouldReturn400ForInvalidMaterialIdFormat() throws Exception {
mockMvc.perform(get("/api/materials/invalid")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("Should return 400 for zero material ID")
void shouldReturn400ForZeroMaterialId() throws Exception {
mockMvc.perform(get("/api/materials/0")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest()); // Assuming 0 is not a valid ID
}
}
@Nested
@DisplayName("Error Handling and Edge Cases")
@Sql(scripts = {"classpath:master_data/countries_properties.sql", "classpath:master_data/nodes.sql", "classpath:master_data/material_packaging.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = {"classpath:master_data/material_packaging-cleanup.sql", "classpath:master_data/nodes-cleanup.sql", "classpath:master_data/countries_properties-cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
class ErrorHandlingTests {
@Test
@DisplayName("Should handle missing required headers")
void shouldHandleMissingRequiredHeaders() throws Exception {
mockMvc.perform(get("/api/materials/"))
.andDo(print())
.andExpect(status().isOk()); // Should still work without explicit content type
}
@Test
@DisplayName("Should handle invalid parameter types for limit")
void shouldHandleInvalidParameterTypesForLimit() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("limit", "invalid")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("Should handle invalid parameter types for page")
void shouldHandleInvalidParameterTypesForPage() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("page", "invalid")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("Should handle extremely large filter string")
void shouldHandleExtremelyLargeFilterString() throws Exception {
String largeFilter = "x".repeat(1000);
mockMvc.perform(get("/api/materials/")
.param("filter", largeFilter)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(0))); // Should return empty result
}
@Test
@DisplayName("Should handle special characters in filter")
void shouldHandleSpecialCharactersInFilter() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("filter", "!@#$%^&*()")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(0))); // Should return empty result
}
@Test
@DisplayName("Should handle SQL injection attempts in filter")
void shouldHandleSqlInjectionAttemptsInFilter() throws Exception {
mockMvc.perform(get("/api/materials/")
.param("filter", "'; DROP TABLE material; --")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(0))); // Should return empty result and not break
}
}
@Nested
@DisplayName("Performance and Load Tests")
class PerformanceTests {
@Test
@DisplayName("Should handle concurrent requests efficiently")
@Sql(scripts = {"classpath:master_data/countries_properties.sql", "classpath:master_data/nodes.sql", "classpath:master_data/material_packaging.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = {"classpath:master_data/material_packaging-cleanup.sql", "classpath:master_data/nodes-cleanup.sql", "classpath:master_data/countries_properties-cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
void shouldHandleConcurrentRequestsEfficiently() throws Exception {
// Simulate multiple concurrent requests
for (int i = 0; i < 10; i++) {
mockMvc.perform(get("/api/materials/")
.param("page", String.valueOf((i % 3) + 1))
.param("limit", "5")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(header().exists("X-Total-Count"));
}
}
@Test
@DisplayName("Should respond within reasonable time limits")
@Sql(scripts = {"classpath:master_data/countries_properties.sql", "classpath:master_data/nodes.sql", "classpath:master_data/material_packaging.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = {"classpath:master_data/material_packaging-cleanup.sql", "classpath:master_data/nodes-cleanup.sql", "classpath:master_data/countries_properties-cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
void shouldRespondWithinReasonableTimeLimits() throws Exception {
long startTime = System.currentTimeMillis();
mockMvc.perform(get("/api/materials/")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
long endTime = System.currentTimeMillis();
long responseTime = endTime - startTime;
// Assert that response time is reasonable (less than 2 seconds)
assert responseTime < 2000 : "Response time too slow: " + responseTime + "ms";
}
}
}

View file

@ -1,19 +1,4 @@
delete
from lcc_test.packaging_property
where 1;
delete
from lcc_test.packaging_property_type
where 1;
delete
from lcc_test.packaging
where 1;
delete
from lcc_test.packaging_dimension
where 1;
delete
from lcc_test.material
where 1;
delete
from lcc_test.country_property
where 1;
delete

View file

@ -0,0 +1,15 @@
delete
from lcc_test.packaging_property
where 1;
delete
from lcc_test.packaging_property_type
where 1;
delete
from lcc_test.packaging
where 1;
delete
from lcc_test.packaging_dimension
where 1;
delete
from lcc_test.material
where 1;

View file

@ -0,0 +1,575 @@
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('28152640129', '028152640129', '84839089', 'gearbox housing blank ''GR4H-10', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('8222640822', '008222640822', '84839089', 'planet gear carrier blank ''stage 1', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('3064540201', '003064540201', '84312000', 'wheel hub', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('8212640113', '008212640113', '84312000', 'transmission housing blank ''GR2E-04', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('28152643516', '028152643516', '84831095', 'wheel shaft blank', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('4222640104', '004222640104', '84139100', 'gearbox housing blank ''AK20E', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('28152643502', '028152643502', '84839089', 'wheel shaft blank', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('28152640804', '028152640804', '84839089', 'planet gear carrier blank ''staire 2', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('4222640805', '004222640805', '84139100', 'planet gear carrier blank ''staire 2', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('4222640803', '004222640803', '84139100', 'planet gear carrier blank ''stage 1', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('8212640811', '008212640811', '84839089', 'planet gear carrier blank', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('8212640827', '008212640827', '84312000', 'planet gear carrier blank ''Stufe 1', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('5512640104', '005512640104', '84312000', 'transmission housing blank', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('5512640106', '005512640106', '84312000', 'transmission housing blank', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('8263500575', '008263500575', '85015220', 'traction motor assy. ''AE18-10 left', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('8263500576', '008263500576', '85015220', 'traction motor assy. ''AE18-10 right', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('28523500575', '028523500575', '85015230', 'traction motor assy. ''AE35-10 links', FALSE);
INSERT INTO material (part_number, normalized_part_number, hs_code, name, is_deprecated)
VALUES ('28523500576', '028523500576', '85015230', 'traction motor assy. ''AE35-10 rechts', FALSE);
-- ============================================
-- Packaging Data Import SQL
-- ============================================
-- Zuerst die packaging_property_types für stackable und rust prevention erstellen
-- (falls sie noch nicht existieren)
INSERT INTO packaging_property_type (name, external_mapping_id, data_type, validation_rule, is_required)
VALUES
('Stackable', 'STACKABLE', 'BOOLEAN', NULL, FALSE),
('Rust Prevention', 'RUST_PREVENTION', 'BOOLEAN', NULL, FALSE)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
data_type = VALUES(data_type);
-- ============================================
-- SHU Packaging Dimensions
-- ============================================
-- Part Number: 28152640129
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 7000, 7900, 'CM', 677000, 'KG', 1, FALSE);
SET @shu_dim_28152640129 = LAST_INSERT_ID();
-- Part Number: 8222640822
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5200, 'CM', 942000, 'KG', 630, FALSE);
SET @shu_dim_8222640822 = LAST_INSERT_ID();
-- Part Number: 3064540201
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5200, 'CM', 868000, 'KG', 160, FALSE);
SET @shu_dim_3064540201 = LAST_INSERT_ID();
-- Part Number: 8212640113
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 6500, 'CM', 702000, 'KG', 54, FALSE);
SET @shu_dim_8212640113 = LAST_INSERT_ID();
-- Part Number: 28152643516
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 4700, 'CM', 912000, 'KG', 60, FALSE);
SET @shu_dim_28152643516 = LAST_INSERT_ID();
-- Part Number: 4222640104
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5700, 'CM', 1074000, 'KG', 400, FALSE);
SET @shu_dim_4222640104 = LAST_INSERT_ID();
-- Part Number: 28152643502
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 4700, 'CM', 912000, 'KG', 60, FALSE);
SET @shu_dim_28152643502 = LAST_INSERT_ID();
-- Part Number: 28152640804
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 4700, 'CM', 740000, 'KG', 48, FALSE);
SET @shu_dim_28152640804 = LAST_INSERT_ID();
-- Part Number: 4222640805
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5700, 'CM', 912000, 'KG', 300, FALSE);
SET @shu_dim_4222640805 = LAST_INSERT_ID();
-- Part Number: 4222640803
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5700, 'CM', 962000, 'KG', 320, FALSE);
SET @shu_dim_4222640803 = LAST_INSERT_ID();
-- Part Number: 8212640811
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 3400, 'CM', 962000, 'KG', 320, FALSE);
SET @shu_dim_8212640811 = LAST_INSERT_ID();
-- Part Number: 8212640827
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 3400, 'CM', 962000, 'KG', 320, FALSE);
SET @shu_dim_8212640827 = LAST_INSERT_ID();
-- Part Number: 5512640104
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5700, 'CM', 1074000, 'KG', 400, FALSE);
SET @shu_dim_5512640104 = LAST_INSERT_ID();
-- Part Number: 5512640106
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5700, 'CM', 1074000, 'KG', 400, FALSE);
SET @shu_dim_5512640106 = LAST_INSERT_ID();
-- Part Number: 8263500575
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5200, 'CM', 1050000, 'KG', 600, FALSE);
SET @shu_dim_8263500575 = LAST_INSERT_ID();
-- Part Number: 8263500576
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5200, 'CM', 1050000, 'KG', 600, FALSE);
SET @shu_dim_8263500576 = LAST_INSERT_ID();
-- Part Number: 28523500575
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5200, 'CM', 1050000, 'KG', 600, FALSE);
SET @shu_dim_28523500575 = LAST_INSERT_ID();
-- Part Number: 28523500576
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('SHU', 12000, 8000, 5200, 'CM', 1050000, 'KG', 600, FALSE);
SET @shu_dim_28523500576 = LAST_INSERT_ID();
-- ============================================
-- HU Packaging Dimensions
-- ============================================
-- Part Number: 28152640129
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 700, 790, 'MM', 677000, 'KG', 1, FALSE);
SET @hu_dim_28152640129 = LAST_INSERT_ID();
-- Part Number: 8222640822
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 520, 'MM', 942000, 'KG', 1, FALSE);
SET @hu_dim_8222640822 = LAST_INSERT_ID();
-- Part Number: 3064540201
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 520, 'MM', 868000, 'KG', 1, FALSE);
SET @hu_dim_3064540201 = LAST_INSERT_ID();
-- Part Number: 8212640113
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 650, 'MM', 702000, 'KG', 1, FALSE);
SET @hu_dim_8212640113 = LAST_INSERT_ID();
-- Part Number: 28152643516
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 470, 'MM', 912000, 'KG', 1, FALSE);
SET @hu_dim_28152643516 = LAST_INSERT_ID();
-- Part Number: 4222640104
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 570, 'MM', 1074000, 'KG', 1, FALSE);
SET @hu_dim_4222640104 = LAST_INSERT_ID();
-- Part Number: 28152643502
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 470, 'MM', 912000, 'KG', 1, FALSE);
SET @hu_dim_28152643502 = LAST_INSERT_ID();
-- Part Number: 28152640804
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 470, 'MM', 740000, 'KG', 1, FALSE);
SET @hu_dim_28152640804 = LAST_INSERT_ID();
-- Part Number: 4222640805
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 570, 'MM', 912000, 'KG', 1, FALSE);
SET @hu_dim_4222640805 = LAST_INSERT_ID();
-- Part Number: 4222640803
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 570, 'MM', 962000, 'KG', 1, FALSE);
SET @hu_dim_4222640803 = LAST_INSERT_ID();
-- Part Number: 8212640811
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 340, 'MM', 962000, 'KG', 1, FALSE);
SET @hu_dim_8212640811 = LAST_INSERT_ID();
-- Part Number: 8212640827
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 340, 'MM', 962000, 'KG', 1, FALSE);
SET @hu_dim_8212640827 = LAST_INSERT_ID();
-- Part Number: 5512640104
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 570, 'MM', 1074000, 'KG', 1, FALSE);
SET @hu_dim_5512640104 = LAST_INSERT_ID();
-- Part Number: 5512640106
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 570, 'MM', 1074000, 'KG', 1, FALSE);
SET @hu_dim_5512640106 = LAST_INSERT_ID();
-- Part Number: 8263500575
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 520, 'MM', 1050000, 'KG', 1, FALSE);
SET @hu_dim_8263500575 = LAST_INSERT_ID();
-- Part Number: 8263500576
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 520, 'MM', 1050000, 'KG', 1, FALSE);
SET @hu_dim_8263500576 = LAST_INSERT_ID();
-- Part Number: 28523500575
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 520, 'MM', 1050000, 'KG', 1, FALSE);
SET @hu_dim_28523500575 = LAST_INSERT_ID();
-- Part Number: 28523500576
INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated)
VALUES ('HU', 1200, 800, 520, 'MM', 1050000, 'KG', 1, FALSE);
SET @hu_dim_28523500576 = LAST_INSERT_ID();
-- ============================================
-- Packaging Einträge
-- ============================================
-- Part Number: 28152640129
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '28152640129' LIMIT 1),
@hu_dim_28152640129,
@shu_dim_28152640129,
FALSE
);
SET @packaging_28152640129 = LAST_INSERT_ID();
-- Part Number: 8222640822
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '8222640822' LIMIT 1),
@hu_dim_8222640822,
@shu_dim_8222640822,
FALSE
);
SET @packaging_8222640822 = LAST_INSERT_ID();
-- Part Number: 3064540201
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '3064540201' LIMIT 1),
@hu_dim_3064540201,
@shu_dim_3064540201,
FALSE
);
SET @packaging_3064540201 = LAST_INSERT_ID();
-- Part Number: 8212640113
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '8212640113' LIMIT 1),
@hu_dim_8212640113,
@shu_dim_8212640113,
FALSE
);
SET @packaging_8212640113 = LAST_INSERT_ID();
-- Part Number: 28152643516
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '28152643516' LIMIT 1),
@hu_dim_28152643516,
@shu_dim_28152643516,
FALSE
);
SET @packaging_28152643516 = LAST_INSERT_ID();
-- Part Number: 4222640104
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '4222640104' LIMIT 1),
@hu_dim_4222640104,
@shu_dim_4222640104,
FALSE
);
SET @packaging_4222640104 = LAST_INSERT_ID();
-- Part Number: 28152643502
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '28152643502' LIMIT 1),
@hu_dim_28152643502,
@shu_dim_28152643502,
FALSE
);
SET @packaging_28152643502 = LAST_INSERT_ID();
-- Part Number: 28152640804
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '28152640804' LIMIT 1),
@hu_dim_28152640804,
@shu_dim_28152640804,
FALSE
);
SET @packaging_28152640804 = LAST_INSERT_ID();
-- Part Number: 4222640805
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '4222640805' LIMIT 1),
@hu_dim_4222640805,
@shu_dim_4222640805,
FALSE
);
SET @packaging_4222640805 = LAST_INSERT_ID();
-- Part Number: 4222640803
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '4222640803' LIMIT 1),
@hu_dim_4222640803,
@shu_dim_4222640803,
FALSE
);
SET @packaging_4222640803 = LAST_INSERT_ID();
-- Part Number: 8212640811
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '8212640811' LIMIT 1),
@hu_dim_8212640811,
@shu_dim_8212640811,
FALSE
);
SET @packaging_8212640811 = LAST_INSERT_ID();
-- Part Number: 8212640827
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '8212640827' LIMIT 1),
@hu_dim_8212640827,
@shu_dim_8212640827,
FALSE
);
SET @packaging_8212640827 = LAST_INSERT_ID();
-- Part Number: 5512640104
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '5512640104' LIMIT 1),
@hu_dim_5512640104,
@shu_dim_5512640104,
FALSE
);
SET @packaging_5512640104 = LAST_INSERT_ID();
-- Part Number: 5512640106
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '5512640106' LIMIT 1),
@hu_dim_5512640106,
@shu_dim_5512640106,
FALSE
);
SET @packaging_5512640106 = LAST_INSERT_ID();
-- Part Number: 8263500575
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '8263500575' LIMIT 1),
@hu_dim_8263500575,
@shu_dim_8263500575,
FALSE
);
SET @packaging_8263500575 = LAST_INSERT_ID();
-- Part Number: 8263500576
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '8263500576' LIMIT 1),
@hu_dim_8263500576,
@shu_dim_8263500576,
FALSE
);
SET @packaging_8263500576 = LAST_INSERT_ID();
-- Part Number: 28523500575
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '28523500575' LIMIT 1),
@hu_dim_28523500575,
@shu_dim_28523500575,
FALSE
);
SET @packaging_28523500575 = LAST_INSERT_ID();
-- Part Number: 28523500576
INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated)
VALUES (
(SELECT id FROM node WHERE name = 'Linde (China) Forklift Truck (Supplier)' LIMIT 1),
(SELECT id FROM material WHERE part_number = '28523500576' LIMIT 1),
@hu_dim_28523500576,
@shu_dim_28523500576,
FALSE
);
SET @packaging_28523500576 = LAST_INSERT_ID();
-- ============================================
-- Packaging Properties
-- ============================================
-- Stackable und Rust Prevention Property Type IDs ermitteln
SET @stackable_type_id = (SELECT id FROM packaging_property_type WHERE external_mapping_id = 'STACKABLE' LIMIT 1);
SET @rust_prevention_type_id = (SELECT id FROM packaging_property_type WHERE external_mapping_id = 'RUST_PREVENTION' LIMIT 1);
-- Part Number: 28152640129 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_28152640129, 'true'),
(@rust_prevention_type_id, @packaging_28152640129, 'false');
-- Part Number: 8222640822 - Stackable: No, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_8222640822, 'false'),
(@rust_prevention_type_id, @packaging_8222640822, 'false');
-- Part Number: 3064540201 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_3064540201, 'true'),
(@rust_prevention_type_id, @packaging_3064540201, 'false');
-- Part Number: 8212640113 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_8212640113, 'true'),
(@rust_prevention_type_id, @packaging_8212640113, 'false');
-- Part Number: 28152643516 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_28152643516, 'true'),
(@rust_prevention_type_id, @packaging_28152643516, 'false');
-- Part Number: 4222640104 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_4222640104, 'true'),
(@rust_prevention_type_id, @packaging_4222640104, 'false');
-- Part Number: 28152643502 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_28152643502, 'true'),
(@rust_prevention_type_id, @packaging_28152643502, 'false');
-- Part Number: 28152640804 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_28152640804, 'true'),
(@rust_prevention_type_id, @packaging_28152640804, 'false');
-- Part Number: 4222640805 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_4222640805, 'true'),
(@rust_prevention_type_id, @packaging_4222640805, 'false');
-- Part Number: 4222640803 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_4222640803, 'true'),
(@rust_prevention_type_id, @packaging_4222640803, 'false');
-- Part Number: 8212640811 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_8212640811, 'true'),
(@rust_prevention_type_id, @packaging_8212640811, 'false');
-- Part Number: 8212640827 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_8212640827, 'true'),
(@rust_prevention_type_id, @packaging_8212640827, 'false');
-- Part Number: 5512640104 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_5512640104, 'true'),
(@rust_prevention_type_id, @packaging_5512640104, 'false');
-- Part Number: 5512640106 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_5512640106, 'true'),
(@rust_prevention_type_id, @packaging_5512640106, 'false');
-- Part Number: 8263500575 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_8263500575, 'true'),
(@rust_prevention_type_id, @packaging_8263500575, 'false');
-- Part Number: 8263500576 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_8263500576, 'true'),
(@rust_prevention_type_id, @packaging_8263500576, 'false');
-- Part Number: 28523500575 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_28523500575, 'true'),
(@rust_prevention_type_id, @packaging_28523500575, 'false');
-- Part Number: 28523500576 - Stackable: Yes, Rust Prevention: No
INSERT INTO packaging_property (packaging_property_type_id, packaging_id, property_value)
VALUES
(@stackable_type_id, @packaging_28523500576, 'true'),
(@rust_prevention_type_id, @packaging_28523500576, 'false');

View file

@ -0,0 +1,9 @@
delete
from lcc_test.node_predecessor_entry
where 1;
delete
from lcc_test.node_predecessor_chain
where 1;
delete
from lcc_test.node
where 1;

File diff suppressed because it is too large Load diff