Skip to content

Commit

Permalink
Add rule to detect echidna deliverer change (#1710)
Browse files Browse the repository at this point in the history
* add rule deliverer-change to echidna files

* add test for change of delivers

* fix test

* use w3c-api for previous id

* fix test

* fix test

* fix test

* remove unused var

* use moch for good document

* fix test

* Update lib/rules/echidna/deliverer-change.js

Co-authored-by: Denis Ah-Kang <[email protected]>

* Update lib/l10n-en_GB.js

Co-authored-by: Denis Ah-Kang <[email protected]>

* refine get previous IDs

* better regexp to getPreviousDelivererIDs

* address #1710 (comment)

---------

Co-authored-by: Denis Ah-Kang <[email protected]>
  • Loading branch information
jennyliang220 and deniak authored Mar 3, 2023
1 parent a7262b1 commit 25c225d
Show file tree
Hide file tree
Showing 19 changed files with 154 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"datedlink",
"dcterms",
"deniak",
"discr",
"DNOTE",
"doasync",
"doctypes",
Expand Down Expand Up @@ -81,6 +82,7 @@
"vcard",
"wcag",
"webidl",
"webperf",
"webrtc",
"Whut",
"wrongprocess"
Expand Down
2 changes: 1 addition & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ io.on('connection', socket => {
profile = await import(`./lib/profiles/${profilePath}`);
} catch (err) {
return socket.emit('exception', {
message: 'Profile does not exist.',
message: `Failed to get profile ${profilePath}.`,
});
}
const specberus = new Specberus(process.env.W3C_API_KEY);
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n-en_GB.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ export const messages = {
'The publication date of this document must be set to today (UTC).',
'echidna.todays-date.date-not-detected':
'Could not find a publication date in the document.',
'echidna.deliverer-change.deliverer-changed':
'The list of groups producing this document has changed since the previous version',
// Metadata:
'metadata.deliverers': false,
'metadata.dl.latest-not-found':
Expand Down
2 changes: 2 additions & 0 deletions lib/profiles/TR/Note/DNOTE-Echidna.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// TODO: merge all Echidna files.

import * as todaysDate from '../../../rules/echidna/todays-date.js';
import * as delivererChange from '../../../rules/echidna/deliverer-change.js';
import { insertAfter } from '../../profileUtil.js';
import { config as baseConfig, rules as baseRules } from './DNOTE.js';

Expand All @@ -9,4 +10,5 @@ export const config = baseConfig;

export const rules = insertAfter(baseRules, 'sotd.process-document', [
todaysDate,
delivererChange,
]);
2 changes: 2 additions & 0 deletions lib/profiles/TR/Note/NOTE-Echidna.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as todaysDate from '../../../rules/echidna/todays-date.js';
import * as delivererChange from '../../../rules/echidna/deliverer-change.js';
import { insertAfter } from '../../profileUtil.js';
import { config as baseConfig, rules as baseRules } from './NOTE.js';

Expand All @@ -7,4 +8,5 @@ export const config = baseConfig;

export const rules = insertAfter(baseRules, 'sotd.process-document', [
todaysDate,
delivererChange,
]);
2 changes: 2 additions & 0 deletions lib/profiles/TR/Recommendation/CR-Echidna.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as todaysDate from '../../../rules/echidna/todays-date.js';
import * as delivererChange from '../../../rules/echidna/deliverer-change.js';
import { insertAfter } from '../../profileUtil.js';
import { rules as baseRules } from './CR.js';

Expand All @@ -7,4 +8,5 @@ export { config } from './CR.js';

export const rules = insertAfter(baseRules, 'sotd.process-document', [
todaysDate,
delivererChange,
]);
2 changes: 2 additions & 0 deletions lib/profiles/TR/Recommendation/CRD-Echidna.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as todaysDate from '../../../rules/echidna/todays-date.js';
import * as delivererChange from '../../../rules/echidna/deliverer-change.js';
import { insertAfter } from '../../profileUtil.js';
import { rules as baseRules } from './CRD.js';

Expand All @@ -7,4 +8,5 @@ export const name = 'CRD-Echidna';

export const rules = insertAfter(baseRules, 'sotd.process-document', [
todaysDate,
delivererChange,
]);
2 changes: 2 additions & 0 deletions lib/profiles/TR/Recommendation/REC-Echidna.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as todaysDate from '../../../rules/echidna/todays-date.js';
import * as delivererChange from '../../../rules/echidna/deliverer-change.js';
import { insertAfter } from '../../profileUtil.js';
import { rules as baseRules } from './REC.js';

Expand All @@ -7,4 +8,5 @@ export const name = 'REC-Echidna';

export const rules = insertAfter(baseRules, 'sotd.process-document', [
todaysDate,
delivererChange,
]);
2 changes: 2 additions & 0 deletions lib/profiles/TR/Recommendation/WD-Echidna.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as todaysDate from '../../../rules/echidna/todays-date.js';
import * as delivererChange from '../../../rules/echidna/deliverer-change.js';
import { insertAfter } from '../../profileUtil.js';
import { rules as baseRules } from './WD.js';

Expand All @@ -7,4 +8,5 @@ export { config } from './WD.js';

export const rules = insertAfter(baseRules, 'sotd.process-document', [
todaysDate,
delivererChange,
]);
61 changes: 61 additions & 0 deletions lib/rules/echidna/deliverer-change.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import w3cApi from 'node-w3capi';

w3cApi.apiKey = process.env.W3C_API_KEY;

const self = {
name: 'echidna.deliverer-change',
section: 'metadata',
rule: 'delivererID',
};

export const { name } = self;

function getPreviousDelivererIDs(shortname, previousUrl) {
const date = previousUrl.match(/-(\d{8})\/$/);
if (date)
return new Promise(resolve => {
// e.g. https://api.w3.org/specifications/WGSL/versions/20230221/deliverers
w3cApi
.specification(shortname)
.version(date[1])
.deliverers()
.fetch({ embed: true }, (err, data) => {
resolve(data && data.map(obj => obj.id));
});
});
return new Promise(resolve => {
resolve([]);
});
}

/**
* @param sr
* @param done
*/
export async function check(sr, done) {
const previousVersion = await sr.getPreviousVersion(sr);
const shortname = await sr.getShortname(sr);

if (!previousVersion) {
return done();
}

const previousDelivererIDs = await getPreviousDelivererIDs(
shortname,
previousVersion
);
const delivererIDs = await sr.getDelivererIDs();

const delivererChanged =
delivererIDs.sort().toString() !==
previousDelivererIDs.sort().toString();

if (delivererChanged) {
sr.error(self, 'deliverer-changed', {
this: delivererIDs.sort().toString(),
previous: previousDelivererIDs.sort().toString(),
});
}

done();
}
6 changes: 6 additions & 0 deletions test/data/TR/TRBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ export const echidnaRules = {
errors: ['echidna.todays-date.wrong-date'],
},
],
'deliverer-change': [
{
data: 'delivererChanged',
errors: ['echidna.deliverer-change.deliverer-changed'],
},
],
};

export const draftStabilityRules = [
Expand Down
8 changes: 7 additions & 1 deletion test/doc-views/TR/Note/DNOTE-Echidna.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import DNOTE from './DNOTE.js';
import noteBase from './noteBase.js';

const { good: data } = DNOTE;
const { buildCommonViewData, buildDraftStability, buildTodaysDate } = noteBase;
const {
buildCommonViewData,
buildDraftStability,
buildTodaysDate,
buildDelivererChange,
} = noteBase;

const profile = 'DNOTE-Echidna';
const customData = {
Expand Down Expand Up @@ -44,4 +49,5 @@ export default {
},
'draft-stability': buildDraftStability(good),
'todays-date': buildTodaysDate(good),
'deliverer-change': buildDelivererChange(good),
};
3 changes: 2 additions & 1 deletion test/doc-views/TR/Note/NOTE-Echidna.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import NOTE from './NOTE.js';
import noteBase from './noteBase.js';

const { good: data } = NOTE;
const { buildCommonViewData, buildTodaysDate } = noteBase;
const { buildCommonViewData, buildTodaysDate, buildDelivererChange } = noteBase;

const profile = 'NOTE-Echidna';
const customData = {
Expand Down Expand Up @@ -34,4 +34,5 @@ export default {
},
},
'todays-date': buildTodaysDate(good),
'deliverer-change': buildDelivererChange(good),
};
2 changes: 2 additions & 0 deletions test/doc-views/TR/Recommendation/CR-Echidna.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
buildCommonViewData,
buildSecurityPrivacy,
buildTodaysDate,
buildDelivererChange,
} = recommendationBase;

