Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-10-16 06:08:48 +00:00
parent c311ce331f
commit e94d662e5a
30 changed files with 447 additions and 85 deletions

View file

@ -25,7 +25,8 @@ export default class FilteredSearchBoards extends FilteredSearchManager {
}
updateObject(path) {
this.store.path = path.substr(1);
const groupByParam = new URLSearchParams(window.location.search).get('group_by');
this.store.path = `${path.substr(1)}${groupByParam ? `&group_by=${groupByParam}` : ''}`;
if (gon.features.boardsWithSwimlanes || gon.features.graphqlBoardLists) {
boardsStore.updateFiltersUrl();

View file

@ -18,6 +18,13 @@ function onLoaded() {
alert(res.responseJSON.error);
};
AP.getLocation(function(location) {
$('.js-jira-connect-sign-in').each(function() {
var updatedLink = `${$(this).attr('href')}?return_to=${location}`;
$(this).attr('href', updatedLink);
});
});
$('#add-subscription-form').on('submit', function(e) {
var actionUrl = $(this).attr('action');
e.preventDefault();

View file

@ -21,6 +21,7 @@ const createApolloProvider = appData => {
},
{
typeDefs,
assumeImmutableResults: true,
},
);

View file

@ -1,16 +1,24 @@
import { produce } from 'immer';
import query from '../queries/app_data.query.graphql';
const hasSubmittedChangesResolver = (_, { input: { hasSubmittedChanges } }, { cache }) => {
const { appData } = cache.readQuery({ query });
cache.writeQuery({
query,
data: {
const oldData = cache.readQuery({ query });
const data = produce(oldData, draftState => {
// punctually modifying draftState as per immer docs upsets our linters
return {
...draftState,
appData: {
__typename: 'AppData',
...appData,
...draftState.appData,
hasSubmittedChanges,
},
},
};
});
cache.writeQuery({
query,
data,
});
};

View file

@ -1,3 +1,4 @@
import { produce } from 'immer';
import submitContentChanges from '../../services/submit_content_changes';
import savedContentMetaQuery from '../queries/saved_content_meta.query.graphql';
@ -14,14 +15,18 @@ const submitContentChangesResolver = (
images,
mergeRequestMeta,
}).then(savedContentMeta => {
cache.writeQuery({
query: savedContentMetaQuery,
data: {
const data = produce(savedContentMeta, draftState => {
return {
savedContentMeta: {
__typename: 'SavedContentMeta',
...savedContentMeta,
...draftState,
},
},
};
});
cache.writeQuery({
query: savedContentMetaQuery,
data,
});
});
};

View file

@ -186,6 +186,7 @@ table {
.checkbox {
padding-left: $gl-spacing-scale-4;
padding-right: 0;
width: 1px;
+ td,
+ th {
@ -205,12 +206,20 @@ table {
width: 10%;
}
.description {
max-width: 0;
}
.identifier {
width: 16%;
}
.scanner {
width: 15%;
width: 10%;
}
.activity {
width: 5%;
}
}
}

View file

@ -226,20 +226,20 @@
@return calc(#{$original-padding + $original-border} - var(--ide-btn-hover-border-width, #{$original-border}));
}
.btn:not(.btn-link):not([disabled]):hover {
.btn:not(.gl-button):not(.btn-link):not([disabled]):hover {
border-width: var(--ide-btn-hover-border-width, 1px);
padding: calc-btn-hover-padding(6px) calc-btn-hover-padding(10px);
}
.btn:not([disabled]).btn-sm:hover {
.btn:not(.gl-button):not([disabled]).btn-sm:hover {
padding: calc-btn-hover-padding(4px) calc-btn-hover-padding(10px);
}
.btn:not([disabled]).btn-block:hover {
.btn:not(.gl-button):not([disabled]).btn-block:hover {
padding: calc-btn-hover-padding(6px) 0;
}
.btn-default,
.btn-default:not(.gl-button),
.dropdown,
.dropdown-menu-toggle {
background-color: var(--ide-input-background, $white) !important;
@ -258,7 +258,7 @@
}
// In IDE, the only inverted buttons are `.btn-remove`
.btn-inverted.btn-remove {
.btn-inverted.btn-remove:not(.gl-button) {
color: var(--ide-input-color, $red-500) !important;
background-color: var(--ide-input-background, $white) !important;
border-color: var(--ide-btn-default-border, $red-500);
@ -277,17 +277,21 @@
}
}
.btn-default {
// todo: remove this block after all default buttons have been migrated to gl-button
.btn-default:not(.gl-button) {
background-color: var(--ide-btn-default-background, $white) !important;
border-color: var(--ide-btn-default-border, $border-color);
&:hover,
&:focus {
border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
background-color: var(--ide-input-background, $white-normal) !important;
background-color: var(--ide-btn-default-background, $white-normal) !important;
}
&:active,
.active {
border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
background-color: var(--ide-input-background, $white-dark) !important;
background-color: var(--ide-btn-default-background, $white-dark) !important;
}
}
@ -321,8 +325,9 @@
border-color: var(--ide-dropdown-hover-background, $gray-100) !important;
}
.btn-primary,
.btn-info {
// todo: remove this block after all primary/info buttons have been migrated to gl-button
.btn-primary:not(.gl-button),
.btn-info:not(.gl-button) {
background-color: var(--ide-btn-primary-background, $blue-500);
border-color: var(--ide-btn-primary-border, $blue-600) !important;
@ -339,7 +344,8 @@
}
}
.btn-success {
// todo: remove this block after all success buttons have been migrated to gl-button
.btn-success:not(.gl-button) {
background-color: var(--ide-btn-success-background, $green-500);
border-color: var(--ide-btn-success-border, $green-600) !important;
@ -356,12 +362,70 @@
}
}
.btn[disabled] {
// todo: remove this block after all disabled buttons have been migrated to gl-button
.btn[disabled]:not(.gl-button) {
background-color: var(--ide-btn-default-background, $gray-light) !important;
border: 1px solid var(--ide-btn-disabled-border, $gray-100) !important;
color: var(--ide-btn-disabled-color, $gl-text-color-disabled) !important;
}
@function ide-btn-var($btn-type, $var-type, $value) {
@return var(--ide-btn-#{$btn-type}-#{$var-type}, $value);
}
@mixin ide-gl-button($btn-type, $bg-normal, $bg-hover, $bg-active, $border-normal, $border-hover, $border-focus, $border-active, $border-width-hover: 2px, $box-shadow-hover: $t-gray-a-08, $box-shadow-focus: 0 0 0 4px rgba($blue-500, 0.25)) {
background-color: ide-btn-var($btn-type, background, $bg-normal);
box-shadow: inset 0 0 0 1px ide-btn-var($btn-type, border, $border-normal);
&:hover,
&:focus {
background-color: ide-btn-var($btn-type, background, $bg-hover);
}
&:hover {
box-shadow: inset 0 0 0 ide-btn-var($btn-type, hover-border-width, $border-width-hover) ide-btn-var($btn-type, hover-border, $border-hover),
0 2px 2px 0 $box-shadow-hover;
}
&:focus {
box-shadow: inset 0 0 0 ide-btn-var($btn-type, hover-border-width, $border-width-hover) ide-btn-var($btn-type, hover-border, $border-focus),
ide-btn-var($btn-type, focus-box-shadow, $box-shadow-focus);
}
&:active:focus {
background-color: ide-btn-var($btn-type, background, $bg-active);
box-shadow: inset 0 0 0 ide-btn-var($btn-type, hover-border-width, $border-width-hover) ide-btn-var($btn-type, hover-border, $border-active),
ide-btn-var($btn-type, focus-box-shadow, $box-shadow-focus);
}
}
.btn-default.gl-button.gl-button {
color: var(--ide-input-color, $gl-text-color);
@include ide-gl-button(default, $white, $gray-50, $gray-100, $gray-200, $gray-300, $gray-300, $gray-400);
}
.btn-success.gl-button.gl-button {
@include ide-gl-button(success, $green-500, $green-600, $green-800, $green-600, $green-800, $green-800, $green-900);
}
.btn-info.gl-button.gl-button,
.btn-primary.gl-button.gl-button {
@include ide-gl-button(primary, $blue-500, $blue-600, $blue-800, $blue-600, $blue-800, $blue-800, $blue-900);
}
.btn-danger.btn-danger-secondary.gl-button.gl-button {
color: var(--ide-input-color, $red-500);
@include ide-gl-button(danger-secondary, $white, $red-50, $red-100, $red-500, $red-600, $red-600, $red-700);
}
.btn[disabled].gl-button.gl-button {
color: var(--ide-btn-disabled-color, $gl-text-color-disabled);
@include ide-gl-button(disabled, $gray-10, $gray-10, $gray-10, $gray-100, $gray-100, $gray-100, $gray-100, 1px, transparent, transparent);
}
.md table:not(.code) tbody {
background-color: var(--ide-border-color, $white);
}

View file

@ -20,20 +20,28 @@
--ide-btn-default-background: transparent;
--ide-btn-default-border: #bfbfbf;
--ide-btn-default-hover-border: #d8d8d8;
--ide-btn-default-hover-border-width: 2px;
--ide-btn-default-focus-box-shadow: 0 0 0 1px #bfbfbf;
--ide-btn-primary-background: #1068bf;
--ide-btn-primary-border: #428fdc;
--ide-btn-primary-hover-border: #63a6e9;
--ide-btn-primary-hover-border-width: 2px;
--ide-btn-primary-focus-box-shadow: 0 0 0 1px #63a6e9;
--ide-btn-success-background: #217645;
--ide-btn-success-border: #108548;
--ide-btn-success-hover-border: #2da160;
--ide-btn-success-hover-border-width: 2px;
--ide-btn-success-focus-box-shadow: 0 0 0 1px #2da160;
--ide-btn-disabled-background: transparent;
--ide-btn-disabled-border: rgba(223, 223, 223, 0.24);
--ide-btn-disabled-hover-border: rgba(223, 223, 223, 0.24);
--ide-btn-disabled-hover-border-width: 1px;
--ide-btn-disabled-focus-box-shadow: 0 0 0 0 transparent;
--ide-btn-disabled-color: rgba(145, 145, 145, 0.48);
--ide-btn-hover-border-width: 2px;
--ide-dropdown-background: #404040;
--ide-dropdown-hover-background: #525252;

View file

@ -18,22 +18,30 @@
--ide-input-color: #fff;
--ide-btn-default-background: transparent;
--ide-btn-default-border: var(--ide-input-border);
--ide-btn-default-border: #d8d8d8;
--ide-btn-default-hover-border: #d8d8d8;
--ide-btn-default-hover-border-width: 2px;
--ide-btn-default-focus-box-shadow: 0 0 0 1px #d8d8d8;
--ide-btn-primary-background: #1068bf;
--ide-btn-primary-border: #428fdc;
--ide-btn-primary-hover-border: #63a6e9;
--ide-btn-primary-hover-border-width: 2px;
--ide-btn-primary-focus-box-shadow: 0 0 0 1px #63a6e9;
--ide-btn-success-background: #217645;
--ide-btn-success-border: #108548;
--ide-btn-success-hover-border: #2da160;
--ide-btn-success-hover-border-width: 2px;
--ide-btn-success-focus-box-shadow: 0 0 0 1px #2da160;
--ide-btn-disabled-background: transparent;
--ide-btn-disabled-border: rgba(223, 223, 223, 0.24);
--ide-btn-disabled-hover-border: rgba(223, 223, 223, 0.24);
--ide-btn-disabled-hover-border-width: 1px;
--ide-btn-disabled-focus-box-shadow: transparent;
--ide-btn-disabled-color: rgba(145, 145, 145, 0.48);
--ide-btn-hover-border-width: 2px;
--ide-dropdown-background: #004c61;
--ide-dropdown-hover-background: #00617a;

View file

@ -13,6 +13,7 @@ $atlaskit-border-color: #dfe1e6;
padding-top: $gl-padding-4;
.ak-button {
align-items: center;
height: auto;
margin-left: $btn-margin-5;
}
@ -20,6 +21,74 @@ $atlaskit-border-color: #dfe1e6;
}
}
$header-height: 40px;
.jira-connect-header {
border-bottom: 1px solid $gray-100;
display: flex;
align-items: center;
justify-content: center;
min-height: $header-height;
padding-left: 16px;
padding-right: 16px;
position: fixed;
top: 0;
left: 0;
right: 0;
}
.jira-connect-user {
float: right;
position: relative;
top: -30px;
}
.jira-connect-app {
margin-top: $header-height;
max-width: 600px;
padding-top: 48px;
padding-left: 16px;
padding-right: 16px;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.gl-mt-5 {
margin-top: 16px;
}
.heading-with-border {
border-bottom: 1px solid $gray-100;
display: inline-block;
padding-bottom: 16px;
}
svg {
fill: currentColor;
&.s16 {
height: 16px;
width: 16px;
}
}
.ak-field-group label {
text-align: left;
}
.ak-button__appearance-primary {
&:hover {
color: $white;
text-decoration: none;
}
svg {
align-self: center;
margin-left: 4px;
}
}
.subscriptions {
tbody {
tr {
@ -31,3 +100,11 @@ $atlaskit-border-color: #dfe1e6;
}
}
}
.empty-subscriptions {
color: $gray-900;
}
.browser-limitations-notice {
margin-top: 32px;
}

View file

@ -0,0 +1,13 @@
@import 'mixins_and_variables_and_functions';
.jira-connect-users-container {
margin-left: auto;
margin-right: auto;
width: px-to-rem(350px);
}
.devise-layout-html body .navless-container {
@include media-breakpoint-down(xs) {
padding-top: 65px;
}
}

View file

@ -1,10 +1,14 @@
# frozen_string_literal: true
class JiraConnect::EventsController < JiraConnect::ApplicationController
# See https://developer.atlassian.com/cloud/jira/software/app-descriptor/#lifecycle
skip_before_action :verify_atlassian_jwt!, only: :installed
before_action :verify_qsh_claim!, only: :uninstalled
def installed
return head :ok if atlassian_jwt_valid?
installation = JiraConnectInstallation.new(install_params)
if installation.save

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class JiraConnect::UsersController < ApplicationController
feature_category :integrations
layout 'devise_experimental_onboarding_issues'
def show
@jira_app_link = params.delete(:return_to)
end
end

View file

@ -3,7 +3,7 @@
module ExternalLinkHelper
def external_link(body, url, options = {})
link_to url, { target: '_blank', rel: 'noopener noreferrer' }.merge(options) do
"#{body} #{icon('external-link')}".html_safe
"#{body} #{sprite_icon('external-link')}".html_safe
end
end
end

View file

@ -1,37 +1,61 @@
%h1
GitLab for Jira Configuration
%header.jira-connect-header
= brand_header_logo
%form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path }
.ak-field-group
%label
Namespace
.jira-connect-user
- if current_user
- user_link = link_to(current_user.to_reference, user_path(current_user), target: '_blank', rel: 'noopener noreferrer')
= _('Signed in to GitLab as %{user_link}').html_safe % { user_link: user_link }
- elsif @subscriptions.present?
= link_to _('Sign in to GitLab'), jira_connect_users_path, target: '_blank', rel: 'noopener noreferrer', class: 'js-jira-connect-sign-in'
.ak-field-group.field-group-input
%input#namespace-input.ak-field-text{ type: 'text', required: true }
%button.ak-button.ak-button__appearance-primary{ type: 'submit' }
Link namespace to Jira
.jira-connect-app
%h1
GitLab for Jira Configuration
%table.subscriptions
%thead
%tr
%th Namespace
%th Added
%th
%tbody
- @subscriptions.each do |subscription|
%tr
%td= subscription.namespace.full_path
%td= subscription.created_at
%td= link_to 'Remove', jira_connect_subscription_path(subscription), class: 'remove-subscription'
- if current_user.blank? && @subscriptions.empty?
%h2.heading-with-border Sign in to GitLab.com to get started.
%p
%strong Browser limitations:
Adding a namespace currently works only in browsers that allow cross site cookies. Please make sure to use
%a{ href: 'https://www.mozilla.org/en-US/firefox/', target: '_blank', rel: 'noopener noreferrer' } Firefox
or
%a{ href: 'https://www.google.com/chrome/index.html', target: '_blank', rel: 'noopener noreferrer' } Google Chrome
or enable cross-site cookies in your browser when adding a namespace.
%a{ href: 'https://gitlab.com/gitlab-org/gitlab/-/issues/263509', target: '_blank', rel: 'noopener noreferrer' } Learn more
.gl-mt-5
= external_link _('Sign in to GitLab'), jira_connect_users_path, class: 'ak-button ak-button__appearance-primary js-jira-connect-sign-in'
.gl-mt-5
%p Note: this integration only works with accounts on GitLab.com (SaaS).
- else
%form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path }
.ak-field-group
%label
GitLab namespace
.ak-field-group.field-group-input
%input#namespace-input.ak-field-text{ type: 'text', required: true, placeholder: 'e.g. "MyCompany" or "MyCompany/GroupName"' }
%button.ak-button.ak-button__appearance-primary{ type: 'submit' }
Link namespace to Jira
- if @subscriptions.present?
%table.subscriptions
%thead
%tr
%th Namespace
%th Added
%th
%tbody
- @subscriptions.each do |subscription|
%tr
%td= subscription.namespace.full_path
%td= subscription.created_at
%td= link_to 'Remove', jira_connect_subscription_path(subscription), class: 'remove-subscription'
- else
%h4.empty-subscriptions
No linked namespaces
%p.browser-limitations-notice
%strong Browser limitations:
Adding a namespace currently works only in browsers that allow cross site cookies. Please make sure to use
%a{ href: 'https://www.mozilla.org/en-US/firefox/', target: '_blank', rel: 'noopener noreferrer' } Firefox
or
%a{ href: 'https://www.google.com/chrome/index.html', target: '_blank', rel: 'noopener noreferrer' } Google Chrome
or enable cross-site cookies in your browser when adding a namespace.
%a{ href: 'https://gitlab.com/gitlab-org/gitlab/-/issues/263509', target: '_blank', rel: 'noopener noreferrer' } Learn more
= page_specific_javascript_tag('jira_connect.js')
- add_page_specific_style 'page_bundles/jira_connect'

View file

@ -0,0 +1,12 @@
.jira-connect-users-container.gl-text-center
- user_link = link_to(current_user.to_reference, user_path(current_user), target: '_blank', rel: 'noopener noreferrer')
%h2= _('You are signed into GitLab as %{user_link}').html_safe % { user_link: user_link }
%p= s_('Integrations|You can now close this window and return to the GitLab for Jira application.')
- if @jira_app_link
%p= external_link s_('Integrations|Return to GitLab for Jira'), @jira_app_link, class: 'btn btn-success'
%p= link_to _('Sign out'), destroy_user_session_path, method: :post
- add_page_specific_style 'page_bundles/jira_connect_users'

View file

@ -0,0 +1,5 @@
---
title: Fix Jira Connect App update webhooks
merge_request: 45151
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Add user sign in indicator to Jira connect app
merge_request: 42628
author:
type: changed

View file

@ -182,6 +182,7 @@ module Gitlab
config.assets.precompile << "page_bundles/ide.css"
config.assets.precompile << "page_bundles/issues_list.css"
config.assets.precompile << "page_bundles/jira_connect.css"
config.assets.precompile << "page_bundles/jira_connect_users.css"
config.assets.precompile << "page_bundles/merge_conflicts.css"
config.assets.precompile << "page_bundles/merge_requests.css"
config.assets.precompile << "page_bundles/milestone.css"

View file

@ -1,7 +1,7 @@
---
name: global_default_branch_name
introduced_by_url:
rollout_issue_url:
group:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35269
rollout_issue_url:
group: group::source code
type: development
default_enabled: true

View file

@ -1,7 +1,7 @@
---
name: mr_commit_neighbor_nav
introduced_by_url:
rollout_issue_url:
group:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28596
rollout_issue_url:
group: group::source code
type: development
default_enabled: true

View file

@ -5,6 +5,7 @@ namespace :jira_connect do
root to: proc { [404, {}, ['']] }, as: 'base'
get 'app_descriptor' => 'app_descriptor#show'
get :users, to: 'users#show'
namespace :events do
post 'installed'

View file

@ -385,8 +385,8 @@ end
GitLab's GraphQL API is versionless, which means we maintain backwards
compatibility with older versions of the API with every change. Rather
than removing a field or [enum value](#enums), we need to _deprecate_ it instead.
In future, GitLab
[may remove deprecated parts of the schema](https://gitlab.com/gitlab-org/gitlab/-/issues/32292).
The deprecated parts of the schema can then be removed in a future release
in accordance with [GitLab's deprecation process](../api/graphql/index.md#deprecation-process).
Fields and enum values are deprecated using the `deprecated` property.
The value of the property is a `Hash` of:

View file

@ -14149,6 +14149,9 @@ msgstr ""
msgid "Integrations|Projects using custom settings will not be impacted unless the project owner chooses to use instance-level defaults."
msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
msgid "Integrations|Save settings?"
msgstr ""
@ -14173,6 +14176,9 @@ msgstr ""
msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
msgstr ""
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@ -24241,6 +24247,9 @@ msgstr ""
msgid "Sign in to \"%{group_name}\""
msgstr ""
msgid "Sign in to GitLab"
msgstr ""
msgid "Sign in using smart card"
msgstr ""
@ -24286,6 +24295,9 @@ msgstr ""
msgid "Signed in"
msgstr ""
msgid "Signed in to GitLab as %{user_link}"
msgstr ""
msgid "Signed in with %{authentication} authentication"
msgstr ""
@ -29859,6 +29871,9 @@ msgstr ""
msgid "You are receiving this message because you are a GitLab administrator for %{url}."
msgstr ""
msgid "You are signed into GitLab as %{user_link}"
msgstr ""
msgid "You are trying to upload something other than an image. Please upload a .png, .jpg, .jpeg, .gif, .bmp, .tiff or .ico."
msgstr ""

View file

@ -43,7 +43,7 @@
"@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.5",
"@gitlab/svgs": "1.171.0",
"@gitlab/ui": "21.30.1",
"@gitlab/ui": "21.32.1",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "^6.0.3-3",
"@rails/ujs": "^6.0.3-2",

View file

@ -4,14 +4,20 @@ require 'spec_helper'
RSpec.describe JiraConnect::EventsController do
describe '#installed' do
subject do
post :installed, params: {
clientKey: '1234',
sharedSecret: 'secret',
let(:client_key) { '1234' }
let(:shared_secret) { 'secret' }
let(:params) do
{
clientKey: client_key,
sharedSecret: shared_secret,
baseUrl: 'https://test.atlassian.net'
}
end
subject do
post :installed, params: params
end
it 'saves the jira installation data' do
expect { subject }.to change { JiraConnectInstallation.count }.by(1)
end
@ -19,15 +25,15 @@ RSpec.describe JiraConnect::EventsController do
it 'saves the correct values' do
subject
installation = JiraConnectInstallation.find_by_client_key('1234')
installation = JiraConnectInstallation.find_by_client_key(client_key)
expect(installation.shared_secret).to eq('secret')
expect(installation.shared_secret).to eq(shared_secret)
expect(installation.base_url).to eq('https://test.atlassian.net')
end
context 'client key already exists' do
it 'returns 422' do
create(:jira_connect_installation, client_key: '1234')
create(:jira_connect_installation, client_key: client_key)
subject
@ -35,6 +41,23 @@ RSpec.describe JiraConnect::EventsController do
end
end
context 'when it is a version update and shared_secret is not sent' do
let(:params) do
{
clientKey: client_key,
baseUrl: 'https://test.atlassian.net'
}
end
it 'validates the JWT token in authorization header and returns 200 without creating a new installation' do
create(:jira_connect_installation, client_key: client_key, shared_secret: shared_secret)
request.headers["Authorization"] = "Bearer #{Atlassian::Jwt.encode({ iss: client_key }, shared_secret)}"
expect { subject }.not_to change { JiraConnectInstallation.count }
expect(response).to have_gitlab_http_status(:ok)
end
end
describe '#uninstalled' do
let!(:installation) { create(:jira_connect_installation) }
let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/events/uninstalled', 'POST', 'https://gitlab.test') }

View file

@ -0,0 +1,27 @@
import appDataQuery from '~/static_site_editor/graphql/queries/app_data.query.graphql';
import hasSubmittedChanges from '~/static_site_editor/graphql/resolvers/has_submitted_changes';
describe('static_site_editor/graphql/resolvers/has_submitted_changes', () => {
it('updates the cache with the data passed in input', () => {
const cachedData = { appData: { original: 'foo' } };
const newValue = { input: { hasSubmittedChanges: true } };
const cache = {
readQuery: jest.fn().mockReturnValue(cachedData),
writeQuery: jest.fn(),
};
hasSubmittedChanges(null, newValue, { cache });
expect(cache.readQuery).toHaveBeenCalledWith({ query: appDataQuery });
expect(cache.writeQuery).toHaveBeenCalledWith({
query: appDataQuery,
data: {
appData: {
__typename: 'AppData',
original: 'foo',
hasSubmittedChanges: true,
},
},
});
});
});

View file

@ -6,12 +6,15 @@ RSpec.describe ExternalLinkHelper do
include IconsHelper
it 'returns external link with icon' do
expect(external_link('https://gitlab.com', 'https://gitlab.com').to_s)
.to eq('<a target="_blank" rel="noopener noreferrer" href="https://gitlab.com">https://gitlab.com <i aria-hidden="true" data-hidden="true" class="fa fa-external-link"></i></a>')
link = external_link('https://gitlab.com', 'https://gitlab.com').to_s
expect(link).to start_with('<a target="_blank" rel="noopener noreferrer" href="https://gitlab.com">https://gitlab.com')
expect(link).to include('data-testid="external-link-icon"')
end
it 'allows options when creating external link with icon' do
expect(external_link('https://gitlab.com', 'https://gitlab.com', { "data-foo": "bar", class: "externalLink" }).to_s)
.to eq('<a target="_blank" rel="noopener noreferrer" data-foo="bar" class="externalLink" href="https://gitlab.com">https://gitlab.com <i aria-hidden="true" data-hidden="true" class="fa fa-external-link"></i></a>')
link = external_link('https://gitlab.com', 'https://gitlab.com', { "data-foo": "bar", class: "externalLink" }).to_s
expect(link).to start_with('<a target="_blank" rel="noopener noreferrer" data-foo="bar" class="externalLink" href="https://gitlab.com">https://gitlab.com')
expect(link).to include('data-testid="external-link-icon"')
end
end

View file

@ -0,0 +1,30 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'jira_connect/subscriptions/index.html.haml' do
let(:user) { build_stubbed(:user) }
before do
allow(view).to receive(:current_user).and_return(user)
assign(:subscriptions, [])
end
context 'when the user is signed in' do
it 'shows link to user profile' do
render
expect(rendered).to have_link(user.to_reference)
end
end
context 'when the user is not signed in' do
let(:user) { nil }
it 'shows "Sign in" link' do
render
expect(rendered).to have_link('Sign in to GitLab')
end
end
end

View file

@ -866,10 +866,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.171.0.tgz#abc3092bf804f0898301626130e0f3231834924a"
integrity sha512-TPfdqIxQDda+0CQHhb9XdF50lmqDmADu6yT8R4oZi6BoUtWLdiHbyFt+RnVU6t7EmjIKicNAii7Ga+f2ljCfUA==
"@gitlab/ui@21.30.1":
version "21.30.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-21.30.1.tgz#561bd10c5264e48d16be4c5706827f40ec31286f"
integrity sha512-JdLA8x7fOk1qgsqBeNhlmg1VTJIrl+ECWea8whoyqWnI95GPuiM5ZSnehZHA6FoNwB9n/u1GnVSLCHcqvHZW0w==
"@gitlab/ui@21.32.1":
version "21.32.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-21.32.1.tgz#8ed29de1093afc36ea31d3cf93b047bcfe0c6543"
integrity sha512-ZZi/rJfDTXMytX1vNV2FU+l0fG6J7V2+1M7CWIkxdPIPVJ1LopkkfwnbBP29zrwBFBmguXcPoRfTjGa2oSNdbg==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"