Skip to content

Commit

Permalink
implement addon icon upload
Browse files Browse the repository at this point in the history
  • Loading branch information
eviljeff committed Sep 5, 2023
1 parent 52656dc commit d5a46fa
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/cmd/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default function sign(
channel,
amoMetadata,
uploadSourceCode,
iconFile,
webextVersion,
},
{
Expand Down Expand Up @@ -154,6 +155,7 @@ export default function sign(
approvalCheckTimeout:
approvalTimeout !== undefined ? approvalTimeout : timeout,
submissionSource: uploadSourceCode,
iconFile,
});
} else {
const {
Expand Down
7 changes: 7 additions & 0 deletions src/program.js
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,13 @@ Example: $0 --help run.
'details. Only used with `use-submission-api`',
type: 'string',
},
'icon-file': {
describe:
'Path to an image that should be displayed as the addon icon on ' +
'addons.mozilla.org. Must be square; 128px x 128px is recommended. ' +
'Only used with `use-submission-api`',
type: 'string',
},
},
)
.command('run', 'Run the extension', commands.run, {
Expand Down
37 changes: 26 additions & 11 deletions src/util/submit-addon.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,18 @@ export default class Client {
}

async doFormDataPatch(data, addonId, versionId) {
const patchUrl = new URL(
`addon/${addonId}/versions/${versionId}/`,
this.apiUrl,
);
let patchUrl;
if (versionId) {
log.info(`Submitting ${Object.keys(data)} to the version`);
patchUrl = new URL(
`addon/${addonId}/versions/${versionId}/`,
this.apiUrl,
);
} else {
log.info(`Submitting ${Object.keys(data)} to the addon`);
patchUrl = new URL(`addon/${addonId}/`, this.apiUrl);
}

try {
const formData = new FormData();
for (const field in data) {
Expand All @@ -207,15 +215,20 @@ export default class Client {
}

async doAfterSubmit(addonId, newVersionId, editUrl, patchData) {
const promises = [];
if (patchData && patchData.version) {
log.info(`Submitting ${Object.keys(patchData.version)} to version`);
await this.doFormDataPatch(patchData.version, addonId, newVersionId);
promises.push(
this.doFormDataPatch(patchData.version, addonId, newVersionId),
);
}
if (patchData && patchData.addon) {
promises.push(this.doFormDataPatch(patchData.addon, addonId));
}
await Promise.all(promises);

if (this.approvalCheckTimeout > 0) {
const fileUrl = new URL(
await this.waitForApproval(addonId, newVersionId),
);
return this.downloadSignedFile(fileUrl, addonId);
const fileUrl = await this.waitForApproval(addonId, newVersionId);
return this.downloadSignedFile(new URL(fileUrl), addonId);
} else {
log.info('Waiting for approval and download of signed xpi skipped.');
log.info(
Expand Down Expand Up @@ -415,6 +428,7 @@ export async function signAddon({
savedUploadUuidPath,
metaDataJson = {},
submissionSource,
iconFile,
userAgentString,
SubmitClient = Client,
ApiAuthClass = JwtApiAuth,
Expand Down Expand Up @@ -450,11 +464,12 @@ export async function signAddon({
channel,
savedUploadUuidPath,
);
// if we have a source file we need to upload we patch after the create
// if we have a source or icon file we need to upload we patch after the create
const patchData = {
version: submissionSource
? { source: client.fileFromSync(submissionSource) }
: undefined,
addon: iconFile ? { icon: client.fileFromSync(iconFile) } : undefined,
};

// We specifically need to know if `id` has not been passed as a parameter because
Expand Down
78 changes: 75 additions & 3 deletions tests/unit/test-util/test.submit-addon.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ describe('util.submit-addon', () => {
uploadUuid,
signAddonDefaults.savedIdPath,
{},
{ version: { source: fakeFileFromSync } },
{ version: { source: fakeFileFromSync }, addon: undefined },
);
});

Expand All @@ -227,7 +227,43 @@ describe('util.submit-addon', () => {
uploadUuid,
id,
{},
{ version: { source: fakeFileFromSync } },
{ version: { source: fakeFileFromSync }, addon: undefined },
);
});

it('includes icon data to be patched if iconFile defined for new addon', async () => {
const iconFile = 'path/to/icon/image';
await signAddon({
...signAddonDefaults,
iconFile,
});

sinon.assert.calledWith(fileFromSyncStub, iconFile);
sinon.assert.calledWith(
postNewAddonStub,
uploadUuid,
signAddonDefaults.savedIdPath,
{},
{ version: undefined, addon: { icon: fakeFileFromSync } },
);
});

it('includes icon data to be patched if iconFile defined for new version', async () => {
const iconFile = 'path/to/icon/image';
const id = '@thisID';
await signAddon({
...signAddonDefaults,
iconFile,
id,
});

sinon.assert.calledWith(fileFromSyncStub, iconFile);
sinon.assert.calledWith(
putVersionStub,
uploadUuid,
id,
{},
{ version: undefined, addon: { icon: fakeFileFromSync } },
);
});
});
Expand Down Expand Up @@ -1009,7 +1045,6 @@ describe('util.submit-addon', () => {
const downloadUrl = 'https://a.download/url';
const newVersionId = sampleVersionDetail.id;
const editUrl = sampleVersionDetail.editUrl;
const patchData = { version: { source: 'somesource' } };

let approvalStub;
let downloadStub;
Expand Down Expand Up @@ -1047,8 +1082,45 @@ describe('util.submit-addon', () => {

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

sinon.assert.calledOnce(doFormDataPatchStub);
sinon.assert.calledWith(
doFormDataPatchStub,
patchData.version,
addonId,
newVersionId,
);
});

it('calls doFormDataPatch if patchData.addon is defined', async () => {
client.approvalCheckTimeout = 0;
const patchData = { addon: { icon: 'someimage' } };
await client.doAfterSubmit(addonId, newVersionId, editUrl, patchData);

sinon.assert.calledOnce(doFormDataPatchStub);
sinon.assert.calledWith(
doFormDataPatchStub,
patchData.addon,
addonId,
);
});

it('calls doFormDataPatch twice if patchData.addon and patchData.version is defined', async () => {
client.approvalCheckTimeout = 0;
const patchData = {
version: { source: 'somesource' },
addon: { icon: 'someimage' },
};
await client.doAfterSubmit(addonId, newVersionId, editUrl, patchData);

sinon.assert.callCount(doFormDataPatchStub, 2);
sinon.assert.calledWith(
doFormDataPatchStub,
patchData.addon,
addonId,
);
sinon.assert.calledWith(
doFormDataPatchStub,
patchData.version,
Expand Down

0 comments on commit d5a46fa

Please sign in to comment.