diff --git a/README.md b/README.md
index f809999..9e27864 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,5 @@
-# PiS-Hello
-Business card holder app
-
-Timeline:
-17.11 - 1 stage
-13.12 - 2 stage
-03.01 - 3 stage
-24.01 - 4 stage
+# Hello
+Application for holding and sharing business cards
### Server
@@ -110,7 +104,8 @@ npm start
```
After that, you can run the app on an android/iOS device emulator or directly on your mobile device using Expo Go app.
-Links:
+Useful links:
* [Jira Board](https://hello-pis.atlassian.net/jira/software/projects/HPIS/boards/1)
-* [CI documentation](https://circleci.com/docs/2.0/configuration-reference)
-* [Documentation](https://www.overleaf.com/read/gyhnrhzrhfxw)
+* [CI documentation](https://docs.github.com/en/actions)
+* [ORM documentation](https://github.com/JetBrains/Exposed/wiki)
+* [Project documentation](https://www.overleaf.com/read/gyhnrhzrhfxw)
diff --git a/frontend/.expo-shared/assets.json b/application/.expo-shared/assets.json
similarity index 100%
rename from frontend/.expo-shared/assets.json
rename to application/.expo-shared/assets.json
diff --git a/frontend/.gitignore b/application/.gitignore
similarity index 100%
rename from frontend/.gitignore
rename to application/.gitignore
diff --git a/frontend/App.js b/application/App.js
similarity index 88%
rename from frontend/App.js
rename to application/App.js
index ecd3cc2..4152790 100644
--- a/frontend/App.js
+++ b/application/App.js
@@ -2,12 +2,9 @@ import React, { useState, useEffect } from 'react';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import * as Font from 'expo-font';
-import AppLoading from 'expo-app-loading';
import ReduxThunk from 'redux-thunk';
-
-import { StyleSheet, SafeAreaView, View } from 'react-native';
+import { View } from 'react-native';
import AppNavigation from './navigation/AppNavigation';
-
import authReducer from './reducers/auth';
import searchReducer from './reducers/search';
import businessCardsReducer from './reducers/businessCards';
@@ -50,7 +47,7 @@ export default function App() {
if (!fontLoaded) {
return (
-
+
);
}
@@ -77,11 +74,3 @@ export default function App() {
// )
// }
}
-
-const styles = StyleSheet.create({
- root: {
- flex: 1,
- backgroundColor: '#F9FBFC'
- }
-});
-
diff --git a/frontend/actions/auth.js b/application/actions/auth.js
similarity index 94%
rename from frontend/actions/auth.js
rename to application/actions/auth.js
index f4a2421..af56e76 100644
--- a/frontend/actions/auth.js
+++ b/application/actions/auth.js
@@ -54,11 +54,11 @@ export const signIn = (login, password) => {
console.log(`response status: ${response.status}`);
let token = null;
- if(response.status == 200) {
+ if(response.status === 200) {
const respData = await response.json();
token = respData.token;
console.log(`Received token: ${token}`);
- } else if (response.status == 403) {
+ } else if (response.status === 403) {
console.log(`Request rejected. Wrong credentials.`);
} else {
console.log(`Request rejected for unknown reason.`);
@@ -120,11 +120,11 @@ export const logInWithGoogle = googleToken => {
console.log(`response status: ${second_response.status}`);
let token = null;
- if(first_response.status == 200) {
+ if(first_response.status === 200) {
const respData = await second_response.json();
token = respData.token;
console.log(`Received token: ${token}`);
- } else if (first_response.status == 403) {
+ } else if (first_response.status === 403) {
console.log(`Request rejected. Wrong credentials.`);
} else {
console.log(`Request rejected for unknown reason.`);
@@ -138,7 +138,7 @@ export const register = (login, password, passwordRepeat) => {
return async dispatch => {
console.log('registering...');
- if (password != passwordRepeat) {
+ if (password !== passwordRepeat) {
console.log('Passwords are not the same. Please try again.');
return dispatch({ type: REGISTER, outcome: null });
}
@@ -172,10 +172,10 @@ export const register = (login, password, passwordRepeat) => {
}
console.log(`response status: ${response.status}`);
- if(response.status == 201) {
+ if(response.status === 201) {
console.log(`Registration successful!`);
dispatch({ type: REGISTER, outcome: true });
- } else if (response.status == 409) {
+ } else if (response.status === 409) {
console.log(`Request rejected. Wrong credentials. Try changing your login.`);
dispatch({ type: REGISTER, outcome: false });
} else {
@@ -192,10 +192,10 @@ export const checkLogin = (login) => {
`http://${serverAddress.address}:8080/check?name=${login}`
);
console.log(`response status: ${response.status}`);
- if(response.status == 200) {
+ if(response.status === 200) {
console.log(`Login available`);
dispatch({ type: CHECK_LOGIN, outcome: true });
- } else if (response.status == 409) {
+ } else if (response.status === 409) {
console.log(`User with this name already exists.`);
dispatch({ type: CHECK_LOGIN, outcome: false });
} else {
diff --git a/frontend/actions/businessCards.js b/application/actions/businessCards.js
similarity index 92%
rename from frontend/actions/businessCards.js
rename to application/actions/businessCards.js
index 542b054..8e66bb8 100644
--- a/frontend/actions/businessCards.js
+++ b/application/actions/businessCards.js
@@ -1,6 +1,4 @@
-import { SHA256 } from 'crypto-js';
-
-import serverAddress from '../constants/serverAddress';
+import { serverAddress } from '../constants/serverAddress';
export const ADD_CARD = 'ADD_CARD';
@@ -57,7 +55,7 @@ export const addBusinessCard = (photo, ownerName) => {
console.log(`response status: ${response.status}`);
- const outcome = response.status === 201 ? true : false;
+ const outcome = response.status === 201;
dispatch({ type: ADD_CARD, outcome: outcome });
}
diff --git a/frontend/actions/edit.js b/application/actions/edit.js
similarity index 89%
rename from frontend/actions/edit.js
rename to application/actions/edit.js
index 06f37fd..e143021 100644
--- a/frontend/actions/edit.js
+++ b/application/actions/edit.js
@@ -22,7 +22,7 @@ async function fetchWithTimeout(resource, options = {}) {
}
};
-export const editCardData = (idU, company, name, phone, email, category, mode) => {
+export const setCardData = (idU, company, name, phone, email, category, mode) => {
return async dispatch => {
const id = parseInt(idU);
@@ -33,7 +33,7 @@ export const editCardData = (idU, company, name, phone, email, category, mode) =
try {
response = await fetchWithTimeout(
- `http://${serverAddress.address}:8080/card/changedata`,
+ `http://${serverAddress.address}:8080/card/set`,
{
method: 'POST',
headers: {
@@ -60,10 +60,10 @@ export const editCardData = (idU, company, name, phone, email, category, mode) =
}
console.log(`Response status: ${response.status}`);
- if(response.status == 200) {
+ if(response.status === 200) {
console.log(`Update data successfully`);
dispatch({ type: EDIT_DATA, outcome: true });
- } else if (response.status == 404) {
+ } else if (response.status === 404) {
console.log(`Request rejected. Wrong credentials.`);
dispatch({ type: EDIT_DATA, outcome: false });
} else {
diff --git a/frontend/actions/search.js b/application/actions/search.js
similarity index 94%
rename from frontend/actions/search.js
rename to application/actions/search.js
index e77bfcd..fef5053 100644
--- a/frontend/actions/search.js
+++ b/application/actions/search.js
@@ -37,9 +37,9 @@ export const getMyBusinessCards = (username) => {
console.log(`response status: ${response.status}`);
var respData = [];
- if(response.status == 200) {
+ if(response.status === 200) {
respData = await response.json();
- } else if (response.status == 404) {
+ } else if (response.status === 404) {
console.log(`No business cards found.`);
} else {
console.log(`Request rejected for unknown reason.`);
@@ -80,9 +80,9 @@ export const searchBusinessCards = ({id=null, profession=null, ownername=null})
console.log(`response status: ${response.status}`);
var respData = [];
- if(response.status == 200) {
+ if(response.status === 200) {
respData = await response.json();
- } else if (response.status == 404) {
+ } else if (response.status === 404) {
console.log(`No business cards found.`);
} else {
console.log(`Request rejected for unknown reason.`);
diff --git a/frontend/app.json b/application/app.json
similarity index 95%
rename from frontend/app.json
rename to application/app.json
index 6df1bf4..758f59d 100644
--- a/frontend/app.json
+++ b/application/app.json
@@ -33,7 +33,7 @@
"foregroundImage": "./assets/business-card.png",
"backgroundColor": "#FFFFFF"
},
- "package": "com.pishello.hellopis"
+ "package": "com.hello.hello"
},
"web": {
"favicon": "./assets/business-card.png"
diff --git a/frontend/assets/adaptive-icon.png b/application/assets/adaptive-icon.png
similarity index 100%
rename from frontend/assets/adaptive-icon.png
rename to application/assets/adaptive-icon.png
diff --git a/frontend/assets/business-card.png b/application/assets/business-card.png
similarity index 100%
rename from frontend/assets/business-card.png
rename to application/assets/business-card.png
diff --git a/frontend/assets/favicon.png b/application/assets/favicon.png
similarity index 100%
rename from frontend/assets/favicon.png
rename to application/assets/favicon.png
diff --git a/frontend/assets/fonts/OpenSans-Bold.ttf b/application/assets/fonts/OpenSans-Bold.ttf
similarity index 100%
rename from frontend/assets/fonts/OpenSans-Bold.ttf
rename to application/assets/fonts/OpenSans-Bold.ttf
diff --git a/frontend/assets/fonts/OpenSans-Regular.ttf b/application/assets/fonts/OpenSans-Regular.ttf
similarity index 100%
rename from frontend/assets/fonts/OpenSans-Regular.ttf
rename to application/assets/fonts/OpenSans-Regular.ttf
diff --git a/frontend/assets/fonts/Roboto-Medium.ttf b/application/assets/fonts/Roboto-Medium.ttf
similarity index 100%
rename from frontend/assets/fonts/Roboto-Medium.ttf
rename to application/assets/fonts/Roboto-Medium.ttf
diff --git a/frontend/assets/fonts/roboto.zip b/application/assets/fonts/roboto.zip
similarity index 100%
rename from frontend/assets/fonts/roboto.zip
rename to application/assets/fonts/roboto.zip
diff --git a/frontend/assets/google-logo.png b/application/assets/google-logo.png
similarity index 100%
rename from frontend/assets/google-logo.png
rename to application/assets/google-logo.png
diff --git a/frontend/assets/gradient.png b/application/assets/gradient.png
similarity index 100%
rename from frontend/assets/gradient.png
rename to application/assets/gradient.png
diff --git a/frontend/assets/icon.png b/application/assets/icon.png
similarity index 100%
rename from frontend/assets/icon.png
rename to application/assets/icon.png
diff --git a/frontend/assets/purple-bg.jpg b/application/assets/purple-bg.jpg
similarity index 100%
rename from frontend/assets/purple-bg.jpg
rename to application/assets/purple-bg.jpg
diff --git a/frontend/assets/splash.png b/application/assets/splash.png
similarity index 100%
rename from frontend/assets/splash.png
rename to application/assets/splash.png
diff --git a/frontend/babel.config.js b/application/babel.config.js
similarity index 100%
rename from frontend/babel.config.js
rename to application/babel.config.js
diff --git a/frontend/components/Card.js b/application/components/Card.js
similarity index 100%
rename from frontend/components/Card.js
rename to application/components/Card.js
diff --git a/frontend/components/GoogleSignInButton.js b/application/components/GoogleSignInButton.js
similarity index 100%
rename from frontend/components/GoogleSignInButton.js
rename to application/components/GoogleSignInButton.js
diff --git a/frontend/components/LoadingScreenModal.js b/application/components/LoadingScreenModal.js
similarity index 93%
rename from frontend/components/LoadingScreenModal.js
rename to application/components/LoadingScreenModal.js
index 61df0ed..900acff 100644
--- a/frontend/components/LoadingScreenModal.js
+++ b/application/components/LoadingScreenModal.js
@@ -14,7 +14,3 @@ export default function LoadingScreenModal({amIVisible}){
);
};
-
-const styles = StyleSheet.create({
-
-})
\ No newline at end of file
diff --git a/frontend/components/MenuItem.js b/application/components/MenuItem.js
similarity index 100%
rename from frontend/components/MenuItem.js
rename to application/components/MenuItem.js
diff --git a/frontend/components/OverscreenModal.js b/application/components/OverscreenModal.js
similarity index 100%
rename from frontend/components/OverscreenModal.js
rename to application/components/OverscreenModal.js
diff --git a/frontend/navigation/AppNavigation.js b/application/navigation/AppNavigation.js
similarity index 100%
rename from frontend/navigation/AppNavigation.js
rename to application/navigation/AppNavigation.js
diff --git a/frontend/navigation/futureAppNavigator.js b/application/navigation/futureAppNavigator.js
similarity index 100%
rename from frontend/navigation/futureAppNavigator.js
rename to application/navigation/futureAppNavigator.js
diff --git a/frontend/package.json b/application/package.json
similarity index 98%
rename from frontend/package.json
rename to application/package.json
index 305620b..f207b9e 100644
--- a/frontend/package.json
+++ b/application/package.json
@@ -1,5 +1,5 @@
{
- "name": "pis-front",
+ "name": "hello",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
diff --git a/frontend/reducers/auth.js b/application/reducers/auth.js
similarity index 100%
rename from frontend/reducers/auth.js
rename to application/reducers/auth.js
diff --git a/frontend/reducers/businessCards.js b/application/reducers/businessCards.js
similarity index 100%
rename from frontend/reducers/businessCards.js
rename to application/reducers/businessCards.js
diff --git a/frontend/reducers/edit.js b/application/reducers/edit.js
similarity index 100%
rename from frontend/reducers/edit.js
rename to application/reducers/edit.js
diff --git a/frontend/reducers/search.js b/application/reducers/search.js
similarity index 100%
rename from frontend/reducers/search.js
rename to application/reducers/search.js
diff --git a/frontend/screens/CameraScreen.js b/application/screens/CameraScreen.js
similarity index 99%
rename from frontend/screens/CameraScreen.js
rename to application/screens/CameraScreen.js
index c6f59c3..7736ffd 100644
--- a/frontend/screens/CameraScreen.js
+++ b/application/screens/CameraScreen.js
@@ -2,7 +2,6 @@ import React, { useEffect, useState } from 'react';
import { View, StyleSheet, Text, Image, Alert, TouchableOpacity, Dimensions } from 'react-native';
import { Camera } from 'expo-camera';
import { AntDesign } from '@expo/vector-icons';
-import * as ScreenOrientation from 'expo-screen-orientation';
import * as businessCardsActions from '../actions/businessCards';
import LoadingScreenModal from '../components/LoadingScreenModal';
import OverscreenModal from '../components/OverscreenModal';
diff --git a/frontend/screens/EditCardScreen.js b/application/screens/EditCardScreen.js
similarity index 91%
rename from frontend/screens/EditCardScreen.js
rename to application/screens/EditCardScreen.js
index 82cac72..b7a0a3a 100644
--- a/frontend/screens/EditCardScreen.js
+++ b/application/screens/EditCardScreen.js
@@ -1,14 +1,10 @@
-import React, {useDebugValue, useEffect, useState} from 'react';
-import { View, StyleSheet, Text, TextInput, Image, useWindowDimensions, ScrollView, ImageBackground, Pressable, TouchableOpacity, Button } from 'react-native';
-import GoogleSignInButton from '../components/GoogleSignInButton';
-import { CommonActions, useNavigation, useRoute} from '@react-navigation/core';
+import React, {useEffect, useState} from 'react';
+import { View, StyleSheet, Text, TextInput, Image, TouchableOpacity } from 'react-native';
import Card from '../components/Card';
import OverscreenModal from '../components/OverscreenModal';
import LoadingScreenModal from '../components/LoadingScreenModal';
-import backgroundImage from '../assets/purple-bg.jpg';
import purple from '../assets/gradient.png';
import { useDispatch, useSelector } from 'react-redux';
-import { logInAsync } from 'expo-google-app-auth';
import * as authActions from '../actions/edit';
export default function EditCardScreen({ route, navigation }) {
@@ -36,7 +32,7 @@ export default function EditCardScreen({ route, navigation }) {
return;
if (editOutcome == null)
return;
- if (editOutcome == true)
+ if (editOutcome === true)
{
dispatch(authActions.editFinished());
navigation.navigate('HomeScreen');
@@ -46,10 +42,10 @@ export default function EditCardScreen({ route, navigation }) {
}, [editResponse]);
- const onChangeDataPressed = async () => {
+ const onSetDataPressed = async () => {
setWaitingForResponse(true);
- dispatch(authActions.editCardData(photoId, company, name, phone, email, category, mode));
+ dispatch(authActions.setCardData(photoId, company, name, phone, email, category, mode));
}
const onReturnPressed = () => {
@@ -57,7 +53,7 @@ export default function EditCardScreen({ route, navigation }) {
}
function onChangeModePressed () {
- if (mode == 'PRIVATE') {
+ if (mode === 'PRIVATE') {
setMode('PUBLIC')
}
else{
@@ -139,7 +135,7 @@ export default function EditCardScreen({ route, navigation }) {
-
+
Wprowadź zmiany
diff --git a/frontend/screens/GalleryScreen.js b/application/screens/GalleryScreen.js
similarity index 97%
rename from frontend/screens/GalleryScreen.js
rename to application/screens/GalleryScreen.js
index 1b8daf1..0ad319e 100644
--- a/frontend/screens/GalleryScreen.js
+++ b/application/screens/GalleryScreen.js
@@ -1,5 +1,5 @@
import React, {useEffect, useState} from 'react';
-import {Button, View, StyleSheet, Image, Dimensions, TouchableOpacity, Text, Alert} from 'react-native';
+import { View, StyleSheet, Image, TouchableOpacity, Alert } from 'react-native';
import { useNavigation } from '@react-navigation/core';
import { useDispatch, useSelector } from 'react-redux';
import * as ImagePicker from 'expo-image-picker';
@@ -7,7 +7,6 @@ import {AntDesign} from "@expo/vector-icons";
import LoadingScreenModal from "../components/LoadingScreenModal";
import OverscreenModal from "../components/OverscreenModal";
import * as businessCardsActions from "../actions/businessCards";
-import {Camera} from "expo-camera";
export default function GalleryScreen() {
const navigation = useNavigation();
diff --git a/frontend/screens/HomeScreen.js b/application/screens/HomeScreen.js
similarity index 94%
rename from frontend/screens/HomeScreen.js
rename to application/screens/HomeScreen.js
index 21b5042..3e55b39 100644
--- a/frontend/screens/HomeScreen.js
+++ b/application/screens/HomeScreen.js
@@ -1,8 +1,8 @@
import { StatusBar } from 'expo-status-bar';
-import React, { useState, useEffect } from 'react';
+import React from 'react';
import { StyleSheet, Text, View, ScrollView } from 'react-native';
import { useNavigation } from '@react-navigation/core';
-import { useSelector, useDispatch } from 'react-redux';
+import { useSelector } from 'react-redux';
import MenuItem from '../components/MenuItem';
export default function HomeScreen() {
diff --git a/frontend/screens/MyBusinessCardsScreen.js b/application/screens/MyBusinessCardsScreen.js
similarity index 99%
rename from frontend/screens/MyBusinessCardsScreen.js
rename to application/screens/MyBusinessCardsScreen.js
index d0e6532..a88fc80 100644
--- a/frontend/screens/MyBusinessCardsScreen.js
+++ b/application/screens/MyBusinessCardsScreen.js
@@ -23,7 +23,7 @@ const MyBusinessCardsScreen = props => {
await dispatch(searchActions.getMyBusinessCards(username));
console.log(`Fetched my business cards`);
setWaitingForResponse(false);
- };
+ }
useEffect(() => {
if (getMyCardsTimestamp === undefined)
diff --git a/frontend/screens/SearchBusinessCardsScreen.js b/application/screens/SearchBusinessCardsScreen.js
similarity index 97%
rename from frontend/screens/SearchBusinessCardsScreen.js
rename to application/screens/SearchBusinessCardsScreen.js
index 1b375dd..805671f 100644
--- a/frontend/screens/SearchBusinessCardsScreen.js
+++ b/application/screens/SearchBusinessCardsScreen.js
@@ -1,9 +1,8 @@
import React, { useEffect, useState } from 'react';
-import { View, StyleSheet, Text, Image, TouchableOpacity, ImageBackground, Dimensions, FlatList, TextInput } from 'react-native';
+import { View, StyleSheet, Text, Image, TouchableOpacity, FlatList, TextInput } from 'react-native';
import { AntDesign } from '@expo/vector-icons';
import { useNavigation } from '@react-navigation/core';
import { useSelector, useDispatch } from 'react-redux';
-// import * as ScreenOrientation from 'expo-screen-orientation';
import * as searchActions from '../actions/search';
import serverAddress from '../constants/serverAddress';
import LoadingScreenModal from '../components/LoadingScreenModal';
@@ -179,10 +178,9 @@ const styles = StyleSheet.create({
},
searchBar: {
flexGrow: 1,
- backgroundColor: 'magenta',
+ backgroundColor: 'white',
borderRadius: 10,
marginHorizontal: 5,
- backgroundColor: 'white',
elevation: 3,
padding: 10,
fontSize: 18,
diff --git a/frontend/screens/login/RegisterScreen.js b/application/screens/login/RegisterScreen.js
similarity index 97%
rename from frontend/screens/login/RegisterScreen.js
rename to application/screens/login/RegisterScreen.js
index dd43ea6..09ba355 100644
--- a/frontend/screens/login/RegisterScreen.js
+++ b/application/screens/login/RegisterScreen.js
@@ -1,9 +1,8 @@
import React, { useEffect, useState } from 'react';
-import { View, StyleSheet, Text, TextInput, ScrollView, Image, ImageBackground, TouchableOpacity, StatusBar } from 'react-native';
+import { View, StyleSheet, Text, TextInput, ScrollView, Image, TouchableOpacity, StatusBar } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
import { useNavigation } from '@react-navigation/core';
import gradient from '../../assets/purple-bg.jpg';
-import purple from '../../assets/gradient.png';
import Card from '../../components/Card';
import OverscreenModal from '../../components/OverscreenModal';
import LoadingScreenModal from '../../components/LoadingScreenModal';
@@ -27,7 +26,7 @@ export default function RegisterScreen() {
setWaitingForResponse(false);
if (registerResponse == null)
return;
- if (registerOutcome == true)
+ if (registerOutcome === true)
setSuccessModalVisible(true);
else
setFailureModalVisible(true);
diff --git a/frontend/screens/login/SignInScreen.js b/application/screens/login/SignInScreen.js
similarity index 97%
rename from frontend/screens/login/SignInScreen.js
rename to application/screens/login/SignInScreen.js
index 3774df9..ac14dc2 100644
--- a/frontend/screens/login/SignInScreen.js
+++ b/application/screens/login/SignInScreen.js
@@ -1,4 +1,4 @@
-import React, {useDebugValue, useEffect, useState} from 'react';
+import React, {useEffect, useState} from 'react';
import { View, StyleSheet, Text, TextInput, Image, TouchableOpacity } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import GoogleSignInButton from '../../components/GoogleSignInButton';
@@ -7,9 +7,7 @@ import Card from '../../components/Card';
import OverscreenModal from '../../components/OverscreenModal';
import LoadingScreenModal from '../../components/LoadingScreenModal';
import backgroundImage from '../../assets/purple-bg.jpg';
-import purple from '../../assets/gradient.png';
import { useDispatch, useSelector } from 'react-redux';
-import { logInAsync } from 'expo-google-app-auth';
import * as authActions from '../../actions/auth';
export default function SignInScreen() {
diff --git a/commit-msg b/commit-msg
index fe0e6d9..64ffb62 100644
--- a/commit-msg
+++ b/commit-msg
@@ -2,12 +2,12 @@
# To enable this hook, copy locally this file and move to ".git/hooks/commit-msg".
export MESSAGE=$(<$1)
-export JIRA_ISSUE_TAG='HPIS-([0-9]*)'
+export GITHUB_ISSUE_TAG='HELL-([0-9]*)'
-if [[ $MESSAGE =~ $JIRA_ISSUE_TAG ]]; then
- echo -e "\e[32mYes! It contains a JIRA issue!\e[0m"
+if [[ $MESSAGE =~ GITHUB_ISSUE_TAG ]]; then
+ echo -e "\e[32mYes! It contains a GitHub issue!\e[0m"
exit 0;
fi
-echo -e "\e[31mOh no... You forgot to add a JIRA issue number!\e[0m";
+echo -e "\e[31mOh no... You forgot to add a GitHub issue number!\e[0m";
exit 1;
\ No newline at end of file
diff --git a/frontend/constants/Colors.js b/frontend/constants/Colors.js
deleted file mode 100644
index 0624c4e..0000000
--- a/frontend/constants/Colors.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default {
- primary: '#C2185B',
- accent: '#FFC107'
-};
\ No newline at end of file
diff --git a/server/build.gradle.kts b/server/build.gradle.kts
index 9a6b610..93883fa 100644
--- a/server/build.gradle.kts
+++ b/server/build.gradle.kts
@@ -13,7 +13,7 @@ plugins {
jacoco
}
-group = "pis-hello"
+group = "hello"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
@@ -25,11 +25,15 @@ dependencies {
val springBootVersion = "2.6.2"
val jacocoVersion = "0.8.7"
val sqliteJDBCVersion = "3.36.0.2"
+ val exposedVersion = "0.37.3"
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
+ implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
+ implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
+ implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
+ implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
implementation("org.springframework.boot:spring-boot-starter:$springBootVersion")
- implementation("org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion")
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
implementation("org.xerial:sqlite-jdbc:$sqliteJDBCVersion")
implementation("org.jacoco:org.jacoco.core:$jacocoVersion")
diff --git a/server/src/main/kotlin/pishello/hello/HelloApplication.kt b/server/src/main/kotlin/hello/hello/HelloApplication.kt
similarity index 55%
rename from server/src/main/kotlin/pishello/hello/HelloApplication.kt
rename to server/src/main/kotlin/hello/hello/HelloApplication.kt
index 68d1205..0272139 100644
--- a/server/src/main/kotlin/pishello/hello/HelloApplication.kt
+++ b/server/src/main/kotlin/hello/hello/HelloApplication.kt
@@ -1,5 +1,6 @@
-package pishello.hello
+package hello.hello
+import hello.hello.adapters.persistence.database.init
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@@ -7,5 +8,6 @@ import org.springframework.boot.runApplication
class HelloApplication
fun main(args: Array) {
- runApplication(*args)
+ val context = runApplication(*args)
+ init(context.environment)
}
diff --git a/server/src/main/kotlin/pishello/hello/api/AuthEndpoint.kt b/server/src/main/kotlin/hello/hello/adapters/api/AuthEndpoint.kt
similarity index 68%
rename from server/src/main/kotlin/pishello/hello/api/AuthEndpoint.kt
rename to server/src/main/kotlin/hello/hello/adapters/api/AuthEndpoint.kt
index 578a103..abaf0cb 100644
--- a/server/src/main/kotlin/pishello/hello/api/AuthEndpoint.kt
+++ b/server/src/main/kotlin/hello/hello/adapters/api/AuthEndpoint.kt
@@ -1,16 +1,21 @@
-package pishello.hello.api
+package hello.hello.adapters.api
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
-import pishello.hello.persistence.database.entities.Token
-import pishello.hello.persistence.database.ports.TokenPort
-import pishello.hello.persistence.database.ports.UserPort
+import hello.hello.adapters.persistence.database.adapters.TokenAdapter
+import hello.hello.adapters.persistence.database.adapters.UserAdapter
+import hello.hello.domain.models.Token
+import hello.hello.domain.ports.TokenPort
+import hello.hello.domain.ports.UserPort
data class LoginRequest(val name: String, val password: String)
@RestController
-class AuthEndpoint(val userPort: UserPort, val tokenPort: TokenPort) {
+class AuthEndpoint {
+ val userPort: UserPort = UserAdapter()
+ val tokenPort: TokenPort = TokenAdapter()
+
@GetMapping("/check")
fun check(@RequestParam name: String): ResponseEntity {
return if (userPort.checkIfUserExists(name)) {
@@ -22,7 +27,7 @@ class AuthEndpoint(val userPort: UserPort, val tokenPort: TokenPort) {
@PostMapping("/register", consumes = ["application/json"])
fun register(@RequestBody request: LoginRequest): ResponseEntity {
return if (!userPort.checkIfUserExists(request.name)) {
- userPort.createNewUser(request.name, request.password)
+ userPort.create(request.name, request.password)
ResponseEntity(HttpStatus.CREATED)
} else
ResponseEntity(HttpStatus.CONFLICT)
@@ -32,7 +37,7 @@ class AuthEndpoint(val userPort: UserPort, val tokenPort: TokenPort) {
fun login(@RequestBody request: LoginRequest): ResponseEntity {
val user = userPort.checkLogin(request.name, request.password)
return if (user != null) {
- val token = tokenPort.createNewToken(user)
+ val token = tokenPort.create(user)
ResponseEntity(token, HttpStatus.OK)
} else
ResponseEntity(HttpStatus.FORBIDDEN)
@@ -41,12 +46,12 @@ class AuthEndpoint(val userPort: UserPort, val tokenPort: TokenPort) {
@PostMapping("/loginWithGoogle", consumes = ["application/json"])
fun google(@RequestBody request: LoginRequest): ResponseEntity {
return if (!userPort.checkIfUserExists(request.name)) {
- val user = userPort.createNewUser(request.name, request.password)
- ResponseEntity(tokenPort.createNewToken(user), HttpStatus.OK)
+ val user = userPort.create(request.name, request.password)
+ ResponseEntity(tokenPort.create(user), HttpStatus.OK)
} else {
val user = userPort.checkLogin(request.name, request.password)
if (user != null) {
- ResponseEntity(tokenPort.createNewToken(user), HttpStatus.OK)
+ ResponseEntity(tokenPort.create(user), HttpStatus.OK)
} else
ResponseEntity(HttpStatus.FORBIDDEN)
}
diff --git a/server/src/main/kotlin/hello/hello/adapters/api/CardEndpoint.kt b/server/src/main/kotlin/hello/hello/adapters/api/CardEndpoint.kt
new file mode 100644
index 0000000..3685bc3
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/api/CardEndpoint.kt
@@ -0,0 +1,61 @@
+package hello.hello.adapters.api
+
+import org.springframework.http.HttpStatus
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.*
+import org.springframework.web.multipart.MultipartFile
+import hello.hello.adapters.persistence.cloudStorage.PhotosStorage
+import hello.hello.adapters.persistence.database.adapters.CardAdapter
+import hello.hello.domain.ports.CardPort
+
+data class SetCardRequest(val id: Int, val company: String?, val name: String?, val phone: String?, val email: String?, val category: String?, val mode: String?)
+
+@RestController
+@RequestMapping("/card")
+class CardEndpoint(val photosStorage: PhotosStorage) {
+ val cardPort: CardPort = CardAdapter()
+
+ @PostMapping
+ fun putCard(@RequestParam image: MultipartFile, @RequestParam ownerName: String): ResponseEntity {
+ val card = cardPort.create(ownerName, "PRIVATE", null)
+ return if (card != null) {
+ photosStorage.writeImage("cards/${card.id}.jpg", image.bytes)
+ cardPort.updatePath(card, "cards/${card.id}.jpg")
+ ResponseEntity(HttpStatus.CREATED)
+ } else {
+ ResponseEntity(HttpStatus.NOT_FOUND)
+ }
+ }
+
+ @GetMapping("/image", produces = [MediaType.IMAGE_JPEG_VALUE])
+ fun getImage(@RequestParam id: Int): ResponseEntity {
+ val result = cardPort.read(id)
+ return if (result?.path != null) {
+ val image = photosStorage.readImage(result.path!!)
+ return if (image != null) {
+ ResponseEntity(image, HttpStatus.OK)
+ } else {
+ ResponseEntity(HttpStatus.NOT_FOUND)
+ }
+ } else {
+ ResponseEntity(HttpStatus.NOT_FOUND)
+ }
+ }
+
+ @PostMapping("/set", consumes = ["application/json"])
+ fun setCard(@RequestBody request: SetCardRequest): ResponseEntity {
+ val company: String? = request.company?.ifBlank { null }
+ val name: String? = request.name?.ifBlank { null }
+ val phone: String? = request.phone?.ifBlank { null }
+ val email: String? = request.email?.ifBlank { null }
+ val category: String? = request.category?.ifBlank { null }
+ val mode: String? = request.mode?.ifBlank { null }
+
+ return if (cardPort.update(request.id, company, name, phone, email, category, mode) != null) {
+ ResponseEntity(HttpStatus.OK)
+ } else {
+ ResponseEntity(HttpStatus.NOT_FOUND)
+ }
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/api/RootEndpoint.kt b/server/src/main/kotlin/hello/hello/adapters/api/RootEndpoint.kt
similarity index 86%
rename from server/src/main/kotlin/pishello/hello/api/RootEndpoint.kt
rename to server/src/main/kotlin/hello/hello/adapters/api/RootEndpoint.kt
index a6e5f12..3ca3d5b 100644
--- a/server/src/main/kotlin/pishello/hello/api/RootEndpoint.kt
+++ b/server/src/main/kotlin/hello/hello/adapters/api/RootEndpoint.kt
@@ -1,4 +1,4 @@
-package pishello.hello.api
+package hello.hello.adapters.api
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
diff --git a/server/src/main/kotlin/pishello/hello/api/SearchEndpoint.kt b/server/src/main/kotlin/hello/hello/adapters/api/SearchEndpoint.kt
similarity index 58%
rename from server/src/main/kotlin/pishello/hello/api/SearchEndpoint.kt
rename to server/src/main/kotlin/hello/hello/adapters/api/SearchEndpoint.kt
index 27fefdc..4bb5a78 100644
--- a/server/src/main/kotlin/pishello/hello/api/SearchEndpoint.kt
+++ b/server/src/main/kotlin/hello/hello/adapters/api/SearchEndpoint.kt
@@ -1,17 +1,19 @@
-package pishello.hello.api
+package hello.hello.adapters.api
import org.springframework.http.HttpStatus
-import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
-import pishello.hello.persistence.database.entities.Card
-import pishello.hello.persistence.database.ports.CardPort
+import hello.hello.adapters.persistence.database.adapters.CardAdapter
+import hello.hello.domain.models.Card
+import hello.hello.domain.ports.CardPort
@RestController
-class SearchEndpoint(val searchPort: CardPort) {
+class SearchEndpoint {
+ val cardPort: CardPort = CardAdapter()
+
@GetMapping("/search")
- fun search(@RequestParam id: Int?, @RequestParam profession: String?, @RequestParam ownername: String?): ResponseEntity> {
- val result = searchPort.searchCards(id, profession, ownername)
+ fun search(@RequestParam id: Int?, @RequestParam profession: String?, @RequestParam ownername: String?): ResponseEntity> {
+ val result = cardPort.search(id, profession, ownername)
return if (result != null) {
ResponseEntity(result, HttpStatus.OK)
} else
@@ -19,8 +21,8 @@ class SearchEndpoint(val searchPort: CardPort) {
}
@GetMapping("/{user}/cards")
- fun getUserCards(@PathVariable user: String?): ResponseEntity> {
- val result = searchPort.searchOwnerCards(ownerName = user)
+ fun getUserCards(@PathVariable user: String?): ResponseEntity> {
+ val result = cardPort.read(ownerName = user)
return if (result != null) {
ResponseEntity(result, HttpStatus.OK)
} else
diff --git a/server/src/main/kotlin/pishello/hello/persistence/cloudStorage/PhotosStorage.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/cloudStorage/PhotosStorage.kt
similarity index 97%
rename from server/src/main/kotlin/pishello/hello/persistence/cloudStorage/PhotosStorage.kt
rename to server/src/main/kotlin/hello/hello/adapters/persistence/cloudStorage/PhotosStorage.kt
index eef1f05..8fb85fd 100644
--- a/server/src/main/kotlin/pishello/hello/persistence/cloudStorage/PhotosStorage.kt
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/cloudStorage/PhotosStorage.kt
@@ -1,4 +1,4 @@
-package pishello.hello.persistence.cloudStorage
+package hello.hello.adapters.persistence.cloudStorage
import com.google.auth.Credentials
import com.google.auth.oauth2.GoogleCredentials
diff --git a/server/src/main/kotlin/hello/hello/adapters/persistence/database/DatabaseUtilities.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/database/DatabaseUtilities.kt
new file mode 100644
index 0000000..c297f5b
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/database/DatabaseUtilities.kt
@@ -0,0 +1,35 @@
+package hello.hello.adapters.persistence.database
+
+import hello.hello.adapters.persistence.database.entities.CardTable
+import hello.hello.adapters.persistence.database.entities.TokenTable
+import hello.hello.adapters.persistence.database.entities.UserTable
+import org.jetbrains.exposed.sql.Database
+import org.jetbrains.exposed.sql.SchemaUtils
+import org.jetbrains.exposed.sql.transactions.TransactionManager
+import org.jetbrains.exposed.sql.transactions.transaction
+import org.springframework.core.env.Environment
+import java.sql.Connection
+
+fun init(env: Environment) {
+ TransactionManager.defaultDatabase = Database.connect(
+ env.getRequiredProperty("spring.datasource.url"),
+ env.getRequiredProperty("spring.datasource.driver-class-name")
+ )
+ TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
+}
+
+fun create() {
+ transaction {
+ SchemaUtils.create(UserTable)
+ SchemaUtils.create(TokenTable)
+ SchemaUtils.create(CardTable)
+ }
+}
+
+fun drop() {
+ transaction {
+ SchemaUtils.drop(UserTable)
+ SchemaUtils.drop(TokenTable)
+ SchemaUtils.drop(CardTable)
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/CardAdapter.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/CardAdapter.kt
new file mode 100644
index 0000000..b03efc0
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/CardAdapter.kt
@@ -0,0 +1,72 @@
+package hello.hello.adapters.persistence.database.adapters
+
+import hello.hello.adapters.persistence.database.adapters.UserAdapter.Companion.findByName
+import hello.hello.adapters.persistence.database.entities.CardEntity
+import hello.hello.adapters.persistence.database.entities.CardTable
+import hello.hello.adapters.persistence.database.entities.toCard
+import hello.hello.adapters.persistence.database.entities.toCardEntity
+import hello.hello.domain.models.Card
+import hello.hello.domain.ports.CardPort
+import org.jetbrains.exposed.dao.id.EntityID
+import org.jetbrains.exposed.sql.and
+import org.jetbrains.exposed.sql.transactions.transaction
+
+class CardAdapter: CardPort() {
+
+ private fun search(cardId: Int): List =
+ CardEntity.find { (CardTable.id eq cardId) and (CardTable.mode eq "PUBLIC") }.toList().map { it.toCard() }
+
+ private fun search(profession: String): List =
+ CardEntity.find { (CardTable.category eq profession) and (CardTable.mode eq "PUBLIC") }.toList().map { it.toCard() }
+
+ private fun search(ownerId: EntityID): List =
+ CardEntity.find { (CardTable.owner eq ownerId) and (CardTable.mode eq "PUBLIC") }.toList().map { it.toCard() }
+
+ private fun find(ownerId: EntityID): List =
+ CardEntity.find { CardTable.owner eq ownerId }.toList().map { it.toCard() }
+
+ override fun create(userName: String, mode: String, category: String?): Card? =
+ transaction {
+ val owner = findByName(userName) ?: return@transaction null
+ CardEntity.new {
+ this.mode = mode
+ this.category = category
+ this.owner = owner
+ }.toCard()
+ }
+
+ override fun read(cardId: Int): Card? =
+ transaction { CardEntity.findById(cardId)?.toCard() }
+
+ override fun read(ownerName: String?): List? =
+ transaction { ownerName?.let { findByName(ownerName)?.let { find(it.id) } } }
+
+ override fun search(id: Int?, profession: String?, ownerName: String?): List? =
+ transaction {
+ when {
+ id != null -> search(id)
+ profession != null -> search(profession)
+ ownerName != null -> findByName(ownerName)?.let { search(it.id) } ?: emptyList()
+ else -> null
+ }
+ }
+
+ override fun update(id: Int, company: String?, name: String?, phone: String?, email: String?, category: String?, mode: String?): Card? =
+ transaction {
+ val cardEntity = CardEntity.findById(id) ?: return@transaction null
+ mode?.let { cardEntity.mode = it }
+ company?.let { cardEntity.company = it }
+ name?.let { cardEntity.name = it }
+ phone?.let { cardEntity.phone = it }
+ email?.let { cardEntity.email = it }
+ category?.let { cardEntity.category = it }
+ cardEntity.toCard()
+ }
+
+ override fun updatePath(card: Card, path: String): Card =
+ transaction {
+ val cardEntity = card.toCardEntity()
+ cardEntity.path = path
+ cardEntity.toCard()
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/TokenAdapter.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/TokenAdapter.kt
new file mode 100644
index 0000000..ba47692
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/TokenAdapter.kt
@@ -0,0 +1,24 @@
+package hello.hello.adapters.persistence.database.adapters
+
+import hello.hello.adapters.persistence.database.entities.TokenEntity
+import hello.hello.adapters.persistence.database.entities.TokenTable
+import hello.hello.adapters.persistence.database.entities.toToken
+import hello.hello.adapters.persistence.database.entities.toUserEntity
+import hello.hello.domain.models.Token
+import hello.hello.domain.models.User
+import hello.hello.domain.ports.TokenPort
+import org.jetbrains.exposed.dao.id.EntityID
+import org.jetbrains.exposed.sql.transactions.transaction
+import java.time.Instant
+import java.util.*
+
+class TokenAdapter: TokenPort() {
+ override fun create(user: User): Token =
+ transaction {
+ TokenEntity.new {
+ this.token = EntityID(UUID.randomUUID().toString(), TokenTable)
+ this.name = user.toUserEntity()
+ this.creationDate = Instant.now()
+ }.toToken()
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/UserAdapter.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/UserAdapter.kt
new file mode 100644
index 0000000..94269a0
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/database/adapters/UserAdapter.kt
@@ -0,0 +1,29 @@
+package hello.hello.adapters.persistence.database.adapters
+
+import hello.hello.adapters.persistence.database.entities.UserEntity
+import hello.hello.adapters.persistence.database.entities.UserTable
+import hello.hello.adapters.persistence.database.entities.toUser
+import hello.hello.domain.models.User
+import hello.hello.domain.ports.UserPort
+import org.jetbrains.exposed.sql.and
+import org.jetbrains.exposed.sql.transactions.transaction
+
+class UserAdapter: UserPort() {
+ override fun checkIfUserExists(name: String): Boolean =
+ transaction { findByName(name) != null }
+
+ override fun checkLogin(name: String, password: String): User? =
+ transaction { UserEntity.find { (UserTable.name eq name) and (UserTable.password eq password) }.firstOrNull()?.toUser() }
+
+ override fun create(argName: String, argPassword: String): User =
+ transaction {
+ UserEntity.new {
+ name = argName
+ password = argPassword
+ }.toUser()
+ }
+
+ companion object {
+ internal fun findByName(name: String) = UserEntity.find { UserTable.name eq name }.firstOrNull()
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/CardEntity.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/CardEntity.kt
new file mode 100644
index 0000000..692c93d
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/CardEntity.kt
@@ -0,0 +1,37 @@
+package hello.hello.adapters.persistence.database.entities
+
+import hello.hello.domain.models.Card
+import org.jetbrains.exposed.dao.IntEntity
+import org.jetbrains.exposed.dao.IntEntityClass
+import org.jetbrains.exposed.dao.id.EntityID
+import org.jetbrains.exposed.dao.id.IntIdTable
+
+
+object CardTable: IntIdTable(name = "cards") {
+ var mode = varchar("mode", 7)
+ var path = varchar("path", 120).nullable()
+ var category = varchar("category", 40).nullable()
+ var company = varchar("company", 40).nullable()
+ var name = varchar("name", 40).nullable()
+ var phone = varchar("phone", 12).nullable()
+ var email = varchar("email", 40).nullable()
+ var owner = reference("owner", UserTable)
+}
+
+class CardEntity(id: EntityID): IntEntity(id) {
+ companion object : IntEntityClass(CardTable)
+ var mode by CardTable.mode
+ var path by CardTable.path
+ var category by CardTable.category
+ var company by CardTable.company
+ var name by CardTable.name
+ var phone by CardTable.phone
+ var email by CardTable.email
+ var owner by UserEntity referencedOn CardTable.owner
+}
+
+fun CardEntity.toCard(): Card =
+ Card(id.value, mode, path, category, company, name, phone, email, owner.name)
+
+fun Card.toCardEntity(): CardEntity =
+ CardEntity.findById(id)!!
diff --git a/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/TokenEntity.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/TokenEntity.kt
new file mode 100644
index 0000000..a6e1dc1
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/TokenEntity.kt
@@ -0,0 +1,31 @@
+package hello.hello.adapters.persistence.database.entities
+
+import hello.hello.domain.models.Token
+import org.jetbrains.exposed.dao.Entity
+import org.jetbrains.exposed.dao.EntityClass
+import org.jetbrains.exposed.dao.id.EntityID
+import org.jetbrains.exposed.dao.id.IdTable
+import org.jetbrains.exposed.sql.javatime.timestamp
+import java.util.*
+
+// TODO: this should be a UUIDTable
+object TokenTable: IdTable(name = "tokens") {
+ val token = varchar("token", 40).entityId()
+ val name = reference("name", UserTable)
+ val creationDate = timestamp("creation_date")
+
+ override val id = token
+}
+
+class TokenEntity(id: EntityID): Entity(id) {
+ companion object : EntityClass(TokenTable)
+ var token by TokenTable.token
+ var name by UserEntity referencedOn TokenTable.name
+ var creationDate by TokenTable.creationDate
+}
+
+fun TokenEntity.toToken(): Token =
+ Token(UUID.fromString(token.value), name.toUser(), creationDate)
+
+fun Token.toTokenEntity(): TokenEntity =
+ TokenEntity.findById(token.toString())!!
diff --git a/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/UserEntity.kt b/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/UserEntity.kt
new file mode 100644
index 0000000..2c79174
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/adapters/persistence/database/entities/UserEntity.kt
@@ -0,0 +1,25 @@
+package hello.hello.adapters.persistence.database.entities
+
+import hello.hello.domain.models.User
+import org.jetbrains.exposed.dao.IntEntity
+import org.jetbrains.exposed.dao.IntEntityClass
+import org.jetbrains.exposed.dao.id.EntityID
+import org.jetbrains.exposed.dao.id.IntIdTable
+import org.jetbrains.exposed.sql.and
+
+object UserTable: IntIdTable(name = "users") {
+ val name = varchar("name", 40).uniqueIndex()
+ val password = varchar("password", 40)
+}
+
+class UserEntity(id: EntityID): IntEntity(id) {
+ companion object : IntEntityClass(UserTable)
+ var name by UserTable.name
+ var password by UserTable.password
+}
+
+fun UserEntity.toUser(): User =
+ User(this.name, this.password)
+
+fun User.toUserEntity(): UserEntity =
+ UserEntity.find { (UserTable.name eq name) and (UserTable.password eq password) }.first()
diff --git a/server/src/main/kotlin/hello/hello/domain/models/Card.kt b/server/src/main/kotlin/hello/hello/domain/models/Card.kt
new file mode 100644
index 0000000..35da49c
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/domain/models/Card.kt
@@ -0,0 +1,13 @@
+package hello.hello.domain.models
+
+data class Card(
+ var id: Int,
+ var mode: String,
+ var path: String?,
+ var category: String?,
+ var company: String?,
+ var name: String?,
+ var phone: String?,
+ var email: String?,
+ var owner: String
+)
diff --git a/server/src/main/kotlin/hello/hello/domain/models/Token.kt b/server/src/main/kotlin/hello/hello/domain/models/Token.kt
new file mode 100644
index 0000000..21f2a34
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/domain/models/Token.kt
@@ -0,0 +1,10 @@
+package hello.hello.domain.models
+
+import java.time.Instant
+import java.util.UUID
+
+data class Token(
+ var token: UUID,
+ val name: User,
+ var creationDate: Instant
+)
\ No newline at end of file
diff --git a/server/src/main/kotlin/hello/hello/domain/models/User.kt b/server/src/main/kotlin/hello/hello/domain/models/User.kt
new file mode 100644
index 0000000..b8a8371
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/domain/models/User.kt
@@ -0,0 +1,6 @@
+package hello.hello.domain.models
+
+data class User(
+ var name: String,
+ var password: String
+)
diff --git a/server/src/main/kotlin/hello/hello/domain/ports/CardPort.kt b/server/src/main/kotlin/hello/hello/domain/ports/CardPort.kt
new file mode 100644
index 0000000..07b9f5c
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/domain/ports/CardPort.kt
@@ -0,0 +1,17 @@
+package hello.hello.domain.ports
+
+import hello.hello.domain.models.Card
+
+abstract class CardPort {
+ abstract fun create(userName: String, mode: String, category: String?): Card?
+
+ abstract fun read(cardId: Int): Card?
+
+ abstract fun read(ownerName: String?): List?
+
+ abstract fun search(id: Int?, profession: String?, ownerName: String?): List?
+
+ abstract fun update(id: Int, company: String?, name: String?, phone: String?, email: String?, category: String?, mode: String?): Card?
+
+ abstract fun updatePath(card: Card, path: String): Card
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/hello/hello/domain/ports/TokenPort.kt b/server/src/main/kotlin/hello/hello/domain/ports/TokenPort.kt
new file mode 100644
index 0000000..25685d3
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/domain/ports/TokenPort.kt
@@ -0,0 +1,8 @@
+package hello.hello.domain.ports
+
+import hello.hello.domain.models.Token
+import hello.hello.domain.models.User
+
+abstract class TokenPort {
+ abstract fun create(user: User): Token
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/hello/hello/domain/ports/UserPort.kt b/server/src/main/kotlin/hello/hello/domain/ports/UserPort.kt
new file mode 100644
index 0000000..27dfcb4
--- /dev/null
+++ b/server/src/main/kotlin/hello/hello/domain/ports/UserPort.kt
@@ -0,0 +1,11 @@
+package hello.hello.domain.ports
+
+import hello.hello.domain.models.User
+
+abstract class UserPort {
+ abstract fun create(argName: String, argPassword: String): User
+
+ abstract fun checkIfUserExists(name: String): Boolean
+
+ abstract fun checkLogin(name: String, password: String): User?
+}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/api/CardEndpoint.kt b/server/src/main/kotlin/pishello/hello/api/CardEndpoint.kt
deleted file mode 100644
index 28bae1c..0000000
--- a/server/src/main/kotlin/pishello/hello/api/CardEndpoint.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-package pishello.hello.api
-
-import org.springframework.http.HttpStatus
-import org.springframework.http.MediaType
-import org.springframework.http.ResponseEntity
-import org.springframework.web.bind.annotation.*
-import org.springframework.web.multipart.MultipartFile
-import pishello.hello.persistence.cloudStorage.PhotosStorage
-import pishello.hello.persistence.database.ports.CardPort
-
-data class CardRequest(val id: Int, val mode: String?, val category: String?)
-data class CardData(val id: Int, val company: String?, val name: String?, val phone: String?, val email: String?, val category: String?, val mode: String?)
-
-@RestController
-@RequestMapping("/card")
-class CardEndpoint(val cardPort: CardPort, val photosStorage: PhotosStorage) {
-
- @PostMapping
- fun addCard(@RequestParam image: MultipartFile, @RequestParam ownerName: String): ResponseEntity {
- val card = cardPort.createNewCard(ownerName, "PRIVATE", null)
- return if (card != null) {
- photosStorage.writeImage("cards/${card.id}.jpg", image.bytes)
- cardPort.setPath(card, "cards/${card.id}.jpg")
- ResponseEntity(HttpStatus.CREATED)
- } else {
- ResponseEntity(HttpStatus.NOT_FOUND)
- }
- }
-
- @PostMapping("/set")
- fun setCard(@RequestBody request: CardRequest): ResponseEntity {
- return if (cardPort.updateCard(request.id, request.mode, request.category) != null) {
- ResponseEntity(HttpStatus.OK)
- } else {
- ResponseEntity(HttpStatus.NOT_FOUND)
- }
- }
-
- @GetMapping("/image", produces = [MediaType.IMAGE_JPEG_VALUE])
- fun getImage(@RequestParam id: Int): ResponseEntity {
- val result = cardPort.findById(id)
- return if (result?.path != null) {
- val image = photosStorage.readImage(result.path!!)
- return if (image != null) {
- ResponseEntity(image, HttpStatus.OK)
- } else {
- ResponseEntity(HttpStatus.NOT_FOUND)
- }
- } else {
- ResponseEntity(HttpStatus.NOT_FOUND)
- }
- }
-
- @PostMapping("/changedata", consumes = ["application/json"])
- fun editCard(@RequestBody request: CardData): ResponseEntity {
- var company: String?
- var name: String?
- var phone: String?
- var email: String?
- var category: String?
- var mode: String?
-
- if (request.company ==""){
- company = null
- }
- else{
- company = request.company
- }
- if (request.name ==""){
- name = null
- }
- else{
- name = request.name
- }
- if (request.phone ==""){
- phone = null
- }
- else{
- phone = request.phone
- }
- if (request.email ==""){
- email = null
- }
- else{
- email = request.email
- }
- if (request.category ==""){
- category = null
- }
- else{
- category = request.category
- }
- if (request.mode ==""){
- mode = null
- }
- else{
- mode = request.mode
- }
- return if (cardPort.updateData(request.id, company, name, phone, email, category, mode) != null) {
- ResponseEntity(HttpStatus.OK)
- } else {
- ResponseEntity(HttpStatus.NOT_FOUND)
- }
- }
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/DataSource.kt b/server/src/main/kotlin/pishello/hello/persistence/database/DataSource.kt
deleted file mode 100644
index a459a02..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/DataSource.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package pishello.hello.persistence.database
-
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.context.annotation.Bean
-import org.springframework.core.env.Environment
-import org.springframework.jdbc.datasource.DriverManagerDataSource
-import javax.sql.DataSource
-
-
-@Autowired
-var env: Environment? = null
-
-@Bean
-fun dataSource(): DataSource {
- val dataSource = DriverManagerDataSource()
- dataSource.setDriverClassName(env!!.getProperty("spring.jpa.database-platform")!!)
- dataSource.url = env!!.getProperty("spring.datasource.url")!!
-// dataSource.username = env!!.getProperty("user")
-// dataSource.password = env!!.getProperty("password")
- return dataSource
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/SQLDialect.kt b/server/src/main/kotlin/pishello/hello/persistence/database/SQLDialect.kt
deleted file mode 100644
index 3da0e70..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/SQLDialect.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-package pishello.hello.persistence.database
-
-import org.hibernate.dialect.Dialect
-import org.hibernate.dialect.function.SQLFunctionTemplate
-import org.hibernate.dialect.function.StandardSQLFunction
-import org.hibernate.dialect.function.VarArgsSQLFunction
-import org.hibernate.type.StringType
-import java.sql.Types
-
-
-class SQLDialect: Dialect() {
- init {
- registerColumnType(Types.BIT, "integer")
- registerColumnType(Types.TINYINT, "tinyint")
- registerColumnType(Types.SMALLINT, "smallint")
- registerColumnType(Types.INTEGER, "integer")
- registerColumnType(Types.BIGINT, "bigint")
- registerColumnType(Types.FLOAT, "float")
- registerColumnType(Types.REAL, "real")
- registerColumnType(Types.DOUBLE, "double")
- registerColumnType(Types.NUMERIC, "numeric")
- registerColumnType(Types.DECIMAL, "decimal")
- registerColumnType(Types.CHAR, "char")
- registerColumnType(Types.VARCHAR, "varchar")
- registerColumnType(Types.LONGVARCHAR, "longvarchar")
- registerColumnType(Types.DATE, "date")
- registerColumnType(Types.TIME, "time")
- registerColumnType(Types.TIMESTAMP, "timestamp")
- registerColumnType(Types.BINARY, "blob")
- registerColumnType(Types.VARBINARY, "blob")
- registerColumnType(Types.LONGVARBINARY, "blob")
- // registerColumnType(Types.NULL, "null");
- registerColumnType(Types.BLOB, "blob")
- registerColumnType(Types.CLOB, "clob")
- registerColumnType(Types.BOOLEAN, "integer")
- registerFunction("concat", VarArgsSQLFunction(StringType.INSTANCE, "", "||", ""))
- registerFunction("mod", SQLFunctionTemplate(StringType.INSTANCE, "?1 % ?2"))
- registerFunction("substr", StandardSQLFunction("substr", StringType.INSTANCE))
- registerFunction("substring", StandardSQLFunction("substr", StringType.INSTANCE))
- }
-
- fun supportsIdentityColumns(): Boolean {
- return true
- }
-
- fun hasDataTypeInIdentityColumn(): Boolean {
- return false // As specify in NHibernate dialect
- }
-
- // return "integer primary key autoincrement";
- val identityColumnString: String
- get() =// return "integer primary key autoincrement";
- "integer"
-
- val identitySelectString: String
- get() = "select last_insert_rowid()"
-
- override fun supportsLimit(): Boolean {
- return true
- }
-
- override fun getLimitString(query: String, hasOffset: Boolean): String {
- return StringBuffer(query.length + 20).append(query).append(if (hasOffset) " limit ? offset ?" else " limit ?")
- .toString()
- }
-
- fun supportsTemporaryTables(): Boolean {
- return true
- }
-
- val createTemporaryTableString: String
- get() = "create temporary table if not exists"
-
- fun dropTemporaryTableAfterUse(): Boolean {
- return false
- }
-
- override fun supportsCurrentTimestampSelection(): Boolean {
- return true
- }
-
- override fun isCurrentTimestampSelectStringCallable(): Boolean {
- return false
- }
-
- override fun getCurrentTimestampSelectString(): String {
- return "select current_timestamp"
- }
-
- override fun supportsUnionAll(): Boolean {
- return true
- }
-
- override fun hasAlterTable(): Boolean {
- return false // As specify in NHibernate dialect
- }
-
- override fun dropConstraints(): Boolean {
- return false
- }
-
- override fun getAddColumnString(): String {
- return "add column"
- }
-
- override fun getForUpdateString(): String {
- return ""
- }
-
- override fun supportsOuterJoinForUpdate(): Boolean {
- return false
- }
-
- override fun getDropForeignKeyString(): String {
- throw UnsupportedOperationException("No drop foreign key syntax supported by SQLiteDialect")
- }
-
- override fun getAddForeignKeyConstraintString(
- constraintName: String, foreignKey: Array, referencedTable: String,
- primaryKey: Array, referencesPrimaryKey: Boolean
- ): String {
- throw UnsupportedOperationException("No add foreign key syntax supported by SQLiteDialect")
- }
-
- override fun getAddPrimaryKeyConstraintString(constraintName: String): String {
- throw UnsupportedOperationException("No add primary key syntax supported by SQLiteDialect")
- }
-
- override fun supportsIfExistsBeforeTableName(): Boolean {
- return true
- }
-
- override fun supportsCascadeDelete(): Boolean {
- return false
- }
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/entities/Card.kt b/server/src/main/kotlin/pishello/hello/persistence/database/entities/Card.kt
deleted file mode 100644
index 731ce21..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/entities/Card.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package pishello.hello.persistence.database.entities
-
-import org.hibernate.Hibernate
-import javax.persistence.*
-
-@Entity(name = "cards")
-data class Card(
- @Id
- @GeneratedValue(strategy = GenerationType.TABLE)
- val id: Int,
- var mode: String,
- var path: String?,
- var category: String?,
- var company: String?,
- var name: String?,
- var phone: String?,
- var email: String?,
- val owner: String // "FK"
-) {
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
- other as Card
-
- return id == other.id
- }
-
- override fun hashCode(): Int = javaClass.hashCode()
-
- @Override
- override fun toString(): String = this::class.simpleName + "(id = $id )"
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/entities/Token.kt b/server/src/main/kotlin/pishello/hello/persistence/database/entities/Token.kt
deleted file mode 100644
index 5f870ec..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/entities/Token.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package pishello.hello.persistence.database.entities
-
-import org.hibernate.Hibernate
-import java.sql.Timestamp
-import javax.persistence.Entity
-import javax.persistence.Id
-import javax.persistence.JoinColumn
-import javax.persistence.ManyToOne
-
-@Entity(name = "tokens")
-data class Token(
- @Id
- val token: String,
- @ManyToOne
- @JoinColumn(name = "name")
- val name: User,
- val creationDate: Timestamp
-) {
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
- other as Token
-
- return token == other.token
- }
-
- override fun hashCode(): Int = javaClass.hashCode()
-
- @Override
- override fun toString(): String = this::class.simpleName + "(token = $token )"
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/entities/User.kt b/server/src/main/kotlin/pishello/hello/persistence/database/entities/User.kt
deleted file mode 100644
index e88699f..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/entities/User.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package pishello.hello.persistence.database.entities
-
-import org.hibernate.Hibernate
-import javax.persistence.Entity
-import javax.persistence.Id
-
-@Entity(name = "users")
-data class User(
- @Id val name: String,
- val password: String
-) {
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
- other as User
- return name == other.name
- }
-
- override fun hashCode(): Int = javaClass.hashCode()
-
- override fun toString(): String = this::class.simpleName + "(name = $name )"
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/ports/CardPort.kt b/server/src/main/kotlin/pishello/hello/persistence/database/ports/CardPort.kt
deleted file mode 100644
index 5e78082..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/ports/CardPort.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package pishello.hello.persistence.database.ports
-
-import org.springframework.stereotype.Component
-import pishello.hello.persistence.database.entities.Card
-import pishello.hello.persistence.database.repositories.CardRepository
-import pishello.hello.persistence.database.repositories.UserRepository
-
-@Component
-class CardPort(val repository: CardRepository, val userRepository: UserRepository) {
- fun searchCards(id: Int?, profession: String?, ownerName: String?): List? {
- return when {
- id != null -> repository.searchById(id)
- profession != null -> repository.searchByProfession(profession)
- ownerName != null -> repository.searchByOwnerName(ownerName)
- else -> null
- }
- }
-
- fun searchOwnerCards(ownerName: String?): List? {
- return ownerName?.let { repository.findByOwner(it) }
- }
-
- fun findById(cardId: Int): Card? {
- return repository.findById(cardId)
- }
-
- fun createNewCard(userName: String, mode: String, category: String?): Card? {
- userRepository.findByName(userName) ?: return null
- val card = Card(0, mode, null, category, null, null, null, null, userName)
- return repository.save(card)
- }
-
- fun updateCard(id: Int, mode: String?, category: String?): Card? {
- val card = repository.findById(id) ?: return null
- if (mode != null)
- card.mode = mode
- if (category != null)
- card.category = category
- return repository.save(card)
- }
-
- fun setPath(card: Card, path: String): Card? {
- card.path = path
- return repository.save(card)
- }
-
- fun updateData(id: Int, company: String?, name: String?, phone: String?, email: String?, category: String?, mode: String?): Card? {
- val card = repository.findById(id) ?: return null
- if (company != null)
- card.company = company
- if (name != null)
- card.name = name
- if (phone != null)
- card.phone = phone
- if (email != null)
- card.email = email
- if (category != null)
- card.category = category
- if (mode != null)
- card.mode = mode
- return repository.save(card)
- }
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/ports/TokenPort.kt b/server/src/main/kotlin/pishello/hello/persistence/database/ports/TokenPort.kt
deleted file mode 100644
index 21c8422..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/ports/TokenPort.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package pishello.hello.persistence.database.ports
-
-import org.springframework.stereotype.Component
-import pishello.hello.persistence.database.entities.Token
-import pishello.hello.persistence.database.entities.User
-import pishello.hello.persistence.database.repositories.TokenRepository
-import java.sql.Timestamp
-import java.time.Instant
-import java.util.*
-
-@Component
-class TokenPort(val repository: TokenRepository) {
- fun createNewToken(userId: User): Token {
- val token = Token(UUID.randomUUID().toString(), userId, Timestamp.from(Instant.now()))
- repository.save(token)
- return token
- }
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/ports/UserPort.kt b/server/src/main/kotlin/pishello/hello/persistence/database/ports/UserPort.kt
deleted file mode 100644
index d14289d..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/ports/UserPort.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package pishello.hello.persistence.database.ports
-
-import org.springframework.stereotype.Component
-import pishello.hello.persistence.database.entities.User
-import pishello.hello.persistence.database.repositories.UserRepository
-
-@Component
-class UserPort(val repository: UserRepository) {
- fun checkIfUserExists(username: String): Boolean {
- return repository.findByName(username) != null
- }
-
- fun checkLogin(username: String, password: String): User? {
- return repository.findByNameAndPassword(username, password)
- }
-
- fun createNewUser(username: String, password: String): User {
- val user = User(username, password)
- repository.save(user)
- return user
- }
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/repositories/CardRepository.kt b/server/src/main/kotlin/pishello/hello/persistence/database/repositories/CardRepository.kt
deleted file mode 100644
index 23b499b..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/repositories/CardRepository.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package pishello.hello.persistence.database.repositories
-
-import org.springframework.data.jpa.repository.JpaRepository
-import org.springframework.data.jpa.repository.Query
-import org.springframework.data.repository.query.Param
-import pishello.hello.persistence.database.entities.Card
-
-interface CardRepository: JpaRepository {
-
- @Query("SELECT * FROM CARDS C WHERE C.ID = :id AND C.MODE = :mode", nativeQuery = true)
- fun searchById(@Param("id") id: Int?, @Param("mode") mode: String? = "PUBLIC"): List?
-
- @Query("SELECT * FROM CARDS C WHERE C.CATEGORY= :profession AND C.MODE = :mode", nativeQuery = true)
- fun searchByProfession(@Param("profession") profession: String?, @Param("mode") mode: String? = "PUBLIC"): List?
-
- @Query("SELECT * FROM CARDS C WHERE C.OWNER= :ownerName AND C.MODE = :mode", nativeQuery = true)
- fun searchByOwnerName(@Param("ownerName") ownerName: String?, @Param("mode") mode: String? = "PUBLIC"): List?
-
- fun findByOwner(@Param("ownerName") ownerName: String):List?
-
- fun findById(id: Int): Card?
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/repositories/TokenRepository.kt b/server/src/main/kotlin/pishello/hello/persistence/database/repositories/TokenRepository.kt
deleted file mode 100644
index be88a28..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/repositories/TokenRepository.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package pishello.hello.persistence.database.repositories
-
-import org.springframework.data.repository.CrudRepository
-import pishello.hello.persistence.database.entities.Token
-import pishello.hello.persistence.database.entities.User
-
-
-interface TokenRepository: CrudRepository {
- fun findByName(name: User): Token?
-}
\ No newline at end of file
diff --git a/server/src/main/kotlin/pishello/hello/persistence/database/repositories/UserRepository.kt b/server/src/main/kotlin/pishello/hello/persistence/database/repositories/UserRepository.kt
deleted file mode 100644
index 0546ac6..0000000
--- a/server/src/main/kotlin/pishello/hello/persistence/database/repositories/UserRepository.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package pishello.hello.persistence.database.repositories
-
-import org.springframework.data.repository.CrudRepository
-import pishello.hello.persistence.database.entities.User
-
-
-interface UserRepository: CrudRepository {
- fun findByName(name: String): User?
- fun findByNameAndPassword(name: String, password: String): User?
-}
\ No newline at end of file
diff --git a/server/src/main/resources/application-test.properties b/server/src/main/resources/application-test.properties
index cf20c1f..4b94c30 100644
--- a/server/src/main/resources/application-test.properties
+++ b/server/src/main/resources/application-test.properties
@@ -1,2 +1 @@
-spring.jpa.hibernate.ddl-auto = create-drop
spring.datasource.url = jdbc:sqlite:src/main/resources/test.db
\ No newline at end of file
diff --git a/server/src/main/resources/application.properties b/server/src/main/resources/application.properties
index 4102ed4..eadb8c7 100644
--- a/server/src/main/resources/application.properties
+++ b/server/src/main/resources/application.properties
@@ -1,6 +1,3 @@
-spring.jpa.database-platform = pishello.hello.persistence.database.SQLDialect
-spring.jpa.hibernate.ddl-auto = none
-
spring.datasource.url = jdbc:sqlite:src/main/resources/main.db
spring.datasource.driver-class-name = org.sqlite.JDBC
spring.servlet.multipart.max-file-size=128MB
diff --git a/server/src/main/resources/main.db b/server/src/main/resources/main.db
new file mode 100644
index 0000000..e7eab26
Binary files /dev/null and b/server/src/main/resources/main.db differ
diff --git a/server/src/main/resources/test.db b/server/src/main/resources/test.db
new file mode 100644
index 0000000..2795803
Binary files /dev/null and b/server/src/main/resources/test.db differ
diff --git a/server/src/main/sql/create.sql b/server/src/main/sql/create.sql
deleted file mode 100644
index 6de5999..0000000
--- a/server/src/main/sql/create.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-create table users
-(
- name text not null constraint users_pk primary key,
- password text not null
-);
-
-create table tokens
-(
- token text not null constraint token_pk primary key,
- name text constraint name references users on update cascade,
- creationDate timestamp not null
-);
-
-create table cards
-(
- id integer not null constraint card_pk primary key autoincrement,
- mode text not null,
- path text,
- category text,
- company text,
- name text,
- phone text,
- email text,
- owner integer not null references users
-);
-
-create unique index users_name_uindex on users (name);
-create unique index token_token_uindex on tokens (token);
\ No newline at end of file
diff --git a/server/src/main/sql/insert.sql b/server/src/main/sql/insert.sql
deleted file mode 100644
index 3ec0b4d..0000000
--- a/server/src/main/sql/insert.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-INSERT INTO cards(mode, path) VALUES('PRIVATE', 'test/photo1');
-INSERT INTO cards(mode, path, category) VALUES('PUBLIC', 'test/photo2', 'lawyer');
-INSERT INTO cards(mode, path, category) VALUES('PUBLIC', 'test/photo3', 'lawyer');
-INSERT INTO cards(mode, path, category) VALUES('PUBLIC', 'test/photo4', 'cook');
diff --git a/server/src/test/kotlin/pishello/hello/TestUtilities.kt b/server/src/test/kotlin/hello/hello/TestUtilities.kt
similarity index 56%
rename from server/src/test/kotlin/pishello/hello/TestUtilities.kt
rename to server/src/test/kotlin/hello/hello/TestUtilities.kt
index f07f758..ce367db 100644
--- a/server/src/test/kotlin/pishello/hello/TestUtilities.kt
+++ b/server/src/test/kotlin/hello/hello/TestUtilities.kt
@@ -1,11 +1,24 @@
-package pishello.hello
+package hello.hello
+import hello.hello.adapters.persistence.database.create
+import hello.hello.adapters.persistence.database.drop
+import hello.hello.adapters.persistence.database.init
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+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.core.env.Environment
import org.springframework.core.io.ClassPathResource
import org.springframework.mock.web.MockMultipartFile
+import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
-open class TestUtilities {
+@SpringBootTest
+@AutoConfigureMockMvc
+@ActiveProfiles("test")
+class TestUtilities {
fun correctUserName() = "test_user"
@@ -18,10 +31,7 @@ open class TestUtilities {
fun incorrectAuthRequestData(): String =
"""{ "name": "test_user", "password": "no, this is not a hash" }"""
- fun correctSetRequestData(id: Int, mode: String?, category: String?): String =
- """{ "id": $id, "mode": "$mode", "category": "$category" }"""
-
- fun correctEditRequestData(id: Int, company: String?, name: String?, phone: String?, email: String?, category: String?, mode: String?): String =
+ fun correctSetRequestData(id: Int, company: String?, name: String?, phone: String?, email: String?, category: String?, mode: String?): String =
"""{ "id": $id, "company": "$company", "name": "$name", "phone": "$phone", "email": "$email", "category": "$category", "mode": "$mode"}"""
@@ -43,15 +53,23 @@ open class TestUtilities {
.param("ownerName", correctUserName()))
}
- fun setCard(mockMvc: MockMvc, id: Int, mode: String?, category: String?) {
+ fun setCard(mockMvc: MockMvc, id: Int, company: String? = null, name: String? = null, phone: String? = null, email: String? = null, category: String? = null, mode: String? = null) {
mockMvc.perform(MockMvcRequestBuilders.post("/card/set")
.header("Content-Type", "application/json")
- .content(correctSetRequestData(id, mode, category)))
+ .content(correctSetRequestData(id, company, name, phone, email, category, mode)))
}
- fun editCard(mockMvc: MockMvc, id: Int, company: String?, name: String?, phone: String?, email: String?, category: String?, mode: String?) {
- mockMvc.perform(MockMvcRequestBuilders.post("/card/changedata")
- .header("Content-Type", "application/json")
- .content(correctEditRequestData(id, company, name, phone, email, category, mode)))
+ @Autowired
+ var env: Environment? = null
+
+ @BeforeEach
+ fun setup() {
+ init(env!!)
+ create()
+ }
+
+ @AfterEach
+ fun cleanUp() {
+ drop()
}
}
\ No newline at end of file
diff --git a/server/src/test/kotlin/pishello/hello/api/AuthEndpointTests.kt b/server/src/test/kotlin/hello/hello/api/AuthEndpointTests.kt
similarity index 61%
rename from server/src/test/kotlin/pishello/hello/api/AuthEndpointTests.kt
rename to server/src/test/kotlin/hello/hello/api/AuthEndpointTests.kt
index d4eacf4..69b7aa2 100644
--- a/server/src/test/kotlin/pishello/hello/api/AuthEndpointTests.kt
+++ b/server/src/test/kotlin/hello/hello/api/AuthEndpointTests.kt
@@ -1,27 +1,16 @@
-package pishello.hello.api
+package hello.hello.api
import org.hamcrest.Matchers.containsString
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.test.annotation.DirtiesContext
-import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
-import pishello.hello.TestUtilities
+import hello.hello.TestUtilities
-
-@SpringBootTest
-@AutoConfigureMockMvc
-@ActiveProfiles("test")
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
-class AuthEndpointTests(@Autowired val mockMvc: MockMvc) {
-
- val util = TestUtilities()
+class AuthEndpointTests(@Autowired val mockMvc: MockMvc): TestUtilities() {
@Test
fun contextLoads() { }
@@ -29,7 +18,7 @@ class AuthEndpointTests(@Autowired val mockMvc: MockMvc) {
@Test
fun shouldAcknowledgeThatThereIsNoSuchUser() {
mockMvc.perform(get("/check")
- .param("name", util.correctUserName()))
+ .param("name", correctUserName()))
.andExpect(status().isOk)
}
@@ -37,43 +26,43 @@ class AuthEndpointTests(@Autowired val mockMvc: MockMvc) {
fun shouldRegisterUser() {
mockMvc.perform(post("/register")
.header("Content-Type", "application/json")
- .content(util.correctAuthRequestData()))
+ .content(correctAuthRequestData()))
.andExpect(status().isCreated)
}
@Test
fun shouldAcknowledgeThatSuchUserAlreadyExists() {
- util.createUser(mockMvc)
+ createUser(mockMvc)
mockMvc.perform(get("/check")
- .param("name", util.correctUserName()))
+ .param("name", correctUserName()))
.andExpect(status().isConflict)
}
@Test
fun shouldFailToRegisterTheSameUser() {
- util.createUser(mockMvc)
+ createUser(mockMvc)
mockMvc.perform(post("/register")
.header("Content-Type", "application/json")
- .content(util.correctAuthRequestData()))
+ .content(correctAuthRequestData()))
.andExpect(status().isConflict)
}
@Test
fun shouldLoginProperly() {
- util.createUser(mockMvc)
+ createUser(mockMvc)
mockMvc.perform(post("/login")
.header("Content-Type", "application/json")
- .content(util.correctAuthRequestData()))
+ .content(correctAuthRequestData()))
.andExpect(status().isOk)
.andExpect(content().string(containsString("token")))
}
@Test
fun shouldFailToLogin() {
- util.createUser(mockMvc)
+ createUser(mockMvc)
mockMvc.perform(post("/login")
.header("Content-Type", "application/json")
- .content(util.incorrectAuthRequestData()))
+ .content(incorrectAuthRequestData()))
.andExpect(status().isForbidden)
}
}
diff --git a/server/src/test/kotlin/pishello/hello/api/CardEndpointTests.kt b/server/src/test/kotlin/hello/hello/api/CardEndpointTests.kt
similarity index 68%
rename from server/src/test/kotlin/pishello/hello/api/CardEndpointTests.kt
rename to server/src/test/kotlin/hello/hello/api/CardEndpointTests.kt
index c8ebb43..e1e0078 100644
--- a/server/src/test/kotlin/pishello/hello/api/CardEndpointTests.kt
+++ b/server/src/test/kotlin/hello/hello/api/CardEndpointTests.kt
@@ -1,22 +1,14 @@
-package pishello.hello.api
+package hello.hello.api
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.test.annotation.DirtiesContext
-import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
-import pishello.hello.TestUtilities
+import hello.hello.TestUtilities
// TODO: change the bucket in GCS to not use the same as PROD
-@SpringBootTest
-@AutoConfigureMockMvc
-@ActiveProfiles("test")
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class CardEndpointTests(@Autowired val mockMvc: MockMvc): TestUtilities() {
@Test
@@ -29,6 +21,15 @@ class CardEndpointTests(@Autowired val mockMvc: MockMvc): TestUtilities() {
.andExpect(MockMvcResultMatchers.status().isCreated)
}
+ @Test
+ fun shouldNotCreateCardForNonExistingUser() {
+ mockMvc
+ .perform(MockMvcRequestBuilders.multipart("/card")
+ .file(correctPutCardImageData())
+ .param("ownerName", correctUserName()))
+ .andExpect(MockMvcResultMatchers.status().isNotFound)
+ }
+
@Test
fun shouldSetCard() {
createUser(mockMvc)
@@ -36,16 +37,17 @@ class CardEndpointTests(@Autowired val mockMvc: MockMvc): TestUtilities() {
mockMvc
.perform(MockMvcRequestBuilders.post("/card/set")
.header("Content-Type", "application/json")
- .content(correctSetRequestData(1, null, null)))
+ .content(correctSetRequestData(1, "company", "name", null, null, null, null)))
.andExpect(MockMvcResultMatchers.status().isOk)
}
@Test
- fun shouldNotCreateCardForNonExistingUser() {
+ fun shouldNotSetCardForNonExistingCard() {
+ createUser(mockMvc)
mockMvc
- .perform(MockMvcRequestBuilders.multipart("/card")
- .file(correctPutCardImageData())
- .param("ownerName", correctUserName()))
+ .perform(MockMvcRequestBuilders.post("/card/set")
+ .header("Content-Type", "application/json")
+ .content(correctSetRequestData(1, "company", "name", null, null, null, null)))
.andExpect(MockMvcResultMatchers.status().isNotFound)
}
@@ -60,13 +62,11 @@ class CardEndpointTests(@Autowired val mockMvc: MockMvc): TestUtilities() {
}
@Test
- fun shouldEditCard() {
+ fun shouldNotGetCardImageForNonExistingCard() {
createUser(mockMvc)
- createCard(mockMvc)
mockMvc
- .perform(MockMvcRequestBuilders.post("/card/changedata")
- .header("Content-Type", "application/json")
- .content(correctEditRequestData(1, "company", "name",null ,null, null, null)))
- .andExpect(MockMvcResultMatchers.status().isOk)
+ .perform(MockMvcRequestBuilders.get("/card/image")
+ .param("id", "1"))
+ .andExpect(MockMvcResultMatchers.status().isNotFound)
}
}
\ No newline at end of file
diff --git a/server/src/test/kotlin/pishello/hello/api/RootEndpointTests.kt b/server/src/test/kotlin/hello/hello/api/RootEndpointTests.kt
similarity index 62%
rename from server/src/test/kotlin/pishello/hello/api/RootEndpointTests.kt
rename to server/src/test/kotlin/hello/hello/api/RootEndpointTests.kt
index a0fc77a..63537cf 100644
--- a/server/src/test/kotlin/pishello/hello/api/RootEndpointTests.kt
+++ b/server/src/test/kotlin/hello/hello/api/RootEndpointTests.kt
@@ -1,20 +1,14 @@
-package pishello.hello.api
+package hello.hello.api
+import hello.hello.TestUtilities
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.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
-
-@SpringBootTest
-@AutoConfigureMockMvc
-@ActiveProfiles("test")
-class RootEndpointTests(@Autowired val mockMvc: MockMvc) {
+class RootEndpointTests(@Autowired val mockMvc: MockMvc): TestUtilities() {
@Test
fun contextLoads() { }
diff --git a/server/src/test/kotlin/pishello/hello/api/SearchEndpointTests.kt b/server/src/test/kotlin/hello/hello/api/SearchEndpointTests.kt
similarity index 55%
rename from server/src/test/kotlin/pishello/hello/api/SearchEndpointTests.kt
rename to server/src/test/kotlin/hello/hello/api/SearchEndpointTests.kt
index ff866f5..32f2acd 100644
--- a/server/src/test/kotlin/pishello/hello/api/SearchEndpointTests.kt
+++ b/server/src/test/kotlin/hello/hello/api/SearchEndpointTests.kt
@@ -1,47 +1,37 @@
-package pishello.hello.api
+package hello.hello.api
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
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.test.annotation.DirtiesContext
-import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
-import pishello.hello.TestUtilities
+import hello.hello.TestUtilities
-@SpringBootTest
-@AutoConfigureMockMvc
-@ActiveProfiles("test")
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
-class SearchEndpointTests(@Autowired val mockMvc: MockMvc) {
-
- val util = TestUtilities()
+class SearchEndpointTests(@Autowired val mockMvc: MockMvc): TestUtilities() {
@ParameterizedTest
@CsvSource("id,1", "profession,lawyer", "ownername,test_user")
fun shouldSearchCardsByParam(paramName: String, paramValue: String) {
- util.createUser(mockMvc)
- util.createCard(mockMvc)
- util.setCard(mockMvc, 1, "PUBLIC", "lawyer")
+ createUser(mockMvc)
+ createCard(mockMvc)
+ setCard(mockMvc, 1, mode = "PUBLIC", category = "lawyer")
mockMvc
.perform(MockMvcRequestBuilders.get("/search")
.param(paramName, paramValue))
.andExpect(MockMvcResultMatchers.status().isOk)
- .andExpect(MockMvcResultMatchers.content().json(util.correctSearchByIdRequestData()))
+ .andExpect(MockMvcResultMatchers.content().json(correctSearchByIdRequestData()))
}
@Test
fun shouldReturnUserCards() {
- util.createUser(mockMvc)
- util.createCard(mockMvc)
- util.setCard(mockMvc, 1, "PUBLIC", "lawyer")
+ createUser(mockMvc)
+ createCard(mockMvc)
+ setCard(mockMvc, 1, mode = "PUBLIC", category = "lawyer")
mockMvc
.perform(MockMvcRequestBuilders.get("/test_user/cards"))
.andExpect(MockMvcResultMatchers.status().isOk)
- .andExpect(MockMvcResultMatchers.content().json(util.correctSearchByIdRequestData()))
+ .andExpect(MockMvcResultMatchers.content().json(correctSearchByIdRequestData()))
}
}
\ No newline at end of file