Merge pull-request #312

This commit is contained in:
Frederic Guillot 2015-01-19 19:30:11 -05:00
commit bb570ecd3e
58 changed files with 1519 additions and 1614 deletions

View File

@ -237,7 +237,7 @@ textarea.form-error {
}
/* alerts */
.alert {
.alert, .panel {
padding: 8px 35px 8px 14px;
margin-bottom: 20px;
color: #c09853;
@ -253,7 +253,7 @@ textarea.form-error {
border-color: #d6e9c6;
}
.alert-error {
.alert-error, .panel-danger {
color: #b94a48;
background-color: #f2dede;
border-color: #eed3d7;
@ -265,13 +265,13 @@ textarea.form-error {
border-color: #bce8f1;
}
.alert-normal {
.alert-normal, .panel-default {
color: #333;
background-color: #f0f0f0;
border-color: #ddd;
}
.alert-error a {
.alert-error a, .panel-danger a {
color: #b94a48;
}

38
assets/js/all.min.js vendored
View File

@ -1,21 +1,21 @@
var Miniflux={};Miniflux.App=function(){return{Run:function(){Miniflux.Event.ListenKeyboardEvents();Miniflux.Event.ListenMouseEvents()}}}();
Miniflux.Feed=function(){var f=[];return{Update:function(e,a){var b=e.querySelector("span.items-count");if(b){var c=e.getAttribute("data-feed-id"),f=e.querySelector("h2:first-of-type");f.className="loading-icon";var h=new XMLHttpRequest;h.onload=function(){f.className="";e.removeAttribute("data-feed-error");var c=e.querySelector(".feed-last-checked");c&&(c.innerHTML=c.getAttribute("data-after-update"));c=JSON.parse(this.responseText);c.result?b.innerHTML=c.items_count.items_unread+"/"+c.items_count.items_total:
e.setAttribute("data-feed-error","1");a&&a(c)};h.open("POST","?action=refresh-feed&feed_id="+c,!0);h.send()}},UpdateAll:function(){var e=Array.prototype.slice.call(document.querySelectorAll("article:not([data-feed-disabled])")),a=setInterval(function(){for(;0<e.length&&5>f.length;){var b=e.shift();f.push(parseInt(b.getAttribute("data-feed-id")));Miniflux.Feed.Update(b,function(b){b=f.indexOf(b.feed_id);0<=b&&f.splice(b,1);0===e.length&&0===f.length&&(clearInterval(a),window.location.href="?action=unread")})}},
Miniflux.Feed=function(){var e=[];return{Update:function(d,a){var b=d.querySelector("span.items-count");if(b){var c=d.getAttribute("data-feed-id"),e=d.querySelector("h2:first-of-type");e.className="loading-icon";var h=new XMLHttpRequest;h.onload=function(){e.className="";d.removeAttribute("data-feed-error");var c=d.querySelector(".feed-last-checked");c&&(c.innerHTML=c.getAttribute("data-after-update"));c=JSON.parse(this.responseText);c.result?b.innerHTML=c.items_count.items_unread+"/"+c.items_count.items_total:
d.setAttribute("data-feed-error","1");a&&a(c)};h.open("POST","?action=refresh-feed&feed_id="+c,!0);h.send()}},UpdateAll:function(){var d=Array.prototype.slice.call(document.querySelectorAll("article:not([data-feed-disabled])")),a=setInterval(function(){for(;0<d.length&&5>e.length;){var b=d.shift();e.push(parseInt(b.getAttribute("data-feed-id")));Miniflux.Feed.Update(b,function(b){b=e.indexOf(b.feed_id);0<=b&&e.splice(b,1);0===d.length&&0===e.length&&(clearInterval(a),window.location.href="?action=unread")})}},
100)}}}();
Miniflux.Item=function(){function f(a){return item_id=a.getAttribute("data-item-id")}function e(a){if(a&&a.hasAttribute("data-reverse-label")){var b=a.innerHTML;a.innerHTML=a.getAttribute("data-reverse-label");a.setAttribute("data-reverse-label",b)}}function a(a){"mouse"!==Miniflux.Event.lastEventType&&Miniflux.Nav.SelectNextItem();a.parentNode.removeChild(a);k--}function b(){0===k&&window.location.reload();var a=document.getElementById("page-counter");a.textContent=k||"";document.getElementById("nav-counter").textContent=h||
"";switch(document.querySelector("section.page").getAttribute("data-item-page")){case "unread":document.title="Miniflux ("+h+")";break;case "feed-items":document.title="("+k+") "+a.parentNode.firstChild.nodeValue;break;default:document.title=a.parentNode.firstChild.nodeValue+" ("+k+")"}}function c(g){var d=f(g),c=new XMLHttpRequest;c.onload=function(){if(Miniflux.Nav.IsListing()){if(g.getAttribute("data-hide"))a(g);else{g.setAttribute("data-item-status","read");var d=g.querySelector("a.mark");e(d);
(d=g.querySelector("a.mark"))&&d.setAttribute("data-action","mark-unread")}h--;b()}};c.open("POST","?action=mark-item-read&id="+d,!0);c.send()}function m(g){var d=f(g),c=new XMLHttpRequest;c.onload=function(){if(Miniflux.Nav.IsListing()){if(g.getAttribute("data-hide"))a(g);else{g.setAttribute("data-item-status","unread");var d=g.querySelector("a.mark");e(d);(d=g.querySelector("a.mark"))&&d.setAttribute("data-action","mark-read")}h++;b()}};c.open("POST","?action=mark-item-unread&id="+d,!0);c.send()}
var h=function(){var a=document.getElementById("nav-counter");if(a)return counter=parseInt(a.textContent,10)||0}(),k=function(){var a=document.getElementById("page-counter");if(a)return counter=parseInt(a.textContent,10)||0}();return{MarkAsRead:c,MarkAsUnread:m,MarkAsRemoved:function(g){var d=f(g),c=new XMLHttpRequest;c.onload=function(){Miniflux.Nav.IsListing()&&(a(g),"unread"===g.getAttribute("data-item-status")&&h--,b())};c.open("POST","?action=mark-item-removed&id="+d,!0);c.send()},SwitchBookmark:function(g){var d=
f(g),c="1"===g.getAttribute("data-item-bookmark")?"0":"1",l=new XMLHttpRequest;l.onload=function(){var d=document.querySelector("section.page");if(Miniflux.Nav.IsListing()&&"bookmarks"===d.getAttribute("data-item-page"))a(g),b();else if(g.setAttribute("data-item-bookmark",c),Miniflux.Nav.IsListing())d=g.querySelector("a.bookmark"),e(d);else if((d=g.querySelector("a.bookmark-icon"))&&d.hasAttribute("data-reverse-title")){var f=d.getAttribute("title");d.setAttribute("title",d.getAttribute("data-reverse-title"));
d.setAttribute("data-reverse-title",f)}};l.open("POST","?action=bookmark&id="+d+"&value="+c,!0);l.send()},SwitchStatus:function(a){var d=a.getAttribute("data-item-status");"read"===d?m(a):"unread"===d&&c(a)},Show:function(a){(a=a.querySelector("a.show"))&&a.click()},OpenOriginal:function(a){var d=a.querySelector("a.original");d&&("unread"===a.getAttribute("data-item-status")&&c(a),d.removeAttribute("data-action"),"mouse"!==Miniflux.Event.lastEventType&&d.click())},DownloadContent:function(a){var d=
document.getElementById("download-item");if(d){d.innerHTML=" "+d.getAttribute("data-before-message");d.className="loading-icon";var b=new XMLHttpRequest;b.onload=function(){var a=JSON.parse(b.responseText);d.className="";if(a.result){var c=document.getElementById("item-content");c&&(c.innerHTML=a.content);d.innerHTML=d.getAttribute("data-after-message")}else d.innerHTML=d.getAttribute("data-failure-message")};a=f(a);b.open("POST","?action=download-item&id="+a,!0);b.send()}},MarkListingAsRead:function(a){for(var b=
document.getElementsByTagName("article"),c=[],e=0,h=b.length;e<h;e++)c.push(f(b[e]));b=new XMLHttpRequest;b.onload=function(){window.location.href=a};b.open("POST","?action=mark-items-as-read",!0);b.send(JSON.stringify(c))},ToggleRTLMode:function(){for(var a=["#current-item h1","#item-content","#listing #current-item h2","#listing #current-item .preview"],b=0;b<a.length;b++){var c=document.querySelector(a[b]);c&&(c.dir=""==c.dir?"rtl":"")}}}}();
Miniflux.Event=function(){function f(a){if(63!==a.keyCode&&(a.ctrlKey||a.shiftKey||a.altKey||a.metaKey))return!0;a=a.target||a.srcElement;return"INPUT"===a.tagName||"TEXTAREA"===a.tagName?!0:!1}var e=[];return{lastEventType:"",ListenMouseEvents:function(){document.onclick=function(a){var b=a.target.getAttribute("data-action");b&&"original-link"!==b&&a.preventDefault()};document.onmouseup=function(a){if(2!==a.button)if("INPUT"===a.target.nodeName&&"auto-select"===a.target.className)a.target.select();
else{var b=a.target.getAttribute("data-action");if(b){Miniflux.Event.lastEventType="mouse";var c;a:{for(element=a.target;element&&element.parentNode;)if(element=element.parentNode,element.tagName&&"article"===element.tagName.toLowerCase()){c=element;break a}c=null}switch(b){case "refresh-all":Miniflux.Feed.UpdateAll();break;case "refresh-feed":Miniflux.Feed.Update(c);break;case "mark-read":Miniflux.Item.MarkAsRead(c);break;case "mark-unread":Miniflux.Item.MarkAsUnread(c);break;case "mark-removed":Miniflux.Item.MarkAsRemoved(c);
break;case "bookmark":Miniflux.Item.SwitchBookmark(c);break;case "download-item":Miniflux.Item.DownloadContent(c);break;case "original-link":Miniflux.Item.OpenOriginal(c);break;case "mark-all-read":Miniflux.Item.MarkListingAsRead("?action=unread");break;case "mark-feed-read":Miniflux.Item.MarkListingAsRead("?action=feed-items&feed_id="+a.target.getAttribute("data-feed-id"))}}}}},ListenKeyboardEvents:function(){document.onkeypress=function(a){if(!f(a))if(Miniflux.Event.lastEventType="keyboard",e.push(a.keyCode||
a.which),103===e[0])switch(e[1]){case void 0:break;case 117:window.location.href="?action=unread";e=[];break;case 98:window.location.href="?action=bookmarks";e=[];break;case 104:window.location.href="?action=history";e=[];break;case 115:window.location.href="?action=feeds";e=[];break;case 112:window.location.href="?action=config";e=[];break;default:e=[]}else{e=[];var b=document.getElementById("current-item");switch(a.keyCode||a.which){case 100:Miniflux.Item.DownloadContent(b);break;case 112:case 107:Miniflux.Nav.SelectPreviousItem();
break;case 110:case 106:Miniflux.Nav.SelectNextItem();break;case 118:Miniflux.Item.OpenOriginal(b);break;case 111:Miniflux.Item.Show(b);break;case 109:Miniflux.Item.SwitchStatus(b);break;case 102:Miniflux.Item.SwitchBookmark(b);break;case 104:Miniflux.Nav.OpenPreviousPage();break;case 108:Miniflux.Nav.OpenNextPage();break;case 114:Miniflux.Feed.UpdateAll();break;case 63:Miniflux.Nav.ShowHelp();break;case 122:Miniflux.Item.ToggleRTLMode()}}};document.onkeydown=function(a){if(!f(a))switch(Miniflux.Event.lastEventType=
"keyboard",a.keyCode||a.which){case 37:Miniflux.Nav.SelectPreviousItem();break;case 39:Miniflux.Nav.SelectNextItem()}}}}}();
Miniflux.Nav=function(){function f(a){var b=pageYOffset+document.documentElement.clientHeight;(0>b-(a.offsetTop+a.offsetHeight)||b-a.offsetTop>document.documentElement.clientHeight)&&window.scrollTo(0,a.offsetTop-10)}function e(){return document.getElementById("listing")?!0:!1}return{OpenNextPage:function(){var a=document.getElementById("next-page");a&&a.click()},OpenPreviousPage:function(){var a=document.getElementById("previous-page");a&&a.click()},SelectNextItem:function(){var a=document.getElementById("next-item");
if(a)a.click();else if(e())if(a=document.getElementsByTagName("article"),document.getElementById("current-item"))for(var b=0,c=a.length;b<c;b++){if("current-item"===a[b].id){b+1<c&&(a[b].id="item-"+a[b].getAttribute("data-item-id"),a[b+1].id="current-item",f(a[b+1]));break}}else a[0].id="current-item",f(a[0])},SelectPreviousItem:function(){var a=document.getElementById("previous-item");if(a)a.click();else if(e())if(a=document.getElementsByTagName("article"),document.getElementById("current-item"))for(var b=
a.length-1;0<=b;b--){if("current-item"===a[b].id){0<=b-1&&(a[b].id="item-"+a[b].getAttribute("data-item-id"),a[b-1].id="current-item",f(a[b-1]));break}}else a[a.length-1].id="current-item",f(a[a.length-1])},ShowHelp:function(){open("?action=show-help","Help","width=320,height=450,location=no,scrollbars=no,status=no,toolbar=no")},IsListing:e}}();Miniflux.App.Run();
Miniflux.Item=function(){function e(a){return item_id=a.getAttribute("data-item-id")}function d(a){if(a&&a.hasAttribute("data-reverse-label")){var b=a.innerHTML;a.innerHTML=a.getAttribute("data-reverse-label");a.setAttribute("data-reverse-label",b)}}function a(a){"mouse"!==Miniflux.Event.lastEventType&&Miniflux.Nav.SelectNextItem();a.parentNode.removeChild(a);l--}function b(){0===l&&window.location.reload();var a=document.getElementById("page-counter");a.textContent=l||"";document.getElementById("nav-counter").textContent=h||
"";switch(document.querySelector("section.page").getAttribute("data-item-page")){case "unread":document.title="Miniflux ("+h+")";break;case "feed-items":document.title="("+l+") "+a.parentNode.firstChild.nodeValue;break;default:document.title=a.parentNode.firstChild.nodeValue+" ("+l+")"}}function c(g){var f=e(g),c=new XMLHttpRequest;c.onload=function(){if(Miniflux.Nav.IsListing()){if(g.getAttribute("data-hide"))a(g);else{g.setAttribute("data-item-status","read");var c=g.querySelector("a.mark");d(c);
(c=g.querySelector("a.mark"))&&c.setAttribute("data-action","mark-unread")}h--;b()}};c.open("POST","?action=mark-item-read&id="+f,!0);c.send()}function n(g){var c=e(g),k=new XMLHttpRequest;k.onload=function(){if(Miniflux.Nav.IsListing()){if(g.getAttribute("data-hide"))a(g);else{g.setAttribute("data-item-status","unread");var c=g.querySelector("a.mark");d(c);(c=g.querySelector("a.mark"))&&c.setAttribute("data-action","mark-read")}h++;b()}};k.open("POST","?action=mark-item-unread&id="+c,!0);k.send()}
var h=function(){var a=document.getElementById("nav-counter");if(a)return counter=parseInt(a.textContent,10)||0}(),l=function(){var a=document.getElementById("page-counter");if(a)return counter=parseInt(a.textContent,10)||0}();return{MarkAsRead:c,MarkAsUnread:n,MarkAsRemoved:function(c){var f=e(c),d=new XMLHttpRequest;d.onload=function(){Miniflux.Nav.IsListing()&&(a(c),"unread"===c.getAttribute("data-item-status")&&h--,b())};d.open("POST","?action=mark-item-removed&id="+f,!0);d.send()},SwitchBookmark:function(c){var f=
e(c),k="1"===c.getAttribute("data-item-bookmark")?"0":"1",m=new XMLHttpRequest;m.onload=function(){var f=document.querySelector("section.page");if(Miniflux.Nav.IsListing()&&"bookmarks"===f.getAttribute("data-item-page"))a(c),b();else if(c.setAttribute("data-item-bookmark",k),Miniflux.Nav.IsListing())f=c.querySelector("a.bookmark"),d(f);else if((f=c.querySelector("a.bookmark-icon"))&&f.hasAttribute("data-reverse-title")){var e=f.getAttribute("title");f.setAttribute("title",f.getAttribute("data-reverse-title"));
f.setAttribute("data-reverse-title",e)}};m.open("POST","?action=bookmark&id="+f+"&value="+k,!0);m.send()},SwitchStatus:function(a){var b=a.getAttribute("data-item-status");"read"===b?n(a):"unread"===b&&c(a)},Show:function(a){(a=a.querySelector("a.show"))&&a.click()},OpenOriginal:function(a){var b=a.querySelector("a.original");b&&("unread"===a.getAttribute("data-item-status")&&c(a),b.removeAttribute("data-action"),"mouse"!==Miniflux.Event.lastEventType&&b.click())},DownloadContent:function(a){var b=
document.getElementById("download-item");if(b){b.innerHTML=" "+b.getAttribute("data-before-message");b.className="loading-icon";var c=new XMLHttpRequest;c.onload=function(){var a=JSON.parse(c.responseText);b.className="";if(a.result){var d=document.getElementById("item-content");d&&(d.innerHTML=a.content);b.innerHTML=b.getAttribute("data-after-message")}else b.innerHTML=b.getAttribute("data-failure-message")};a=e(a);c.open("POST","?action=download-item&id="+a,!0);c.send()}},MarkListingAsRead:function(a){for(var b=
document.getElementsByTagName("article"),c=[],d=0,h=b.length;d<h;d++)c.push(e(b[d]));b=new XMLHttpRequest;b.onload=function(){window.location.href=a};b.open("POST","?action=mark-items-as-read",!0);b.send(JSON.stringify(c))},ToggleRTLMode:function(){for(var a=["#current-item h1","#item-content","#listing #current-item h2","#listing #current-item .preview"],b=0;b<a.length;b++){var c=document.querySelector(a[b]);c&&(c.dir=""==c.dir?"rtl":"")}}}}();
Miniflux.Event=function(){function e(a){if(63!==a.keyCode&&63!==a.which&&(a.ctrlKey||a.shiftKey||a.altKey||a.metaKey))return!0;a=a.target||a.srcElement;return"INPUT"===a.tagName||"TEXTAREA"===a.tagName?!0:!1}var d=[];return{lastEventType:"",ListenMouseEvents:function(){document.onclick=function(a){var b=a.target.getAttribute("data-action");b&&"original-link"!==b&&a.preventDefault()};document.onmouseup=function(a){if(2!==a.button)if("INPUT"===a.target.nodeName&&"auto-select"===a.target.className)a.target.select();
else{var b=a.target.getAttribute("data-action");if(b){Miniflux.Event.lastEventType="mouse";var c;a:{for(element=a.target;element&&element.parentNode;)if(element=element.parentNode,element.tagName&&"article"===element.tagName.toLowerCase()){c=element;break a}c=void 0}switch(b){case "refresh-all":Miniflux.Feed.UpdateAll();break;case "refresh-feed":c&&Miniflux.Feed.Update(c);break;case "mark-read":c&&Miniflux.Item.MarkAsRead(c);break;case "mark-unread":c&&Miniflux.Item.MarkAsUnread(c);break;case "mark-removed":c&&
Miniflux.Item.MarkAsRemoved(c);break;case "bookmark":c&&Miniflux.Item.SwitchBookmark(c);break;case "download-item":c&&Miniflux.Item.DownloadContent(c);break;case "original-link":c&&Miniflux.Item.OpenOriginal(c);break;case "mark-all-read":Miniflux.Item.MarkListingAsRead("?action=unread");break;case "mark-feed-read":Miniflux.Item.MarkListingAsRead("?action=feed-items&feed_id="+a.target.getAttribute("data-feed-id"))}}}}},ListenKeyboardEvents:function(){document.onkeypress=function(a){if(!e(a))if(Miniflux.Event.lastEventType=
"keyboard",d.push(a.keyCode||a.which),103===d[0])switch(d[1]){case void 0:break;case 117:window.location.href="?action=unread";d=[];break;case 98:window.location.href="?action=bookmarks";d=[];break;case 104:window.location.href="?action=history";d=[];break;case 115:window.location.href="?action=feeds";d=[];break;case 112:window.location.href="?action=config";d=[];break;default:d=[]}else{d=[];var b=document.getElementById("current-item");switch(a.keyCode||a.which){case 100:b&&Miniflux.Item.DownloadContent(b);
break;case 112:case 107:Miniflux.Nav.SelectPreviousItem();break;case 110:case 106:Miniflux.Nav.SelectNextItem();break;case 118:b&&Miniflux.Item.OpenOriginal(b);break;case 111:b&&Miniflux.Item.Show(b);break;case 109:b&&Miniflux.Item.SwitchStatus(b);break;case 102:b&&Miniflux.Item.SwitchBookmark(b);break;case 104:Miniflux.Nav.OpenPreviousPage();break;case 108:Miniflux.Nav.OpenNextPage();break;case 114:Miniflux.Feed.UpdateAll();break;case 63:Miniflux.Nav.ShowHelp();break;case 122:Miniflux.Item.ToggleRTLMode()}}};
document.onkeydown=function(a){if(!e(a))switch(Miniflux.Event.lastEventType="keyboard",a.keyCode||a.which){case 37:Miniflux.Nav.SelectPreviousItem();break;case 39:Miniflux.Nav.SelectNextItem()}}}}}();
Miniflux.Nav=function(){function e(a){var b=pageYOffset+document.documentElement.clientHeight;(0>b-(a.offsetTop+a.offsetHeight)||b-a.offsetTop>document.documentElement.clientHeight)&&window.scrollTo(0,a.offsetTop-10)}function d(){return document.getElementById("listing")?!0:!1}return{OpenNextPage:function(){var a=document.getElementById("next-page");a&&a.click()},OpenPreviousPage:function(){var a=document.getElementById("previous-page");a&&a.click()},SelectNextItem:function(){var a=document.getElementById("next-item");
if(a)a.click();else if(d())if(a=document.getElementsByTagName("article"),document.getElementById("current-item"))for(var b=0,c=a.length;b<c;b++){if("current-item"===a[b].id){b+1<c&&(a[b].id="item-"+a[b].getAttribute("data-item-id"),a[b+1].id="current-item",e(a[b+1]));break}}else a[0].id="current-item",e(a[0])},SelectPreviousItem:function(){var a=document.getElementById("previous-item");if(a)a.click();else if(d())if(a=document.getElementsByTagName("article"),document.getElementById("current-item"))for(var b=
a.length-1;0<=b;b--){if("current-item"===a[b].id){0<=b-1&&(a[b].id="item-"+a[b].getAttribute("data-item-id"),a[b-1].id="current-item",e(a[b-1]));break}}else a[a.length-1].id="current-item",e(a[a.length-1])},ShowHelp:function(){open("?action=show-help","Help","width=320,height=450,location=no,scrollbars=no,status=no,toolbar=no")},IsListing:d}}();Miniflux.App.Run();

View File

@ -4,7 +4,7 @@ Miniflux.Event = (function() {
function isEventIgnored(e)
{
if (e.keyCode !== 63 && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey)) {
if (e.keyCode !== 63 && e.which !== 63 && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey)) {
return true;
}
@ -61,7 +61,7 @@ Miniflux.Event = (function() {
}
}
return null;
return;
}();
switch (action) {
@ -69,25 +69,25 @@ Miniflux.Event = (function() {
Miniflux.Feed.UpdateAll();
break;
case 'refresh-feed':
Miniflux.Feed.Update(currentItem);
currentItem && Miniflux.Feed.Update(currentItem);
break;
case 'mark-read':
Miniflux.Item.MarkAsRead(currentItem);
currentItem && Miniflux.Item.MarkAsRead(currentItem);
break;
case 'mark-unread':
Miniflux.Item.MarkAsUnread(currentItem);
currentItem && Miniflux.Item.MarkAsUnread(currentItem);
break;
case 'mark-removed':
Miniflux.Item.MarkAsRemoved(currentItem);
currentItem && Miniflux.Item.MarkAsRemoved(currentItem);
break;
case 'bookmark':
Miniflux.Item.SwitchBookmark(currentItem);
currentItem && Miniflux.Item.SwitchBookmark(currentItem);
break;
case 'download-item':
Miniflux.Item.DownloadContent(currentItem);
currentItem && Miniflux.Item.DownloadContent(currentItem);
break;
case 'original-link':
Miniflux.Item.OpenOriginal(currentItem);
currentItem && Miniflux.Item.OpenOriginal(currentItem);
break;
case 'mark-all-read':
Miniflux.Item.MarkListingAsRead("?action=unread");
@ -151,7 +151,7 @@ Miniflux.Event = (function() {
switch (e.keyCode || e.which) {
case 100: // d
Miniflux.Item.DownloadContent(currentItem);
currentItem && Miniflux.Item.DownloadContent(currentItem);
break;
case 112: // p
case 107: // k
@ -162,16 +162,16 @@ Miniflux.Event = (function() {
Miniflux.Nav.SelectNextItem();
break;
case 118: // v
Miniflux.Item.OpenOriginal(currentItem);
currentItem && Miniflux.Item.OpenOriginal(currentItem);
break;
case 111: // o
Miniflux.Item.Show(currentItem);
currentItem && Miniflux.Item.Show(currentItem);
break;
case 109: // m
Miniflux.Item.SwitchStatus(currentItem);
currentItem && Miniflux.Item.SwitchStatus(currentItem);
break;
case 102: // f
Miniflux.Item.SwitchBookmark(currentItem);
currentItem && Miniflux.Item.SwitchBookmark(currentItem);
break;
case 104: // h
Miniflux.Nav.OpenPreviousPage();

View File

@ -11,9 +11,14 @@ Router\before(function($action) {
Session\open(BASE_URL_DIRECTORY, SESSION_SAVE_PATH, 0);
// Select the requested database. If it fails, logout to destroy session and
// Select the requested database either from post param database or from the
// session variable. If it fails, logout to destroy session and
// 'remember me' cookie
if (! empty($_SESSION['database'])) {
if (! is_null(Request\value('database')) && ! Model\Database\select(Request\value('database'))) {
Model\User\logout();
Response\redirect('?action=login');
}
elseif (! empty($_SESSION['database'])) {
if (! Model\Database\select($_SESSION['database'])) {
Model\User\logout();
Response\redirect('?action=login');

View File

@ -229,9 +229,9 @@ function form_radios($name, array $options, array $values = array())
return $html;
}
function form_radio($name, $label, $value, $selected = false, $class = '')
function form_radio($name, $label, $value, $checked = false, $class = '')
{
return '<label><input type="radio" name="'.$name.'" class="'.$class.'" value="'.escape($value).'" '.($selected ? 'selected="selected"' : '').'>'.escape($label).'</label>';
return '<label><input type="radio" name="'.$name.'" class="'.$class.'" value="'.escape($value).'" '.($checked ? 'checked' : '').'>'.escape($label).'</label>';
}
function form_checkbox($name, $label, $value, $checked = false, $class = '')

View File

@ -23,8 +23,8 @@ return array(
// 'Older items first' => '',
// 'Most recent first' => '',
// 'Default sorting order for items' => '',
// 'This subscription is empty, <a href="?action=unread">go back to unread items</a>' => '',
// 'sort by date<span class="hide-mobile"> (%s)</span>' => '',
// 'This subscription is empty, %sgo back to unread items%s' => '',
// 'sort by date %s(%s)%s' => '',
// 'most recent first' => '',
// 'older first' => '',
// 'Show only this subscription' => '',
@ -143,7 +143,7 @@ return array(
'Passwords don\'t match' => 'Hesla se neshodují',
'Do you really want to remove these items from your history?' => 'Opravdu chcete odstranit tyto články z historie?',
'Do you really want to remove this subscription: "%s"?' => 'Opravdu chcete odstranit tento odběr: "%s"?',
'Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>' => 'Nic ke čtení, chete <a href="?action=refresh-all" data-action="refresh-all">aktualizovat vaše odběry?</a>',
'Nothing to read, do you want to %supdate your subscriptions%s?' => 'Nic ke čtení, chete %saktualizovat vaše odběry%s?',
'Show help' => 'Zobrazit nápovědu',
'Close help' => 'Zavřít nápovědu',
// '%d second ago' => '',
@ -184,7 +184,7 @@ return array(
// 'Activated' => '',
// 'Remove this feed' => '',
// 'Miniflux' => '',
// 'mini<span>flux</span>' => '',
// 'mini%sflux%s' => '',
// 'All' => '',
// 'Advanced' => '',
// 'Documentation' => '',

View File

@ -23,8 +23,8 @@ return array(
'Older items first' => 'Ältere Einträge zuerst',
'Most recent first' => 'Neueste Einträge zuerst',
'Default sorting order for items' => 'Standardsortierung der Einträge',
'This subscription is empty, <a href="?action=unread">go back to unread items</a>' => 'Dieses Abonnement ist leer, <a href="?action=unread">zurück zu den ungelesenen Artikeln gehen</a>',
'sort by date<span class="hide-mobile"> (%s)</span>' => 'nach Datum sortieren<span class="hide-mobile"> (%s)</span>',
'This subscription is empty, %sgo back to unread items%s' => 'Dieses Abonnement ist leer, %szurück zu den ungelesenen Artikeln gehen%s',
'sort by date %s(%s)%s' => 'nach Datum sortieren %s(%s)%s',
'most recent first' => 'neueste zuerst',
'older first' => 'ältere zuerst',
'Show only this subscription' => 'Nur dieses Abonnement anzeigen',
@ -143,7 +143,7 @@ return array(
'Passwords don\'t match' => 'Passwörter stimmen nicht überein',
'Do you really want to remove these items from your history?' => 'Möchtest du wirklich diese Einträge aus deinem Verlauf entfernen?',
'Do you really want to remove this subscription: "%s"?' => 'Möchtest du wirklich dieses Abonnement entfernen: "%s"?',
'Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>' => 'Nichts zu lesen, möchtest du <a href="?action=refresh-all" data-action="refresh-all">alle Abonnements aktualisieren?</a>',
'Nothing to read, do you want to %supdate your subscriptions%s?' => 'Nichts zu lesen, möchtest du %sdeine Abonnements aktualisieren%s?',
'Show help' => 'Hilfe zeigen',
'Close help' => 'Hilfe schließen',
'%d second ago' => 'Vor %d Sekunde',
@ -184,7 +184,7 @@ return array(
'Activated' => 'Aktiviert',
'Remove this feed' => 'Dieses Abonnement entfernen',
'Miniflux' => 'Miniflux',
'mini<span>flux</span>' => 'mini<span>flux</span>',
'mini%sflux%s' => 'mini%sflux%s',
'All' => 'Alle',
'Advanced' => 'Erweitert',
'Documentation' => 'Dokumentation',

View File

@ -23,8 +23,8 @@ return array(
'Older items first' => 'Ítems más antiguos primero',
'Most recent first' => 'Más recientes primero',
'Default sorting order for items' => 'Orden de clasificación predeterminado para los ítems',
'This subscription is empty, <a href="?action=unread">go back to unread items</a>' => 'Esta suscripción está vacía, <a href="?action=unread">volver a los ítems no leídos</a>',
'sort by date<span class="hide-mobile"> (%s)</span>' => 'ordenar por fecha<span class="hide-mobile"> (%s)</span>',
'This subscription is empty, %sgo back to unread items%s' => 'Esta suscripción está vacía, %svolver a los ítems no leídos%s',
'sort by date %s(%s)%s' => 'ordenar por fecha %s(%s)%s',
'most recent first' => 'más reciente primero',
'older first' => 'más antiguo primero',
'Show only this subscription' => 'Mostrar sólo esta suscripción',
@ -143,7 +143,7 @@ return array(
'Passwords don\'t match' => 'Las contraseñas no coinciden',
'Do you really want to remove these items from your history?' => '¿De verdad quiere borrar estos ítems del historial?',
'Do you really want to remove this subscription: "%s"?' => '¿De verdad quiere borrar esta suscripción: "%s"?',
'Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>' => 'No hay nada que leer, ¿quiere <a href="?action=refresh-all" data-action="refresh-all">actualizar las suscripciones</a>?',
'Nothing to read, do you want to %supdate your subscriptions%s?' => 'No hay nada que leer, ¿quiere %sactualizar las suscripciones%s?',
'Show help' => 'Mostrar la ayuda',
'Close help' => 'Cerrar la ayuda',
// '%d second ago' => '',
@ -184,7 +184,7 @@ return array(
// 'Activated' => '',
// 'Remove this feed' => '',
// 'Miniflux' => '',
// 'mini<span>flux</span>' => '',
// 'mini%sflux%s' => '',
// 'All' => '',
// 'Advanced' => '',
// 'Documentation' => '',

View File

@ -23,8 +23,8 @@ return array(
'Older items first' => 'Plus anciens en premier',
'Most recent first' => 'Plus récents en premier',
'Default sorting order for items' => 'Ordre des éléments par défaut',
'This subscription is empty, <a href="?action=unread">go back to unread items</a>' => 'Cet abonnement est vide, <a href="?action=unread">retourner à la liste des éléments non lus</a>',
'sort by date<span class="hide-mobile"> (%s)</span>' => 'trier par date<span class="hide-mobile"> (%s)</span>',
'This subscription is empty, %sgo back to unread items%s' => 'Cet abonnement est vide, %sretourner à la liste des éléments non lus%s',
'sort by date %s(%s)%s' => 'trier par date %s(%s)%s',
'most recent first' => 'plus récents d\'abord',
'older first' => 'anciens d\'abord',
'Show only this subscription' => 'Montrer seulement cet abonnement',
@ -143,7 +143,7 @@ return array(
'Passwords don\'t match' => 'Les mots de passe ne sont pas identiques',
'Do you really want to remove these items from your history?' => 'Voulez-vous vraiment supprimer les éléments de votre historique ?',
'Do you really want to remove this subscription: "%s"?' => 'Voulez-vous vraiment supprimer cet abonnement : « %s » ?',
'Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>' => 'Il n\'y a rien à lire, voulez-vous <a href="?action=refresh-all" data-action="refresh-all">mettre à jour vos abonnements ?</a>',
'Nothing to read, do you want to %supdate your subscriptions%s?' => 'Il n\'y a rien à lire, voulez-vous %smettre à jour vos abonnements%s ?',
'Show help' => 'Afficher l\'aide',
'Close help' => 'Fermer l\'aide',
'%d second ago' => 'Il y a %d seconde',
@ -184,7 +184,7 @@ return array(
'Activated' => 'Activé',
'Remove this feed' => 'Supprimer cet abonnement',
'Miniflux' => 'Miniflux',
'mini<span>flux</span>' => 'mini<span>flux</span>',
'mini%sflux%s' => 'mini%sflux%s',
'All' => 'Tout',
'Advanced' => 'Avancé',
'Documentation' => 'Documentation',

View File

@ -23,8 +23,8 @@ return array(
// 'Older items first' => '',
// 'Most recent first' => '',
// 'Default sorting order for items' => '',
// 'This subscription is empty, <a href="?action=unread">go back to unread items</a>' => '',
// 'sort by date<span class="hide-mobile"> (%s)</span>' => '',
// 'This subscription is empty, %sgo back to unread items%s' => '',
// 'sort by date %s(%s)%s' => '',
// 'most recent first' => '',
// 'older first' => '',
// 'Show only this subscription' => '',
@ -143,7 +143,7 @@ return array(
'Passwords don\'t match' => 'Le password non coincidono',
'Do you really want to remove these items from your history?' => 'Vuoi veramente cancellare questi articoli dalla cronologia?',
'Do you really want to remove this subscription: "%s"?' => 'Vuoi veramente cancellare la sottoscrizione a: "%s" ?',
'Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>' => 'Niente da leggere, vuoi <a href="?action=refresh-all" data-action="refresh-all">aggiornare tutte le sottoscrizioni?</a>',
'Nothing to read, do you want to %supdate your subscriptions%s?' => 'Niente da leggere, vuoi %saggiornare tutte le sottoscrizioni%s?',
'Show help' => 'Mostra guida',
'Close help' => 'Chiudi guida',
// '%d second ago' => '',
@ -184,7 +184,7 @@ return array(
// 'Activated' => '',
// 'Remove this feed' => '',
// 'Miniflux' => '',
// 'mini<span>flux</span>' => '',
// 'mini%sflux%s' => '',
// 'All' => '',
// 'Advanced' => '',
// 'Documentation' => '',

View File

@ -23,8 +23,8 @@ return array(
'Older items first' => 'Itens mais antigos primeiro',
'Most recent first' => 'Mais recentes primeiro',
'Default sorting order for items' => 'Ordenação padrão dos itens',
'This subscription is empty, <a href="?action=unread">go back to unread items</a>' => 'Esta assinatura está vazia, <a href="?action=unread">voltar para os tens não lidos</a>',
'sort by date<span class="hide-mobile"> (%s)</span>' => 'ordenar por data<span class="hide-mobile"> (%s)</span>',
'This subscription is empty, %sgo back to unread items%s' => 'Esta assinatura está vazia, %svoltar para os tens não lidos%s',
'sort by date %s(%s)%s' => 'ordenar por data %s(%s)%s',
'most recent first' => 'mais recentes primeiro',
'older first' => 'antigos primeiro',
'Show only this subscription' => 'Mostrar apenas esta assinatura',
@ -143,7 +143,7 @@ return array(
'Passwords don\'t match' => 'Senha não corresponde.',
'Do you really want to remove these items from your history?' => 'Você realmente deseja remover esses itens de sua histórico?',
'Do you really want to remove this subscription: "%s"?' => 'Você realmente deseja remover essa assinatura: "%s" ?',
'Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>' => 'Nada para ler, você quer <a href="?action=refresh-all" data-action="refresh-all">atualizar suas assinaturas?</a>',
'Nothing to read, do you want to %supdate your subscriptions%s?' => 'Nada para ler, você quer %satualizar suas assinaturas%s?',
'Show help' => 'Abrir ajuda',
'Close help' => 'Fechar ajuda',
'%d second ago' => '%d segundo atrás',
@ -184,7 +184,7 @@ return array(
'Activated' => 'Ativado',
'Remove this feed' => 'Remover este feed',
'Miniflux' => 'Miniflux',
'mini<span>flux</span>' => 'mini<span>flux</span>',
'mini%sflux%s' => 'mini%sflux%s',
'All' => 'Todos',
'Advanced' => 'Avançado',
'Documentation' => 'Documentação',

View File

@ -23,8 +23,8 @@ return array(
// 'Older items first' => '',
// 'Most recent first' => '',
// 'Default sorting order for items' => '',
// 'This subscription is empty, <a href="?action=unread">go back to unread items</a>' => '',
// 'sort by date<span class="hide-mobile"> (%s)</span>' => '',
// 'This subscription is empty, %sgo back to unread items%s' => '',
// 'sort by date %s(%s)%s' => '',
// 'most recent first' => '',
// 'older first' => '',
// 'Show only this subscription' => '',
@ -143,7 +143,7 @@ return array(
'Passwords don\'t match' => '两次输入密码不一致',
'Do you really want to remove these items from your history?' => '你确认要移除这些历史记录吗?',
'Do you really want to remove this subscription: "%s"?' => '你确定要移除这个订阅源: "%s" ',
'Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>' => '空空如也,你想要<a href="?action=refresh-all" data-action="refresh-all">更新订阅源</a>嘛?',
'Nothing to read, do you want to %supdate your subscriptions%s?' => '空空如也,你想要%s更新订阅源%s嘛?',
'Show help' => '显示帮助',
'Close help' => '关闭帮助',
// '%d second ago' => '',
@ -184,7 +184,7 @@ return array(
// 'Activated' => '',
// 'Remove this feed' => '',
// 'Miniflux' => '',
// 'mini<span>flux</span>' => '',
// 'mini%sflux%s' => '',
// 'All' => '',
// 'Advanced' => '',
// 'Documentation' => '',

View File

@ -41,7 +41,7 @@ function select($filename = '')
// function gets called with a filename at least once the database
// connection is established
if ($filename !== '') {
if (! empty($filename)) {
if (ENABLE_MULTIPLE_DB && in_array($filename, get_all())) {
$current_filename = $filename;

View File

@ -29,12 +29,12 @@ function store_favicon($feed_id, $link, $icon)
}
// Download favicon
function fetch_favicon($feed_id, $site_url)
function fetch_favicon($feed_id, $site_url, $icon_link)
{
if (Config\get('favicons') == 1 && ! has_favicon($feed_id)) {
$favicon = new Favicon;
$link = $favicon->find($site_url);
$link = $favicon->find($site_url, $icon_link);
$icon = $favicon->getDataUri();
if ($icon !== '') {
@ -189,7 +189,7 @@ function create($url, $enable_grabber = false, $force_rtl = false)
$feed_id = $db->getConnection()->getLastId();
Item\update_all($feed_id, $feed->getItems());
fetch_favicon($feed_id, $feed->getSiteUrl());
fetch_favicon($feed_id, $feed->getSiteUrl(), $feed->getIcon());
Config\write_debug();
@ -261,7 +261,7 @@ function refresh($feed_id)
update_cache($feed_id, $resource->getLastModified(), $resource->getEtag());
Item\update_all($feed_id, $feed->getItems());
fetch_favicon($feed_id, $feed->getSiteUrl());
fetch_favicon($feed_id, $feed->getSiteUrl(), $feed->getIcon());
}
update_parsing_error($feed_id, 0);

View File

@ -1,4 +1,4 @@
<phpunit>
<phpunit bootstrap="tests/integration/minifluxTestCase.php" >
<php>
<const name="DB_FILENAME" value="unittest.sqlite" />
<const name="PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL" value="http://localhost/miniflux/" />

View File

@ -12,7 +12,7 @@
</nav>
</div>
<section>
<div class="alert alert-normal">
<div class="panel panel-default">
<h3><?= t('Bookmarks') ?></h3>
<ul>
<li>
@ -20,12 +20,12 @@
</li>
</ul>
</div>
<div class="alert alert-normal">
<div class="panel panel-default">
<h3><?= t('Bookmarklet') ?></h3>
<a class="bookmarklet" href="javascript:location.href='<?= Helper\get_current_base_url() ?>?action=subscribe&amp;token=<?= urlencode($config['bookmarklet_token']) ?>&amp;url='+encodeURIComponent(location.href)"><?= t('Subscribe with Miniflux') ?></a> (<?= t('Drag and drop this link to your bookmarks') ?>)
<input type="text" class="auto-select" readonly="readonly" value="javascript:location.href='<?= Helper\get_current_base_url() ?>?action=subscribe&amp;token=<?= urlencode($config['bookmarklet_token']) ?>&amp;url='+encodeURIComponent(location.href)"/>
</div>
<div class="alert alert-normal">
<div class="panel panel-default">
<h3><?= t('About') ?></h3>
<ul>
<li><?= t('Miniflux version:') ?> <strong><?= APP_VERSION ?></strong></li>

View File

@ -12,7 +12,7 @@
</nav>
</div>
<section>
<div class="alert alert-normal">
<div class="panel panel-default">
<h3 id="fever"><?= t('Fever API') ?></h3>
<ul>
<li><?= t('API endpoint:') ?> <strong><?= Helper\get_current_base_url().'fever/' ?></strong></li>
@ -20,7 +20,7 @@
<li><?= t('API token:') ?> <strong><?= Helper\escape($config['fever_token']) ?></strong></li>
</ul>
</div>
<div class="alert alert-normal">
<div class="panel panel-default">
<h3 id="api"><?= t('Miniflux API') ?></h3>
<ul>
<li><?= t('API endpoint:') ?> <strong><?= Helper\get_current_base_url().'jsonrpc.php' ?></strong></li>

View File

@ -7,7 +7,7 @@
</div>
<?php if ($nothing_to_read): ?>
<p class="alert"><?= t('There is nothing new to read, enjoy your favorites articles!') ?></p>
<p class="alert alert-info"><?= t('There is nothing new to read, enjoy your favorites articles!') ?></p>
<?php endif ?>
<section class="items" id="listing">

View File

@ -75,7 +75,7 @@
<div class="page-section">
<h2><?= t('Advanced') ?></h2>
</div>
<section class="alert alert-error">
<section class="panel panel-danger">
<ul>
<li><a href="?action=generate-tokens&amp;csrf=<?= $values['csrf'] ?>"><?= t('Generate new tokens') ?></a> (<?= t('Miniflux API') ?>, <?= t('Fever API') ?>, <?= t('Bookmarklet') ?>, <?= t('Bookmark RSS Feed') ?>)</li>
<?php if (ENABLE_AUTO_UPDATE): ?>

View File

@ -2,7 +2,7 @@
<h2><?= t('Confirmation') ?></h2>
</div>
<p class="alert alert-error"><?= t('This action will update Miniflux with the last development version, are you sure?') ?></p>
<p class="alert alert-info"><?= t('This action will update Miniflux with the last development version, are you sure?') ?></p>
<div class="form-actions">
<a href="?action=auto-update" class="btn btn-red"><?= t('Update Miniflux') ?></a>

View File

@ -12,7 +12,7 @@
</nav>
</div>
<section>
<div class="alert alert-normal">
<div class="panel panel-default">
<ul>
<li><?= t('Database size:') ?> <strong><?= Helper\format_bytes($db_size) ?></strong></li>
<li><a href="?action=optimize-db&amp;csrf=<?= $csrf ?>"><?= t('Optimize the database') ?></a> <?= t('(VACUUM command)') ?></li>

View File

@ -32,9 +32,6 @@
<?= t('or') ?> <a href="?action=feeds"><?= t('cancel') ?></a>
</div>
</form>
<br/>
<div class="alert alert-error">
<ul>
<li><a href="?action=confirm-remove-feed&amp;feed_id=<?= $values['id'] ?>"><?= t('Remove this feed') ?></a></li>
</ul>
<div class="form-actions">
<a href="?action=confirm-remove-feed&amp;feed_id=<?= $values['id'] ?>" class="btn btn-red"><?= t('Remove this feed') ?></a>
</div>

View File

@ -1,6 +1,6 @@
<?php if (empty($items)): ?>
<p class="alert">
<?= tne('This subscription is empty, <a href="?action=unread">go back to unread items</a>') ?>
<p class="alert alert-info">
<?= tne('This subscription is empty, %sgo back to unread items%s','<a href="?action=unread">','</a>') ?>
</p>
<?php else: ?>
@ -11,7 +11,7 @@
<a href="?action=refresh-feed&amp;feed_id=<?= $feed['id'] ?>&amp;redirect=feed-items"><?= t('refresh') ?></a>
</li>
<li>
<a href="?action=feed-items&amp;feed_id=<?= $feed['id'] ?>&amp;order=updated&amp;direction=<?= $direction == 'asc' ? 'desc' : 'asc' ?>"><?= tne('sort by date<span class="hide-mobile"> (%s)</span>', $direction == 'desc' ? t('older first') : t('most recent first')) ?></a>
<a href="?action=feed-items&amp;feed_id=<?= $feed['id'] ?>&amp;order=updated&amp;direction=<?= $direction == 'asc' ? 'desc' : 'asc' ?>"><?= tne('sort by date %s(%s)%s', '<span class="hide-mobile">', $direction == 'desc' ? t('older first') : t('most recent first'), '</span>') ?></a>
</li>
<li>
<a href="?action=mark-feed-as-read&amp;feed_id=<?= $feed['id'] ?>" data-action="mark-feed-read" data-feed-id="<?= $feed['id'] ?>"><?= t('mark all as read') ?></a>
@ -20,7 +20,7 @@
</div>
<?php if ($feed['parsing_error']): ?>
<p class="alert alert-warning">
<p class="alert alert-error">
<?= tne('An error occurred during the last check. Refresh the feed manually and check the %sconsole%s for errors afterwards!','<a href="?action=console">','</a>') ?>
</p>
<?php endif; ?>

View File

@ -20,7 +20,7 @@
<?php if ($nb_failed_feeds > 0): ?>
<p class="alert alert-error"><?= tne('An error occurred during the last check. Refresh the feed manually and check the %sconsole%s for errors afterwards!', '<a href="?action=console">', '</a>') ?></p>
<?php elseif ($nothing_to_read): ?>
<p class="alert"><?= tne('Nothing to read, do you want to <a href="?action=refresh-all" data-action="refresh-all">update your subscriptions?</a>') ?></p>
<p class="alert alert-info"><?= tne('Nothing to read, do you want to %supdate your subscriptions%s?','<a href="?action=refresh-all" data-action="refresh-all">','</a>') ?></p>
<?php endif ?>
<section class="items">

View File

@ -10,7 +10,7 @@
</div>
<?php if ($nothing_to_read): ?>
<p class="alert"><?= t('There is nothing new to read, enjoy your previous readings!') ?></p>
<p class="alert alert-info"><?= t('There is nothing new to read, enjoy your previous readings!') ?></p>
<?php endif ?>
<section class="items" id="listing">

View File

@ -1,4 +1,4 @@
<div class="alert alert-normal" id="shortcuts">
<div class="panel panel-default" id="shortcuts">
<h3><?= t('Keyboard shortcuts') ?></h3>
<ul>
<li><?= t('Go to unread') ?> = <strong>gu</strong></li>

View File

@ -20,7 +20,7 @@
<body>
<header>
<nav>
<a class="logo" href="?"><?= tne('mini<span>flux</span>') ?></a>
<a class="logo" href="?"><?= tne('mini%sflux%s','<span>','</span>') ?></a>
<ul>
<li <?= isset($menu) && $menu === 'unread' ? 'class="active"' : '' ?>>
<a href="?action=unread"><?= t('unread') ?><span id="nav-counter"><?= empty($nb_unread_items) ? '' : $nb_unread_items ?></span></a>

View File

@ -34,17 +34,9 @@
<?php if (ENABLE_MULTIPLE_DB && count($databases) > 1): ?>
<div id="database-selector">
<h4><?= t('Select another database') ?></h4>
<ul>
<?php foreach ($databases as $filename => $dbname): ?>
<li>
<?php if ($current_database === $filename): ?>
<strong><?= Helper\escape($dbname) ?></strong>
<?php else: ?>
<a href="?action=select-db&amp;database=<?= Helper\escape($filename) ?>"><?= Helper\escape($dbname) ?></a>
<?php endif ?>
</li>
<?= Helper\form_radio('database', $dbname, $filename, ($current_database === $filename)) ?>
<?php endforeach ?>
</ul>
</div>
<?php endif ?>

View File

@ -1,5 +1,5 @@
<?php if (empty($item)): ?>
<p class="alert alert-info"><?= t('Item not found') ?></p>
<p class="alert alert-error"><?= t('Item not found') ?></p>
<?php else: ?>
<article
class="item"

View File

@ -6,7 +6,7 @@
<h2><?= t('Unread') ?><span id="page-counter"><?= isset($nb_items) ? $nb_items : '' ?></span></h2>
<ul>
<li>
<a href="?action=unread&amp;order=updated&amp;direction=<?= $direction == 'asc' ? 'desc' : 'asc' ?>"><?= tne('sort by date<span class="hide-mobile"> (%s)</span>', $direction == 'desc' ? t('older first') : t('most recent first')) ?></a>
<a href="?action=unread&amp;order=updated&amp;direction=<?= $direction == 'asc' ? 'desc' : 'asc' ?>"><?= tne('sort by date %s(%s)%s', '<span class="hide-mobile">',$direction == 'desc' ? t('older first') : t('most recent first'), '</span>') ?></a>
</li>
<li>
<a href="?action=mark-as-read" data-action="mark-all-read"><?= t('mark all as read') ?></a>

View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="feeds">
<column>id</column>
<column>site_url</column>
<column>feed_url</column>
<column>title</column>
<column>last_modified</column>
<column>etag</column>
<column>last_checked</column>
<column>enabled</column>
<column>download_content</column>
<column>parsing_error</column>
<column>rtl</column>
<row>
<value>1</value>
<value>http://miniflux.net/</value>
<value>http://miniflux.net/feed.xml</value>
<value>Recent Miniflux Releases</value>
<null />
<null />
<null />
<value>1</value>
<value>0</value>
<value>1</value>
<value>0</value>
</row>
</table>
<table name="items">
<column>id</column>
<column>url</column>
<column>title</column>
<column>author</column>
<column>content</column>
<column>updated</column>
<column>status</column>
<column>feed_id</column>
<column>bookmark</column>
<column>enclosure</column>
<column>enclosure_type</column>
<column>language</column>
<row>
<value>22ca3b4f</value>
<value>http://miniflux.net/news.html#2013-03-21</value>
<value>Miniflux 1.0.2 is released</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.0.2.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.html#v1.0.2&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##92</value>
<value>unread</value>
<value>1</value>
<value>0</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>30d227f3</value>
<value>http://miniflux.net/news.html#2013-07-22</value>
<value>Miniflux 1.0.10 is released!</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.0.10.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.html#v1.0.10&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##97</value>
<value>unread</value>
<value>1</value>
<value>1</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>4b2dbd17</value>
<value>http://miniflux.net/news.html#2013-03-26</value>
<value>Miniflux 1.0.3 is released</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.0.3.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.html#v1.0.3&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##93</value>
<value>read</value>
<value>1</value>
<value>0</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>51b4239b</value>
<value>http://miniflux.net/news.html#2013-04-12</value>
<value>Miniflux 1.0.6 is released</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.0.6.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.html#v1.0.6&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##94</value>
<value>read</value>
<value>1</value>
<value>1</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>7c6afaa5</value>
<value>http://miniflux.net/news.html#2014-01-02</value>
<value>Miniflux 1.1.1 is released</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.1.1.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.html#v1.1.1&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Major improvements:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;New theme: Copper (By the contributor Nicolas Dewaele)&lt;/li&gt;
&lt;li&gt;Display a message next to a feed when there is a parsing error&lt;/li&gt;
&lt;li&gt;Change default value of autoflush to 15 days if not set to avoid large database&lt;/li&gt;
&lt;li&gt;Add autoflush value &amp;quot;immediately&amp;quot;&lt;/li&gt;
&lt;li&gt;Add an option to choose where to be redirected when there is nothing to read&lt;/li&gt;
&lt;li&gt;Bug fixes&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##99</value>
<value>unread</value>
<value>1</value>
<value>0</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>7cb2809d</value>
<value>http://miniflux.net/news.html#2013-09-02</value>
<value>Miniflux 1.0.11 is released</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.0.11.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.html#v1.0.11&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##98</value>
<value>unread</value>
<value>1</value>
<value>1</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>9b20eb66</value>
<value>http://miniflux.net/news.html#2013-04-30</value>
<value>Miniflux 1.0.7 is released</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.0.7.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.html#v1.0.7&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##95</value>
<value>read</value>
<value>1</value>
<value>0</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>9fa78b54</value>
<value>http://miniflux.net/news.html#2013-06-02</value>
<value>Miniflux 1.0.8 is released</value>
<value></value>
<value>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://miniflux.net/miniflux-1.0.8.zip&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;Download archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://miniflux.net/changes.htm#v1.0.8&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; &gt;ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</value>
<value>##TIMESTAMP##96</value>
<value>read</value>
<value>1</value>
<value>1</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
</table>
</dataset>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="feeds">
<column>id</column>
<column>site_url</column>
<column>feed_url</column>
<column>title</column>
<column>last_modified</column>
<column>etag</column>
<column>last_checked</column>
<column>enabled</column>
<column>download_content</column>
<column>parsing_error</column>
<column>rtl</column>
<row>
<value>1</value>
<value>http://www.01net.com/actus/</value>
<value>http://www.netzsensor.de/noone.rss</value>
<value>01net. Actualités</value>
<null />
<null />
<null />
<value>1</value>
<value>0</value>
<value>0</value>
<value>0</value>
</row>
<row>
<value>2</value>
<value>http://devopsreactions.tumblr.com/</value>
<value>http://devopsreactions.tumblr.com/rss</value>
<value>DevOps Reactions</value>
<null />
<null />
<value>##TIMESTAMP##00</value>
<value>0</value>
<value>0</value>
<value>0</value>
<value>0</value>
</row>
<row>
<value>3</value>
<value>http://forums.fedoraforum.org/</value>
<value>http://forums.fedoraforum.org/external.php?type=RSS2</value>
<value>FedoraForum.org</value>
<null />
<null />
<value>##TIMESTAMP##00</value>
<value>1</value>
<value>0</value>
<value>0</value>
<value>0</value>
</row>
<row>
<value>4</value>
<value>https://news.ycombinator.com/</value>
<value>https://news.ycombinator.com/rss</value>
<value>Hacker News</value>
<null />
<null />
<value>##TIMESTAMP##00</value>
<value>1</value>
<value>0</value>
<value>1</value>
<value>0</value>
</row>
<row>
<value>5</value>
<value>http://xakep.ru/</value>
<value>http://www.xakep.ru/articles/rss/</value>
<value>XAKEP.RU</value>
<null />
<null />
<value>##TIMESTAMP##00</value>
<value>1</value>
<value>0</value>
<value>0</value>
<value>0</value>
</row>
</table>
<table name="items">
<column>id</column>
<column>url</column>
<column>title</column>
<column>author</column>
<column>content</column>
<column>updated</column>
<column>status</column>
<column>feed_id</column>
<column>bookmark</column>
<column>enclosure</column>
<column>enclosure_type</column>
<column>language</column>
<row>
<value>0fccceb1</value>
<value>http://www.expatsoftware.com/Articles/bootstrapping-abroad.html?try=3</value>
<value>Bootstrapping overseas as an American</value>
<value></value>
<value>&lt;a href=&quot;https://news.ycombinator.com/item?id=8898238&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;Comments&lt;/a&gt;</value>
<value>##TIMESTAMP##00</value>
<value>read</value>
<value>4</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>6b8e4aa3</value>
<value>http://forums.fedoraforum.org/showthread.php?t=302442&amp;goto=newpost</value>
<value>Question about http hack from another thread</value>
<value>lightman47</value>
<value>Ref: &lt;a href=&quot;http://www.forums.fedoraforum.org/showthread.php?t=302439&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;http://www.forums.fedoraforum.org/sh...d.php?t=302439&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;
I didn&amp;#039;t want to hijack this thread, but the bigger question remains - How could this happen? In my mind I wouldn&amp;#039;t think that user Apache (or ftpsecure) could even get to the &amp;#039;etc&amp;#039; directory - much less abscond a file.&lt;br/&gt;&lt;br/&gt;
I&amp;#039;m curious because I run a site of my own, although I also run denyhosts with bad attempts throttled to 3 and lock out all sevrvices.&lt;br/&gt;&lt;br/&gt;
Thx</value>
<value>##TIMESTAMP##00</value>
<value>unread</value>
<value>3</value>
<value>0</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
<row>
<value>72d36b63</value>
<value>http://ocsigen.org/js_of_ocaml/</value>
<value>Js_of_ocaml A compiler of OCaml bytecode to Javascript</value>
<value></value>
<value>&lt;a href=&quot;https://news.ycombinator.com/item?id=8898680&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;Comments&lt;/a&gt;</value>
<value>##TIMESTAMP##00</value>
<value>unread</value>
<value>4</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>8374a575</value>
<value>http://devopsreactions.tumblr.com/post/108246850813</value>
<value>Who will pick up this bug in the legacy code?</value>
<value>sharhalakis</value>
<value>&lt;p&gt;&lt;img src=&quot;?action=proxy&amp;amp;url=https%3A%2F%2Fi.imgur.com%2FqSU3xKV.gif&quot;/&gt;&lt;/p&gt;
&lt;p&gt;by uaiHebert&lt;/p&gt;</value>
<value>##TIMESTAMP##00</value>
<value>read</value>
<value>2</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>b8b894ad</value>
<value>https://xakep.ru/2015/01/16/hackers-list/</value>
<value>Hackers List: найми правильного хакера!</value>
<value>Denis Mirkov</value>
<value>&lt;a href=&quot;https://xakep.ru/2015/01/16/hackers-list/&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;?action=proxy&amp;amp;url=https%3A%2F%2Fxakep.ru%2Fwp-content%2Fuploads%2F2015%2F01%2F00228-120x76.jpg%3F614ffd&quot; title=&quot;Hackers List: найми правильного хакера!&quot;/&gt;&lt;/a&gt;&lt;p&gt;Нужно провести разведывательную операцию? Шпионаж? Прослушка? Никаких проблем — в онлайне сотни хакеров, готовых помочь за вознаграждение. Нужно только выбрать среди них.&lt;/p&gt;
&lt;p&gt;«Найми подходящего хакера!», — под таким девизом открылся новый сайт Hackers List, настоящий каталог со списком разнообразных услуг, &lt;a href=&quot;http://dealbook.nytimes.com/2015/01/15/need-some-espionage-done-hackers-are-for-hire-online/&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;пишет&lt;/a&gt; NY Times. Сайт открылся в начале ноября.&lt;/p&gt;
&lt;p&gt;Спрос на хакерские услуги немаленький. Например, некий житель Швеции предлагает $2000 тому, кто сможет взломать сайт его арендодателя. Жительница Калифорнии предлагает $500 за взлом странички Facebook её парня, а также его почтового ящика Gmail — несчастная девушка хочет убедиться, что парень ей не изменяет. Какой-то австралиец готов выложить $2000, чтобы получить список клиентов из базы конкурента.&lt;/p&gt;
&lt;p&gt;В наше время взлом, слежка и прослушка перестали быть монополией спецслужб. Соответствующие инструменты и обучающие курсы свободно доступны в онлайне. Специалисты по информационной безопасности работают не только на государственные структуры, но не гнушаются и более мелкими заказами от частных лиц. И если взломы крупных корпораций вроде Sony Pictures, JPMorgan Chase и Home Depot привлекают всеобщее внимание, то подпольная индустрия частного взлома тихо живёт и процветает.&lt;/p&gt;
&lt;p&gt;Взлом почтовых ящиков, удаление фотографий из социальной сети, доступ к базе данных компании, изменение оценки на школьном сервере. Менее чем за три месяца работы на сайте Hackers List накопилось более 500 «грязных» заказов, по которым идёт торговля со снижением цены (голландский аукцион). Есть и «невинные» заказы, когда клиент просит восстановить забытый пароль от собственного почтового ящика (впрочем, кто докажет, что это именно его ящик?).&lt;/p&gt;
&lt;p&gt;Всего на сайте сейчас около 40 зарегистрированных хакеров и 844 зарегистрированных клиента.&lt;/p&gt;
&lt;p&gt;Все участники сохраняют анонимность, а неизвестный оператор сайта получает процент с каждого заказа. Есть опция «гарантированной оплаты», когда платёж происходит только после выполнения работы. Оператор сайта снимает с себя всякую ответственность: каждый пользователь должен подписать 10-страничное соглашение об использовании сервиса, в котором обязуется соблюдать закон. Сайт зарегистрирован в Новой Зеландии, у него даже есть твиттер-аккаунт (@hackerslist).&lt;/p&gt;
&lt;p&gt;Пример этого сайта, а также исключительная активность в соответствующих ветках форума журнала «Хакер» показывает, что рынок «низкоуровневых» взломов процветает, а главное — существует огромный неудовлетворённый спрос на хакерские услуги. Независимые эксперты подтверждают, что взлом почтовых ящиков и аккаунтов в социальных сетях происходит на ежедневной основе. Появились даже специализированные ресурсы вроде &lt;a href=&quot;http://hackerforhirereview.com/&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;hackerforhirereview.com&lt;/a&gt; с обзором таких сервисов, где им выставляют оценки.&lt;/p&gt;
&lt;p&gt;Прочитать полностью на сайте: &lt;a href=&quot;https://xakep.ru/2015/01/16/hackers-list/&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;Hackers List: найми правильного хакера!&lt;/a&gt;&lt;/p&gt;</value>
<value>##TIMESTAMP##00</value>
<value>unread</value>
<value>5</value>
<value>0</value>
<value></value>
<value></value>
<value>en-US</value>
</row>
</table>
</dataset>

View File

@ -1,7 +1,5 @@
<?php
require_once 'minifluxTestCase.php';
class keyboardShortcutTest extends minifluxTestCase
{
const DEFAULT_COUNTER_PAGE = 8;
@ -21,6 +19,16 @@ class keyboardShortcutTest extends minifluxTestCase
return "($this->expectedCounterPage) $this->basePageHeading";
}
public function testNoAlertShown()
{
$alertBox = $this->getAlertBox();
$this->assertEmpty($alertBox, 'Unexpected alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testNextItemShortcutA()
{
$articles = $this->getArticles();
@ -36,7 +44,7 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testNextItemShortcutB()
@ -54,7 +62,25 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testNextItemShortcutC()
{
$articles = $this->getArticles();
$this->setArticleAsCurrentArticle($articles[0]);
$this->keys($this->getShortcutNextItemC());
$firstIsNotCurrentArticle = $this->waitForArticleIsNotCurrentArticle($articles[0]);
$secondIsCurrentArticle = $this->waitForArticleIsCurrentArticle($articles[1]);
$this->assertTrue($firstIsNotCurrentArticle, 'The first Article is still the current Article');
$this->assertTrue($secondIsCurrentArticle, 'The second Article is not the current Article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testPreviousItemA()
@ -67,12 +93,12 @@ class keyboardShortcutTest extends minifluxTestCase
$firstIsCurrentArticle = $this->waitForArticleIsCurrentArticle($articles[0]);
$secondIsNotCurrentArticle = $this->waitForArticleIsNotCurrentArticle($articles[1]);
$this->assertTrue($firstIsCurrentArticle, 'The first Article is not the current Article');
$this->assertTrue($firstIsCurrentArticle, 'The first article is not the current article');
$this->assertTrue($secondIsNotCurrentArticle, 'The second Article is still the current Article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testPreviousItemB()
@ -85,12 +111,30 @@ class keyboardShortcutTest extends minifluxTestCase
$firstIsCurrentArticle = $this->waitForArticleIsCurrentArticle($articles[0]);
$secondIsNotCurrentArticle = $this->waitForArticleIsNotCurrentArticle($articles[1]);
$this->assertTrue($firstIsCurrentArticle, 'The first Article is not the current Article');
$this->assertTrue($firstIsCurrentArticle, 'The first article is not the current article');
$this->assertTrue($secondIsNotCurrentArticle, 'The second Article is still the current Article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testPreviousItemC()
{
$articles = $this->getArticles();
$this->setArticleAsCurrentArticle($articles[1]);
$this->keys($this->getShortcutPreviousItemC());
$firstIsCurrentArticle = $this->waitForArticleIsCurrentArticle($articles[0]);
$secondIsNotCurrentArticle = $this->waitForArticleIsNotCurrentArticle($articles[1]);
$this->assertTrue($firstIsCurrentArticle, 'The first article is not the current article');
$this->assertTrue($secondIsNotCurrentArticle, 'The second Article is still the current Article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testNextStopsAtLastArticle()
@ -109,7 +153,7 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testPreviousStopsAtFirstArticle()
@ -124,11 +168,74 @@ class keyboardShortcutTest extends minifluxTestCase
$firstIsCurrentArticle = $this->waitForArticleIsCurrentArticle($articles[0]);
$this->assertTrue($lastIsNotCurrentArticle, 'The last Article is still the current Article');
$this->assertTrue($firstIsCurrentArticle, 'The first Article is not the current Article');
$this->assertTrue($firstIsCurrentArticle, 'The first article is not the current article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testSHIFTModifierIsDisabled()
{
if ($this->getBrowser() === "iexplore") {
$this->markTestSkipped('Modifier key test is not supported with Internet Explorer [Selenium issue #4973].');
}
$articles = $this->getArticles();
$this->setArticleAsCurrentArticle($articles[0]);
$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::SHIFT.$this->getShortcutNextItemC());
$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::SHIFT);
$firstIsNotCurrentArticle = $this->waitForArticleIsNotCurrentArticle($articles[0]);
$this->assertFalse($firstIsNotCurrentArticle, 'The first article is not the current article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testALTModifierIsDisabled()
{
if ($this->getBrowser() === "iexplore") {
$this->markTestSkipped('Modifier key test is not supported with Internet Explorer [Selenium issue #4973].');
}
$articles = $this->getArticles();
$this->setArticleAsCurrentArticle($articles[0]);
$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::ALT.$this->getShortcutNextItemB());
$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::ALT);
$firstIsNotCurrentArticle = $this->waitForArticleIsNotCurrentArticle($articles[0]);
$this->assertFalse($firstIsNotCurrentArticle, 'The first article is not the current article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testCTRLModifierIsDisabled()
{
if ($this->getBrowser() === "iexplore") {
$this->markTestSkipped('Modifier key test is not supported with Internet Explorer [Selenium issue #4973].');
}
$articles = $this->getArticles();
$this->setArticleAsCurrentArticle($articles[0]);
$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::CONTROL.$this->getShortcutNextItemB());
$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::CONTROL);
$firstIsNotCurrentArticle = $this->waitForArticleIsNotCurrentArticle($articles[0]);
$this->assertFalse($firstIsNotCurrentArticle, 'The first article is not the current article');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testShortcutsOnInputFiledAreDisabled()
@ -136,11 +243,13 @@ class keyboardShortcutTest extends minifluxTestCase
$url = $this->getURLPagePreferences();
$this->url($url);
$this->byId('form-username')->value($this->getShortcutGoToUnread());
$this->byId('form-username')->click();
$this->keys($this->getShortcutGoToUnread());
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedPageUrl = $url;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
$this->ignorePageTitle = TRUE;
}
@ -152,7 +261,7 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterPage = '6';
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedPageUrl = $this->getURLPageBookmarks();
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
$this->ignorePageTitle = TRUE;
}
@ -164,7 +273,7 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterPage = '6';
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedPageUrl = $this->getURLPageHistory();
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
$this->ignorePageTitle = TRUE;
}
@ -176,7 +285,7 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterPage = '6';
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedPageUrl = $this->getURLPageUnread();
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
$this->ignorePageTitle = TRUE;
}
@ -187,7 +296,7 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedPageUrl = PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL.'?action=feeds';
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
$this->ignorePageTitle = TRUE;
}
@ -198,7 +307,7 @@ class keyboardShortcutTest extends minifluxTestCase
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedPageUrl = $this->getURLPagePreferences();
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
$this->ignorePageTitle = TRUE;
}

View File

@ -1,5 +1,7 @@
<?php
use PHPUnit_Extensions_Selenium2TestCase_Keys as Keys;
abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
{
protected $basePageHeading = NULL;
@ -25,7 +27,8 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
parent::setUp();
// trigger database fixtures onSetUp routines
$this->getDatabaseTester('fixture_feed1', TRUE)->onSetUp();
$dataset = $this->getDataSet('fixture_feed1', 'fixture_feed2');
$this->getDatabaseTester($dataset)->onSetUp();
// Set the base URL for the tests.
$this->setBrowserUrl(PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL);
@ -40,7 +43,7 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
$elements = $this->elements($this->using('css selector')->value('body#login-page'));
if (count($elements) === 1) {
$this->url('?action=select-db&database='.DB_FILENAME);
$this->byCssSelector("input[value='".DB_FILENAME."']")->click();
$this->byId('form-username')->click();
$this->keys('admin');
@ -90,17 +93,14 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
PHPUnit_Extensions_Database_TestCase::assertDataSetsEqual($expectedDataSetFiltered, $actualDataSetFiltered, 'Unexpected changes in database');
}
protected function getDataSet($dataSetFile, $appendFeed2 = TRUE)
protected function getDataSet()
{
$compositeDs = new PHPUnit_Extensions_Database_DataSet_CompositeDataSet();
$dataSetFiles = func_get_args();
$ds1 = new PHPUnit_Extensions_Database_DataSet_XmlDataSet(dirname(__FILE__).DIRECTORY_SEPARATOR.'datasets'.DIRECTORY_SEPARATOR.$dataSetFile.'.xml');
$compositeDs->addDataSet($ds1);
if ($appendFeed2) {
// feed2 should be normaly untouched
$ds2 = new PHPUnit_Extensions_Database_DataSet_XmlDataSet(dirname(__FILE__).DIRECTORY_SEPARATOR.'datasets'.DIRECTORY_SEPARATOR.'fixture_feed2.xml');
$compositeDs->addDataSet($ds2);
foreach ($dataSetFiles as $dataSetFile) {
$ds = new PHPUnit_Extensions_Database_DataSet_XmlDataSet(dirname(__FILE__).DIRECTORY_SEPARATOR.'datasets'.DIRECTORY_SEPARATOR.$dataSetFile.'.xml');
$compositeDs->addDataSet($ds);
}
return $compositeDs;
@ -140,16 +140,15 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
return static::$databaseConnection;
}
protected function getDatabaseTester($dataSetFile, $appendFeed2)
protected function getDatabaseTester($dataset)
{
if (is_null(static::$databaseTester)) {
$tester = new PHPUnit_Extensions_Database_DefaultTester($this->getConnection());
// article/feed import on database->onSetUp();
$tester->setSetUpOperation(PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT());
$dataset = $this->getDataSet($dataSetFile, $appendFeed2);
$rdataset = new PHPUnit_Extensions_Database_DataSet_ReplacementDataSet($dataset);
$rdataset->addSubStrReplacement('##TIMESTAMP##', substr((string)(time()-100), 0, -2));
// article/feed import on database->onSetUp();
$tester = new PHPUnit_Extensions_Database_DefaultTester($this->getConnection());
$tester->setSetUpOperation(PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT());
$tester->setDataSet($rdataset);
static::$databaseTester = $tester;
@ -177,18 +176,35 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
return $value;
}
// public to be accessible within an closure
public function isElementVisible($element)
{
$displaySize = $element->size();
return ($element->displayed() && $displaySize['height']>0 && $displaySize['width']>0);
}
// public to be accessible within an closure
public function isElementInvisible($element)
{
$displaySize = $element->size();
return ($element->displayed() === FALSE || $displaySize['height']=0 || $displaySize['width']=0);
}
private function waitForElementVisibility($element, $visible)
{
// return false in case of timeout
try {
$value = $this->waitUntil(function() use($element, $visible) {
// Workaround for PHP < 5.4
$CI = $this;
$value = $this->waitUntil(function() use($CI, $element, $visible) {
// a "No such Element" or "Stale Element Reference" exception is
// valid if an object should disappear
try {
$displaySize = $element->size();
if ((($visible === TRUE) && ($element->displayed() && $displaySize['height']>0 && $displaySize['width']>0))
|| (($visible === FALSE) && ($element->displayed() === FALSE || $displaySize['height']=0 || $displaySize['width']=0))) {
if (($visible && $CI->isElementVisible($element))
|| (! $visible && $CI->isElementInvisible($element))) {
return TRUE;
}
}
@ -329,6 +345,11 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
return PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL.'?action=config';
}
public function getURLPageSubscriptions()
{
return PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL.'?action=feeds';
}
public function getShortcutNextItemA()
{
return 'n';
@ -339,6 +360,11 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
return 'j';
}
public function getShortcutNextItemC()
{
return PHPUnit_Extensions_Selenium2TestCase_Keys::RIGHT;
}
public function getShortcutPreviousItemA()
{
return 'p';
@ -349,6 +375,11 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
return 'k';
}
public function getShortcutPreviousItemC()
{
return PHPUnit_Extensions_Selenium2TestCase_Keys::LEFT;
}
public function getShortcutToogleReadStatus()
{
return 'm';
@ -404,6 +435,43 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
return $articles;
}
public function getFeedFailed()
{
$cssSelector = 'article[data-feed-id="4"]';
$feed = $this->element($this->using('css selector')->value($cssSelector));
return $feed;
}
public function getFeedDisabled()
{
$cssSelector = 'article[data-feed-id="2"]';
$feed = $this->element($this->using('css selector')->value($cssSelector));
return $feed;
}
public function getFeedErrorMessages()
{
$cssSelector = 'article .feed-parsing-error';
if (func_num_args() === 0) {
$feed = $this;
}
else {
$feed = func_get_arg(0);
}
$feeds = $feed->elements($this->using('css selector')->value($cssSelector));
// Workaround for PHP < 5.4
$CI = $this;
return array_filter($feeds, function($feed) use($CI) {
return $CI->isElementVisible($feed);
});
}
public function getArticleUnreadNotBookmarked()
{
$cssSelector = 'article[data-item-id="7c6afaa5"]';
@ -490,6 +558,14 @@ abstract class minifluxTestCase extends PHPUnit_Extensions_Selenium2TestCase
return $link;
}
public function getAlertBox()
{
$cssSelector = 'p.alert';
$alertBox = $this->elements($this->using('css selector')->value($cssSelector));
return $alertBox;
}
public function waitForArticleIsCurrentArticle($article)
{
$isCurrent = $this->waitForElementAttributeHasValue($article, 'id', 'current-item');

View File

@ -1,7 +1,5 @@
<?php
require_once 'minifluxTestCase.php';
class pageBookmarksTest extends minifluxTestCase
{
const DEFAULT_COUNTER_PAGE = 6;
@ -21,6 +19,16 @@ class pageBookmarksTest extends minifluxTestCase
return "$this->basePageHeading ($this->expectedCounterPage)";
}
public function testNoAlertShown()
{
$alertBox = $this->getAlertBox();
$this->assertEmpty($alertBox, 'Unexpected alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testItemsFromAllFeeds()
{
$articles = $this->getArticlesNotFromFeedOne();
@ -28,7 +36,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testOnlyBookmarkedArticles()
@ -38,7 +46,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testMarkReadBookmarkedArticleLink()
@ -52,8 +60,8 @@ class pageBookmarksTest extends minifluxTestCase
$this->assertTrue($visible, 'read icon is not visible');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle');
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkReadBookmarkedArticleKeyboard()
@ -67,8 +75,8 @@ class pageBookmarksTest extends minifluxTestCase
$this->assertTrue($visible, 'read icon is not visible');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle');
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadBookmarkedArticleLink()
@ -82,8 +90,8 @@ class pageBookmarksTest extends minifluxTestCase
$this->assertTrue($invisible, 'read icon is not invisible');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle');
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadBookmarkedArticleKeyboard()
@ -97,8 +105,8 @@ class pageBookmarksTest extends minifluxTestCase
$this->assertTrue($invisible, 'read icon is not invisible');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle');
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testUnbookmarkReadArticleLink()
@ -113,7 +121,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle', 'fixture_feed2');
}
@ -129,7 +137,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle', 'fixture_feed2');
}
public function testUnbookmarkUnreadArticleLink()
@ -144,7 +152,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle', 'fixture_feed2');
}
public function testUnbookmarkUnreadArticleKeyboard()
@ -159,7 +167,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle', 'fixture_feed2');
}
public function testRemoveReadBookmarkedArticleLink()
@ -174,7 +182,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadBookmarkedArticle', 'fixture_feed2');
}
public function testRemoveUnreadBookmarkedArticleLink()
@ -189,7 +197,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testUnreadCounterFromNothingToValue()
@ -198,7 +206,9 @@ class pageBookmarksTest extends minifluxTestCase
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$this->getDatabaseTester('fixture_OnlyReadArticles', FALSE)->onSetUp();
$dataset = $this->getDataSet('fixture_OnlyReadArticles');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
@ -214,7 +224,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = 1;
$this->expectedDataSet = $this->getDataSet('fixture_OneUnreadArticle',FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OneUnreadArticle');
}
public function testUnreadCounterFromValueToNothing()
@ -223,7 +233,9 @@ class pageBookmarksTest extends minifluxTestCase
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$this->getDatabaseTester('fixture_OneUnreadArticle', FALSE)->onSetUp();
$dataset = $this->getDataSet('fixture_OneUnreadArticle');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
@ -238,7 +250,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = '';
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles',FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles');
}
public function testRedirectWithZeroArticles()
@ -257,7 +269,7 @@ class pageBookmarksTest extends minifluxTestCase
$this->expectedCounterPage = NULL;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_NoBookmarkedArticles', FALSE);
$this->expectedDataSet = $this->getDataSet('expected_NoBookmarkedArticles');
$this->ignorePageTitle = TRUE;
}

View File

@ -1,7 +1,5 @@
<?php
require_once 'minifluxTestCase.php';
class pageFirstFeedTest extends minifluxTestCase
{
const DEFAULT_COUNTER_PAGE = 8;
@ -21,6 +19,37 @@ class pageFirstFeedTest extends minifluxTestCase
return "($this->expectedCounterPage) $this->basePageHeading";
}
public function testNoAlertShown()
{
$alertBox = $this->getAlertBox();
$this->assertEmpty($alertBox, 'Unexpected alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testAlertOnParsingError()
{
// load different fixture and reload the page
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$dataset = $this->getDataSet('fixture_feed1_parsing_error', 'fixture_feed2');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
$alertBox = $this->getAlertBox();
$this->assertCount(1, $alertBox, 'No alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $dataset;
}
public function testOnlyItemsFromFirstFeed()
{
$articles = $this->getArticlesNotFromFeedOne();
@ -28,7 +57,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testMarkReadNotBookmarkedArticleLink()
@ -43,7 +72,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkReadNotBookmarkedArticleKeyboard()
@ -58,7 +87,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkReadBookmarkedArticleLink()
@ -73,7 +102,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkReadBookmarkedArticleKeyboard()
@ -88,7 +117,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadNotBookmarkedArticleLink()
@ -103,7 +132,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadNotBookmarkedArticleKeyboard()
@ -118,7 +147,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadBookmarkedArticleLink()
@ -133,7 +162,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadBookmarkedArticleKeyboard()
@ -148,7 +177,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testBookmarkReadArticleLink()
@ -163,7 +192,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle', 'fixture_feed2');
}
public function testBookmarkReadArticleKeyboard()
@ -178,7 +207,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle', 'fixture_feed2');
}
public function testBookmarkUnreadArticleLink()
@ -193,7 +222,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle', 'fixture_feed2');
}
public function testBookmarkUnreadArticleKeyboard()
@ -208,7 +237,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle', 'fixture_feed2');
}
public function testUnbookmarkReadArticleLink()
@ -223,7 +252,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle', 'fixture_feed2');
}
public function testUnbookmarkReadArticleKeyboard()
@ -238,7 +267,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle', 'fixture_feed2');
}
public function testUnbookmarkUnreadArticleLink()
@ -253,7 +282,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle', 'fixture_feed2');
}
public function testUnbookmarkUnreadArticleKeyboard()
@ -268,7 +297,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle', 'fixture_feed2');
}
public function testRemoveReadNotBookmarkedArticleLink()
@ -283,7 +312,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadNotBookmarkedArticle', 'fixture_feed2');
}
public function testRemoveReadBookmarkedArticleLink()
@ -298,7 +327,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadBookmarkedArticle', 'fixture_feed2');
}
public function testRemoveUnreadNotBookmarkedArticleLink()
@ -313,7 +342,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadNotBookmarkedArticle', 'fixture_feed2');
}
public function testRemoveUnreadBookmarkedArticleLink()
@ -328,7 +357,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkFeedReadHeaderLink()
@ -341,7 +370,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = 2;
$this->expectedDataSet = $this->getDataSet('expected_MarkFeedRead');
$this->expectedDataSet = $this->getDataSet('expected_MarkFeedRead', 'fixture_feed2');
}
public function testMarkFeedReadBottomLink()
@ -354,7 +383,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = 2;
$this->expectedDataSet = $this->getDataSet('expected_MarkFeedRead');
$this->expectedDataSet = $this->getDataSet('expected_MarkFeedRead', 'fixture_feed2');
}
public function testUnreadCounterFromNothingToValue()
@ -363,7 +392,9 @@ class pageFirstFeedTest extends minifluxTestCase
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$this->getDatabaseTester('fixture_OnlyReadArticles', FALSE)->onSetUp();
$dataset = $this->getDataSet('fixture_OnlyReadArticles');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
@ -379,7 +410,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = 1;
$this->expectedDataSet = $this->getDataSet('fixture_OneUnreadArticle',FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OneUnreadArticle');
}
public function testUnreadCounterFromValueToNothing()
@ -388,7 +419,9 @@ class pageFirstFeedTest extends minifluxTestCase
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$this->getDatabaseTester('fixture_OneUnreadArticle', FALSE)->onSetUp();
$dataset = $this->getDataSet('fixture_OneUnreadArticle');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
@ -403,7 +436,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = '';
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles',FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles');
}
public function testRedirectWithZeroArticles()
@ -423,7 +456,7 @@ class pageFirstFeedTest extends minifluxTestCase
$this->expectedCounterPage = NULL;
$this->expectedCounterUnread = 2;
$this->expectedDataSet = $this->getDataSet('expected_FirstFeedAllRemoved');
$this->expectedDataSet = $this->getDataSet('expected_FirstFeedAllRemoved', 'fixture_feed2');
$this->ignorePageTitle = TRUE;
}

View File

@ -1,7 +1,5 @@
<?php
require_once 'minifluxTestCase.php';
class pageHistoryTest extends minifluxTestCase
{
const DEFAULT_COUNTER_PAGE = 6;
@ -21,6 +19,16 @@ class pageHistoryTest extends minifluxTestCase
return "$this->basePageHeading ($this->expectedCounterPage)";
}
public function testNoAlertShown()
{
$alertBox = $this->getAlertBox();
$this->assertEmpty($alertBox, 'Unexpected alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testItemsFromAllFeeds()
{
$articles = $this->getArticlesNotFromFeedOne();
@ -28,7 +36,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testOnlyReadArticles()
@ -38,7 +46,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testMarkUnreadNotBookmarkedArticleLink()
@ -53,7 +61,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadNotBookmarkedArticleKeyboard()
@ -68,7 +76,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadBookmarkedArticleLink()
@ -83,7 +91,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkUnreadBookmarkedArticleKeyboard()
@ -98,7 +106,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testBookmarkReadArticleLink()
@ -113,7 +121,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle', 'fixture_feed2');
}
public function testBookmarkReadArticleKeyboard()
@ -128,7 +136,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkReadArticle', 'fixture_feed2');
}
public function testUnbookmarkReadArticleLink()
@ -143,7 +151,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle', 'fixture_feed2');
}
public function testUnbookmarkReadArticleKeyboard()
@ -158,7 +166,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkReadArticle', 'fixture_feed2');
}
public function testRemoveReadNotBookmarkedArticleLink()
@ -173,7 +181,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadNotBookmarkedArticle', 'fixture_feed2');
}
public function testRemoveReadBookmarkedArticleLink()
@ -188,7 +196,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveReadBookmarkedArticle', 'fixture_feed2');
}
public function testFlushAllKeepsBookmarkedAndUnread()
@ -201,7 +209,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = 3;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_NoReadNotBookmarkedArticles', FALSE);
$this->expectedDataSet = $this->getDataSet('expected_NoReadNotBookmarkedArticles');
$this->ignorePageTitle = TRUE;
}
@ -212,7 +220,9 @@ class pageHistoryTest extends minifluxTestCase
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$this->getDatabaseTester('fixture_OnlyReadArticles', FALSE)->onSetUp();
$dataset = $this->getDataSet('fixture_OnlyReadArticles');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
@ -228,7 +238,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE + static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedCounterUnread = 1;
$this->expectedDataSet = $this->getDataSet('fixture_OneUnreadArticle',FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OneUnreadArticle');
}
public function testRedirectWithZeroArticles()
@ -248,7 +258,7 @@ class pageHistoryTest extends minifluxTestCase
$this->expectedCounterPage = NULL;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD + static::DEFAULT_COUNTER_PAGE;
$this->expectedDataSet = $this->getDataSet('expected_NoReadArticles', FALSE);
$this->expectedDataSet = $this->getDataSet('expected_NoReadArticles');
$this->ignorePageTitle = TRUE;
}

View File

@ -0,0 +1,130 @@
<?php
class pageSubscriptionTest extends minifluxTestCase
{
const DEFAULT_COUNTER_PAGE = null;
const DEFAULT_COUNTER_UNREAD = 3;
protected function setUp()
{
// trigger database fixtures onSetUp routines
$dataset = $this->getDataSet('fixture_feed_error_disabled_normal');
$this->getDatabaseTester($dataset)->onSetUp();
// Set the base URL for the tests.
$this->setBrowserUrl(PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL);
}
public function setUpPage()
{
$url = $this->getURLPageSubscriptions();
$this->doLoginIfRequired($url);
$this->basePageHeading = $this->getBasePageHeading();
$this->expectedPageUrl = $url;
}
public function getExpectedPageTitle()
{
return "$this->basePageHeading";
}
public function testNoAlertShown()
{
// load different fixture and reload the page
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$dataset = $this->getDataSet('fixture_feed1', 'fixture_feed2');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
$alertBox = $this->getAlertBox();
$this->assertEmpty($alertBox, 'Unexpected alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = 6;
$this->expectedDataSet = $dataset;
}
public function testNoPerFeedErrorMessages()
{
// load different fixture and reload the page
$backupDataTester = static::$databaseTester;
static::$databaseTester = NULL;
$dataset = $this->getDataSet('fixture_feed1', 'fixture_feed2');
$this->getDatabaseTester($dataset)->onSetUp();
static::$databaseTester = $backupDataTester;
$this->refresh();
$messages = $this->getFeedErrorMessages();
$this->assertCount(0, $messages, 'Feeds have unexpected error messages visible.');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = 6;
$this->expectedDataSet = $dataset;
}
public function testAlertOnParsingError()
{
$alertBox = $this->getAlertBox();
$this->assertCount(1, $alertBox, 'No alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testFailedFeedIsFirstFeed()
{
$feeds = $this->getArticles();
$this->assertEquals($this->getFeedFailed(), $feeds[0], 'The first feed is not the failed feed');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testFailedFeedIsHighlighted()
{
$feeds = $this->getArticles();
$this->assertNotEquals($feeds[0]->css('background-color'), $feeds[1]->css('background-color'), 'The failed feed is not highlighted');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testFailedHasErrorMessageVisible()
{
$feed = $this->getFeedFailed();
$this->assertCount(1, $this->getFeedErrorMessages($feed), 'The failed feed has no error message');
$this->assertCount(1, $this->getFeedErrorMessages(), 'Another than the failed feed has an error message');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testDisabledIsLastFeed()
{
$feeds = $this->getArticles();
$this->assertEquals($this->getFeedDisabled(), $feeds[count($feeds)-1], 'The disabled feed is not the last feed');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
}
?>

View File

@ -1,7 +1,5 @@
<?php
require_once 'minifluxTestCase.php';
class pageUnreadTest extends minifluxTestCase
{
const DEFAULT_COUNTER_PAGE = 6;
@ -21,6 +19,16 @@ class pageUnreadTest extends minifluxTestCase
return "Miniflux ($this->expectedCounterPage)";
}
public function testNoAlertShown()
{
$alertBox = $this->getAlertBox();
$this->assertEmpty($alertBox, 'Unexpected alert box found');
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testItemsFromAllFeeds()
{
$articles = $this->getArticlesNotFromFeedOne();
@ -28,7 +36,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testOnlyUnreadArticles()
@ -38,7 +46,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('fixture_feed1');
$this->expectedDataSet = static::$databaseTester->getDataSet();
}
public function testMarkReadNotBookmarkedArticleLink()
@ -53,7 +61,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkReadNotBookmarkedArticleKeyboard()
@ -68,7 +76,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadNotBookmarkedArticle', 'fixture_feed2');
}
public function testMarkReadBookmarkedArticleLink()
@ -83,7 +91,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkReadBookmarkedArticleKeyboard()
@ -98,7 +106,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_MarkReadBookmarkedArticle', 'fixture_feed2');
}
public function testBookmarkUnreadArticleLink()
@ -113,7 +121,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle', 'fixture_feed2');
}
public function testBookmarkUnreadArticleKeyboard()
@ -128,7 +136,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_BookmarkUnreadArticle', 'fixture_feed2');
}
public function testUnbookmarkUnreadArticleLink()
@ -143,7 +151,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle', 'fixture_feed2');
}
public function testUnbookmarkUnreadArticleKeyboard()
@ -158,7 +166,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD;
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle');
$this->expectedDataSet = $this->getDataSet('expected_UnbookmarkUnreadArticle', 'fixture_feed2');
}
public function testRemoveUnreadNotBookmarkedArticleLink()
@ -173,7 +181,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadNotBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadNotBookmarkedArticle', 'fixture_feed2');
}
public function testRemoveUnreadBookmarkedArticleLink()
@ -188,7 +196,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = static::DEFAULT_COUNTER_PAGE - 1;
$this->expectedCounterUnread = static::DEFAULT_COUNTER_UNREAD - 1;
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadBookmarkedArticle');
$this->expectedDataSet = $this->getDataSet('expected_RemoveUnreadBookmarkedArticle', 'fixture_feed2');
}
public function testMarkAllReadHeaderLink()
@ -202,7 +210,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = NULL;
$this->expectedCounterUnread = '';
$this->expectedPageUrl = PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL.'?action=feeds&nothing_to_read=1';
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles', FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles');
$this->ignorePageTitle = TRUE;
}
@ -218,7 +226,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = NULL;
$this->expectedCounterUnread = '';
$this->expectedPageUrl = PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL.'?action=feeds&nothing_to_read=1';
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles', FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles');
$this->ignorePageTitle = TRUE;
}
@ -241,7 +249,7 @@ class pageUnreadTest extends minifluxTestCase
$this->expectedCounterPage = NULL;
$this->expectedCounterUnread = '';
$this->expectedPageUrl = PHPUNIT_TESTSUITE_EXTENSION_SELENIUM_BASEURL.'?action=feeds&nothing_to_read=1';
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles', FALSE);
$this->expectedDataSet = $this->getDataSet('fixture_OnlyReadArticles');
$this->ignorePageTitle = TRUE;
}

2
vendor/autoload.php vendored
View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInit1aea6e0e97930d7617e83f53a5287aca::getLoader();
return ComposerAutoloaderInitdd123afa0ab8d569c051c35ab70311cb::getLoader();

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit1aea6e0e97930d7617e83f53a5287aca
class ComposerAutoloaderInitdd123afa0ab8d569c051c35ab70311cb
{
private static $loader;
@ -19,9 +19,9 @@ class ComposerAutoloaderInit1aea6e0e97930d7617e83f53a5287aca
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit1aea6e0e97930d7617e83f53a5287aca', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitdd123afa0ab8d569c051c35ab70311cb', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit1aea6e0e97930d7617e83f53a5287aca', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitdd123afa0ab8d569c051c35ab70311cb', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
@ -42,14 +42,14 @@ class ComposerAutoloaderInit1aea6e0e97930d7617e83f53a5287aca
$includeFiles = require __DIR__ . '/autoload_files.php';
foreach ($includeFiles as $file) {
composerRequire1aea6e0e97930d7617e83f53a5287aca($file);
composerRequiredd123afa0ab8d569c051c35ab70311cb($file);
}
return $loader;
}
}
function composerRequire1aea6e0e97930d7617e83f53a5287aca($file)
function composerRequiredd123afa0ab8d569c051c35ab70311cb($file)
{
require $file;
}

View File

@ -162,12 +162,12 @@
"source": {
"type": "git",
"url": "https://github.com/fguillot/picoFeed.git",
"reference": "d3785fc54d0bf9d521fd85e369cc5600f66099cc"
"reference": "f3ed9fef18b4cd0d25a1fd389c8a2e2370bcb51b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/picoFeed/zipball/d3785fc54d0bf9d521fd85e369cc5600f66099cc",
"reference": "d3785fc54d0bf9d521fd85e369cc5600f66099cc",
"reference": "f3ed9fef18b4cd0d25a1fd389c8a2e2370bcb51b",
"shasum": ""
},
"require": {

View File

@ -21,6 +21,21 @@ PicoFeed will try first to find the favicon from the meta tags and fallback to t
When the HTML page is parsed, relative links and protocol relative links are converted to absolute url.
Download a know favicon
-----------------------
It's possible to download a known favicon using the second optional parameter of Favicon::find(). The link to the favicon can be a relative or protocol relative url as well, but it has to be relative to the specified website.
If the requested favicon could not be found, the HTML of the website is parsed instead, with the fallback to the `favicon.ico` located in the website's root.
```php
use PicoFeed\Reader\Favicon;
$favicon = new Favicon;
$icon_link = $favicon->find('https://en.wikipedia.org/','https://bits.wikimedia.org/favicon/wikipedia.ico');
$icon_content = $favicon->getContent();
```
Get Favicon file type
---------------------

View File

@ -183,6 +183,7 @@ class Curl extends Client
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'readHeaders'));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'php://memory');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'php://memory');
curl_setopt($ch, CURLOPT_SSLVERSION, 1); // Enforce TLS v1
$ch = $this->prepareProxyContext($ch);
$ch = $this->prepareAuthContext($ch);

View File

@ -171,6 +171,35 @@ class Grabber
return $this;
}
/**
* Get URL to download.
*
* @access public
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Set URL to download and reset object to use for another grab.
*
* @access public
* @param string $url URL
* @return string
*/
public function setUrl($url)
{
$this->url = $url;
$this->html = "";
$this->content = "";
$this->encoding = "";
$this->handleFiles();
$this->handleStreamingVideos();
}
/**
* Get relevant content
*
@ -284,7 +313,7 @@ class Grabber
*/
public function download()
{
if (! $this->skip_processing) {
if (! $this->skip_processing && $this->url != '') {
try {

View File

@ -74,6 +74,18 @@ class Atom extends Parser
$feed->logo = (string) $xml->logo;
}
/**
* Find the feed icon
*
* @access public
* @param SimpleXMLElement $xml Feed xml
* @param \PicoFeed\Parser\Feed $feed Feed object
*/
public function findFeedIcon(SimpleXMLElement $xml, Feed $feed)
{
$feed->icon = (string) $xml->icon;
}
/**
* Find the feed title
*

View File

@ -75,13 +75,21 @@ class Feed
public $language = '';
/**
* Feed logo URL (not the same as icon)
* Feed logo URL
*
* @access public
* @var string
*/
public $logo = '';
/**
* Feed icon URL
*
* @access public
* @var string
*/
public $icon = '';
/**
* Return feed information
*
@ -140,6 +148,17 @@ class Feed
return $this->logo;
}
/**
* Get the icon url
*
* @access public
* $return string
*/
public function getIcon()
{
return $this->icon;
}
/**
* Get feed url
*

View File

@ -149,6 +149,7 @@ abstract class Parser
$this->findFeedId($xml, $feed);
$this->findFeedDate($xml, $feed);
$this->findFeedLogo($xml, $feed);
$this->findFeedIcon($xml, $feed);
foreach ($this->getItemsTree($xml) as $entry) {
@ -549,6 +550,15 @@ abstract class Parser
*/
public abstract function findFeedLogo(SimpleXMLElement $xml, Feed $feed);
/**
* Find the feed icon
*
* @access public
* @param SimpleXMLElement $xml Feed xml
* @param \PicoFeed\Parser\Feed $feed Feed object
*/
public abstract function findFeedIcon(SimpleXMLElement $xml, Feed $feed);
/**
* Get the path to the items XML tree
*

View File

@ -76,6 +76,18 @@ class Rss20 extends Parser
}
}
/**
* Find the feed icon
*
* @access public
* @param SimpleXMLElement $xml Feed xml
* @param \PicoFeed\Parser\Feed $feed Feed object
*/
public function findFeedIcon(SimpleXMLElement $xml, Feed $feed)
{
$feed->icon = '';
}
/**
* Find the feed title
*

View File

@ -157,17 +157,21 @@ class Favicon
*
* @access public
* @param string $website_link URL
* @param string $favicon_link optional URL
* @return string
*/
public function find($website_link)
public function find($website_link, $favicon_link = '')
{
$website = new Url($website_link);
if ($favicon_link !== '') {
$icons = array($favicon_link);
} else {
$icons = $this->extract($this->download($website->getBaseUrl('/'))->getContent());
$icons[] = $website->getBaseUrl('/favicon.ico');
}
foreach ($icons as $icon_link) {
$icon_link = $this->convertLink($website, new Url($icon_link));
$resource = $this->download($icon_link);
$this->content = $resource->getContent();
@ -175,6 +179,8 @@ class Favicon
if ($this->content !== '') {
return $icon_link;
} elseif ($favicon_link !== '') {
return $this->find($website_link);
}
}

View File

@ -1,17 +1,20 @@
<?php
return array(
'test_url' => 'http://www.allgemeine-zeitung.de/lokales/polizei/zweimal-totalschaden-nach-unfaellen-auf-eisglatten-fahrbahnen-bei-mainz-und-bei-bad-sobernheim-mit-baeumen-kollidiert_14904737.htm',
'test_url' => 'http://www.allgemeine-zeitung.de/lokales/polizei/mainz-gonsenheim-unbekannte-rauben-esso-tankstelle-in-kurt-schumacher-strasse-aus_14913147.htm',
'body' => array(
'//div[contains(@class, "article")][1]',
),
'strip' => array(
'//read/h1',
'//*[@id="t-map"]',
'//*[contains(@class, "modules")]',
'//*[contains(@class, "adsense")]',
'//*[contains(@class, "linkbox")]',
'//*[contains(@class, "info")]',
'//*[@class="skip"]',
'//*[@class="funcs"]',
'//span[@class="nd address"]',
'//a[contains(@href, "abo-und-services")]'
)
);

View File

@ -36,6 +36,14 @@ class GrabberTest extends PHPUnit_Framework_TestCase
$this->assertTrue(is_array($grabber->getRules()));
}
// 01net.com - https://github.com/fguillot/miniflux/issues/267
public function testGetRules_afterRedirection()
{
$grabber = new Grabber('http://rss.feedsportal.com/c/629/f/502199/s/422f8c8a/sc/44/l/0L0S0A1net0N0Ceditorial0C640A3130Cces0E20A150Eimprimer0Eune0Epizza0Eet0Edes0Ebiscuits0Evideo0C0T0Dxtor0FRSS0E16/story01.htm');
$grabber->download();
$this->assertTrue(is_array($grabber->getRules()));
}
public function testGrabContent()
{
$grabber = new Grabber('http://www.egscomics.com/index.php?id=1690');

View File

@ -14,6 +14,10 @@ class FilterTest extends PHPUnit_Framework_TestCase
$expected = '<html><body><h1>boo</h1></body>';
$this->assertEquals($expected, Filter::stripHeadTags($input));
$input = file_get_contents('tests/fixtures/html4_page.html');
$expected = file_get_contents('tests/fixtures/html4_head_stripped_page.html');
$this->assertEquals($expected, Filter::stripHeadTags($input));
$input = file_get_contents('tests/fixtures/html_page.html');
$expected = file_get_contents('tests/fixtures/html_head_stripped_page.html');
$this->assertEquals($expected, Filter::stripHeadTags($input));

View File

@ -47,6 +47,17 @@ class AtomParserTest extends PHPUnit_Framework_TestCase
$this->assertEquals('http://www.bbc.co.uk/urdu/images/gel/rss_logo.gif', $feed->getLogo());
}
public function testFeedIcon()
{
$parser = new Atom(file_get_contents('tests/fixtures/atom.xml'));
$feed = $parser->execute();
$this->assertEquals('', $feed->getIcon());
$parser = new Atom(file_get_contents('tests/fixtures/lagrange.xml'));
$feed = $parser->execute();
$this->assertEquals('http://www.la-grange.net/favicon.png', $feed->getIcon());
}
public function testFeedUrl()
{
$parser = new Atom(file_get_contents('tests/fixtures/atom.xml'));

View File

@ -11,137 +11,218 @@ class FaviconTest extends PHPUnit_Framework_TestCase
{
$favicon = new Favicon;
$html = '<!DOCTYPE html><html><head>
<link rel="shortcut icon" href="http://example.com/myicon.ico" />
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/myicon.ico'), $favicon->extract($html));
$html = '<!DOCTYPE html><html><head>
<link rel="icon" href="http://example.com/myicon.ico" />
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/myicon.ico'), $favicon->extract($html));
// multiple values in rel attribute
$html = '<!DOCTYPE html><html><head>
<link rel="shortcut icon" href="http://example.com/myicon.ico" />
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/myicon.ico'), $favicon->extract($html));
// icon part of another string
$html = '<!DOCTYPE html><html><head>
<link rel="fluid-icon" href="http://example.com/myicon.ico" />
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/myicon.ico'), $favicon->extract($html));
// with other attributes present
$html = '<!DOCTYPE html><html><head>
<link rel="icon" type="image/vnd.microsoft.icon" href="http://example.com/image.ico" />
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/image.ico'), $favicon->extract($html));
// ignore icon in other attribute
$html = '<!DOCTYPE html><html><head>
<link type="icon" href="http://example.com/image.ico" />
</head><body><p>boo</p></body></html>';
// ignores apple icon
$html = '<!DOCTYPE html><html><head>
<link rel="apple-touch-icon" href="assets/img/touch-icon-iphone.png">
<link rel="icon" type="image/png" href="http://example.com/image.png" />
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/image.png'), $favicon->extract($html));
// allows multiple icons
$html = '<!DOCTYPE html><html><head>
<link rel="icon" type="image/gif" href="http://example.com/image.gif" />
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/image.gif'), $favicon->extract($html));
$html = '<!DOCTYPE html><html><head>
<link rel="icon" type="image/x-icon" href="http://example.com/image.ico"/>
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/image.ico'), $favicon->extract($html));
$html = '<!DOCTYPE html><html><head>
<link rel="apple-touch-icon" href="assets/img/touch-icon-iphone.png">
<link rel="icon" type="image/png" href="http://example.com/image.png" />
<link rel="icon" type="image/x-icon" href="http://example.com/image.ico"/>
</head><body><p>boo</p></body></html>';
$this->assertEquals(array('http://example.com/image.png', 'http://example.com/image.ico'), $favicon->extract($html));
// empty array with broken html
$html = '!DOCTYPE html html head
link rel="icon" type="image/png" href="http://example.com/image.png" /
link rel="icon" type="image/x-icon" href="http://example.com/image.ico"/
/head body /p boo /p body /html';
$this->assertEquals(array(), $favicon->extract($html));
// empty array on no input
$this->assertEquals(array(), $favicon->extract(''));
// empty array on no icon found
$html = '<!DOCTYPE html><html><head>
</head><body><p>boo</p></body></html>';
$this->assertEquals(array(), $favicon->extract($html));
}
/*
public function testHasFile()
public function testExists()
{
$favicon = new Favicon;
$this->assertTrue($favicon->exists('https://en.wikipedia.org/favicon.ico'));
$this->assertFalse($favicon->exists('http://minicoders.com/favicon.ico'));
$this->assertFalse($favicon->exists('http://blabla'));
$this->assertFalse($favicon->exists(''));
}
*/
public function testConvertLink()
{
$favicon = new Favicon;
// relative link
$this->assertEquals(
'http://miniflux.net/assets/img/favicon.png',
$favicon->convertLink(new Url('http://miniflux.net'), new Url('assets/img/favicon.png'))
);
// relative link + HTTPS
$this->assertEquals(
'https://miniflux.net/assets/img/favicon.png',
$favicon->convertLink(new Url('https://miniflux.net'), new Url('assets/img/favicon.png'))
);
// absolute link
$this->assertEquals(
'http://miniflux.net/assets/img/favicon.png',
$favicon->convertLink(new Url('http://miniflux.net'), new Url('/assets/img/favicon.png'))
);
// absolute link + HTTPS
$this->assertEquals(
'https://miniflux.net/assets/img/favicon.png',
$favicon->convertLink(new Url('https://miniflux.net'), new Url('/assets/img/favicon.png'))
);
// Protocol relative link
$this->assertEquals(
'http://google.com/assets/img/favicon.png',
$favicon->convertLink(new Url('http://miniflux.net'), new Url('//google.com/assets/img/favicon.png'))
);
// Protocol relative link + HTTPS
$this->assertEquals(
'https://google.com/assets/img/favicon.png',
$favicon->convertLink(new Url('https://miniflux.net'), new Url('//google.com/assets/img/favicon.png'))
);
// URL same fqdn
$this->assertEquals(
'http://miniflux.net/assets/img/favicon.png',
$favicon->convertLink(new Url('https://miniflux.net'), new Url('http://miniflux.net/assets/img/favicon.png'))
);
// URL different fqdn
$this->assertEquals(
'https://www.google.com/assets/img/favicon.png',
$favicon->convertLink(new Url('https://miniflux.net'), new Url('https://www.google.com/assets/img/favicon.png'))
);
// HTTPS URL
$this->assertEquals(
'https://miniflux.net/assets/img/favicon.png',
$favicon->convertLink(new Url('https://miniflux.net'), new Url('https://miniflux.net/assets/img/favicon.png'))
);
// empty string on missing website parameter
$this->assertEquals(
'',
$favicon->convertLink(new Url(''), new Url('favicon.png'))
);
// website only on missing icon parameter
$this->assertEquals(
'https://miniflux.net/',
$favicon->convertLink(new Url('https://miniflux.net'), new Url(''))
);
// empty string on missing website and icon parameter
$this->assertEquals(
'',
$favicon->convertLink(new Url(''), new Url(''))
);
}
public function testFind()
public function testFind_inMeta()
{
$favicon = new Favicon;
// Relative favicon in html
// favicon in meta
$this->assertEquals(
'http://miniflux.net/assets/img/favicon.png',
$favicon->find('http://miniflux.net')
);
$this->assertNotEmpty($favicon->getContent());
}
// Absolute html favicon
$this->assertEquals(
'http://php.net/favicon.ico',
$favicon->find('http://php.net/parse_url')
);
// public function testFind_inRootDir()
// {
// // favicon not in meta, only in website root (need example page)
// $favicon = new Favicon;
//
// $this->assertEquals(
// 'http://minicoders.com/favicon.ico',
// $favicon->find('http://minicoders.com')
// );
// }
$this->assertNotEmpty($favicon->getContent());
public function testFind_noIcons()
{
$favicon = new Favicon;
// Protocol relative favicon
$this->assertEquals(
'https://bits.wikimedia.org/favicon/wikipedia.ico',
$favicon->find('https://en.wikipedia.org/')
);
$this->assertNotEmpty($favicon->getContent());
// fluid-icon + https
$this->assertEquals(
'https://github.com/fluidicon.png',
$favicon->find('https://github.com')
);
$this->assertNotEmpty($favicon->getContent());
// favicon in meta
$this->assertEquals(
'http://www.microsoft.com/favicon.ico?v2',
$favicon->find('http://www.microsoft.com')
);
$this->assertNotEmpty($favicon->getContent());
// no icon
$this->assertEquals(
'',
$favicon->find('http://minicoders.com/favicon.ico')
$favicon->find('http://minicoders.com')
);
$this->assertEmpty($favicon->getContent());
}
public function testFind_directLinkFirst()
{
$favicon = new Favicon;
$this->assertEquals(
'http://miniflux.net/assets/img/touch-icon-ipad.png',
$favicon->find('http://miniflux.net', '/assets/img/touch-icon-ipad.png')
);
$this->assertNotEmpty($favicon->getContent());
}
public function testFind_fallsBackToExtract()
{
$favicon = new Favicon;
$this->assertEquals(
'http://miniflux.net/assets/img/favicon.png',
$favicon->find('http://miniflux.net','/nofavicon.ico')
);
$this->assertNotEmpty($favicon->getContent());
}
public function testDataUri()
{
$favicon = new Favicon;
@ -156,7 +237,7 @@ class FaviconTest extends PHPUnit_Framework_TestCase
$this->assertEquals($expected, $favicon->getDataUri());
}
public function testDataUriWithBadContentType()
public function testDataUri_withBadContentType()
{
$favicon = new Favicon;
$this->assertNotEmpty($favicon->find('http://www.lemonde.fr/'));

View File

@ -15,14 +15,21 @@ class ReaderTest extends PHPUnit_Framework_TestCase
$this->assertEquals('https://google.com', $reader->prependScheme('https://google.com'));
}
public function testDownload()
public function testDownload_withHTTP()
{
$reader = new Reader;
$feed = $reader->download('http://wordpress.org/news/feed/')->getContent();
$this->assertNotEmpty($feed);
}
public function testDownloadWithCache()
public function testDownload_withHTTPS()
{
$reader = new Reader;
$feed = $reader->download('https://wordpress.org/news/feed/')->getContent();
$this->assertNotEmpty($feed);
}
public function testDownload_withCache()
{
$reader = new Reader;
$resource = $reader->download('http://linuxfr.org/robots.txt');
@ -78,30 +85,129 @@ class ReaderTest extends PHPUnit_Framework_TestCase
$this->assertEquals('Rss20', $reader->detectFormat($content));
}
public function testFind()
public function testFind_rssFeed()
{
$reader = new Reader;
$resource = $reader->download('http://miniflux.net/');
$feeds = $reader->find($resource->getUrl(), $resource->getContent());
$this->assertTrue(is_array($feeds));
$this->assertNotEmpty($feeds);
$this->assertEquals('http://miniflux.net/feed', $feeds[0]);
$reader = new Reader;
$resource = $reader->download('http://www.bbc.com/news/');
$feeds = $reader->find($resource->getUrl(), $resource->getContent());
$this->assertTrue(is_array($feeds));
$this->assertNotEmpty($feeds);
$this->assertEquals('http://feeds.bbci.co.uk/news/rss.xml', $feeds[0]);
$html = '<!DOCTYPE html><html><head>
<link type="application/rss+xml" href="http://miniflux.net/feed">
</head><body><p>boo</p></body></html>';
$feeds = $reader->find('http://miniflux.net/', $html);
$this->assertEquals(array('http://miniflux.net/feed'), $feeds);
}
public function testFind_atomFeed()
{
$reader = new Reader;
$resource = $reader->download('http://www.cnn.com/services/rss/');
$feeds = $reader->find($resource->getUrl(), $resource->getContent());
$this->assertTrue(is_array($feeds));
$this->assertNotEmpty($feeds);
$this->assertTrue(count($feeds) > 1);
$this->assertEquals('http://rss.cnn.com/rss/cnn_topstories.rss', $feeds[0]);
$this->assertEquals('http://rss.cnn.com/rss/cnn_world.rss', $feeds[1]);
$html = '<!DOCTYPE html><html><head>
<link type="application/atom+xml" href="http://miniflux.net/feed">
</head><body><p>boo</p></body></html>';
$feeds = $reader->find('http://miniflux.net/', $html);
$this->assertEquals(array('http://miniflux.net/feed'), $feeds);
}
public function testFind_feedNotInHead()
{
$reader = new Reader;
$html = '<!DOCTYPE html><html><head></head>
<body>
<link type="application/atom+xml" href="http://miniflux.net/feed">
<p>boo</p></body></html>';
$feeds = $reader->find('http://miniflux.net/', $html);
$this->assertEquals(array('http://miniflux.net/feed'), $feeds);
}
public function testFind_noFeedPresent()
{
$reader = new Reader;
$html = '<!DOCTYPE html><html><head>
</head><body><p>boo</p></body></html>';
$feeds = $reader->find('http://miniflux.net/', $html);
$this->assertEquals(array(), $feeds);
}
public function testFind_ignoreUnknownType()
{
$reader = new Reader;
$html = '<!DOCTYPE html><html><head>
<link type="application/flux+xml" href="http://miniflux.net/feed">
</head><body><p>boo</p></body></html>';
$feeds = $reader->find('http://miniflux.net/', $html);
$this->assertEquals(array(), $feeds);
}
public function testFind_ignoreTypeInOtherAttribute()
{
$reader = new Reader;
$html = '<!DOCTYPE html><html><head>
<link rel="application/rss+xml" href="http://miniflux.net/feed">
</head><body><p>boo</p></body></html>';
$feeds = $reader->find('http://miniflux.net/', $html);
$this->assertEquals(array(), $feeds);
}
public function testFind_withOtherAttributesPresent()
{
$reader = new Reader;
$html = '<!DOCTYPE html><html><head>
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://miniflux.net/feed">
</head><body><p>boo</p></body></html>';
$feeds = $reader->find('http://miniflux.net/', $html);
$this->assertEquals(array('http://miniflux.net/feed'), $feeds);
}
public function testFind_multipleFeeds()
{
$reader = new Reader;
$html = '<!DOCTYPE html><html><head>
<link rel="alternate" type="application/rss+xml" title="CNN International: Top Stories" href="http://rss.cnn.com/rss/edition.rss"/>
<link rel="alternate" type="application/rss+xml" title="Connect The World" href="http://rss.cnn.com/rss/edition_connecttheworld.rss"/>
<link rel="alternate" type="application/rss+xml" title="World Sport" href="http://rss.cnn.com/rss/edition_worldsportblog.rss"/>
</head><body><p>boo</p></body></html>';
$feeds = $reader->find('http://www.cnn.com/services/rss/', $html);
$this->assertEquals(
array(
'http://rss.cnn.com/rss/edition.rss',
'http://rss.cnn.com/rss/edition_connecttheworld.rss',
'http://rss.cnn.com/rss/edition_worldsportblog.rss'
),
$feeds
);
}
public function testFind_withInvalidHTML()
{
$reader = new Reader;
$html = '!DOCTYPE html html head
link type="application/rss+xml" href="http://miniflux.net/feed"
/head body /p boo /p body /html';
$feeds = $reader->find('http://miniflux.net/', '');
$this->assertEquals(array(), $feeds);
}
public function testFind_withHtmlParamEmptyString()
{
$reader = new Reader;
$feeds = $reader->find('http://miniflux.net/', '');
$this->assertEquals(array(), $feeds);
}
public function testDiscover()

View File

@ -1,6 +1,6 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Un bilan des plantes génétiquement modifiées aux USA - Résumé d'un rapport américain - Afis - Association française pour l'information scientifique</title>
<meta name="Keywords" lang="fr" content="OGM, Afis, pseudo-sciences">

File diff suppressed because it is too large Load Diff