Cleanup pinned items that are no longer for purchase

This commit is contained in:
Phillip Thelen
2024-04-08 15:41:51 +02:00
parent 4cdfefd92b
commit d7dc878b1c
5 changed files with 185 additions and 22 deletions

25
package-lock.json generated
View File

@@ -71,6 +71,7 @@
"remove-markdown": "^0.5.0", "remove-markdown": "^0.5.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"short-uuid": "^4.2.2", "short-uuid": "^4.2.2",
"sinon": "^15.2.0",
"stripe": "^12.18.0", "stripe": "^12.18.0",
"superagent": "^8.1.2", "superagent": "^8.1.2",
"universal-analytics": "^0.5.3", "universal-analytics": "^0.5.3",
@@ -94,7 +95,6 @@
"monk": "^7.3.4", "monk": "^7.3.4",
"require-again": "^2.0.0", "require-again": "^2.0.0",
"run-rs": "^0.7.7", "run-rs": "^0.7.7",
"sinon": "^15.2.0",
"sinon-chai": "^3.7.0", "sinon-chai": "^3.7.0",
"sinon-stub-promise": "^4.0.0" "sinon-stub-promise": "^4.0.0"
}, },
@@ -2682,7 +2682,6 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
"integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
"dev": true,
"dependencies": { "dependencies": {
"type-detect": "4.0.8" "type-detect": "4.0.8"
} }
@@ -2691,7 +2690,6 @@
"version": "10.3.0", "version": "10.3.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
"integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
"dev": true,
"dependencies": { "dependencies": {
"@sinonjs/commons": "^3.0.0" "@sinonjs/commons": "^3.0.0"
} }
@@ -2700,7 +2698,6 @@
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
"integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
"dev": true,
"dependencies": { "dependencies": {
"@sinonjs/commons": "^2.0.0", "@sinonjs/commons": "^2.0.0",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
@@ -2711,7 +2708,6 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
"integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
"dev": true,
"dependencies": { "dependencies": {
"type-detect": "4.0.8" "type-detect": "4.0.8"
} }
@@ -2719,8 +2715,7 @@
"node_modules/@sinonjs/text-encoding": { "node_modules/@sinonjs/text-encoding": {
"version": "0.7.2", "version": "0.7.2",
"resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz",
"integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ=="
"dev": true
}, },
"node_modules/@slack/types": { "node_modules/@slack/types": {
"version": "1.10.0", "version": "1.10.0",
@@ -12806,8 +12801,7 @@
"node_modules/just-extend": { "node_modules/just-extend": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
"integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw=="
"dev": true
}, },
"node_modules/jwa": { "node_modules/jwa": {
"version": "2.0.0", "version": "2.0.0",
@@ -13123,8 +13117,7 @@
"node_modules/lodash.get": { "node_modules/lodash.get": {
"version": "4.4.2", "version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
"dev": true
}, },
"node_modules/lodash.includes": { "node_modules/lodash.includes": {
"version": "4.3.0", "version": "4.3.0",
@@ -14567,7 +14560,6 @@
"version": "5.1.9", "version": "5.1.9",
"resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz",
"integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==",
"dev": true,
"dependencies": { "dependencies": {
"@sinonjs/commons": "^3.0.0", "@sinonjs/commons": "^3.0.0",
"@sinonjs/fake-timers": "^11.2.2", "@sinonjs/fake-timers": "^11.2.2",
@@ -14580,7 +14572,6 @@
"version": "11.2.2", "version": "11.2.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
"integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
"dev": true,
"dependencies": { "dependencies": {
"@sinonjs/commons": "^3.0.0" "@sinonjs/commons": "^3.0.0"
} }
@@ -14588,8 +14579,7 @@
"node_modules/nise/node_modules/path-to-regexp": { "node_modules/nise/node_modules/path-to-regexp": {
"version": "6.2.1", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
"dev": true
}, },
"node_modules/node-abi": { "node_modules/node-abi": {
"version": "2.30.1", "version": "2.30.1",
@@ -17604,7 +17594,6 @@
"resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz",
"integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==",
"deprecated": "16.1.1", "deprecated": "16.1.1",
"dev": true,
"dependencies": { "dependencies": {
"@sinonjs/commons": "^3.0.0", "@sinonjs/commons": "^3.0.0",
"@sinonjs/fake-timers": "^10.3.0", "@sinonjs/fake-timers": "^10.3.0",
@@ -17641,7 +17630,6 @@
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
"dev": true,
"engines": { "engines": {
"node": ">=0.3.1" "node": ">=0.3.1"
} }
@@ -17650,7 +17638,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@@ -17659,7 +17646,6 @@
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": { "dependencies": {
"has-flag": "^4.0.0" "has-flag": "^4.0.0"
}, },
@@ -19270,7 +19256,6 @@
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true,
"engines": { "engines": {
"node": ">=4" "node": ">=4"
} }

View File

@@ -0,0 +1,123 @@
import {
generateUser,
} from '../../helpers/common.helper';
import cleanupPinnedItems from '../../../website/common/script/libs/cleanupPinnedItems';
describe.only('cleanupPinnedItems', () => {
let user;
let testPinnedItems;
let clock;
beforeEach(() => {
user = generateUser();
clock = sinon.useFakeTimers(new Date('2024-04-08'));
testPinnedItems = [
{ type: 'armoire', path: 'armoire' },
{ type: 'potion', path: 'potion' },
{ type: 'background', path: 'backgrounds.backgrounds042020.heather_field' },
{ type: 'background', path: 'backgrounds.backgrounds042021.heather_field' },
{ type: 'premiumHatchingPotion', path: 'premiumHatchingPotions.Rainbow' },
{ type: 'premiumHatchingPotion', path: 'premiumHatchingPotions.StainedGlass' },
{ type: 'quests', path: 'quests.rat' },
{ type: 'quests', path: 'quests.spider' },
{ type: 'quests', path: 'quests.moon1' },
{ type: 'quests', path: 'quests.silver' },
{ type: 'marketGear', path: 'gear.flat.head_special_nye2021' },
{ type: 'gear', path: 'gear.flat.armor_special_spring2019Rogue' },
{ type: 'gear', path: 'gear.flat.armor_special_winter2021Rogue' },
{ type: 'mystery_set', path: 'mystery.201804' },
{ type: 'mystery_set', path: 'mystery.201506' },
{ type: 'bundles', path: 'bundles.farmFriends' },
{ type: 'bundles', path: 'bundles.birdBuddies' },
{ type: 'customization', path: 'skin.birdBuddies' },
];
});
afterEach(() => {
clock.restore();
});
it('always keeps armoire and potion', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'armoire')).to.exist;
expect(_.find(result, item => item.path === 'potion')).to.exist;
});
it('removes simple items that are no longer available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'backgrounds.backgrounds042021.heather_field')).to.not.exist;
expect(_.find(result, item => item.path === 'premiumHatchingPotions.Rainbow')).to.not.exist;
});
it('keeps simple items that are still available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'backgrounds.backgrounds042020.heather_field')).to.exist;
expect(_.find(result, item => item.path === 'premiumHatchingPotions.StainedGlass')).to.exist;
});
it('removes gear that is no longer available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'gear.flat.armor_special_winter2021Rogue')).to.not.exist;
});
it('keeps gear that is still available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'gear.flat.armor_special_spring2019Rogue')).to.exist;
});
it('keeps gear that is not seasonal', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'gear.flat.head_special_nye2021')).to.exist;
});
it('removes time traveler gear that is no longer available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'mystery.201506')).to.not.exist;
});
it('keeps time traveler gear that is still available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'mystery.201804')).to.exist;
});
it('removes quests that are no longer available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'quests.rat')).to.not.exist;
expect(_.find(result, item => item.path === 'quests.silver')).to.not.exist;
});
it('keeps quests that are still available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'quests.spider')).to.exist;
});
it('keeps quests that are not seasonal', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'quests.moon1')).to.exist;
});
it('removes bundles that are no longer available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'bundles.farmFriends')).to.not.exist;
});
it('keeps bundles that are still available', () => {
user.pinnedItems = testPinnedItems;
const result = cleanupPinnedItems(user);
expect(_.find(result, item => item.path === 'bundles.birdBuddies')).to.exist;
});
});

