Skip to content

Commit 50dbfd1

Browse files
authored
Merge pull request #5486 from grafana/dev
v1.15.1
2 parents 41d510e + 06bc076 commit 50dbfd1

File tree

9 files changed

+415
-145
lines changed

9 files changed

+415
-145
lines changed

engine/requirements-dev.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ charset-normalizer==3.3.2
1818
# requests
1919
distlib==0.3.8
2020
# via virtualenv
21-
django==4.2.18
21+
django==4.2.19
2222
# via
2323
# -c requirements.txt
2424
# django-stubs

engine/requirements.in

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ babel==2.12.1
22
beautifulsoup4==4.12.2
33
celery[redis]==5.3.6
44
cryptography==43.0.1
5-
django==4.2.18
5+
django==4.2.19
66
django-add-default-value==0.10.0
77
django-anymail[amazon-ses]==12.0
88
django-cors-headers==3.7.0
@@ -14,7 +14,7 @@ django-ipware==4.0.2
1414
django-log-request-id==1.6.0
1515
django-migration-linter==4.1.0
1616
django-mirage-field==1.3.0
17-
django-mysql==4.6.0
17+
django-mysql==4.16.0
1818
django-polymorphic==3.1.0
1919
django-ratelimit==2.0.0
2020
django-redis==5.4.0
@@ -23,7 +23,7 @@ django-silk==5.0.3
2323
django-sns-view==0.1.2
2424
djangorestframework==3.15.2
2525
factory-boy<3.0
26-
drf-spectacular==0.26.5
26+
drf-spectacular==0.28.0
2727
emoji==2.4.0
2828
# If the version of grpcio is changed
2929
# upload a new arm64 wheel instead of /engine/grpcio-1.57.0-cp311-cp311-linux_aarch64.whl
@@ -32,7 +32,7 @@ fcm-django @ https://github.com/grafana/fcm-django/archive/refs/tags/v1.0.12r1.t
3232
hiredis==2.2.3
3333
humanize==4.10.0
3434
icalendar==5.0.10
35-
jinja2==3.1.5
35+
jinja2==3.1.6
3636
lxml==5.2.2
3737
markdown2==2.4.10
3838
opentelemetry-sdk==1.26.0

engine/requirements.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ deprecated==1.2.14
7575
# opentelemetry-api
7676
# opentelemetry-exporter-otlp-proto-grpc
7777
# opentelemetry-semantic-conventions
78-
django==4.2.18
78+
django==4.2.19
7979
# via
8080
# -r requirements.in
8181
# django-add-default-value
@@ -115,7 +115,7 @@ django-migration-linter==4.1.0
115115
# via -r requirements.in
116116
django-mirage-field==1.3.0
117117
# via -r requirements.in
118-
django-mysql==4.6.0
118+
django-mysql==4.16.0
119119
# via -r requirements.in
120120
django-polymorphic==3.1.0
121121
# via
@@ -136,7 +136,7 @@ djangorestframework==3.15.2
136136
# -r requirements.in
137137
# django-rest-polymorphic
138138
# drf-spectacular
139-
drf-spectacular==0.26.5
139+
drf-spectacular==0.28.0
140140
# via -r requirements.in
141141
emoji==2.4.0
142142
# via
@@ -229,7 +229,7 @@ inflection==0.5.1
229229
# via drf-spectacular
230230
itsdangerous==2.1.2
231231
# via flask
232-
jinja2==3.1.5
232+
jinja2==3.1.6
233233
# via
234234
# -r requirements.in
235235
# flask
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { test, expect } from '../fixtures';
2+
import grafanaApiClient from '../utils/clients/grafana';
3+
import { clickButton, generateRandomValue } from '../utils/forms';
4+
import { goToOnCallPage } from '../utils/navigation';
5+
import { checkWebhookPresenceInTable } from '../utils/outgoingWebhooks';
6+
7+
const WEBHOOK_NAME = generateRandomValue();
8+
const TRIGGER_TYPE = 'Personal Notification';
9+
10+
let webhookID: string;
11+
12+
test.afterAll(async ({ request }) => {
13+
// Delete the created webhook
14+
if (webhookID) {
15+
await grafanaApiClient.makeRequest(
16+
request,
17+
`resources/webhooks/${webhookID}/`,
18+
'delete',
19+
)
20+
}
21+
});
22+
23+
test('Connects a personal notification webhook', async ({ adminRolePage: { page } }) => {
24+
// Create a new webhook
25+
await goToOnCallPage(page, 'outgoing_webhooks');
26+
await page.getByRole('button', { name: 'New Outgoing Webhook' }).click();
27+
28+
// Choose Advanced webhook
29+
await page.getByTestId('create-outgoing-webhook-modal').locator('div').filter({ hasText: 'AdvancedAn advanced webhook' }).first().click();
30+
31+
// Give it a name
32+
await page.locator('input[name="name"]').fill(WEBHOOK_NAME);
33+
34+
// Choose a trigger type
35+
await page.getByTestId('triggerType-selector').locator('div').nth(1).click();
36+
await page.getByLabel('Select options menu').getByText(TRIGGER_TYPE).click();
37+
38+
// Set a URL
39+
await page.locator('#OutgoingWebhook div').locator('.monaco-editor').first().click();
40+
await page.keyboard.insertText('https://example.com');
41+
42+
// Create and check it has been created
43+
const responsePromise = page.waitForResponse('**/resources/webhooks/');
44+
await clickButton({ page, buttonText: 'Create' });
45+
await checkWebhookPresenceInTable({ page, webhookName: WEBHOOK_NAME, expectedTriggerType: TRIGGER_TYPE });
46+
47+
// save the ID so we can delete the webhook after the tests have run
48+
const response = await responsePromise;
49+
const wh = await response.json();
50+
webhookID = wh?.id;
51+
52+
await goToOnCallPage(page, 'users/me');
53+
await page.getByRole('tab', { name: 'Webhook connection' }).click();
54+
55+
// Select webhook
56+
await page.getByRole('dialog').locator('svg').nth(2).click();
57+
await page.getByLabel('Select options menu').getByText(WEBHOOK_NAME).click();
58+
59+
// Add some context
60+
await page.getByRole('textbox').fill('{ "test": true }');
61+
62+
// Connect
63+
await page.getByRole('button', { name: 'Connect' }).click();
64+
65+
// Check connection on User Info tab
66+
await page.getByRole('tab', { name: 'User info' }).click();
67+
expect(page.getByText(WEBHOOK_NAME)).toBeVisible();
68+
69+
// Disconnect
70+
await page.getByRole('tab', { name: 'Webhook connection' }).click();
71+
await page.getByRole('button', { name: 'Disconnect' }).click();
72+
await page.getByTestId('data-testid Confirm Modal Danger Button').click();
73+
74+
// Check connection is no longer shown
75+
await page.getByRole('tab', { name: 'User info' }).click();
76+
expect(page.getByText(WEBHOOK_NAME)).not.toBeVisible();
77+
})

