From 622238e2fde8575199bbe05098d8c6a2969bef6c Mon Sep 17 00:00:00 2001 From: Jerome Simeon Date: Tue, 30 Apr 2019 09:01:07 -0400 Subject: [PATCH] (feature) Add generateText from data to command line and testing (#349) * (feature) Add generateText from data to command line and testing Signed-off-by: Jerome Simeon * (fix) Add testing for CLI's generateText Signed-off-by: Jerome Simeon * (chore) Bump to Ergo 0.8.1 Signed-off-by: Jerome Simeon --- package-lock.json | 41 ++---- packages/cicero-cli/index.js | 32 +++++ packages/cicero-cli/lib/commands.js | 46 ++++++- packages/cicero-cli/test/cli.js | 121 +++++++++++++++++- .../data/latedeliveryandpenalty/.gitignore | 3 +- .../data/latedeliveryandpenalty/data.json | 1 + .../data/latedeliveryandpenalty/data_err.json | 1 + packages/cicero-core/package.json | 2 +- packages/cicero-engine/package.json | 4 +- packages/cicero-test/lib/steps.js | 11 ++ packages/cicero-test/package.json | 2 +- .../helloemit/test/helloemit_data.feature | 77 +++++++++++ .../latedeliveryandpenalty_data.feature | 85 ++++++++++++ 13 files changed, 390 insertions(+), 36 deletions(-) create mode 100644 packages/cicero-cli/test/data/latedeliveryandpenalty/data.json create mode 100644 packages/cicero-cli/test/data/latedeliveryandpenalty/data_err.json create mode 100644 packages/cicero-test/test/data/helloemit/test/helloemit_data.feature create mode 100644 packages/cicero-test/test/features/latedeliveryandpenalty_data.feature diff --git a/package-lock.json b/package-lock.json index c3e7557d8..6edeee86e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,51 +3,36 @@ "lockfileVersion": 1, "dependencies": { "@accordproject/ergo-compiler": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@accordproject/ergo-compiler/-/ergo-compiler-0.8.0.tgz", - "integrity": "sha512-3ZWKk7nzoKEWWX2NKNiEKlW/AudhZvuFlC1Y/sx21ZV4eWHkx72copHoRvPAduWPr7KbxyAQ3F31+fk70Po8bw==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@accordproject/ergo-compiler/-/ergo-compiler-0.8.1.tgz", + "integrity": "sha512-IE3jd7JpWoA1xNkuwk3MIODM4wTUfEdzM/a+vc+vo/0wamLXOthdMeZ3Pzftm77O1/ioEmm5yPwwVf44sWdJQQ==", "requires": { "composer-concerto": "0.70.2", - "debug": "^2.6.9", + "debug": "4.1.0", "fast-safe-stringify": "2.0.5", "jsome": "2.5.0", "moment-mini": "2.22.1", "winston": "^3.2.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } } }, "@accordproject/ergo-engine": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@accordproject/ergo-engine/-/ergo-engine-0.8.0.tgz", - "integrity": "sha512-8jndFeFJpOVrXzgizQTyTIYBxJMDf0tukQpIiTgFjCPsfJiClLVbrNkTWTY1T5xL2QKGjbWM9Vp26IORgHh9+g==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@accordproject/ergo-engine/-/ergo-engine-0.8.1.tgz", + "integrity": "sha512-4BWmoF7E6GTTPZszi2xKhM6PcrX2O9qg6HI/MouvPcH8WalZNamzt7EQuHRGVLePGYz8b6pBvTqq9xhqgifNIg==", "requires": { - "@accordproject/ergo-compiler": "0.8.0", + "@accordproject/ergo-compiler": "0.8.1", "composer-concerto": "0.70.2", "moment-mini": "2.22.1", "vm2": "3.5.0" } }, "@accordproject/ergo-test": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@accordproject/ergo-test/-/ergo-test-0.8.0.tgz", - "integrity": "sha512-PBYw4JDfhg+U+jHsMJrO72ME1NmzdGx1PP/ckoPsm97Y8eghgEt2Nc7RyCqqNYnOjaU38wthBBhh9cXWQjnLpg==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@accordproject/ergo-test/-/ergo-test-0.8.1.tgz", + "integrity": "sha512-4VQNGsyO9d19HqydWevNjZ1f92aLSXksje5imMuNwICIFMtr4AI+fc1mxrVO9B3qtcM3X3C6TvDCa+j1MztA9g==", "requires": { - "@accordproject/ergo-compiler": "0.8.0", - "@accordproject/ergo-engine": "0.8.0", + "@accordproject/ergo-compiler": "0.8.1", + "@accordproject/ergo-engine": "0.8.1", "chai": "4.2.0", "chai-as-promised": "7.1.1", "chai-things": "0.2.0", diff --git a/packages/cicero-cli/index.js b/packages/cicero-cli/index.js index 3d1c88ffc..d4380608a 100755 --- a/packages/cicero-cli/index.js +++ b/packages/cicero-cli/index.js @@ -56,6 +56,38 @@ require('yargs') return; } }) + .command('generateText', 'generate sample text from template data', (yargs) => { + yargs.option('template', { + describe: 'path to the directory with the template', + type: 'string' + }); + yargs.option('data', { + describe: 'path to the template data text', + type: 'string' + }); + yargs.option('out', { + describe: 'path to the output file', + type: 'string' + }); + }, (argv) => { + if (argv.verbose) { + Logger.info(`generate text from data ${argv.data} using a template ${argv.template}`); + } + + try { + argv = Commands.validateGenerateTextArgs(argv); + return Commands.generateText(argv.template, argv.data, argv.out) + .then((result) => { + Logger.info(result); + }) + .catch((err) => { + Logger.error(err.message); + }); + } catch (err){ + Logger.error(err.message); + return; + } + }) .command('archive', 'archive a template directory', (yargs) => { yargs.option('target', { describe: 'the target language of the archive', diff --git a/packages/cicero-cli/lib/commands.js b/packages/cicero-cli/lib/commands.js index b376759e6..fe52e07dc 100644 --- a/packages/cicero-cli/lib/commands.js +++ b/packages/cicero-cli/lib/commands.js @@ -150,7 +150,7 @@ class Commands { clause.parse(sampleText, currentTime); if (outPath) { Logger.info('Creating file: ' + outPath); - fs.writeFileSync(outPath, JSON.stringify(clause.getData())); + fs.writeFileSync(outPath, JSON.stringify(clause.getData(),null,2)); } return clause.getData(); }) @@ -159,6 +159,33 @@ class Commands { }); } + /** + * Generate a sample text from JSON data using a template + * + * @param {string} templatePath to the template path directory or file + * @param {string} dataPath to the data file + * @param {string} outPath to the contract file + * @returns {object} Promise to the result of parsing + */ + static generateText(templatePath, dataPath, outPath) { + let clause; + const dataJson = JSON.parse(fs.readFileSync(dataPath, 'utf8')); + + return Commands.loadTemplate(templatePath) + .then((template) => { + clause = new Clause(template); + clause.setData(dataJson); + if (outPath) { + Logger.info('Creating file: ' + outPath); + fs.writeFileSync(outPath, clause.generateText()); + } + return clause.generateText(); + }) + .catch((err) => { + Logger.error(err.message); + }); + } + /** * Set default params before we parse a sample text using a template * @@ -176,6 +203,23 @@ class Commands { return argv; } + /** + * Set default params before we generatet a sample text using a template + * + * @param {object} argv the inbound argument values object + * @returns {object} a modfied argument object + */ + static validateGenerateTextArgs(argv) { + argv = Commands.validateCommonArgs(argv); + argv = Commands.setDefaultFileArg(argv, 'data', 'data.json', ((argv, argDefaultName) => { return path.resolve(argv.template,argDefaultName); })); + + if(argv.verbose) { + Logger.info(`generate text from data ${argv.data} using a template ${argv.template}`); + } + + return argv; + } + /** * Initializes a sample text using a template * diff --git a/packages/cicero-cli/test/cli.js b/packages/cicero-cli/test/cli.js index 564642cb9..6b851e56a 100644 --- a/packages/cicero-cli/test/cli.js +++ b/packages/cicero-cli/test/cli.js @@ -33,9 +33,11 @@ describe('cicero-cli', () => { const templateJs = path.resolve(__dirname, 'data/latedeliveryandpenalty_js/'); const templateArchive = path.resolve(__dirname, 'data/latedeliveryandpenalty.cta'); const sample = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'sample.txt'); + const data = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'data.json'); const request = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'request.json'); const state = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'state.json'); - const contract = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'contract.json'); + const dataOut = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'data_out.json'); + const sampleOut = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'sample_out.txt'); const parseReponse = { '$class':'org.accordproject.latedeliveryandpenalty.TemplateModel', 'forceMajeure':true, @@ -53,8 +55,10 @@ describe('cicero-cli', () => { }, 'fractionalPart':'days' }; + const generateTextResponse = 'Late Delivery and Penalty. In case of delayed delivery except for Force Majeure cases, the Seller shall pay to the Buyer for every 9 days of delay penalty amounting to 7% of the total value of the Equipment whose delivery has been delayed. Any fractional part of a days is to be considered a full days. The total amount of penalty shall not however, exceed 2% of the total value of the Equipment involved in late delivery. If the delay is more than 2 weeks, the Buyer is entitled to terminate this Contract.'; const sampleErr = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'sample_err.txt'); + const dataErr = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'data_err.json'); const stateErr = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'state_err.json'); const requestErr = path.resolve(__dirname, 'data/latedeliveryandpenalty/', 'request_err.json'); @@ -79,12 +83,39 @@ describe('cicero-cli', () => { describe('#parsesave', async () => { it('should parse a clause using a template and save to a JSON file', async () => { - const result = await Commands.parse(template, sample, contract); + const result = await Commands.parse(template, sample, dataOut); delete result.clauseId; result.should.eql(parseReponse); }); }); + describe('#generateText', () => { + it('should generate the text for a clause using a template', async () => { + const result = await Commands.generateText(template, data, null); + delete result.clauseId; + result.should.eql(generateTextResponse); + }); + + it('should generate the text for a clause using a template archive', async () => { + const result = await Commands.generateText(templateArchive, data, null); + delete result.clauseId; + result.should.eql(generateTextResponse); + }); + + it('should fail generating the text for a clause using a template', async () => { + const result = await Commands.generateText(template, dataErr, null); + should.equal(result,undefined); + }); + }); + + describe('#generateTextsave', async () => { + it('should generate the text for a clause using a template and save to a JSON file', async () => { + const result = await Commands.generateText(template, data, sampleOut); + delete result.clauseId; + result.should.eql(generateTextResponse); + }); + }); + describe('#archive', async () => { it('should create a valid ergo archive', async () => { const archiveName = 'test.cta'; @@ -184,6 +215,92 @@ describe('cicero-cli', () => { }); }); + describe('#validateGenerateTextArgs', () => { + it('no args specified', () => { + process.chdir(path.resolve(__dirname, 'data/latedeliveryandpenalty/')); + const args = Commands.validateGenerateTextArgs({ + _: ['generateText'], + }); + args.template.should.match(/cicero-cli\/test\/data\/latedeliveryandpenalty$/); + args.data.should.match(/data.json$/); + }); + it('all args specified', () => { + process.chdir(path.resolve(__dirname, 'data/latedeliveryandpenalty/')); + const args = Commands.validateGenerateTextArgs({ + _: ['generateText'], + template: './', + data: 'data.json' + }); + args.template.should.match(/cicero-cli\/test\/data\/latedeliveryandpenalty$/); + args.data.should.match(/data.json$/); + }); + it('all args specified, parent folder', () => { + process.chdir(path.resolve(__dirname, 'data/')); + const args = Commands.validateGenerateTextArgs({ + _: ['generateText'], + template: 'latedeliveryandpenalty', + data: 'latedeliveryandpenalty/data.json' + }); + args.template.should.match(/cicero-cli\/test\/data\/latedeliveryandpenalty$/); + args.data.should.match(/data.json$/); + }); + it('all args specified, archive', () => { + process.chdir(path.resolve(__dirname, 'data/')); + const args = Commands.validateGenerateTextArgs({ + _: ['generateText'], + template: 'latedeliveryandpenalty.cta', + data: 'latedeliveryandpenalty/data.json' + }); + args.template.should.match(/cicero-cli\/test\/data\/latedeliveryandpenalty.cta$/); + args.data.should.match(/data.json$/); + }); + it('all args specified, parent folder, no sample', () => { + process.chdir(path.resolve(__dirname, 'data/')); + const args = Commands.validateGenerateTextArgs({ + _: ['generateText'], + template: 'latedeliveryandpenalty', + }); + args.template.should.match(/cicero-cli\/test\/data\/latedeliveryandpenalty$/); + args.data.should.match(/data.json$/); + }); + it('all args specified, child folder, no sample', () => { + process.chdir(path.resolve(__dirname, 'data/latedeliveryandpenalty/grammar')); + const args = Commands.validateGenerateTextArgs({ + _: ['generateText'], + template: '../', + }); + args.template.should.match(/cicero-cli\/test\/data\/latedeliveryandpenalty$/); + args.data.should.match(/data.json$/); + }); + it('no flags specified', () => { + const args = Commands.validateGenerateTextArgs({ + _: ['generateText', path.resolve(__dirname, 'data/latedeliveryandpenalty/')], + }); + args.template.should.match(/cicero-cli\/test\/data\/latedeliveryandpenalty$/); + args.data.should.match(/data.json$/); + }); + it('verbose flag specified', () => { + process.chdir(path.resolve(__dirname, 'data/latedeliveryandpenalty/')); + Commands.validateGenerateTextArgs({ + _: ['generateText'], + verbose: true + }); + }); + it('bad package.json', () => { + process.chdir(path.resolve(__dirname, 'data/')); + (() => Commands.validateGenerateTextArgs({ + _: ['generateText'], + })).should.throw(' not a valid cicero template. Make sure that package.json exists and that it has a cicero entry.'); + }); + it('bad data.json', () => { + process.chdir(path.resolve(__dirname, 'data/latedeliveryandpenalty/')); + (() => Commands.validateGenerateTextArgs({ + _: ['generateText'], + data: 'data_en.json' + })).should.throw('A data.json file is required. Try the --data flag or create a data.json in the root folder of your template.'); + }); + }); + describe('#init', () => { it('should initialize a clause using a template', async () => { const response = await Commands.init(template, sample); diff --git a/packages/cicero-cli/test/data/latedeliveryandpenalty/.gitignore b/packages/cicero-cli/test/data/latedeliveryandpenalty/.gitignore index e3223a286..79df74ed0 100644 --- a/packages/cicero-cli/test/data/latedeliveryandpenalty/.gitignore +++ b/packages/cicero-cli/test/data/latedeliveryandpenalty/.gitignore @@ -1 +1,2 @@ -contract.json \ No newline at end of file +data_out.json +sample_out.txt \ No newline at end of file diff --git a/packages/cicero-cli/test/data/latedeliveryandpenalty/data.json b/packages/cicero-cli/test/data/latedeliveryandpenalty/data.json new file mode 100644 index 000000000..98bc9d06a --- /dev/null +++ b/packages/cicero-cli/test/data/latedeliveryandpenalty/data.json @@ -0,0 +1 @@ +{"$class":"org.accordproject.latedeliveryandpenalty.TemplateModel","clauseId":"426d00d8-4293-4244-bd25-e66aa21eb0a4","forceMajeure":true,"penaltyDuration":{"$class":"org.accordproject.time.Duration","amount":9,"unit":"days"},"penaltyPercentage":7,"capPercentage":2,"termination":{"$class":"org.accordproject.time.Duration","amount":2,"unit":"weeks"},"fractionalPart":"days"} \ No newline at end of file diff --git a/packages/cicero-cli/test/data/latedeliveryandpenalty/data_err.json b/packages/cicero-cli/test/data/latedeliveryandpenalty/data_err.json new file mode 100644 index 000000000..b58dae88d --- /dev/null +++ b/packages/cicero-cli/test/data/latedeliveryandpenalty/data_err.json @@ -0,0 +1 @@ +{"$class":"org.accordproject.foo.TemplateModel","clauseId":"426d00d8-4293-4244-bd25-e66aa21eb0a4","forceMajeure":true,"penaltyDuration":{"$class":"org.accordproject.time.Duration","amount":9,"unit":"days"},"penaltyPercentage":7,"capPercentage":2,"termination":{"$class":"org.accordproject.time.Duration","amount":2,"unit":"weeks"},"fractionalPart":"days"} \ No newline at end of file diff --git a/packages/cicero-core/package.json b/packages/cicero-core/package.json index cebbc7fee..a68f6b81e 100644 --- a/packages/cicero-core/package.json +++ b/packages/cicero-core/package.json @@ -61,7 +61,7 @@ "webpack-cli": "^3.1.0" }, "dependencies": { - "@accordproject/ergo-compiler": "0.8.0", + "@accordproject/ergo-compiler": "0.8.1", "axios": "0.18.0", "composer-concerto": "0.70.2", "debug": "4.1.0", diff --git a/packages/cicero-engine/package.json b/packages/cicero-engine/package.json index 0eef58f0a..b8520ffe7 100644 --- a/packages/cicero-engine/package.json +++ b/packages/cicero-engine/package.json @@ -48,8 +48,8 @@ }, "dependencies": { "@accordproject/cicero-core": "0.12.0", - "@accordproject/ergo-compiler": "0.8.0", - "@accordproject/ergo-engine": "0.8.0", + "@accordproject/ergo-compiler": "0.8.1", + "@accordproject/ergo-engine": "0.8.1", "composer-concerto": "0.70.2", "moment-mini": "2.22.1" }, diff --git a/packages/cicero-test/lib/steps.js b/packages/cicero-test/lib/steps.js index 423ecc618..2850b5a77 100644 --- a/packages/cicero-test/lib/steps.js +++ b/packages/cicero-test/lib/steps.js @@ -107,6 +107,17 @@ Given('that the contract says', async function (contractText) { this.clause.parse(contractText); }); +Given('that the contract data is', async function (contractData) { + const dataJson = JSON.parse(contractData); + if (!this.clause) { + const templateDir = Path.resolve(Util.resolveRootDir(this.parameters),'.'); + const clause = await loadClause(templateDir); + this.request = clause.getTemplate().getMetadata().getRequest(); + this.clause = clause; + } + this.clause.setData(dataJson); +}); + Given('the default( sample) contract', async function () { if (!this.clause) { const templateDir = Path.resolve(Util.resolveRootDir(this.parameters),'.'); diff --git a/packages/cicero-test/package.json b/packages/cicero-test/package.json index c2954fc63..363da55d8 100644 --- a/packages/cicero-test/package.json +++ b/packages/cicero-test/package.json @@ -46,7 +46,7 @@ "dependencies": { "@accordproject/cicero-core": "0.12.0", "@accordproject/cicero-engine": "0.12.0", - "@accordproject/ergo-test": "0.8.0", + "@accordproject/ergo-test": "0.8.1", "chai": "4.2.0", "chai-things": "0.2.0", "cucumber": "^5.1.0" diff --git a/packages/cicero-test/test/data/helloemit/test/helloemit_data.feature b/packages/cicero-test/test/data/helloemit/test/helloemit_data.feature new file mode 100644 index 000000000..228e7b45a --- /dev/null +++ b/packages/cicero-test/test/data/helloemit/test/helloemit_data.feature @@ -0,0 +1,77 @@ +Feature: HelloWorld+Emit contract + This describe the expected behavior for the HelloWorld+Emit + + Background: + Given that the contract data is +""" +{ + "$class": "org.accordproject.helloemit.TemplateModel", + "clauseId": "402709ef-deac-4ea7-9341-b18a3bc3079e", + "name": "John Doe" +} +""" + + Scenario: The contract data should be set + Then the contract data should be +""" +{ + "$class": "org.accordproject.helloemit.TemplateModel", + "name": "John Doe" +} +""" + + Scenario: The contract should say hello + When it receives the request +""" +{ + "$class": "org.accordproject.helloemit.MyRequest", + "input": "Le Monde" +} +""" + Then it should respond with +""" +{ + "$class": "org.accordproject.helloemit.MyResponse", + "output": "Hello John Doe (Le Monde)" +} +""" + + Scenario: The contract should emit a greeting + When it receives the request +""" +{ + "$class": "org.accordproject.helloemit.MyRequest", + "input": "World" +} +""" + Then the following obligations should have been emitted +""" +[{ + "$class": "org.accordproject.helloemit.Greeting", + "message": "Voila!" +}] +""" + + Scenario: The contract should say hello and emit a greeting + When it receives the request +""" +{ + "$class": "org.accordproject.helloemit.MyRequest", + "input": "World" +} +""" + Then it should respond with +""" +{ + "$class": "org.accordproject.helloemit.MyResponse", + "output": "Hello John Doe (World)" +} +""" + And the following obligations should have been emitted +""" +[{ + "$class": "org.accordproject.helloemit.Greeting", + "message": "Voila!" +}] +""" + diff --git a/packages/cicero-test/test/features/latedeliveryandpenalty_data.feature b/packages/cicero-test/test/features/latedeliveryandpenalty_data.feature new file mode 100644 index 000000000..a458ffbae --- /dev/null +++ b/packages/cicero-test/test/features/latedeliveryandpenalty_data.feature @@ -0,0 +1,85 @@ +Feature: Late delivery contract + This describe the expected behavior for the Accord Project's late delivery and penalty contract + + Background: + Given the template in "data/latedeliveryandpenalty" + And that the contract data is +""" +{ + "$class": "org.accordproject.latedeliveryandpenalty.TemplateModel", + "clauseId": "db000e58-ef72-4d43-9777-67428249a731", + "forceMajeure": true, + "penaltyDuration": { + "$class": "org.accordproject.time.Duration", + "amount": 2, + "unit": "days" + }, + "penaltyPercentage": 10.5, + "capPercentage": 55, + "termination": { + "$class": "org.accordproject.time.Duration", + "amount": 15, + "unit": "days" + }, + "fractionalPart": "days" +} +""" + + Scenario: The contract should be in the default initial state + Then the initial state of the contract should be the default state + + Scenario: The contract should return the penalty amount but not allow the buyer to terminate + When the current time is "2019-01-11T16:34:00-05:00" + And it receives the request +""" +{ + "$class": "org.accordproject.latedeliveryandpenalty.LateDeliveryAndPenaltyRequest", + "forceMajeure": false, + "agreedDelivery": "2018-12-31 03:24:00Z", + "deliveredAt": null, + "goodsValue": 200.00 +} +""" + Then it should respond with +""" +{ + "$class": "org.accordproject.latedeliveryandpenalty.LateDeliveryAndPenaltyResponse", + "buyerMayTerminate": false, + "penalty": 110 +} +""" + + Scenario: The contract should return the penalty amount and allow the buyer to terminate + When the current time is "2019-01-11T16:34:00-05:00" + And it receives the request +""" +{ + "$class": "org.accordproject.latedeliveryandpenalty.LateDeliveryAndPenaltyRequest", + "forceMajeure": false, + "agreedDelivery": "2018-01-31 03:24:00Z", + "deliveredAt": null, + "goodsValue": 200.00 +} +""" + Then it should respond with +""" +{ + "$class": "org.accordproject.latedeliveryandpenalty.LateDeliveryAndPenaltyResponse", + "buyerMayTerminate": true, + "penalty": 110 +} +""" + + Scenario: The contract should not allow the late delivery clause to be triggered when the delivery is on time + When the current time is "2019-01-11T16:34:00-05:00" + And it receives the request +""" +{ + "$class": "org.accordproject.latedeliveryandpenalty.LateDeliveryAndPenaltyRequest", + "forceMajeure": false, + "agreedDelivery": "2019-01-31 03:24:00Z", + "deliveredAt": null, + "goodsValue": 200.00 +} +""" + Then it should reject the request with the error "[Ergo] Cannot exercise late delivery before delivery date"