OSDN Git Service

add PostFilter test and fix to work PostFilter
authorhylom <hylom@users.sourceforge.jp>
Thu, 24 Jan 2019 10:39:05 +0000 (19:39 +0900)
committerhylom <hylom@users.sourceforge.jp>
Thu, 24 Jan 2019 10:39:05 +0000 (19:39 +0900)
src/newslash_web/lib/Newslash/Plugin/PostFilter.pm
src/newslash_web/t/api/filter.t
src/newslash_web/t/plugins/post_filter.t [new file with mode: 0644]
src/newslash_web/templates/admin/filter/index.html.tt2

index 9e042a0..e2b24dc 100644 (file)
@@ -12,19 +12,19 @@ sub register {
     my $cnf = $app->config->{PostFilter} ||= {};
     $cnf->{enable} = 0 if !$cnf->{enable};
 
-    my $filters = [
-                  { filter_id => "foobarhogehoge",
-                    name => "foobarhogehoge",
-                    discription => "test filter",
-                    message => "filter test",
-                    status => "enabled",
-                    regexp => "foobarhogehoge",
-                    ratio => 1,
-                    threshold => 0,
-                    limit => 0,
-                    pathes => ['^\/api\/v1\/comment$', ],
-                    fields => ["/title", "/comment"],
-                  },
+    my $filters_sample = [
+                          { filter_id => "foobarhogehoge",
+                            name => "foobarhogehoge",
+                            discription => "test filter",
+                            message => "filter test",
+                            status => "enabled",
+                            regexp => '^foobarhogehoge',
+                            ratio => 1,
+                            threshold => 0,
+                            limit => 0,
+                            pathes => ['^\/api\/v1\/comment$', ],
+                            fields => ["/title", "/comment"],
+                          },
                  ];
 
     $app->hook(around_action => sub {
@@ -35,20 +35,30 @@ sub register {
                    return $next->() if !$config->{enable};
 
                    # calculation score
-                   my $score = 0.0;
                    my $post_data;
-
                    if ($c->req->headers->content_type =~ m/^.*\/json(\s*|;.*)$/) {
                        # request body is JSON
                        $post_data = $c->req->json;
                    }
 
                    my $reason = "";
+                   my $score = 0.0;
                    my $max_score = 0.0;
                    if ($post_data) {
+                       # get filters
+                       my $filters = $c->model('filters')->select;
+                       if (!$filters) {
+                           $app->log->error("Plugin::PostFilter: cannot retrieve filters from database.");
+                           return $next->();
+                       }
+
                        #$app->log->debug(Dumper $post_data);
                        my $pointer = Mojo::JSON::Pointer->new($post_data);
+                       #warn "target: " . Dumper $post_data;
+
                        for my $filter (@$filters) {
+                           #warn "filter test:" . Dumper $filter;
+
                            # check if enabled
                            next if $filter->{status} eq "disabled";
 
@@ -58,15 +68,18 @@ sub register {
                            # check for each field
                            my $match_count = 0;
                            for my $field (@{$filter->{fields}}) {
+                               #warn "check $field field...";
                                if ($pointer->contains($field)) {
                                    my $val = $pointer->get($field);
-                                   my @matches = eval {$val =~ $filter->{regexp}};
+                                   #warn "check $filter->{regexp} for $val";
+                                   my @matches = eval {$val =~ /$filter->{regexp}/};
                                    if ($@) {
                                        $app->log->warn("Plugin::PostFilter: invalid regexp: $filter->{regexp}. filter ID: $filter->{id}");
                                    }
                                    $match_count += @matches;
                                }
                            }
+                           #warn "$match_count matches";
 
                            # ceiling by limit
                            if ($filter->{limit} > 0 && $match_count > $filter->{limit}) {
@@ -81,6 +94,7 @@ sub register {
                                    $reason = $filter->{message};
                                }
                            }
+                           #warn "score: $score";
                        }
                    }
 
index 80d4c0b..9a47cf1 100644 (file)
@@ -33,10 +33,10 @@ subtest 'create/select/update/delete/exports filters and items' => sub {
     my $rs = $filters->select(name => $test_name);
     $filters->delete(filter_id => $rs->{filter_id}) if $rs;
 
-    $t->post_ok('/login' => {Accept => '*/*'} => form => {nickname => $admin->{nickname}, passwd => $test_passwd})
-      ->status_is(302);
+    # login
+    $test_man->login($admin);
 
-    # create
+    # create filter
     my $params = { action => "create",
                    name => $test_name,
                    description => "test description",
@@ -108,7 +108,7 @@ subtest 'create/select/update/delete/exports filters and items' => sub {
       ->status_is(404);
 
     # finish
-    $t->get_ok('/logout')->status_is(302);
+    $test_man->logout;
 };
 
 $test_man->cleanup;
diff --git a/src/newslash_web/t/plugins/post_filter.t b/src/newslash_web/t/plugins/post_filter.t
new file mode 100644 (file)
index 0000000..681f62a
--- /dev/null
@@ -0,0 +1,130 @@
+# -*-Perl-*-
+# PostFilter plugin tests
+
+use Mojo::Base -strict;
+use Test::More;
+use Test::Mojo;
+
+use Newslash::Util::TestMan;
+use Data::Dumper;
+use Newslash::Eventd::Handlers;
+
+my $t = Test::Mojo->new('Newslash::Web');
+my $test_man = Newslash::Util::TestMan->new($t);
+
+my $filters = $t->app->model('filters');
+
+my $user_name = "postfiltertest";
+my $admin_name = "postfilteradmin";
+my $test_passwd = "foobar";
+my ($user, $admin);
+
+my $cnf = $t->app->config->{PostFilter} ||= {};
+my $filter_enabled = $cnf->{enable} ||= 0;
+
+# prepare for test
+if ($t->app->mode eq 'test') {
+    # at first, create test users.
+    $user = $test_man->create_user($user_name, $test_passwd);
+    $admin = $test_man->create_admin($admin_name, $test_passwd);
+}
+
+subtest 'filter test' => sub {
+    if ($t->app->mode ne 'test') {
+        fail("mode is not 'test'");
+        return;
+    }
+
+    # clean-up all filter
+    $filters->delete;
+
+    # check if no filter exists
+    my $filter_items = $filters->select;
+    ok($filter_items, "filter select succeed");
+    is(@$filter_items, 0, "no filter exists");
+
+    # clean-up all submissions
+    #$t->app->model('submissions')->hard_delete;
+    #ok(my $subs = $t->app->model('submissions')->select, "get submissions");
+    #is(@$subs, 0, "all submission deleted");
+
+    # login
+    $test_man->login($admin);
+
+    # enable post filter
+    $cnf->{enable} ||= 1;
+
+    # append filter
+    my $error_message = "error_message";
+    my $params = { action => "create",
+                   name => "test_filter",
+                   description => "test_description",
+                   message => $error_message,
+                   regexp => '^\A\s*1\s*get\s*\z',
+                   fields => "/item/introtext /item/bodytext /item/title",
+                   pathes => '^/api/v1/submission$',
+                 };
+    $t->post_ok('/api/v1/admin/filter' => {Accept => '*/*'} => json => $params)
+      ->status_is(200)
+      ->json_has('/filter_id');
+    if (!$t->success) {
+        diag Dumper $t->tx->res;
+    }
+
+    my $filter_id = 0;
+    if ($t->tx->res->json) {
+        $filter_id = $t->tx->res->json->{filter_id};
+    }
+
+    # logout
+    $test_man->logout;
+
+    # do posting (expect to filter)
+    my $test_data = {
+                     action => 'preview',
+                     item => {
+                              title => "テストタレコミ @ " . localtime,
+                              introtext => "1 get"
+                             },
+                    };
+
+    $t->post_ok('/api/v1/submission' => {Accept => '*/*'} => json => $test_data)
+      ->status_is(400)
+      ->content_type_like(qr/application\/json/)
+      ->json_has('/error')
+      ->json_is('/reason', "post_is_filtered")
+      ->json_is('/message', $error_message);
+    if (!$t->success) {
+        diag Dumper $t->tx->res->json;
+    }
+
+    # do posting (expect to no filter)
+    $test_data = {
+                  action => 'preview',
+                  item => {
+                           title => "テストタレコミ @ " . localtime,
+                           introtext => "ほげほげ"
+                          },
+                 };
+
+    $t->post_ok('/api/v1/submission' => {Accept => '*/*'} => json => $test_data)
+      ->status_is(200)
+      ->content_type_like(qr/application\/json/);
+    if (!$t->success) {
+        diag Dumper $t->tx->res->json;
+    }
+
+    # clean-up all filter
+    $filters->delete;
+
+    # clean-up all submissions
+    #$t->app->model('submissions')->hard_delete;
+
+
+    # restore settings
+    $cnf->{enable} = $filter_enabled;
+
+};
+
+$test_man->cleanup;
+done_testing();
index 6f0cf5b..96a40ff 100644 (file)
@@ -98,7 +98,7 @@
       <dt>ratio</dt><dd>小数。マッチ1回に付きratio分だけスコアを加算する</dd>
       <dt>threshold</dt><dd>整数。マッチ回数からこの値だけを減算したものがスコア計算に使われる。マッチ回数がこの値を超えない限りフィルタは適用されない</dd>
       <dt>limit</dt><dd>マッチ回数がこの値を超えた場合、この値をマッチ回数として使用する</dd>
-      <dt>paths</dt><dd>フィルタを適用するAPIエンドポイント(例:/api/v1/comment)。空白区切りで複数指定可能</dd>
+      <dt>paths</dt><dd>フィルタを適用するAPIエンドポイント(正規表現)(例:^/api/v1/comment$)。空白区切りで複数指定可能</dd>
       <dt>fields</dt><dd>フィルタを適用するフィールド名をjsonpath形式で指定する。空白区切りで複数指定可能</dd>
   </div>
 </div>