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,
|
||||
WikidataImageProvider.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[]>>()
|
||||
|
|
|
@ -15,7 +15,7 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
private readonly commons_key = "wikimedia_commons"
|
||||
public readonly defaultKeyPrefixes = [this.commons_key,"image"]
|
||||
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() {
|
||||
super();
|
||||
|
@ -89,22 +89,40 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
}
|
||||
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>[]> {
|
||||
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 []
|
||||
}
|
||||
|
||||
if (value.startsWith(WikimediaImageProvider.commonsPrefix)) {
|
||||
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)]
|
||||
}
|
||||
value = this.removeCommonsPrefix(value)
|
||||
if (value.startsWith("Category:")) {
|
||||
const urls = await Wikimedia.GetCategoryContents(value)
|
||||
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 TileFreshnessCalculatorSpec from "./TileFreshnessCalculator.spec";
|
||||
import WikidataSpecTest from "./Wikidata.spec.test";
|
||||
import ImageProviderSpec from "./ImageProvider.spec";
|
||||
|
||||
|
||||
ScriptUtils.fixUtils()
|
||||
|
@ -25,7 +26,8 @@ const allTests = [
|
|||
new RelationSplitHandlerSpec(),
|
||||
new SplitActionSpec(),
|
||||
new TileFreshnessCalculatorSpec(),
|
||||
new WikidataSpecTest()
|
||||
new WikidataSpecTest(),
|
||||
new ImageProviderSpec()
|
||||
]
|
||||
|
||||
Utils.externalDownloadFunction = async (url) => {
|
||||
|
@ -44,16 +46,17 @@ args = args.map(a => a.toLowerCase())
|
|||
const allFailures: { testsuite: string, name: string, msg: string } [] = []
|
||||
let testsToRun = allTests
|
||||
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) {
|
||||
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++) {
|
||||
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() ?? []))
|
||||
console.log("OK!")
|
||||
}
|
||||
|
|
|
@ -40,6 +40,14 @@ export default class T {
|
|||
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) {
|
||||
if (b) {
|
||||
|
|
Loading…
Reference in a new issue