Skip to content

Commit

Permalink
DMND-674 Update open source repo with osmt-ui tests (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
Roberto-Meza authored Sep 1, 2021
1 parent a2c68d4 commit 96b3237
Show file tree
Hide file tree
Showing 52 changed files with 6,653 additions and 18 deletions.
35 changes: 29 additions & 6 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"test": "./node_modules/@angular/cli/bin/ng test",
"lint": "./node_modules/@angular/cli/bin/ng lint",
"e2e": "./node_modules/@angular/cli/bin/ng e2e",
"ci-test": "./node_modules/@angular/cli/bin/ng test --no-watch --no-progress --karma-config=karma.ci.conf.js"
"ci-test": "./node_modules/@angular/cli/bin/ng test --no-watch --no-progress --karma-config=karma.ci.conf.js",
"clean": "rm -rf dist; rm -rf coverage; rm -rf reports; rm -rf test-results; rm -rf node_modules; rm -rf src/env.js"
},
"private": true,
"dependencies": {
Expand Down Expand Up @@ -42,6 +43,7 @@
"@angular/compiler-cli": "~10.0.9",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/lodash": "^4.14.168",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.5.0",
Expand All @@ -52,6 +54,8 @@
"karma-jasmine": "~3.3.0",
"karma-jasmine-html-reporter": "^1.5.0",
"karma-junit-reporter": "^2.0.1",
"karma-sonarqube-unit-reporter": "^0.0.23",
"lodash": "^4.17.21",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
Expand Down
302 changes: 302 additions & 0 deletions ui/src/app/abstract.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
import { Location } from "@angular/common"
import { HttpClient, HttpClientModule } from "@angular/common/http"
import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"
import { Injectable } from "@angular/core"
import { async, TestBed } from "@angular/core/testing"
import { Data, Router } from "@angular/router"
import { Observable, of } from "rxjs"
import { map } from "rxjs/operators"
import { createMockTaskResult } from "../../test/resource/mock-data"
import { AuthServiceData, AuthServiceStub, RouterData, RouterStub } from "../../test/resource/mock-stubs"
import { AbstractService } from "./abstract.service"
import { AppConfig } from "./app.config"
import { AuthService } from "./auth/auth-service"
import { EnvironmentService } from "./core/environment.service"
import { PublishStatus } from "./PublishStatus"
import { ApiSortOrder } from "./richskill/ApiSkill"
import { ApiSearch } from "./richskill/service/rich-skill-search.service"
import { ApiTaskResult } from "./task/ApiTaskResult"


@Injectable({
providedIn: "root"
})
export class ConcreteService extends AbstractService {
constructor(httpClient: HttpClient, authService: AuthService, router: Router, location: Location) {
super(httpClient, authService, router, location)
}

public buildUrl(path: string): string {
return super.buildUrl(path)
}

public safeUnwrapBody<T>(body: T | null, failureMessage: string): T {
return super.safeUnwrapBody(body, failureMessage)
}
}

interface IWork {
foo: string // Data def that is not likely to collide with real code
}
class Work implements IWork { // This just follows the pattern used throughout the source code
foo: string
constructor(work: IWork) {
this.foo = work.foo
}

doWork(id: string): Observable<ApiTaskResult> {
return of(new ApiTaskResult({
status: PublishStatus.Draft,
contentType: "my content type",
id,
uuid: "my collection summary uuid"
}))
}
}


describe("AbstractService (no HTTP needed)", () => {
let router: RouterStub
let authService: AuthServiceStub
let testService: ConcreteService

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [],
imports: [
HttpClientModule
],
providers: [
ConcreteService,
Location,
{ provide: AuthService, useClass: AuthServiceStub },
{ provide: Router, useClass: RouterStub }
]
})

router = TestBed.inject(Router)
authService = TestBed.inject(AuthService)
testService = TestBed.inject(ConcreteService)
}))

it("should be created", () => {
expect(testService).toBeTruthy()
})

it("redirectToLogin with no status should ignore it", () => {
[
{ input: undefined,
output: { commands: [], isDown: false }},
{ input: { },
output: { commands: [], isDown: false }},
{ input: { status: 401 },
output: { commands: ["/login"], isDown: false }},
{ input: { status: 0 },
output: { commands: [], isDown: true }}
].forEach((params) => {
// Arrange
RouterData.commands = []
AuthServiceData.isDown = false

// Act
testService.redirectToLogin(params.input)

// Assert
expect(RouterData.commands).toEqual(params.output.commands)
expect(AuthServiceData.isDown).toEqual(params.output.isDown)
})
})

it("buildTableParams should be correct", () => {
// Arrange
const size = 5
const from = 1
const filter = new Set<PublishStatus>([PublishStatus.Published, PublishStatus.Draft])
const sort = ApiSortOrder.NameAsc

// Act
const params = testService.buildTableParams(
size,
from,
filter,
sort
)

// Assert
expect(params).toEqual({
size,
from,
status: Array.from(filter).map(s => s.toString()),
sort: sort.toString()
})
})
})

