Skip to content

Commit 6de6225

Browse files
committed
crate.settings: Add "Remove" button to Trusted Publishing configs
1 parent 018a809 commit 6de6225

File tree

5 files changed

+114
-2
lines changed

5 files changed

+114
-2
lines changed

app/controllers/crate/settings.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { task } from 'ember-concurrency';
77

88
export default class CrateSettingsController extends Controller {
99
@service notifications;
10+
@service store;
1011

1112
crate = null;
1213
username = '';
@@ -64,6 +65,22 @@ export default class CrateSettingsController extends Controller {
6465
this.notifications.error(message);
6566
}
6667
});
68+
69+
removeConfigTask = task(async config => {
70+
try {
71+
await config.destroyRecord();
72+
this.notifications.success('Trusted Publishing configuration removed successfully');
73+
} catch (error) {
74+
let message = 'Failed to remove Trusted Publishing configuration';
75+
76+
let detail = error.errors?.[0]?.detail;
77+
if (detail && !detail.startsWith('{')) {
78+
message += `: ${detail}`;
79+
}
80+
81+
this.notifications.error(message);
82+
}
83+
});
6784
}
6885

6986
function removeOwner(owners, target) {

app/styles/crate/settings.module.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@
6161
font-size: 0.85em;
6262
line-height: 1.5;
6363
}
64+
65+
.actions {
66+
text-align: right;
67+
}
6468
}
6569

6670
.email-column {

app/templates/crate/settings.hbs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<tr>
6464
<th>Publisher</th>
6565
<th>Details</th>
66+
<th></th>
6667
</tr>
6768
</thead>
6869
<tbody>
@@ -76,10 +77,13 @@
7677
<strong>Environment:</strong> {{config.environment}}
7778
{{/if}}
7879
</td>
80+
<td local-class="actions">
81+
<button type="button" class="button button--small" data-test-remove-config-button {{on "click" (perform this.removeConfigTask config)}}>Remove</button>
82+
</td>
7983
</tr>
8084
{{else}}
8185
<tr data-test-no-config>
82-
<td colspan="2">No trusted publishers configured for this crate.</td>
86+
<td colspan="3">No trusted publishers configured for this crate.</td>
8387
</tr>
8488
{{/each}}
8589
</tbody>

e2e/routes/crate/settings.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { expect, test } from '@/e2e/helper';
2+
import { click } from '@ember/test-helpers';
3+
import { http, HttpResponse } from 'msw';
24

35
test.describe('Route | crate.settings', { tag: '@routes' }, () => {
46
async function prepare(msw) {
@@ -90,12 +92,55 @@ test.describe('Route | crate.settings', { tag: '@routes' }, () => {
9092
await expect(details).toContainText('Repository: rust-lang/crates.io');
9193
await expect(details).toContainText('Workflow: ci.yml');
9294
await expect(details).not.toContainText('Environment');
95+
await expect(page.locator('[data-test-github-config="1"] [data-test-remove-config-button]')).toBeVisible();
9396
await expect(page.locator('[data-test-github-config="2"] td:nth-child(1)')).toHaveText('GitHub');
9497
details = page.locator('[data-test-github-config="2"] td:nth-child(2)');
9598
await expect(details).toContainText('Repository: johndoe/crates.io');
9699
await expect(details).toContainText('Workflow: release.yml');
97100
await expect(details).toContainText('Environment: release');
101+
await expect(page.locator('[data-test-github-config="2"] [data-test-remove-config-button]')).toBeVisible();
98102
await expect(page.locator('[data-test-no-config]')).not.toBeVisible();
103+
104+
// Click the remove button
105+
await page.click('[data-test-github-config="2"] [data-test-remove-config-button]');
106+
107+
// Check that the config is no longer displayed
108+
await expect(page.locator('[data-test-github-config]')).toHaveCount(1);
109+
details = page.locator('[data-test-github-config="1"] td:nth-child(2)');
110+
await expect(details).toContainText('Repository: rust-lang/crates.io');
111+
await expect(page.locator('[data-test-notification-message]')).toHaveText(
112+
'Trusted Publishing configuration removed successfully',
113+
);
114+
});
115+
116+
test('deletion failure', async ({ msw, page, percy }) => {
117+
let { crate } = await prepare(msw);
118+
119+
// Create a GitHub config for the crate
120+
let config = msw.db.trustpubGithubConfig.create({
121+
crate,
122+
repository_owner: 'rust-lang',
123+
repository_name: 'crates.io',
124+
workflow_filename: 'ci.yml',
125+
environment: 'release',
126+
});
127+
128+
// Mock the server to return an error when trying to delete the config
129+
await msw.worker.use(
130+
http.delete(`/api/v1/trusted_publishing/github_configs/${config.id}`, () => {
131+
return HttpResponse.json({ errors: [{ detail: 'Server error' }] }, { status: 500 });
132+
}),
133+
);
134+
135+
await page.goto(`/crates/${crate.name}/settings`);
136+
await expect(page).toHaveURL(`/crates/${crate.name}/settings`);
137+
await expect(page.locator('[data-test-github-config]')).toHaveCount(1);
138+
139+
await page.click('[data-test-remove-config-button]');
140+
await expect(page.locator('[data-test-github-config]')).toHaveCount(1);
141+
await expect(page.locator('[data-test-notification-message]')).toHaveText(
142+
'Failed to remove Trusted Publishing configuration: Server error',
143+
);
99144
});
100145
});
101146
});

