Skip to content

Commit

Permalink
feat: update workflows (#152)
Browse files Browse the repository at this point in the history
* feat: update workflows

* fix: tests

* fix: revert cypress workflow to old version

* fix: use composite workflow

* chore: update

* chore: update correct
  • Loading branch information
spaenleh authored Nov 14, 2022
1 parent 6eb7b3e commit f7942bd
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cdelivery-s3-caller.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
jobs:
graasp-deploy-s3-workflow:
name: Graasp Player
uses: graasp/graasp-deploy/.github/workflows/cdelivery-s3.yml@a936fcc673bca2e70cdc2dcb0880658b5ecb65ef
uses: graasp/graasp-deploy/.github/workflows/cdelivery-s3.yml@v1
with:
build-folder: 'build'
tag: ${{ github.event.client_payload.tag }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cdeployment-s3-caller.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
graasp-deploy-s3-workflow:
name: Graasp Player
# Reference reusable workflow file. Using the commit SHA is the safest for stability and security
uses: graasp/graasp-deploy/.github/workflows/cdeployment-s3.yml@a936fcc673bca2e70cdc2dcb0880658b5ecb65ef
uses: graasp/graasp-deploy/.github/workflows/cdeployment-s3.yml@v1
with:
build-folder: 'build'
tag: ${{ github.event.client_payload.tag }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/cintegration-s3-caller.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ on:
test-execution:
description: 'Execute test job (Default: true)'
type: choice
options:
- yes
- no
options:
- yes
- no
default: yes
# This workflow is made up of one job that calls the reusable workflow in graasp-deploy
jobs:
graasp-deploy-s3-workflow:
name: Graasp Player
# Reference reusable workflow file. Using the commit SHA is the safest for stability and security
uses: graasp/graasp-deploy/.github/workflows/cintegration-s3.yml@a936fcc673bca2e70cdc2dcb0880658b5ecb65ef
uses: graasp/graasp-deploy/.github/workflows/cintegration-s3.yml@v1
with:
build-folder: 'build'
secrets:
Expand Down
13 changes: 7 additions & 6 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,30 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: install
run: yarn
- name: Yarn install and cache
uses: graasp/graasp-deploy/.github/actions/yarn-install-and-cache@v1
with:
cypress: true

- name: cypress run
uses: cypress-io/github-action@v2
uses: cypress-io/github-action@v4
env:
REACT_APP_API_HOST: ${{ secrets.REACT_APP_API_HOST }}
REACT_APP_GRAASP_COMPOSE_HOST: http://localhost:3111
REACT_APP_AUTHENTICATION_HOST: http://localhost:3001
REACT_APP_NODE_ENV: test
REACT_APP_DOMAIN: 'localhost'
# mock values
REACT_APP_HIDDEN_ITEM_TAG_ID: 12345678-1234-1234-1234-123456789012
REACT_APP_PUBLIC_TAG_ID: 22345678-1234-1234-1234-123456789013
with:
install: false
config: baseUrl=http://localhost:3000
start: yarn start:ci
wait-on: 'http://localhost:3000'
wait-on-timeout: 180
browser: chrome
headless: true
quiet: true

- name: coverage report
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/update-staging-version.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This workflow triggers a new workflow inside the graasp-deploy repository. It passes a json
# with the repository name and the latest tag pushed from the caller repository.
# This workflow triggers a new workflow inside the graasp-deploy repository. It passes a json
# with the repository name and the latest tag pushed from the caller repository.
name: Push new tag to graasp-deploy repository

# Controls when the action will run
Expand All @@ -14,11 +14,11 @@ on:
# Default value if no value is explicitly provided
# Input does not have to be provided for the workflow to run
type: choice
options:
- first
- patch
- minor
- major
options:
- first
- patch
- minor
- major
default: patch
required: true

Expand All @@ -29,7 +29,7 @@ jobs:
name: Graasp Player
# Replace 'main' with the hash of a commit, so it points to an specific version of the reusable workflow that is used
# Reference reusable workflow file. Using the commit SHA is the safest for stability and security
uses: graasp/graasp-deploy/.github/workflows/update-staging-version.yml@c5c706c5b643b04f6e9012fc4bb5fa736b6a651e
uses: graasp/graasp-deploy/.github/workflows/update-staging-version.yml@v1
with:
release-type: ${{ inputs.release-type }}
secrets:
Expand Down
13 changes: 12 additions & 1 deletion cypress/integration/main.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ describe('Main Screen', () => {
cy.visit(buildMainPath({ rootId: GRAASP_DOCUMENT_ITEM.id, id: null }));

expectDocumentViewScreenLayout(GRAASP_DOCUMENT_ITEM);
cy.get(`#${BUILDER_EDIT_BUTTON_ID}`).should('be.visible').click();
});
});

Expand Down Expand Up @@ -137,4 +136,16 @@ describe('Main Screen', () => {
expectFolderLayout({ rootId, items: PUBLIC_STATIC_ELECTRICITY.items });
});
});

