From 627ff6e3901d44f138feeb2ea88fd841a989254a Mon Sep 17 00:00:00 2001 From: Matt Raible Date: Thu, 25 May 2017 08:38:26 -0600 Subject: [PATCH] Fix tests and add Travis --- .travis.yml | 32 +++++++++ client/e2e/app.e2e-spec.ts | 9 +++ client/e2e/app.po.ts | 6 +- client/src/app/app.component.spec.ts | 17 ++++- .../app/beer-list/beer-list.component.html | 2 +- .../app/beer-list/beer-list.component.spec.ts | 18 ++++- .../src/app/shared/beer/beer.service.spec.ts | 12 +++- .../com/example/beer/BeerControllerTest.java | 66 +++++++++++++++++++ 8 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 .travis.yml create mode 100644 server/src/test/java/com/example/beer/BeerControllerTest.java diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..99fd2ac --- /dev/null +++ b/.travis.yml @@ -0,0 +1,32 @@ +language: java +jdk: + - oraclejdk8 +sudo: false +cache: + directories: + - node + - node_modules +env: + - NODE_VERSION=6.9.5 +before_install: + - nvm install $NODE_VERSION + - npm install -g @angular/cli + - node -v + - npm -v + - ng -v + - java -version +install: npm install +script: + - cd server && ./mvnw clean test + - cd ../client && ng test -sr -cc + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - cd ../server && ./mvnw spring-boot:run & + - bootPid=$! + - sleep 30s + - cd ../client && ng e2e +notifications: + webhooks: + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: false # default: false diff --git a/client/e2e/app.e2e-spec.ts b/client/e2e/app.e2e-spec.ts index fa0666a..42b1711 100644 --- a/client/e2e/app.e2e-spec.ts +++ b/client/e2e/app.e2e-spec.ts @@ -1,4 +1,5 @@ import { ClientPage } from './app.po'; +import { browser } from 'protractor'; describe('client App', () => { let page: ClientPage; @@ -11,4 +12,12 @@ describe('client App', () => { page.navigateTo(); expect(page.getParagraphText()).toEqual('app works!'); }); + + it('should have beer list', () => { + page.navigateTo(); + expect(page.getBeerListTitle()).toEqual('Beer List'); + // don't verify list because protractor runs on random port + // and I don't want to change Spring Boot to accept origin="*" + // because then it won't match the blog post instructions + }); }); diff --git a/client/e2e/app.po.ts b/client/e2e/app.po.ts index 7c8ae33..280b6d7 100644 --- a/client/e2e/app.po.ts +++ b/client/e2e/app.po.ts @@ -6,7 +6,11 @@ export class ClientPage { } getParagraphText() { - return element(by.css('app-root md-toolbar')).getText(); + return element(by.css('app-root h1')).getText(); + } + + getBeerListTitle() { + return element(by.css('app-root h2')).getText(); } } diff --git a/client/src/app/app.component.spec.ts b/client/src/app/app.component.spec.ts index c740bcd..ab55450 100644 --- a/client/src/app/app.component.spec.ts +++ b/client/src/app/app.component.spec.ts @@ -1,13 +1,28 @@ import { TestBed, async } from '@angular/core/testing'; import { AppComponent } from './app.component'; +import { BeerListComponent } from './beer-list/beer-list.component'; +import { BaseRequestOptions, ConnectionBackend, Http } from '@angular/http'; +import { MockBackend } from '@angular/http/testing'; +import { BeerService, GiphyService } from './shared'; describe('AppComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ - AppComponent + AppComponent, + BeerListComponent ], + providers: [BeerService, GiphyService, + { + provide: Http, useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => { + return new Http(backend, defaultOptions); + }, + deps: [MockBackend, BaseRequestOptions] + }, + {provide: MockBackend, useClass: MockBackend}, + {provide: BaseRequestOptions, useClass: BaseRequestOptions} + ] }).compileComponents(); })); diff --git a/client/src/app/beer-list/beer-list.component.html b/client/src/app/beer-list/beer-list.component.html index e8cfe69..d4d3b35 100644 --- a/client/src/app/beer-list/beer-list.component.html +++ b/client/src/app/beer-list/beer-list.component.html @@ -1,6 +1,6 @@

