Skip to content

Commit

Permalink
chore: improve the code from the PR #861
Browse files Browse the repository at this point in the history
- Update the redirection host to the short link’s backend route (go.graasp.org for prod)
- Update mockGetShortLinksItem to filter by item id
- Update SDK version
- Adding changeVisibility test (part of tests from deleted shareItem)
- Update shareItem tests to test short links displayed links
- Moved short link test into share folder
- Replace alias by short link in translations
- Translates alias input
- Replace aliasUnchanged state by hasAliasChanged in ShortLinkDialogContent
- Regroup the useEffect in AliasValidation
- Set GraaspLogo as default icon when PlatformIcon get invalid platform
- Encapsulate debounce of API calls in a custom hooks
- Others minor improvements
  • Loading branch information
ReidyT committed Nov 29, 2023
1 parent 2580c94 commit a628efd
Show file tree
Hide file tree
Showing 24 changed files with 535 additions and 110 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
VITE_GRAASP_LIBRARY_HOST: ${{ vars.VITE_GRAASP_LIBRARY_HOST }}
VITE_GRAASP_ANALYZER_HOST: ${{ vars.VITE_GRAASP_ANALYZER_HOST }}
VITE_SHOW_NOTIFICATIONS: ${{ vars.VITE_SHOW_NOTIFICATIONS }}
VITE_GRAASP_REDIRECTION_HOST: "http://localhost:3030"
VITE_GRAASP_REDIRECTION_HOST: ${{ vars.VITE_GRAASP_REDIRECTION_HOST }}

# use the Cypress GitHub Action to run Cypress tests within the chrome browser
- name: Cypress run
Expand All @@ -66,8 +66,7 @@ jobs:
VITE_GRAASP_LIBRARY_HOST: ${{ vars.VITE_GRAASP_LIBRARY_HOST }}
VITE_GRAASP_ANALYZER_HOST: ${{ vars.VITE_GRAASP_ANALYZER_HOST }}
VITE_SHOW_NOTIFICATIONS: ${{ vars.VITE_SHOW_NOTIFICATIONS }}
# TODO: add REDIRECTION_HOST !
VITE_GRAASP_REDIRECTION_HOST: "http://localhost:3030"
VITE_GRAASP_REDIRECTION_HOST: ${{ vars.VITE_GRAASP_REDIRECTION_HOST }}

# after the test run completes
# store any screenshots
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ VITE_PORT=3111
VITE_GRAASP_API_HOST=http://localhost:3000
VITE_SHOW_NOTIFICATIONS=true
VITE_GRAASP_AUTH_HOST=http://localhost:3001
VITE_GRAASP_REDIRECTION_HOST=http://localhost:3000
# in prod, it is https://go.graasp.org
VITE_GRAASP_REDIRECTION_HOST=http://localhost:3000/items/short-links
VITE_H5P_INTEGRATION_URL=
VITE_VERSION=latest-dev
```
Expand Down Expand Up @@ -56,7 +57,8 @@ VITE_GRAASP_AUTH_HOST=http://localhost:3001
VITE_GRAASP_PLAYER_HOST=http://localhost:3112
VITE_GRAASP_LIBRARY_HOST=http://localhost:3005
VITE_GRAASP_ANALYZER_HOST=http://localhost:3113
VITE_GRAASP_REDIRECTION_HOST=http://localhost:3000
# in prod, it is https://go.graasp.org who will redirect to the backend
VITE_GRAASP_REDIRECTION_HOST=http://localhost:3000/items/short-links
VITE_H5P_INTEGRATION_URL=
VITE_VERSION=cypress-tests
VITE_SHOW_NOTIFICATIONS=true
Expand Down
2 changes: 2 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export default defineConfig({
BUILDER_HOST: `http://localhost:${process.env.VITE_PORT}`,
PLAYER_HOST: process.env.VITE_GRAASP_PLAYER_HOST,
ANALYZER_HOST: process.env.VITE_GRAASP_ANALYZER_HOST,
LIBRARY_HOST: process.env.VITE_GRAASP_LIBRARY_HOST,
REDIRECTION_HOST: process.env.VITE_GRAASP_REDIRECTION_HOST,
},
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
Expand Down
119 changes: 119 additions & 0 deletions cypress/e2e/item/share/changeVisibility.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { ItemLoginSchemaType, ItemTagType } from '@graasp/sdk';

