Skip to content

Commit

Permalink
Merge pull request #26 from goark/issue-25
Browse files Browse the repository at this point in the history
 Enable to get browse node Info #25
  • Loading branch information
spiegel-im-spiegel authored Jul 13, 2022
2 parents d2bce62 + c6f7f64 commit 3ed4e26
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 701 deletions.
82 changes: 37 additions & 45 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,52 +15,44 @@ on:
- cron: '0 20 * * 0'

jobs:
analyze:
name: Analyze
CodeQL-Build:
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['go']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
permissions:
# required for all workflows
security-events: write

steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# only required for workflows in private repositories
actions: read
contents: read

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language

#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
# Override language selection by uncommenting this and choosing your languages
with:
languages: go

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below).
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following
# three lines and modify them (or add more) to build your code if your
# project uses a compiled language

#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
32 changes: 27 additions & 5 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,43 @@ on:
branches:
- master
pull_request:

permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/setup-go@v3
with:
go-version: ^1.17
go-version: ^1.18
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
uses: golangci/golangci-lint-action@v3
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
args: --enable gosec

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

# Optional: if set to true then the all caching functionality will be complete disabled,
# takes precedence over all other caching options.
# skip-cache: true

# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true
- name: testing
run: go test -shuffle on ./...
4 changes: 1 addition & 3 deletions .github/workflows/vulns.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: vulns
on:
push:
tags:
- v*
branches:
- master
pull_request:
Expand All @@ -14,7 +12,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: ^1.17
go-version: ^1.18
- name: WriteGoList
run: go list -json -m all > go.list
- name: Nancy
Expand Down
4 changes: 2 additions & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ tasks:
cmds:
- go mod verify
- go test -shuffle on ./...
- docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.44.2 golangci-lint run --enable gosec --timeout 3m0s ./...
- docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.46.2 golangci-lint run --enable gosec --timeout 3m0s ./...
sources:
- ./go.mod
- '**/*.go'

clean:
desc: Initialize module and build cache, and remake go.sum file.
cmds:
- go mod tidy -v -go=1.17
- go mod tidy -v -go=1.18
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/goark/pa-api

go 1.17
go 1.18

