Merge branch 'guest-profiles' into 'develop'

Allow guest browsing on Profiles and Statuses

See merge request soapbox-pub/soapbox-fe!1477
dnd
Justin 2022-06-02 19:27:58 +00:00
commit 646006b22d
3 zmienionych plików z 110 dodań i 3 usunięć

Wyświetl plik

@ -0,0 +1,87 @@
import { Map as ImmutableMap } from 'immutable';
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import { render, screen, waitFor } from '../../../jest/test-helpers';
import { normalizeAccount } from '../../../normalizers';
import UI from '../index';
const TestableComponent = () => (
<Switch>
<Route path='/@:username/posts/:statusId' exact><UI /></Route>
<Route path='/@:username/media' exact><UI /></Route>
<Route path='/@:username' exact><UI /></Route>
<Route path='/login' exact><span data-testid='sign-in'>Sign in</span></Route>
</Switch>
);
describe('<UI />', () => {
let store;
beforeEach(() => {
store = {
me: false,
accounts: ImmutableMap({
'1': normalizeAccount({
id: '1',
acct: 'username',
display_name: 'My name',
avatar: 'test.jpg',
}),
}),
};
});
describe('when logged out', () => {
describe('with guest experience disabled', () => {
beforeEach(() => {
store = { ...store, soapbox: ImmutableMap({ guestExperience: false }) };
});
describe('when viewing a Profile Page', () => {
it('should render the Profile page', async() => {
render(
<TestableComponent />,
{},
store,
{ initialEntries: ['/@username'] },
);
await waitFor(() => {
expect(screen.getByTestId('cta-banner')).toHaveTextContent('Sign up now to discuss');
});
});
});
describe('when viewing a Status Page', () => {
it('should render the Status page', async() => {
render(
<TestableComponent />,
{},
store,
{ initialEntries: ['/@username/posts/12'] },
);
await waitFor(() => {
expect(screen.getByTestId('cta-banner')).toHaveTextContent('Sign up now to discuss');
});
});
});
describe('when viewing any other page', () => {
it('should redirect to the login page', async() => {
render(
<TestableComponent />,
{},
store,
{ initialEntries: ['/@username/media'] },
);
await waitFor(() => {
expect(screen.getByTestId('sign-in')).toHaveTextContent('Sign in');
});
});
});
});
});
});

Wyświetl plik

@ -5,8 +5,7 @@ import React, { useState, useEffect, useRef, useCallback } from 'react';
import { HotKeys } from 'react-hotkeys';
import { defineMessages, useIntl } from 'react-intl';
import { useDispatch } from 'react-redux';
import { Switch, useHistory } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import { Switch, useHistory, matchPath, Redirect } from 'react-router-dom';
import { fetchFollowRequests } from 'soapbox/actions/accounts';
import { fetchReports, fetchUsers, fetchConfig } from 'soapbox/actions/admin';
@ -608,7 +607,14 @@ const UI: React.FC = ({ children }) => {
// Wait for login to succeed or fail
if (me === null) return null;
if (!me && !guestExperience) {
const isProfileOrStatusPage = !!matchPath(
history.location.pathname,
['/@:username', '/@:username/posts/:statusId'],
);
// Require login if Guest Experience is disabled and we're not trying
// to render a Profile or Status.
if (!me && (!guestExperience && !isProfileOrStatusPage)) {
cacheCurrentUrl(history.location);
return <Redirect to='/login' />;
}

Wyświetl plik

@ -15,3 +15,17 @@ jest.mock('uuid', () => ({ v4: jest.fn(() => '1') }));
const intersectionObserverMock = () => ({ observe: () => null, disconnect: () => null });
window.IntersectionObserver = jest.fn().mockImplementation(intersectionObserverMock);
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});