const { good: data } = CR;
Expand Down Expand Up @@ -64,4 +65,5 @@ export default {
},
'todays-date': buildTodaysDate(good),
'security-privacy': buildSecurityPrivacy(good),
'deliverer-change': buildDelivererChange(good),
};
2 changes: 2 additions & 0 deletions test/doc-views/TR/Recommendation/CRD-Echidna.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
buildDraftStability,
buildSecurityPrivacy,
buildTodaysDate,
buildDelivererChange,
} = recommendationBase;

const profile = 'CRD-Echidna';
Expand Down Expand Up @@ -45,4 +46,5 @@ export default {
'draft-stability': buildDraftStability(good),
'todays-date': buildTodaysDate(good),
'security-privacy': buildSecurityPrivacy(good),
'deliverer-change': buildDelivererChange(good),
};
2 changes: 2 additions & 0 deletions test/doc-views/TR/Recommendation/WD-Echidna.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
buildDraftStability,
buildSecurityPrivacy,
buildTodaysDate,
buildDelivererChange,
} = recommendationBase;

const profile = 'WD-Echidna';
Expand Down Expand Up @@ -44,4 +45,5 @@ export default {
},
},
'todays-date': buildTodaysDate(good),
'deliverer-change': buildDelivererChange(good),
};
16 changes: 16 additions & 0 deletions test/doc-views/TR/TRBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,22 @@ export function buildTodaysDate(base) {
};
}

