Skip to content
Snippets Groups Projects
Commit 4a9c6273 authored by Oda Alida Fønstelien Hjelljord's avatar Oda Alida Fønstelien Hjelljord
Browse files

Merge branch 'rating-load' into 'main'

Rating load

See merge request idatt2106_2022_02/boco-frontend!157
parents f1f2d069 54d642fd
No related branches found
No related tags found
1 merge request!157Rating load
Pipeline #182470 failed
Showing
with 171 additions and 143 deletions
...@@ -328,7 +328,6 @@ export default { ...@@ -328,7 +328,6 @@ export default {
}; };
}, },
methods: { methods: {
/** /**
* Checks validation. Checks also if any community is selected. * Checks validation. Checks also if any community is selected.
* If no community is selected or any other field isn't valid * If no community is selected or any other field isn't valid
...@@ -424,7 +423,6 @@ export default { ...@@ -424,7 +423,6 @@ export default {
} }
}, },
async removeImage(image) { async removeImage(image) {
let newImages = []; let newImages = [];
for (let i in this.item.images) { for (let i in this.item.images) {
......
...@@ -51,10 +51,11 @@ ...@@ -51,10 +51,11 @@
</p> </p>
</div> </div>
</div> </div>
<div class="mt-2"> <div class="mt-2" v-if="userForId">
<UserListItemCard <UserListItemCard
:buttons="['chat']" :buttons="['chat']"
:user="userForId" :user="userForId"
:rating="rating"
></UserListItemCard> ></UserListItemCard>
</div> </div>
<div class="mt-4"> <div class="mt-4">
...@@ -75,7 +76,7 @@ ...@@ -75,7 +76,7 @@
<p class="text-xl font-semibold text-gray-900"> <p class="text-xl font-semibold text-gray-900">
Total pris: {{ totPrice }} kr Total pris: {{ totPrice }} kr
</p> </p>
<p v-if="error" style="color: red;">Dato er påkrevd</p> <p v-if="error" class="text-error-medium">Dato er påkrevd</p>
<button <button
class="px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-gray-500 rounded-md focus:outline-none focus:ring focus:ring-opacity-80" class="px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-gray-500 rounded-md focus:outline-none focus:ring focus:ring-opacity-80"
v-bind:class="{ colorChange: allowForRent }" v-bind:class="{ colorChange: allowForRent }"
...@@ -142,6 +143,7 @@ export default { ...@@ -142,6 +143,7 @@ export default {
dateMessage: "Venligst velg dato for leieperioden", dateMessage: "Venligst velg dato for leieperioden",
allowForRent: false, allowForRent: false,
nonAvailableTimes: [], nonAvailableTimes: [],
rating: 0,
}; };
}, },
components: { components: {
...@@ -224,11 +226,24 @@ export default { ...@@ -224,11 +226,24 @@ export default {
amountOfDays = Math.ceil(amountOfDays / 86400000); amountOfDays = Math.ceil(amountOfDays / 86400000);
this.totPrice = this.item.pricePerDay * amountOfDays; this.totPrice = this.item.pricePerDay * amountOfDays;
}, },
async getUserRating() {
let maybeRating = await UserService.getUserRatingAverage(
this.userForId.userId
);
if (isNaN(maybeRating)) {
this.rating = NaN;
} else {
this.rating = maybeRating;
if (this.rating > 5) this.rating = 5;
else if (this.rating < 1) this.rating = 1;
}
},
}, },
async beforeMount() { async created() {
await this.getItemPictures(); await this.getItemPictures();
await this.getItem(); await this.getItem();
await this.getUser(this.item.userID); await this.getUser(this.item.userID);
await this.getUserRating();
await this.getAvailableTimesForListing(); await this.getAvailableTimesForListing();
}, },
}; };
......
...@@ -43,7 +43,7 @@ export default { ...@@ -43,7 +43,7 @@ export default {
methods: { methods: {
//Fills the rating stars //Fills the rating stars
getFill(i) { getFill(i) {
if (i <= this.rating) { if (i <= Math.round(this.rating)) {
return "w-5 h-5 text-warn-medium"; return "w-5 h-5 text-warn-medium";
} }
return "w-5 h-5 text-gray-300 dark:text-gray-500"; return "w-5 h-5 text-gray-300 dark:text-gray-500";
......
...@@ -42,15 +42,15 @@ ...@@ -42,15 +42,15 @@
:key="item" :key="item"
> >
<div class="w-full"> <div class="w-full">
<ItemCard <ItemCard
id="ItemCardPage" id="ItemCardPage"
class="ItemCard w-full h-full" class="ItemCard w-full h-full"
:item="item" :item="item"
/> />
</div> </div>
<!-- Dropdown menu with options for editing an item and deleting an item --> <!-- Dropdown menu with options for editing an item and deleting an item -->
<TripleDotButton class="DotButton" @click="openDotMenu(item)"/> <TripleDotButton class="DotButton" @click="openDotMenu(item)" />
<div <div
v-show="item.toggle" v-show="item.toggle"
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
</div> </div>
<!-- Dropdown menu with options for editing an item and deleting an item --> <!-- Dropdown menu with options for editing an item and deleting an item -->
<TripleDotButton class="DotButton" @click="openDotMenu(item)"/> <TripleDotButton class="DotButton" @click="openDotMenu(item)" />
<div <div
v-show="item.toggle" v-show="item.toggle"
class="options z-10 w-44 text-base list-none bg-white rounded divide-y divide-gray-100 shadow dark:bg-gray-700" class="options z-10 w-44 text-base list-none bg-white rounded divide-y divide-gray-100 shadow dark:bg-gray-700"
......
...@@ -65,7 +65,6 @@ ...@@ -65,7 +65,6 @@
<script> <script>
import RatingComponent from "@/components/UserProfileComponents/RatingComponents/Rating.vue"; import RatingComponent from "@/components/UserProfileComponents/RatingComponents/Rating.vue";
import IconButton from "@/components/BaseComponents/IconButton.vue"; import IconButton from "@/components/BaseComponents/IconButton.vue";
import UserService from "@/services/user.service";
import CommunityAdminService from "@/services/community-admin.service"; import CommunityAdminService from "@/services/community-admin.service";
import { import {
...@@ -79,7 +78,6 @@ export default { ...@@ -79,7 +78,6 @@ export default {
name: "UserListItem", name: "UserListItem",
data() { data() {
return { return {
rating: -1.0,
communityID: -1, communityID: -1,
profileImage: { profileImage: {
src: require("../../assets/defaultUserProfileImage.jpg"), src: require("../../assets/defaultUserProfileImage.jpg"),
...@@ -97,6 +95,7 @@ export default { ...@@ -97,6 +95,7 @@ export default {
props: { props: {
user: Object, user: Object,
buttons: Array, buttons: Array,
rating: Number,
}, },
computed: { computed: {
/** /**
...@@ -145,17 +144,7 @@ export default { ...@@ -145,17 +144,7 @@ export default {
); );
}, },
}, },
/** async beforeMounted() {
* Gets the user's rating before mounting the page
*/
async beforeMount() {
const maybeRating = await UserService.getUserRatingAverage(
this.user.userId
);
if (isNaN(maybeRating)) this.rating = NaN;
else this.rating = maybeRating;
if (this.rating > 5) this.rating = 5;
if (this.rating < 1) this.rating = 1;
this.communityID = this.$route.params.communityID; this.communityID = this.$route.params.communityID;
}, },
}; };
......
...@@ -103,7 +103,10 @@ ...@@ -103,7 +103,10 @@
</h5> </h5>
<div> <div>
<rating-component :rating="renterRating" :ratingType="'Leietaker'" /> <rating-component :rating="renterRating" :ratingType="'Leietaker'" />
<rating-component :rating="ownerRating" :ratingType="'Utleier'" /> <RatingComponent
:rating="ownerRating"
:ratingType="'Utleier'"
></RatingComponent>
</div> </div>
<div <div
...@@ -172,11 +175,13 @@ export default { ...@@ -172,11 +175,13 @@ export default {
this.isCurrentUser = true; this.isCurrentUser = true;
this.user = this.currentUser; this.user = this.currentUser;
this.user = await UserService.getUserFromId(this.user.accountId); this.user = await UserService.getUserFromId(this.user.accountId);
return; } else {
this.user = await getUser(this.id);
} }
this.user = await getUser(this.id); let ratingAsOwner = await UserService.getUserRatingAverageOwner(this.id);
let ratingAsOwner = await UserService.getUserRatingAsOwner(this.id); let ratingAsRenter = await UserService.getUserRatingAverageRenter(
let ratingAsRenter = await UserService.getUserRatingAsRenter(this.id); this.id
);
if (ratingAsOwner >= 0 && ratingAsOwner <= 5) { if (ratingAsOwner >= 0 && ratingAsOwner <= 5) {
this.ownerRating = ratingAsOwner; this.ownerRating = ratingAsOwner;
...@@ -201,8 +206,8 @@ export default { ...@@ -201,8 +206,8 @@ export default {
this.logout(); this.logout();
}, },
}, },
beforeMount() { async beforeMount() {
this.getUser(); await this.getUser();
}, },
}; };
</script> </script>
...@@ -24,11 +24,9 @@ function authGuardRoute(to, from, next) { ...@@ -24,11 +24,9 @@ function authGuardRoute(to, from, next) {
function adminGuardRoute(to, from, next) { function adminGuardRoute(to, from, next) {
if (store.state.user.adminList.includes(parseInt(from.params.communityID))) if (store.state.user.adminList.includes(parseInt(from.params.communityID)))
next(); // allow to enter route next(); // allow to enter route
else else next("/"); // go to the home page
next("/"); // go to the home page
} }
const routes = [ const routes = [
{ {
path: "/", path: "/",
......
...@@ -39,6 +39,28 @@ class UserService { ...@@ -39,6 +39,28 @@ class UserService {
.catch((err) => console.error(err)); .catch((err) => console.error(err));
} }
async getUserRatingAverageOwner(userId) {
return await axios
.get(API_URL + "rating/" + userId + "/average/owner", {
headers: tokenHeader(),
})
.then((res) => {
return res.data;
})
.catch((err) => console.error(err));
}
async getUserRatingAverageRenter(userId) {
return await axios
.get(API_URL + "rating/" + userId + "/average/renter", {
headers: tokenHeader(),
})
.then((res) => {
return res.data;
})
.catch((err) => console.error(err));
}
async setListingToDeleted(listingId) { async setListingToDeleted(listingId) {
return await axios return await axios
.delete(API_URL + "listing/" + listingId, { .delete(API_URL + "listing/" + listingId, {
......
<template> <template>
<!-- A view for editing the item --> <!-- A view for editing the item -->
<div class="h-screen grid md:mt-8"> <div class="h-screen grid md:mt-8">
<edit-item-form/> <edit-item-form />
</div> </div>
</template> </template>
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
import CommunityList from "@/components/CommunityComponents/CommunityList.vue"; import CommunityList from "@/components/CommunityComponents/CommunityList.vue";
import CommunityService from "@/services/community.service"; import CommunityService from "@/services/community.service";
import { UserAddIcon } from "@heroicons/vue/outline"; import { UserAddIcon } from "@heroicons/vue/outline";
import LoaderSpinner from "@/components/BaseComponents/LoaderSpinner" import LoaderSpinner from "@/components/BaseComponents/LoaderSpinner";
export default { export default {
data() { data() {
......
...@@ -29,7 +29,7 @@ describe("RentalMessage.vue", () => { ...@@ -29,7 +29,7 @@ describe("RentalMessage.vue", () => {
let wrapper; let wrapper;
const mockRouter = { const mockRouter = {
go: jest.fn(), go: jest.fn(),
} };
beforeEach(() => { beforeEach(() => {
wrapper = shallowMount(RentalMessage, { wrapper = shallowMount(RentalMessage, {
propsData: { propsData: {
...@@ -54,7 +54,7 @@ describe("RentalMessage.vue", () => { ...@@ -54,7 +54,7 @@ describe("RentalMessage.vue", () => {
mocks: { mocks: {
$router: mockRouter, $router: mockRouter,
}, },
} },
}); });
}); });
......
import { shallowMount } from "@vue/test-utils"; import { shallowMount } from "@vue/test-utils";
import ItemInfo from "@/components/RentingComponents/ItemInfo.vue"; import ItemInfo from "@/components/RentingComponents/ItemInfo.vue";
const mockMethod = jest.spyOn(ItemInfo.methods, "sendToConfirm");
const mockCreatePush = jest.spyOn(ItemInfo.methods, "createPushItem");
const mockMethod = jest.spyOn(ItemInfo.methods, 'sendToConfirm')
const mockCreatePush = jest.spyOn(ItemInfo.methods, 'createPushItem')
jest.mock("@/utils/apiutil", () => { jest.mock("@/utils/apiutil", () => {
return { return {
getItem: () => { getItem: () => {
return new Promise((resolve) => { return new Promise((resolve) => {
resolve({ resolve({
listingID: 0, listingID: 0,
title: "Title", title: "Title",
description: "Description", description: "Description",
pricePerDay: 100, pricePerDay: 100,
address: "ABC ROAD 3", address: "ABC ROAD 3",
userID: 1, userID: 1,
categoryNames: [], categoryNames: [],
communityIDs: [], communityIDs: [],
}); });
}); });
}, },
getItemPictures: () => { getItemPictures: () => {
return new Promise((resolve) => { return new Promise((resolve) => {
resolve([]); resolve([]);
}); });
} },
}; };
}); });
describe("ItemInfo component", () => { describe("ItemInfo component", () => {
let wrapper; let wrapper;
const mockRouter = { const mockRouter = {
push: jest.fn(), push: jest.fn(),
currentRoute: { currentRoute: {
value: { value: {
params: { params: {
id: "1", id: "1",
} },
} },
} },
}; };
const mockStore = { const mockStore = {
commit: jest.fn(), commit: jest.fn(),
}; };
beforeEach(() => { beforeEach(() => {
wrapper = shallowMount(ItemInfo, { wrapper = shallowMount(ItemInfo, {
global: { global: {
mocks: { mocks: {
$router: mockRouter, $router: mockRouter,
$store: mockStore, $store: mockStore,
}, },
}, },
});
}); });
});
it("is instantiated", () => { it("is instantiated", () => {
expect(wrapper.exists()).toBeTruthy(); expect(wrapper.exists()).toBeTruthy();
}) });
it("Check that title is displayed", () => {
expect(wrapper.findAll("h1")[0].text()).toBe("Title");
});
it("Check that title is displayed", () => { it("Check that button cannot be clicked if date is not selected", async () => {
expect(wrapper.findAll("h1")[0].text()).toBe("Title"); const jestCreatePushItemMock = jest.fn();
}) wrapper.vm.createPushItem = jestCreatePushItemMock;
it("Check that button cannot be clicked if date is not selected", async () => { // Click rent button
const jestCreatePushItemMock = jest.fn(); wrapper.find("button").trigger("click");
wrapper.vm.createPushItem = jestCreatePushItemMock;
// Click rent button
wrapper.find("button").trigger("click");
// wait a tick
await wrapper.vm.$nextTick();
// Check that jestMock was not clicked // wait a tick
expect(mockMethod).toHaveBeenCalledTimes(1); await wrapper.vm.$nextTick();
expect(mockCreatePush).toHaveBeenCalledTimes(0);
// Check that the last p contains "Dato er påkrevd"
expect(wrapper.findAll("p")[wrapper.findAll("p").length - 1].text()).toBe("Dato er påkrevd");
}) // Check that jestMock was not clicked
expect(mockMethod).toHaveBeenCalledTimes(1);
expect(mockCreatePush).toHaveBeenCalledTimes(0);
// Check that the last p contains "Dato er påkrevd"
expect(wrapper.findAll("p")[wrapper.findAll("p").length - 1].text()).toBe(
"Dato er påkrevd"
);
});
it("Check that send to confirm works", async () => { it("Check that send to confirm works", async () => {
// Set valid days // Set valid days
wrapper.vm.setDate({ wrapper.vm.setDate({
startDate: "2020-01-01", startDate: "2020-01-01",
endDate: "2020-02-01", endDate: "2020-02-01",
}) });
wrapper.find("button").trigger("click"); wrapper.find("button").trigger("click");
// wait a tick // wait a tick
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
// Check that method to change component was called // Check that method to change component was called
expect(mockCreatePush).toHaveBeenCalledTimes(1); expect(mockCreatePush).toHaveBeenCalledTimes(1);
}) });
it("Test that price calculation works", async () => { it("Test that price calculation works", async () => {
wrapper.vm.setDate({ wrapper.vm.setDate({
startDate: new Date("2022-01-01"), startDate: new Date("2022-01-01"),
endDate: new Date("2022-01-03"), endDate: new Date("2022-01-03"),
}) });
// wait a tick // wait a tick
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(wrapper.vm.totPrice).toBe(200); expect(wrapper.vm.totPrice).toBe(200);
}) });
}); });
\ No newline at end of file
...@@ -7,8 +7,8 @@ let mockRouter; ...@@ -7,8 +7,8 @@ let mockRouter;
describe("Confirm and send a rent request", () => { describe("Confirm and send a rent request", () => {
mockRouter = { mockRouter = {
go: jest.fn() go: jest.fn(),
} };
let wrapper; let wrapper;
beforeEach(() => { beforeEach(() => {
...@@ -24,11 +24,11 @@ describe("Confirm and send a rent request", () => { ...@@ -24,11 +24,11 @@ describe("Confirm and send a rent request", () => {
isAccepted: false, isAccepted: false,
}, },
}, },
global:{ global: {
mocks:{ mocks: {
$router: mockRouter $router: mockRouter,
} },
} },
}); });
}); });
...@@ -51,11 +51,11 @@ describe("Confirm and send a rent request", () => { ...@@ -51,11 +51,11 @@ describe("Confirm and send a rent request", () => {
expect(axios.post).toHaveBeenCalledTimes(1); expect(axios.post).toHaveBeenCalledTimes(1);
}); });
it("Checks that page is reloaded when cancelButton is press", async () =>{ it("Checks that page is reloaded when cancelButton is press", async () => {
const button = wrapper.find("#cancelButton"); const button = wrapper.find("#cancelButton");
button.trigger("click"); button.trigger("click");
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(mockRouter.go).toHaveBeenCalledTimes(1); expect(mockRouter.go).toHaveBeenCalledTimes(1);
expect(mockRouter.go).toHaveBeenCalledWith(0); expect(mockRouter.go).toHaveBeenCalledWith(0);
}) });
}); });
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment