currently Iam trying to mock a session for website project with cypress, so the tests are not actually accessing database cause Iam using only 0Auth 3th party login (google and github). I already succesfuly mocked a session so main page shows as logged user. However when I click on my profile, it says: No profile (expected behavior when there is no UserInfo data).
This is my cypress code:
Command:
Cypress.Commands.add("login", () => {
cy.intercept("/api/auth/session", { fixture: "session.json" }).as("session");
cy.setCookie("next-auth.session-token", "testcookie");
Cypress.Cookies.preserveOnce("next-auth.session-token");
});
Fixture:
{
"user": {
"name": "test",
"email": "test#test.com",
"slug": "test0000",
"id": "strasnedlouhejstring",
"image": "https://avatars.githubusercontent.com/u/112759319?v=4"
},
"userInfo": {
"bio": "Lorem Testum",
"name": "test",
"email": "test#test.com",
"slug": "test0000",
"id": "strasnedlouhejstring",
"isActive": "true"
},
"expires": "3000-01-01T00:00:00.000Z",
"accessToken": "test"
}
First test (success):
describe("Cypress login", () => {
it("should provide a valid session", () => {
cy.login();
cy.visit("/");
cy.wait("#session");
cy.get("#dropdown > div")
.should("exist")
.then(() => {
cy.log("Cypress login successful");
});
});
});
And finally page rendering:
import ProfilePage from "#components/Layout/ProfilePage";
import { User } from "#prisma/client";
import { getUserInfo } from "#scripts/prisma/getUserInfo";
import { GetServerSideProps } from "next";
import { useSession } from "next-auth/react";
const UserProfile = ({ userInfo }: { userInfo: User | null }) => {
const { data: session } = useSession();
if (userInfo) return <ProfilePage userInfo={userInfo} session={session} />;
return <h1>No profile</h1>;
};
export const getServerSideProps: GetServerSideProps = async (context) => {
const slug = context.query.userProfile?.toString();
if (slug) {
const user = await getUserInfo(slug);
if (user) {
return {
props: { userInfo: JSON.parse(JSON.stringify(user)) },
};
}
}
return {
props: { userInfo: null },
};
};
export default UserProfile;
As I said, the condition is always false so i get the message: No Profile.
I spent 2days figuring this out, however not successfuly.
Related
I am using Vue3 option API and Pinia .
I want to call an action in Pinia option Api from component
component
import { mapActions } from "pinia";
import { useTableStore } from "../../../stores/table";
export default {
name: "LoggingForm",
data() {
return {
login: {
username: "",
password: "",
serverhost: "",
},
};
},
methods: {
submit(){
this.getData(this.login)
}
},
computed: {
...mapActions(useTableStore, ["getData"]),
},
};
and this is store/table.js
import { defineStore } from 'pinia'
import authService from "#/api/auth.js";
export const useTableStore = defineStore({
id: 'table',
state: () => ({
table: []
}),
getters: {
headers: (state) => state.table[0],
body: (state) => state.table.slice(1)
},
actions: {
async getData1(data) {
// do something
}
},
}
})
But I get this error
I can Use state and getters perfectly Just action don't work !
what's the problem ?
Here is what you need
https://pinia.vuejs.org/core-concepts/actions.html#without-setup
In short:
computed => mapGetters
methods => mapActions
You are using mapActions with computed so that will not work
I redirect users to the login page, when they try to access a page without authentication.
I then wanna show them a Message.
But I am not able to pass parameters in the redirect. What causes the issue and how to do it properly?
// PAGE NEEDS AUTH / REDIRECT TO LOGIN WITH MESSAGE
// application
import { GetServerSideProps } from 'next';
import SitePageProducts from '../../components/site/SitePageProducts';
import axios from 'axios';
import { getSession } from 'next-auth/react';
import url from '../../services/url';
import { ProductFields } from '../../lib/ebTypes';
function Page() {
return <SitePageProducts />;
}
export default Page;
export const getServerSideProps: GetServerSideProps = async (context) => {
const session = await getSession(context)
if (session) {
const products = await axios.get(`${process.env.NEXT_PUBLIC_API_URL}/products`, {
}).then(res => {
console.log('res :>> ', res);
return res.data.products as ProductFields[]
}).catch(err => console.log(err));
console.log('products :>> ', products);
return {
props: {
loading: true,
token: session.user.token,
}
}
} else {
return {
redirect: {
permanent: false,
destination: url.accountSignIn().href,
props: { test: "Message from inside Redirect" }
},
props: {
params: { message: "Message from inside props" },
query: {
message: 'Message from inside props query'
},
message: 'Message from inside props root'
},
};
}
}
// LOGIN PAGE, SHOULD CONSUME AND SHOW MESSAGE WHY LOGIN IS NEEDED
import { GetServerSideProps } from 'next';
import AccountPageLogin from '../../components/account/AccountPageLogin';
import url from '../../services/url';
import { getSession } from "next-auth/react"
function Page(props: any) {
return <AccountPageLogin {...props} />;
}
export default Page;
export const getServerSideProps: GetServerSideProps = async (ctx) => {
// ALL CTX queries / props are empty?????
// CURRENT: query:{} --- EXPECTING: query: {message: "MY MESSAGE"}
console.log('ctx accountpagelogin::: :>> ', ctx);
const session = await getSession(ctx)
if (session) {
return {
redirect: {
destination: url.accountDashboard().href,
permanent: false,
},
};
}
return {
props: {},
};
};
I have a Nuxt app in which everything works fine in middleware except when I use redirect.
When I comment the redirect('/admin') line it works fine even the state data is present when console logged. As soon as I uncomment the redirect line it makes the state null.
Please help if someone knows this issue. This exact code works in my other projects but not here.
This is my auth.js file in the middleware folder.
export default function ({ store, route, redirect }) {
const user = store.getters['user/user']
const blockRouteAdmin = /\/admin\/*/g
const blockRouteManager = /\/manager\/*/g
const path = ['/signup', '/login']
let value = path.includes(route.path)
if (user) {
if (user.isAdmin) {
if (!route.path.match(blockRouteAdmin)) {
redirect('/admin')
}
}
if (user.isManager) {
if (!route.path.match(blockRouteManager)) {
redirect('/manager')
}
}
if (user.isUser) {
if (
route.path.match(blockRouteAdmin) ||
route.path.match(blockRouteManager) ||
value
) {
console.log('isUser', user.isUser)
redirect('/')
}
}
}
if (!user) {
if (
route.path.match(blockRouteAdmin) ||
route.path.match(blockRouteManager)
) {
redirect('/')
} else {
redirect()
}
}
}
Here is my nuxt.config.js
export default {
// Target: https://go.nuxtjs.dev/config-target
target: 'static',
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'aitl',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: ['~/plugins/firebaseConfig.js'],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/buefy
'nuxt-buefy',
// https://go.nuxtjs.dev/pwa
'#nuxtjs/pwa',
// https://go.nuxtjs.dev/content
'#nuxt/content',
],
// PWA module configuration: https://go.nuxtjs.dev/pwa
pwa: {
manifest: {
lang: 'en',
},
},
// Content module configuration: https://go.nuxtjs.dev/config-content
content: {},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
}
My index.js inside store.
import { vuexfireMutations } from 'vuexfire'
import { getUserFromCookie } from '../helper/index.js'
export const mutations = {
...vuexfireMutations,
}
export const actions = {
async nuxtServerInit({ dispatch, commit }, { req }) {
try {
const user = getUserFromCookie(req)
if (user) {
await dispatch('user/setUSER', {
email: user.email,
isAdmin: user.admin,
isManager: user.manager,
isUser: user.user,
uid: user.user_id,
name: user.name,
})
}
} catch (err) {
console.log(err)
}
},
}
User.js in store folder
import { auth } from '../plugins/firebaseConfig'
import Cookies from 'js-cookie'
export const state = () => ({
user: null,
})
export const getters = {
user(state) {
return state.user
},
}
export const actions = {
async userlogin({ dispatch }, user) {
try {
const token = await auth.currentUser.getIdToken(true)
const userInfo = {
email: user.email,
isAdmin: user.admin,
isManager: user.manager,
isUser: user.user,
uid: user.uid,
name: user.displayName,
}
Cookies.set('access_token', token)
await dispatch('setUSER', userInfo)
} catch (err) {
console.log(err)
}
},
setUSER({ commit }, user) {
commit('setUSER', user)
},
}
export const mutations = {
setUSER(state, user) {
state.user = user
},
}
The issue was solved by going from target: 'static' to target: 'server', aka mirroring the settings of another working project.
I have a component that passes a string (userToFetch) it as a variable parameter in a parameterized query. The component looks like this:
// pages/index.jsx
import React from 'react';
import { useQuery } from '#apollo/react-hooks';
import gql from 'graphql-tag';
const GET_USERS = gql`
query users ($limit: Int!, $username: String!) {
users (limit: $limit, where: { username: $username }) {
username
firstName
}
}
`;
const Home = () => {
const userToFetch = 'jonsnow';
const {
loading,
error,
data,
} = useQuery(
GET_USERS,
{
variables: { limit: 2, username: userToFetch },
notifyOnNetworkStatusChange: true,
},
);
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error: {JSON.stringify(error)}</p>;
}
return (
<div>
<ul>
{data.users.map(user => {
return <li>{user.username} {user.firstName}</li>;
})}
</ul>
</div>
);
};
export default Home;
And this is how I have configured my Apollo client:
// /apollo-client.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import withApollo from 'next-with-apollo';
import { createHttpLink } from 'apollo-link-http';
import fetch from 'isomorphic-unfetch';
const GRAPHQL_URL = 'https://dev.schandillia.com/graphql';
const link = createHttpLink({
fetch, // Switches between unfetch & node-fetch for client & server.
uri: GRAPHQL_URL
});
// Export a HOC from next-with-apollo
// Docs: https://www.npmjs.com/package/next-with-apollo
export default withApollo(
// You can get headers and ctx (context) from the callback params
// e.g. ({ headers, ctx, initialState })
({ initialState, ctx }) => {
console.log('initialState', initialState);
console.log('ctx', ctx);
return new ApolloClient({
link: link,
cache: new InMemoryCache()
// rehydrate the cache using the initial data passed from the server:
.restore(initialState || {})
})
}
);
The database is a collection of following users:
"users": [
{
"username": "negger",
"firstName": "Arnold",
"lastName": "Schwarzenegger"
},
{
"username": "jonsnow",
"firstName": "Jon",
"lastName": "Snow"
},
{
"username": "tonystark",
"firstName": "Tony",
"lastName": "Stark"
}
]
}
Now, although this should work (it does when I run the query in my graphql playground at https://dev.schandillia.com/graphql), the code runs as if the where clause didn't exist! It just returns all results as if the query being run were:
users {
_id
username
firstName
}
In order to reproduce the issue, visit https://www.schandillia.com. The page ought to display a list with only one element consisting of a matching username-firstName value: jonsnow Jon but it returns two entries, negger Arnold and jonsnow Jon (respecing limit but completely ignoring where). Now, run the same query with jonsnow as a where parameter in https://dev.schandillia.com/graphql:
{
users(where: { username: "jonsnow" }) {
_id
username
firstName
}
}
And the results would be exactly as expected:
{
"data": {
"users": [
{
"_id": "5d9f261678a32159e61018fc",
"username": "jonsnow",
"firstName": "Jon",
}
]
}
}
What am I overlooking?
P.S.: The repo is up for reference at https://github.com/amitschandillia/proost/tree/master/apollo-nextjs.
UPDATE: In order to track down the root cause, I tried logging some values in apollo-client.js:
console.log('initialState', initialState);
Strangely, the output shows the right query, along with the variables being passed, but wrong results:
...
ROOT_QUERY.users({"limit":2,"where":{"username":"jonsnow"}}).0:
firstName: "Arnold"
username: "negger"
__typename: "UsersPermissionsUser"
...
UPDATE: Here's a screenshot of results in my Apollo Client Developer Tools:
The schema generated by Strapi gives the where attribute a Type JSON and hence you have to pass the entire where part in the query variable as JSON since the variables are not getting injected.
# Write your query or mutation here
query users($where: JSON) {
users(where: $where) {
username
firstName
}
}
And the variables would look like:
{"where": {"username": "jonsnow"}}
I'm new to react-native and when I trying to get data from RESR api and it nicely work for github api, I used following example for developing
https://blog.cloudboost.io/getting-started-with-react-native-and-redux-6cd4addeb29
And I change this for get from another from REST api it shows that following error
HTTP Failure in Axios [Error: Network Error]
Object {
"error": Object {
"data": "Network Error",
"status": 0,
},
"meta": Object {
"previousAction": Object {
"payload": Object {
"request": Object {
"url": "/XXXX/list",
},
},
"type": "my-awesome-app/repos/LOAD",
},
},
"type": "my-awesome-app/repos/LOAD_FAIL",
}
Do you guys have any idea
There seems to be a problem with the url config that you're trying to use in the tutorial that you've mentioned.
I'm using this api from the docs https://dog.ceo/api/breed/hound/images
As per the tutorial and the comments that you've mentioned here are the relevant changes for the api and the reducers
App.js
// Changing the URL here
const client = axios.create({
baseURL: 'https://dog.ceo/',
responseType: 'json'
});
HoundsList.js
class HoundsList extends Component {
componentDidMount() {
this.props.listHounds('hound');
}
renderItem = ({ item }) => (
<View style={styles.item}>
<Text>{item}</Text>
</View>
);
render() {
const { hounds } = this.props;
return (
<FlatList
styles={styles.container}
data={hounds}
renderItem={this.renderItem}
/>
);
}
}
const mapStateToProps = state => {
return {
hounds: state.hounds.message
};
};
const mapDispatchToProps = {
listHounds
};
export default connect(mapStateToProps, mapDispatchToProps)(HoundsList);
reducer.js
export const GET_HOUNDS = 'my-awesome-app/hounds/LOAD';
export const GET_HOUNDS_SUCCESS = 'my-awesome-app/hounds/LOAD_SUCCESS';
export const GET_HOUNDS_FAIL = 'my-awesome-app/hounds/LOAD_FAIL';
export default function reducer(state = { hounds: [] }, action) {
switch (action.type) {
case GET_HOUNDS:
console.log('Loading')
return { ...state, loading: true };
case GET_HOUNDS_SUCCESS:
console.log('Success')
return { ...state, loading: false, hounds: action.payload.data };
case GET_HOUNDS_FAIL:
console.log('failure')
return {
...state,
loading: false,
error: 'Error while fetching hounds list'
};
default:
return state;
}
}
export function listHounds(breed_name) {
return {
type: GET_HOUNDS,
payload: {
request: {
url: `/api/breed/${breed_name}/images`
}
}
};
}