tests/routes/crate/settings-test.js

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { currentURL } from '@ember/test-helpers';
1+
import { click, currentURL } from '@ember/test-helpers';
22
import { module, test } from 'qunit';
33

44
import percySnapshot from '@percy/ember';
5+
import { http, HttpResponse } from 'msw';
56

67
import { setupApplicationTest } from 'crates-io/tests/helpers';
78

@@ -96,11 +97,52 @@ module('Route | crate.settings', hooks => {
9697
assert.dom('[data-test-github-config="1"] td:nth-child(2)').includesText('Repository: rust-lang/crates.io');
9798
assert.dom('[data-test-github-config="1"] td:nth-child(2)').includesText('Workflow: ci.yml');
9899
assert.dom('[data-test-github-config="1"] td:nth-child(2)').doesNotIncludeText('Environment');
100+
assert.dom('[data-test-github-config="1"] [data-test-remove-config-button]').exists();
99101
assert.dom('[data-test-github-config="2"] td:nth-child(1)').hasText('GitHub');
100102
assert.dom('[data-test-github-config="2"] td:nth-child(2)').includesText('Repository: johndoe/crates.io');
101103
assert.dom('[data-test-github-config="2"] td:nth-child(2)').includesText('Workflow: release.yml');
102104
assert.dom('[data-test-github-config="2"] td:nth-child(2)').includesText('Environment: release');
105+
assert.dom('[data-test-github-config="2"] [data-test-remove-config-button]').exists();
103106
assert.dom('[data-test-no-config]').doesNotExist();
107+
108+
// Click the remove button
109+
await click('[data-test-github-config="2"] [data-test-remove-config-button]');
110+
111+
// Check that the config is no longer displayed
112+
assert.dom('[data-test-github-config]').exists({ count: 1 });
113+
assert.dom('[data-test-github-config="1"] td:nth-child(2)').includesText('Repository: rust-lang/crates.io');
114+
assert.dom('[data-test-notification-message]').hasText('Trusted Publishing configuration removed successfully');
115+
});
116+
117+
test('deletion failure', async function (assert) {
118+
let { crate, user } = prepare(this);
119+
this.authenticateAs(user);
120+
121+
// Create a GitHub config for the crate
122+
let config = this.db.trustpubGithubConfig.create({
123+
crate,
124+
repository_owner: 'rust-lang',
125+
repository_name: 'crates.io',
126+
workflow_filename: 'ci.yml',
127+
environment: 'release',
128+
});
129+
130+
// Mock the server to return an error when trying to delete the config
131+
this.worker.use(
132+
http.delete(`/api/v1/trusted_publishing/github_configs/${config.id}`, () => {
133+
return HttpResponse.json({ errors: [{ detail: 'Server error' }] }, { status: 500 });
134+
}),
135+
);
136+
137+
await visit(`/crates/${crate.name}/settings`);
138+
assert.strictEqual(currentURL(), `/crates/${crate.name}/settings`);
139+
assert.dom('[data-test-github-config]').exists({ count: 1 });
140+
141+
await click('[data-test-remove-config-button]');
142+
assert.dom('[data-test-github-config]').exists({ count: 1 });
143+
assert
144+
.dom('[data-test-notification-message]')
145+
.hasText('Failed to remove Trusted Publishing configuration: Server error');
104146
});
105147
});
106148
});

0 commit comments

Comments
 (0)