summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.markdownlint.yml2
-rw-r--r--app/assets/images/auth_buttons/atlassian_64.pngbin1512 -> 1364 bytes
-rw-r--r--app/assets/images/auth_buttons/facebook_64.pngbin870 -> 1033 bytes
-rw-r--r--app/assets/javascripts/emoji/awards_app/store/actions.js41
-rw-r--r--doc/api/status_checks.md3
-rw-r--r--doc/integration/oauth_provider.md2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb10
-rw-r--r--spec/features/merge_request/user_awards_emoji_spec.rb1
-rw-r--r--spec/frontend/emoji/awards_app/store/actions_spec.js37
9 files changed, 79 insertions, 17 deletions
diff --git a/.markdownlint.yml b/.markdownlint.yml
index e1e2b246314..7f71c933d96 100644
--- a/.markdownlint.yml
+++ b/.markdownlint.yml
@@ -139,6 +139,8 @@ proper-names:
"unicorn-worker-killer",
"URL",
"WebdriverIO",
+ "Workload Identity Pool",
+ "Workload Identity Provider",
"YAML",
"YouTrack"
]
diff --git a/app/assets/images/auth_buttons/atlassian_64.png b/app/assets/images/auth_buttons/atlassian_64.png
index 548f1c93318..63169b9a81b 100644
--- a/app/assets/images/auth_buttons/atlassian_64.png
+++ b/app/assets/images/auth_buttons/atlassian_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/facebook_64.png b/app/assets/images/auth_buttons/facebook_64.png
index 71ffb1c6a1f..34b75de4498 100644
--- a/app/assets/images/auth_buttons/facebook_64.png
+++ b/app/assets/images/auth_buttons/facebook_64.png
Binary files differ
diff --git a/app/assets/javascripts/emoji/awards_app/store/actions.js b/app/assets/javascripts/emoji/awards_app/store/actions.js
index f0340209248..f83bfe614dd 100644
--- a/app/assets/javascripts/emoji/awards_app/store/actions.js
+++ b/app/assets/javascripts/emoji/awards_app/store/actions.js
@@ -33,20 +33,51 @@ export const fetchAwards = async ({ commit, dispatch, state }, page = '1') => {
}
};
+/**
+ * Creates an intermediary award, used for display
+ * until the real award is loaded from the backend.
+ */
+const newOptimisticAward = (name, state) => {
+ const freeId = Math.min(...state.awards.map((a) => a.id), Number.MAX_SAFE_INTEGER) - 1;
+ return {
+ id: freeId,
+ name,
+ user: {
+ id: window.gon.current_user_id,
+ name: window.gon.current_user_fullname,
+ username: window.gon.current_username,
+ },
+ };
+};
+
export const toggleAward = async ({ commit, state }, name) => {
const award = state.awards.find((a) => a.name === name && a.user.id === state.currentUserId);
try {
if (award) {
- await axios.delete(joinPaths(gon.relative_url_root || '', `${state.path}/${award.id}`));
-
commit(REMOVE_AWARD, award.id);
+ await axios
+ .delete(joinPaths(gon.relative_url_root || '', `${state.path}/${award.id}`))
+ .catch((err) => {
+ commit(ADD_NEW_AWARD, award);
+
+ throw err;
+ });
+
showToast(__('Award removed'));
} else {
- const { data } = await axios.post(joinPaths(gon.relative_url_root || '', state.path), {
- name,
- });
+ const optimisticAward = newOptimisticAward(name, state);
+
+ commit(ADD_NEW_AWARD, optimisticAward);
+
+ const { data } = await axios
+ .post(joinPaths(gon.relative_url_root || '', state.path), {
+ name,
+ })
+ .finally(() => {
+ commit(REMOVE_AWARD, optimisticAward.id);
+ });
commit(ADD_NEW_AWARD, data);
diff --git a/doc/api/status_checks.md b/doc/api/status_checks.md
index e2849063475..0cded150474 100644
--- a/doc/api/status_checks.md
+++ b/doc/api/status_checks.md
@@ -31,7 +31,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/status_checks
"id": 2,
"name": "Rule 1",
"external_url": "https://gitlab.com/test-endpoint",
- "status": "approved"
+ "status": "pass"
},
{
"id": 1,
@@ -60,6 +60,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/status_check_responses
| `merge_request_iid` | integer | yes | IID of a merge request |
| `sha` | string | yes | SHA at `HEAD` of the source branch |
| `external_status_check_id` | integer | yes | ID of an external status check |
+| `status` | string | no | Set to `pass` to pass the check |
NOTE:
`sha` must be the SHA at the `HEAD` of the merge request's source branch.
diff --git a/doc/integration/oauth_provider.md b/doc/integration/oauth_provider.md
index 373981c83e4..d091de09ee4 100644
--- a/doc/integration/oauth_provider.md
+++ b/doc/integration/oauth_provider.md
@@ -105,6 +105,8 @@ Existing:
**Expire access tokens** to enable them.
- Tokens must be [revoked](../api/oauth2.md#revoke-a-token) or they don't expire.
+When applications are deleted, all grants and tokens associated with the application are also deleted.
+
## Authorized applications
Every application you authorize with your GitLab credentials is shown
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
index 908376ca2ca..45693ecee41 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
@@ -13,10 +13,10 @@ module QA
let(:package_version) { '1.3.7' }
let(:package_type) { 'maven_gradle' }
- where(:authentication_token_type, :maven_header_name, :testcase) do
- :personal_access_token | 'Private-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347601'
- :ci_job_token | 'Job-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347603'
- :project_deploy_token | 'Deploy-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347602'
+ where(:case_name, :authentication_token_type, :maven_header_name, :testcase) do
+ 'using personal access token' | :personal_access_token | 'Private-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347601'
+ 'using ci job token' | :ci_job_token | 'Job-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347603'
+ 'using project deploy token' | :project_deploy_token | 'Deploy-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347602'
end
with_them do
@@ -31,7 +31,7 @@ module QA
end
end
- it "pushes and pulls a maven package via gradle using #{params[:authentication_token_type]}", testcase: params[:testcase] do
+ it 'pushes and pulls a maven package via gradle', testcase: params[:testcase] do
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
gradle_upload_yaml = ERB.new(read_fixture('package_managers/maven', 'gradle_upload_package.yaml.erb')).result(binding)
diff --git a/spec/features/merge_request/user_awards_emoji_spec.rb b/spec/features/merge_request/user_awards_emoji_spec.rb
index 240b8f996c8..35eadb34799 100644
--- a/spec/features/merge_request/user_awards_emoji_spec.rb
+++ b/spec/features/merge_request/user_awards_emoji_spec.rb
@@ -27,6 +27,7 @@ RSpec.describe 'Merge request > User awards emoji', :js do
it 'removes award from merge request' do
first('[data-testid="award-button"]').click
+ expect(first('[data-testid="award-button"]')).to have_content '1'
find('[data-testid="award-button"].selected').click
expect(first('[data-testid="award-button"]')).to have_content '0'
diff --git a/spec/frontend/emoji/awards_app/store/actions_spec.js b/spec/frontend/emoji/awards_app/store/actions_spec.js
index 02b643244d2..0761256ed23 100644
--- a/spec/frontend/emoji/awards_app/store/actions_spec.js
+++ b/spec/frontend/emoji/awards_app/store/actions_spec.js
@@ -87,6 +87,26 @@ describe('Awards app actions', () => {
describe('toggleAward', () => {
let mock;
+ const optimisticAwardId = Number.MAX_SAFE_INTEGER - 1;
+ const makeOptimisticAddMutation = (
+ id = optimisticAwardId,
+ name = null,
+ userId = window.gon.current_user_id,
+ ) => ({
+ type: 'ADD_NEW_AWARD',
+ payload: {
+ id,
+ name,
+ user: {
+ id: userId,
+ },
+ },
+ });
+ const makeOptimisticRemoveMutation = (id = optimisticAwardId) => ({
+ type: 'REMOVE_AWARD',
+ payload: id,
+ });
+
beforeEach(() => {
mock = new MockAdapter(axios);
});
@@ -110,8 +130,10 @@ describe('Awards app actions', () => {
mock.onPost(`${relativeRootUrl || ''}/awards`).reply(200, { id: 1 });
});
- it('commits ADD_NEW_AWARD', async () => {
+ it('adds an optimistic award, removes it, and then commits ADD_NEW_AWARD', async () => {
testAction(actions.toggleAward, null, { path: '/awards', awards: [] }, [
+ makeOptimisticAddMutation(),
+ makeOptimisticRemoveMutation(),
{ type: 'ADD_NEW_AWARD', payload: { id: 1 } },
]);
});
@@ -127,7 +149,7 @@ describe('Awards app actions', () => {
actions.toggleAward,
null,
{ path: '/awards', awards: [] },
- [],
+ [makeOptimisticAddMutation(), makeOptimisticRemoveMutation()],
[],
() => {
expect(Sentry.captureException).toHaveBeenCalled();
@@ -137,7 +159,7 @@ describe('Awards app actions', () => {
});
});
- describe('removing a award', () => {
+ describe('removing an award', () => {
const mockData = { id: 1, name: 'thumbsup', user: { id: 1 } };
describe('success', () => {
@@ -160,6 +182,9 @@ describe('Awards app actions', () => {
});
describe('error', () => {
+ const currentUserId = 1;
+ const name = 'thumbsup';
+
beforeEach(() => {
mock.onDelete(`${relativeRootUrl || ''}/awards/1`).reply(500);
});
@@ -167,13 +192,13 @@ describe('Awards app actions', () => {
it('calls Sentry.captureException', async () => {
await testAction(
actions.toggleAward,
- 'thumbsup',
+ name,
{
path: '/awards',
- currentUserId: 1,
+ currentUserId,
awards: [mockData],
},
- [],
+ [makeOptimisticRemoveMutation(1), makeOptimisticAddMutation(1, name, currentUserId)],
[],
() => {
expect(Sentry.captureException).toHaveBeenCalled();