Nestjs Optional DTO during the Unit test - testing

I have a simple controller:
#Patch('/:userId')
public async updateUser(
#Param('userId') userId: string,
#Body() userUpdate: UpdateUserDto): Promise<any> {
await this.usersService.update(userId, userUpdate);
}
The UpdateUserDto is:
import { IsEmail,IsString, IsOptional, MaxLength, IsNotEmpty} from "class-validator";
export class UpdateUserDto{
#IsEmail()
#IsOptional()
email:string;
#IsString()
#IsOptional()
password:string;
#IsString()
#MaxLength(30)
#IsNotEmpty()
#IsOptional()
name: string;
#IsString()
#MaxLength(40)
#IsNotEmpty()
#IsOptional()
username: string;
}
all fields are optional to create partial updates.
I don't have any error in my unit test if I use all fields
it('test', async () => {
const users = await controller.updateUser('10',{name: "testname",username:"fakeUser",email:"email",password:"S"});
});
but I get an error if I use part of it, like:
it('test', async () => {
const users = await controller.updateUser('10',{name: "testname",email:"email",password:"S"});
Argument of type '{ name: string; email: string; password: string; }'
is not assignable to parameter of type 'UpdateUserDto'.
Property 'username' is missing in type '{ name: string; email: string; password: string; }' but required in type 'UpdateUserDto'.
});

if password is optional (ie., can be undefined), then tell to TS it is: password?: string

Related

Create a document in beforeEach on Jest nest.js

