2021-12-07 15:30:53 +01:00
// @flow
import o from "ospec"
2021-12-15 16:07:07 +01:00
import { ContactTypeRef , createContact } from "../../../src/api/entities/tutanota/Contact"
2021-12-07 15:30:53 +01:00
import { BadRequestError , InternalServerError , PayloadTooLargeError } from "../../../src/api/common/error/RestError"
import { assertThrows } from "@tutao/tutanota-test-utils"
import { SetupMultipleError } from "../../../src/api/common/error/SetupMultipleError"
import { downcast , TypeRef } from "@tutao/tutanota-utils"
import type { HttpMethodEnum , MediaTypeEnum } from "../../../src/api/common/EntityFunctions"
import { HttpMethod , resolveTypeReference } from "../../../src/api/common/EntityFunctions"
2021-12-15 16:07:07 +01:00
import { createCustomer , CustomerTypeRef } from "../../../src/api/entities/sys/Customer"
import { EntityRestClient , typeRefToPath } from "../../../src/api/worker/rest/EntityRestClient"
2021-12-07 15:30:53 +01:00
import { RestClient } from "../../../src/api/worker/rest/RestClient"
import type { CryptoFacade } from "../../../src/api/worker/crypto/CryptoFacade"
import type { TypeModel } from "../../../src/api/common/EntityTypes"
import { createInternalRecipientKeyData } from "../../../src/api/entities/tutanota/InternalRecipientKeyData"
import { create } from "../../../src/api/common/utils/EntityUtils"
import { InstanceMapper } from "../../../src/api/worker/crypto/InstanceMapper"
import { CalendarEventTypeRef } from "../../../src/api/entities/tutanota/CalendarEvent"
2021-12-15 16:07:07 +01:00
const accessToken = "My cool access token"
const authHeader = { accessToken : accessToken }
2021-12-07 15:30:53 +01:00
2021-12-15 16:07:07 +01:00
function createEntityRestClientWithMocks ( requestMock : Function ) : {
entityRestClient : EntityRestClient ,
cryptoFacadeMock : CryptoFacade ,
instanceMapperMock : InstanceMapper ,
requestSpy : OspecSpy < typeof RestClient . prototype . request >
} {
2021-12-07 15:30:53 +01:00
2021-12-15 16:07:07 +01:00
const cryptoFacadeMock : CryptoFacade = {
applyMigrations : o . spy ( async < T > ( typeRef : TypeRef < T > , data : any ) : Promise < T > => resolveTypeReference ( typeRef ) . then ( model => create ( model , typeRef ) ) ) ,
applyMigrationsForInstance : o . spy ( async < T > ( decryptedInstance : T ) : Promise < T > => decryptedInstance ) ,
setNewOwnerEncSessionKey : o . spy ( ( model : TypeModel , entity : Object ) => [ ] ) ,
resolveServiceSessionKey : o . spy ( async ( typeModel : TypeModel , instance : Object ) => [ ] ) ,
encryptBucketKeyForInternalRecipient : o . spy ( async ( bucketKey : Aes128Key , recipientMailAddress : string , notFoundRecipients : Array < string > ) => createInternalRecipientKeyData ( ) ) ,
resolveSessionKey : o . spy ( async ( typeModel : TypeModel , instance : Object ) => [ ] ) ,
2021-12-07 15:30:53 +01:00
}
2021-12-15 16:07:07 +01:00
const instanceMapperMock : InstanceMapper = downcast ( {
encryptAndMapToLiteral : o . spy ( async ( model , instance , sk ) => {
return {
dummyMessage : "encrypted"
}
} ) ,
decryptAndMapToInstance : o . spy ( async ( model , instance , sk ) => {
return {
dummyMessage : "decrypted"
}
} )
} )
2021-12-07 15:30:53 +01:00
const requestSpy = o . spy ( requestMock )
2021-12-15 16:07:07 +01:00
2021-12-07 15:30:53 +01:00
const entityRestClient = new EntityRestClient (
2021-12-15 16:07:07 +01:00
( ) => authHeader , // Entity rest client doesn't allow requests without authorization
2021-12-07 15:30:53 +01:00
downcast < RestClient > ( { request : async ( ... args ) => requestSpy ( ... args ) } ) ,
( ) => cryptoFacadeMock ,
instanceMapperMock ,
)
return {
2021-12-15 16:07:07 +01:00
instanceMapperMock ,
cryptoFacadeMock ,
2021-12-07 15:30:53 +01:00
entityRestClient ,
requestSpy
}
}
function createArrayOf < T > ( count : number , factory : ( index : number ) => T ) : Array < T > {
return Array ( count ) . fill ( ) . map ( ( _ , idx ) => factory ( idx ) )
}
const range = ( start , count ) => createArrayOf ( count , idx => String ( idx + start ) )
function contacts ( count ) {
const contactFactory = idx => createContact ( {
firstName : ` Contact ${ idx } `
} )
return createArrayOf ( count , contactFactory )
}
o . spec ( "EntityRestClient" , async function ( ) {
2021-12-15 16:07:07 +01:00
o . spec ( "Load" , function ( ) {
o ( "loading a list element" , async function ( ) {
const { entityRestClient , requestSpy , instanceMapperMock , cryptoFacadeMock } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( "The element that was returned from the server" )
)
const calendarListId = "calendarListId"
const id1 = "id1"
const result = await entityRestClient . load ( CalendarEventTypeRef , [ calendarListId , id1 ] )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 0 ] ) . equals ( ` ${ typeRefToPath ( CalendarEventTypeRef ) } / ${ calendarListId } / ${ id1 } ` ) ( "path is correct" )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( instanceMapperMock . decryptAndMapToInstance . callCount ) . equals ( 1 )
o ( cryptoFacadeMock . applyMigrationsForInstance . callCount ) . equals ( 1 )
} )
o ( "loading an element " , async function ( ) {
2021-12-07 15:30:53 +01:00
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
2021-12-15 16:07:07 +01:00
( ) => JSON . stringify ( "The element that was returned from the server" )
2021-12-07 15:30:53 +01:00
)
2021-12-15 16:07:07 +01:00
const id1 = "id1"
const result = await entityRestClient . load ( CustomerTypeRef , id1 )
2021-12-07 15:30:53 +01:00
o ( requestSpy . callCount ) . equals ( 1 )
2021-12-15 16:07:07 +01:00
o ( requestSpy . args [ 0 ] ) . equals ( ` ${ typeRefToPath ( CustomerTypeRef ) } / ${ id1 } ` ) ( "path is correct" )
2021-12-07 15:30:53 +01:00
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
2021-12-15 16:07:07 +01:00
o ( result ) . deepEquals ( { dummyMessage : "decrypted" } ) ( "decrypts and returns from the client" )
} )
o ( "query parameters and additional headers + access token and version are always passed to the rest client" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( "The element that was returned from the server" )
)
const id1 = "id1"
const queryParameters = { "foo" : "bar" }
const headers = { "baz" : "quux" }
const result = await entityRestClient . load ( CustomerTypeRef , id1 , queryParameters , headers )
2021-12-07 15:30:53 +01:00
2021-12-15 16:07:07 +01:00
const { version } = await resolveTypeReference ( CustomerTypeRef )
o ( requestSpy . args [ 2 ] ) . deepEquals ( queryParameters ) ( "query parameters are passed" )
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken : accessToken , v : version , baz : "quux" } ) ( "headers are passed" )
2021-12-07 15:30:53 +01:00
} )
} )
2021-12-15 16:07:07 +01:00
o . spec ( "Load Range" , function ( ) {
o ( "Loads a range of entities in a single request" , async function ( ) {
const { entityRestClient , requestSpy , instanceMapperMock , cryptoFacadeMock } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ "e1" , "e2" , "e3" ] )
)
const startId = "42"
const count = 5
await entityRestClient . loadRange ( CalendarEventTypeRef , "listId" , startId , count , false )
const { version } = await resolveTypeReference ( CalendarEventTypeRef )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . args [ 2 ] ) . deepEquals ( {
start : ` ${ startId } ` ,
count : ` ${ count } ` ,
reverse : "false"
} ) ( "Range is passed in as query params" )
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken , v : version } ) ( "access token and version are passed" )
} )
} )
2021-12-07 15:30:53 +01:00
o . spec ( "Load multiple" , function ( ) {
o ( "Less than 100 entities requested should result in a single rest request" , async function ( ) {
2021-12-15 16:07:07 +01:00
const { entityRestClient , requestSpy , instanceMapperMock , cryptoFacadeMock } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ "e1" , "e2" , "e3" ] )
2021-12-07 15:30:53 +01:00
)
const ids = range ( 0 , 5 )
const result = await entityRestClient . loadMultiple ( CustomerTypeRef , null , ids )
2021-12-15 16:07:07 +01:00
const { version } = await resolveTypeReference ( CustomerTypeRef )
2021-12-07 15:30:53 +01:00
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . args [ 2 ] ) . deepEquals ( { ids : ids . join ( "," ) } ) ( "Requested IDs are passed in as query params" )
2021-12-15 16:07:07 +01:00
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken , v : version } ) ( "access token and version are passed" )
o ( instanceMapperMock . decryptAndMapToInstance . callCount ) . equals ( 3 )
o ( cryptoFacadeMock . applyMigrationsForInstance . callCount ) . equals ( 3 )
2021-12-07 15:30:53 +01:00
} )
o ( "Exactly 100 entities requested should result in a single rest request" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ "The elements that were returned from the server" ] )
)
const ids = range ( 0 , 100 )
const result = await entityRestClient . loadMultiple ( CustomerTypeRef , null , ids )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . args [ 2 ] ) . deepEquals ( { ids : ids . join ( "," ) } ) ( "Requested IDs are passed in as query params" )
o ( result ) . deepEquals ( [ { dummyMessage : "decrypted" } ] ) ( "Returns what was returned by the rest client" )
} )
o ( "More than 100 entities requested results in 2 rest requests" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ "entities" ] )
)
const ids = range ( 0 , 101 )
const result = await entityRestClient . loadMultiple ( CustomerTypeRef , null , ids )
o ( requestSpy . callCount ) . equals ( 2 )
o ( requestSpy . calls [ 0 ] . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . calls [ 0 ] . args [ 2 ] ) . deepEquals ( { ids : ids . slice ( 0 , 100 ) . join ( "," ) } ) ( "The first 100 ids are requested" )
o ( requestSpy . calls [ 1 ] . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . calls [ 1 ] . args [ 2 ] ) . deepEquals ( { ids : ids . slice ( 100 , 101 ) . join ( "," ) } ) ( "The remaining 1 id is requested" )
o ( result ) . deepEquals ( [
{ dummyMessage : "decrypted" } , { dummyMessage : "decrypted" }
] ) ( "Returns what was returned by the rest client" )
} )
o ( "More than 200 entities requested results in 3 rest requests" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ "entities" ] )
)
const ids = range ( 0 , 211 )
const result = await entityRestClient . loadMultiple ( CustomerTypeRef , null , ids )
o ( requestSpy . callCount ) . equals ( 3 )
o ( requestSpy . calls [ 0 ] . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . calls [ 0 ] . args [ 2 ] ) . deepEquals ( { ids : ids . slice ( 0 , 100 ) . join ( "," ) } ) ( "The first 100 ids are requested" )
o ( requestSpy . calls [ 1 ] . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . calls [ 1 ] . args [ 2 ] ) . deepEquals ( { ids : ids . slice ( 100 , 200 ) . join ( "," ) } ) ( "The next 100 ids are requested" )
o ( requestSpy . calls [ 2 ] . args [ 1 ] ) . equals ( HttpMethod . GET ) ( "Method is GET" )
o ( requestSpy . calls [ 2 ] . args [ 2 ] ) . deepEquals ( { ids : ids . slice ( 200 , 211 ) . join ( "," ) } ) ( "The remaining 11 ids are requested" )
o ( result ) . deepEquals ( [
{ dummyMessage : "decrypted" } , { dummyMessage : "decrypted" } , { dummyMessage : "decrypted" }
] ) ( "Returns what was returned by the rest client" )
} )
} )
2021-12-15 16:07:07 +01:00
o . spec ( "Setup" , async function ( ) {
o ( "Setup list entity" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( { generatedId : "id" } )
)
const newContact = createContact ( )
const result = await entityRestClient . setup ( "listId" , newContact )
const { version } = await resolveTypeReference ( ContactTypeRef )
o ( result ) . deepEquals ( "id" )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken , v : version } ) ( "access token and version are passed" )
o ( requestSpy . args [ 4 ] ) . deepEquals ( JSON . stringify ( { dummyMessage : "encrypted" } ) ) ( "Contact were sent" )
} )
o ( "Setup list entity throws when no listid is passed" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( { generatedId : "id" } )
)
const newContact = createContact ( )
const result = await assertThrows ( Error , async ( ) => await entityRestClient . setup ( null , newContact ) )
o ( result . message ) . equals ( "List id must be defined for LETs" )
} )
o ( "Setup entity" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( { generatedId : "id" } )
)
const newCustomer = createCustomer ( )
const result = await entityRestClient . setup ( null , newCustomer )
const { version } = await resolveTypeReference ( CustomerTypeRef )
o ( result ) . deepEquals ( "id" )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken , v : version } ) ( "access token and version are passed" )
o ( requestSpy . args [ 4 ] ) . deepEquals ( JSON . stringify ( { dummyMessage : "encrypted" } ) ) ( "Contact were sent" )
} )
o ( "Setup entity throws when listid is passed" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( { generatedId : "id" } )
)
const newCustomer = createCustomer ( )
const result = await assertThrows ( Error , async ( ) => await entityRestClient . setup ( "listId" , newCustomer ) )
o ( result . message ) . equals ( "List id must not be defined for ETs" )
} )
} )
2021-12-07 15:30:53 +01:00
o . spec ( "Setup multiple" , async function ( ) {
o ( "Less than 100 entities created should result in a single rest request" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ { generatedId : "someReturnedId" } ] )
)
const newContacts = contacts ( 1 )
const result = await entityRestClient . setupMultiple ( "listId" , newContacts )
2021-12-15 16:07:07 +01:00
const { version } = await resolveTypeReference ( ContactTypeRef )
2021-12-07 15:30:53 +01:00
o ( result ) . deepEquals ( [ "someReturnedId" ] )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
2021-12-15 16:07:07 +01:00
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken , v : version } ) ( "access token and version are passed" )
2021-12-07 15:30:53 +01:00
o ( requestSpy . args [ 4 ] ) . deepEquals ( JSON . stringify ( newContacts . map ( ( ) => ( { dummyMessage : "encrypted" } ) ) ) ) ( "All contacts were sent" )
} )
o ( "Exactly 100 entities created should result in a single rest request" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ { generatedId : "someReturnedId" } ] )
)
const newContacts = contacts ( 100 )
const result = await entityRestClient . setupMultiple ( "listId" , newContacts )
o ( result ) . deepEquals ( [ "someReturnedId" ] )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . args [ 4 ] ) . deepEquals ( JSON . stringify ( newContacts . map ( ( ) => ( { dummyMessage : "encrypted" } ) ) ) ) ( "All contacts were sent" )
} )
o ( "More than 100 entities created should result in 2 rest requests" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ { generatedId : "someReturnedId" } ] )
)
const newContacts = contacts ( 101 )
const result = await entityRestClient . setupMultiple ( "listId" , newContacts )
o ( result ) . deepEquals ( [ "someReturnedId" , "someReturnedId" ] )
o ( requestSpy . callCount ) . equals ( 2 )
o ( requestSpy . calls [ 0 ] . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . calls [ 0 ] . args [ 4 ] ) . deepEquals ( JSON . stringify ( newContacts . map ( ( ) => ( { dummyMessage : "encrypted" } ) ) . slice ( 0 , 100 ) ) ) ( "First 100 contacts were sent" )
o ( requestSpy . calls [ 1 ] . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . calls [ 1 ] . args [ 4 ] ) . deepEquals ( JSON . stringify ( newContacts . map ( ( ) => ( { dummyMessage : "encrypted" } ) ) . slice ( 100 , 101 ) ) ) ( "Remaining contact was sent" )
} )
o ( "More than 200 entities created should result in 3 rest requests" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => JSON . stringify ( [ { generatedId : "someReturnedId" } ] )
)
const newContacts = contacts ( 211 )
const result = await entityRestClient . setupMultiple ( "listId" , newContacts )
o ( result ) . deepEquals ( [ "someReturnedId" , "someReturnedId" , "someReturnedId" ] )
o ( requestSpy . callCount ) . equals ( 3 )
o ( requestSpy . calls [ 0 ] . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . calls [ 0 ] . args [ 4 ] ) . deepEquals ( JSON . stringify ( newContacts . map ( ( ) => ( { dummyMessage : "encrypted" } ) ) . slice ( 0 , 100 ) ) ) ( "First 100 contacts were sent" )
o ( requestSpy . calls [ 1 ] . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . calls [ 1 ] . args [ 4 ] ) . deepEquals ( JSON . stringify ( newContacts . map ( ( ) => ( { dummyMessage : "encrypted" } ) ) . slice ( 100 , 200 ) ) ) ( "Next 100 contacts were sent" )
o ( requestSpy . calls [ 2 ] . args [ 1 ] ) . equals ( HttpMethod . POST ) ( "The method is POST" )
o ( requestSpy . calls [ 2 ] . args [ 4 ] ) . deepEquals ( JSON . stringify ( newContacts . map ( ( ) => ( { dummyMessage : "encrypted" } ) ) . slice ( 200 , 211 ) ) ) ( "Remaining 11 contacts were sent" )
} )
o ( "A single request is made and an error occurs, all entites should be returned as failedInstances" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => { throw new BadRequestError ( "canny do et" ) }
)
const newContacts = contacts ( 100 )
const result = await assertThrows ( SetupMultipleError , ( ) => entityRestClient . setupMultiple ( "listId" , newContacts ) )
o ( requestSpy . callCount ) . equals ( 1 )
o ( result . failedInstances . length ) . equals ( newContacts . length )
o ( result . errors . length ) . equals ( 1 )
o ( result . errors [ 0 ] instanceof BadRequestError ) . equals ( true )
o ( result . failedInstances ) . deepEquals ( newContacts )
} )
o ( "Post multiple: An error is encountered for part of the request, only failed entities are returned in the result" , async function ( ) {
let requestCounter = 0
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => {
requestCounter += 1
if ( requestCounter % 2 === 0 ) {
// Second and Fourth requests are success
return JSON . stringify ( range ( 0 , 100 ) )
} else {
// First and Third requests are failure
throw new BadRequestError ( "It was a bad request" )
}
}
)
const newContacts = contacts ( 400 )
const result = await assertThrows ( SetupMultipleError ,
( ) => entityRestClient . setupMultiple ( "listId" , newContacts )
)
o ( requestSpy . callCount ) . equals ( 4 )
o ( result . failedInstances ) . deepEquals ( newContacts . slice ( 0 , 100 ) . concat ( newContacts . slice ( 200 , 300 ) ) )
o ( result . errors . length ) . equals ( 2 )
o ( result . errors . every ( e => e instanceof BadRequestError ) ) . equals ( true )
} )
o ( "Post multiple: When a PayloadTooLarge error occurs individual instances are posted" , async function ( ) {
const listId = "listId"
const idArray = [ "0" , null , "2" ] // GET fails for id 1
let instances = [ ]
for ( let i = 0 ; i < idArray . length ; i ++ ) {
instances . push ( createContact ( ) )
}
let step = 0
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
function ( path : string ,
method : HttpMethodEnum ,
2021-12-28 13:53:11 +01:00
queryParams : Dict ,
headers : Dict ,
2021-12-07 15:30:53 +01:00
body : ? string ,
responseType : ? MediaTypeEnum ,
progressListener : ? ProgressListener ,
baseUrl ? : string ) {
//post multiple - body is an array
if ( body && body . startsWith ( "[" ) ) {
throw new PayloadTooLargeError ( "test" )
//post single
} else if ( step === 1 ) {
step += 1
throw new InternalServerError ( "might happen" )
} else {
return JSON . stringify ( idArray [ step ++ ] )
}
}
)
const result = await assertThrows ( SetupMultipleError , async ( ) => {
return await entityRestClient . setupMultiple ( listId , instances )
} )
o ( requestSpy . callCount ) . equals ( 4 ) //one post multiple and three individual posts
o ( result . failedInstances . length ) . equals ( 1 ) //one individual post results in an error
o ( result . errors . length ) . equals ( 1 )
o ( result . errors [ 0 ] instanceof InternalServerError ) . equals ( true )
o ( result . failedInstances ) . deepEquals ( [ instances [ 1 ] ] )
} )
} )
2021-12-15 16:07:07 +01:00
o . spec ( "Update" , function ( ) {
o ( "Update entity" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => { }
)
const newCustomer = createCustomer ( { _id : "id" } )
await entityRestClient . update ( newCustomer )
const { version } = await resolveTypeReference ( CustomerTypeRef )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . PUT ) ( "The method is PUT" )
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken , v : version } ) ( "access token and version are passed" )
o ( requestSpy . args [ 4 ] ) . deepEquals ( JSON . stringify ( { dummyMessage : "encrypted" } ) ) ( "Contact were sent" )
} )
o ( "Update entity throws if entity does not have an id" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => { }
)
const newCustomer = createCustomer ( )
const result = await assertThrows ( Error , async ( ) => await entityRestClient . update ( newCustomer ) )
o ( result . message ) . equals ( "Id must be defined" )
} )
} )
o . spec ( "Delete" , function ( ) {
o ( "Delete entity" , async function ( ) {
const { entityRestClient , requestSpy } = createEntityRestClientWithMocks (
( ) => { }
)
const id = "id"
const newCustomer = createCustomer ( { _id : id } )
await entityRestClient . erase ( newCustomer )
const { version } = await resolveTypeReference ( CustomerTypeRef )
o ( requestSpy . callCount ) . equals ( 1 )
o ( requestSpy . args [ 0 ] ) . equals ( ` ${ typeRefToPath ( CustomerTypeRef ) } / ${ id } ` ) ( "path is correct" )
o ( requestSpy . args [ 1 ] ) . equals ( HttpMethod . DELETE ) ( "The method is DELETE" )
o ( requestSpy . args [ 3 ] ) . deepEquals ( { accessToken , v : version } ) ( "access token and version are passed" )
} )
} )
2021-12-07 15:30:53 +01:00
} )