import { buildItemPath } from '@/config/paths';

import { SETTINGS } from '../../../../src/config/constants';
import {
SHARE_ITEM_PSEUDONYMIZED_SCHEMA_ID,
SHARE_ITEM_VISIBILITY_SELECT_ID,
buildShareButtonId,
} from '../../../../src/config/selectors';
import {
ITEM_LOGIN_ITEMS,
SAMPLE_ITEMS,
SAMPLE_PUBLIC_ITEMS,
} from '../../../fixtures/items';

const changeVisibility = (value: string): void => {
cy.get(`#${SHARE_ITEM_VISIBILITY_SELECT_ID}`).click();
cy.get(`li[data-value="${value}"]`, { timeout: 1000 }).click();
};

describe('Visibility of an Item', () => {
it('Change Private Item to Public', () => {
const item = SAMPLE_ITEMS.items[0];
cy.setUpApi({ ...SAMPLE_ITEMS });
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

const visiblitySelect = cy.get(
`#${SHARE_ITEM_VISIBILITY_SELECT_ID} + input`,
);

// visibility select default value
visiblitySelect.should('have.value', SETTINGS.ITEM_PRIVATE.name);

// change private -> public
changeVisibility(SETTINGS.ITEM_PUBLIC.name);
cy.wait(`@postItemTag-${ItemTagType.Public}`).then(
({ request: { url } }) => {
expect(url).to.contain(item.id);
},
);
});

it('Change Public Item to Private', () => {
const item = SAMPLE_PUBLIC_ITEMS.items[0];
cy.setUpApi({ ...SAMPLE_PUBLIC_ITEMS });
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();
cy.wait(1000);
const visiblitySelect = cy.get(
`#${SHARE_ITEM_VISIBILITY_SELECT_ID} + input`,
);

// visibility select default value
visiblitySelect.should('have.value', SETTINGS.ITEM_PUBLIC.name);

// change public -> private
changeVisibility(SETTINGS.ITEM_PRIVATE.name);
cy.wait(`@deleteItemTag-${ItemTagType.Public}`).then(
({ request: { url } }) => {
expect(url).to.contain(item.id);
},
);
});

it('Change Public Item to Item Login', () => {
const item = SAMPLE_PUBLIC_ITEMS.items[0];
cy.setUpApi({ ...SAMPLE_PUBLIC_ITEMS });
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();
cy.wait(1000);
const visiblitySelect = cy.get(
`#${SHARE_ITEM_VISIBILITY_SELECT_ID} + input`,
);

// visibility select default value
visiblitySelect.should('have.value', SETTINGS.ITEM_PUBLIC.name);

// change public -> item login
changeVisibility(SETTINGS.ITEM_LOGIN.name);
cy.wait([
`@deleteItemTag-${ItemTagType.Public}`,
'@putItemLoginSchema',
]).then((data) => {
const {
request: { url },
} = data[0];
expect(url).to.contain(item.id);
expect(url).to.contain(ItemTagType.Public); // originally item login
});
});

it('Change Pseudonymized Item to Private Item', () => {
const item = ITEM_LOGIN_ITEMS.items[0];
cy.setUpApi({ items: [item] });
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

// visibility select default value
cy.get(`#${SHARE_ITEM_VISIBILITY_SELECT_ID} + input`).should(
'have.value',
SETTINGS.ITEM_LOGIN.name,
);

// change item login schema
cy.get(`#${SHARE_ITEM_PSEUDONYMIZED_SCHEMA_ID} + input`).should(
'have.value',
ItemLoginSchemaType.Username,
);
// item login edition is done in itemLogin.cy.js

// change pseudonymized -> private
changeVisibility(SETTINGS.ITEM_PRIVATE.name);
cy.wait(`@deleteItemLoginSchema`).then(({ request: { url } }) => {
expect(url).to.include(item.id);
});
});
});
194 changes: 194 additions & 0 deletions cypress/e2e/item/share/shareItem.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import { Context, ShortLink, appendPathToUrl } from '@graasp/sdk';

import { buildItemPath } from '@/config/paths';
import { ShortLinkPlatform } from '@/utils/shortLink';

