Skip to content

Commit

Permalink
[TASK][NRPTI-1223] add two tests for work around act name changes (#1225
Browse files Browse the repository at this point in the history
)

* updated some comments with some copy/paste errors and added a boilerplate test for acts.service

* added legislation list detail comp test to show legislation data being shown in component

* modified parseTitleFromXML, improved error handling and made function public

* added test for parseTitleFromXML, includes positive and negative cases

* linting fix

* reformatted legislation list detail test to make the test more readable

* further lint fix
  • Loading branch information
acatchpole authored May 28, 2024
1 parent 1ec544c commit d44c763
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { LegislationListDetailComponent } from './legislation-list-detail.component';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRouteStub } from '../../spec/spec-utils';
import { GlobalModule } from 'nrpti-angular-components';
import { Legislation } from '../../models/master/common-models/legislation';

describe('LegislationListDetailComponent', () => {
let component: LegislationListDetailComponent;
Expand All @@ -14,7 +15,7 @@ describe('LegislationListDetailComponent', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [GlobalModule],
imports: [GlobalModule, HttpClientTestingModule],
declarations: [LegislationListDetailComponent],
providers: [
{ provide: ActivatedRoute, useValue: activedRouteStub },
Expand All @@ -32,4 +33,16 @@ describe('LegislationListDetailComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

it('should display an actCode when the backend cannot return the legislation code map', async () => {
const testActCode = 'ACT_103';
const testLegislation = new Legislation({ act: testActCode });

// populates the component with legislation data, which will then be parsed by buildLegislationString() and added as a grid item
component.data = [testLegislation];
fixture.detectChanges();
const gridEl = fixture.nativeElement.querySelector('.grid-item-value');

expect(gridEl.textContent).toContain(testActCode);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ActService } from './acts.service';
import { ConfigService } from 'nrpti-angular-components';

describe('ApiService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ActService, ConfigService],
imports: [HttpClientTestingModule]
});
});

it('should be created', () => {
const service = TestBed.get(ActService);
expect(service).toBeTruthy();
});
});
13 changes: 6 additions & 7 deletions angular/projects/public-nrpti/src/app/services/acts.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
* @description This service provides methods to fetch and store issuing agencies.
* @class ApplicationAgencyService
*/

import { Injectable } from '@angular/core';
import { ConfigService } from 'nrpti-angular-components';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';

/**
* @class
* @description Service for managing issuing agencies.
* @description Service for serving up-to-date map of actCode to actName and regulations.
*/
@Injectable({
providedIn: 'root'
Expand All @@ -27,16 +26,16 @@ export class ActService {
constructor(private configService: ConfigService, public http: HttpClient) {}

/**
* Initialize the service by setting the API endpoint and refreshing agencies.
* Initialize the service by setting the API endpoint and refreshing acts.
* @async
*/
async init() {
this.api = `${this.configService.config['API_LOCATION']}${this.configService.config['API_PATH']}`;
await this.refreshAct().toPromise();
}
/**
* Refresh the list of agencies from the API.
* @returns {Observable<void>} An observable that completes when agencies are refreshed.
* Refresh the map of actCodes from the API.
* @returns {Observable<void>} An observable that completes when acts are refreshed.
*/
refreshAct(): Observable<void> {
return new Observable<void>(observer => {
Expand All @@ -58,8 +57,8 @@ export class ActService {
});
}
/**
* Get the list of agencies.
* @returns {Object} A dictionary of agency codes and names.
* Get the list of acts and regualtions mapped to an actCode.
* @returns {Object} A dictionary of act codes, names, and regulations.
*/
getAllActsAndRegulations() {
return this.actsRegulationsData;
Expand Down
12 changes: 8 additions & 4 deletions api/src/controllers/acts-regulations-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ exports.updateActTitles = async function(args, res, next){
let actTitle = '';
for (const [actCode, {actAPI}] of Object.entries(LEGISLATION_CODES)){
const response = await axios.get(actAPI);
actTitle = parseTitleFromXML(response.data);
actTitle = this.parseTitleFromXML(response.data);
actMap[actCode] = actTitle;
}
updateTitlesInDB(actMap);
Expand All @@ -91,6 +91,7 @@ exports.getActTitleFromDB = async function(actCode){
return (actTitleFromDB);
} catch (error) {
console.error("getActTitleFromDB: Failed to fetch data from DB:", error);
return actCode;
}
}

Expand Down Expand Up @@ -119,19 +120,22 @@ exports.getAllActsAndRegulationsFromDB = async function(){
* @param {string} responseXML xml as a string from the BCLaws API
* @return {string} the title of the act
*/
function parseTitleFromXML(responseXML){
exports.parseTitleFromXML = function(responseXML){
let actTitle = '';
let startIndex = 0;
try{
const titleStart = '<act:title>';
const titleEnd = '</act:title>';
const titleStartIndex = responseXML.indexOf(titleStart, startIndex);
const titleEndIndex = responseXML.indexOf(titleEnd, titleStart);
actTitle = responseXML.substring(titleStartIndex + titleStart.length, titleEndIndex);

if(titleStartIndex >= 0 && titleEndIndex >= 0){ //indexOf() returns -1 if no matches are found
actTitle = responseXML.substring(titleStartIndex + titleStart.length, titleEndIndex);
} else throw new Error('act:title not found in XML');

} catch (error) {
console.error("parseTitleFromXML: Failed to parse XML:", error);
return null;
}
return actTitle;
}

17 changes: 17 additions & 0 deletions api/src/tests/controllers/acts-regulations-controller.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const actsRegulationsController = require('../../controllers/acts-regulations-controller');

describe('parseTitleFromXML', () => {
const testTitle = 'Act Name';
const testXMLWithActName = '<act:act><act:title>' + testTitle + '</act:title></act:act>';
const testXMLWithoutActName = '<act:act></act:act>';

it('returns null if act:title field is not found', () => {
const result = actsRegulationsController.parseTitleFromXML(testXMLWithoutActName);
expect(result).toEqual(null);
});

it('returns Act title if act:title field is present', () => {
const result = actsRegulationsController.parseTitleFromXML(testXMLWithActName);
expect(result).toEqual(testTitle);
});
});

0 comments on commit d44c763

Please sign in to comment.