widlam/dev/implement_rest_mock #231
@@ -36,14 +36,12 @@ public class MockController {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates queried message with given set of data
 | 
			
		||||
     * @param body {@link MockedMessageDto} json representation
 | 
			
		||||
     * @param message {@link MockedMessageDto} json representation
 | 
			
		||||
     * @return confirmation and 200 OK
 | 
			
		||||
     */
 | 
			
		||||
    @SneakyThrows
 | 
			
		||||
    @PutMapping
 | 
			
		||||
    public ResponseEntity<String> updateMessage(@RequestBody String body){
 | 
			
		||||
        ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
        MockedMessageDto message = mapper.readValue(body, MockedMessageDto.class);
 | 
			
		||||
    public ResponseEntity<String> updateMessage(@RequestBody MockedMessageDto message){
 | 
			
		||||
        return klausService.setMockedResponse(message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +1,42 @@
 | 
			
		||||
<script setup>
 | 
			
		||||
import {ref} from 'vue';
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref} from 'vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps(
 | 
			
		||||
    {
 | 
			
		||||
        headersObject : Object
 | 
			
		||||
    } 
 | 
			
		||||
)
 | 
			
		||||
const headerData = ref( props.headersObject )
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits([
 | 
			
		||||
    'update:httpHeaders'
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
const headerData  = ref(props.headersObject)
 | 
			
		||||
const newHeaderName = ref('');
 | 
			
		||||
const newHeaderValue = ref('');
 | 
			
		||||
 | 
			
		||||
function isHeaderEssential(headerName){
 | 
			
		||||
function isHeaderEssential(headerName : string){
 | 
			
		||||
    return headerName == "Keep-Alive" || headerName == "Connection" || headerName == "Date"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setEssentialHeaderStyle(headerName){
 | 
			
		||||
return isHeaderEssential(headerName) ? "text-gray-400" : "text-red-400";
 | 
			
		||||
function setEssentialHeaderStyle(headerName : string){
 | 
			
		||||
    return isHeaderEssential(headerName) ? "text-gray-400" : "text-red-400";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function deleteHeader(index){
 | 
			
		||||
    if(!isHeaderEssential(index)){
 | 
			
		||||
function deleteHeader(index : string){
 | 
			
		||||
    if(!isHeaderEssential(index) && headerData.value != undefined){
 | 
			
		||||
        delete headerData.value[index]
 | 
			
		||||
        emit('update:httpHeaders',headerData.value)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addNewHeader(name, value){
 | 
			
		||||
    headerData.value[name] = value;
 | 
			
		||||
    newHeaderName.value = "";
 | 
			
		||||
    newHeaderValue.value = "";
 | 
			
		||||
function addNewHeader(name : string, value : string){
 | 
			
		||||
    if (headerData.value != undefined){
 | 
			
		||||
        headerData.value[name] = value;
 | 
			
		||||
        newHeaderName.value = "";
 | 
			
		||||
        newHeaderValue.value = "";
 | 
			
		||||
        emit('update:httpHeaders',headerData.value)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, type Ref } from 'vue';
 | 
			
		||||
 | 
			
		||||
interface historyRecord {
 | 
			
		||||
    clientUUID : String,
 | 
			
		||||
    dateTimeStamp: String,
 | 
			
		||||
    headers : Object,
 | 
			
		||||
    httpMethod: String,
 | 
			
		||||
    requestBody: String
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const clientUUID = localStorage.getItem("clientUUID")
 | 
			
		||||
const fetchLink = window.location.protocol + "//" + window.location.hostname + "/mock/api/event";
 | 
			
		||||
const historyRecords : Ref<Array<historyRecord>> = ref([])
 | 
			
		||||
fetch(fetchLink+"/"+clientUUID).then(response => response.json()).then(data => { historyRecords.value = data });
 | 
			
		||||
 | 
			
		||||
function parseTimeStamp(timestamp : String){
 | 
			
		||||
    return timestamp.substring(10,19).replace("T"," ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showHeaders(headers:Object){
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showBody(body : String){
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
    <table class="text-white h-28 w-5/12 text-center border-l-4 border-b-2">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>Time</th>
 | 
			
		||||
            <th>HTTP Method</th>
 | 
			
		||||
            <th>HTTP Headers</th>
 | 
			
		||||
            <th>Request Body</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr v-for="(item , index) in historyRecords" :key="index">
 | 
			
		||||
            <td> {{ parseTimeStamp(item.dateTimeStamp) }} </td>
 | 
			
		||||
            <td> {{ item.httpMethod }} </td>
 | 
			
		||||
            <td> <button @click="showHeaders(item.headers);">Show Headers</button> </td>
 | 
			
		||||
            <td> <button @click="showBody(item.requestBody)">Show Body</button> </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
</template>
 | 
			
		||||
							
								
								
									
										36
									
								
								Frontend/src/components/mock/MockedMessageToastComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Frontend/src/components/mock/MockedMessageToastComponent.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref} from 'vue';
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits([
 | 
			
		||||
    'closed:toast_closed'
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
const props = defineProps(
 | 
			
		||||
    {
 | 
			
		||||
        message: {type: String, required: true},
 | 
			
		||||
        visible: {type: String, required: true},
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
function hideToast(){
 | 
			
		||||
    emit('closed:toast_closed',"hidden")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
    <div id="toast-success" :class="visible" class="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800" role="alert">
 | 
			
		||||
    <div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-green-500 bg-green-100 rounded-lg dark:bg-green-800 dark:text-green-200">
 | 
			
		||||
        <svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path></svg>
 | 
			
		||||
        <span class="sr-only">Check icon</span>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="ml-3 text-sm font-normal">{{ props.message }}</div>
 | 
			
		||||
    <button @click="hideToast"  type="button" class="ml-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700">
 | 
			
		||||
        <span class="sr-only">Close</span>
 | 
			
		||||
        <svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
 | 
			
		||||
    </button>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import {ref, onBeforeMount , type Ref} from 'vue';
 | 
			
		||||
import {ref, type Ref} from 'vue';
 | 
			
		||||
import HeadersComponent from './HeadersComponent.vue';
 | 
			
		||||
import SaveComponent from './SaveComponent.vue';
 | 
			
		||||
 | 
			
		||||
const clientUUID = ref('');
 | 
			
		||||
const host = window.location.protocol + "//" + window.location.hostname + "/mock";
 | 
			
		||||
@@ -21,15 +22,12 @@ const exampleData : mockedMessageData = {
 | 
			
		||||
  httpHeaders: {Connection:"keep-alive"},
 | 
			
		||||
  httpStatus: 200,
 | 
			
		||||
}
 | 
			
		||||
let messageData : Ref<mockedMessageData> = ref(exampleData) ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
onBeforeMount( () => {
 | 
			
		||||
  if ( localStorage.clientUUID != undefined ){
 | 
			
		||||
let messageData : Ref<mockedMessageData> = ref(exampleData);
 | 
			
		||||
if ( localStorage.clientUUID != undefined ){
 | 
			
		||||
    clientUUID.value = localStorage.clientUUID;
 | 
			
		||||
  }
 | 
			
		||||
  fetch(host + '/api/mock/' + clientUUID.value).then( response => response.json() ).then(data => putDataInFields(data));
 | 
			
		||||
} )
 | 
			
		||||
}
 | 
			
		||||
fetch(host + '/api/mock/' + clientUUID.value).then( response => response.json() ).then(data => {putDataInFields(data);  });
 | 
			
		||||
 | 
			
		||||
function putDataInFields(data: mockedMessageData){
 | 
			
		||||
  clientUUID.value = data.clientUUID;
 | 
			
		||||
@@ -41,28 +39,33 @@ function putDataInFields(data: mockedMessageData){
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="flex flex-col w-3/5 text-center gap-6">
 | 
			
		||||
  <div class="flex flex-col w-3/5 text-center dark:text-white gap-6">
 | 
			
		||||
    <div>
 | 
			
		||||
      <label for="link">Link</label><br/>
 | 
			
		||||
    <div class="p-2 border-white border-2">
 | 
			
		||||
      <a class="underline" :href="mockMessageLink">{{ mockMessageLink }}</a>
 | 
			
		||||
    </div>
 | 
			
		||||
      <div class="flex gap-4">
 | 
			
		||||
        <div class="p-2 w-full border-white border-2">
 | 
			
		||||
          <a class="underline" :href="mockMessageLink">{{ mockMessageLink }}</a>
 | 
			
		||||
        </div>
 | 
			
		||||
        <SaveComponent v-bind:message-data="messageData"></SaveComponent>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="flex flex-row w-full gap-64">
 | 
			
		||||
      <div class="w-full">
 | 
			
		||||
        <label for="contentType">Content Type</label><br/>
 | 
			
		||||
        <input class="bg-gray-600 w-full" id="contentType" type="text" :value="messageData.contentType"/>
 | 
			
		||||
        <input  class="bg-gray-600 w-full" id="contentType" type="text" v-model="messageData.contentType"/>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class=" w-full">
 | 
			
		||||
      
 | 
			
		||||
      <div class="w-full">
 | 
			
		||||
        <label for="httpStatus">HttpStatus</label><br/>
 | 
			
		||||
        <input class="bg-gray-600 w-full" id="httpStatus" type="text" :value="messageData.httpStatus"/>
 | 
			
		||||
        <input class="bg-gray-600 w-full" id="httpStatus" type="text" v-model="messageData.httpStatus"/>
 | 
			
		||||
      </div>
 | 
			
		||||
      
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="flex flex-col">
 | 
			
		||||
      <label for="messageBody">Body</label>
 | 
			
		||||
      <textarea class="bg-gray-600 h-64" id="messageBody" :value="messageData.messageBody.toString()"></textarea>
 | 
			
		||||
      <textarea class="bg-gray-600 h-64" id="messageBody" v-model="messageData.messageBody"></textarea>
 | 
			
		||||
    </div>
 | 
			
		||||
    <HeadersComponent :key="JSON.stringify(messageData.httpHeaders)" :headers-object="messageData.httpHeaders"></HeadersComponent>
 | 
			
		||||
    <HeadersComponent @update:httpHeaders="(newHeaders: object) => {messageData.httpHeaders = newHeaders }" :key="JSON.stringify(messageData.httpHeaders)" :headers-object="messageData.httpHeaders"></HeadersComponent>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								Frontend/src/components/mock/SaveComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Frontend/src/components/mock/SaveComponent.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import MockedMessageToastComponent from './MockedMessageToastComponent.vue';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const props = defineProps(
 | 
			
		||||
    {
 | 
			
		||||
    messageData : {type: Object, required:true}
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const message = ref('');
 | 
			
		||||
const visible = ref('hidden');
 | 
			
		||||
const fetchLink = window.location.protocol + "//" + window.location.hostname + "/mock/api/mock"
 | 
			
		||||
 | 
			
		||||
function prepareAndSendData(){
 | 
			
		||||
    if (props.messageData != null|| props.messageData != undefined ){
 | 
			
		||||
        fetch(fetchLink, { method: "put", body:JSON.stringify(props.messageData), headers: { "Content-Type" : "application/json" }})
 | 
			
		||||
        .then( response => response.text() )
 | 
			
		||||
        .then( data =>  {message.value = data} )
 | 
			
		||||
        .catch(exception => {message.value = exception})
 | 
			
		||||
 | 
			
		||||
        showToast();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showToast(){
 | 
			
		||||
    visible.value = "visible";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function hideToast(){
 | 
			
		||||
    visible.value = "hidden";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
    <button @click="prepareAndSendData()" class="w-2/12 tool-button">Save</button>
 | 
			
		||||
 | 
			
		||||
    <div class="fixed bottom-5 right-12">
 | 
			
		||||
        <MockedMessageToastComponent @closed:toast_closed="hideToast()" v-bind:visible="visible" v-bind:message="message"/>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -34,11 +34,6 @@ const routes = [
 | 
			
		||||
    name: 'xslt',
 | 
			
		||||
    component: () => xsltTool
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    path: '/xml/xpath',
 | 
			
		||||
    name: 'xpath',
 | 
			
		||||
    component: () => restMock
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    path: '/rest/mock',
 | 
			
		||||
    name: 'restmock',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,14 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import RestMockMessageComponent from '@components/mock/RestMockMessageComponent.vue'
 | 
			
		||||
import mockedMessageData from '@components/mock/RestMockMessageComponent.vue'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    name:"RestMockView",
 | 
			
		||||
    components: {RestMockMessageComponent}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
import HistoryComponent from '@components/mock/HistoryComponent.vue'
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="flex w-full h-screen items-center flex-col">
 | 
			
		||||
    <div class="flex gap-6 w-full h-screen">
 | 
			
		||||
        <RestMockMessageComponent></RestMockMessageComponent>
 | 
			
		||||
        <HistoryComponent></HistoryComponent>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user