import {
SHARE_ITEM_QR_BTN_ID,
SHARE_ITEM_QR_DIALOG_ID,
SHORT_LINK_COMPONENT,
buildShareButtonId,
buildShortLinkPlatformTextId,
buildShortLinkUrlTextId,
} from '../../../../src/config/selectors';
import { PUBLISHED_ITEM } from '../../../fixtures/items';
import {
GRAASP_REDIRECTION_HOST,
buildGraaspBuilderView,
buildGraaspLibraryLink,
buildGraaspPlayerView,
} from '../../../support/paths';

const checkContainPlatformText = (platform: ShortLinkPlatform) =>
cy
.get(`#${buildShortLinkPlatformTextId(platform)}`)
.should('contain', platform);

const checkContainUrlText = (platform: ShortLinkPlatform, itemId: string) => {
let expectedUrl;

// The client host manager can't be used here because
// cypress run this before the main.tsx, where the manager is init.
switch (platform) {
case 'builder':
expectedUrl = buildGraaspBuilderView(itemId);
break;
case 'player':
expectedUrl = buildGraaspPlayerView(itemId);
break;
case 'library':
expectedUrl = buildGraaspLibraryLink(itemId);
break;
default:
throw new Error(`The given platform ${platform} is unknown.`);
}

cy.get(`#${buildShortLinkUrlTextId(platform)}`).should(
'contain',
expectedUrl,
);
};

const checkContainShortLinkText = (
platform: ShortLinkPlatform,
alias: string,
) => {
const expectedUrl = appendPathToUrl({
baseURL: GRAASP_REDIRECTION_HOST,
pathname: alias,
}).toString();

cy.get(`#${buildShortLinkUrlTextId(platform)}`).should(
'contain',
expectedUrl,
);
};

describe('Share Item Link', () => {
describe('Without short links', () => {
const item = PUBLISHED_ITEM;

beforeEach(() => {
cy.setUpApi({ items: [PUBLISHED_ITEM] });
});

it('Builder link is correctly displayed', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

const context = Context.Builder;
checkContainPlatformText(context);
checkContainUrlText(context, item.id);
});

it('Player link is correctly displayed', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

const context = Context.Player;
checkContainPlatformText(context);
checkContainUrlText(context, item.id);
});

it('Library link is correctly displayed', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

const context = Context.Library;
checkContainPlatformText(context);
checkContainUrlText(context, item.id);
});

it('Share Item with QR Code', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

cy.get(`#${SHARE_ITEM_QR_BTN_ID}`).click();
cy.get(`#${SHARE_ITEM_QR_DIALOG_ID}`).should('exist');
});
});

describe('With short links', () => {
const item = PUBLISHED_ITEM;

const shortLinks: ShortLink[] = [
{
alias: 'test-1',
platform: Context.Builder,
item: { id: item.id },
createdAt: new Date().toISOString(),
},
{
alias: 'test-2',
platform: Context.Player,
item: { id: item.id },
createdAt: new Date().toISOString(),
},
{
alias: 'test-3',
platform: Context.Library,
item: { id: item.id },
createdAt: new Date().toISOString(),
},
];

beforeEach(() => {
cy.setUpApi({ items: [PUBLISHED_ITEM], shortLinks, itemId: item.id });
});

it('Builder link is correctly displayed', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.wait('@getShortLinksItem').its('response.body.length').should('eq', 3);
cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

const context = Context.Builder;
checkContainPlatformText(context);
checkContainShortLinkText(context, shortLinks[0].alias);
});

it('Player link is correctly displayed', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.wait('@getShortLinksItem').its('response.body.length').should('eq', 3);
cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

const context = Context.Player;
checkContainPlatformText(context);
checkContainShortLinkText(context, shortLinks[1].alias);
});

it('Library link is correctly displayed', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.wait('@getShortLinksItem').its('response.body.length').should('eq', 3);
cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

const context = Context.Library;
checkContainPlatformText(context);
checkContainShortLinkText(context, shortLinks[2].alias);
});

it('Share Item with QR Code', () => {
cy.visit(buildItemPath(item.id));
cy.get(`#${buildShareButtonId(item.id)}`).click();

cy.wait('@getShortLinksItem').its('response.body.length').should('eq', 3);
cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

cy.get(`#${SHARE_ITEM_QR_BTN_ID}`).click();
cy.get(`#${SHARE_ITEM_QR_DIALOG_ID}`).should('exist');
});
});
});
Loading

0 comments on commit a628efd

Please sign in to comment.