Skip to content

Commit

Permalink
Merge pull request #1764 from fecgov/feature/1662
Browse files Browse the repository at this point in the history
Feature/1662
  • Loading branch information
toddlees authored Mar 8, 2024
2 parents b80c9d4 + 85e8a57 commit f174ca0
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ <h5 class="font-karla-bold">COMMITTEE NAME OR ID</h5>
class="committee-search p-fluid"
id="searchBox"
field="label"
[(ngModel)]="query"
dropdownMode="current"
dropdownIcon="pi pi-search"
[suggestions]="suggestions ?? []"
Expand All @@ -45,9 +46,9 @@ <h5 class="font-karla-bold">COMMITTEE NAME OR ID</h5>
</p-autoComplete>
Examples: Obama for America; C00431445; Bush for President Inc.; C00343509
</div>
<div class="right-side-box" *ngIf="selectedCommittee">
<div class="right-side-box" *ngIf="selectedCommittee || unableToCreateAccount">
<h2>Results</h2>
<div class="committee-card">
<div class="committee-card" *ngIf="selectedCommittee">
<img alt="Document with magnifying lens" src="assets/img/document-with-lens.svg" />
<div class="committee-info">
<h3>{{ selectedCommittee.name }}</h3>
Expand All @@ -64,6 +65,15 @@ <h5 class="font-karla-bold">{{ selectedCommittee.committee_id }}</h5>
</p-button>
</div>
</div>
<div class="committee-card unable-card" *ngIf="unableToCreateAccount">
<div class="unable-excl-img">
<img alt="Exclamation mark" src="assets/img/exclamation.svg" />
</div>
<div class="unable-verbiage">
<p class="unable-verbiage-p1">Unable to create account</p>
<p class="unable-verbiage-p2">CONTACT FECFILE TECHNICAL SUPPORT FOR HELP</p>
</div>
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,29 @@
background-color: #ffffff;
box-shadow: 0 0 4px 0px #d1d1d1
}

.unable-card {
height: 200px;
flex-direction: column;
}
.unable-excl-img {
align-self: center;
}
.unable-verbiage {
margin-top: 10px;
}
.unable-verbiage-p1 {
text-align: center;
font-family: karla-bold, serif;
font-size: x-large;
line-height: normal;
margin-bottom: 10px;
}
.unable-verbiage-p2 {
text-align: center;
font-family: karla-bold, serif;
font-size: small;
line-height: normal;
}
.committee-info {
padding-left: 10px;
h3 {
Expand All @@ -56,6 +78,7 @@
flex-direction: column;
padding: 15px 25px;
border-radius: 5px;
margin-bottom: 30px;
}

h2 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';

import { RegisterCommitteeComponent } from './register-committee.component';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ToastModule } from 'primeng/toast';
import { DialogModule } from 'primeng/dialog';
import { ConfirmationService, MessageService } from 'primeng/api';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { provideMockStore } from '@ngrx/store/testing';
import { testMockStore } from 'app/shared/utils/unit-test.utils';
import { FecApiService } from 'app/shared/services/fec-api.service';
import { CommitteeAccount } from 'app/shared/models/committee-account.model';
import { FecFiling } from 'app/shared/models/fec-filing.model';
import { CommitteeAccountService } from 'app/shared/services/committee-account.service';
import { CommitteeAccount } from 'app/shared/models/committee-account.model';
import { FecApiService } from 'app/shared/services/fec-api.service';
import { testMockStore } from 'app/shared/utils/unit-test.utils';
import { environment } from 'environments/environment';
import { ConfirmationService, MessageService } from 'primeng/api';
import { DialogModule } from 'primeng/dialog';
import { ToastModule } from 'primeng/toast';
import { RegisterCommitteeComponent } from './register-committee.component';

