diff --git a/Jenkinsfile b/Jenkinsfile
index e7c1e2fc..49534a0a 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,7 +1,7 @@
pipeline {
agent any
environment {
- GIT_REPO = '202212_Equipo11'
+ GIT_REPO = '202212_Equipo10'
GIT_CREDENTIAL_ID = '277a9d46-cf19-4119-afd9-4054a7d35151'
SONARQUBE_URL = 'http://172.24.100.52:8082/sonar-misovirtual'
}
@@ -80,4 +80,3 @@ pipeline {
}
}
}
-
\ No newline at end of file
diff --git a/angular.json b/angular.json
index 077cc889..a4c3f38c 100644
--- a/angular.json
+++ b/angular.json
@@ -23,7 +23,8 @@
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
- "styles": ["src/styles.css"],
+ "styles": ["src/styles.css",
+ "node_modules/bootstrap/dist/css/bootstrap.min.css"],
"scripts": []
},
"configurations": {
diff --git a/package-lock.json b/package-lock.json
index 6fc0900b..bcbaba6c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,7 @@
"@angular/platform-browser": "~13.3.0",
"@angular/platform-browser-dynamic": "~13.3.0",
"@angular/router": "~13.3.0",
+ "bootstrap": "^5.2.2",
"exec-sh": "^0.4.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
@@ -2516,6 +2517,16 @@
"read-package-json-fast": "^2.0.1"
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@schematics/angular": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.3.0.tgz",
@@ -3484,6 +3495,24 @@
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
"dev": true
},
+ "node_modules/bootstrap": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.2.tgz",
+ "integrity": "sha512-dEtzMTV71n6Fhmbg4fYJzQsw1N29hJKO1js5ackCgIpDcGid2ETMGC6zwSYw09v05Y+oRdQ9loC54zB1La3hHQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.6"
+ }
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -13377,6 +13406,12 @@
"read-package-json-fast": "^2.0.1"
}
},
+ "@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "peer": true
+ },
"@schematics/angular": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.3.0.tgz",
@@ -14189,6 +14224,12 @@
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
"dev": true
},
+ "bootstrap": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.2.tgz",
+ "integrity": "sha512-dEtzMTV71n6Fhmbg4fYJzQsw1N29hJKO1js5ackCgIpDcGid2ETMGC6zwSYw09v05Y+oRdQ9loC54zB1La3hHQ==",
+ "requires": {}
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
diff --git a/package.json b/package.json
index 9355c4a0..6646d0e3 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"@angular/platform-browser": "~13.3.0",
"@angular/platform-browser-dynamic": "~13.3.0",
"@angular/router": "~13.3.0",
+ "bootstrap": "^5.2.2",
"exec-sh": "^0.4.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
diff --git a/reports/ut_report.xml b/reports/ut_report.xml
index fd74f42e..9a1fa050 100644
--- a/reports/ut_report.xml
+++ b/reports/ut_report.xml
@@ -1,7 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+ Error: Expected undefined to contain 'base-project app is running!'.
+ at <Jasmine>
+ at UserContext.<anonymous> (src/app/app.component.spec.ts:29:66)
+ at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:372:1)
+ at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:287:1)
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/app/app.component.html b/src/app/app.component.html
index b8968db4..09496abc 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,484 +1,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ title }} app is running!
-
-
-
-
-
-
-
Resources
-
Here are some links to help you get started:
-
-
-
-
-
Next Steps
-
What do you want to do next with your app?
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
ng generate component xyz
-
ng add @angular/material
-
ng add @angular/pwa
-
ng add _____
-
ng test
-
ng build
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index b1c6c96a..6d9246f5 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,8 +1,11 @@
+import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
+import { BookModule } from './book/book.module';
+import { EditorialModule } from './editorial/editorial.module';
@NgModule({
declarations: [
@@ -10,7 +13,10 @@ import { AppComponent } from './app.component';
],
imports: [
BrowserModule,
- AppRoutingModule
+ AppRoutingModule,
+ BookModule,
+ EditorialModule,
+ HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/book/book-list/book-list.component.css b/src/app/book/book-list/book-list.component.css
new file mode 100644
index 00000000..943a1b33
--- /dev/null
+++ b/src/app/book/book-list/book-list.component.css
@@ -0,0 +1,5 @@
+img {
+ height: 350px;
+ width: auto;
+ max-width: 400px;
+}
diff --git a/src/app/book/book-list/book-list.component.html b/src/app/book/book-list/book-list.component.html
new file mode 100644
index 00000000..98ed6132
--- /dev/null
+++ b/src/app/book/book-list/book-list.component.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+

+
+
{{ book.name }}
+
[{{ book.editorial.name }}]
+
+
+
+
+
diff --git a/src/app/book/book-list/book-list.component.spec.ts b/src/app/book/book-list/book-list.component.spec.ts
new file mode 100644
index 00000000..2dcf2f98
--- /dev/null
+++ b/src/app/book/book-list/book-list.component.spec.ts
@@ -0,0 +1,104 @@
+/* tslint:disable:no-unused-variable */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+import { faker } from '@faker-js/faker';
+
+import { BookListComponent } from './book-list.component';
+import { HttpClientModule } from '@angular/common/http';
+import { Editorial } from 'src/app/editorial/editorial';
+import { Book } from '../book';
+import { BookService } from '../book.service';
+
+describe('BookListComponent', () => {
+ let component: BookListComponent;
+ let fixture: ComponentFixture;
+ let debug: DebugElement;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpClientModule],
+ declarations: [ BookListComponent ],
+ providers: [ BookService ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BookListComponent);
+ component = fixture.componentInstance;
+
+ const editorial = new Editorial(
+ faker.datatype.number(),
+ faker.lorem.sentence()
+ );
+
+ for(let i = 0; i < 10; i++) {
+ const book = new Book(
+ faker.datatype.number(),
+ faker.lorem.sentence(),
+ faker.lorem.sentence(),
+ faker.lorem.sentence(),
+ faker.image.imageUrl(),
+ faker.date.past(),
+ editorial,
+ );
+ component.books.push(book);
+ }
+ fixture.detectChanges();
+ debug = fixture.debugElement;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have 10 elements', () => {
+ expect(debug.queryAll(By.css('div.col.mb-2'))).toHaveSize(10)
+ });
+
+ it('should have 10 elements', () => {
+ expect(debug.queryAll(By.css('div.card.p-2'))).toHaveSize(10)
+ });
+
+ it('should have 10
elements', () => {
+ expect(debug.queryAll(By.css('img'))).toHaveSize(10)
+ });
+
+ it('should have 10 elements', () => {
+ expect(debug.queryAll(By.css('div.card-body'))).toHaveSize(10)
+ });
+
+ it('should have the corresponding src to the book image and alt to the book name', () => {
+ debug.queryAll(By.css('img')).forEach((img, i)=>{
+ expect(img.attributes['src']).toEqual(
+ component.books[i].image)
+
+ expect(img.attributes['alt']).toEqual(
+ component.books[i].name)
+ })
+ });
+
+ it('should have h5 tag with the book.name', () => {
+ debug.queryAll(By.css('h5.card-title')).forEach((h5, i)=>{
+ expect(h5.nativeElement.textContent).toContain(component.books[i].name)
+ });
+ });
+
+ it('should have p tag with the book.editorial.name', () => {
+ debug.queryAll(By.css('p.card-text')).forEach((p, i)=>{
+ expect(p.nativeElement.textContent).toContain(component.books[i].editorial.name)
+ });
+ });
+
+ it('should have 9 elements and the deleted book should not exist', () => {
+ const book = component.books.pop()!;
+ fixture.detectChanges();
+ expect(debug.queryAll(By.css('div.col.mb-2'))).toHaveSize(9)
+
+ debug.queryAll(By.css('div.col.mb-2')).forEach((selector, i)=>{
+ expect(selector.nativeElement.textContent).not.toContain(book.name);
+ });
+ });
+
+});
diff --git a/src/app/book/book-list/book-list.component.ts b/src/app/book/book-list/book-list.component.ts
new file mode 100644
index 00000000..3f15e1e2
--- /dev/null
+++ b/src/app/book/book-list/book-list.component.ts
@@ -0,0 +1,25 @@
+import { Component, OnInit } from '@angular/core';
+import { Book } from '../book';
+import { BookService } from '../book.service';
+
+@Component({
+ selector: 'app-book-list',
+ templateUrl: './book-list.component.html',
+ styleUrls: ['./book-list.component.css']
+})
+export class BookListComponent implements OnInit {
+
+ books: Array=[];
+ constructor(private bookService: BookService) { }
+
+ getBooks(): void{
+ this.bookService.getBooks().subscribe((books) => {
+ this.books=books;
+ });
+ }
+
+ ngOnInit():void {
+ this.getBooks();
+ }
+
+}
diff --git a/src/app/book/book.module.ts b/src/app/book/book.module.ts
new file mode 100644
index 00000000..dff955b0
--- /dev/null
+++ b/src/app/book/book.module.ts
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { BookListComponent } from './book-list/book-list.component';
+
+
+@NgModule({
+ imports: [
+ CommonModule
+ ],
+ exports: [BookListComponent],
+ declarations: [BookListComponent]
+})
+export class BookModule { }
diff --git a/src/app/book/book.service.spec.ts b/src/app/book/book.service.spec.ts
new file mode 100644
index 00000000..e44e9222
--- /dev/null
+++ b/src/app/book/book.service.spec.ts
@@ -0,0 +1,18 @@
+/* tslint:disable:no-unused-variable */
+
+import { TestBed, async, inject } from '@angular/core/testing';
+import { BookService } from './book.service';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+
+describe('Service: Book', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [BookService]
+ });
+ });
+
+ it('should ...', inject([BookService], (service: BookService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/src/app/book/book.service.ts b/src/app/book/book.service.ts
new file mode 100644
index 00000000..ffcc926e
--- /dev/null
+++ b/src/app/book/book.service.ts
@@ -0,0 +1,20 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { environment } from 'src/environments/environment';
+import { Observable } from 'rxjs';
+import { Book } from './book';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class BookService {
+
+private apiUrl: string = environment.baseUrl + 'books';
+
+constructor(private http: HttpClient) { }
+
+getBooks(): Observable {
+ return this.http.get(this.apiUrl);
+}
+
+}
diff --git a/src/app/book/book.ts b/src/app/book/book.ts
new file mode 100644
index 00000000..12d501bb
--- /dev/null
+++ b/src/app/book/book.ts
@@ -0,0 +1,29 @@
+import { Editorial } from '../editorial/editorial'
+
+export class Book {
+ id: number;
+ name: string;
+ isbn: string;
+ description: string;
+ image: string;
+ publishingdate: any;
+ editorial: Editorial;
+
+ constructor(
+ id:number,
+ name:string,
+ isbn:string,
+ description:string,
+ image:string,
+ publishingdate: any,
+ editorial: Editorial
+ ) {
+ this.id=id;
+ this.name=name;
+ this.isbn=isbn;
+ this.description=description;
+ this.image=image;
+ this.publishingdate=publishingdate;
+ this.editorial=editorial;
+ }
+}
diff --git a/src/app/editorial/editorial.module.ts b/src/app/editorial/editorial.module.ts
new file mode 100644
index 00000000..de0f8b1d
--- /dev/null
+++ b/src/app/editorial/editorial.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+
+@NgModule({
+ imports: [
+ CommonModule
+ ],
+ declarations: []
+})
+export class EditorialModule { }
diff --git a/src/app/editorial/editorial.ts b/src/app/editorial/editorial.ts
new file mode 100644
index 00000000..2025219c
--- /dev/null
+++ b/src/app/editorial/editorial.ts
@@ -0,0 +1,10 @@
+
+export class Editorial {
+ id:number;
+ name: string;
+
+ constructor(id:number, name:string) {
+ this.id =id;
+ this.name=name;
+ }
+}
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index f56ff470..bfc7fb26 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -1,9 +1,11 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
+const baseUrl = 'https://misw4104-api.herokuapp.com/api/';
export const environment = {
- production: false
+ production: false,
+ baseUrl
};
/*
diff --git a/src/index.html b/src/index.html
index 13d8b794..79d09f1c 100644
--- a/src/index.html
+++ b/src/index.html
@@ -2,7 +2,7 @@
- MuseumsFront
+ base-project