Ado

 view release on metacpan or  search on metacpan

lib/Ado/Manual/Contributing.pod  view on Meta::CPAN

=head2 MODEL

Put your database related code under the L<Model> namespace.
Use L<DBIx::Simple::Class>.
Generate your classes from tables using C<dsc_dump_schema.pl> utility
that comes with DBIx::Simple::Class.
Feel free to contribute to L<DBIx::Simple::Class>.
Minimize SQL complexity. Write ANSI SQL if you need to write SQL.
Write your SQL in a way to be compatible with
L<SQLite|http://sqlite.org/>, L<MySQL|http://dev.mysql.com/>
and L<PostgreSQL|http://www.postgresql.org/>.
Use the L<DBIx::Simple::Class/SQL> feature to achieve this.
See L<DBIx::Simple::Class/SQL> and its source to figure out how to do it.
To guess the current driver:

  use DBI::Const::GetInfoType;
  #...
  my $dbms = $self->dbh->get_info( $GetInfoType{SQL_DBMS_NAME} );
  if($dbms eq 'SQLite'){
  ...
  }

public/vendor/pagedown/Markdown.Converter.js  view on Meta::CPAN

    Markdown.Converter = function () {
        var pluginHooks = this.hooks = new HookCollection();
        
        // given a URL that was encountered by itself (without markup), should return the link text that's to be given to this link
        pluginHooks.addNoop("plainLinkText");
        
        // called with the orignal text as given to makeHtml. The result of this plugin hook is the actual markdown source that will be cooked
        pluginHooks.addNoop("preConversion");
        
        // called with the text once all normalizations have been completed (tabs to spaces, line endings, etc.), but before any conversions have
        pluginHooks.addNoop("postNormalization");
        
        // Called with the text before / after creating block elements like code blocks and lists. Note that this is called recursively
        // with inner content, e.g. it's called with the full text, and then only with the content of a blockquote. The inner
        // call will receive outdented text.
        pluginHooks.addNoop("preBlockGamut");
        pluginHooks.addNoop("postBlockGamut");
        
        // called with the text of a single block element before / after the span-level conversions (bold, code spans, etc.) have been made
        pluginHooks.addNoop("preSpanGamut");
        pluginHooks.addNoop("postSpanGamut");
        
        // called with the final cooked HTML code. The result of this plugin hook is the actual output of makeHtml
        pluginHooks.addNoop("postConversion");

        //
        // Private state of the converter instance:
        //

        // Global hashes, used by various utility routines
        var g_urls;
        var g_titles;
        var g_html_blocks;

public/vendor/pagedown/Markdown.Converter.js  view on Meta::CPAN


            // Convert all tabs to spaces.
            text = _Detab(text);

            // Strip any lines consisting only of spaces and tabs.
            // This makes subsequent regexen easier to write, because we can
            // match consecutive blank lines with /\n+/ instead of something
            // contorted like /[ \t]*\n+/ .
            text = text.replace(/^[ \t]+$/mg, "");
            
            text = pluginHooks.postNormalization(text);

            // Turn block-level HTML blocks into hash entries
            text = _HashHTMLBlocks(text);

            // Strip link definitions, store in hashes.
            text = _StripLinkDefinitions(text);

            text = _RunBlockGamut(text);

            text = _UnescapeSpecialChars(text);

            // attacklab: Restore dollar signs
            text = text.replace(/~D/g, "$$");

            // attacklab: Restore tildes
            text = text.replace(/~T/g, "~");

            text = pluginHooks.postConversion(text);

            g_html_blocks = g_titles = g_urls = null;

            return text;
        };

        function _StripLinkDefinitions(text) {
            //
            // Strips link definitions from text, stores the URLs and titles in
            // hash references.

public/vendor/pagedown/Markdown.Converter.js  view on Meta::CPAN

            // Do Horizontal Rules:
            var replacement = "<hr />\n";
            text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, replacement);
            text = text.replace(/^[ ]{0,2}([ ]?-[ ]?){3,}[ \t]*$/gm, replacement);
            text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, replacement);

            text = _DoLists(text);
            text = _DoCodeBlocks(text);
            text = _DoBlockQuotes(text);
            
            text = pluginHooks.postBlockGamut(text, blockGamutHookCallback);

            // We already ran _HashHTMLBlocks() before, in Markdown(), but that
            // was to escape raw HTML in the original Markdown source. This time,
            // we're escaping the markup we've just created, so that we don't wrap
            // <p> tags around block-level tags.
            text = _HashHTMLBlocks(text);
            text = _FormParagraphs(text, doNotUnhash);

            return text;
        }

