#11 Use nodeId (ID) instead of id (number) as identifier for apollo cache
This commit is contained in:
parent
8c450790c3
commit
524739cbbb
37
redaktions-app/src/backend/mutations/login.mock.ts
Normal file
37
redaktions-app/src/backend/mutations/login.mock.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import {MockedResponse} from "@apollo/client/testing";
|
||||
import {loginMutation, LoginMutationResponse} from "./login";
|
||||
|
||||
export const loginMock: Array<MockedResponse<LoginMutationResponse>> = [
|
||||
{
|
||||
request: {
|
||||
query: loginMutation,
|
||||
variables: {
|
||||
email: "test@email.com",
|
||||
password: "password",
|
||||
}
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
authenticate: {
|
||||
jwtToken: "123"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
request: {
|
||||
query: loginMutation,
|
||||
variables: {
|
||||
email: "test@email.com",
|
||||
password: "wrong-password",
|
||||
}
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
authenticate: {
|
||||
jwtToken: null
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
19
redaktions-app/src/backend/mutations/login.ts
Normal file
19
redaktions-app/src/backend/mutations/login.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import {gql} from "@apollo/client";
|
||||
|
||||
export const loginMutation = gql`
|
||||
mutation Login($email: String!, $password: String!) {
|
||||
authenticate(input: {email: $email, password: $password}) {
|
||||
jwtToken
|
||||
}
|
||||
}`
|
||||
|
||||
export interface LoginMutationVariables {
|
||||
email: string,
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface LoginMutationResponse {
|
||||
authenticate: {
|
||||
jwtToken: string | null
|
||||
}
|
||||
}
|
26
redaktions-app/src/backend/mutations/signUp.ts
Normal file
26
redaktions-app/src/backend/mutations/signUp.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import {gql} from "@apollo/client";
|
||||
|
||||
export const registerMutation = gql`
|
||||
mutation CreateAccount($firstName: String!, $lastName: String!, $email: String!, $password: String!) {
|
||||
registerPerson(input: {firstName: $firstName, lastName: $lastName, email: $email, password: $password}) {
|
||||
person {
|
||||
nodeId
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export interface RegisterMutationVariables {
|
||||
firstName: string,
|
||||
lastName: string,
|
||||
email: string,
|
||||
password: string,
|
||||
}
|
||||
|
||||
export interface RegisterMutationResponse {
|
||||
registerPerson: {
|
||||
person: {
|
||||
nodeId: string
|
||||
}
|
||||
}
|
||||
}
|
25
redaktions-app/src/backend/queries/allCategories.ts
Normal file
25
redaktions-app/src/backend/queries/allCategories.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import {gql} from "@apollo/client";
|
||||
|
||||
export const allCategoriesQuery = gql`
|
||||
query AllQuestions {
|
||||
allCategories {
|
||||
nodes {
|
||||
nodeId
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export interface AllCategoriesQueryResponse {
|
||||
allCategories: {
|
||||
nodes: Array<AllCategoriesQueryNodes>
|
||||
}
|
||||
}
|
||||
|
||||
interface AllCategoriesQueryNodes {
|
||||
nodeId: string,
|
||||
title: string,
|
||||
description: string,
|
||||
}
|
31
redaktions-app/src/backend/queries/allQuestions.ts
Normal file
31
redaktions-app/src/backend/queries/allQuestions.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import {gql} from "@apollo/client";
|
||||
|
||||
export const allQuestionsQuery = gql`
|
||||
query AllQuestions {
|
||||
allQuestions {
|
||||
nodes {
|
||||
nodeId
|
||||
text
|
||||
description
|
||||
categoryByCategoryId {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export interface AllQuestionsQueryResponse {
|
||||
allQuestions: {
|
||||
nodes: Array<AllQuestionsQueryNodes>
|
||||
}
|
||||
}
|
||||
|
||||
interface AllQuestionsQueryNodes {
|
||||
nodeId: string,
|
||||
text: string,
|
||||
description: string,
|
||||
categoryByCategoryId: {
|
||||
title: string
|
||||
}
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
import {Paper, Typography} from "@material-ui/core";
|
||||
import React from "react";
|
||||
import {makeStyles} from "@material-ui/core/styles";
|
||||
import {gql, useQuery} from "@apollo/client";
|
||||
import {useQuery} from "@apollo/client";
|
||||
import AddCard from "./AddCard";
|
||||
import AccordionWithEdit from "./AccordionWithEdit";
|
||||
import {allCategoriesQuery, AllCategoriesQueryResponse} from "../backend/queries/allCategories";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -21,7 +22,7 @@ export default function CategoryList() {
|
|||
<Paper className={classes.root}>
|
||||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>Kategorien</Typography>
|
||||
{data?.allCategories.nodes.map(category => <AccordionWithEdit
|
||||
key={category.id.toString()}
|
||||
key={category.nodeId}
|
||||
title={category.title}
|
||||
description={category.description}/>
|
||||
)}
|
||||
|
@ -30,26 +31,3 @@ export default function CategoryList() {
|
|||
)
|
||||
}
|
||||
|
||||
const allCategoriesQuery = gql`
|
||||
query AllQuestions {
|
||||
allCategories {
|
||||
nodes {
|
||||
id
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
interface AllCategoriesQueryResponse {
|
||||
allCategories: {
|
||||
nodes: Array<AllCategoriesQueryNodes>
|
||||
}
|
||||
}
|
||||
|
||||
interface AllCategoriesQueryNodes {
|
||||
id: number,
|
||||
title: string,
|
||||
description: string,
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import {Paper, Typography} from "@material-ui/core";
|
||||
import React from "react";
|
||||
import {makeStyles} from "@material-ui/core/styles";
|
||||
import {gql, useQuery} from "@apollo/client";
|
||||
import {useQuery} from "@apollo/client";
|
||||
import AddCard from "./AddCard";
|
||||
import AccordionWithEdit from "./AccordionWithEdit";
|
||||
import {allQuestionsQuery, AllQuestionsQueryResponse} from "../backend/queries/allQuestions";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -21,7 +22,7 @@ export default function QuestionList() {
|
|||
<Paper className={classes.root}>
|
||||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>Fragen</Typography>
|
||||
{data?.allQuestions.nodes.map(question => <AccordionWithEdit
|
||||
key={question.id.toString()}
|
||||
key={question.nodeId}
|
||||
title={question.text}
|
||||
subTitle={question.categoryByCategoryId.title}
|
||||
description={question.description}/>
|
||||
|
@ -31,32 +32,3 @@ export default function QuestionList() {
|
|||
)
|
||||
}
|
||||
|
||||
const allQuestionsQuery = gql`
|
||||
query AllQuestions {
|
||||
allQuestions {
|
||||
nodes {
|
||||
id
|
||||
text
|
||||
description
|
||||
categoryByCategoryId {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
interface AllQuestionsQueryResponse {
|
||||
allQuestions: {
|
||||
nodes: Array<AllQuestionsQueryNodes>
|
||||
}
|
||||
}
|
||||
|
||||
interface AllQuestionsQueryNodes {
|
||||
id: number,
|
||||
text: string,
|
||||
description: string,
|
||||
categoryByCategoryId: {
|
||||
title: string
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,10 @@ import {Link, useHistory, useLocation} from 'react-router-dom';
|
|||
import Typography from '@material-ui/core/Typography';
|
||||
import {makeStyles} from '@material-ui/core/styles';
|
||||
import Container from '@material-ui/core/Container';
|
||||
import {gql, useMutation} from "@apollo/client";
|
||||
import {useMutation} from "@apollo/client";
|
||||
import ButtonWithSpinner from "./ButtonWithSpinner";
|
||||
import {Copyright} from "./Copyright";
|
||||
import {loginMutation, LoginMutationResponse, LoginMutationVariables} from "../backend/mutations/login";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
paper: {
|
||||
|
@ -152,24 +153,6 @@ export default function SignIn() {
|
|||
);
|
||||
}
|
||||
|
||||
export const loginMutation = gql`
|
||||
mutation Login($email: String!, $password: String!) {
|
||||
authenticate(input: {email: $email, password: $password}) {
|
||||
jwtToken
|
||||
}
|
||||
}`
|
||||
|
||||
interface LoginMutationVariables {
|
||||
email: string,
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface LoginMutationResponse {
|
||||
authenticate: {
|
||||
jwtToken: string | null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,10 +10,11 @@ import Typography from '@material-ui/core/Typography';
|
|||
import {makeStyles} from '@material-ui/core/styles';
|
||||
import Container from '@material-ui/core/Container';
|
||||
import {Copyright} from "./Copyright";
|
||||
import {gql, useMutation} from "@apollo/client";
|
||||
import {useMutation} from "@apollo/client";
|
||||
import ButtonWithSpinner from "./ButtonWithSpinner";
|
||||
import {errorHandler, SignUpError} from "./SignUpErrorHandler";
|
||||
import {Alert} from "@material-ui/lab";
|
||||
import {registerMutation, RegisterMutationResponse, RegisterMutationVariables} from "../backend/mutations/signUp";
|
||||
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
|
@ -199,28 +200,3 @@ export default function SignUp() {
|
|||
);
|
||||
}
|
||||
|
||||
const registerMutation = gql`
|
||||
mutation CreateAccount($firstName: String!, $lastName: String!, $email: String!, $password: String!) {
|
||||
registerPerson(input: {firstName: $firstName, lastName: $lastName, email: $email, password: $password}) {
|
||||
person {
|
||||
nodeId
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
interface RegisterMutationVariables {
|
||||
firstName: string,
|
||||
lastName: string,
|
||||
email: string,
|
||||
password: string,
|
||||
}
|
||||
|
||||
interface RegisterMutationResponse {
|
||||
registerPerson: {
|
||||
person: {
|
||||
nodeId: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import './index.css';
|
|||
import App from './App';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import {ApolloProvider} from "@apollo/client";
|
||||
import {client} from "./backend-connection/helper";
|
||||
import {client} from "./backend/helper";
|
||||
import {BrowserRouter as Router} from "react-router-dom";
|
||||
|
||||
ReactDOM.render(
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React from 'react';
|
||||
import SignIn, {loginMutation, LoginMutationResponse} from "../components/SignIn";
|
||||
import SignIn from "../components/SignIn";
|
||||
import {fireEvent, render, screen, waitFor} from '@testing-library/react'
|
||||
import {MockedProvider, MockedResponse} from '@apollo/client/testing';
|
||||
import {MockedProvider} from '@apollo/client/testing';
|
||||
import {MemoryRouter} from 'react-router-dom';
|
||||
import {loginMock} from "../backend/mutations/login.mock";
|
||||
|
||||
const mockHistoryReplace = jest.fn();
|
||||
|
||||
|
@ -13,46 +14,11 @@ jest.mock('react-router-dom', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
const mocks: Array<MockedResponse<LoginMutationResponse>> = [
|
||||
{
|
||||
request: {
|
||||
query: loginMutation,
|
||||
variables: {
|
||||
email: "test@email.com",
|
||||
password: "password",
|
||||
}
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
authenticate: {
|
||||
jwtToken: "123"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
request: {
|
||||
query: loginMutation,
|
||||
variables: {
|
||||
email: "test@email.com",
|
||||
password: "wrong-password",
|
||||
}
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
authenticate: {
|
||||
jwtToken: null
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
describe('SignIn page', () => {
|
||||
beforeEach(() => mockHistoryReplace.mockReset())
|
||||
|
||||
test('initial state', () => {
|
||||
render(<MockedProvider mocks={mocks}><MemoryRouter><SignIn/></MemoryRouter></MockedProvider>);
|
||||
render(<MockedProvider mocks={loginMock}><MemoryRouter><SignIn/></MemoryRouter></MockedProvider>);
|
||||
|
||||
// it renders empty email and passsword fields
|
||||
const emailField = screen.getByRole('textbox', {name: 'Email Address'});
|
||||
|
@ -68,7 +34,7 @@ describe('SignIn page', () => {
|
|||
});
|
||||
|
||||
test('successful login', async () => {
|
||||
render(<MockedProvider mocks={mocks}><MemoryRouter><SignIn/></MemoryRouter></MockedProvider>);
|
||||
render(<MockedProvider mocks={loginMock}><MemoryRouter><SignIn/></MemoryRouter></MockedProvider>);
|
||||
|
||||
const emailField = screen.getByRole('textbox', {name: 'Email Address'});
|
||||
const passwordField = screen.getByLabelText(/Password/);
|
||||
|
@ -86,7 +52,7 @@ describe('SignIn page', () => {
|
|||
});
|
||||
|
||||
test('error login', async () => {
|
||||
render(<MockedProvider mocks={mocks}><MemoryRouter><SignIn/></MemoryRouter></MockedProvider>);
|
||||
render(<MockedProvider mocks={loginMock}><MemoryRouter><SignIn/></MemoryRouter></MockedProvider>);
|
||||
|
||||
const emailField = screen.getByRole('textbox', {name: 'Email Address'});
|
||||
const passwordField = screen.getByLabelText(/Password/);
|
||||
|
|
Loading…
Reference in a new issue