make integration-tests-in-docker
</pre>
+### Run tests interactively in container
+
+<pre>
+$ xhost +local:root
+$ ARVADOS_DIR=/path/to/arvados
+$ docker run -ti -v$PWD:$PWD -v$ARVADOS_DIR:/usr/src/arvados -w$PWD --env="DISPLAY" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" workbench2-build /bin/bash
+(inside container)
+# yarn run cypress install
+# tools/run-integration-tests.sh -i -a /usr/src/arvados
+</pre>
+
### Production build
<pre>
yarn install
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+describe('Collection panel tests', function() {
+ let activeUser;
+ let adminUser;
+
+ before(function() {
+ // Only set up common users once. These aren't set up as aliases because
+ // aliases are cleaned up after every test. Also it doesn't make sense
+ // to set the same users on beforeEach() over and over again, so we
+ // separate a little from Cypress' 'Best Practices' here.
+ cy.getUser('admin', 'Admin', 'User', true, true)
+ .as('adminUser').then(function() {
+ adminUser = this.adminUser;
+ }
+ );
+ cy.getUser('collectionuser1', 'Collection', 'User', false, true)
+ .as('activeUser').then(function() {
+ activeUser = this.activeUser;
+ }
+ );
+ })
+
+ beforeEach(function() {
+ cy.clearCookies()
+ cy.clearLocalStorage()
+ })
+
+ it('checks that Public favorites does not appear under shared with me', function() {
+ cy.loginAs(adminUser);
+ cy.contains('Shared with me').click();
+ cy.get('main').contains('Public favorites').should('not.exist');
+ })
+
+ it('creates and removes a public favorite', function() {
+ cy.loginAs(adminUser);
+ cy.createGroup(adminUser.token, {
+ name: `my-favorite-project`,
+ group_class: 'project',
+ }).as('myFavoriteProject').then(function() {
+ cy.contains('Refresh').click();
+ cy.get('main').contains('my-favorite-project').rightclick();
+ cy.contains('Add to public favorites').click();
+ cy.contains('Public Favorites').click();
+ cy.get('main').contains('my-favorite-project').rightclick();
+ cy.contains('Remove from public favorites').click();
+ cy.get('main').contains('my-favorite-project').should('not.exist');
+ cy.trashGroup(adminUser.token, this.myFavoriteProject.uuid);
+ });
+ })
+})
}
)
+Cypress.Commands.add(
+ "trashGroup", (token, uuid) => {
+ return cy.deleteResource(token, 'groups', uuid);
+ }
+)
+
Cypress.Commands.add(
"createCollection", (token, data) => {
return cy.createResource(token, 'collections', {
}
)
+Cypress.Commands.add(
+ "deleteResource", (token, suffix, uuid) => {
+ return cy.doRequest('DELETE', '/arvados/v1/'+suffix+'/'+uuid)
+ .its('body').as('resource')
+ .then(function() {
+ return this.resource;
+ })
+ }
+)
+
Cypress.Commands.add(
"loginAs", (user) => {
cy.visit(`/token/?api_token=${user.token}`);
cy.get('div#root').should('contain', 'Arvados Workbench (zzzzz)');
cy.get('div#root').should('not.contain', 'Your account is inactive');
}
-)
\ No newline at end of file
+)
import { getDataExplorerColumnFilters } from '~/store/data-explorer/data-explorer-middleware-service';
import { serializeSimpleObjectTypeFilters } from '../resource-type-filters/resource-type-filters';
import { ResourceKind } from "~/models/resource";
+import { LinkClass } from "~/models/link";
export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareService {
constructor(private services: ServiceRepository, id: string) {
api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
const responseLinks = await this.services.linkService.list({
filters: new FilterBuilder()
- .addEqual("link_class", 'star')
+ .addEqual("link_class", LinkClass.STAR)
.addEqual('tail_uuid', getUserUuid(api.getState()))
.addEqual('tail_kind', ResourceKind.USER)
.getFilters()
try {
api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
const uuidPrefix = api.getState().auth.config.uuidPrefix;
- const uuid = `${uuidPrefix}-j7d0g-fffffffffffffff`;
+ const publicProjectUuid = `${uuidPrefix}-j7d0g-publicfavorites`;
const responseLinks = await this.services.linkService.list({
limit: dataExplorer.rowsPerPage,
offset: dataExplorer.page * dataExplorer.rowsPerPage,
filters: new FilterBuilder()
.addEqual('link_class', LinkClass.STAR)
- .addILike("name", dataExplorer.searchValue)
- .addEqual('owner_uuid', uuid)
+ .addEqual('owner_uuid', publicProjectUuid)
.addIsA("head_uuid", typeFilters)
.getFilters()
});
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<any> => {
dispatch(progressIndicatorActions.START_WORKING("togglePublicFavorite"));
const uuidPrefix = getState().auth.config.uuidPrefix;
- const uuid = `${uuidPrefix}-j7d0g-fffffffffffffff`;
+ const uuid = `${uuidPrefix}-j7d0g-publicfavorites`;
dispatch(publicFavoritesActions.TOGGLE_PUBLIC_FAVORITE({ resourceUuid: resource.uuid }));
const isPublicFavorite = checkPublicFavorite(resource.uuid, getState().publicFavorites);
dispatch(snackbarActions.OPEN_SNACKBAR({
export const updatePublicFavorites = (resourceUuids: string[]) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
const uuidPrefix = getState().auth.config.uuidPrefix;
- const uuid = `${uuidPrefix}-j7d0g-fffffffffffffff`;
+ const uuid = `${uuidPrefix}-j7d0g-publicfavorites`;
dispatch(publicFavoritesActions.CHECK_PRESENCE_IN_PUBLIC_FAVORITES(resourceUuids));
services.favoriteService
.checkPresenceInFavorites(uuid, resourceUuids)
import { updateFavorites } from '~/store/favorites/favorites-actions';
import { updateResources } from '~/store/resources/resources-actions';
import { loadMissingProcessesInformation, getFilters } from '~/store/project-panel/project-panel-middleware-service';
-import {snackbarActions, SnackbarKind} from '~/store/snackbar/snackbar-actions';
+import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
import { sharedWithMePanelActions } from './shared-with-me-panel-actions';
import { ListResults } from '~/services/common-service/common-service';
import { GroupContentsResource, GroupContentsResourcePrefix } from '~/services/groups-service/groups-service';
import { ProjectPanelColumnNames } from '~/views/project-panel/project-panel';
import { getSortColumn } from "~/store/data-explorer/data-explorer-reducer";
import { updatePublicFavorites } from '~/store/public-favorites/public-favorites-actions';
+import { FilterBuilder } from '~/services/api/filter-builder';
export class SharedWithMeMiddlewareService extends DataExplorerMiddlewareService {
constructor(private services: ServiceRepository, id: string) {
.contents('', {
...getParams(dataExplorer),
excludeHomeProject: true,
+ filters: new FilterBuilder().addDistinct('uuid', `${state.auth.config.uuidPrefix}-j7d0g-publicfavorites`).getFilters()
});
api.dispatch<any>(updateFavorites(response.items.map(item => item.uuid)));
api.dispatch<any>(updatePublicFavorites(response.items.map(item => item.uuid)));
dispatch(resourcesActions.SET_RESOURCES(items));
};
-const loadSharedRoot = async (dispatch: Dispatch, _: () => RootState, services: ServiceRepository) => {
+const loadSharedRoot = async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(treePickerActions.LOAD_TREE_PICKER_NODE({ id: SidePanelTreeCategory.SHARED_WITH_ME, pickerId: SIDE_PANEL_TREE }));
const params = {
filters: `[${new FilterBuilder()
.addIsA('uuid', ResourceKind.PROJECT)
.addEqual('group_class', GroupClass.PROJECT)
+ .addDistinct('uuid', getState().auth.config.uuidPrefix + '-j7d0g-publicfavorites')
.getFilters()}]`,
order: new OrderBuilder<ProjectResource>()
.addAsc('name', GroupContentsResourcePrefix.PROJECT)
async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
const { pickerId, includeCollections = false, includeFiles = false } = params;
const uuidPrefix = getState().auth.config.uuidPrefix;
- const uuid = `${uuidPrefix}-j7d0g-fffffffffffffff`;
- if (uuid) {
+ const publicProjectUuid = `${uuidPrefix}-j7d0g-publicfavorites`;
- const filters = pipe(
- (fb: FilterBuilder) => includeCollections
- ? fb.addIsA('head_uuid', [ResourceKind.PROJECT, ResourceKind.COLLECTION])
- : fb.addIsA('head_uuid', [ResourceKind.PROJECT]),
- fb => fb
- .addEqual('link_class', LinkClass.STAR)
- .addEqual('owner_uuid', uuid)
- .getFilters(),
- )(new FilterBuilder());
+ const filters = pipe(
+ (fb: FilterBuilder) => includeCollections
+ ? fb.addIsA('head_uuid', [ResourceKind.PROJECT, ResourceKind.COLLECTION])
+ : fb.addIsA('head_uuid', [ResourceKind.PROJECT]),
+ fb => fb
+ .addEqual('link_class', LinkClass.STAR)
+ .addEqual('owner_uuid', publicProjectUuid)
+ .getFilters(),
+ )(new FilterBuilder());
- const { items } = await services.linkService.list({ filters });
+ const { items } = await services.linkService.list({ filters });
- dispatch<any>(receiveTreePickerData<LinkResource>({
- id: 'Public Favorites',
- pickerId,
- data: items,
- extractNodeData: item => ({
- id: item.headUuid,
- value: item,
- status: item.headKind === ResourceKind.PROJECT
+ dispatch<any>(receiveTreePickerData<LinkResource>({
+ id: 'Public Favorites',
+ pickerId,
+ data: items,
+ extractNodeData: item => ({
+ id: item.headUuid,
+ value: item,
+ status: item.headKind === ResourceKind.PROJECT
+ ? TreeNodeStatus.INITIAL
+ : includeFiles
? TreeNodeStatus.INITIAL
- : includeFiles
- ? TreeNodeStatus.INITIAL
- : TreeNodeStatus.LOADED
- }),
- }));
- }
+ : TreeNodeStatus.LOADED
+ }),
+ }));
};
export const receiveTreePickerProjectsData = (id: string, projects: ProjectResource[], pickerId: string) =>