Skip to content

Commit

Permalink
Added Mex rice
Browse files Browse the repository at this point in the history
  • Loading branch information
afoeder committed Aug 5, 2024
1 parent 600b6bd commit a5adf85
Show file tree
Hide file tree
Showing 12 changed files with 3,903 additions and 428 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ permissions:
env:
INSTANCE: 'Writerside/ac'
ARTIFACT: 'webHelpAC2-all.zip'
DOCKER_VERSION: '241.16003'
DOCKER_VERSION: '241.18775'

jobs:
build:
Expand Down
3 changes: 2 additions & 1 deletion .grazie.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ extends: substitution
message: "Use the unicode counterpart '%s' instead of '%s' for this vulgar fraction"
level: warning
swap:
'1/2': '½'
'1/8': ''
'1/3': ''
'1/4': '¼'
'1/2': '½'
'2/3': ''
'3/4': '¾'
'1/10': ''
1 change: 1 addition & 0 deletions Writerside/ac.tree
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<toc-element topic="kenjis-streamlined-meatloaf.md"/>
<toc-element topic="mapo-tofu.md"/>
<toc-element topic="Mexican-black-beans.md"/>
<toc-element topic="Mexican-rice.md"/>
<toc-element topic="mole-negro.md"/>
<toc-element topic="Quarkkuchen.md"/>
<toc-element topic="rösti.md"/>
Expand Down
24 changes: 24 additions & 0 deletions Writerside/topics/recipes/Mexican-rice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
tags: mexican
---

# Mexican Rice

