I am trying to use createRemoteFileNode to create optimised images for an array of nodes that exist on a Product.
I have a Product that has items and on each item, it has a featuredImg. I can create a featuredImg for a Product but as soon as I try to create it for the child nodes (items) then it is not queryable.
I am creating my nodes as such:
const products = [
{
id: "product_1",
imageUrl: "https://images.unsplash.com/photo-1665081661649-8656335a6cbb?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1738&q=80",
items: [
{
id: 'item_1',
imageUrl: "https://images.unsplash.com/photo-1666120565124-7e763880444a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1770&q=80"
}
]
}
]
const sourceNodes = async ({ actions, createNodeId, createContentDigest }, options) => {
products.forEach((testNode) => {
const node = {
...testNode,
id: createNodeId(`Product-${testNode.id}`),
}
actions.createNode({
...node,
internal: {
type: 'Product',
contentDigest: createContentDigest(node),
},
});
testNode.items.forEach(item => {
const itemNode = {
...item,
id: createNodeId(`Item-${item.id}`),
}
actions.createNode({
...itemNode,
parent: node.id,
internal: {
type: 'Item',
contentDigest: createContentDigest(itemNode),
},
});
})
})
};
module.exports = sourceNodes;
Then on the node creation, I am running the onCreateNode function which should create the remote file node for each item featuredImg.
const { createRemoteFileNode } = require(`gatsby-source-filesystem`);
const onCreateNode = async ({ node, cache, store, getCache, actions: { createNode, createNodeField }, createNodeId }) => {
if( node.internal.type === 'Item') {
const fileNode = await createRemoteFileNode({
url: node.imageUrl,
parentNodeId: node.parent,
createNode,
createNodeId,
getCache,
})
if (fileNode) {
createNodeField({ node, name: "localFile", value: fileNode.id })
}
}
if( node.internal.type === 'Product') {
const fileNode = await createRemoteFileNode({
url: node.imageUrl,
parentNodeId: node.id,
createNode,
createNodeId,
getCache,
})
if (fileNode) {
createNodeField({ node, name: "localFile", value: fileNode.id })
}
}
};
module.exports = onCreateNode
I have defined my types here:
module.exports = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
type Product implements Node {
id: String!
imageUrl: String!
featuredImg: File #link(from: "fields.localFile")
items: [Item]
}
type Item implements Node {
id: String!
imageUrl: String!
featuredImg: File #link(from: "fields.localFile")
}
`;
createTypes(typeDefs);
};
For some reason, when I query Products.items[i].featuredImg it always returns null. However, I can see the node is generated because I can query item.featuredImg and it returns the gatsbyImageData.
I have created a simple example here and included a read me on how to replicate it: https://github.com/stretch0/gatsby-sandbox
I have also noticed that this post is a similar issue of not being able to create remote file nodes within a loop but because they have a different file structure, I can't figure out how their solution to use createSchemaCustomization or createResolvers would apply to my setup.
Using this node-ews package, I can send email, but I haven't been able to find a good example of how to read mails from the Inbox folder and get the email's text and attachments.
I've read the Microsoft documentation, such as this one: https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-work-with-exchange-mailbox-items-by-using-ews-in-exchange#get-an-item-by-using-the-ews-managed-api, but the examples are in C#, C++, or VB.
However, I would like to use Nodejs for this.
**I have found a best way extract every content using mailparser. see bellow
// At first Read emails from Inbox
const EWS = require('node-ews');
const simpleParser = require('mailparser').simpleParser;
// exchange server connection info
const ewsConfig = {
username: 'username',
password: 'password',
host: 'hostname'
};
const options = {
rejectUnauthorized: false,
strictSSL: false
};
// initialize node-ews
const ews = new EWS(ewsConfig, options);
var ewsFunction = 'FindItem';
var ewsArgs = {
'attributes': {
'Traversal': 'Shallow'
},
'ItemShape': {
't:BaseShape': 'Default'
},
'ParentFolderIds' : {
'DistinguishedFolderId': {
'attributes': {
'Id': 'inbox'
}
}
}
};
// Itreate over all the emails and store Id and ChangeKey.
ews.run(ewsFunction, ewsArgs, ewsSoapHeader)
.then(result => {
// Iterate over the result and extract Id and ChangeKey of the messages and pass those to GetItem function to read messages
})
// For reading individual messages returned by FindItem (using Id and ChangeKey)
var ewsFunction = 'GetItem';
var ewsArgs = {
'ItemShape': {
'BaseShape': 'Default',
'AdditionalProperties': {
'FieldURI': [
{ 'attributes': { 'FieldURI': 'item:MimeContent'}}
]
}
},
'ItemIds': {
'ItemId': {
'attributes': {
'Id': Id,
'ChangeKey': ChangeKey
}
}
}
};
await ews.run(ewsFunction, ewsArgs, ewsSoapHeader)
.then(result => {
// Iterate over the result and extract meesage
const {Message} = result.ResponseMessages.GetItemResponseMessage.Items
let mimeContent = Buffer.from(Message.MimeContent['$value'], 'base64').toString('binary');// decode mime content
simpleParser(mimeContent).then(async function (mail) {
console.log("mail")
console.log(mail.attachments)
console.log(mail.headers.get('message-id'))
console.log(mail.headers.get('references'))
console.log(mail.headers.get('in-reply-to'))
console.log({
// text: mail.text,
// html: mail.html ? mail.html.replace(/<meta([^>]+)>/g, "") : "",
from: (mail.from) ? mail.from.value.map(item => item.address) : [],
to: (mail.to) ? mail.to.value.map(item => item.address) : [],
cc: (mail.cc) ? mail.cc.value.map(item => item.address) : [],
bcc: (mail.bcc) ? mail.bcc.value.map(item => item.address) : [],
messageId: mail.messageId,
subject: mail.subject
})
}).catch((err) => {
console.log("err")
console.log(err)
})
})
Here you will get the full parsed mail contents with attachments. Happy Coding!!!
I`m creating a bookstore and I have 3 models: Book, Author and Genre.
Books stores an array of authors ids and the array of genres ids. Author stores the array of books ids. Genre too has the array of books ids.
BookSchema = new mongoose.Schema({
title: String,
authors: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Author"
}
],
image: String,
description: String,
price: Number,
genres: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Genre"
}
],
});
AuthorSchema = new mongoose.Schema({
name: String,
books: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Book"
}
],
});
GenreSchema = new mongoose.Schema({
name: String,
books: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Book"
}
],
});
Then I have a data array that stores information about the book we need to create like this
{
title: "The Monster at the End of This Book",
authors: ["Jon Stone"],
img: "https://images-na.jpg",
price: "0.35",
description: "Carve out family time for ...",
genres: ["Children's Humour (Books)"]
},
I`m trying to add authors, genres and books. After that I want to associate authors with books
Book.deleteMany({}, () => {
insertBooks().then(insertGenres).then(insertAuthors).then(connectBooksToAuthors);
}).then(function () {
connectBooksToGenres();
})
async function insertAuthors() {
let authorsArr = [];
data.forEach(dataPiece => {
dataPiece.authors.forEach(author => {
if (authorsArr.indexOf(author) === -1) {
authorsArr.push(author)
}
})
})
authorsArr.forEach(author => {
Author.findOne({name: author}, (err, a) => {
if (!a) {
Author.create({name: author});
}
})
})
}
async function insertGenres() {
let genresArr = [];
data.forEach(dataPiece => {
dataPiece.genres.forEach(genre => {
if (genresArr.indexOf(genre) === -1) {
genresArr.push(genre);
}
})
})
genresArr.forEach(genre => {
Genre.findOne({name: genre}, (err, g) => {
if (!g) {
Genre.create({name: genre});
}
})
})
}
async function insertBooks() {
data.forEach((dataPiece) => {
let obj = {
"title": `${dataPiece.title}`,
'description': `${dataPiece.description}`,
"price": `${dataPiece.price}`,
};
Book.create(obj);
})
}
async function connectBooksToAuthors() {
data.forEach(dataPiece => {
Book.findOne({"title": `${dataPiece.title}`}, (err, book) => {
let authorsArr = [];
dataPiece.authors.forEach(authorsName => {
Author.findOne({name: authorsName}, (err, author) => {
author.books.push(book);
author.save();
authorsArr.push(author);
if (authorsArr.length === dataPiece.authors.length) {
book.authors = [...authorsArr];
book.save();
}
});
});
})
})
}
async function connectBooksToGenres() {
data.forEach(dataPiece => {
Book.findOne({"title": `${dataPiece.title}`}, (err, book) => {
let genresArr = [];
dataPiece.genres.forEach(genreName => {
Genre.findOne({name: genreName}, (err, genre) => {
genre.books.push(book);
genre.save();
genresArr.push(genre);
if (genresArr.length === dataPiece.genres.length) {
book.genres = [...genresArr];
book.save();
}
});
});
})
})
}
When I run the code I get this exception:
(node:29028) UnhandledPromiseRejectionWarning: VersionError: No matching document found for id "5fa1dbbb969d727164f1f59e" version 0 modifiedPaths "genres"
at generateVersionError (C:\Users\sasha\Desktop\Bookstore\node_modules\mongoose\lib\model.js:421:10)
at model.Model.save (C:\Users\sasha\Desktop\Bookstore\node_modules\mongoose\lib\model.js:478:28)
at C:\Users\sasha\Desktop\Bookstore\seed.js:234:34
at C:\Users\sasha\Desktop\Bookstore\node_modules\mongoose\lib\model.js:4844:16
at C:\Users\sasha\Desktop\Bookstore\node_modules\mongoose\lib\model.js:4844:16
at C:\Users\sasha\Desktop\Bookstore\node_modules\mongoose\lib\helpers\promiseOrCallback.js:24:16
at C:\Users\sasha\Desktop\Bookstore\node_modules\mongoose\lib\model.js:4867:21
at C:\Users\sasha\Desktop\Bookstore\node_modules\mongoose\lib\query.js:4420:11
at C:\Users\sasha\Desktop\Bookstore\node_modules\kareem\index.js:135:16
at processTicksAndRejections (internal/process/task_queues.js:79:11)
at runNextTicks (internal/process/task_queues.js:66:3)
at processImmediate (internal/timers.js:434:9)
In the database books arrays with authors are filed. Ganres arrays are not The problem might be in book.save() calls from connectBooksToAuthors and connectBooksToGenres but I dont really know how to fix it
I'm attempting to check if a user's ID is in this array and if they are, also get the "text" from it.
Array:
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
I've tried if (staff.user.includes(msg.member.id)) (Which I didn't think was going to work, and didn't.)
const findUser = (users, id) => users.find(user => user.id === id)
const usersExample = [
{
id: '123456765',
text: 'sdfsdfsdsd'
},
{
id: '654345676',
text: 'fdgdgdg'
}
]
//////////////////
const user = findUser(usersExample, '123456765')
console.log(user && user.text)
The some method on an array is used to tell if an item meets a condition, it is similar to the find method but the find method returns the item where the some method return true or false.
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
const isStaff = (staff, id) => staff.some(s => s.user === id);
console.log(isStaff(staff, '123'));
console.log(isStaff(staff, '245569534218469376'));
You may try something like this:
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
let item = staff.find(item => item.user == '294597887919128576'); // msg.member.id
if (item) {
console.log(item.text);
}
One another way to do that is:
const inArray = (array, id) => array.filter(item => item.user === id).length >= 1;
const users = [
{
user: '245569534218469356',
text: 'foo'
}, {
user: '245564734218469376',
text: 'bar'
}, {
user: '246869534218469376',
text: 'baz'
}
];
console.log(inArray(users, '246869534218469376')); // true
console.log(inArray(users, '222479534218469376')); // false
I have an angular application and I need to do some unit testing on some methods with Jasmine. IN this case I do a unit test on a select list. So that the select list will not be empty.
The method looks like this:
createStatusOptions(listValueoptions: OptionModel[], resources: any): OptionModel[] {
const processStatusOptions = listValueoptions.map(listValueOption => {
listValueOption.value = `${caseStatusEnum.inProgress}_${listValueOption.value}`;
listValueOption.selected = true;
return listValueOption;
});
const caseStatusEnumKeys = Object.keys(caseStatusEnum).filter(key => !isNaN(Number(key)));
const enumOptions = this.optionService.createOptions(
new ConfigOptionModel({ source: caseStatusEnumKeys, resources, resourcesModel: enumResourcesModel, isCustomEnum: true, }));
return [
this.getEnumOption(enumOptions, caseStatusEnum.submitted, true),
...processStatusOptions,
this.getEnumOption(enumOptions, caseStatusEnum.closed),
];
}
private getEnumOption(options: OptionModel[], enumType, isSelected = false): OptionModel {
const option = options.filter(enumOption => enumOption.value === `${enumType}`)[0];
option.selected = isSelected;
return option;
}
And I have the unit test like this:
it('should create status options when there ar list value options are provided', () => {
optionService.options = [
{
value: caseStatusEnum.submitted.toString(),
},
{
value: caseStatusEnum.inProgress.toString(),
},
{
value: caseStatusEnum.closed.toString(),
},
] as OptionModel[];
// tslint:disable-next-line:max-line-length
const result = service.createStatusOptions(optionService.options, [[103], [104], [105] ]);
console.log(result);
expect(result.length).toBe(2);
expect(result).toEqual([{ value: '103', selected: true }, { value: '105', selected: false }]);
});
But I get an error like this:
Services: CaseService > should create status options when there ar list value options are provided
TypeError: Cannot set property 'selected' of undefined
at <Jasmine>
at CaseService.getEnumOption (http://localhost:9878/src/app/case/src/services/case.service.ts?:130:9)
at CaseService.getEnumOption [as createStatusOptions] (http://localhost:9878/src/app/case/src/services/case.service.ts?:109:22)
at UserContext.<anonymous> (http://localhost:9878/src/app/case/src/services/case.service.spec.ts?:149:32)
at ZoneDelegate.../../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/zone.js?:388:1)
at ProxyZoneSpec.push.../../node_modules/zone.js/dist/proxy.js.ProxyZoneSpec.onInvoke (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/proxy.js?:128:1)
at ZoneDelegate.../../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/zone.js?:387:1)
at Zone.../../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/zone.js?:138:1)
at runInTestZone (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/jasmine-patch.js?:145:1)
at UserContext.<anonymous> (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/jasmine-patch.js?:160:1)
at <Jasmine>
So my question is: How to solve this?
Thank you
if I do this:
console.log(optionService.options);
I get this output:
Array(3)
0: {value: "103", selected: true}
1: {value: "104"}
2: {value: "105", selected: false}
length: 3
__proto__: Array(0)
this is the file:
import { fakeAsync, tick } from '#angular/core/testing';
import { FormServiceMock, MultiFileUploadServiceMock } from 'afw/forms/testing';
import { AfwHttp } from 'afw/generic-services';
import { AfwHttpMock, OptionServiceMock } from 'afw/generic-services/testing';
import { OptionModel, SearchResultModel } from 'afw/models';
import { FeedbackStoreServiceMock } from 'afw/store-services/testing';
import { RouterMock } from 'afw/testing';
import { PagingDataModel, TableSortDataModel } from 'afw/ui-components';
import { caseOwnerEnum, caseStatusEnum, caseTypeEnum, MultiFileUploadResourcesModel } from 'lr/models';
import { Observable, observable } from 'rxjs';
import { CaseTypeInfoModel } from 'support-shared/base/models';
import { CaseTypeInfoStoreServiceMock } from 'support-shared/base/services/case-type-info-store.service.mock';
import { CaseFormComponent } from '../case-base/src/case-form/case-form.component';
import { CaseBaseModel, CaseReferenceModel } from '../models';
import { CaseService } from './case.service';
let service: CaseService;
let afwHttpMock: AfwHttpMock;
// tslint:disable-next-line:prefer-const
let formServiceMock: FormServiceMock;
let multiFileUploadService: MultiFileUploadServiceMock;
let router: RouterMock;
let feedbackStoreService: FeedbackStoreServiceMock;
let optionService: OptionServiceMock;
let caseTypeInfoStoreService: CaseTypeInfoStoreServiceMock;
// tslint:disable-next-line:prefer-const
let component: CaseFormComponent;
fdescribe('Services: CaseService', () => {
beforeEach(() => {
afwHttpMock = new AfwHttpMock();
multiFileUploadService = new MultiFileUploadServiceMock();
router = new RouterMock();
feedbackStoreService = new FeedbackStoreServiceMock();
optionService = new OptionServiceMock();
caseTypeInfoStoreService = new CaseTypeInfoStoreServiceMock();
service = new CaseService(afwHttpMock as any, multiFileUploadService as any, router as any,
feedbackStoreService as any, optionService as any, caseTypeInfoStoreService as any);
});
it('should create an instance', () => {
expect(service).toBeTruthy();
});
it('should get case reference details', () => {
afwHttpMock.setupOnlyResponse({ type: caseTypeEnum.revisionRequest, details: { bsn: 'bsnLabel' } }, 200);
const d = service.getCaseReferenceDetails('spinnerMessage', { reference: '112314121', type: caseTypeEnum.revisionRequest });
d.subscribe(r => {
expect(r.details.length === 1);
expect(r.details[0].key).toBe('bsn');
expect(r.details[0].value).toBe('bsnLabel');
expect((r.details[0] as any).resourceKey).toBe('bsn');
});
afwHttpMock.returnSuccessResponse();
});
// tslint:disable-next-line:no-identical-functions
it('should get case reference details with full response', () => {
afwHttpMock.setupOnlyResponse({ body: { type: caseTypeEnum.revisionRequest, details: [{ key: 'hoi' }] } }, 200);
const d = service.getCaseReferenceDetailsFullResponse('spinnerMessage', { reference: '100001075', type: caseTypeEnum.revisionRequest });
// tslint:disable-next-line:no-commented-code
// tslint:disable-next-line:no-identical-functions
/* let result;
d.subscribe(r => {
result = r;
}); */
d.subscribe(r => {
expect(r.ok === true);
expect(r.body.details[0].key).toBe('hoi');
});
afwHttpMock.returnSuccessResponse();
// expect(result.ok === true);
// expect(result.)
});
// tslint:disable-next-line:no-commented-code
it('shoud get case type info configuration that is used on various views when snapshot exists', () => {
let result99: Observable<CaseTypeInfoModel[]>;
result99 = service.getCaseTypeInfo('spinner') as Observable<CaseTypeInfoModel[]>;
const response = [{ mock: 'mock' } as any];
service['caseTypeInfoSnapshot'] = response;
service.getCaseTypeInfo('spinner').subscribe(i => {
expect(i).toEqual(response);
});
});
// tslint:disable-next-line:no-identical-functions
it('shoud get case type info configuration that is used on various views when snapshot doesnt exists', () => {
let result99: Observable<CaseTypeInfoModel[]>;
const spy = spyOn(caseTypeInfoStoreService, 'addCaseTypeInfoToStore');
result99 = service.getCaseTypeInfo('spinner') as Observable<CaseTypeInfoModel[]>;
const response = [{ mock: 'mock' } as any];
service['caseTypeInfoSnapshot'] = response;
// caseTypeInfoStoreService..subscribe((result) => { expect(result).toBe(false); });
result99.subscribe((result) => {
expect(response).toEqual(response);
});
afwHttpMock.setupOnlyResponse(result99, 200);
afwHttpMock.returnSuccessResponse();
});
it('should create status options when no list value options are provided', () => {
optionService.options = [
{
value: caseStatusEnum.submitted.toString(),
},
{
value: caseStatusEnum.inProgress.toString(),
},
{
value: caseStatusEnum.closed.toString(),
},
] as OptionModel[];
// tslint:disable-next-line:no-commented-code
// const spy = spyOn(service, 'createStatusOptions');
const result = service.createStatusOptions([], {});
expect(result.length).toBe(2);
expect(result).toEqual([{ value: '103', selected: true }, { value: '105', selected: false }]);
// tslint:disable-next-line:no-commented-code
// const response = [{ mock: 'mock' } as any];
// expect(spy).toBe(result);
});
it('should create status options when there ar list value options are provided', () => {
optionService.options = [
{
value: caseStatusEnum.submitted.toString(),
},
{
value: caseStatusEnum.inProgress.toString(),
},
{
value: caseStatusEnum.closed.toString(),
},
] as OptionModel[];
// tslint:disable-next-line:max-line-length
const result = service.createStatusOptions(optionService.options, 103);
console.log(optionService.options);
expect(result.length).toBe(2);
expect(result).toEqual([{ value: '103', selected: true }, { value: '105', selected: false }]);
});
it('should get case reference without details', () => {
afwHttpMock.setupOnlyResponse({}, 200);
const spy = spyOn(afwHttpMock, 'post').and.callThrough();
const model = new CaseReferenceModel({ reference: '112314121', type: caseTypeEnum.revisionRequest });
const d = service.getCaseReferenceDetails('spinnerMessage', model);
d.subscribe(r => {
expect(r).toBeDefined();
});
expect(spy).toHaveBeenCalledWith('api/support/cases/get-reference-details', model, 'spinnerMessage');
afwHttpMock.returnSuccessResponse();
});
it('should add case reference without details', () => {
afwHttpMock.setupOnlyResponse({}, 200);
const spy = spyOn(afwHttpMock, 'post').and.callThrough();
const model = new CaseReferenceModel({ reference: '112314121', type: caseTypeEnum.revisionRequest });
const d = service.addCase('spinnerMessage', model as any);
d.subscribe(r => {
expect(r).toBeDefined();
});
expect(spy).toHaveBeenCalledWith('api/support/cases', model, 'spinnerMessage');
afwHttpMock.returnSuccessResponse();
});
it('should search for cases', () => {
const formModel: any = { makeQueryString: () => 'name=test' };
const pagingModel = new PagingDataModel({ currentPage: 10, itemsPerPage: 20 });
const sortModel = new TableSortDataModel({ columnName: 'kol', isDescending: false });
const spy = spyOn(afwHttpMock, 'get').and.callThrough();
const mockData = [
new CaseBaseModel({
id: 100000001,
type: caseTypeEnum.revisionRequest,
status: caseStatusEnum.inProgress,
substatus: 5266,
verdict: null,
owner: caseOwnerEnum.caseManager,
dateSubmitted: '02-02-2009',
dateClosed: '',
reference: 'aaa',
}),
];
const setupResponse = new SearchResultModel<CaseBaseModel>();
setupResponse.result = mockData;
setupResponse.totalResultCount = 27;
afwHttpMock.setupOnlyResponse(setupResponse, 200);
let response: SearchResultModel<CaseBaseModel>;
service.search(formModel, sortModel, pagingModel, 'spinnerText').subscribe(result => {
response = result;
});
afwHttpMock.returnOnlyResponse();
expect(spy).toHaveBeenCalledWith('api/support/cases?name=test&columnName=kol&isDescending=false¤tPage=10&itemsPerPage=20',
'spinnerText');
expect(response).toEqual(setupResponse);
expect(response.result[0].getResourceForStatus).toBeDefined();
});
it('should save documents', fakeAsync(() => {
const spy = spyOn(multiFileUploadService, 'syncFilesWithBackend').and.callThrough();
const spyRouter = spyOn(router, 'navigate').and.callThrough();
const spyFeedback = spyOn(feedbackStoreService, 'addSuccessMessageOnMainPortal');
service.saveDocuments(1, [{} as any], MultiFileUploadResourcesModel.keys, '../', { key: 'da', value: 'fa' });
expect(spy).toHaveBeenCalledWith('api/support/cases/1/documents', [{}],
MultiFileUploadResourcesModel.keys.bijlageToevoegenSpinnerTekst,
MultiFileUploadResourcesModel.keys.bijlageVerwijderenSpinnerTekst
);
tick();
expect(spyRouter).toHaveBeenCalledWith(['../']);
expect(spyFeedback).toHaveBeenCalled();
}));
it('should not save documents if there are no documents in array', fakeAsync(() => {
const spy = spyOn(multiFileUploadService, 'syncFilesWithBackend').and.callThrough();
const spyRouter = spyOn(router, 'navigate').and.callThrough();
const spyFeedback = spyOn(feedbackStoreService, 'addSuccessMessageOnMainPortal');
service.saveDocuments(1, [], MultiFileUploadResourcesModel.keys, '../', { key: 'da', value: 'fa' });
expect(spy).not.toHaveBeenCalled();
tick();
expect(spyRouter).toHaveBeenCalledWith(['../']);
expect(spyFeedback).toHaveBeenCalled();
}));
it('should save documents and report errors', fakeAsync(() => {
multiFileUploadService.setResponse([{}, { error: {} }]);
spyOn(multiFileUploadService, 'makeWarningMessageForUnsyncedFiles').and.returnValue('mock');
const spyRouter = spyOn(router, 'navigate').and.callThrough();
const spyFeedback = spyOn(feedbackStoreService, 'addWarningMessageOnMainPortal');
const spy = spyOn(multiFileUploadService, 'syncFilesWithBackend').and.callThrough();
service.saveDocuments(1, [{} as any], MultiFileUploadResourcesModel.keys, '../', { key: 'da', value: 'fa' });
expect(spy).toHaveBeenCalledWith('api/support/cases/1/documents', [{}],
MultiFileUploadResourcesModel.keys.bijlageToevoegenSpinnerTekst,
MultiFileUploadResourcesModel.keys.bijlageVerwijderenSpinnerTekst
);
tick();
expect(spyRouter).toHaveBeenCalledWith(['../']);
expect(spyFeedback).toHaveBeenCalled();
}));
it('should get case by id', () => {
const id = 66208014;
const setupResponse = new CaseBaseModel({
id,
dateSubmitted: '',
owner: caseOwnerEnum.caseManager,
reference: 'ksjhkjshdf',
status: caseStatusEnum.submitted,
type: caseTypeEnum.revisionRequest,
});
afwHttpMock.setupOnlyResponse(setupResponse, 200);
service.getCase(id, 'spinner').subscribe(r => {
expect(r).toEqual(setupResponse);
});
afwHttpMock.returnSuccessResponse();
});
it('edit the case with model', () => {
const spy = spyOn(service, 'editCase').and.callThrough();
const caseUpdate = new CaseBaseModel({
id: 100001075,
dateSubmitted: '',
owner: caseOwnerEnum.caseManager,
reference: 'ksjhkjshdf',
status: caseStatusEnum.submitted,
type: caseTypeEnum.revisionRequest,
});
service.editCase('spinner', caseUpdate);
expect(spy).toHaveBeenCalledWith('spinner', caseUpdate);
expect(caseUpdate.id).toEqual(100001075);
});
});
Based on what you showed so far, my guess is that the options parameter passed to getEnumOption() is undefined, which is causing the error you see. A quick console.log(options) within getEnumOption() would verify this.
If your code is working fine otherwise, but only failing in the test then I would make a second guess that you haven't properly mocked/spiedOn this.optionService.createOptions() since it sets up the options parameter that is potentially undefined. That would have been done earlier in the .spec file - if you post the whole file then that would help others who read your question to determine if this is the case.
Update with Stackblitz
I put all your code into a Stackblitz to test it. There was a lot of code I didn't have access to that I just guessed at the functionality of. However, I did discover a few things.
First, when you are testing you appear to be using the same variable both for the mock of the return expected by this.optionService.createOptions() as well as in the call to service.createStatusOptions() - which is likely not what you want to do.
Here is the code snippet I am talking about:
optionService.options = [
{
value: caseStatusEnum.submitted.toString(),
},
{
value: caseStatusEnum.inProgress.toString(),
},
{
value: caseStatusEnum.closed.toString(),
},
] as OptionModel[];
// tslint:disable-next-line:max-line-length
const result = service.createStatusOptions(optionService.options, [[103], [104], [105] ]);
When I called it this way in the Stackblitz I ran into a mutability issue - you are changing the data within the members of the objects inside the array, which will change it whereever that variable is accessed. To overcome this in the Stackblitz I made two copies of the data, one to use in the mock returnValue and another completely separate array of objects for the call to service.createStatusOptions(). Also, I am not familiar with the way you are mocking your service call, so I replaced it with a simple Jasmine spy in the Stackblitz.
Feel free to have a look at what I produced. Perhaps it will be helpful.