Skip to content

Commit 7ef8e59

Browse files
author
Luke Wesley-Holley
authored
Merge branch 'main' into copilot/fix-53057619-100534315-1719bfbb-4a1a-46ec-8717-8f5835138475
2 parents 49d26cf + 72b19a5 commit 7ef8e59

11 files changed

Lines changed: 442 additions & 204 deletions

File tree

static/js/publisher/pages/Releases/actions/__tests__/releases.test.js

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -60,48 +60,6 @@ describe("releases actions", () => {
6060
});
6161
});
6262

63-
describe("getErrorMessage", () => {
64-
it("should return the default error message if no error is defined", () => {
65-
expect(getErrorMessage({})).toEqual(ERROR_MESSAGE);
66-
});
67-
68-
it("should return error.message if defined", () => {
69-
expect(getErrorMessage({ message: "error!" })).toEqual("error!");
70-
});
71-
72-
it("should return multiple messages if errors.json is an array", () => {
73-
expect(
74-
getErrorMessage({
75-
message: "error!",
76-
json: [{ message: "error1" }, { message: "error2" }],
77-
}),
78-
).toEqual("error! error1 error2");
79-
});
80-
81-
it("should return multiple message if errors.json.errors is an array", () => {
82-
expect(
83-
getErrorMessage({
84-
message: "error!",
85-
json: { errors: [{ message: "error1" }, { message: "error2" }] },
86-
}),
87-
).toEqual("error! error1 error2");
88-
});
89-
90-
it("should return error message if errors property is an array of objects", () => {
91-
expect(
92-
getErrorMessage({
93-
errors: [
94-
{
95-
code: "invalid-field",
96-
extra: { field: "channels", value: ["latest/candidate"] },
97-
message: "error message",
98-
},
99-
],
100-
}),
101-
).toEqual("error message");
102-
});
103-
});
104-
10563
describe("handleReleaseResponse", () => {
10664
describe("RELEASE_REVISION_SUCCESS", () => {
10765
it("should be dispatched if revision is passed", () => {
@@ -234,7 +192,7 @@ describe("releases actions", () => {
234192

235193
global.fetch = vi
236194
.fn()
237-
.mockResolvedValue({ json: () => ({ sucess: true }) });
195+
.mockResolvedValue({ json: () => ({ success: true }) });
238196

239197
return store.dispatch(releaseRevisions()).then(() => {
240198
const calls = global.fetch.mock.calls;
@@ -275,7 +233,7 @@ describe("releases actions", () => {
275233

276234
global.fetch = vi
277235
.fn()
278-
.mockResolvedValue({ json: () => ({ sucess: true }) });
236+
.mockResolvedValue({ json: () => ({ success: true, channel_map_tree: {} }) });
279237

280238
return store.dispatch(releaseRevisions()).then(() => {
281239
const calls = global.fetch.mock.calls;

static/js/publisher/pages/Releases/actions/releases.ts

Lines changed: 58 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,16 @@ import {
2626
initReleasesData,
2727
} from "../releasesState";
2828
import { updateFailedRevisions } from "./failedRevisions";
29-
import { PendingReleaseItem, Release, ReleasesAPIResponse, DispatchFn, ReleasesReduxState } from "../../../types/releaseTypes";
29+
import {
30+
PendingReleaseItem,
31+
Release,
32+
ReleasesAPIResponse,
33+
DispatchFn,
34+
ReleasesReduxState,
35+
FetchReleaseResponse,
36+
FetchReleasePayload,
37+
CloseChannelsResponse,
38+
} from "../../../types/releaseTypes";
3039

3140
export const UPDATE_RELEASES = "UPDATE_RELEASES";
3241

@@ -37,9 +46,7 @@ function updateReleasesData(apiData: ReleasesAPIResponse) {
3746
channel_map: channelMap,
3847
snap_name: snapName,
3948
} = apiData.data;
40-
return (
41-
dispatch: DispatchFn,
42-
) => {
49+
return (dispatch: DispatchFn) => {
4350
const revisionsList = releasesData.revisions;
4451
const releases = releasesData.releases;
4552

@@ -53,12 +60,16 @@ function updateReleasesData(apiData: ReleasesAPIResponse) {
5360
dispatch(updateArchitectures(revisionsList));
5461
dispatch(initChannelMap(transformedChannelMap));
5562
dispatch(updateFailedRevisions(failedRevisions));
56-
},
63+
}
5764
);
5865
};
5966
}
6067

61-
export function handleCloseResponse(dispatch: DispatchFn, json: any, channels: any) {
68+
export function handleCloseResponse(
69+
dispatch: DispatchFn,
70+
json: CloseChannelsResponse,
71+
channels: ReleasesReduxState["pendingCloses"]
72+
) {
6273
if (json.success) {
6374
if (json.closed_channels && json.closed_channels.length > 0) {
6475
json.closed_channels.forEach((channel: string) => {
@@ -73,46 +84,19 @@ export function handleCloseResponse(dispatch: DispatchFn, json: any, channels: a
7384
}
7485
} else {
7586
const error = new Error(
76-
`Error while closing channels: ${channels.join(", ")}.`,
87+
`Error while closing channels: ${channels.join(", ")}.`
7788
);
7889
// @ts-ignore
7990
error.json = json;
8091
throw error;
8192
}
8293
}
8394

84-
export function getErrorMessage(error: {
85-
message?: any;
86-
json?: any;
87-
errors?: any;
88-
}) {
89-
let message = error.message || ERROR_MESSAGE;
90-
91-
if (error.errors && error.errors.length > 0) {
92-
message = error.errors[0].message;
93-
}
94-
95-
// try to find error messages in response json
96-
// which may be an array or errors or object with errors propery
97-
if (error.json) {
98-
const errors = error.json.length ? error.json : error.json.errors;
99-
100-
if (errors.length) {
101-
message = `${message} ${errors
102-
.map((e: { message: any }) => e.message)
103-
.filter((m: any) => m)
104-
.join(" ")}`;
105-
}
106-
}
107-
108-
return message;
109-
}
110-
11195
export function handleReleaseResponse(
11296
dispatch: DispatchFn,
113-
json: any,
114-
release: any,
115-
revisions: any,
97+
json: FetchReleaseResponse,
98+
release: FetchReleasePayload,
99+
revisions: ReleasesReduxState["revisions"]
116100
) {
117101
if (json.success) {
118102
// Update channel map based on the response
@@ -123,41 +107,39 @@ export function handleReleaseResponse(
123107
const series = track[seriesKey];
124108
Object.keys(series).forEach((archKey) => {
125109
const arch = series[archKey];
126-
arch.forEach(
127-
(map: { revision: number; version: any; channel: any }) => {
128-
if (map.revision) {
129-
let revision;
130-
131-
if (map.revision === +release.id) {
132-
// release.id is a string so turn it into a number for comparison
133-
revision = release.revision;
134-
} else if (revisions[map.revision]) {
135-
revision = revisions[map.revision];
136-
} else {
137-
revision = {
138-
revision: map.revision,
139-
version: map.version,
140-
architectures: release.revision.architectures,
141-
};
142-
}
143-
144-
const channel = `${trackKey}/${map.channel}`;
145-
dispatch(releaseRevisionSuccess(revision, channel));
110+
arch.forEach((map) => {
111+
if (map.revision) {
112+
let revision;
113+
114+
if (map.revision === +release.id) {
115+
// release.id is a string so turn it into a number for comparison
116+
revision = release.revision;
117+
} else if (revisions[map.revision]) {
118+
revision = revisions[map.revision];
119+
} else {
120+
revision = {
121+
revision: map.revision,
122+
version: map.version,
123+
architectures: release.revision.architectures,
124+
};
146125
}
147-
},
148-
);
126+
127+
const channel = `${trackKey}/${map.channel}`;
128+
dispatch(releaseRevisionSuccess(revision, channel));
129+
}
130+
});
149131
});
150132
});
151133
});
152134
} else {
153-
if (json.errors) {
154-
throw new Error(json.errors[0]);
155-
}
135+
throw new Error(json.errors[0]);
156136
}
157137
}
158138

159139
export function releaseRevisions() {
160-
const mapToRelease = (pendingRelease: PendingReleaseItem) => {
140+
const mapToRelease = (
141+
pendingRelease: PendingReleaseItem
142+
): FetchReleasePayload => {
161143
let progressive = null;
162144

163145
if (
@@ -175,21 +157,13 @@ export function releaseRevisions() {
175157
};
176158
};
177159

178-
return (
179-
dispatch: DispatchFn,
180-
getState: () => ReleasesReduxState,
181-
) => {
160+
return (dispatch: DispatchFn, getState: () => ReleasesReduxState) => {
182161
const { pendingReleases, pendingCloses, revisions, options } = getState();
183162
const { snapName } = options;
184163

185164
// To dedupe releases
186-
const progressiveReleases: {
187-
id: number;
188-
revision: PendingReleaseItem["revision"];
189-
channels: PendingReleaseItem["channel"][];
190-
progressive: PendingReleaseItem["progressive"] | null;
191-
}[] = [];
192-
const regularReleases: Array<any> = [];
165+
const progressiveReleases: FetchReleasePayload[] = [];
166+
const regularReleases: FetchReleasePayload[] = [];
193167
Object.keys(pendingReleases).forEach((revId) => {
194168
Object.keys(pendingReleases[revId]).forEach((channel) => {
195169
const pendingRelease = pendingReleases[revId][channel];
@@ -199,8 +173,7 @@ export function releaseRevisions() {
199173
progressiveReleases.push(mapToRelease(pendingRelease));
200174
} else {
201175
const releaseIndex = regularReleases.findIndex(
202-
(release: { revision: { revision: number } }) =>
203-
release.revision.revision === parseInt(revId),
176+
(release) => release.revision.revision === parseInt(revId)
204177
);
205178
if (releaseIndex === -1) {
206179
regularReleases.push(mapToRelease(pendingRelease));
@@ -214,36 +187,30 @@ export function releaseRevisions() {
214187
const releases = progressiveReleases.concat(regularReleases);
215188

216189
const _handleReleaseResponse = (
217-
json: { success: boolean; channel_map_tree: any; errors?: any },
218-
release: { id: number; revision: number; channels: string[] }[],
190+
json: FetchReleaseResponse,
191+
release: FetchReleasePayload
219192
) => {
220193
return handleReleaseResponse(dispatch, json, release, revisions);
221194
};
222195

223-
const _handleCloseResponse = (json: {
224-
success?: boolean;
225-
closed_channels?: string[];
226-
error?: boolean;
227-
json?: string;
228-
}) => {
196+
const _handleCloseResponse = (json: CloseChannelsResponse) => {
229197
return handleCloseResponse(dispatch, json, pendingCloses);
230198
};
231199

232200
dispatch(hideNotification());
201+
233202
return fetchReleases(_handleReleaseResponse, releases, snapName)
234203
.then(() => fetchCloses(_handleCloseResponse, snapName, pendingCloses))
235204
.then(() => fetchSnapReleaseStatus(snapName))
236-
.then((json) =>
237-
dispatch(updateReleasesData(json)),
238-
)
239-
.catch((error) =>
205+
.then((json) => dispatch(updateReleasesData(json)))
206+
.catch(() =>
240207
dispatch(
241208
showNotification({
242209
status: "error",
243210
appearance: "negative",
244-
content: getErrorMessage(error),
245-
}),
246-
),
211+
content: ERROR_MESSAGE,
212+
})
213+
)
247214
)
248215
.then(() => dispatch(cancelPendingReleases()))
249216
.then(() => dispatch(closeHistory()));

0 commit comments

Comments
 (0)