Beer List

-
+
{{b.name}}
{{b.name}}
diff --git a/client/src/app/beer-list/beer-list.component.spec.ts b/client/src/app/beer-list/beer-list.component.spec.ts index 22b678c..7a25165 100644 --- a/client/src/app/beer-list/beer-list.component.spec.ts +++ b/client/src/app/beer-list/beer-list.component.spec.ts @@ -1,6 +1,10 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { BeerListComponent } from './beer-list.component'; +import { BeerService } from '../shared/beer/beer.service'; +import { GiphyService } from '../shared/giphy/giphy.service'; +import { BaseRequestOptions, ConnectionBackend, Http } from '@angular/http'; +import { MockBackend } from '@angular/http/testing'; describe('BeerListComponent', () => { let component: BeerListComponent; @@ -8,9 +12,19 @@ describe('BeerListComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ BeerListComponent ] + declarations: [BeerListComponent], + providers: [BeerService, GiphyService, + { + provide: Http, useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => { + return new Http(backend, defaultOptions); + }, + deps: [MockBackend, BaseRequestOptions] + }, + {provide: MockBackend, useClass: MockBackend}, + {provide: BaseRequestOptions, useClass: BaseRequestOptions} + ] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { diff --git a/client/src/app/shared/beer/beer.service.spec.ts b/client/src/app/shared/beer/beer.service.spec.ts index 2e3f326..24e086a 100644 --- a/client/src/app/shared/beer/beer.service.spec.ts +++ b/client/src/app/shared/beer/beer.service.spec.ts @@ -1,11 +1,21 @@ import { TestBed, inject } from '@angular/core/testing'; import { BeerService } from './beer.service'; +import { BaseRequestOptions, ConnectionBackend, Http } from '@angular/http'; +import { MockBackend } from '@angular/http/testing'; describe('BeerService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [BeerService] + providers: [BeerService, + { + provide: Http, useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => { + return new Http(backend, defaultOptions); + }, + deps: [MockBackend, BaseRequestOptions] + }, + {provide: MockBackend, useClass: MockBackend}, + {provide: BaseRequestOptions, useClass: BaseRequestOptions}] }); }); diff --git a/server/src/test/java/com/example/beer/BeerControllerTest.java b/server/src/test/java/com/example/beer/BeerControllerTest.java new file mode 100644 index 0000000..a4e174f --- /dev/null +++ b/server/src/test/java/com/example/beer/BeerControllerTest.java @@ -0,0 +1,66 @@ +package com.example.beer; + +import com.example.DemoApplication; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.not; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Test class for the Beer REST controller. + * + * @see BeerController + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = DemoApplication.class) +public class BeerControllerTest { + + @Autowired + private BeerRepository beerRepository; + + @Autowired + private EntityManager em; + + private MockMvc mockMvc; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + BeerController beerController = new BeerController(beerRepository); + this.mockMvc = MockMvcBuilders.standaloneSetup(beerController).build(); + } + + @Test + @Transactional + public void getGoodBeers() throws Exception { + // Initialize the database + Beer beer1 = new Beer("White Rascal"); + Beer beer2 = new Beer("Budweiser"); + beerRepository.saveAndFlush(beer1); + beerRepository.saveAndFlush(beer2); + + // Get all the blogList + mockMvc.perform(get("/good-beers")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.[*].id").value(hasItem(beer1.getId().intValue()))) + .andExpect(jsonPath("$.[*].name").value(hasItem(beer1.getName()))) + .andExpect(jsonPath("$.[*].name").value(not(beer2.getName()))); + } +} \ No newline at end of file