2575-image_download #448
|
@ -0,0 +1,96 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('download', {
|
||||||
|
description: 'Get the user image',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'collection',
|
||||||
|
type: 'String',
|
||||||
|
description: 'The image collection',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'size',
|
||||||
|
type: 'String',
|
||||||
|
description: 'The image size',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'Number',
|
||||||
|
description: 'The user id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
returns: [
|
||||||
|
{
|
||||||
|
arg: 'body',
|
||||||
|
type: 'file',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'Content-Type',
|
||||||
|
type: 'String',
|
||||||
|
http: {target: 'header'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'Content-Disposition',
|
||||||
|
type: 'String',
|
||||||
|
http: {target: 'header'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
http: {
|
||||||
|
path: `/:collection/:size/:id/download`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.download = async function(collection, size, id) {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const filter = {
|
||||||
|
where: {
|
||||||
|
name: collection},
|
||||||
|
include: {
|
||||||
|
relation: 'readRole'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const imageCollection = await models.ImageCollection.findOne(filter);
|
||||||
|
const entity = await models[imageCollection.model].findById(id, {
|
||||||
|
fields: ['id', imageCollection.property]
|
||||||
|
});
|
||||||
|
const image = await models.Image.findOne({where: {
|
||||||
|
collectionFk: collection,
|
||||||
|
name: entity[imageCollection.property]}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!image) return false;
|
||||||
|
|
||||||
|
const imageRole = imageCollection.readRole().name;
|
||||||
|
const hasRole = await models.Account.hasRole(id, imageRole);
|
||||||
|
if (!hasRole)
|
||||||
|
throw new UserError(`You don't have enough privileges`);
|
||||||
|
|
||||||
|
let file;
|
||||||
|
let env = process.env.NODE_ENV;
|
||||||
|
if (env && env != 'development') {
|
||||||
|
file = {
|
||||||
|
path: `/var/lib/salix/image/${collection}/${size}/${image.name}.png`,
|
||||||
|
contentType: 'image/png',
|
||||||
|
name: `${image.name}.png`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
file = {
|
||||||
|
path: `${process.cwd()}/storage/image/${collection}/${size}/${image.name}.png`,
|
||||||
|
contentType: 'image/png',
|
||||||
|
name: `${image.name}.png`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await fs.access(file.path);
|
||||||
|
let stream = fs.createReadStream(file.path);
|
||||||
|
return [stream, file.contentType, `filename="${file.name}"`];
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('image download()', () => {
|
||||||
|
const collection = 'user';
|
||||||
|
const size = '160x160';
|
||||||
|
|
||||||
|
it('should return the image content-type of the user', async() => {
|
||||||
|
const userId = 9;
|
||||||
|
const image = await app.models.Image.download(collection, size, userId);
|
||||||
|
const contentType = image[1];
|
||||||
|
|
||||||
bernat marked this conversation as resolved
|
|||||||
|
expect(contentType).toEqual('image/png');
|
||||||
|
});
|
||||||
|
|
||||||
bernat marked this conversation as resolved
Outdated
carlosjr
commented
doesn't doesn't
|
|||||||
|
it(`should return false if the user doesn't have image`, async() => {
|
||||||
|
const userId = 110;
|
||||||
|
const image = await app.models.Image.download(collection, size, userId);
|
||||||
|
|
||||||
|
expect(image).toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
|
@ -45,6 +45,9 @@
|
||||||
},
|
},
|
||||||
"updated": {
|
"updated": {
|
||||||
"type": "date"
|
"type": "date"
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"type": "String"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -43,7 +43,12 @@
|
||||||
"model": "ImageCollectionSize",
|
"model": "ImageCollectionSize",
|
||||||
"foreignKey": "collectionFk",
|
"foreignKey": "collectionFk",
|
||||||
"property": "id"
|
"property": "id"
|
||||||
}
|
},
|
||||||
|
"readRole": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Role",
|
||||||
|
"foreignKey": "readRoleFk"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"acls": [
|
"acls": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,8 @@ const sharp = require('sharp');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
|
require('../methods/image/download')(Self);
|
||||||
|
|
||||||
Self.getPath = function() {
|
Self.getPath = function() {
|
||||||
return '/var/lib/salix/image';
|
return '/var/lib/salix/image';
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,14 @@
|
||||||
"default": 0
|
"default": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"relations": {
|
||||||
|
"collection": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "ImageCollection",
|
||||||
|
"foreignKey": "collectionFk",
|
||||||
|
"primaryKey": "name"
|
||||||
|
}
|
||||||
|
},
|
||||||
"acls": [
|
"acls": [
|
||||||
{
|
{
|
||||||
"accessType": "READ",
|
"accessType": "READ",
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
ALTER TABLE `hedera`.`imageCollection`
|
||||||
|
ADD COLUMN `readRoleFk` VARCHAR(45) NULL DEFAULT NULL AFTER `column`;
|
||||||
|
|
||||||
|
update `hedera`.`imageCollection` set `readRoleFk` = 1;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE `account`.`user`
|
||||||
|
ADD COLUMN `image` VARCHAR(255) NULL AFTER `password`;
|
|
@ -443,7 +443,7 @@ USE `hedera`;
|
||||||
|
|
||||||
LOCK TABLES `imageCollection` WRITE;
|
LOCK TABLES `imageCollection` WRITE;
|
||||||
/*!40000 ALTER TABLE `imageCollection` DISABLE KEYS */;
|
/*!40000 ALTER TABLE `imageCollection` DISABLE KEYS */;
|
||||||
INSERT INTO `imageCollection` VALUES (1,'catalog','Artículo',3840,2160,'Item','image','vn','item','image'),(4,'link','Enlace',200,200,'Link','image','hedera','link','image'),(5,'news','Noticias',800,1200,'New','image','hedera','news','image');
|
INSERT INTO `imageCollection` VALUES (1,'catalog','Artículo',3840,2160,'Item','image','vn','item','image'),(4,'link','Enlace',200,200,'Link','image','hedera','link','image'),(5,'news','Noticias',800,1200,'New','image','hedera','news','image'),('6','user','Usuario','800','1200','Account','image','account','user','image');
|
||||||
/*!40000 ALTER TABLE `imageCollection` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `imageCollection` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@ INSERT INTO `vn`.`packagingConfig`(`upperGap`)
|
||||||
UPDATE `account`.`role` SET id = 100 WHERE id = 0;
|
UPDATE `account`.`role` SET id = 100 WHERE id = 0;
|
||||||
CALL `account`.`role_sync`;
|
CALL `account`.`role_sync`;
|
||||||
|
|
||||||
INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `password`,`role`,`active`,`email`, `lang`)
|
INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `password`,`role`,`active`,`email`, `lang`, `image`)
|
||||||
SELECT id, name, CONCAT(name, 'Nick'),MD5('nightmare'), id, 1, CONCAT(name, '@mydomain.com'), 'en'
|
SELECT id, name, CONCAT(name, 'Nick'),MD5('nightmare'), id, 1, CONCAT(name, '@mydomain.com'), 'en', 'e7723f0b24ff05b32ed09d95196f2f29'
|
||||||
FROM `account`.`role` WHERE id <> 20
|
FROM `account`.`role` WHERE id <> 20
|
||||||
ORDER BY id;
|
ORDER BY id;
|
||||||
|
|
||||||
|
@ -51,20 +51,20 @@ INSERT INTO `hedera`.`tpvConfig`(`id`, `currency`, `terminal`, `transactionType`
|
||||||
VALUES
|
VALUES
|
||||||
(1, 978, 1, 0, 2000, 9, 0);
|
(1, 978, 1, 0, 2000, 9, 0);
|
||||||
|
|
||||||
INSERT INTO `account`.`user`(`id`,`name`,`nickname`, `password`,`role`,`active`,`email`,`lang`)
|
INSERT INTO `account`.`user`(`id`,`name`,`nickname`, `password`,`role`,`active`,`email`,`lang`, `image`)
|
||||||
VALUES
|
VALUES
|
||||||
(101, 'BruceWayne', 'Bruce Wayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@mydomain.com', 'es'),
|
(101, 'BruceWayne', 'Bruce Wayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@mydomain.com', 'es', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(102, 'PetterParker', 'Petter Parker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@mydomain.com', 'en'),
|
(102, 'PetterParker', 'Petter Parker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@mydomain.com', 'en', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(103, 'ClarkKent', 'Clark Kent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@mydomain.com', 'fr'),
|
(103, 'ClarkKent', 'Clark Kent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@mydomain.com', 'fr', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(104, 'TonyStark', 'Tony Stark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@mydomain.com', 'es'),
|
(104, 'TonyStark', 'Tony Stark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@mydomain.com', 'es', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(105, 'MaxEisenhardt', 'Max Eisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@mydomain.com', 'pt'),
|
(105, 'MaxEisenhardt', 'Max Eisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@mydomain.com', 'pt', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(106, 'DavidCharlesHaller', 'David Charles Haller', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'DavidCharlesHaller@mydomain.com', 'en'),
|
(106, 'DavidCharlesHaller', 'David Charles Haller', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'DavidCharlesHaller@mydomain.com', 'en', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(107, 'HankPym', 'Hank Pym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@mydomain.com', 'en'),
|
(107, 'HankPym', 'Hank Pym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@mydomain.com', 'en', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(108, 'CharlesXavier', 'Charles Xavier', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'CharlesXavier@mydomain.com', 'en'),
|
(108, 'CharlesXavier', 'Charles Xavier', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'CharlesXavier@mydomain.com', 'en', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(109, 'BruceBanner', 'Bruce Banner', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'BruceBanner@mydomain.com', 'en'),
|
(109, 'BruceBanner', 'Bruce Banner', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'BruceBanner@mydomain.com', 'en', 'e7723f0b24ff05b32ed09d95196f2f29'),
|
||||||
(110, 'JessicaJones', 'Jessica Jones', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'JessicaJones@mydomain.com', 'en'),
|
(110, 'JessicaJones', 'Jessica Jones', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'JessicaJones@mydomain.com', 'en', NULL),
|
||||||
(111, 'Missing', 'Missing', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'en'),
|
(111, 'Missing', 'Missing', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'en', NULL),
|
||||||
(112, 'Trash', 'Trash', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'en');
|
(112, 'Trash', 'Trash', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'en', NULL);
|
||||||
|
|
||||||
INSERT INTO `account`.`mailAlias`(`id`, `alias`, `description`, `isPublic`)
|
INSERT INTO `account`.`mailAlias`(`id`, `alias`, `description`, `isPublic`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -2148,3 +2148,10 @@ INSERT INTO `vn`.`campaign`(`code`, `dated`)
|
||||||
('allSaints', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -2 YEAR)), '-11-01')),
|
('allSaints', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -2 YEAR)), '-11-01')),
|
||||||
('allSaints', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -3 YEAR)), '-11-01'));
|
('allSaints', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -3 YEAR)), '-11-01'));
|
||||||
|
|
||||||
|
INSERT INTO `hedera`.`image`(`collectionFk`, `name`)
|
||||||
|
VALUES
|
||||||
|
('user', 'e7723f0b24ff05b32ed09d95196f2f29');
|
||||||
|
|
||||||
|
INSERT INTO `hedera`.`imageCollectionSize`(`id`, `collectionFk`,`width`, `height`)
|
||||||
|
VALUES
|
||||||
|
(1, 4, 160, 160);
|
|
@ -31,12 +31,15 @@
|
||||||
ng-if="$ctrl.rightMenu"
|
ng-if="$ctrl.rightMenu"
|
||||||
ng-click="$ctrl.rightMenu.show()">
|
ng-click="$ctrl.rightMenu.show()">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
<vn-icon-button
|
<button class="buttonAccount">
|
||||||
|
<img
|
||||||
bernat marked this conversation as resolved
carlosjr
commented
please add the id to the element. please add the id to the element.
|
|||||||
id="user"
|
id="user"
|
||||||
icon="account_circle"
|
ng-src="{{$ctrl.getImageUrl()}}"
|
||||||
ng-click="userPopover.show($event)"
|
ng-click="userPopover.show($event)"
|
||||||
translate-attr="{title: 'Account'}">
|
translate-attr="{title: 'Account'}"
|
||||||
</vn-icon-button>
|
on-error-src/>
|
||||||
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<vn-menu vn-id="apps-menu">
|
<vn-menu vn-id="apps-menu">
|
||||||
<vn-list class="modules-menu">
|
<vn-list class="modules-menu">
|
||||||
|
|
|
@ -18,6 +18,14 @@ export class Layout extends Component {
|
||||||
window.localStorage.currentUserWorkerId = json.data.id;
|
window.localStorage.currentUserWorkerId = json.data.id;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getImageUrl() {
|
||||||
|
if (!this.$.$root.user) return;
|
||||||
|
|
||||||
|
const userId = this.$.$root.user.id;
|
||||||
|
const token = this.vnToken.token;
|
||||||
|
return `/api/Images/user/160x160/${userId}/download?access_token=${token}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Layout.$inject = ['$element', '$scope', 'vnModules'];
|
Layout.$inject = ['$element', '$scope', 'vnModules'];
|
||||||
|
|
||||||
|
|
|
@ -22,4 +22,19 @@ describe('Component vnLayout', () => {
|
||||||
expect(controller.$.$root.user.name).toEqual('batman');
|
expect(controller.$.$root.user.name).toEqual('batman');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getImageUrl()', () => {
|
||||||
|
it('should return the url image if the user is defined', () => {
|
||||||
|
controller.$.$root.user = {id: 1};
|
||||||
|
const url = controller.getImageUrl();
|
||||||
|
|
||||||
|
expect(url).not.toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined if the user is not defined', () => {
|
||||||
|
const url = controller.getImageUrl();
|
||||||
|
|
||||||
|
expect(url).not.toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -109,6 +109,14 @@ vn-layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
img {
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.buttonAccount {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
@media screen and (max-width: $mobile-width) {
|
@media screen and (max-width: $mobile-width) {
|
||||||
& > vn-topbar {
|
& > vn-topbar {
|
||||||
& > .start > .logo {
|
& > .start > .logo {
|
||||||
|
@ -147,3 +155,4 @@ vn-layout {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
<vn-popover vn-id="popover">
|
<vn-popover vn-id="popover">
|
||||||
<vn-vertical class="user-popover vn-pa-md">
|
<vn-vertical class="user-popover vn-pa-md">
|
||||||
<div class="profile-card vn-pb-md">
|
<div class="profile-card vn-pb-md">
|
||||||
<vn-icon icon="account_circle"></vn-icon>
|
<img
|
||||||
|
ng-src="{{$ctrl.getImageUrl($root.user.id)}}"
|
||||||
|
on-error-src/>
|
||||||
<div class="vn-pl-sm">
|
<div class="vn-pl-sm">
|
||||||
<div>
|
<div>
|
||||||
<div class="user">
|
<div class="user">
|
||||||
|
|
|
@ -3,12 +3,13 @@ import './style.scss';
|
||||||
import config from '../../config.json';
|
import config from '../../config.json';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($, $translate, vnConfig, vnAuth) {
|
constructor($, $translate, vnConfig, vnAuth, vnToken) {
|
||||||
Object.assign(this, {
|
Object.assign(this, {
|
||||||
$,
|
$,
|
||||||
$translate,
|
$translate,
|
||||||
vnConfig,
|
vnConfig,
|
||||||
vnAuth,
|
vnAuth,
|
||||||
|
vnToken,
|
||||||
lang: $translate.use(),
|
lang: $translate.use(),
|
||||||
langs: []
|
langs: []
|
||||||
});
|
});
|
||||||
|
@ -77,8 +78,12 @@ class Controller {
|
||||||
this.$.companies.refresh();
|
this.$.companies.refresh();
|
||||||
this.$.popover.show(event.target);
|
this.$.popover.show(event.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getImageUrl(userId) {
|
||||||
|
return '/api/Images/user/160x160/' + userId + '/download?access_token=' + this.vnToken.token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Controller.$inject = ['$scope', '$translate', 'vnConfig', 'vnAuth'];
|
Controller.$inject = ['$scope', '$translate', 'vnConfig', 'vnAuth', 'vnToken'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnUserPopover', {
|
ngModule.vnComponent('vnUserPopover', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -57,5 +57,13 @@ describe('Salix', () => {
|
||||||
expect(controller.companyFk).toBe(4);
|
expect(controller.companyFk).toBe(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getImageUrl()', () => {
|
||||||
|
it('should return de url image', () => {
|
||||||
|
const url = controller.getImageUrl();
|
||||||
|
|
||||||
|
expect(url).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
font-size: 5rem;
|
font-size: 5rem;
|
||||||
color: $color-font-bg-marginal;
|
color: $color-font-bg-marginal;
|
||||||
}
|
}
|
||||||
|
img {
|
||||||
|
width: 80px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
& > div {
|
& > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -11,11 +11,10 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"ticketFk": {
|
"ticketFk": {
|
||||||
"id": 1,
|
"id": true,
|
||||||
"type": "Number"
|
"type": "Number"
|
||||||
},
|
},
|
||||||
"ticketTrackingFk": {
|
"ticketTrackingFk": {
|
||||||
"id": 2,
|
|
||||||
"type": "Number"
|
"type": "Number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Loading…
Reference in New Issue
expect(contentType).toEqual....