From 8ca76bcf06f0751270c5c1bf47b9be559643121d Mon Sep 17 00:00:00 2001 From: ionous Date: Mon, 24 Jun 2024 19:07:25 -0700 Subject: [PATCH 1/2] update tests 1. ical feed was giving trailing line whitespace for words, but the tests were never updated 2. on my new machine i was getting EPIPE errors on some of the test runs; reading the file first seems to fix things? ( maybe just slows things down enough for pipes to be happy? ) --- app/test/ical_test.js | 16 +++++++-------- app/test/manage_test.js | 45 ++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/app/test/ical_test.js b/app/test/ical_test.js index c11fa24f..05341a16 100644 --- a/app/test/ical_test.js +++ b/app/test/ical_test.js @@ -160,8 +160,8 @@ String.raw`BEGIN:VEVENT`, String.raw`UID:event-201@shift2bikes.org`, String.raw`SUMMARY:ride 2 title`, String.raw`CONTACT:organizer`, -String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit`, -String.raw` ipsum duis elit.\ntime details\nEnds at location\;`, +String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit `, +String.raw` ipsum duis elit.\ntime details\nEnds at location\; `, String.raw` end.\nhttp://localhost:3080/calendar/event-201`, String.raw`LOCATION:location\, name.\n
\nlocation && details`, String.raw`STATUS:CONFIRMED`, @@ -176,8 +176,8 @@ String.raw`BEGIN:VEVENT`, String.raw`UID:event-202@shift2bikes.org`, String.raw`SUMMARY:ride 2 title`, String.raw`CONTACT:organizer`, -String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit`, -String.raw` ipsum duis elit.\ntime details\nEnds at location\;`, +String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit `, +String.raw` ipsum duis elit.\ntime details\nEnds at location\; `, String.raw` end.\nhttp://localhost:3080/calendar/event-202`, String.raw`LOCATION:location\, name.\n
\nlocation && details`, String.raw`STATUS:CONFIRMED`, @@ -219,8 +219,8 @@ String.raw`BEGIN:VEVENT`, String.raw`UID:event-201@shift2bikes.org`, String.raw`SUMMARY:ride 2 title`, String.raw`CONTACT:organizer`, -String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit`, -String.raw` ipsum duis elit.\ntime details\nEnds at location\;`, +String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit `, +String.raw` ipsum duis elit.\ntime details\nEnds at location\; `, String.raw` end.\nhttp://localhost:3080/calendar/event-201`, String.raw`LOCATION:location\, name.\n
\nlocation && details`, String.raw`STATUS:CANCELLED`, @@ -235,8 +235,8 @@ String.raw`BEGIN:VEVENT`, String.raw`UID:event-202@shift2bikes.org`, String.raw`SUMMARY:ride 2 title`, String.raw`CONTACT:organizer`, -String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit`, -String.raw` ipsum duis elit.\ntime details\nEnds at location\;`, +String.raw`DESCRIPTION:Quis ex cupidatat pariatur cillum pariatur esse id magna sit `, +String.raw` ipsum duis elit.\ntime details\nEnds at location\; `, String.raw` end.\nhttp://localhost:3080/calendar/event-202`, String.raw`LOCATION:location\, name.\n
\nlocation && details`, String.raw`STATUS:CONFIRMED`, diff --git a/app/test/manage_test.js b/app/test/manage_test.js index c5db2d8d..b6b846a4 100644 --- a/app/test/manage_test.js +++ b/app/test/manage_test.js @@ -11,8 +11,8 @@ // x add / cancel dates from a published event // x raw json ( curl ) vs body json ( forms ) // x multi-part form ( attach image ) - -const fsp = require('fs').promises; +const fs = require('fs'); +const fsp = fs.promises; const path = require('node:path'); const sinon = require('sinon'); const app = require("../app"); @@ -232,7 +232,7 @@ describe("managing events", () => { function getImageTarget(id, imageSource) { return path.join( config.image.dir, id + path.extname(imageSource) ); }; - async function postImage(id, imageSource, imageTarget) { + function postImage(id, imageSource, imageTarget) { // remove any image from earlier tests: return fsp.rm(imageTarget, {force:true}).then(_ => { // act as if we are a client who just created an event @@ -251,32 +251,35 @@ describe("managing events", () => { .field({ json: JSON.stringify(post) }) - .attach('file', imageSource, path.basename(imageSource)); + // the tests originally based a filepath here + // but that started generating EPIPE errors for reasons. + .attach('file', fs.readFileSync(imageSource), path.basename(imageSource)); }); }); }); } - it("attaches an image", async function(){ + it("attaches an image", function(){ const imageSource = path.join( config.image.dir, "bike.jpg" ); const imageTarget = getImageTarget(3, imageSource); - return postImage(3, imageSource, imageTarget).then(async function (res) { + return postImage(3, imageSource, imageTarget).then(function (res) { expect(res).to.have.status(200); // - const evt = await CalEvent.getByID(3); - // event creation is change 1, - // the image post is change 2, - // the event id is 3. - expect(evt.image, "image names should have a sequence number") - .to.equal("3-2.jpg"); - // - const imageTarget = getImageTarget(3, imageSource); - return fsp.stat(imageTarget); // rejects if it doesn't exist on disk. + CalEvent.getByID(3).then(evt => { + // event creation is change 1, + // the image post is change 2, + // the event id is 3. + expect(evt.image, "image names should have a sequence number") + .to.equal("3-2.jpg"); + // + const imageTarget = getImageTarget(3, imageSource); + return fsp.stat(imageTarget); // rejects if it doesn't exist on disk. + }); }); }); - it("fails too large", async function(){ + it("fails too large", function(){ const imageSource = path.join( config.image.dir, "bike-big.png" ); const imageTarget = getImageTarget(3, imageSource); - return postImage(3, imageSource, imageTarget).then(async function (res) { + return postImage(3, imageSource, imageTarget).then(function (res) { testData.expectError(expect, res, 'image'); return fsp.stat(imageTarget) .then(_ => { @@ -287,10 +290,10 @@ describe("managing events", () => { }); }); }); - it("fails bad format", async function(){ + it("fails bad format", function(){ const imageSource = path.join( config.image.dir, "bike-bad.tiff" ); const imageTarget = getImageTarget(3, imageSource); - return postImage(3, imageSource, imageTarget).then(async function (res) { + return postImage(3, imageSource, imageTarget).then(function (res) { testData.expectError(expect, res, 'image'); return fsp.stat(imageTarget) .then(_ => { @@ -311,8 +314,8 @@ describe("managing events", () => { .field({ json: JSON.stringify(eventData) }) - .attach('file', imageSource, path.basename(imageSource)) - .then(function (res) { + .attach('file', fs.readFileSync(imageSource), path.basename(imageSource)) + .then(async function (res) { expect(res).to.have.status(400); expect(res.body.error.fields).to.have.key('image'); }); From 650aaf4bbcbaa483e0020be45339f2e2ef00fedd Mon Sep 17 00:00:00 2001 From: ionous Date: Mon, 24 Jun 2024 19:59:44 -0700 Subject: [PATCH 2/2] add option to hide print calendar - .Site.Params.pedalp.enablePrintCal can be toggled int the config.toml - edit.html hides the print fields in that case - the validator doesn't write the fields into the "values" object unless "tinytitle" is in the input data, that way -- in calEvent.js updateFromJSON() the `Object.assign()` won't overwrite the existing values --- app/models/calEventValidator.js | 22 ++++++++++++++----- site/config.toml | 5 +++++ .../layouts/partials/cal/edit.html | 5 ++--- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/app/models/calEventValidator.js b/app/models/calEventValidator.js index da8a8b0d..23e23095 100644 --- a/app/models/calEventValidator.js +++ b/app/models/calEventValidator.js @@ -28,6 +28,9 @@ function makeValidator(input, errors) { return ((input[field] ?? '') + '').trim(); } return { + hasValue(field) { + return field in input; + }, requireString(field, msg) { const str = getString(field); if (validator.isEmpty(str)) { @@ -206,17 +209,24 @@ function validateEvent(input) { weburl: v.nullString('weburl'), // fix? validate this is a url> webname: v.nullString('webname'), audience: v.nullString('audience'), - tinytitle: v.mungeTinyTitle(title), - printdescr: v.nullString('printdescr'), dates: v.nullString('datestring'), // string field 'dates' needed for legacy admin calendar datestype: v.optionalChar('datestype', DatesType.OneDay), area: v.optionalChar('area', Area.Portland), - printemail: v.optionalFlag('printemail'), - printphone: v.optionalFlag('printphone'), - printweburl: v.optionalFlag('printweburl'), - printcontact: v.optionalFlag('printcontact'), safetyplan: v.optionalFlag('safetyplan'), }; + // print calendar data: + // if the tinytitle exists, assume the rest are valid too + // ( otherwise, we'll keep them however they were ) + if (v.hasValue('tinytitle')) { + Object.assign(values, { + tinytitle: v.mungeTinyTitle(title), + printdescr: v.nullString('printdescr'), + printemail: v.optionalFlag('printemail'), + printphone: v.optionalFlag('printphone'), + printweburl: v.optionalFlag('printweburl'), + printcontact: v.optionalFlag('printcontact'), + }); + }; const statusList = v.validateStatus(input.datestatuses); return { id: input.id, diff --git a/site/config.toml b/site/config.toml index 9ec36f85..2f69a7f8 100644 --- a/site/config.toml +++ b/site/config.toml @@ -86,6 +86,11 @@ disableKinds = ["taxonomy", "term"] logo = "images/shift-logo-large.jpg" verificationURL = "https://pdx.social/@shift2bikes" +# Pedalpalooza specific config +[params.pedalp] + # can be enabled between March-June during Pedalpalooza when these fields are required + enablePrintCal = false + # Main page image carousel [params.carousel] enable = true diff --git a/site/themes/s2b_hugo_theme/layouts/partials/cal/edit.html b/site/themes/s2b_hugo_theme/layouts/partials/cal/edit.html index d94012e2..f929e851 100644 --- a/site/themes/s2b_hugo_theme/layouts/partials/cal/edit.html +++ b/site/themes/s2b_hugo_theme/layouts/partials/cal/edit.html @@ -376,8 +376,7 @@

- - +{{ if .Site.Params.pedalp.enablePrintCal }}

@@ -438,7 +437,7 @@

- +{{ end }}{{/* print cal */}}