View File

@@ -835,7 +835,7 @@ function makeMatcherClass () {
}; };
} }
export function getScheduleMatchingGroup (type, date) { export function getAllScheduleMatchingGroups (date) {
const checkedDate = date || new Date(); const checkedDate = date || new Date();
if (cacheDate !== null && (getDay(checkedDate) !== getDay(cacheDate) if (cacheDate !== null && (getDay(checkedDate) !== getDay(cacheDate)
|| getMonth(checkedDate) !== getMonth(cacheDate))) { || getMonth(checkedDate) !== getMonth(cacheDate))) {
@@ -869,7 +869,7 @@ export function getScheduleMatchingGroup (type, date) {
}, },
}; };
} }
return cachedScheduleMatchers[type]; return matchingGroups[type];
} }
export function getCurrentGalaKey (date) { export function getCurrentGalaKey (date) {

View File

@@ -0,0 +1,50 @@
import getItemByPathAndType from './getItemByPathAndType';
import { getAllScheduleMatchingGroups } from '../content/constants/schedule';
const simpleSeasonalPins = [
'background',
'premiumHatchingPotion',
'mystery_set',
'bundles',
'seasonalQuest',
];
const detailSeasonalPins = [
'quests',
'gear',
];
export default function cleanupPinnedItems (user) {
const matchers = getAllScheduleMatchingGroups();
const items = user.pinnedItems
.filter(pinnedItem => {
const { type } = pinnedItem;
const key = pinnedItem.path.split('.').slice(-1)[0];
if (simpleSeasonalPins.indexOf(type) != -1) {
if (type === 'background') {
return matchers.backgrounds.match(pinnedItem.path.split('.')[1]);
} if (type === 'premiumHatchingPotion') {
return matchers.premiumHatchingPotions.match(key);
} if (type === 'mystery_set') {
return matchers.timeTravelers.match(key);
} if (type === 'seasonalQuest') {
return matchers.seasonalQuests.match(key);
}
return matchers[type].match(key);
} if (detailSeasonalPins.indexOf(type) != -1) {
const item = getItemByPathAndType(type, pinnedItem.path);
if (type === 'gear' && item.klass === 'special') {
return matchers.seasonalGear.match(item.set);
} if (type === 'quests' && item.category === 'pet') {
return matchers.petQuests.match(item.key);
} if (type === 'quests' && item.category === 'hatchingPotion') {
return matchers.hatchingPotionQuests.match(item.key);
}
return true;
}
return true;
});
return items;
}

View File

@@ -7,6 +7,7 @@ import common from '../../common';
import { preenUserHistory } from './preening'; import { preenUserHistory } from './preening';
import { sleep } from './sleep'; import { sleep } from './sleep';
import { revealMysteryItems } from './payments/subscriptions'; import { revealMysteryItems } from './payments/subscriptions';
import cleanupPinnedItems from '../../common/script/libs/cleanupPinnedItems';
const CRON_SAFE_MODE = nconf.get('CRON_SAFE_MODE') === 'true'; const CRON_SAFE_MODE = nconf.get('CRON_SAFE_MODE') === 'true';
const CRON_SEMI_SAFE_MODE = nconf.get('CRON_SEMI_SAFE_MODE') === 'true'; const CRON_SEMI_SAFE_MODE = nconf.get('CRON_SEMI_SAFE_MODE') === 'true';
@@ -499,6 +500,10 @@ export async function cron (options = {}) {
_.merge(progress, { down: 0, up: 0, collectedItems: 0 }); _.merge(progress, { down: 0, up: 0, collectedItems: 0 });
} }
if (user.pinnedItems && user.pinnedItems.length > 0) {
user.pinnedItems = cleanupPinnedItems(user);
}
// Send notification for changes in HP and MP. // Send notification for changes in HP and MP.
// First remove a possible previous cron notification because // First remove a possible previous cron notification because
// we don't want to flood the users with many cron notifications at once. // we don't want to flood the users with many cron notifications at once.