describe('RegisterCommitteeComponent', () => {
let component: RegisterCommitteeComponent;
let fixture: ComponentFixture<RegisterCommitteeComponent>;
let httpTestingController: HttpTestingController;

beforeEach(() => {
TestBed.configureTestingModule({
Expand All @@ -24,6 +26,7 @@ describe('RegisterCommitteeComponent', () => {
});
fixture = TestBed.createComponent(RegisterCommitteeComponent);
component = fixture.componentInstance;
httpTestingController = TestBed.inject(HttpTestingController);
fixture.detectChanges();
});

Expand Down Expand Up @@ -62,4 +65,18 @@ describe('RegisterCommitteeComponent', () => {

expect(spy).toHaveBeenCalledWith(filing.committee_id);
});
it('should fail to register committee', waitForAsync(() => {
const filing = new FecFiling();
filing.committee_id = 'C12345678';
filing.committee_name = 'test name';
component.select(filing);
component.createAccount();
const req = httpTestingController.expectOne(`${environment.apiUrl}/committees/register/`);
expect(req.request.method).toEqual('POST');
req.flush(null);
httpTestingController.verify();
setTimeout(() => {
expect(component.unableToCreateAccount).toBeTrue();
}, 500)
}));
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class RegisterCommitteeComponent extends DestroyerComponent {
suggestions?: FecFiling[];
selectedCommittee?: CommitteeAccount;
explanationVisible = false;
unableToCreateAccount = false;

constructor(
protected fecApiService: FecApiService,
Expand All @@ -34,21 +35,27 @@ export class RegisterCommitteeComponent extends DestroyerComponent {
});
}
select(committee: FecFiling) {
this.query = undefined;
this.selectedCommittee = new CommitteeAccount();
this.selectedCommittee.name = committee.committee_name;
this.selectedCommittee.committee_id = committee.committee_id;
}
createAccount() {
this.committeeAccountService
.registerCommitteeAccount(this.selectedCommittee?.committee_id ?? '')
.then((committeeAccount) => {
this.unableToCreateAccount = false;
this.committeeAccountService.registerCommitteeAccount(this.selectedCommittee?.committee_id ?? '').then(
(committeeAccount) => {
this.messageService.add({
severity: 'success',
summary: 'Successful',
detail: `Committee Account ${committeeAccount.committee_id} Created`,
life: 3000,
});
});
},
() => {
this.unableToCreateAccount = true;
this.selectedCommittee = undefined;
},
);
}
showExplanation() {
this.explanationVisible = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('ReportDetailedSummaryComponent', () => {
fixture = TestBed.createComponent(ReportDetailedSummaryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
spyOn(apiService, 'post').and.returnValue(of(true));
spyOn(apiService, 'post').and.returnValue(of());
});

it('should create', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('ReportSummaryComponent', () => {
fixture = TestBed.createComponent(ReportDetailedSummaryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
spyOn(apiService, 'post').and.returnValue(of(true));
spyOn(apiService, 'post').and.returnValue(of());
});

it('should create', () => {
Expand Down
19 changes: 16 additions & 3 deletions front-end/src/app/shared/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ALLOW_ERROR_CODES } from '../interceptors/http-error.interceptor';
providedIn: 'root',
})
export class ApiService {
constructor(private http: HttpClient, private cookieService: CookieService) {}
constructor(private http: HttpClient, private cookieService: CookieService) { }

getHeaders(headersToAdd: object = {}) {
const csrfToken = `${this.cookieService.get('csrftoken')}`;
Expand Down Expand Up @@ -58,12 +58,25 @@ export class ApiService {
});
}

// prettier-ignore
public post<T>(endpoint: string, payload: any, queryParams: any = {}): Observable<T> { // eslint-disable-line @typescript-eslint/no-explicit-any
/* eslint-disable @typescript-eslint/no-explicit-any */
public post<T>(endpoint: string, payload: any, queryParams?: any): Observable<T>;
public post<T>(endpoint: string, payload: any, queryParams?: any, allowedErrorCodes?: number[]): Observable<HttpResponse<T>>;
public post<T>(endpoint: string, payload: any, queryParams: any = {}, allowedErrorCodes?: number[]): Observable<T> | Observable<HttpResponse<T>> {
const headers = this.getHeaders();
const params = this.getQueryParams(queryParams);
if (allowedErrorCodes) {
return this.http.post<T>(
`${environment.apiUrl}${endpoint}`, payload, {
headers: headers,
params: params,
withCredentials: true,
observe: 'response',
context: new HttpContext().set(ALLOW_ERROR_CODES, allowedErrorCodes),
});
}
return this.http.post<T>(`${environment.apiUrl}${endpoint}`, payload, { headers: headers, params: params, withCredentials: true });
}
/* eslint-enable @typescript-eslint/no-explicit-any */

// prettier-ignore
public postAbsoluteUrl<T>(endpoint: string, payload: any, queryParams: any = {}): Observable<T> { // eslint-disable-line @typescript-eslint/no-explicit-any
Expand Down
20 changes: 13 additions & 7 deletions front-end/src/app/shared/services/committee-account.service.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { HttpStatusCode } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { firstValueFrom, map, Observable } from 'rxjs';
import { CommitteeAccount } from '../models/committee-account.model';
import { FecApiService } from './fec-api.service';
import { Store } from '@ngrx/store';
import { ApiService } from './api.service';
import { ListRestResponse } from '../models/rest-api.model';
import { ApiService } from './api.service';

@Injectable({
providedIn: 'root',
})
export class CommitteeAccountService {
constructor(
private fecApiService: FecApiService,
private store: Store,
private apiService: ApiService,
) {}
) { }

public getCommittees(): Observable<CommitteeAccount[]> {
return this.apiService
Expand All @@ -32,7 +29,16 @@ export class CommitteeAccountService {

public registerCommitteeAccount(committeeId: string): Promise<CommitteeAccount> {
return firstValueFrom(
this.apiService.post<CommitteeAccount>('/committees/register/', { committee_id: committeeId }),
this.apiService.post<CommitteeAccount>('/committees/register/',
{ committee_id: committeeId }, {}, [HttpStatusCode.BadRequest])
.pipe(
map((response) => {
if (!response.body) {
throw new Error();
}
return response.body;
}),
)
);
}
}
8 changes: 8 additions & 0 deletions front-end/src/assets/img/exclamation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f174ca0

Please sign in to comment.