I'm Using the in memory mongoose database for create my Unit test, and I want to create a document before the tests.
My interface is:
export interface IUsers {
readonly name: string;
readonly username: string;
readonly email: string;
readonly password: string;
}
and my beforeEach is:
import { MongooseModule } from "#nestjs/mongoose";
import { Test, TestingModule } from "#nestjs/testing";
import { closeInMongodConnection, rootMongooseTestModule } from '../test-utils/mongo/MongooseTestModule';
import { User, UserSchema } from "./schemas/users.schema";
import { UsersService } from "./users.service";
describe("UsersService", () => {
let service: UsersService;
let testingModule: TestingModule;
let userModel: Model<User>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
rootMongooseTestModule(),
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
],
providers: [UsersService],
}).compile();
service = module.get<UsersService>(UsersService);
//create user
userModel = testingModule.get<Model<User>>(
'UserModel',
);
});
I get an error TypeError: Cannot read pro perties of undefined (reading 'get') during the test. I tried to use let userModel: Model<IUsers>; But I get the same error.
Use either testingModule or module.
You declared testingModule but never initialized.
let testingModule: TestingModule; This part is undefined unless something is assigned to it.
Try like this
describe('UsersService', () => {
let testingModule: TestingModule;
let userModel: Model<User>;
let userService: UserService;
beforeEach(async () => {
testingModule = await Test.createTestingModule({
imports: [
rootMongooseTestModule,
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
providers: [UsersService],
}).compile();
userService = testingModule.get<UsersService>(UsersService);
userModel = testingModule.get<Model<User>>('UserModel');
// await userModel.create(...) or whatever methods you have
});
});

Vue-Apollo V4 composition API #vue/apollo-composable on loginform. TS2349: This expression is not callable. Type 'Ref<any>' has no call signatures

I am a new one in the apollo world. I use Vue composition API and #vue/apollo-composable with version V4 for my vue apollo client. And the backend is nodejs server with apollo server.
Now I have a problem on the login page with useQuery, if I call the result of the query, they will be show the error
TS2349: This expression is not callable. Type 'Ref' has no call signatures
import { ref, defineComponent } from '#vue/composition-api'
import gql from 'graphql-tag'
import { useUserLogin } from '#/mixins/user-login'
import { CustomRules } from '#/validators/rules'
import { useQuery, useMutation } from '#vue/apollo-composable'
export default defineComponent({
props: {
msg: String,
},
setup(props, { root }) {
const form = ref()
const rules = ref(CustomRules)
const username = ref('')
const password = ref('')
const errorMessage = ref('')
const { result: loginBenutzer } = useQuery(gql`
query loginBenutzer($kuerzel: String!, $passwort: String!) {
loginBenutzer(kuerzel: $kuerzel, passwort: $passwort) {
user {
kuerzel: BEN_MIA_KUERZEL,
name: BEN_NAME
},
token
}
}
`)
function login() {
if (form.value.validate()) {
loginBenutzer({ kuerzel: username.value, passwort: password.value })
.then(data => {
useUserLogin(data.data.loginBenutzer)
root.$router.push('/hm')
})
.catch(err => {
errorMessage.value = err.message
console.log(err)
})
}
}
return {
form,
rules,
username,
password,
login,
errorMessage,
}
},
})
Calling to result: loginBenutzer of this line
loginBenutzer({ kuerzel: username.value, passwort: password.value })
the loginBenutzer shows the error:
TS2349: This expression is not callable. Type 'Ref' has no call signatures
And in the Apollo server type is defined like this
type Query {
loginBenutzer(kuerzel: String!, passwort: String!): LoginResponse!,
}
but if I change the query to mutation, then they are working. Like this
const { mutate: loginBenutzer } = useMutation(gql`
mutation loginBenutzer($kuerzel: String!, $passwort: String!) {
loginBenutzer(kuerzel: $kuerzel, passwort: $passwort) {
user {
kuerzel: BEN_MIA_KUERZEL,
name: BEN_NAME
},
token
}
}
`)
function login() {
if (form.value.validate()) {
loginBenutzer({ kuerzel: username.value, passwort: password.value })
.then(data => {
useUserLogin(data.data.loginBenutzer)
root.$router.push('/hm')
})
.catch(err => {
errorMessage.value = err.message
console.log(err)
})
}
}
and the type like this
type Mutation {
loginBenutzer(kuerzel: String!, passwort: String!): LoginResponse!,
}
but I am very sure, the useQuery for the calling of user information is a right way.
result: result data object.
As documentation said,result return result data object, which will be a Ref type,
refetch(variables?): Execute the query again, optionally with new
variables.
Try refetch instead if you want to pass new variables

Undefined args on a mutation, using apollo-server

Im working with apollo-server, everything works as expetected but the mutation arguments are undefined when the mutation is called from the frontend.
const express = require('express');
const morgan = require('morgan');
const { ApolloServer, gql } = require('apollo-server-express');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
const typeDefs = gql`
type msgFields {
email: String!
textarea: String!
createdAt: String!
}
input MsgFieldsInput {
email: String!
textarea: String!
createdAt: String!
}
type Query {
formContact: msgFields!
}
type Mutation {
createMsg(email: String!, textarea: String!, createdAt: String!): String!
}
`;
const resolvers = {
Query: {
formContact: () => {
return {
email: 'test#mail.com',
textarea: 'checking Checking checking Checking checking Checking'
}
}
},
Mutation: {
createMsg: (args) => {
console.log(args); // => undefined here
return 'Worked';
}
}
}
const server = new ApolloServer({
typeDefs,
resolvers
});
app.use(morgan('dev'));
server.applyMiddleware({app})
mongoose.connect(process.env.MONGO_URL, { useNewUrlParser: true })
.then(() => {
app.listen({port: 4000}, () => {
console.log(`Server and DB ready at http://localhost:4000${server.graphqlPath}`)
});
})
.catch(err => {
throw err;
})
This is what i send from /graphql
mutation {
createMsg(email: "test#mail.com" textarea: "testing textarea" createdAt: "19-05-2018")
}
The resolver signature is as follows: (parent, args, context, info) where:
parent: The object that contains the result returned from the resolver on the parent field, or, in the case of a top-level Query field, the rootValue passed from the server configuration. This argument enables the nested nature of GraphQL queries.
args: An object with the arguments passed into the field in the query. For example, if the field was called with query{ key(arg: "you meant") }, the args object would be: { "arg": "you meant" }.
context: This is an object shared by all resolvers in a particular query, and is used to contain per-request state, including authentication information, dataloader instances, and anything else that should be taken into account when resolving the query. Read this section for an explanation of when and how to use context.
info: This argument contains information about the execution state of the query, including the field name, path to the field from the root, and more. It's only documented in the GraphQL.js source code, but is extended with additional functionality by other modules, like apollo-cache-control.
The arguments are passed to the resolver as the second parameter, not the first. See the docs for additional details.

Trouble Rendering Mongoose find() to EJS

I'm trying to load and display several work entries from my MongoDB database using mongoose and Express and I'm running into trouble.
When I try to pass the results to my .ejs file, I get the error that the variable is not defined.
For some reason, it works when I pass individual objects to the .ejs file.
Here's what is working, but isn't useful
router.get('loadEntries', (req,res) => {
Entry.find({}, function(err, data) {
data.forEach(function(item) {
res.render('loadEntries',{firstName:item.firstName});
}
});
});
//ejs file. Very basic, just to capture the data
<p>
<%=firstName%>
</p>
Here's what I would like to do, but isn't working
router.get('loadEntries', (req,res) => {
Entry.find({}, function(err, data) {
res.render('loadEntries',{result:data});
});
});
//ejs file
<p>
<%result.forEach(function(item) { %>
First name: <%=item.firstName%>
Last name: <%=item.lastName%>
<%})%>
</p>
My mongoose model
const mongoose = require('mongoose');
const EntrySchema = new mongoose.Schema({
//hours, room, buliding, note
hours: {
type: Number,
required: true
},
room: {
type: String,
required: true
},
building: {
type: String,
required: true
},
note: {
type: String,
required: false
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
}
});
const Entry = mongoose.model('Entry', EntrySchema);
module.exports = Entry;

Type 'Observable<boolean>' is not assignable to type error. works in Ang 5 not in v6

Upgrading a sample project from Angular 5 to 6.
https://github.com/mmacneil/AngularASPNETCore2WebApiAuth
The error happens on the return statement.
Type 'Observable<boolean>' is not assignable to type 'Observable<UserRegistration>'.
register Function
register(email: string, password: string, firstName: string, lastName: string, location: string, gender: string, birthDate: any): Observable<UserRegistration> {
let body = JSON.stringify({ email, password, firstName, lastName, location, gender, birthDate });
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.baseUrl + "/accounts", body, options)
.pipe(
map(res => true),
catchError(this.handleError)
);
}
UserRegistration
export interface UserRegistration {
email: string;
password: string;
firstName: string;
lastName: string;
location: string;
birthDate: any;
gender: string;
}
Could it be some new import I'm missing.??
Showing the Imports.
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { HttpClientModule } from '#angular/common/http';
import { UserRegistration } from '../models/user.registration.interface';
import { ConfigService } from '../utils/config.service';
import { BaseService } from "./base.service";
import { Observable } from 'rxjs/Rx';
import { BehaviorSubject } from 'rxjs/Rx';
import { map, filter, catchError, mergeMap } from 'rxjs/operators';
// Add the RxJS Observable operators we need in this app.
import '../../rxjs-operators';
#Injectable()