github.com/pdfcpu/pdfcpu@v0.11.1/pkg/api/test/form_test.go (about)

     1  /*
     2  Copyright 2023 The pdf Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package test
    18  
    19  import (
    20  	"os"
    21  	"path/filepath"
    22  	"testing"
    23  
    24  	"github.com/pdfcpu/pdfcpu/pkg/api"
    25  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/form"
    26  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
    27  )
    28  
    29  /**************************************************************
    30   * All form related processing is optimized for Adobe Reader! *
    31   **************************************************************/
    32  
    33  func listFormFieldsFile(t *testing.T, inFile string, conf *model.Configuration) ([]string, error) {
    34  	t.Helper()
    35  
    36  	msg := "listFormFields"
    37  
    38  	if conf == nil {
    39  		conf = model.NewDefaultConfiguration()
    40  	}
    41  	conf.Cmd = model.LISTFORMFIELDS
    42  
    43  	f, err := os.Open(inFile)
    44  	if err != nil {
    45  		t.Fatalf("%s: %v\n", msg, err)
    46  	}
    47  	defer f.Close()
    48  
    49  	ctx, err := api.ReadValidateAndOptimize(f, conf)
    50  	if err != nil {
    51  		t.Fatalf("%s: %v\n", msg, err)
    52  	}
    53  
    54  	return form.ListFormFields(ctx)
    55  }
    56  
    57  func TestListFormFields(t *testing.T) {
    58  
    59  	msg := "TestListFormFields"
    60  	inFile := filepath.Join(samplesDir, "form", "demo", "english.pdf")
    61  
    62  	ss, err := listFormFieldsFile(t, inFile, conf)
    63  	if err != nil {
    64  		t.Fatalf("%s: %v\n", msg, err)
    65  	}
    66  
    67  	if len(ss) != 27 {
    68  		t.Fatalf("%s: want 27, got %d lines\n", msg, len(ss))
    69  	}
    70  }
    71  
    72  func TestRemoveFormFields(t *testing.T) {
    73  
    74  	msg := "TestRemoveFormFields"
    75  	inFile := filepath.Join(samplesDir, "form", "demo", "english.pdf")
    76  	outFile := filepath.Join(samplesDir, "form", "remove", "removedField.pdf")
    77  
    78  	ss, err := listFormFieldsFile(t, inFile, conf)
    79  	if err != nil {
    80  		t.Fatalf("%s: %v\n", msg, err)
    81  	}
    82  	want := len(ss) - 2
    83  
    84  	if err := api.RemoveFormFieldsFile(inFile, outFile, []string{"dob1", "firstName1"}, conf); err != nil {
    85  		t.Fatalf("%s: %v\n", msg, err)
    86  	}
    87  
    88  	ss, err = listFormFieldsFile(t, outFile, conf)
    89  	if err != nil {
    90  		t.Fatalf("%s: %v\n", msg, err)
    91  	}
    92  	got := len(ss)
    93  
    94  	if got != want {
    95  		t.Fail()
    96  	}
    97  }
    98  
    99  func TestResetFormFields(t *testing.T) {
   100  
   101  	for _, tt := range []struct {
   102  		msg     string
   103  		inFile  string
   104  		outFile string
   105  	}{
   106  		{"TestResetFormCorefont", "english.pdf", "english-reset.pdf"},        // Core font (Helvetica)
   107  		{"TestResetFormUserfont", "ukrainian.pdf", "ukrainian-reset.pdf"},    // User font (Roboto-Regular)
   108  		{"TestFormRTL", "arabic.pdf", "arabic-reset.pdf"},                    // User font RTL (Roboto-Regular)
   109  		{"TestResetFormCJK", "chineseSimple.pdf", "chineseSimple-reset.pdf"}, // User font CJK (UnifontMedium)
   110  		{"TestResetPersonForm", "person.pdf", "person-reset.pdf"},            // Person Form
   111  	} {
   112  		inFile := filepath.Join(samplesDir, "form", "demoSinglePage", tt.inFile)
   113  		outFile := filepath.Join(samplesDir, "form", "reset", tt.outFile)
   114  		if err := api.ResetFormFieldsFile(inFile, outFile, nil, conf); err != nil {
   115  			t.Fatalf("%s: %v\n", tt.msg, err)
   116  		}
   117  	}
   118  
   119  }
   120  
   121  func TestLockFormFields(t *testing.T) {
   122  
   123  	for _, tt := range []struct {
   124  		msg     string
   125  		inFile  string
   126  		outFile string
   127  	}{
   128  		{"TestLockFormEN", "english.pdf", "english-locked.pdf"},              // Core font (Helvetica)
   129  		{"TestLockFormUK", "ukrainian.pdf", "ukrainian-locked.pdf"},          // User font (Roboto-Regular)
   130  		{"TestLockFormRTL", "arabic.pdf", "arabic-locked.pdf"},               // User font RTL (Roboto-Regular)
   131  		{"TestLockFormCJK", "chineseSimple.pdf", "chineseSimple-locked.pdf"}, // User font CJK (UnifontMedium)
   132  		{"TestLockPersonForm", "person.pdf", "person-locked.pdf"},            // Person Form
   133  	} {
   134  		inFile := filepath.Join(samplesDir, "form", "demoSinglePage", tt.inFile)
   135  		outFile := filepath.Join(samplesDir, "form", "lock", tt.outFile)
   136  		if err := api.LockFormFieldsFile(inFile, outFile, nil, conf); err != nil {
   137  			t.Fatalf("%s: %v\n", tt.msg, err)
   138  		}
   139  	}
   140  }
   141  
   142  func TestUnlockFormFields(t *testing.T) {
   143  
   144  	for _, tt := range []struct {
   145  		msg     string
   146  		inFile  string
   147  		outFile string
   148  	}{
   149  		{"TestUnlockFormEN", "english-locked.pdf", "english-unlocked.pdf"},              // Core font (Helvetica)
   150  		{"TestUnlockFormUK", "ukrainian-locked.pdf", "ukrainian-unlocked.pdf"},          // User font (Roboto-Regular)
   151  		{"TestUnlockFormRTL", "arabic-locked.pdf", "arabic-unlocked.pdf"},               // User font RTL (Roboto-Regular)
   152  		{"TestUnlockFormCJK", "chineseSimple-locked.pdf", "chineseSimple-unlocked.pdf"}, // User font CJK (UnifontMedium)
   153  		{"TestUnlockPersonForm", "person-locked.pdf", "person-unlocked.pdf"},            // Person Form
   154  	} {
   155  		inFile := filepath.Join(samplesDir, "form", "lock", tt.inFile)
   156  		outFile := filepath.Join(samplesDir, "form", "lock", tt.outFile)
   157  		if err := api.UnlockFormFieldsFile(inFile, outFile, nil, conf); err != nil {
   158  			t.Fatalf("%s: %v\n", tt.msg, err)
   159  		}
   160  	}
   161  }
   162  
   163  func TestExportForm(t *testing.T) {
   164  
   165  	inDir := filepath.Join(samplesDir, "form", "demoSinglePage")
   166  	outDir := filepath.Join(samplesDir, "form", "export")
   167  
   168  	for _, tt := range []struct {
   169  		msg     string
   170  		inFile  string
   171  		outFile string
   172  	}{
   173  		{"TestExportFormEN", "english.pdf", "english.json"},              // Core font (Helvetica)
   174  		{"TestExportFormUK", "ukrainian.pdf", "ukrainian.json"},          // User font (Roboto-Regular)
   175  		{"TestExportFormRTL", "arabic.pdf", "arabic.json"},               // User font RTL (Roboto-Regular)
   176  		{"TestExportFormCJK", "chineseSimple.pdf", "chineseSimple.json"}, // User font CJK (UnifontMedium)
   177  		{"TestExportPersonForm", "person.pdf", "person.json"},            // Person Form
   178  	} {
   179  		inFile := filepath.Join(inDir, tt.inFile)
   180  		outFile := filepath.Join(outDir, tt.outFile)
   181  		if err := api.ExportFormFile(inFile, outFile, conf); err != nil {
   182  			t.Fatalf("%s: %v\n", tt.msg, err)
   183  		}
   184  	}
   185  }
   186  
   187  func TestFillForm(t *testing.T) {
   188  
   189  	inDir := filepath.Join(samplesDir, "form", "demoSinglePage")
   190  	jsonDir := filepath.Join(samplesDir, "form", "fill")
   191  	outDir := jsonDir
   192  
   193  	for _, tt := range []struct {
   194  		msg        string
   195  		inFile     string
   196  		inFileJSON string
   197  		outFile    string
   198  	}{
   199  		{"TestFillFormEN", "english.pdf", "english.json", "english.pdf"},                    // Core font (Helvetica)
   200  		{"TestFillFormUK", "ukrainian.pdf", "ukrainian.json", "ukrainian.pdf"},              // User font (Roboto-Regular)
   201  		{"TestFillFormRTL", "arabic.pdf", "arabic.json", "arabic.pdf"},                      // User font RTL (Roboto-Regular)
   202  		{"TestFillFormCJK", "chineseSimple.pdf", "chineseSimple.json", "chineseSimple.pdf"}, // User font CJK (UnifontMedium)
   203  		{"TestFillPersonForm", "person.pdf", "person.json", "person.pdf"},                   // Person Form
   204  	} {
   205  		inFile := filepath.Join(inDir, tt.inFile)
   206  		inFileJSON := filepath.Join(jsonDir, tt.inFileJSON)
   207  		outFile := filepath.Join(outDir, tt.outFile)
   208  		if err := api.FillFormFile(inFile, inFileJSON, outFile, conf); err != nil {
   209  			t.Fatalf("%s: %v\n", tt.msg, err)
   210  		}
   211  	}
   212  }
   213  
   214  func TestMultiFillFormJSON(t *testing.T) {
   215  
   216  	inDir := filepath.Join(samplesDir, "form", "demoSinglePage")
   217  	jsonDir := filepath.Join(samplesDir, "form", "multifill", "json")
   218  	outDir := jsonDir
   219  
   220  	for _, tt := range []struct {
   221  		msg        string
   222  		inFile     string
   223  		inFileJSON string
   224  	}{
   225  		{"TestMultiFillFormJSONEnglish", "english.pdf", "english.json"},
   226  		{"TestMultiFillFormJSONPerson", "person.pdf", "person.json"},
   227  	} {
   228  		inFile := filepath.Join(inDir, tt.inFile)
   229  		inFileJSON := filepath.Join(jsonDir, tt.inFileJSON)
   230  		if err := api.MultiFillFormFile(inFile, inFileJSON, outDir, inFile, false, conf); err != nil {
   231  			t.Fatalf("%s: %v\n", tt.msg, err)
   232  		}
   233  	}
   234  }
   235  
   236  func TestMultiFillFormJSONMerged(t *testing.T) {
   237  
   238  	inDir := filepath.Join(samplesDir, "form", "demoSinglePage")
   239  	jsonDir := filepath.Join(samplesDir, "form", "multifill", "json")
   240  	outDir := filepath.Join(jsonDir, "merge")
   241  
   242  	for _, tt := range []struct {
   243  		msg        string
   244  		inFile     string
   245  		inFileJSON string
   246  	}{
   247  		{"TestMultiFillFormJSONEnglish", "english.pdf", "english.json"},
   248  		{"TestMultiFillFormJSONPerson", "person.pdf", "person.json"},
   249  	} {
   250  		inFile := filepath.Join(inDir, tt.inFile)
   251  		inFileJSON := filepath.Join(jsonDir, tt.inFileJSON)
   252  		if err := api.MultiFillFormFile(inFile, inFileJSON, outDir, inFile, true, conf); err != nil {
   253  			t.Fatalf("%s: %v\n", tt.msg, err)
   254  		}
   255  	}
   256  }
   257  
   258  func TestMultiFillFormCSV(t *testing.T) {
   259  
   260  	inDir := filepath.Join(samplesDir, "form", "demoSinglePage")
   261  	csvDir := filepath.Join(samplesDir, "form", "multifill", "csv")
   262  	outDir := csvDir
   263  
   264  	for _, tt := range []struct {
   265  		msg       string
   266  		inFile    string
   267  		inFileCSV string
   268  	}{
   269  		{"TestMultiFillFormCSVEnglish", "english.pdf", "english.csv"},
   270  		{"TestMultiFillFormCSVPerson", "person.pdf", "person.csv"},
   271  	} {
   272  
   273  		inFile := filepath.Join(inDir, tt.inFile)
   274  		inFileCSV := filepath.Join(csvDir, tt.inFileCSV)
   275  		if err := api.MultiFillFormFile(inFile, inFileCSV, outDir, inFile, false, conf); err != nil {
   276  			t.Fatalf("%s: %v\n", tt.msg, err)
   277  		}
   278  	}
   279  }
   280  
   281  func TestMultiFillFormCSVMerged(t *testing.T) {
   282  
   283  	inDir := filepath.Join(samplesDir, "form", "demoSinglePage")
   284  	csvDir := filepath.Join(samplesDir, "form", "multifill", "csv")
   285  	outDir := filepath.Join(csvDir, "merge")
   286  
   287  	for _, tt := range []struct {
   288  		msg       string
   289  		inFile    string
   290  		inFileCSV string
   291  	}{
   292  		{"TestMultiFillFormCSVEnglish", "english.pdf", "english.csv"},
   293  		{"TestMultiFillFormCSVPerson", "person.pdf", "person.csv"},
   294  	} {
   295  
   296  		inFile := filepath.Join(inDir, tt.inFile)
   297  		inFileCSV := filepath.Join(csvDir, tt.inFileCSV)
   298  		if err := api.MultiFillFormFile(inFile, inFileCSV, outDir, inFile, true, conf); err != nil {
   299  			t.Fatalf("%s: %v\n", tt.msg, err)
   300  		}
   301  	}
   302  }