Skip to content

Commit d5a46fa

Browse files
committed
implement addon icon upload
1 parent 52656dc commit d5a46fa

File tree

4 files changed

+110
-14
lines changed

4 files changed

+110
-14
lines changed

Diff for: src/cmd/sign.js

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default function sign(
4141
channel,
4242
amoMetadata,
4343
uploadSourceCode,
44+
iconFile,
4445
webextVersion,
4546
},
4647
{
@@ -154,6 +155,7 @@ export default function sign(
154155
approvalCheckTimeout:
155156
approvalTimeout !== undefined ? approvalTimeout : timeout,
156157
submissionSource: uploadSourceCode,
158+
iconFile,
157159
});
158160
} else {
159161
const {

Diff for: src/program.js

+7
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,13 @@ Example: $0 --help run.
609609
'details. Only used with `use-submission-api`',
610610
type: 'string',
611611
},
612+
'icon-file': {
613+
describe:
614+
'Path to an image that should be displayed as the addon icon on ' +
615+
'addons.mozilla.org. Must be square; 128px x 128px is recommended. ' +
616+
'Only used with `use-submission-api`',
617+
type: 'string',
618+
},
612619
},
613620
)
614621
.command('run', 'Run the extension', commands.run, {

Diff for: src/util/submit-addon.js

+26-11
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,18 @@ export default class Client {
186186
}
187187

188188
async doFormDataPatch(data, addonId, versionId) {
189-
const patchUrl = new URL(
190-
`addon/${addonId}/versions/${versionId}/`,
191-
this.apiUrl,
192-
);
189+
let patchUrl;
190+
if (versionId) {
191+
log.info(`Submitting ${Object.keys(data)} to the version`);
192+
patchUrl = new URL(
193+
`addon/${addonId}/versions/${versionId}/`,
194+
this.apiUrl,
195+
);
196+
} else {
197+
log.info(`Submitting ${Object.keys(data)} to the addon`);
198+
patchUrl = new URL(`addon/${addonId}/`, this.apiUrl);
199+
}
200+
193201
try {
194202
const formData = new FormData();
195203
for (const field in data) {
@@ -207,15 +215,20 @@ export default class Client {
207215
}
208216

209217
async doAfterSubmit(addonId, newVersionId, editUrl, patchData) {
218+
const promises = [];
210219
if (patchData && patchData.version) {
211-
log.info(`Submitting ${Object.keys(patchData.version)} to version`);
212-
await this.doFormDataPatch(patchData.version, addonId, newVersionId);
220+
promises.push(
221+
this.doFormDataPatch(patchData.version, addonId, newVersionId),
222+
);
223+
}
224+
if (patchData && patchData.addon) {
225+
promises.push(this.doFormDataPatch(patchData.addon, addonId));
213226
}
227+
await Promise.all(promises);
228+
214229
if (this.approvalCheckTimeout > 0) {
215-
const fileUrl = new URL(
216-
await this.waitForApproval(addonId, newVersionId),
217-
);
218-
return this.downloadSignedFile(fileUrl, addonId);
230+
const fileUrl = await this.waitForApproval(addonId, newVersionId);
231+
return this.downloadSignedFile(new URL(fileUrl), addonId);
219232
} else {
220233
log.info('Waiting for approval and download of signed xpi skipped.');
221234
log.info(
@@ -415,6 +428,7 @@ export async function signAddon({
415428
savedUploadUuidPath,
416429
metaDataJson = {},
417430
submissionSource,
431+
iconFile,
418432
userAgentString,
419433
SubmitClient = Client,
420434
ApiAuthClass = JwtApiAuth,
@@ -450,11 +464,12 @@ export async function signAddon({
450464
channel,
451465
savedUploadUuidPath,
452466
);
453-
// if we have a source file we need to upload we patch after the create
467+
// if we have a source or icon file we need to upload we patch after the create
454468
const patchData = {
455469
version: submissionSource
456470
? { source: client.fileFromSync(submissionSource) }
457471
: undefined,
472+
addon: iconFile ? { icon: client.fileFromSync(iconFile) } : undefined,
458473
};
459474

460475
// We specifically need to know if `id` has not been passed as a parameter because

Diff for: tests/unit/test-util/test.submit-addon.js

+75-3
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ describe('util.submit-addon', () => {
208208
uploadUuid,
209209
signAddonDefaults.savedIdPath,
210210
{},
211-
{ version: { source: fakeFileFromSync } },
211+
{ version: { source: fakeFileFromSync }, addon: undefined },
212212
);
213213
});
214214

@@ -227,7 +227,43 @@ describe('util.submit-addon', () => {
227227
uploadUuid,
228228
id,
229229
{},
230-
{ version: { source: fakeFileFromSync } },
230+
{ version: { source: fakeFileFromSync }, addon: undefined },
231+
);
232+
});
233+
234+
it('includes icon data to be patched if iconFile defined for new addon', async () => {
235+
const iconFile = 'path/to/icon/image';
236+
await signAddon({
237+
...signAddonDefaults,
238+
iconFile,
239+
});
240+
241+
sinon.assert.calledWith(fileFromSyncStub, iconFile);
242+
sinon.assert.calledWith(
243+
postNewAddonStub,
244+
uploadUuid,
245+
signAddonDefaults.savedIdPath,
246+
{},
247+
{ version: undefined, addon: { icon: fakeFileFromSync } },
248+
);
249+
});
250+
251+
it('includes icon data to be patched if iconFile defined for new version', async () => {
252+
const iconFile = 'path/to/icon/image';
253+
const id = '@thisID';
254+
await signAddon({
255+
...signAddonDefaults,
256+
iconFile,
257+
id,
258+
});
259+
260+
sinon.assert.calledWith(fileFromSyncStub, iconFile);
261+
sinon.assert.calledWith(
262+
putVersionStub,
263+
uploadUuid,
264+
id,
265+
{},
266+
{ version: undefined, addon: { icon: fakeFileFromSync } },
231267
);
232268
});
233269
});
@@ -1009,7 +1045,6 @@ describe('util.submit-addon', () => {
10091045
const downloadUrl = 'https://a.download/url';
10101046
const newVersionId = sampleVersionDetail.id;
10111047
const editUrl = sampleVersionDetail.editUrl;
1012-
const patchData = { version: { source: 'somesource' } };
10131048

10141049
let approvalStub;
10151050
let downloadStub;
@@ -1047,8 +1082,45 @@ describe('util.submit-addon', () => {
10471082

10481083
it('calls doFormDataPatch if patchData.version is defined', async () => {
10491084
client.approvalCheckTimeout = 0;
1085+
const patchData = { version: { source: 'somesource' } };
10501086
await client.doAfterSubmit(addonId, newVersionId, editUrl, patchData);
10511087

1088+
sinon.assert.calledOnce(doFormDataPatchStub);
1089+
sinon.assert.calledWith(
1090+
doFormDataPatchStub,
1091+
patchData.version,
1092+
addonId,
1093+
newVersionId,
1094+
);
1095+
});
1096+
1097+
it('calls doFormDataPatch if patchData.addon is defined', async () => {
1098+
client.approvalCheckTimeout = 0;
1099+
const patchData = { addon: { icon: 'someimage' } };
1100+
await client.doAfterSubmit(addonId, newVersionId, editUrl, patchData);
1101+
1102+
sinon.assert.calledOnce(doFormDataPatchStub);
1103+
sinon.assert.calledWith(
1104+
doFormDataPatchStub,
1105+
patchData.addon,
1106+
addonId,
1107+
);
1108+
});
1109+
1110+
it('calls doFormDataPatch twice if patchData.addon and patchData.version is defined', async () => {
1111+
client.approvalCheckTimeout = 0;
1112+
const patchData = {
1113+
version: { source: 'somesource' },
1114+
addon: { icon: 'someimage' },
1115+
};
1116+
await client.doAfterSubmit(addonId, newVersionId, editUrl, patchData);
1117+
1118+
sinon.assert.callCount(doFormDataPatchStub, 2);
1119+
sinon.assert.calledWith(
1120+
doFormDataPatchStub,
1121+
patchData.addon,
1122+
addonId,
1123+
);
10521124
sinon.assert.calledWith(
10531125
doFormDataPatchStub,
10541126
patchData.version,

0 commit comments

Comments
 (0)