export function buildDelivererChange(base) {
return {
delivererChanged: {
...base,
config: {
...base.config,
isEchidna: true,
},
header: {
...base.header,
defaultDate: '',
},
},
};
}

export function buildDraftStability(base) {
return {
noDraftEither: {
Expand Down
23 changes: 23 additions & 0 deletions test/lib/nockData.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
export const nockData = {
deliverers: {
page: 1,
limit: 100,
pages: 1,
total: 1,
_links: {},
_embedded: {
deliverers: [
{
id: 32113,
name: 'Web Performance Working Group',
is_closed: false,
description:
'The mission of the Web Performance Working Group is to provide methods to measure aspects of application performance of user agent features and APIs.',
shortname: 'webperf',
discr: 'w3cgroup',
type: 'working group',
'start-date': '2010-08-18',
'end-date': '2023-02-28',
},
],
},
},
versions: {
page: 1,
pages: 1,
Expand Down
23 changes: 16 additions & 7 deletions test/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const DEFAULT_PORT = 8001;
const PORT = process.env.PORT || DEFAULT_PORT;
const ENDPOINT = `http://localhost:${PORT}`;

// These 3 environment variables are to reduce test documents.
// e.g. `RULE=copyright TYPE=noCopyright PROFILE=WD npm run test`
const testRule = process.env.RULE;
const testType = process.env.TYPE;
const testProfile = process.env.PROFILE;

/**
* Assert that metadata detected in a spec is equal to the expected values.
*
Expand Down Expand Up @@ -175,6 +181,7 @@ function buildHandler(test, mock, done) {
.head('/standards/history/hr-time')
.reply(200, 'HR Time history page');
const { versions } = nockData;

nock('https://api.w3.org', { allowUnmocked: true })
.get('/specifications/hr-time/versions')
.query({ embed: true })
Expand Down Expand Up @@ -264,9 +271,17 @@ describe('Making sure good documents pass Specberus...', () => {
Object.keys(testsGoodDoc).forEach(docProfile => {
// testsGoodDoc[docProfile].profile is used to distinguish multiple cases for same profile.
docProfile = testsGoodDoc[docProfile].profile || docProfile;
if (testProfile && testProfile !== docProfile) return;

const url = `${ENDPOINT}/${testsGoodDoc[docProfile].url}`;

it(`should pass for ${docProfile} doc with ${url}`, done => {
const { deliverers } = nockData;
nock('https://api.w3.org', { allowUnmocked: true })
.get(/\/specifications\/hr-time[-0-9a-zA-Z]*\/versions\/w*/)
.query({ embed: true })
.reply(200, deliverers);

const profilePath = allProfiles.find(p =>
p.endsWith(`/${docProfile}.js`)
);
Expand Down Expand Up @@ -316,12 +331,6 @@ describe('Making sure good documents pass Specberus...', () => {
});
});

// These 3 environment variables are to reduce test documents.
// e.g. `RULE=copyright TYPE=noCopyright PROFILE=WD npm run test`
const testRule = process.env.RULE;
const testType = process.env.TYPE;
const testProfile = process.env.PROFILE;

function checkRule(tests, options) {
const { docType, track, profile, category, rule } = options;

Expand All @@ -334,7 +343,7 @@ function checkRule(tests, options) {
if (
(testRule && rule !== testRule) ||
(testType && test.data !== testType) ||
(testProfile && profile !== 'CR')
(testProfile && profile !== testProfile)
)
return;

Expand Down

0 comments on commit 25c225d

Please sign in to comment.