require (
github.com/goark/errs v1.1.0
Expand Down
18 changes: 10 additions & 8 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ var _ json.Marshaler = Operation(0) //Operation type is compatible with j
var _ json.Unmarshaler = (*Operation)(nil) //Operation type is compatible with json.Unmarshaler interface

const (
NullOperation Operation = iota //Unknown
GetVariations //GetVariations
GetItems //GetItems
SearchItems //SearchItems
NullOperation Operation = iota //Unknown
GetVariations //GetVariations
GetItems //GetItems
SearchItems //SearchItems
GetBrowseNodes //GetBrowseNodes
)

var nameMap = map[Operation]string{
GetVariations: "GetVariations",
GetItems: "GetItems",
SearchItems: "SearchItems",
GetVariations: "GetVariations",
GetItems: "GetItems",
SearchItems: "SearchItems",
GetBrowseNodes: "GetBrowseNodes",
}

//String method is a implementation of fmt.Stringer interface.
Expand Down Expand Up @@ -71,7 +73,7 @@ func (c Operation) MarshalJSON() ([]byte, error) {
return []byte(strconv.Quote(c.String())), nil
}

/* Copyright 2019 Spiegel
/* Copyright 2019-2022 Spiegel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
61 changes: 61 additions & 0 deletions query/getbrowsenodes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package query

import (
paapi5 "github.com/goark/pa-api"
)

//GetItems type is embedded Query for GetItems operation in PA-API v5
type GetBrowseNodes struct {
Query
}

var _ paapi5.Query = (*GetItems)(nil) //GetItems is compatible with paapi5.Query interface

//New creates new GetBrowseNodes instance
func NewGetBrowseNodes(marketplace, partnerTag, partnerType string) *GetBrowseNodes {
q := &GetBrowseNodes{*(New(paapi5.GetBrowseNodes))}
q.Request(Marketplace, marketplace).Request(PartnerTag, partnerTag).Request(PartnerType, partnerType)
return q
}

var requestsOfGetBrowseNodes = []RequestFilter{
BrowseNodeIds,
LanguagesOfPreference,
Marketplace,
PartnerTag,
PartnerType,
}

//RequestFilters adds RequestFilter to Query instance
func (q *GetBrowseNodes) Request(request RequestFilter, value interface{}) *GetBrowseNodes {
if request.findIn(requestsOfGetBrowseNodes) {
q.With().RequestFilters(RequestMap{request: value})
}
return q
}

//BrowseNodeIds sets ItemIds in GetItems instance
func (q *GetBrowseNodes) BrowseNodeIds(itms []string) *GetBrowseNodes {
return q.Request(BrowseNodeIds, itms)
}

//EnableBrowseNodes sets the resource of EnableBrowseNodes
func (q *GetBrowseNodes) EnableBrowseNodes() *GetBrowseNodes {
q.With().BrowseNodes()
return q
}

/* Copyright 2022 Spiegel and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
108 changes: 108 additions & 0 deletions query/getbrowsenodes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package query

import (
"testing"
)

func TestGetBrowseNodes(t *testing.T) {
testCases := []struct {
q *GetBrowseNodes
str string
}{
{q: NewGetBrowseNodes("foo.bar", "mytag-20", "Associates"), str: `{"Operation":"GetBrowseNodes","Marketplace":"foo.bar","PartnerTag":"mytag-20","PartnerType":"Associates"}`},
{q: NewGetBrowseNodes("foo.bar", "mytag-20", "Associates").BrowseNodeIds([]string{"123"}), str: `{"Operation":"GetBrowseNodes","BrowseNodeIds":["123"],"Marketplace":"foo.bar","PartnerTag":"mytag-20","PartnerType":"Associates"}`},
}
for _, tc := range testCases {
if str := tc.q.String(); str != tc.str {
t.Errorf("BrowseNodes.String() is \"%v\", want \"%v\"", str, tc.str)
}
}
}

func TestRequestFiltersInGetBrowseNodes(t *testing.T) {
testCases := []struct {
q *GetBrowseNodes
str string
}{
{q: NewGetBrowseNodes("", "", ""), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Actor, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Artist, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Availability, "Available"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Author, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Brand, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(BrowseNodeID, "123"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Condition, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Condition, "Any"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Condition, "New"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Condition, "Used"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Condition, "Collectible"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Condition, "Refurbished"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(CurrencyOfPreference, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(DeliveryFlags, "AmazonGlobal"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(ItemIds, "4900900028"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(ItemIdType, "ASIN"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(ItemCount, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(ItemPage, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(ItemPage, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Keywords, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(BrowseNodeIds, "123"), str: `{"Operation":"GetBrowseNodes","BrowseNodeIds":["123"]}`},
{q: NewGetBrowseNodes("", "", "").Request(BrowseNodeIds, []string{"123", "456"}), str: `{"Operation":"GetBrowseNodes","BrowseNodeIds":["123","456"]}`},
{q: NewGetBrowseNodes("", "", "").Request(LanguagesOfPreference, "foo"), str: `{"Operation":"GetBrowseNodes","LanguagesOfPreference":["foo"]}`},
{q: NewGetBrowseNodes("", "", "").Request(LanguagesOfPreference, []string{"foo", "bar"}), str: `{"Operation":"GetBrowseNodes","LanguagesOfPreference":["foo","bar"]}`},
{q: NewGetBrowseNodes("", "", "").Request(Marketplace, "foo.bar"), str: `{"Operation":"GetBrowseNodes","Marketplace":"foo.bar"}`},
{q: NewGetBrowseNodes("", "", "").Request(MaxPrice, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Merchant, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Merchant, "All"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Merchant, "Amazon"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(MinPrice, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(MinReviewsRating, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(MinSavingPercent, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(OfferCount, -1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(OfferCount, 0), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(OfferCount, 1), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(OfferCount, 123), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(PartnerTag, "foo"), str: `{"Operation":"GetBrowseNodes","PartnerTag":"foo"}`},
{q: NewGetBrowseNodes("", "", "").Request(PartnerType, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(PartnerType, "Associates"), str: `{"Operation":"GetBrowseNodes","PartnerType":"Associates"}`},
{q: NewGetBrowseNodes("", "", "").Request(Properties, map[string]string{"foo": "bar"}), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(SearchIndex, "All"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(SortBy, "AvgCustomerReviews"), str: `{"Operation":"GetBrowseNodes"}`},
{q: NewGetBrowseNodes("", "", "").Request(Title, "foo"), str: `{"Operation":"GetBrowseNodes"}`},
}

for _, tc := range testCases {
if str := tc.q.String(); str != tc.str {
t.Errorf("BrowseNodes.String() is \"%v\", want \"%v\"", str, tc.str)
}
}
}

func TestResourcesInGetBrowseNodes(t *testing.T) {
testCases := []struct {
q *GetBrowseNodes
str string
}{
{q: NewGetBrowseNodes("", "", "").EnableBrowseNodes(), str: `{"Operation":"GetBrowseNodes","Resources":["BrowseNodes.Ancestor","BrowseNodes.Children"]}`},
}

for _, tc := range testCases {
if str := tc.q.String(); str != tc.str {
t.Errorf("Query.String() is \"%v\", want \"%v\"", str, tc.str)
}
}
}

/* Copyright 2022 Spiegel and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Loading

0 comments on commit 3ed4e26

Please sign in to comment.