Inspo src: [ArnieTex' video](https://www.youtube.com/watch?v=7kSiLTnKw0I)

## Ingredients
- 1 tbsp oil
- ¾ cups rice
- 1 tsp garlic powder
- 1 tsp onion powder
- 1 pinch of (Mexican) Orégano
- ½ tsp ground cumin
- 1 tsp salt
- ⅓ cup tomato sauce
- 2 cups warm chicken broth

## Directions

1. Toast rice in some oil in a cast iron pan or a wide Dutch oven
2. Add in the tomato sauce, spices, simmer for 1–2′, then broth.
3. Add lid and keep lid on until finished. Don’t peek!
6 changes: 5 additions & 1 deletion amex-dining-credit/build-places-data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// handy command line infos: https://nodejs.org/en/learn/command-line/output-to-the-command-line-using-nodejs

import {PlaceRepository} from "./modules/place-repository.mjs";
import {GooglePlacesGeocoder} from "./modules/google-places-geocoder.mjs";

import merchantsData from "./amex-merchants.json" with { type: "json" };
import fs from "node:fs";
Expand All @@ -15,7 +16,10 @@ fs.writeFile(
JSON.stringify(
placeRepository
.findAll()
.map(place => place.toJson()),
.map(place => {
place.geocode(GooglePlacesGeocoder);
return place.toJson();
}),
null,
2),
error => error && console.error(error));
Expand Down
6 changes: 6 additions & 0 deletions amex-dining-credit/modules/google-places-geocoder.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class GooglePlacesGeocoder {

static todoFindLocation() {
return {};
}
}
8 changes: 4 additions & 4 deletions amex-dining-credit/modules/place-repository.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ export class PlaceRepository {
Object.entries(countriesMerchantsData).forEach(countryMerchantsData => {
const [countryCode, merchantsData] = countryMerchantsData;

places.push(...this.fromAmexMerchantsData(merchantsData, countryCode));
places.push(...this.#fromAmexMerchantsData(merchantsData, countryCode));
});
return new PlaceRepository(places);
}

static fromAmexMerchantsData(merchantsData, countryCode) {
static #fromAmexMerchantsData(merchantsData, countryCode) {
return merchantsData.flatMap(merchantData => {
if (merchantData.isMerchantGroup) {
// this happens when there is a "merchantGroup";
// like Gordon Ramsey etc. Those have a sub node in ".merchants"
// that again look like the merchants on the first level.
// We have to make a recursion here (yay), like:
console.log("Merchant group!", merchantData.name);
return this.fromAmexMerchantsData(merchantData.merchants, countryCode);
console.log(`Having a Merchant group in ${countryCode}:`, merchantData.name);
return this.#fromAmexMerchantsData(merchantData.merchants, countryCode);
}
return Place.fromAmexMerchantData(merchantData, countryCode);
});
Expand Down
102 changes: 102 additions & 0 deletions amex-dining-credit/modules/place-repository.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import {PlaceRepository} from "./place-repository.mjs";

const merchantGroupData = {"EN": [{
"id": "foo-bar-baz-4242-844221",
"name": "Some Merchant Group",
"address": null,
"postcode": null,
"businessData": {
"isHalal": false,
"isInHotel": false,
"isNew": false
},
"onlineOnly": false,
"translations": {
"en": {
"name": "Some Merchant Group"
}
},
"city": null,
"cuisine": null,
"isMerchantGroup": true,
"merchants": [
{
"id": "aa-bb-cc-dd",
"name": "Le Name",
"address": "Le Address",
"postcode": "L3 P05tc0d3",
"businessData": {
"website": "https://example.org/le-name",
"phone": "0555 888",
"isNew": false,
"isHalal": false,
"isInHotel": false,
"additionalComments": "",
"resyEnabled": false,
"resyApiKey": "",
"resyVenueId": ""
},
"onlineOnly": false,
"translations": {
"en": {
"name": "The Name",
"address": "The Address",
"postcode": "P05tc0d3"
}
},
"city": {
"id": "aa-88-33-cc",
"title": "Fancytown",
"translations": {
"en": {
"title": "Fancytown"
},
"zh_tw": {
"title": "Haiyaaa"
}
}
},
"cuisine": {
"id": "9933-22",
"title": "Lecker Schmecker",
"translations": {
"en": {
"title": "Yum & Nom"
},
"zh_tw": {
"title": "Fuiyoooo"
}
}
},
"isMerchantGroup": false,
"merchants": [],
"showMerchant": true,
"allMerchantsNew": true,
"googleMapsUrl": "https://www.example.org/location",
"takeoutAvailable": null,
"openingSoon": false,
"isInMerchantGroup": true,
"isHalal": false
}
],
"showMerchant": true,
"allMerchantsNew": false,
"googleMapsUrl": null,
"takeoutAvailable": null,
"openingSoon": false,
"isInMerchantGroup": false,
"isHalal": false
}]};

test('PlaceRepository can be instantiated from Amex country merchant data with merchant groups', () => {
const placeRepository =
PlaceRepository.fromAmexCountriesMerchantsData(merchantGroupData);
expect(placeRepository.findAll()).toHaveLength(1);
});

test('PlaceRepository findByCountry finds by correct country', () => {
const placeRepository =
PlaceRepository.fromAmexCountriesMerchantsData(merchantGroupData);
expect(placeRepository.findByCountry("EN")).toHaveLength(1);
expect(placeRepository.findByCountry("XY")).toHaveLength(0);
});
24 changes: 19 additions & 5 deletions amex-dining-credit/modules/place.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export class Place {
#zip
#city
#amexId
#assumedLocation = null
#location = null
#googleMapsUrl
#countryCode;

Expand All @@ -22,18 +22,32 @@ export class Place {
return this.#countryCode === countryCode
}

/**
*
* @param {GooglePlacesGeocoder|MockGeocoder} geocoder
*/
geocode(geocoder) {
if (this.#location) return;

const result = geocoder.todoFindLocation()
this.#location = { lat: result.lat, lon: result.lon, type:"geocoded" }
}

#setGoogleMapsUrl(googleMapsUrl) {
if (!googleMapsUrl) {
return;
}
this.#googleMapsUrl = googleMapsUrl

this.#assumedLocation =
this.#location =
googleMapsUrl
.match(/@(?<lat>-?\d+(?:\.\d+)?),(?<lon>-?\d+(?:\.\d+)?)/)
?.groups ?? null;
if (this.#assumedLocation?.lat) this.#assumedLocation.lat = parseFloat(this.#assumedLocation.lat);
if (this.#assumedLocation?.lon) this.#assumedLocation.lon = parseFloat(this.#assumedLocation.lon);
if (this.#location) {
this.#location.type = "assumed";
this.#location.lat = parseFloat(this.#location.lat);
this.#location.lon = parseFloat(this.#location.lon);
}
}

toJson() {
Expand All @@ -43,7 +57,7 @@ export class Place {
zip: this.#zip,
city: this.#city,
amexId: this.#amexId,
assumedLocation: this.#assumedLocation,
location: this.#location,
googleMapsUrl: this.#googleMapsUrl,
countryCode: this.#countryCode,
}
Expand Down
66 changes: 66 additions & 0 deletions amex-dining-credit/modules/place.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { jest } from '@jest/globals';

import {Place} from "./place.mjs";

const dummyMerchantData = {
"id": "abcde",
"name": "Some Place",
"address": "An Address",
"postcode": "P05TC0D3",
"city": {
"title": "Le City",
},
"googleMapsUrl": "https://Some.url/@48.7292928,9.1204729,foo",
};

test('Place can be instantiated from Amex data', () => {
const place =
Place.fromAmexMerchantData(dummyMerchantData, "DE");
expect(place).toBeInstanceOf(Place);
});

test('Is in country works correctly', () => {
const countryCode = "DE";
const place =
Place.fromAmexMerchantData(dummyMerchantData, countryCode);
expect(place.isInCountry(countryCode)).toBeTruthy();
expect(place.isInCountry("whatever")).toBeFalsy();
})

test('JSON is correctly rendered', () => {
const place =
Place.fromAmexMerchantData(dummyMerchantData, "DE");
expect(place.toJson()).toEqual({
name: "Some Place",
address: "An Address",
zip: "P05TC0D3",
city: "Le City",
amexId: "abcde",
location: {lat: 48.7292928, lon: 9.1204729, type: "assumed" },
googleMapsUrl: "https://Some.url/@48.7292928,9.1204729,foo",
countryCode: "DE"
})
});

class MockGeocoder {
static todoFindLocation = jest.fn(() => {return {lat: 42, lon: 42}})
}

test('Place abstains from geocoding when location is present', () => {
const place =
Place.fromAmexMerchantData(dummyMerchantData, "DE");
place.geocode(MockGeocoder);
expect(MockGeocoder.todoFindLocation).toHaveBeenCalledTimes(0);
expect(place.toJson()).toMatchObject({ location: {lat: 48.7292928, lon: 9.1204729, type:"assumed"} })
});

test('Place does geocoding when no assumed location is present (from google url)', () => {
const dummyMerchantDataWithoutLocationHint = dummyMerchantData;
delete dummyMerchantDataWithoutLocationHint.googleMapsUrl;

const place =
Place.fromAmexMerchantData(dummyMerchantDataWithoutLocationHint, "DE");
place.geocode(MockGeocoder);
expect(MockGeocoder.todoFindLocation).toHaveBeenCalledTimes(1);
expect(place.toJson()).toMatchObject({ location: {lat: 42, lon: 42, type:"geocoded"} })
});
Loading

0 comments on commit a5adf85

Please sign in to comment.