Skip to content
Snippets Groups Projects
Commit df82f328 authored by Jonny Ngo Luong's avatar Jonny Ngo Luong
Browse files

feat: Added endpoints and display for getting posts by userid with tests (#16)

parent 217f0882
No related branches found
No related tags found
1 merge request!21Resolve "Gjesteside for profilen din"
......@@ -124,6 +124,7 @@ div.splash {
}
div.wrapper {
padding: 5%;
min-height: calc(45vh - 200px);
}
div.footer {
......
......@@ -20,7 +20,8 @@ import { PostThumbnailComponent } from './post-thumbnail/post-thumbnail.componen
CommonModule,
SharedModule,
FormsModule
]
],
exports: [ PostThumbnailComponent ]
})
export class PostModule { }
......@@ -331,5 +331,76 @@ describe('PostService', () => {
req.error(new ErrorEvent("400"));
});
});
describe('getPostsByUserId', () => {
it('should get posts by user', () => {
// Gets posts by category and checks values
service.getPostsByUserId(2).then(posts => {
for (let i = 0; i < posts.length; i++) {
expect(posts[i].getId).toBe(i + 1);
expect(posts[i].getTitle).toBe("Test" + (i + 1));
expect(posts[i].getOwner).toBe("2");
}
}).catch(error => {
fail();
});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/?userId=2");
expect(req.request.method).toBe("GET");
req.flush({
data: [{
id: 1,
title: "Test1",
description: "TestDescription",
timestamp: 23947298234,
owner: "2",
imageUrl: null,
price: 49,
categoryid: 2
}, {
id: 2,
title: "Test2",
description: "TestDescription",
timestamp: 23453246527,
owner: "2",
imageUrl: null,
price: 159,
categoryid: 2
}]
});
});
it('should reject on invalid post', () => {
// Gets invalid post, should go to catch
service.getPostsByUserId(420).then(posts => {
fail();
}).catch(error => {});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/?userId=420");
expect(req.request.method).toBe("GET");
req.flush({
data: [{
id: 0,
title: "Test",
description: "TestDescription",
timestamp: 23947298
}]
});
});
it('should reject on http error', () => {
// Gets HTTP error instead of post, should catch
service.getPostsByUserId(520).then(posts => {
fail();
}).catch(error => {});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/?userId=520");
expect(req.request.method).toBe("GET");
req.error(new ErrorEvent("400"));
});
});
});
......@@ -232,4 +232,38 @@ export class PostService {
private get_posts_by_category(categoryId: number) {
return this.http.get(this.postUrl, {params: {categoryid: String(categoryId)}});
}
/**
* Get all posts in database by specified category.
*/
getPostsByUserId(userId: number): Promise<Array<Post>> {
return new Promise<Array<Post>>(
(resolve, reject) => {
this.get_posts_by_user_id(userId).subscribe((data: any) => {
try {
let outputPosts = [];
for (let post of data.data) {
outputPosts.push(new Post(post));
if (!post.id || post.id == 0) {
reject("Could not deserialize Post");
return;
}
}
resolve(outputPosts);
} catch (err: any) {
reject(err);
}
},
(err: any) => {
console.log(err.message);
reject(err);
});
}
);
}
private get_posts_by_user_id(userId: number) {
return this.http.get(this.postUrl, {params: {userId: String(userId)}});
}
}
<p>user-guest-profile works!</p>
<h1>User information</h1>
<p>Userid: {{user.getUserId}}</p>
<p>username: {{user.getUsername}}</p>
<p>email: {{user.getEmail}}</p>
\ No newline at end of file
<p>email: {{user.getEmail}}</p>
<h1>Users posts:</h1>
<app-post-thumbnail *ngFor="let post of userPosts" [post]="post"></app-post-thumbnail>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'
import { AuthService } from 'src/app/authentication/auth.service';
import { Post } from 'src/app/models/post.model';
import { User } from 'src/app/models/user.model';
import { UserService } from '../user.service';
import { PostService } from 'src/app/posts/post.service';
@Component({
selector: 'app-user-guest-profile',
......@@ -12,8 +14,10 @@ import { UserService } from '../user.service';
export class UserGuestProfileComponent implements OnInit {
user: User = new User();
constructor(private userService: UserService, private authService: AuthService, private activatedRoute: ActivatedRoute, private router: Router) { }
userPosts: Array<Post> = [];
constructor(private userService: UserService, private authService: AuthService, private postService: PostService, private activatedRoute: ActivatedRoute, private router: Router) { }
ngOnInit(): void {
// Gets id parameter from URL
const id = +this.activatedRoute.snapshot.params["id"];
......@@ -21,6 +25,7 @@ export class UserGuestProfileComponent implements OnInit {
// Gets User with id from database
this.userService.getUser(id).then(user => {
this.user = user;
this.getPosts();
}).catch (error => {
// Navigate to home on error or invalid userid
console.log("Error getting user: " + error);
......@@ -28,4 +33,13 @@ export class UserGuestProfileComponent implements OnInit {
});
}
getPosts() {
// Gets all posts from database, and displays them
this.postService.getPostsByUserId(this.user.getUserId).then(posts => {
this.userPosts = posts;
console.log(this.userPosts,[this.user.getUserId]);
}).catch(error => {
console.log(error);
});
}
}
......@@ -7,6 +7,7 @@ import { UserProfileComponent } from './user-profile/user-profile.component';
import { UserLoginFormComponent } from './user-login-form/user-login-form.component';
import { UserLogoutComponent } from './user-logout/user-logout.component';
import { UserGuestProfileComponent } from './user-guest-profile/user-guest-profile.component';
import { PostModule } from '../posts/post.module';
......@@ -21,6 +22,7 @@ import { UserGuestProfileComponent } from './user-guest-profile/user-guest-profi
imports: [
CommonModule,
SharedModule,
PostModule,
FormsModule
]
})
......
......@@ -41,14 +41,21 @@ router.route("/").post(async (request: Request, response: Response) => {
});
/* ============================= READ ============================= */
// Get all posts `/api/post/?categoryid=`
// Get all posts `/api/post/?categoryid=:categoryid&userId=:userId`
router.route("/").get(async (request: Request, response: Response) => {
const { categoryid } = request.query as { [key: string]: string };
const { categoryid, userId } = request.query as { [key: string]: string };
try {
let input = `SELECT p.id, p.title, p.description, p.price, p.timestamp, p.owner, p.categoryid, p.imageUrl
FROM post as p`;
if (categoryid) input += ` WHERE p.categoryid=${categoryid}`;
response.status(200).json(await query(input, ""));
if (categoryid || userId) input += ` WHERE `;
const params = Object.entries({
categoryId: categoryid,
owner: userId
}).filter((param) => param[1])
// Add p.categoryId = ? AND p.userId = ? respectively if it is not undefined
input += params.map((param) => `p.${param[0]} = ?`).join(" AND ")
console.log(input, params.map((param) => param[1]));
response.status(200).json(await query(input, params.map((param) => param[1])));
} catch (error) {
response.status(400).send("Bad Request");
}
......
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