Skip to content
Snippets Groups Projects
Commit a8957330 authored by Tormod Nygård's avatar Tormod Nygård
Browse files

Issue: Get categories from DB (#4)

parent 77b4f561
No related branches found
No related tags found
No related merge requests found
Showing with 197 additions and 22 deletions
import { Deserializable } from "./deserializable.model";
import { Serializable } from "./serializable.model";
export class Category implements Deserializable, Serializable {
private categoryid: number;
private name: string;
constructor(input: any = null) {
if (input) {
this.deserialize(input);
} else {
this.categoryid = 0;
this.name = null;
}
}
deserialize(input: Object): this {
Object.assign(this, input);
return this;
}
serialize(): Object {
return {
categoryid: this.categoryid,
name: this.name
};
}
get getCategoryId() {
return this.categoryid;
}
set setCategoryId(categoryid: number) {
this.categoryid = categoryid;
}
get getName() {
return this.name;
}
set setName(name: string) {
this.name = name;
}
}
\ No newline at end of file
......@@ -13,14 +13,7 @@ export class Post implements Deserializable, Serializable {
constructor(input: any = null) {
if (input) {
this.id = input.id;
this.title = input.title;
this.description = input.description;
this.timestamp = input.timestamp;
this.owner = input.owner;
this.imageUrl = input.imageUrl;
this.price = input.price;
this.categoryid = input.categoryid;
this.deserialize(input);
} else {
this.id = 0;
this.title = null;
......
......@@ -7,10 +7,8 @@
<app-number-input [(inputModel)]="price" label="Pris" (blur)="checkForm()"></app-number-input>
<app-select [(inputModel)]="categoryid" (change)="checkForm()" label="Kategori">
<option value="0" selected>Velg kategori</option>
<option value="1">Antikviteter og Kunst</option>
<option value="2">Dyr og Utstyr</option>
<option value="3">Elektronikk og Hvitevarer</option>
<option value="0" selected hidden>Velg kategori</option>
<option *ngFor="let category of categories" [value]="category.getCategoryId">{{category.getName}}</option>
</app-select>
<p>{{statusMessage}}</p>
......
......@@ -3,6 +3,9 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testin
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Category } from 'src/app/models/category.model';
import { SharedModule } from 'src/app/shared/shared.module';
import { PostService } from '../post.service';
import { PostFormComponent } from './post-form.component';
......@@ -10,11 +13,29 @@ describe('PostFormComponent', () => {
let component: PostFormComponent;
let fixture: ComponentFixture<PostFormComponent>;
let router: Router;
let mockPostService;
beforeEach(async () => {
// PostService mock setup
mockPostService = jasmine.createSpyObj(['getAllCategories', 'addPost']);
mockPostService.getAllCategories.and.returnValue(
new Promise<Array<Category>>(
(resolve) => {
resolve([new Category({categoryid: 1, name: "Elektronikk"}), new Category({categoryid: 2, name: "Bil"})])
})
);
mockPostService.addPost.and.returnValue(
new Promise<string>(
(resolve) => {
resolve("success")
})
);
await TestBed.configureTestingModule({
declarations: [ PostFormComponent ],
imports: [ HttpClientTestingModule, RouterTestingModule, FormsModule ]
imports: [ HttpClientTestingModule, RouterTestingModule, FormsModule, SharedModule ],
providers: [ { provide: PostService, useValue: mockPostService } ]
})
.compileComponents();
});
......@@ -27,11 +48,20 @@ describe('PostFormComponent', () => {
router = TestBed.inject(Router);
});
it('should create', () => {
it('should create and get all categories', async () => {
expect(component).toBeTruthy();
// Waits for ngOnInit and checks that we get categories
fixture.whenStable().then(() => {
expect(mockPostService.getAllCategories).toHaveBeenCalled();
expect(component.categories.length).toBe(2);
expect(component.categories[0].getCategoryId).toBe(1);
expect(component.categories[1].getName).toBe("Bil");
});
});
it('should validate form', () => {
// Tests all if-sentences in checkForm
expect(component.checkForm()).toBeFalse();
expect(component.statusMessage).toBe("Tittelen kan ikke være tom");
......@@ -58,17 +88,20 @@ describe('PostFormComponent', () => {
});
it('should stop publishing invalid post', fakeAsync(() => {
// Tests that publishing should be stopped on invalid post
component.publishPost();
expect(component.statusMessage).toBe("Tittelen kan ikke være tom");
}));
it('should route after publishing post', () => {
// Tests that url is changed after post is published
component.title = "Title";
component.description = "Description";
component.price = 50;
component.categoryid = 2;
component.publishPost();
expect(mockPostService.addPost).toHaveBeenCalled();
expect(router.url).toBe('/');
});
});
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Category } from 'src/app/models/category.model';
import { Post } from 'src/app/models/post.model';
import { PostService } from '../post.service';
......@@ -17,9 +18,17 @@ export class PostFormComponent implements OnInit {
statusMessage: string = "";
categories: Array<Category>;
constructor(private postService: PostService, private router: Router) { }
ngOnInit() {
// Gets all categories and displays them in dropdown
this.postService.getAllCategories().then(categories => {
this.categories = categories;
}).catch (error => {
console.log("Error adding catrgories:" + error);
});
}
/**
......@@ -66,6 +75,7 @@ export class PostFormComponent implements OnInit {
categoryid: this.categoryid
});
// Adds post to database and changes page afterwards
this.postService.addPost(newPost).then(status => {
console.log("Post was added: " + status);
this.router.navigateByUrl("/");
......
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { Category } from '../models/category.model';
import { Post } from '../models/post.model';
import { PostService } from './post.service';
......@@ -22,6 +23,7 @@ describe('PostService', () => {
describe('getPost', () => {
it('should get a post', () => {
// Gets post and checks values
service.getPost(1).then(post => {
expect(post.getId).toBe(1);
expect(post.getTitle).toBe("Test");
......@@ -29,6 +31,7 @@ describe('PostService', () => {
fail();
});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/1");
expect(req.request.method).toBe("GET");
req.flush({
......@@ -46,10 +49,12 @@ describe('PostService', () => {
});
it('should reject on invalid post', () => {
// Gets invalid post, should go to catch
service.getPost(2).then(post => {
fail();
}).catch(error => {});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/2");
expect(req.request.method).toBe("GET");
req.flush({
......@@ -63,10 +68,12 @@ describe('PostService', () => {
});
it('should reject on http error', () => {
// Gets HTTP error instead of post, should catch
service.getPost(2).then(post => {
fail();
}).catch(error => {});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/2");
expect(req.request.method).toBe("GET");
req.error(new ErrorEvent("400"));
......@@ -86,12 +93,14 @@ describe('PostService', () => {
categoryid: 2
});
// Adds post
service.addPost(post)
.then(post => {})
.catch(error => {
fail();
});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/");
expect(req.request.method).toBe("POST");
expect(req.request.body).toEqual(post.serialize());
......@@ -114,15 +123,58 @@ describe('PostService', () => {
categoryid: 2
});
// Adds post, gets HTTP error, should catch
service.addPost(post).then(post => {
fail();
}).catch(error => {});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/post/");
expect(req.request.method).toBe("POST");
expect(req.request.body).toEqual(post.serialize());
req.error(new ErrorEvent("400"));
});
});
describe('getAllCategories', () => {
it('should get categories', () => {
// Gets all categories and checks values
service.getAllCategories()
.then(categories => {
expect(categories.length).toBe(3);
expect(categories[0] instanceof Category).toBeTrue();
expect(categories[1].getCategoryId).toBe(2);
expect(categories[2].getName).toBe("Elektronikk");
})
.catch(error => {
fail();
});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/category/");
expect(req.request.method).toBe("GET");
req.flush({
data: [
{categoryid: 1, name: "Dyr"},
{categoryid: 2, name: "Bil"},
{categoryid: 3, name: "Elektronikk"}
]
});
});
it('should reject on http error', () => {
// Gets HTTP error, should catch
service.getAllCategories().then(categories => {
fail();
}).catch(error => {});
// Mocks and checks HTTP request
const req = httpMock.expectOne("api/category/");
expect(req.request.method).toBe("GET");
req.error(new ErrorEvent("400"));
});
});
});
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Category } from '../models/category.model';
import { Post } from '../models/post.model';
@Injectable({
......@@ -8,6 +9,7 @@ import { Post } from '../models/post.model';
export class PostService {
postUrl = "api/post/";
categoryUrl = "api/category/";
constructor(private http: HttpClient) { }
......@@ -19,8 +21,7 @@ export class PostService {
(resolve, reject) => {
this.get_post(id).subscribe((data: any) => {
try {
const post = new Post();
post.deserialize(data.data[0]);
const post = new Post(data.data[0]);
if (post.getId == 0) {
reject("Could not find Post with id: " + id);
return;
......@@ -66,4 +67,40 @@ export class PostService {
private add_post(post: Post) {
return this.http.post(this.postUrl, post.serialize());
}
/**
* Get all categories from database.
*/
getAllCategories(): Promise<Array<Category>>{
return new Promise<Array<Category>>(
(resolve, reject) => {
this.get_all_categories().subscribe((data: any) => {
try {
let outputCategories = [];
for (let dataCategory of data.data) {
const category = new Category(dataCategory);
outputCategories.push(category);
if (category.getCategoryId == 0) {
reject("Could not deserialize category");
return;
}
}
resolve(outputCategories);
} catch (err: any){
reject(err);
}
},
(err: any) => {
console.log(err.message);
reject(err);
});
}
);
}
private get_all_categories() {
return this.http.get(this.categoryUrl);
}
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { NumberInputComponent } from './number-input.component';
......@@ -8,7 +9,9 @@ describe('NumberInputComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NumberInputComponent ]
declarations: [ NumberInputComponent ],
imports: [ FormsModule ]
})
.compileComponents();
});
......
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { SelectComponent } from './select.component';
......@@ -8,7 +9,8 @@ describe('SelectComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SelectComponent ]
declarations: [ SelectComponent ],
imports: [ FormsModule ]
})
.compileComponents();
});
......
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { TextInputComponent } from './text-input.component';
......@@ -8,7 +9,8 @@ describe('TextInputComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TextInputComponent ]
declarations: [ TextInputComponent ],
imports: [ FormsModule ]
})
.compileComponents();
});
......
......@@ -11,7 +11,7 @@ const category = new Category();
// - hente et bestemt kategori (get)
// SELECT * FROM category WHERE categoryid = #num;
// - remove specific cateogry (post)
// INSERT INTO `jonnynl_tdt4140`.`category` (`categoryid`, `navn`) VALUES ('4', 'ad');
// INSERT INTO `jonnynl_tdt4140`.`category` (`categoryid`, `name`) VALUES ('4', 'ad');
// - add category (post)
// DELETE FROM `jonnynl_tdt4140`.`category` WHERE (`categoryid` = '3');
......@@ -20,7 +20,7 @@ const category = new Category();
router.route('/').post(async (request: Request, response: Response) => {
const {category} = request.body;
try {
const input = (` INSERT INTO category(navn) VALUES (?);`)
const input = (` INSERT INTO category(name) VALUES (?);`)
return response.status(200).json(
await query(input,[category])
);
......
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