Skip to content

Commit 8c72123

Browse files
authored
feat: delete crashes (#131)
* feat: delete crashes * fix: post notes
1 parent 732d5e9 commit 8c72123

File tree

3 files changed

+108
-58
lines changed

3 files changed

+108
-58
lines changed

src/common/data/table-data/table-data-client/table-data-client.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
import { ApiClient, TableDataRequest, BugSplatResponse, TableDataResponse } from '@common';
1+
import {
2+
ApiClient,
3+
TableDataRequest,
4+
BugSplatResponse,
5+
TableDataResponse,
6+
} from '@common';
27
import { TableDataFormDataBuilder } from '../table-data-form-data-builder/table-data-form-data-builder';
38

49
export class TableDataClient {
5-
6-
constructor(private _apiClient: ApiClient, private _url: string) { }
10+
constructor(private _apiClient: ApiClient, private _url: string) {}
711

812
// We use POST to get data in most cases because it supports longer queries
9-
async postGetData<T, U = (Record<string, unknown> | undefined)>(request: TableDataRequest, formParts: Record<string, string> = {}): Promise<BugSplatResponse<TableDataResponse<T, U>>> {
13+
async postGetData<T, U = Record<string, unknown> | undefined>(
14+
request: TableDataRequest,
15+
formParts: Record<string, string> = {}
16+
): Promise<BugSplatResponse<TableDataResponse<T, U>>> {
1017
const factory = () => this._apiClient.createFormData();
1118
const formData = new TableDataFormDataBuilder(factory, formParts)
1219
.withDatabase(request.database)
@@ -23,12 +30,14 @@ export class TableDataClient {
2330
cache: 'no-cache',
2431
credentials: 'include',
2532
redirect: 'follow',
26-
duplex: 'half'
33+
duplex: 'half',
2734
} as RequestInit;
2835
return this.makeRequest<T, U>(this._url, requestInit);
2936
}
3037

31-
async getData<T, U = (Record<string, unknown> | undefined)>(request: TableDataRequest): Promise<BugSplatResponse<TableDataResponse<T, U>>> {
38+
async getData<T, U = Record<string, unknown> | undefined>(
39+
request: TableDataRequest
40+
): Promise<BugSplatResponse<TableDataResponse<T, U>>> {
3241
const factory = () => this._apiClient.createFormData();
3342
const formData = new TableDataFormDataBuilder(factory)
3443
.withDatabase(request.database)
@@ -43,17 +52,30 @@ export class TableDataClient {
4352
method: 'GET',
4453
cache: 'no-cache',
4554
credentials: 'include',
46-
redirect: 'follow'
55+
redirect: 'follow',
4756
} as RequestInit;
4857
const queryParams = new URLSearchParams(formData).toString();
4958
return this.makeRequest<T, U>(`${this._url}?${queryParams}`, requestInit);
5059
}
5160

52-
private async makeRequest<T, U = unknown>(url: string, init: RequestInit): Promise<BugSplatResponse<TableDataResponse<T, U>>> {
53-
const response = await this._apiClient.fetch<RawResponse<TableDataResponse<T,U>>>(url, init);
61+
private async makeRequest<T, U = unknown>(
62+
url: string,
63+
init: RequestInit
64+
): Promise<BugSplatResponse<TableDataResponse<T, U>>> {
65+
const response = await this._apiClient.fetch<
66+
RawResponse<TableDataResponse<T, U>> | TableDataResponse<T, U>
67+
>(url, init);
5468
const responseData = await response.json();
55-
const rows = responseData ? responseData[0]?.Rows : [];
56-
const pageData = responseData ? responseData[0]?.PageData : {};
69+
70+
// Handle legacy and new API responses until we can upgrade legacy APIs
71+
const rows =
72+
(responseData as TableDataResponse<T, U>)?.rows ??
73+
responseData?.[0]?.Rows ??
74+
[];
75+
const pageData =
76+
(responseData as TableDataResponse<T, U>)?.pageData ??
77+
responseData?.[0]?.PageData ??
78+
{};
5779

5880
const status = response.status;
5981
const body = response.body;
@@ -64,13 +86,12 @@ export class TableDataClient {
6486
status,
6587
body,
6688
json,
67-
text
89+
text,
6890
};
6991
}
7092
}
7193

7294
// https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as
7395
export type RawResponse<T> = Array<{
74-
[Property in keyof T as Capitalize<string & Property>]: T[Property]
75-
}>
76-
96+
[Property in keyof T as Capitalize<string & Property>]: T[Property];
97+
}>;

src/crashes/crashes-api-client/crashes-api-client.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ describe('CrashesApiClient', () => {
7676
});
7777

7878
it('should call fetch with correct route', () => {
79-
expect(apiClient.fetch).toHaveBeenCalledWith('/allcrash?data', jasmine.anything());
79+
expect(apiClient.fetch).toHaveBeenCalledWith('/browse/allcrash.php', jasmine.anything());
8080
});
8181

8282
it('should call fetch with requestInit containing formData', () => {
Lines changed: 71 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,76 @@
1-
import { ApiClient, BugSplatResponse, TableDataClient, TableDataRequest, TableDataResponse } from '@common';
1+
import {
2+
ApiClient,
3+
BugSplatResponse,
4+
TableDataClient,
5+
TableDataRequest,
6+
TableDataResponse,
7+
} from '@common';
28
import { CrashesApiRow, CrashesPageData } from '@crashes';
39
import { CrashesApiResponseRow } from '../crashes-api-row/crashes-api-row';
410

511
export class CrashesApiClient {
12+
private _tableDataClient: TableDataClient;
613

7-
private _tableDataClient: TableDataClient;
8-
9-
constructor(private _client: ApiClient) {
10-
this._tableDataClient = new TableDataClient(this._client, '/allcrash?data');
11-
}
12-
13-
async getCrashes(request: TableDataRequest): Promise<TableDataResponse<CrashesApiRow, CrashesPageData>> {
14-
const response = await this._tableDataClient.postGetData<CrashesApiResponseRow, CrashesPageData>(request);
15-
const json = await response.json();
16-
const pageData = json.pageData;
17-
const rows = json.rows.map(row => new CrashesApiRow(row));
18-
19-
return {
20-
rows,
21-
pageData
22-
};
23-
}
24-
25-
postNotes(
26-
database: string,
27-
id: number,
28-
notes: string
29-
): Promise<BugSplatResponse> {
30-
const formData = this._client.createFormData();
31-
formData.append('update', 'true');
32-
formData.append('database', database);
33-
formData.append('id', `${id}`);
34-
formData.append('Comments', notes);
35-
36-
const request = {
37-
method: 'POST',
38-
body: formData,
39-
cache: 'no-cache',
40-
credentials: 'include',
41-
redirect: 'follow',
42-
duplex: 'half'
43-
} as RequestInit;
44-
45-
return this._client.fetch('/allcrash?data', request);
46-
}
47-
}
14+
constructor(private _client: ApiClient) {
15+
this._tableDataClient = new TableDataClient(
16+
this._client,
17+
'/api/crashes.php'
18+
);
19+
}
20+
21+
async deleteCrashes(
22+
database: string,
23+
ids: number[]
24+
): Promise<BugSplatResponse> {
25+
const urlParams = new URLSearchParams({ database, ids: ids.join(',') });
26+
const request = {
27+
method: 'DELETE',
28+
cache: 'no-cache',
29+
credentials: 'include',
30+
redirect: 'follow',
31+
duplex: 'half',
32+
} as RequestInit;
33+
return this._client.fetch(`/api/crashes.php?${urlParams}`, request);
34+
}
35+
36+
async getCrashes(
37+
request: TableDataRequest
38+
): Promise<TableDataResponse<CrashesApiRow, CrashesPageData>> {
39+
const response = await this._tableDataClient.postGetData<
40+
CrashesApiResponseRow,
41+
CrashesPageData
42+
>(request);
43+
const json = await response.json();
44+
const pageData = json.pageData;
45+
const rows = json.rows.map((row) => new CrashesApiRow(row));
46+
47+
return {
48+
rows,
49+
pageData,
50+
};
51+
}
52+
53+
// TODO BG we should move this to an api/crash/notes endpoint and reture allcrash
54+
postNotes(
55+
database: string,
56+
id: number,
57+
notes: string
58+
): Promise<BugSplatResponse> {
59+
const formData = this._client.createFormData();
60+
formData.append('update', 'true');
61+
formData.append('database', database);
62+
formData.append('id', `${id}`);
63+
formData.append('Comments', notes);
64+
65+
const request = {
66+
method: 'POST',
67+
body: formData,
68+
cache: 'no-cache',
69+
credentials: 'include',
70+
redirect: 'follow',
71+
duplex: 'half',
72+
} as RequestInit;
73+
74+
return this._client.fetch('/browse/allcrash.php', request);
75+
}
76+
}

0 commit comments

Comments
 (0)