@Test
  public void walktrough() throws Exception {
    mockMvc.perform(get("/specs/{specId}", "notexists")).andExpect(status().is4xxClientError());

    ObjectMapper mapper = new ObjectMapper();

    SpecDTO specDTO = new SpecDTO(SPEC_ID, SPEC_NAME);
    mockMvc
        .perform(
            post("/specs")
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .content(mapper.writeValueAsBytes(specDTO)))
        .andExpect(status().isCreated())
        .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
        .andExpect(jsonPath("$.specId", is(SPEC_ID)))
        .andExpect(jsonPath("$.name", is(SPEC_NAME)));

    mockMvc
        .perform(get("/specs/{specId}", SPEC_ID))
        .andExpect(status().isOk())
        .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
        .andExpect(jsonPath("$.name").value(SPEC_NAME));

    EntityDTO entityOneDTO = new EntityDTO(SPEC_ID, ENTITY_ONE_NAME, false);
    MvcResult result =
        mockMvc
            .perform(
                post("/specs/{specId}/datamodel/entities", SPEC_ID)
                    .contentType(MediaType.APPLICATION_JSON_VALUE)
                    .content(mapper.writeValueAsBytes(entityOneDTO)))
            .andExpect(status().isCreated())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
            .andExpect(jsonPath("$.name").value(ENTITY_ONE_NAME))
            .andExpect(jsonPath("$.exists").value(false))
            .andReturn();
    entityOneDTO = mapper.readValue(result.getResponse().getContentAsString(), EntityDTO.class);

    EntityDTO entityTwoDTO = new EntityDTO(SPEC_ID, "entityTwo", false);
    result =
        mockMvc
            .perform(
                post("/specs/{specId}/datamodel/entities", SPEC_ID)
                    .contentType(MediaType.APPLICATION_JSON_VALUE)
                    .content(mapper.writeValueAsBytes(entityTwoDTO)))
            .andExpect(status().isCreated())
            .andReturn();
    entityTwoDTO = mapper.readValue(result.getResponse().getContentAsString(), EntityDTO.class);

    AttributeDTO attributeOneDTO =
        new AttributeDTO(
            SPEC_ID,
            ProductType.ATTRIBUTE.name(),
            entityOneDTO.getExtId(),
            null,
            "att1",
            "Boolean",
            true);
    result =
        mockMvc
            .perform(
                post("/specs/{specId}/datamodel/attributes", SPEC_ID)
                    .contentType(MediaType.APPLICATION_JSON_VALUE)
                    .content(mapper.writeValueAsBytes(attributeOneDTO)))
            .andExpect(status().isCreated())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
            .andExpect(jsonPath("$.name").value("att1"))
            .andExpect(jsonPath("$.type").value("Boolean"))
            .andExpect(jsonPath("$.isMandatory").value(true))
            .andReturn();
    attributeOneDTO =
        mapper.readValue(result.getResponse().getContentAsString(), AttributeDTO.class);

    AttributeDTO attributeTwoDTO =
        new AttributeDTO(
            SPEC_ID,
            ProductType.ATTRIBUTE.name(),
            entityOneDTO.getExtId(),
            null,
            ATTRIBUTE_TWO_NAME_STRING,
            "String",
            false);
    mockMvc
        .perform(
            post("/specs/{specId}/datamodel/attributes", SPEC_ID)
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .content(mapper.writeValueAsBytes(attributeTwoDTO)))
        .andExpect(status().isCreated());

    AttributeDTO attributeThreeDTO =
        new AttributeDTO(
            SPEC_ID,
            ProductType.ATTRIBUTE.name(),
            entityOneDTO.getExtId(),
            null,
            "att3",
            "Number",
            true);
    mockMvc
        .perform(
            post("/specs/{specId}/datamodel/attributes", SPEC_ID)
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .content(mapper.writeValueAsBytes(attributeThreeDTO)))
        .andExpect(status().isCreated());

    RelationDTO relationDTO =
        new RelationDTO(
            SPEC_ID,
            "relation name",
            entityOneDTO.getExtId(),
            "first",
            "1",
            entityTwoDTO.getExtId(),
            "second",
            "*");
    mockMvc
        .perform(
            post("/specs/{specId}/datamodel/relations", SPEC_ID)
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .content(mapper.writeValueAsBytes(relationDTO)))
        .andExpect(status().isCreated());

    ExpressionDTO expressionDTO =
        new ExpressionDTO(
            SPEC_ID,
            ComparisonOperator.GREATER,
            new ExpressionDTO(SPEC_ID, ExpressionAtom.STRING, "today"),
            new ExpressionDTO(
                SPEC_ID,
                ExpressionAtom.ATT_VALUE,
                ENTITY_ONE_NAME + "." + ATTRIBUTE_TWO_NAME_STRING));
    RuleDTO ruleDTO = new RuleDTO(SPEC_ID, ENTITY_ONE_NAME, "myRule", expressionDTO);
    mockMvc
        .perform(
            post("/specs/{specId}/datamodel/rules", SPEC_ID)
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .content(mapper.writeValueAsBytes(ruleDTO)))
        .andExpect(status().isCreated());
  }