graphdb-workbench-tests 3.5.0 → 3.5.1-RC1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,7 +42,9 @@ describe('Cluster configuration', () => {
42
42
  });
43
43
 
44
44
  ClusterStubs.stubClusterGroupStatusWithTag();
45
+ ClusterStubs.stubClusterConfigWithTag();
45
46
  cy.wait('@3-nodes-cluster-group-status-tag');
47
+ cy.wait('@cluster-config-with-tag');
46
48
  // Assert the tags table contains the expected tag
47
49
  ClusterConfigurationSteps.getTagsTable().should('be.visible');
48
50
  ClusterConfigurationSteps.getTagsTableRows().should('contain.text', tagName);
@@ -62,6 +64,31 @@ describe('Cluster configuration', () => {
62
64
  cy.wait('@delete-tag').then((interception) => {
63
65
  expect(interception.request.body).to.deep.equal({tag: tagName});
64
66
  });
67
+ ClusterStubs.stubClusterGroupStatus();
68
+ ClusterStubs.stubClusterConfig();
69
+ cy.wait('@3-nodes-cluster-group-status');
70
+ cy.wait('@cluster-config');
71
+ ClusterConfigurationSteps.getTagsTable().should('not.exist');
72
+ });
73
+
74
+ it('should show an alert when there is no elected leader in the cluster', () => {
75
+ // Given there is no elected leader in the cluster
76
+ ClusterStubs.stubClusterGroupStatusWithoutLeader();
77
+
78
+ // When I have opened the cluster management page
79
+ ClusterPageSteps.visit();
80
+ // And I click on edit properties and open Multi-region tab
81
+ ClusterPageSteps.previewClusterConfig();
82
+ ClusterConfigurationSteps.selectMultiRegionConfigTab();
83
+
84
+ // Then I expect to see an alert that the leader is not elected
85
+ ClusterConfigurationSteps.getNoLeaderAlert().should('be.visible')
86
+ .and('contain.text', 'Leader is not elected');
87
+ // And no primary or secondary cluster configuration should be rendered
88
+ ClusterConfigurationSteps.getMultiRegionHeader().should('not.exist');
89
+ ClusterConfigurationSteps.getAddTagButton().should('not.exist');
90
+ ClusterConfigurationSteps.getEnableSecondaryModeButton().should('not.exist');
91
+ ClusterConfigurationSteps.getTagsTable().should('not.exist');
65
92
  });
66
93
 
67
94
  it('should be able to switch modes', () => {
@@ -460,7 +460,7 @@ describe('Cluster management', () => {
460
460
  "verificationTimeout": 1500,
461
461
  "transactionLogMaximumSizeGB": 50.0,
462
462
  "batchUpdateInterval": 5000,
463
- "nodes": ['http://pc-desktop:7200', 'http://pc-desktop:7203']
463
+ "nodes": ['http://pc-desktop:7200', 'http://pc-desktop:7203'],
464
464
  });
465
465
  });
466
466
  // And expect success message to be displayed.
@@ -2,7 +2,7 @@ import {MainMenuSteps} from "../../../steps/main-menu-steps";
2
2
  import HomeSteps from "../../../steps/home-steps";
3
3
  import {SettingsSteps} from "../../../steps/setup/settings-steps";
4
4
 
