sinon#SinonStubbedInstance TypeScript Examples

The following examples show how to use sinon#SinonStubbedInstance. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: delete-file-factory.spec.ts    From adminjs-upload with MIT License 5 votes vote down vote up
describe('deleteFileFactory', () => {
  const response = {} as RecordActionResponse
  const request = {} as ActionRequest
  const context = {} as ActionContext
  let provider: BaseProvider
  let record: SinonStubbedInstance<BaseRecord> & BaseRecord
  let uploadOptions: UploadOptionsWithDefault

  before(() => {
    provider = stubProvider()
    uploadOptions = {
      properties: {
        key: 's3Key',
        filePath: 'resolvedPath',
        file: 'file',
        bucket: 'bucket',
        filesToDelete: 'fileToDelete',
      },
      provider: {
        aws: { bucket: 'any' },
      } as UploadOptionsWithDefault['provider'] }
    record = createStubInstance(BaseRecord, {
      id: sinon.stub<any, string>().returns('1'),
      isValid: sinon.stub<any, boolean>().returns(true),
      update: sinon.stub<any, Promise<BaseRecord>>().returnsThis(),
      get: sinon.stub<any, string>(),
    })
    context.record = record
  })

  afterEach(() => {
    sinon.reset()
  })

  it('does nothing when file has not been uploaded', () => {
    const deleteFile = deleteFileFactory(uploadOptions, provider)
    deleteFile(response, request, context)

    expect(provider.delete).not.to.have.been.called
  })

  it('deletes file when one was uploaded with the bucket from the db', () => {
    const [path, bucket] = ['file-to-delete-path', 'file-to-delete-bucket']
    record.get.onCall(0).returns(path)
    record.get.onCall(1).returns(bucket)

    const deleteFile = deleteFileFactory(uploadOptions, provider)
    deleteFile(response, request, context)

    expect(provider.delete).to.have.been.calledWith(path, bucket)
  })

  it('deletes file when one was uploaded with the bucket from provider', () => {
    const [path, bucketFromProvider] = ['file-to-delete-path', undefined]
    record.get.onCall(0).returns(path)
    record.get.onCall(1).returns(bucketFromProvider)

    const deleteFile = deleteFileFactory(uploadOptions, provider)
    deleteFile(response, request, context)

    expect(provider.delete).to.have.been.calledWith(path, provider.bucket)
  })

  it('deletes multiple files when `multiple` option has been selected', () => {
    uploadOptions.multiple = true
    const paths = ['path1', 'path2']
    const buckets = ['bucket1']
    record.get.onCall(0).returns(paths)
    record.get.onCall(1).returns(buckets)

    const deleteFile = deleteFileFactory(uploadOptions, provider)
    deleteFile(response, request, context)

    expect(provider.delete).to.have.callCount(2)
    expect(provider.delete).to.have.been.calledWith(paths[0], buckets[0])
    expect(provider.delete).to.have.been.calledWith(paths[1], provider.bucket)
  })
})
Example #2
Source File: cli_command.test.ts    From ardrive-cli with GNU Affero General Public License v3.0 5 votes vote down vote up
describe('CLICommand class', () => {
	let stubbedProgram: SinonStubbedInstance<CliApiObject>;
	const program: CliApiObject = new Command() as CliApiObject;

	before(() => {
		stubbedProgram = new TestCliApiObject(program);
	});

	it('Calls the library API function once when a command is set', () => {
		new CLICommand(driveNameCommandDescription, stubbedProgram);
		expect(stubbedProgram.command.calledOnce).to.be.true;
		expect(stubbedProgram.action.calledOnce).to.be.true;
	});

	it('The library parses the given argv', () => {
		CLICommand.parse(stubbedProgram, driveNameArgv);
		expect(stubbedProgram.parse.calledOnce).to.be.true;
	});

	it('Assert required in conjunction parameters', () => {
		expect(function () {
			assertConjunctionParameters(commandDescriptorRequiredWallet, parsedOptionsMissingWallet);
		}).to.throw();
	});

	it('Assert forbidden in conjunction parameters', () => {
		expect(function () {
			assertConjunctionParameters(
				commandDescriptorForbiddenWalletFileAndSeedPhrase,
				parsedCommandOptionsBothSpecified
			);
		}).to.throw();
	});

	it('No colliding parameters', () => {
		const allCommandDescriptors = CLICommand.getAllCommandDescriptors();
		allCommandDescriptors.forEach((command) => {
			const parameters = command.parameters.map((param) => new Parameter(param));
			parameters.forEach((parameter_1, index) => {
				const allParametersExceptMe = parameters;
				allParametersExceptMe.splice(index);
				const collidingParameters = allParametersExceptMe.filter((parameter_2) => {
					const areAllowedInConjunction = !parameter_2.forbiddenParametersInConjunction.includes(
						parameter_1.name
					);
					if (areAllowedInConjunction) {
						return parameter_2.aliases.find((alias) => parameter_1.aliases.includes(alias));
					}
					return false;
				});
				// if (collidingParameters.length) {
				// 	debugger;
				// }
				expect(collidingParameters).to.be.empty;
			});
		});
	});
});
Example #3
Source File: update-record-factory.spec.ts    From adminjs-upload with MIT License 4 votes vote down vote up
describe('updateRecordFactory', () => {
  const request: ActionRequest = { method: 'post' } as ActionRequest
  let response: RecordActionResponse
  let actionContext: ActionContext

  let provider: BaseProvider
  let recordStub: SinonStubbedInstance<BaseRecord> & BaseRecord
  let uploadOptions: UploadOptionsWithDefault
  let updateRecord: After<RecordActionResponse>

  const resolvedS3Path = 'resolvedS3Path'
  const expectedKey = '1/some-name.pdf'
  const File: UploadedFile = {
    name: 'some-name.pdf',
    path: 'path/some-name.pdf',
    size: 111,
    type: 'txt',
  }

  beforeEach(() => {
    provider = stubProvider(resolvedS3Path)
    response = { record: { params: {
      name: 'some value',
    } } } as unknown as RecordActionResponse
    uploadOptions = {
      properties: {
        key: 's3Key',
        filePath: 'resolvedPath',
        file: 'file',
        filesToDelete: 'fileToDelete',
      },
      provider: {
        aws: { bucket: 'any' },
      } as UploadOptions['provider'] }
    recordStub = createStubInstance(BaseRecord, {
      id: sinon.stub<any, string>().returns('1'),
      isValid: sinon.stub<any, boolean>().returns(true),
      update: sinon.stub<any, Promise<BaseRecord>>().returnsThis(),
    })
    recordStub.params = {}
  })

  afterEach(() => {
    sinon.restore()
    sinon.reset()
  })

  it('does nothing when request is get', async () => {
    updateRecord = updateRecordFactory(uploadOptions, provider)

    const ret = await updateRecord(
      response as unknown as RecordActionResponse,
      { method: 'get', record: recordStub } as unknown as ActionRequest,
      {} as ActionContext,
    )
    expect(ret).to.deep.eq(response)
  })

  context('property.file is set in the context to single file', () => {
    beforeEach(() => {
      uploadOptions.properties.file = 'uploadedFile'
      uploadOptions.properties.bucket = 'bucketProp'
      uploadOptions.properties.size = 'sizeProp'
      uploadOptions.properties.mimeType = 'mimeTypeProp'
      uploadOptions.properties.filename = 'filenameProp'
      File.name = expectedKey
      actionContext = {
        record: recordStub as BaseRecord,
        [CONTEXT_NAMESPACE]: {
          [uploadOptions.properties.file]: [File],
        },
      } as unknown as ActionContext
      updateRecord = updateRecordFactory(uploadOptions, provider)
    })

    it('uploads file with adapter', async () => {
      await updateRecord(response, request, actionContext)

      expect(provider.upload).to.have.been.calledWith(File)
    })

    it('updates all fields in the record', async () => {
      await updateRecord(response, request, actionContext)

      expect(recordStub.update).to.have.been.calledWith(sinon.match({
        [uploadOptions.properties.key]: expectedKey,
        [uploadOptions.properties.bucket as string]: provider.bucket,
        [uploadOptions.properties.size as string]: File.size.toString(),
        [uploadOptions.properties.mimeType as string]: File.type,
        [uploadOptions.properties.filename as string]: File.name,
      }))
    })

    it('does not delete any old file if there were not file before', async () => {
      await updateRecord(response, request, actionContext)

      expect(provider.delete).not.to.have.been.called
    })

    it('removes old file when there was file before', async () => {
      const oldKey = 'some-old-key.txt'
      const oldBucket = 'oldBucket'
      recordStub.params[uploadOptions.properties.key] = oldKey
      recordStub.params[uploadOptions.properties.bucket as string] = oldBucket

      await updateRecord(response, request, actionContext)

      expect(provider.delete).to.have.been.calledWith(oldKey, oldBucket)
    })

    it('does not remove old file when it had the same key', async () => {
      recordStub.params[uploadOptions.properties.key] = expectedKey

      await updateRecord(response, request, actionContext)

      expect(provider.delete).not.to.have.been.called
    })

    it('removes old file when property.file is set to null', async () => {
      const storedBucket = 'bucketProp'
      recordStub.get.onCall(0).returns(storedBucket)
      recordStub.get.onCall(1).returns(expectedKey)
      actionContext[CONTEXT_NAMESPACE][uploadOptions.properties.file as string] = null

      await updateRecord(response, request, actionContext)

      expect(provider.upload).not.to.have.been.called

      expect(provider.delete).to.have.been.calledWith(expectedKey, storedBucket)

      expect(recordStub.update).to.have.been.calledWith(sinon.match({
        [uploadOptions.properties.key]: null,
        [uploadOptions.properties.bucket as string]: null,
        [uploadOptions.properties.size as string]: null,
        [uploadOptions.properties.mimeType as string]: null,
        [uploadOptions.properties.filename as string]: null,
      }))
    })
  })

  context('property.file is set in the context to multiple files', () => {
    const Files = [
      { ...File, name: 'file1.png' },
      { ...File, name: 'file2.png' },
      { ...File, name: 'file3.png' },
    ]

    beforeEach(() => {
      uploadOptions.multiple = true
      uploadOptions.properties.file = 'media.file'
      uploadOptions.properties.bucket = 'media.bucket'
      uploadOptions.properties.size = 'media.size'
      uploadOptions.properties.mimeType = 'media.mimeType'
      uploadOptions.properties.filename = 'media.filename'
      actionContext = {
        [CONTEXT_NAMESPACE]: {
          [uploadOptions.properties.file]: Files,
        },
        record: recordStub as BaseRecord,
      } as unknown as ActionContext
      updateRecord = updateRecordFactory(uploadOptions, provider)
    })

    it('uploads multiple files with adapter', async () => {
      await updateRecord(response, request, actionContext)

      expect(provider.upload).to.have.callCount(3)
    })

    it('updates all fields in the record', async () => {
      await updateRecord(response, request, actionContext)

      const values = (index) => ({
        [`${uploadOptions.properties.key}.${index}`]: `${recordStub.id()}/${Files[index].name}`,
        [`${uploadOptions.properties.bucket}.${index}` as string]: provider.bucket,
        [`${uploadOptions.properties.size}.${index}` as string]: Files[index].size,
        [`${uploadOptions.properties.mimeType}.${index}` as string]: Files[index].type,
        [`${uploadOptions.properties.filename}.${index}` as string]: Files[index].name,
      })

      expect(recordStub.update).to.have.been.calledWith(sinon.match({
        ...values(0),
        ...values(1),
        ...values(2),
      }))
    })
  })

  context('filesToDelete are set in the context to multiple files', () => {
    const fileIndexesToDelete = ['0', '2']
    const oldParams = {
      'media.key.0': 'key0',
      'media.key.1': 'key1',
      'media.key.2': 'key2',
      'media.bucket.0': 'bucket0',
      'media.bucket.1': 'bucket1',
      'media.bucket.2': 'bucket2',
      'media.type.0': 'mime0',
      'media.type.1': 'mime1',
      'media.type.2': 'mime2',
    }

    beforeEach(() => {
      uploadOptions.multiple = true
      uploadOptions.properties = {
        file: 'media.file',
        key: 'media.key',
        bucket: 'media.bucket',
        mimeType: 'media.type',
        filesToDelete: 'media.fileToDelete',
        filePath: 'media.filePath',
      }
      actionContext = {
        [CONTEXT_NAMESPACE]: {
          [uploadOptions.properties.filesToDelete]: fileIndexesToDelete,
        },
        record: new BaseRecord(oldParams, {} as BaseResource),
      } as unknown as ActionContext
      sinon.stub(BaseRecord.prototype, 'update')

      updateRecord = updateRecordFactory(uploadOptions, provider)
    })

    it('removes files from the database', async () => {
      await updateRecord(response, request, actionContext)

      expect(BaseRecord.prototype.update).to.have.been.calledWith({
        'media.key.0': 'key1',
        'media.bucket.0': 'bucket1',
        'media.type.0': 'mime1',
      })
    })

    it('removes files from the adapter store', async () => {
      await updateRecord(response, request, actionContext)

      expect(provider.delete).to.have.callCount(2)
      expect(provider.delete).to.have.been.calledWith('key0', 'bucket0')
      expect(provider.delete).to.have.been.calledWith('key2', 'bucket2')
    })
  })
})