describe('Write access', () => {
beforeEach(() => {
cy.setUpApi({
items: [GRAASP_DOCUMENT_ITEM, ...FOLDER_WITH_SUBFOLDER_ITEM.items],
});
});
it('Show Builder button', () => {
cy.visit(buildMainPath({ rootId: GRAASP_DOCUMENT_ITEM.id, id: null }));
cy.get(`#${BUILDER_EDIT_BUTTON_ID}`).should('be.visible').click();
});
});
});
2 changes: 2 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
mockGetChildren,
mockGetCurrentMember,
mockGetItem,
mockGetItemMembershipsForItem,
mockGetItemTags,
mockGetItemsTags,
mockGetMemberBy,
Expand Down Expand Up @@ -51,6 +52,7 @@ Cypress.Commands.add(
{ items: cachedItems, currentMember },
getItemError || getCurrentMemberError,
);
mockGetItemMembershipsForItem(items, currentMember);
mockGetPublicItem({ items: cachedItems });

mockGetItemTags(items, currentMember);
Expand Down
47 changes: 47 additions & 0 deletions cypress/support/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { StatusCodes } from 'http-status-codes';
import qs from 'qs';

import { API_ROUTES } from '@graasp/query-client';
import { PermissionLevel } from '@graasp/sdk';

import { DEFAULT_GET } from '../../src/api/utils';
import { MEMBER_PROFILE_PATH } from '../../src/config/constants';
Expand All @@ -22,6 +23,7 @@ const {
buildPublicDownloadFilesRoute,
SIGN_OUT_ROUTE,
buildGetMembersRoute,
buildGetItemMembershipsForItemsRoute,
} = API_ROUTES;

const API_HOST = Cypress.env('API_HOST');
Expand Down Expand Up @@ -120,6 +122,51 @@ export const mockGetItem = ({ items, currentMember }, shouldThrowError) => {
).as('getItem');
};

export const mockGetItemMembershipsForItem = (items, currentMember) => {
cy.intercept(
{
method: DEFAULT_GET.method,
url: new RegExp(
`${API_HOST}/${parseStringToRegExp(
buildGetItemMembershipsForItemsRoute([]),
)}`,
),
},
({ reply, url }) => {
const { itemId } = qs.parse(url.slice(url.indexOf('?') + 1));
const selectedItems = items.filter(({ id }) => itemId?.includes(id));
const allMemberships = selectedItems.map(
({ creator, id, memberships }) => {
// build default membership depending on current member
// if the current member is the creator, it has membership
// otherwise it should return an error
const defaultMembership =
creator === currentMember?.id
? [
{
permission: PermissionLevel.Admin,
memberId: creator,
itemId: id,
},
]
: { statusCode: StatusCodes.UNAUTHORIZED };

// if the defined memberships does not contain currentMember, it should throw
const currentMemberHasMembership = memberships?.find(
({ memberId }) => memberId === currentMember?.id,
);
if (!currentMemberHasMembership) {
return defaultMembership;
}

return memberships || defaultMembership;
},
);
reply(allMemberships);
},
).as('getItemMemberships');
};

export const mockGetPublicItem = ({ items }, shouldThrowError) => {
cy.intercept(
{
Expand Down
3 changes: 3 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
<script>
document.domain = '%REACT_APP_DOMAIN%';
</script>
<title>Graasp Player</title>
</head>
<body>
Expand Down
21 changes: 18 additions & 3 deletions src/components/common/BuilderButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import { Tooltip, makeStyles } from '@material-ui/core';
import IconButton from '@material-ui/core/IconButton';
import EditIcon from '@material-ui/icons/Edit';

import { buildItemLinkForBuilder, redirect } from '@graasp/sdk';
import {
PermissionLevel,
buildItemLinkForBuilder,
redirect,
} from '@graasp/sdk';
import { Loader, PermissionedComponent } from '@graasp/ui';

import {
FLOATING_BUTTON_Z_INDEX,
GRAASP_COMPOSE_HOST,
buildBuilderTabName,
} from '../../config/constants';
import { hooks } from '../../config/queryClient';
import { BUILDER_EDIT_BUTTON_ID } from '../../config/selectors';
import { isRegularUser } from '../../utils/user';
import { CurrentMemberContext } from '../context/CurrentMemberContext';
Expand All @@ -29,6 +34,8 @@ const BuilderButton = ({ id }) => {
const { t } = useTranslation();
const classes = useStyles();
const { data: user, isLoading } = useContext(CurrentMemberContext);
const { data: itemMemberships, isLoading: isLoadingItemMemberships } =
hooks.useItemMemberships(id);

const onClickComposeView = () => {
const url = buildItemLinkForBuilder({
Expand All @@ -41,10 +48,18 @@ const BuilderButton = ({ id }) => {
});
};

if (isLoading) {
if (isLoading || isLoadingItemMemberships) {
<Loader />;
}

// get user permission
const userPermission = itemMemberships?.find(
(perms) => perms.memberId === user?.id,
)?.permission;
const canOpenBuilder = userPermission
? [PermissionLevel.Admin, PermissionLevel.Write].includes(userPermission)
: false;

const ActionButtons = (
<Tooltip title={t('Compose View')}>
<IconButton
Expand All @@ -61,7 +76,7 @@ const BuilderButton = ({ id }) => {
return (
<PermissionedComponent
component={ActionButtons}
checkPermissions={() => isRegularUser(user)}
checkPermissions={() => canOpenBuilder}
/>
);
};
Expand Down

0 comments on commit f7942bd

Please sign in to comment.