forked from MapComplete/MapComplete
Add tests for wikimedia comons edge cases
This commit is contained in:
parent
5628be3632
commit
b5d2b99ced
5 changed files with 118 additions and 17 deletions
|
@ -16,7 +16,11 @@ export default class AllImageProviders {
|
||||||
Mapillary.singleton,
|
Mapillary.singleton,
|
||||||
WikidataImageProvider.singleton,
|
WikidataImageProvider.singleton,
|
||||||
WikimediaImageProvider.singleton,
|
WikimediaImageProvider.singleton,
|
||||||
new GenericImageProvider([].concat(...Imgur.defaultValuePrefix, WikimediaImageProvider.commonsPrefix, ...Mapillary.valuePrefixes))]
|
new GenericImageProvider(
|
||||||
|
[].concat(...Imgur.defaultValuePrefix, ...WikimediaImageProvider.commonsPrefixes, ...Mapillary.valuePrefixes)
|
||||||
|
)
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
private static _cache: Map<string, UIEventSource<ProvidedImage[]>> = new Map<string, UIEventSource<ProvidedImage[]>>()
|
private static _cache: Map<string, UIEventSource<ProvidedImage[]>> = new Map<string, UIEventSource<ProvidedImage[]>>()
|
||||||
|
|
|
@ -15,7 +15,7 @@ export class WikimediaImageProvider extends ImageProvider {
|
||||||
private readonly commons_key = "wikimedia_commons"
|
private readonly commons_key = "wikimedia_commons"
|
||||||
public readonly defaultKeyPrefixes = [this.commons_key,"image"]
|
public readonly defaultKeyPrefixes = [this.commons_key,"image"]
|
||||||
public static readonly singleton = new WikimediaImageProvider();
|
public static readonly singleton = new WikimediaImageProvider();
|
||||||
public static readonly commonsPrefix = "https://commons.wikimedia.org/wiki/"
|
public static readonly commonsPrefixes = ["https://commons.wikimedia.org/wiki/", "https://upload.wikimedia.org", "File:"]
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -89,22 +89,40 @@ export class WikimediaImageProvider extends ImageProvider {
|
||||||
}
|
}
|
||||||
return {url: this.PrepareUrl(image), key: undefined, provider: this}
|
return {url: this.PrepareUrl(image), key: undefined, provider: this}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private startsWithCommonsPrefix(value: string){
|
||||||
|
return WikimediaImageProvider.commonsPrefixes.some(prefix => value.startsWith(prefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeCommonsPrefix(value: string){
|
||||||
|
if(value.startsWith("https://upload.wikimedia.org/")){
|
||||||
|
value = value.substring(value.lastIndexOf("/") + 1)
|
||||||
|
value = decodeURIComponent(value)
|
||||||
|
if(!value.startsWith("File:")){
|
||||||
|
value = "File:"+value
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const prefix of WikimediaImageProvider.commonsPrefixes) {
|
||||||
|
if(value.startsWith(prefix)){
|
||||||
|
let part = value.substr(prefix.length)
|
||||||
|
if(prefix.startsWith("http")){
|
||||||
|
part = decodeURIComponent(part)
|
||||||
|
}
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
public async ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]> {
|
public async ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]> {
|
||||||
if(key !== undefined && key !== this.commons_key && !value.startsWith(WikimediaImageProvider.commonsPrefix)){
|
const hasCommonsPrefix = this.startsWithCommonsPrefix(value)
|
||||||
|
if(key !== undefined && key !== this.commons_key && !hasCommonsPrefix){
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.startsWith(WikimediaImageProvider.commonsPrefix)) {
|
value = this.removeCommonsPrefix(value)
|
||||||
value = value.substring(WikimediaImageProvider.commonsPrefix.length)
|
|
||||||
} else if (value.startsWith("https://upload.wikimedia.org")) {
|
|
||||||
const result: ProvidedImage = {
|
|
||||||
key: undefined,
|
|
||||||
url: value,
|
|
||||||
provider: this
|
|
||||||
}
|
|
||||||
return [Promise.resolve(result)]
|
|
||||||
}
|
|
||||||
if (value.startsWith("Category:")) {
|
if (value.startsWith("Category:")) {
|
||||||
const urls = await Wikimedia.GetCategoryContents(value)
|
const urls = await Wikimedia.GetCategoryContents(value)
|
||||||
return urls.filter(url => url.startsWith("File:")).map(image => this.UrlForImage(image))
|
return urls.filter(url => url.startsWith("File:")).map(image => this.UrlForImage(image))
|
||||||
|
|
68
test/ImageProvider.spec.ts
Normal file
68
test/ImageProvider.spec.ts
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import T from "./TestHelper";
|
||||||
|
import AllImageProviders from "../Logic/ImageProviders/AllImageProviders";
|
||||||
|
import {UIEventSource} from "../Logic/UIEventSource";
|
||||||
|
|
||||||
|
export default class ImageProviderSpec extends T {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super("ImageProvider", [
|
||||||
|
["Search images", () => {
|
||||||
|
|
||||||
|
let i = 0
|
||||||
|
function expects(url, tags, providerName = undefined) {
|
||||||
|
tags.id = "test/"+i
|
||||||
|
i++
|
||||||
|
AllImageProviders.LoadImagesFor(new UIEventSource(tags)).addCallbackD(images => {
|
||||||
|
console.log("ImageProvider test", tags.id, "for", tags)
|
||||||
|
const img = images[0]
|
||||||
|
if(img === undefined){
|
||||||
|
throw "No image found"
|
||||||
|
}
|
||||||
|
T.equals(url, img.url, tags.id)
|
||||||
|
if(providerName){
|
||||||
|
T.equals(img.provider.constructor.name, providerName)
|
||||||
|
}
|
||||||
|
console.log("OK")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const muntpoort_expected = "https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABr%C3%BCgge-Muntpoort_6-29510-58192.jpg?width=500&height=400"
|
||||||
|
expects(
|
||||||
|
muntpoort_expected,
|
||||||
|
{ "wikimedia_commons":"File:Brügge-Muntpoort_6-29510-58192.jpg"
|
||||||
|
} , "WikimediaImageProvider")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
expects(muntpoort_expected,
|
||||||
|
{ "wikimedia_commons":"https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg"
|
||||||
|
} , "WikimediaImageProvider")
|
||||||
|
|
||||||
|
expects(muntpoort_expected , {
|
||||||
|
"image":"https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg"
|
||||||
|
} , "WikimediaImageProvider")
|
||||||
|
|
||||||
|
|
||||||
|
expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400" , {
|
||||||
|
"image":"File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg"
|
||||||
|
} , "WikimediaImageProvider")
|
||||||
|
|
||||||
|
expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400" , {
|
||||||
|
"wikimedia_commons":"File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg"
|
||||||
|
} , "WikimediaImageProvider")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABrugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg?width=500&height=400",{
|
||||||
|
image:"File:Brugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg"
|
||||||
|
}, "WikimediaImageProvider")
|
||||||
|
|
||||||
|
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import SplitActionSpec from "./SplitAction.spec";
|
||||||
import {Utils} from "../Utils";
|
import {Utils} from "../Utils";
|
||||||
import TileFreshnessCalculatorSpec from "./TileFreshnessCalculator.spec";
|
import TileFreshnessCalculatorSpec from "./TileFreshnessCalculator.spec";
|
||||||
import WikidataSpecTest from "./Wikidata.spec.test";
|
import WikidataSpecTest from "./Wikidata.spec.test";
|
||||||
|
import ImageProviderSpec from "./ImageProvider.spec";
|
||||||
|
|
||||||
|
|
||||||
ScriptUtils.fixUtils()
|
ScriptUtils.fixUtils()
|
||||||
|
@ -25,7 +26,8 @@ const allTests = [
|
||||||
new RelationSplitHandlerSpec(),
|
new RelationSplitHandlerSpec(),
|
||||||
new SplitActionSpec(),
|
new SplitActionSpec(),
|
||||||
new TileFreshnessCalculatorSpec(),
|
new TileFreshnessCalculatorSpec(),
|
||||||
new WikidataSpecTest()
|
new WikidataSpecTest(),
|
||||||
|
new ImageProviderSpec()
|
||||||
]
|
]
|
||||||
|
|
||||||
Utils.externalDownloadFunction = async (url) => {
|
Utils.externalDownloadFunction = async (url) => {
|
||||||
|
@ -44,16 +46,17 @@ args = args.map(a => a.toLowerCase())
|
||||||
const allFailures: { testsuite: string, name: string, msg: string } [] = []
|
const allFailures: { testsuite: string, name: string, msg: string } [] = []
|
||||||
let testsToRun = allTests
|
let testsToRun = allTests
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
testsToRun = allTests.filter(t => args.indexOf(t.name) >= 0)
|
args = args.map(a => a.toLowerCase())
|
||||||
|
testsToRun = allTests.filter(t => args.indexOf(t.name.toLowerCase()) >= 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testsToRun.length == 0) {
|
if (testsToRun.length == 0) {
|
||||||
throw "No tests found"
|
throw "No tests found. Try one of "+allTests.map(t => t.name).join(", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < testsToRun.length; i++) {
|
for (let i = 0; i < testsToRun.length; i++) {
|
||||||
const test = testsToRun[i];
|
const test = testsToRun[i];
|
||||||
console.log(" Running test", i, "/", allTests.length, test.name)
|
console.log(" Running test", i, "/", testsToRun.length, test.name)
|
||||||
allFailures.push(...(test.Run() ?? []))
|
allFailures.push(...(test.Run() ?? []))
|
||||||
console.log("OK!")
|
console.log("OK!")
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,14 @@ export default class T {
|
||||||
throw "Expected true, but got false: " + msg
|
throw "Expected true, but got false: " + msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static equals(a, b, msg?){
|
||||||
|
if(a !== b){
|
||||||
|
throw "Not the same: "+(msg??"")+"\n" +
|
||||||
|
"Expcected: "+a+"\n" +
|
||||||
|
"Got : "+b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static isFalse(b: boolean, msg: string) {
|
static isFalse(b: boolean, msg: string) {
|
||||||
if (b) {
|
if (b) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue