go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/explorer/mquery_test.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package explorer
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"go.mondoo.com/cnquery/providers-sdk/v1/testutils"
    14  )
    15  
    16  func TestMquery_Refresh(t *testing.T) {
    17  	a := &Mquery{
    18  		Mql:   "mondoo.version != props.world",
    19  		Uid:   "my-id0",
    20  		Props: []*Property{{Mql: "'hi'", Uid: "world"}},
    21  	}
    22  
    23  	err := a.RefreshMRN("//owner")
    24  	require.NoError(t, err)
    25  	assert.Equal(t, "//owner/queries/my-id0", a.Mrn)
    26  	assert.Empty(t, a.Uid)
    27  	assert.Equal(t, "//owner/queries/world", a.Props[0].Mrn)
    28  	assert.Empty(t, a.Props[0].Uid)
    29  
    30  	x := testutils.LinuxMock()
    31  	err = a.RefreshChecksum(
    32  		context.Background(),
    33  		x.Schema(),
    34  		func(ctx context.Context, mrn string) (*Mquery, error) {
    35  			return nil, nil
    36  		},
    37  	)
    38  	require.NoError(t, err)
    39  	assert.Equal(t, "5KkJ/lLHnBM=", a.Checksum)
    40  	assert.Equal(t, "9NhbOk30tEg=", a.Props[0].Checksum)
    41  }
    42  
    43  func TestMqueryMerge(t *testing.T) {
    44  	a := &Mquery{
    45  		Mql:   "base",
    46  		Title: "base title",
    47  		Docs: &MqueryDocs{
    48  			Desc:  "base desc",
    49  			Audit: "base audit",
    50  			Remediation: &Remediation{
    51  				Items: []*TypedDoc{{
    52  					Id:   "default",
    53  					Desc: "a description",
    54  				}},
    55  			},
    56  		},
    57  	}
    58  	b := &Mquery{
    59  		Mql: "override",
    60  		Docs: &MqueryDocs{
    61  			Desc: "override desc",
    62  			Remediation: &Remediation{
    63  				Items: []*TypedDoc{{
    64  					Id:   "default",
    65  					Desc: "b description",
    66  				}},
    67  			},
    68  		},
    69  	}
    70  
    71  	c := b.Merge(a)
    72  
    73  	assert.NotEqual(t, a.Mql, c.Mql)
    74  	assert.Equal(t, b.Mql, c.Mql)
    75  
    76  	assert.Equal(t, a.Title, c.Title)
    77  	assert.NotEqual(t, b.Title, c.Title)
    78  
    79  	assert.NotEqual(t, a.Docs.Desc, c.Docs.Desc)
    80  	assert.Equal(t, b.Docs.Desc, c.Docs.Desc)
    81  
    82  	assert.Equal(t, a.Docs.Audit, c.Docs.Audit)
    83  	assert.NotEqual(t, b.Docs.Audit, c.Docs.Audit)
    84  
    85  	a.CodeId = "not this"
    86  	b.CodeId = "not this either"
    87  	assert.Equal(t, "", c.CodeId)
    88  
    89  	// we want to make sure there are no residual shallow-copies
    90  	cD := c.Docs.Remediation.Items[0].Desc
    91  	a.Docs.Remediation.Items[0].Desc = "not this"
    92  	a.Docs.Remediation.Items[0].Desc = "not this either"
    93  	assert.Equal(t, cD, c.Docs.Remediation.Items[0].Desc)
    94  }
    95  
    96  func TestMquery_Remediation(t *testing.T) {
    97  	tests := []struct {
    98  		title string
    99  		data  string
   100  		out   *Remediation
   101  	}{
   102  		{
   103  			"parse default remediation, string-only",
   104  			"\"string-only remediation\"",
   105  			&Remediation{Items: []*TypedDoc{
   106  				{Id: "default", Desc: "string-only remediation"},
   107  			}},
   108  		},
   109  		{
   110  			"parse multiple remediation via array",
   111  			"[{\"id\": \"one\", \"desc\": \"two\"}, {\"id\": \"three\", \"desc\": \"four\"}]",
   112  			&Remediation{Items: []*TypedDoc{
   113  				{Id: "one", Desc: "two"},
   114  				{Id: "three", Desc: "four"},
   115  			}},
   116  		},
   117  		{
   118  			"parse internal structure, which uses items",
   119  			"{\"items\":[{\"id\": \"one\", \"desc\": \"two\"}, {\"id\": \"three\", \"desc\": \"four\"}]}",
   120  			&Remediation{Items: []*TypedDoc{
   121  				{Id: "one", Desc: "two"},
   122  				{Id: "three", Desc: "four"},
   123  			}},
   124  		},
   125  	}
   126  
   127  	for _, cur := range tests {
   128  		t.Run(cur.title, func(t *testing.T) {
   129  			var res Remediation
   130  			err := json.Unmarshal([]byte(cur.data), &res)
   131  			require.NoError(t, err)
   132  			assert.Equal(t, cur.out, &res)
   133  		})
   134  	}
   135  
   136  	t.Run("marshal remediation to json", func(t *testing.T) {
   137  		initial := &Remediation{
   138  			Items: []*TypedDoc{
   139  				{Id: "default", Desc: "one remediation"},
   140  			},
   141  		}
   142  
   143  		out, err := json.Marshal(initial)
   144  		require.NoError(t, err)
   145  		assert.Equal(t, "[{\"id\":\"default\",\"desc\":\"one remediation\"}]", string(out))
   146  
   147  		var back Remediation
   148  		err = json.Unmarshal(out, &back)
   149  		require.NoError(t, err)
   150  		assert.Equal(t, initial, &back)
   151  	})
   152  }