5
- function verifyInitialState(repositoryId) {
5
+ function verifyInitialState() {
6
6
  // Password change field is for admin.
7
7
  // explicitly state that the fields must be of type password
8
8
  SettingsSteps.getPasswordField().should('be.visible')
@@ -43,14 +43,8 @@ function verifyInitialState(repositoryId) {
43
43
  // Repository rights
44
44
  // - Admin has read and write access to all repositories."
45
45
  SettingsSteps.getUserRepositoryTable().should('be.visible');
46
- SettingsSteps.getReadRightsCheckbox(repositoryId)
47
- .should('be.visible')
48
- .and('be.checked')
49
- .and('be.disabled');
50
- SettingsSteps.getWriteRightsCheckbox(repositoryId)
51
- .should('be.visible')
52
- .and('be.checked')
53
- .and('be.disabled');
46
+ // And Admin doesn't see the list of the repositories
47
+ SettingsSteps.getRepositoryRightsRows().should('not.exist');
54
48
  }
55
49
 
56
50
  describe('My Settings initial state', () => {
@@ -69,7 +63,7 @@ describe('My Settings initial state', () => {
69
63
  // Given, I visit the My Settings page via URL
70
64
  SettingsSteps.visit();
71
65
  // Then,
72
- verifyInitialState(repositoryId);
66
+ verifyInitialState();
73
67
  });
74
68
 
75
69
  it('Should display the correct initial state when navigating via the navigation bar', () => {
@@ -77,6 +71,6 @@ describe('My Settings initial state', () => {
77
71
  HomeSteps.visit();
78
72
  MainMenuSteps.clickOnMySettings();
79
73
  // Then,
80
- verifyInitialState(repositoryId);
74
+ verifyInitialState();
81
75
  });
82
76
  });
@@ -128,7 +128,6 @@ describe('User and Access', () => {
128
128
  UserAndAccessSteps.getCustomRoleFieldError().should('not.be.visible');
129
129
 
130
130
  // When I create the user with a valid custom role
131
- UserAndAccessSteps.toggleWriteAccessAny();
132
131
  SecurityStubs.spyOnUserCreate();
133
132
  UserAndAccessSteps.confirmUserCreate();
134
133
  // Then the user should be created with that custom role
@@ -318,6 +317,8 @@ describe('User and Access', () => {
318
317
  verifyDisabledUserAuth('*', {read: false, write: false, maintain: true, graphql: true});
319
318
  verifyCheckedUserAuth(repoName, {read: false, write: false, maintain: false, graphql: false});
320
319
  verifyDisabledUserAuth(repoName, {read: false, write: false, maintain: false, graphql: true});
320
+ // The GraphQL checkbox is disabled for the lack of read/write rights, not because of the role
321
+ UserAndAccessSteps.getGraphqlAnyRoleTooltip().should('not.exist');
321
322
  });
322
323
 
323
324
  context('for non user roles', () => {
@@ -327,8 +328,7 @@ describe('User and Access', () => {
327
328
  verifyCheckedUserAuth('*', {read: true, write: true, maintain: true, graphql: false});
328
329
  verifyDisabledUserAuth('*', {read: true, write: true, maintain: true, graphql: true});
329
330
 
330
- verifyCheckedUserAuth(repoName, {read: true, write: true, maintain: true, graphql: false});
331
- verifyDisabledUserAuth(repoName, {read: true, write: true, maintain: true, graphql: true});
331
+ UserAndAccessSteps.getRepositoryRightsRows().should('not.exist');
332
332
  });
333
333
 
334
334
  it('repository manager', () => {
@@ -338,8 +338,7 @@ describe('User and Access', () => {
338
338
  verifyCheckedUserAuth('*', {read: true, write: true, maintain: true, graphql: false});
339
339
  verifyDisabledUserAuth('*', {read: true, write: true, maintain: true, graphql: true});
340
340
 
341
- verifyCheckedUserAuth(repoName, {read: true, write: true, maintain: true, graphql: false});
342
- verifyDisabledUserAuth(repoName, {read: true, write: true, maintain: true, graphql: true});
341
+ UserAndAccessSteps.getRepositoryRightsRows().should('not.exist');
343
342
  });
344
343
  });
345
344
 
@@ -464,6 +463,27 @@ describe('User and Access', () => {
464
463
  createUser(graphqlUser, PASSWORD, ROLE_USER, {read: true, graphql: true, repoName: repositoryId2});
465
464
  });
466
465
 
466
+ it('Should not allow GraphQL access for Ontop and FedX repositories', () => {
467
+ // GIVEN Ontop and FedX repositories alongside a GraphDB one
468
+ RepositoriesStubs.stubRepositories(0, '/repositories/get-repositories-with-unsupported-graphql-types.json');
469
+ UserAndAccessSteps.visit();
470
+ UserAndAccessSteps.clickCreateNewUserButton();
471
+ // WHEN the user is granted read access to all of them
472
+ UserAndAccessSteps.toggleReadAccessAny();
473
+
474
+ // THEN GraphQL should be available only for the GraphDB repository
475
+ UserAndAccessSteps.validateGraphqlAccessForRepo('graphdb-repo', {disabled: false});
476
+ UserAndAccessSteps.getGraphqlRepositoryTypeTooltipForRepo('graphdb-repo').should('not.exist');
477
+
478
+ // AND it should be permanently disabled for the Ontop and the FedX ones
479
+ ['ontop-repo', 'fedx-repo'].forEach((repository) => {
480
+ UserAndAccessSteps.validateGraphqlAccessForRepo(repository, {checked: false, disabled: true});
481
+ UserAndAccessSteps.hoverGraphQlRightsCheckbox(repository)
482
+ UserAndAccessSteps.getAngularTooltip().should('have.text', 'Not available for this repository type');
483
+ UserAndAccessSteps.blurGraphQlRightsCheckbox(repository)
484
+ });
485
+ });
486
+
467
487
  // Fails for unknown reason only in CI
468
488
  it('Can create user with different auth combinations', () => {
469
489
  cy.wait('@getRepositories');
@@ -172,6 +172,60 @@ describe('TTYG create new agent', () => {
172
172
  TTYGViewSteps.getAgent(0).should('contain', 'Test Agent').and('contain', 'starwars');
173
173
  });
174
174
 
175
+ it('should create an agent without temperature or topP parameters', () => {
176
+ // GIVEN: I have opened the Create Agent dialog and filled in the minimum required fields.
177
+ openCreateAgentDialog(repositoryId)
178
+ TtygAgentSettingsModalSteps.getDialog().should('be.visible');
179
+
180
+ fillAgentName('Test Agent');
181
+ TtygAgentSettingsModalSteps.enableSparqlExtractionMethod();
182
+ TtygAgentSettingsModalSteps.selectSparqlMethodSparqlQuery();
183
+
184
+ // WHEN: I disable the temperature setting.
185
+ TtygAgentSettingsModalSteps.toggleTemperature();
186
+
187
+ // AND: I disable the topP setting.
188
+ TtygAgentSettingsModalSteps.toggleTop();
189
+
190
+ // AND: I save the agent.
191
+ TTYGStubs.stubAgentCreate(1000);
192
+ TTYGStubs.stubAgentListGet(
193
+ '/ttyg/agent/get-agent-list-new-agent.json',
194
+ 1000,
195
+ );
196
+
197
+ TtygAgentSettingsModalSteps.saveAgent();
198
+ TtygAgentSettingsModalSteps.getCreatingAgentLoader().should('be.visible');
199
+
200
+ // THEN: I expect the create-agent request not to contain the temperature and topP parameters.
201
+ cy.wait('@create-agent').then((interception) => {
202
+ // eslint-disable-next-line no-undef
203
+ assert.deepEqual(interception.request.body, {
204
+ id: 'id',
205
+ name: 'Test Agent',
206
+ repositoryId: 'starwars',
207
+ model: 'gpt-4o',
208
+ contextSize: 128000,
209
+ seed: 0,
210
+ assistantsInstructions: {
211
+ systemInstruction: '',
212
+ userInstruction: 'If you need to write a SPARQL query, use only the classes and properties provided in the schema and don\'t invent or guess any. Always try to return human-readable names or labels and not only the IRIs. If SPARQL fails to provide the necessary information you can try another tool too.',
213
+ },
214
+ assistantExtractionMethods: [
215
+ {
216
+ method: 'sparql_search',
217
+ sparqlQuery: 'CONSTRUCT {?s ?p ?o} WHERE {GRAPH <http://example.org/ontology> {?s ?p ?o .}}',
218
+ addMissingNamespaces: false,
219
+ },
220
+ ],
221
+ additionalExtractionMethods: [],
222
+ });
223
+ });
224
+
225
+ // AND: I expect the modal to be closed.
226
+ TtygAgentSettingsModalSteps.getDialog().should('not.exist');
227
+ });
228
+
175
229
  it('Should require FTS to be enabled for selected repository when creating agent with FTS extraction method', () => {
176
230
  RepositoriesStubs.stubGetRepositoryConfig(repositoryId, '/repositories/get-repository-config-starwars-disabled-fts.json');
177
231
  TTYGStubs.stubChatsListGetNoResults();
@@ -461,6 +515,53 @@ describe('TTYG create new agent', () => {
461
515
  TtygAgentSettingsModalSteps.getTemperatureField().should('not.have.class', 'has-warning');
462
516
  });
463
517
 
518
+ it('should toggle the temperature setting', () => {
519
+ // GIVEN: I have opened the Create Agent dialog.
520
+ openCreateAgentDialog(repositoryId);
521
+
522
+ // WHEN: I set a high temperature value.
523
+ TtygAgentSettingsModalSteps.setTemperature('1.2');
524
+ // THEN: I expect a warning message to be displayed.
525
+ TtygAgentSettingsModalSteps.getTemperatureField().should('have.class', 'has-warning');
526
+ TtygAgentSettingsModalSteps.getTemperatureSliderField().should('have.value', '1.2');
527
+
528
+ // WHEN: I disable the temperature setting.
529
+ TtygAgentSettingsModalSteps.toggleTemperature();
530
+ // THEN: I expect the high-temperature warning to be hidden.
531
+ TtygAgentSettingsModalSteps.getTemperatureWarning().should('not.exist');
532
+ TtygAgentSettingsModalSteps.getTemperatureField().should('not.have.class', 'has-warning');
533
+ // AND: I expect the temperature controls to be disabled.
534
+ TtygAgentSettingsModalSteps.getTemperatureField().should('be.disabled');
535
+ TtygAgentSettingsModalSteps.getTemperatureSliderField().should('be.disabled');
536
+
537
+ // WHEN: I enable the temperature setting.
538
+ TtygAgentSettingsModalSteps.toggleTemperature();
539
+ // THEN: I expect the last set temperature value to be restored instead of the default one.
540
+ TtygAgentSettingsModalSteps.getTemperatureSliderField().should('have.value', '1.2');
541
+ // AND: I expect the high-temperature warning to be displayed again.
542
+ TtygAgentSettingsModalSteps.getTemperatureField().should('have.class', 'has-warning');
543
+ });
544
+
545
+ it('should toggle the topP setting', () => {
546
+ // GIVEN: I have opened the Create Agent dialog.
547
+ openCreateAgentDialog(repositoryId);
548
+
549
+ // WHEN: I set a custom topP value.
550
+ TtygAgentSettingsModalSteps.setTopP('0.3');
551
+ // THEN: I expect the topP value to be updated.
552
+ TtygAgentSettingsModalSteps.getTopPField().should('have.value', '0.3');
553
+
554
+ // WHEN: I disable the topP setting.
555
+ TtygAgentSettingsModalSteps.toggleTop();
556
+ // THEN: I expect the topP control to be disabled.
557
+ TtygAgentSettingsModalSteps.getTopPField().should('be.disabled');
558
+
559
+ // WHEN: I enable the topP setting.
560
+ TtygAgentSettingsModalSteps.toggleTop();
561
+ // THEN: I expect the last set topP value to be restored instead of the default one.
562
+ TtygAgentSettingsModalSteps.getTopPField().should('have.value', '0.3');
563
+ });
564
+
464
565
  it('Should warn the user when he changes the default value of the base instruction', () => {
465
566
  RepositoriesStubs.stubGetRepositoryConfig(repositoryId, '/repositories/get-repository-config-starwars-enabled-fts.json');
466
567
  TTYGStubs.stubChatsListGetNoResults();
@@ -541,3 +642,13 @@ function fillAgentName(name) {
541
642
  TtygAgentSettingsModalSteps.getAgentNameError().should('be.visible').and('contain', 'This field is required');
542
643
  TtygAgentSettingsModalSteps.typeAgentName(name);
543
644
  }
645
+
646
+ const openCreateAgentDialog = (repositoryId) => {
647
+ TTYGStubs.stubChatsListGetNoResults();
648
+ TTYGStubs.stubAgentListGet('/ttyg/agent/get-agent-list-0.json');
649
+ ConnectorStubs.stubGetConnectors();
650
+ TTYGStubs.getSimilarityIndexesForRepo(repositoryId );
651
+ TTYGViewSteps.visit();
652
+ cy.wait('@get-all-repositories');
653
+ TTYGViewSteps.createFirstAgent();
654
+ }
@@ -45,6 +45,55 @@ describe('TTYG edit an agent', () => {
45
45
  ToasterSteps.verifySuccess('The agent \'agent-1\' was saved successfully.');
46
46
  });
47
47
 
48
+ it('should preserve the temperature and topP values of the edited agent', () => {
49
+ TTYGStubs.stubChatsListGet();
50
+ TTYGStubs.stubAgentListGet();
51
+ TTYGStubs.stubChatGet();
52
+ // GIVEN: I have opened the ttyg page
53
+ TTYGViewSteps.visit();
54
+ cy.wait('@get-chat-list');
55
+ cy.wait('@get-agent-list');
56
+ cy.wait('@get-chat');
57
+
58
+ // WHEN: I open the settings of an agent whose temperature and topP differ from the default values
59
+ TTYGViewSteps.openAgentSettingsModalForAgent(0);
60
+
61
+ // THEN: I expect the values of the agent to be loaded instead of the default ones
62
+ TtygAgentSettingsModalSteps.getTemperatureSliderField().should('have.value', '0');
63
+ TtygAgentSettingsModalSteps.getTopPField().should('have.value', '0');
64
+
65
+ // WHEN: I disable the temperature setting
66
+ TtygAgentSettingsModalSteps.toggleTemperature();
67
+ // THEN: I expect the temperature controls to be disabled
68
+ TtygAgentSettingsModalSteps.getTemperatureField().should('be.disabled');
69
+ TtygAgentSettingsModalSteps.getTemperatureSliderField().should('be.disabled');
70
+
71
+ // WHEN: I enable the temperature setting again
72
+ TtygAgentSettingsModalSteps.toggleTemperature();
73
+ // THEN: I expect the temperature value of the agent to be restored instead of the default one
74
+ TtygAgentSettingsModalSteps.getTemperatureSliderField().should('have.value', '0');
75
+
76
+ // WHEN: I disable the topP setting
77
+ TtygAgentSettingsModalSteps.toggleTop();
78
+ // THEN: I expect the topP control to be disabled
79
+ TtygAgentSettingsModalSteps.getTopPField().should('be.disabled');
80
+
81
+ // WHEN: I enable the topP setting again
82
+ TtygAgentSettingsModalSteps.toggleTop();
83
+ // THEN: I expect the topP value of the agent to be restored instead of the default one
84
+ TtygAgentSettingsModalSteps.getTopPField().should('have.value', '0');
85
+
86
+ // WHEN: I save the agent
87
+ TTYGStubs.stubAgentEdit();
88
+ TtygAgentSettingsModalSteps.saveAgent();
89
+ // THEN: I expect the values of the agent to be sent instead of the default ones
90
+ cy.wait('@edit-agent').then((interception) => {
91
+ expect(interception.request.body.temperature).to.equal(0);
92
+ expect(interception.request.body.topP).to.equal(0);
93
+ });
94
+ ToasterSteps.verifySuccess('The agent \'agent-1\' was saved successfully.');
95
+ });
96
+
48
97
  it('should not be able to edit an agent if an extraction method is selected but the precondition has failed', () => {
49
98
  TTYGStubs.stubChatsListGet();
50
99
  TTYGStubs.stubAgentListGet();
@@ -0,0 +1,41 @@
1
+ [
2
+ {
3
+ "address": "pc-desktop:7300",
4
+ "nodeState": "FOLLOWER",
5
+ "term": 2,
6
+ "syncStatus": {},
7
+ "lastLogTerm": 0,
8
+ "lastLogIndex": 0,
9
+ "endpoint": "http://pc-desktop:7200",
10
+ "recoveryStatus": {},
11
+ "topologyStatus": {
12
+ "state": "PRIMARY_NODE"
13
+ }
14
+ },
15
+ {
16
+ "address": "pc-desktop:7301",
17
+ "nodeState": "FOLLOWER",
18
+ "term": 2,
19
+ "syncStatus": {},
20
+ "lastLogTerm": 0,
21
+ "lastLogIndex": 0,
22
+ "endpoint": "http://pc-desktop:7201",
23
+ "recoveryStatus": {},
24
+ "topologyStatus": {
25
+ "state": "PRIMARY_NODE"
26
+ }
27
+ },
28
+ {
29
+ "address": "pc-desktop:7302",
30
+ "nodeState": "FOLLOWER",
31
+ "term": 2,
32
+ "syncStatus": {},
33
+ "lastLogTerm": 0,
34
+ "lastLogIndex": 0,
35
+ "endpoint": "http://pc-desktop:7202",
36
+ "recoveryStatus": {},
37
+ "topologyStatus": {
38
+ "state": "PRIMARY_NODE"
39
+ }
40
+ }
41
+ ]
@@ -0,0 +1,17 @@
1
+ {
2
+ "electionMinTimeout": 8000,
3
+ "electionRangeTimeout": 6000,
4
+ "heartbeatInterval": 2000,
5
+ "messageSizeKB": 64,
6
+ "verificationTimeout": 1500,
7
+ "transactionLogMaximumSizeGB": 50.0,
8
+ "batchUpdateInterval": 5000,
9
+ "nodes": [
10
+ "pc-desktop:7302",
11
+ "pc-desktop:7300",
12
+ "pc-desktop:7301"
13
+ ],
14
+ "primaryTags": [
15
+ "test"
16
+ ]
17
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "": [
3
+ {
4
+ "id": "graphdb-repo",
5
+ "title": "",
6
+ "uri": "http://localhost:8080/graphdb/repositories/graphdb-repo",
7
+ "externalUrl": "http://localhost:8080/graphdb/repositories/graphdb-repo",
8
+ "local": true,
9
+ "type": "graphdb",
10
+ "sesameType": "graphdb:SailRepository",
11
+ "location": "",
12
+ "readable": true,
13
+ "writable": true,
14
+ "unsupported": false,
15
+ "state": "RUNNING"
16
+ },
17
+ {
18
+ "id": "ontop-repo",
19
+ "title": "",
20
+ "uri": "http://localhost:8080/graphdb/repositories/ontop-repo",
21
+ "externalUrl": "http://localhost:8080/graphdb/repositories/ontop-repo",
22
+ "local": true,
23
+ "type": "ontop",
24
+ "sesameType": "graphdb:OntopRepository",
25
+ "location": "",
26
+ "readable": true,
27
+ "writable": true,
28
+ "unsupported": false,
29
+ "state": "RUNNING"
30
+ },
31
+ {
32
+ "id": "fedx-repo",
33
+ "title": "",
34
+ "uri": "http://localhost:8080/graphdb/repositories/fedx-repo",
35
+ "externalUrl": "http://localhost:8080/graphdb/repositories/fedx-repo",
36
+ "local": true,
37
+ "type": "fedx",
38
+ "sesameType": "graphdb:FedXRepository",
39
+ "location": "",
40
+ "readable": true,
41
+ "writable": true,
42
+ "unsupported": false,
43
+ "state": "RUNNING"
44
+ }
45
+ ]
46
+ }