Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TASK][NRPTI-1223] add two tests for work around act name changes #1225

Merged
merged 8 commits into from
May 28, 2024
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';
acatchpole marked this conversation as resolved.
Show resolved Hide resolved
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);
});
});
Loading