describe("AbstractService (HTTP needed)", () => {
let httpClient: HttpClient
let httpTestingController: HttpTestingController
let router: RouterStub
let authService: AuthServiceStub
let testService: ConcreteService

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [],
imports: [
HttpClientTestingModule
],
providers: [
EnvironmentService,
AppConfig,
ConcreteService,
Location,
{ provide: AuthService, useClass: AuthServiceStub },
{ provide: Router, useClass: RouterStub }
]
})
.compileComponents()

const appConfig = TestBed.inject(AppConfig)
AppConfig.settings = appConfig.defaultConfig()

httpClient = TestBed.inject(HttpClient)
httpTestingController = TestBed.inject(HttpTestingController)
router = TestBed.inject(Router)
authService = TestBed.inject(AuthService)
testService = TestBed.inject(ConcreteService)
}))

afterEach(() => {
httpTestingController.verify()
})

it("should be created", () => {
expect(testService).toBeTruthy()
})

it("buildUrl should return", () => {
const path = "data"
expect(testService.buildUrl(path)).toEqual(AppConfig.settings.baseApiUrl + "/" + path)
})

/* See https://angular.io/guide/http#testing-http-requests */
it("get should return", () => {
// Arrange
RouterData.commands = []
AuthServiceData.isDown = false
const path = "any/path"
const testData: Data = { foo: "bar" } // Data that is unlikely to exist in any AbstractService derivative

// Act
const result$ = testService.get<Data>({ path })

// Assert
result$
.pipe(map(({body}) => body)) // Convert from HttpResponse<Data> to just Data
.subscribe(data => {
expect(data).toEqual(testData)
expect(RouterData.commands).toEqual([ ]) // No errors
expect(AuthServiceData.isDown).toEqual(false)
})

const req = httpTestingController.expectOne(AppConfig.settings.baseApiUrl + "/" + path)
expect(req.request.method).toEqual("GET")
req.flush(testData)
})

/* See https://angular.io/guide/http#testing-http-requests */
it("post should return", () => {
// Arrange
RouterData.commands = []
AuthServiceData.isDown = false
const path = "any/path"
const fullUrl = `${AppConfig.settings.baseApiUrl}/${path}`
const testData: Data = { foo: "bar" } // Data that is unlikely to exist in any AbstractService derivative
const errorMsg = `Could not unwrap Data exception...`

// Act
const result$ = testService.post<Data>({ path })

// Assert
result$
.pipe(map(({body}) => body)) // Convert from HttpResponse<Data> to just Data
.subscribe(unsafe => {
const data = testService.safeUnwrapBody<Data>(unsafe, errorMsg)
expect(data).toEqual(testData)
expect(RouterData.commands).toEqual([ ]) // No errors
expect(AuthServiceData.isDown).toEqual(false)
})

const req = httpTestingController.expectOne(fullUrl)
expect(req.request.method).toEqual("POST")
req.flush(testData)
})

it("bulkStatusChange should return", () => {
// Arrange
const newStatus = PublishStatus.Draft
const path = "any/path"
const fullUrl = `${AppConfig.settings.baseApiUrl}/${path}?newStatus=${newStatus.toString()}`
const query = "my query string"
const apiSearch = new ApiSearch({ query })
const expected = new ApiTaskResult(createMockTaskResult())

// Act
const result$ = testService.bulkStatusChange(
path,
apiSearch,
newStatus
)

// Assert
result$
.subscribe(data =>
expect(data).toEqual(expected)
)

const req = httpTestingController.expectOne(fullUrl)
expect(req.request.method).toEqual("POST")
req.flush(expected)
})

it("pollForTaskResult should return", (done) => {
// Arrange
const testData: IWork = { foo: "bar" } // Data that is unlikely to exist in any AbstractService derivative
const path = "tasks/42"
const fullUrl = AppConfig.settings.baseApiUrl + "/" + path
const worker = new Work(testData)

// Act
testService.pollForTaskResult<IWork>(worker.doWork(path), 1000)
.subscribe((data) => {
expect(data).toEqual(testData)
done()
})
const req = httpTestingController.expectOne(fullUrl)
req.flush(testData)

// Assert
expect(req.request.method).toEqual("GET")
})

it("pollForTaskResult should error", (done) => {
// Arrange
const testData: IWork = { foo: "bar" } // Data that is unlikely to exist in any AbstractService derivative
const path = "tasks/42"
const fullUrl = AppConfig.settings.baseApiUrl + "/" + path
const worker = new Work(testData)

// Act
testService.pollForTaskResult<IWork>(worker.doWork(path), 1000)
.subscribe(
(data) => {
expect(data).toBeFalsy()
done()
})
const req = httpTestingController.expectOne(fullUrl)
req.flush("Missing", { status: 404, statusText: "Not found" })

// Assert
expect(req.request.method).toEqual("GET")
})
})
Loading

0 comments on commit 96b3237

Please sign in to comment.