public/vendor/pagedown/Markdown.Converter.js  view on Meta::CPAN

            text = _DoAutoLinks(text);
            
            text = text.replace(/~P/g, "://"); // put in place to prevent autolinking; reset now
            
            text = _EncodeAmpsAndAngles(text);
            text = _DoItalicsAndBold(text);

            // Do hard breaks:
            text = text.replace(/  +\n/g, " <br>\n");
            
            text = pluginHooks.postSpanGamut(text);

            return text;
        }

        function _EscapeSpecialCharsWithinTagAttributes(text) {
            //
            // Within tags -- meaning between < and > -- encode [\ ` * _] so they
            // don't conflict with their use in Markdown for code, italics and strong.
            //

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

        options.strings = options.strings || {};
        if (options.helpButton) {
            options.strings.help = options.strings.help || options.helpButton.title;
        }
        var getString = function (identifier) { return options.strings[identifier] || defaultsStrings[identifier]; }

        idPostfix = idPostfix || "";

        var hooks = this.hooks = new Markdown.HookCollection();
        hooks.addNoop("onPreviewRefresh");       // called with no arguments after the preview has been refreshed
        hooks.addNoop("postBlockquoteCreation"); // called with the user's selection *after* the blockquote was created; should return the actual to-be-inserted text
        hooks.addFalse("insertImageDialog");     /* called with one parameter: a callback to be called with the URL of the image. If the application creates
                                                  * its own image insertion dialog, this hook should return true, and the callback should be called with the chosen
                                                  * image url (or null if the user cancelled). If this hook returns false, the default dialog will be used.
                                                  */

        this.getConverter = function () { return markdownConverter; }

        var that = this,
            panels;

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

    // select the non-existent link text and discard the selection in the
    // textarea.  The solution to this is to cache the textarea selection
    // on the button's mousedown event and set a flag.  In the part of the
    // code where we need to grab the selection, we check for the flag
    // and, if it's set, use the cached area instead of querying the
    // textarea.
    //
    // This ONLY affects Internet Explorer (tested on versions 6, 7
    // and 8) and ONLY on button clicks.  Keyboard shortcuts work
    // normally since the focus never leaves the textarea.
    function PanelCollection(postfix) {
        this.buttonBar = doc.getElementById("wmd-button-bar" + postfix);
        this.preview = doc.getElementById("wmd-preview" + postfix);
        this.input = doc.getElementById("wmd-input" + postfix);
    };

    // Returns true if the DOM element is visible, false if it's hidden.
    // Checks if display is anything other than none.
    util.isVisible = function (elem) {

        if (window.getComputedStyle) {
            // Most browsers
            return window.getComputedStyle(elem, null).getPropertyValue("display") !== "none";
        }

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

    };

    // Converts \r\n and \r to \n.
    util.fixEolChars = function (text) {
        text = text.replace(/\r\n/g, "\n");
        text = text.replace(/\r/g, "\n");
        return text;
    };

    // Extends a regular expression.  Returns a new RegExp
    // using pre + regex + post as the expression.
    // Used in a few functions where we have a base
    // expression and we want to pre- or append some
    // conditions to it (e.g. adding "$" to the end).
    // The flags are unchanged.
    //
    // regex is a RegExp, pre and post are strings.
    util.extendRegExp = function (regex, pre, post) {

        if (pre === null || pre === undefined) {
            pre = "";
        }
        if (post === null || post === undefined) {
            post = "";
        }

        var pattern = regex.toString();
        var flags;

        // Replace the flags with empty space and store them.
        pattern = pattern.replace(/\/([gim]*)$/, function (wholeMatch, flagsPart) {
            flags = flagsPart;
            return "";
        });

        // Remove the slash delimiters on the regular expression.
        pattern = pattern.replace(/(^\/|\/$)/g, "");
        pattern = pre + pattern + post;

        return new re(pattern, flags);
    }

    // UNFINISHED
    // The assignment in the while loop makes jslint cranky.
    // I'll change it to a better loop later.
    position.getTop = function (elem, isInner) {
        var result = elem.offsetTop;
        if (!isInner) {

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

                range.collapse(false);
                range.moveStart("character", -defTextLen);
                range.moveEnd("character", defTextLen);
                range.select();
            }

            input.focus();
        }, 0);
    };

    function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions, getString) {

        var inputBox = panels.input,
            buttons = {}; // buttons.undo, buttons.link, etc. The actual DOM elements.

        makeSpritedButtonRow();

        var keyEvent = "keydown";
        if (uaSniffed.isOpera) {
            keyEvent = "keypress";
        }

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN


        function makeSpritedButtonRow() {

            var buttonBar = panels.buttonBar;

            var normalYShift = "0px";
            var disabledYShift = "-20px";
            var highlightYShift = "-40px";

            var buttonRow = document.createElement("ul");
            buttonRow.id = "wmd-button-row" + postfix;
            buttonRow.className = 'wmd-button-row';
            buttonRow = buttonBar.appendChild(buttonRow);
            var xPosition = 0;
            var makeButton = function (id, title, XShift, textOp) {
                var button = document.createElement("li");
                button.className = "wmd-button";
                button.style.left = xPosition + "px";
                xPosition += 25;
                var buttonImage = document.createElement("span");
                button.id = id + postfix;
                button.appendChild(buttonImage);
                button.title = title;
                button.XShift = XShift;
                if (textOp)
                    button.textOp = textOp;
                setupButton(button, true);
                buttonRow.appendChild(button);
                return button;
            };
            var makeSpacer = function (num) {
                var spacer = document.createElement("li");
                spacer.className = "wmd-spacer wmd-spacer" + num;
                spacer.id = "wmd-spacer" + num + postfix;
                buttonRow.appendChild(spacer);
                xPosition += 25;
            }

            buttons.bold = makeButton("wmd-bold-button", getString("bold"), "0px", bindCommand("doBold"));
            buttons.italic = makeButton("wmd-italic-button", getString("italic"), "-20px", bindCommand("doItalic"));
            makeSpacer(1);
            buttons.link = makeButton("wmd-link-button", getString("link"), "-40px", bindCommand(function (chunk, postProcessing) {
                return this.doLinkOrImage(chunk, postProcessing, false);
            }));
            buttons.quote = makeButton("wmd-quote-button", getString("quote"), "-60px", bindCommand("doBlockquote"));
            buttons.code = makeButton("wmd-code-button", getString("code"), "-80px", bindCommand("doCode"));
            buttons.image = makeButton("wmd-image-button", getString("image"), "-100px", bindCommand(function (chunk, postProcessing) {
                return this.doLinkOrImage(chunk, postProcessing, true);
            }));
            makeSpacer(2);
            buttons.olist = makeButton("wmd-olist-button", getString("olist"), "-120px", bindCommand(function (chunk, postProcessing) {
                this.doList(chunk, postProcessing, true);
            }));
            buttons.ulist = makeButton("wmd-ulist-button", getString("ulist"), "-140px", bindCommand(function (chunk, postProcessing) {
                this.doList(chunk, postProcessing, false);
            }));
            buttons.heading = makeButton("wmd-heading-button", getString("heading"), "-160px", bindCommand("doHeading"));
            buttons.hr = makeButton("wmd-hr-button", getString("hr"), "-180px", bindCommand("doHorizontalRule"));
            makeSpacer(3);
            buttons.undo = makeButton("wmd-undo-button", getString("undo"), "-200px", null);
            buttons.undo.execute = function (manager) { if (manager) manager.undo(); };

            var redoTitle = /win/.test(nav.platform.toLowerCase()) ?
                getString("redo") :
                getString("redomac"); // mac and other non-Windows platforms

            buttons.redo = makeButton("wmd-redo-button", redoTitle, "-220px", null);
            buttons.redo.execute = function (manager) { if (manager) manager.redo(); };

            if (helpOptions) {
                var helpButton = document.createElement("li");
                var helpButtonImage = document.createElement("span");
                helpButton.appendChild(helpButtonImage);
                helpButton.className = "wmd-button wmd-help-button";
                helpButton.id = "wmd-help-button" + postfix;
                helpButton.XShift = "-240px";
                helpButton.isHelp = true;
                helpButton.style.right = "0px";
                helpButton.title = getString("help");
                helpButton.onclick = helpOptions.handler;

                setupButton(helpButton, true);
                buttonRow.appendChild(helpButton);
                buttons.help = helpButton;
            }

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

        chunk.selection = chunk.selection.replace(regex, function (line, marked) {
            if (new re("^" + that.prefixes, "").test(line)) {
                return line;
            }
            return marked + "\n";
        });

        chunk.selection = chunk.selection.replace(/\s+$/, "");
    };

    commandProto.doBold = function (chunk, postProcessing) {
        return this.doBorI(chunk, postProcessing, 2, this.getString("boldexample"));
    };

    commandProto.doItalic = function (chunk, postProcessing) {
        return this.doBorI(chunk, postProcessing, 1, this.getString("italicexample"));
    };

    // chunk: The selected region that will be enclosed with */**
    // nStars: 1 for italics, 2 for bold
    // insertText: If you just click the button without highlighting text, this gets inserted
    commandProto.doBorI = function (chunk, postProcessing, nStars, insertText) {

        // Get rid of whitespace and fixup newlines.
        chunk.trimWhitespace();
        chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n");

        // Look for stars before and after.  Is the chunk already marked up?
        // note that these regex matches cannot fail
        var starsBefore = /(\**$)/.exec(chunk.before)[0];
        var starsAfter = /(^\**)/.exec(chunk.after)[0];

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

                return querypart.replace(/\+/g, "%2b"); // since we replaced plus with spaces in the query part, all pluses that now appear where originally encoded
            });
            if (title) {
                title = title.trim ? title.trim() : title.replace(/^\s*/, "").replace(/\s*$/, "");
                title = title.replace(/"/g, "quot;").replace(/\(/g, "&#40;").replace(/\)/g, "&#41;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
            }
            return title ? link + ' "' + title + '"' : link;
        });
    }

    commandProto.doLinkOrImage = function (chunk, postProcessing, isImage) {

        chunk.trimWhitespace();
        chunk.findTags(/\s*!?\[/, /\][ ]?(?:\n[ ]*)?(\[.*?\])?/);
        var background;

        if (chunk.endTag.length > 1 && chunk.startTag.length > 0) {

            chunk.startTag = chunk.startTag.replace(/!?\[/, "");
            chunk.endTag = "";
            this.addLinkDef(chunk, null);

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN


                    if (!chunk.selection) {
                        if (isImage) {
                            chunk.selection = that.getString("imagedescription");
                        }
                        else {
                            chunk.selection = that.getString("linkdescription");
                        }
                    }
                }
                postProcessing();
            };

            background = ui.createBackground();

            if (isImage) {
                if (!this.hooks.insertImageDialog(linkEnteredCallback))
                    ui.prompt(this.getString("imagedialog"), imageDefaultText, linkEnteredCallback);
            }
            else {
                ui.prompt(this.getString("linkdialog"), linkDefaultText, linkEnteredCallback);
            }
            return true;
        }
    };

    // When making a list, hitting shift-enter will put your cursor on the next line
    // at the current indent level.
    commandProto.doAutoindent = function (chunk, postProcessing) {

        var commandMgr = this,
            fakeSelection = false;

        chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]*\n$/, "\n\n");
        chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}>[ \t]*\n$/, "\n\n");
        chunk.before = chunk.before.replace(/(\n|^)[ \t]+\n$/, "\n\n");
        
        // There's no selection, end the cursor wasn't at the end of the line:
        // The user wants to split the current list item / code line / blockquote line

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

                commandMgr.doCode(chunk);
            }
        }
        
        if (fakeSelection) {
            chunk.after = chunk.selection + chunk.after;
            chunk.selection = "";
        }
    };

    commandProto.doBlockquote = function (chunk, postProcessing) {

        chunk.selection = chunk.selection.replace(/^(\n*)([^\r]+?)(\n*)$/,
            function (totalMatch, newlinesBefore, text, newlinesAfter) {
                chunk.before += newlinesBefore;
                chunk.after = newlinesAfter + chunk.after;
                return text;
            });

        chunk.before = chunk.before.replace(/(>[ \t]*)$/,
            function (totalMatch, blankLine) {

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN


            if (!/^(\n|^)[ ]{0,3}>/.test(chunk.selection) && chunk.startTag) {
                chunk.startTag = chunk.startTag.replace(/\n{0,2}$/, "\n\n");
            }

            if (!/(\n|^)[ ]{0,3}>.*$/.test(chunk.selection) && chunk.endTag) {
                chunk.endTag = chunk.endTag.replace(/^\n{0,2}/, "\n\n");
            }
        }

        chunk.selection = this.hooks.postBlockquoteCreation(chunk.selection);

        if (!/\n/.test(chunk.selection)) {
            chunk.selection = chunk.selection.replace(/^(> *)/,
            function (wholeMatch, blanks) {
                chunk.startTag += blanks;
                return "";
            });
        }
    };

    commandProto.doCode = function (chunk, postProcessing) {

        var hasTextBefore = /\S[ ]*$/.test(chunk.before);
        var hasTextAfter = /^[ ]*\S/.test(chunk.after);

        // Use 'four space' markdown if the selection is on its own
        // line or is multiline.
        if ((!hasTextAfter && !hasTextBefore) || /\n/.test(chunk.selection)) {

            chunk.before = chunk.before.replace(/[ ]{4}$/,
                function (totalMatch) {

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

            else if (chunk.endTag && !chunk.startTag) {
                chunk.before += chunk.endTag;
                chunk.endTag = "";
            }
            else {
                chunk.startTag = chunk.endTag = "";
            }
        }
    };

    commandProto.doList = function (chunk, postProcessing, isNumberedList) {

        // These are identical except at the very beginning and end.
        // Should probably use the regex extension function to make this clearer.
        var previousItemsRegex = /(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/;
        var nextItemsRegex = /^\n*(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*/;

        // The default bullet is a dash but others are possible.
        // This has nothing to do with the particular HTML bullet,
        // it's just a markdown bullet.
        var bullet = "-";

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN


        chunk.trimWhitespace(true);
        chunk.skipLines(nLinesUp, nLinesDown, true);
        chunk.startTag = prefix;
        var spaces = prefix.replace(/./g, " ");
        this.wrap(chunk, SETTINGS.lineLength - spaces.length);
        chunk.selection = chunk.selection.replace(/\n/g, "\n" + spaces);

    };

    commandProto.doHeading = function (chunk, postProcessing) {

        // Remove leading/trailing whitespace and reduce internal spaces to single spaces.
        chunk.selection = chunk.selection.replace(/\s+/g, " ");
        chunk.selection = chunk.selection.replace(/(^\s+|\s+$)/g, "");

        // If we clicked the button with no selected text, we just
        // make a level 2 hash header around some default text.
        if (!chunk.selection) {
            chunk.startTag = "## ";
            chunk.selection = this.getString("headingexample");

public/vendor/pagedown/Markdown.Editor.js  view on Meta::CPAN

            if (len > SETTINGS.lineLength) {
                len = SETTINGS.lineLength;
            }
            chunk.endTag = "\n";
            while (len--) {
                chunk.endTag += headerChar;
            }
        }
    };

    commandProto.doHorizontalRule = function (chunk, postProcessing) {
        chunk.startTag = "----------\n";
        chunk.selection = "";
        chunk.skipLines(2, 1, true);
    }


})();

public/vendor/pagedown/Markdown.Sanitizer.js  view on Meta::CPAN

    if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module
        output = exports;
        Converter = require("./Markdown.Converter").Converter;
    } else {
        output = window.Markdown;
        Converter = output.Converter;
    }
        
    output.getSanitizingConverter = function () {
        var converter = new Converter();
        converter.hooks.chain("postConversion", sanitizeHtml);
        converter.hooks.chain("postConversion", balanceTags);
        return converter;
    }

    function sanitizeHtml(html) {
        return html.replace(/<[^>]*>?/gi, sanitizeTag);
    }

    // (tags that can be opened/closed) | (tags that stand alone)
    var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
    // <a href="url..." optional title>|</a>

t/command/adoplugin-01.t  view on Meta::CPAN

$ado->routes->find('controlleraction')->remove();
$ado->routes->find('controlleractionid')->remove();

# $ado->start("routes");
# Test generated routes
$t->get_ok('/testatii.json')->status_is(200);
$t->get_ok('/testatii/list?format=html')->status_is(200)
  ->content_like(qr|table.+id</th>.+permissions</th.+Hello</td.+Hello2|smx);

# needs login
$t->post_ok(
    '/testatii/create.html' => form => {
        title => 'Hello3',
        body =>
          'Ала, бала, ница турска паница, Хей гиди Ванчо, наш капитанчо...'
    }
  )->status_is(302)    #requires authentication
  ->header_is('Location' => '/login', 'redirected to /login');
my $login_url = $t->tx->res->headers->header('Location');

# Login after following the Location header (redirect)

t/command/adoplugin-01.t  view on Meta::CPAN

#get the csrf fields
my $form       = $t->tx->res->dom->at('#login_form');
my $csrf_token = $form->at('[name="csrf_token"]')->{value};
my $form_hash  = {
    _method        => 'login/ado',
    login_name     => 'test1',
    login_password => '',
    csrf_token     => $csrf_token,
    digest         => Mojo::Util::sha1_hex($csrf_token . Mojo::Util::sha1_hex('test1test1')),
};
$t->post_ok($login_url => {} => form => $form_hash)->status_is(302)
  ->header_is('Location' => '/testatii/create.html', 'redirected back to /testatii/create');
my $create_url = $t->tx->res->headers->header('Location');

#now we can create a new resouce after authenticating
$t->post_ok(
    $create_url => {Accept => 'text/html'} => form => {
        title => 'Hello3',
        body =>
          'Ала, бала, ница турска паница, Хей гиди Ванчо, наш капитанчо...'
    }
);
$t->get_ok('/testatii/read/3.html')->status_is(200)
  ->content_like(qr|Hello3|smx, 'reading created content - ok');

=pod

t/command/crud.t  view on Meta::CPAN


#Run tests on the generated code?!?!
unshift @{$ado->renderer->paths}, catdir($tempdir, 'site_templates');
$t->get_ok('/testatii/list', {Accept => 'text/plain'})->status_is(415)
  ->content_like(qr|Unsupported.+Please.+list\.json|x, 'Unsupported Media Type - ok');

$t->get_ok('/testatii/list.json')->status_is(200);
$t->get_ok('/testatii/list.html')->status_is(200)
  ->content_like(qr|table.+id</th>.+permissions</th.+Hello</td.+Hello2|smx);

$t->post_ok(
    '/testatii/create.html' => form => {
        title => 'Hello3',
        body =>
          'Ала, бала, ница турска паница, Хей гиди Ванчо, наш капитанчо...'
    }
);
$t->get_ok('/testatii/read/3.html')->status_is(200)
  ->content_like(qr|Hello3|smx, 'reading content - ok');
$t->put_ok(
    '/testatii/update/3.html' => form => {

t/plugin/auth-01.t  view on Meta::CPAN

my $test_auth_url = $t->ua->server->url->path('/test/authenticateduser');
$t->get_ok('/login/ado', {Referer => $test_auth_url})->status_is(200)
  ->element_exists('section.ui.login_form form#login_form')
  ->text_like('form#login_form .ui.header:nth-child(1)' => qr'Sign in')
  ->element_exists('#login_name')->element_exists('#login_password');

#try unexisting login method
my $help_url = $t->ua->server->url->path('/help');
$t->get_ok('/login/alabala', {Referer => $help_url})->status_is(401)
  ->element_exists_not('input[name="_method"][checked="checked"]');
$t->post_ok('/login/alabala', {Referer => $help_url})->status_is(401)
  ->text_like('.ui.error.message' => qr/of the supported login methods/);

#try condition (redirects to /login url)
my $login_url =
  $t->get_ok('/test/authenticateduser')->status_is(302)->header_like('Location' => qr|/login$|)
  ->tx->res->headers->header('Location');

#login after following the Location header (redirect)
$t->get_ok($login_url);

#get the csrf fields
my $form       = $t->tx->res->dom->at('#login_form');
my $csrf_token = $form->at('[name="csrf_token"]')->{value};
my $form_hash  = {
    _method        => 'login/ado',
    login_name     => 'test1',
    login_password => '',
    csrf_token     => $csrf_token,
    digest => Mojo::Util::sha1_hex($csrf_token . Mojo::Util::sha1_hex('test1' . 'wrong_pass')),
};
$t->post_ok($login_url => {} => form => $form_hash)->status_is(401);

#try with wrong (unchanged) csrf token
$t->post_ok($login_url => {DNT => 1} => form => $form_hash)->status_is(403, 'Wrong csrf_token')
  ;    #403 Forbidden

#try with no user passed
$t->get_ok($login_url);
delete $form_hash->{login_name};
$form_hash->{csrf_token} = $t->tx->res->dom->at('#login_form [name="csrf_token"]')->{value};
$form_hash->{digest} =
  Mojo::Util::sha1_hex($form_hash->{csrf_token} . Mojo::Util::sha1_hex('' . 'wrong_pass'));
$t->post_ok($login_url => {} => form => $form_hash)->status_is(401, 'No login_name');

#try with no data
$t->post_ok($login_url)->status_is(401, 'No $val->has_data');

#try with unexisting user
$t->get_ok($login_url);
$form_hash->{login_name} = 'alabala';
$form_hash->{csrf_token} = $t->tx->res->dom->at('#login_form [name="csrf_token"]')->{value};
$form_hash->{digest} =
  Mojo::Util::sha1_hex($form_hash->{csrf_token} . Mojo::Util::sha1_hex('' . 'wrong_pass'));
$t->post_ok($login_url => {} => form => $form_hash)->status_is(401, 'No such user $login_name')
  ->text_like('#error_login',      qr'Wrong credentials! Please try again!')
  ->text_like('#error_login_name', qr"No such user '$form_hash->{login_name}'!");

done_testing;

t/plugin/auth-02.t  view on Meta::CPAN

# It is expected all plugins to load their routes by the time the generic routes load.
# This means it is ok to keep them in ado.conf
#http://localhost:3000/perldoc/Mojolicious/Guides/Routing#Rearranging-routes
$ado->routes->find('controller')->remove();
$ado->routes->find('controlleraction')->remove();
$ado->routes->find('controlleractionid')->remove();
$ado->routes->get('/test/ingroup')->over(ingroup => 'test1')->to('test#ingroup');

my $csrf_token =
  $t->get_ok('/login')->tx->res->dom->at('#login_form [name="csrf_token"]')->{value};
$t->post_ok(
    '/login' => {} => form => {
        _method    => 'login/ado',
        csrf_token => $csrf_token,
    }
)->status_is(401 => 'user submitted empty form 401 ok');
my $login_url =
  $t->get_ok('/test/authenticateduser')->status_is(302)->header_like('Location' => qr|/login$|)
  ->tx->res->headers->header('Location');
$t->get_ok('/login/ado');

#try again with the right password this time
my $form           = $t->tx->res->dom->at('#login_form');
my $new_csrf_token = $form->at('[name="csrf_token"]')->{value};
ok($new_csrf_token ne $csrf_token, '$new_csrf_token is different');
$t->post_ok(
    $login_url => {},
    form       => {
        _method        => 'login/ado',
        login_name     => 'test1',
        login_password => '',
        csrf_token     => $new_csrf_token,
        digest => Mojo::Util::sha1_hex($new_csrf_token . Mojo::Util::sha1_hex('test1' . 'test1')),
      }

      #redirect back to the $c->session('over_route')



( run in 1.719 second using v1.01-cache-2.11-cpan-5735350b133 )