grafana-plugin/e2e-tests/utils/clients/grafana.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { OrgRole } from '@grafana/data';
2-
import { expect, APIRequestContext } from '@playwright/test';
2+
import { expect, APIRequestContext, APIResponse } from '@playwright/test';
33

44
import { BASE_URL, GRAFANA_ADMIN_PASSWORD, GRAFANA_ADMIN_USERNAME } from '../constants';
55

@@ -128,6 +128,14 @@ class GrafanaAPIClient {
128128
const data: GetSettingsResponse = await res.json();
129129
return data.buildInfo.version;
130130
};
131+
132+
makeRequest = async (request: APIRequestContext, path: string, method: 'get' | 'post' | 'put' | 'delete' = 'post'): Promise<APIResponse> => {
133+
const res = await request[method](`${BASE_URL}/api/plugins/grafana-oncall-app/${path.replace(/^\//, '')}`, {
134+
headers: this.requestHeaders,
135+
});
136+
expect(res.ok()).toBeTruthy();
137+
return res;
138+
}
131139
}
132140

133141
const grafanaAPIClient = new GrafanaAPIClient(GRAFANA_ADMIN_USERNAME, GRAFANA_ADMIN_PASSWORD);

grafana-plugin/go.mod

+4-4
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ require (
7878
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
7979
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
8080
golang.org/x/mod v0.17.0 // indirect
81-
golang.org/x/net v0.29.0 // indirect
82-
golang.org/x/sync v0.8.0 // indirect
83-
golang.org/x/sys v0.25.0 // indirect
84-
golang.org/x/text v0.18.0 // indirect
81+
golang.org/x/net v0.33.0 // indirect
82+
golang.org/x/sync v0.10.0 // indirect
83+
golang.org/x/sys v0.28.0 // indirect
84+
golang.org/x/text v0.21.0 // indirect
8585
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
8686
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
8787
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect

grafana-plugin/go.sum

+8-8
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,13 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
235235
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
236236
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
237237
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
238-
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
239-
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
238+
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
239+
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
240240
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
241241
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
242242
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
243-
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
244-
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
243+
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
244+
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
245245
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
246246
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
247247
golang.org/x/sys v0.0.0-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -255,12 +255,12 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
255255
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
256256
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
257257
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
258-
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
259-
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
258+
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
259+
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
260260
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
261261
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
262-
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
263-
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
262+
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
263+
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
264264
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
265265
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
266266
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=

grafana-plugin/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"@typescript-eslint/eslint-plugin": "^5.40.1",
8686
"copy-webpack-plugin": "^11.0.0",
8787
"css-loader": "^6.7.3",
88-
"dompurify": "^2.3.12",
88+
"dompurify": "^3.2.4",
8989
"eslint": "^8.25.0",
9090
"eslint-plugin-deprecation": "^2.0.0",
9191
"eslint-plugin-jsdoc": "^44.2.4",
@@ -95,7 +95,7 @@
9595
"eslint-plugin-rulesdir": "^0.2.1",
9696
"eslint-plugin-unused-imports": "^3.1.0",
9797
"eslint-webpack-plugin": "^4.0.1",
98-
"express": "^4.19.2",
98+
"express": "^4.20.0",
9999
"fork-ts-checker-webpack-plugin": "^8.0.0",
100100
"glob": "^10.2.7",
101101
"identity-obj-proxy": "3.0.0",

0 commit comments

Comments
 (0)